Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ObjectBuilder_UnitTests.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Teuchos: Common Tools Package
5 // Copyright (2004) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
45 
47 
48 namespace Teuchos {
49 
50 const std::string ObjectType_name = "Foo Type";
51 
52 class Foo : virtual public ParameterListAcceptor {
53  public:
54  Foo() {}
55  virtual ~Foo() {}
56  virtual std::string getString() const =0;
57  virtual void setDefaults() =0;
58  void setParameterList(const RCP<ParameterList> & paramList) {
59  if (!is_null(paramList)) {
60  paramList->validateParameters(*this->getValidParameters());
61  paramList_ = paramList;
62  }
63  setDefaults();
64  }
66  return paramList_;
67  }
70  paramList_ = null;
71  return pl;
72  }
74  return paramList_;
75  }
76  private:
78 };
79 class FooA : virtual public Foo {
80  public:
81  FooA() {
82  setDefaults();
83  }
84  virtual ~FooA() {}
85  std::string getString() const {
86  return foo_;
87  }
88  void setDefaults() {
90  if (is_null(pl)) {
91  foo_ = "A";
92  } else {
93  foo_ = pl->get("String",foo_);
94  }
95  }
97  static RCP<ParameterList> validPL;
98  if (is_null(validPL)) {
99  RCP<ParameterList> pl = parameterList();
100  pl->set( "String", foo_ );
101  validPL = pl;
102  }
103  return validPL;
104  }
105  private:
106  std::string foo_;
107 };
108 class FooB : virtual public Foo {
109  public:
110  FooB() {
111  setDefaults();
112  }
113  virtual ~FooB() {}
114  std::string getString() const {
115  return foo_;
116  }
117  void setDefaults() {
119  if (is_null(pl)) {
120  foo_ = "B";
121  } else {
122  foo_ = pl->get("String",foo_);
123  }
124  }
126  static RCP<ParameterList> validPL;
127  if (is_null(validPL)) {
128  RCP<ParameterList> pl = parameterList();
129  pl->set( "String", foo_ );
130  validPL = pl;
131  }
132  return validPL;
133  }
134  private:
135  std::string foo_;
136 };
137 class FooC : virtual public Foo {
138  public:
139  FooC() {
140  setDefaults();
141  }
142  virtual ~FooC() {}
143  std::string getString() const {
144  return foo_;
145  }
146  void setDefaults() {
148  if (is_null(pl)) {
149  foo_ = "C";
150  } else {
151  foo_ = pl->get("String",foo_);
152  }
153  }
155  static RCP<ParameterList> validPL;
156  if (is_null(validPL)) {
157  RCP<ParameterList> pl = parameterList();
158  pl->set( "String", foo_ );
159  validPL = pl;
160  }
161  return validPL;
162  }
163  private:
164  std::string foo_;
165 };
166 
167 // The following happens at construction:
168 // 1. initializeDefaults_ is called
169 // a) object_name_ = "Object"
170 // b) objectType_name_ = "Object Type"
171 // c) defaultObject_ = "None"
172 // d) validObjectNames_ just has "None"
173 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, constructor) {
174  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
175  TEST_EQUALITY_CONST( ob->getObjectName(), "None" );
176  TEST_EQUALITY_CONST( ob->create(), null );
178  TEST_NOTHROW( pl = ob->getValidParameters() );
179  TEST_EQUALITY_CONST( pl->get<std::string>("Object Type"), "None" );
180  TEST_NOTHROW( ob = null );
181 }
182 
183 // Tests setObjectName and setObectTypeName
184 // Note: it should throw an exception if the string is ""
185 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setNames) {
186  {
187  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
188  TEST_THROW( ob->setObjectName(""), std::logic_error );
189  TEST_THROW( ob->setObjectTypeName(""), std::logic_error );
190  }
191  {
193  TEST_THROW( ob = objectBuilder<Foo>("","Foo Type"), std::logic_error );
194  TEST_THROW( ob = objectBuilder<Foo>("Foo",""), std::logic_error );
195  TEST_THROW( ob = objectBuilder<Foo>("",""), std::logic_error );
196  }
197  {
198  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
199  ob->setObjectName("Foo");
200  ob->setObjectTypeName("Foo Type");
201  const RCP<const ParameterList> validpl = ob->getValidParameters();
202  // Now we check that the parameterlist is correct
203  TEST_EQUALITY_CONST( validpl->get<std::string>("Foo Type"), "None" );
204  const ParameterEntry pe = validpl->getEntry("Foo Type");
206  "Determines the type of Foo object that will be built.\nThe parameters for each Foo Type are specified in this sublist"
207  );
208  }
209  {
210  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
211  const RCP<const ParameterList> validpl = ob->getValidParameters();
212  // Now we check that the parameterlist is correct
213  TEST_EQUALITY_CONST( validpl->get<std::string>("Foo Type"), "None" );
214  const ParameterEntry pe = validpl->getEntry("Foo Type");
216  "Determines the type of Foo object that will be built.\nThe parameters for each Foo Type are specified in this sublist"
217  );
218  }
219 }
220 
221 // setObjectFactory does four things:
222 // 1. adds a new object name
223 // 1a. if object name is "" it throws an exception
224 // 2. adds a new object factory
225 // 3. sets defaultObject_
226 // 4. deletes the validParamList_
227 //
228 // Notes about how to sense the changes:
229 // 1. The new object name is appended to the list of valid names and shows up in the valid parameter list
230 // 2. The new object factory is appended to the list of factories and is only accessible through create
231 // 3. The default Object is accessible through both getObjectName and the valid parameter list.
232 // 4. The validParameterList is deleted and this can only be sensed through calling getValidParameters
233 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setObjectFactory) {
234  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
235  TEST_EQUALITY_CONST( ob->getObjectName(), "None" );
236  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
237  TEST_EQUALITY_CONST( ob->getObjectName(), "Foo A" ); // 3.
238  RCP<const ParameterList> pl = ob->getValidParameters();
239  TEST_EQUALITY_CONST( pl->get<std::string>("Foo Type"), "Foo A" ); // 1.
240  TEST_EQUALITY_CONST( pl->sublist("Foo A").get<std::string>("String"), "A" ); // 1.
241  const RCP<Foo> foo = ob->create();
242  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
243  TEST_EQUALITY_CONST( is_null(fooA), false ); // 2.
244  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
245  pl = ob->getValidParameters();
246  TEST_EQUALITY_CONST( pl->get<std::string>("Foo Type"), "Foo B" ); // 4.
247  TEST_THROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),""), std::logic_error ); // 1a.
248 }
249 
250 // We shouldn't be able to set two factories with the same name.
251 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setObjectFactory_bad ) {
252  {
253  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
254  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
255  // ObjectBuilder will let you add the object, but will not throw until getValidParameters is called
256 #ifdef TEUCHOS_DEBUG
257  TEST_THROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"), std::logic_error );
258 #else // TEUCHOS_DEBUG
259  TEST_NOTHROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A") );
260  TEST_THROW( ob->getValidParameters(), std::logic_error );
261 #endif // TEUCHOS_DEBUG
262  }
263  {
264  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
265  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
266  TEST_NOTHROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"New Foo A") );
267  TEST_NOTHROW( ob->getValidParameters() );
268  }
269 }
270 
271 // getObjectName returns the default in the parameter list (if given), or the
272 // default in the valid parameter list (if no parameter list is given)
273 // 1. no parameter list is given, uses default in valid parameter list.
274 // 2. parameter list is given, and uses its default
275 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getObjectName) {
276  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo", "Foo Type");
277  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
278  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
279  const RCP<ParameterList> pl = parameterList();
280  pl->setParameters(*ob->getValidParameters()); // copy parameters
281  pl->set("Foo Type", "Foo A"); // change default
282  // 1.
283  TEST_EQUALITY_CONST( ob->getObjectName(), "Foo B" );
284  // 2.
285  ob->setParameterList(pl);
286  TEST_EQUALITY_CONST( ob->getObjectName(), "Foo A" );
287 }
288 
289 // create has many cases
290 // 1. It should return a null RCP if no factories are set
291 // 2. It should return a null RCP if "Object Type" is set to "None" in the provided parameterList
292 // 3. It should return the correct object consistent with the "Object Type" setting in the parameterList if no string is passed
293 // 3a. It should return the correct object consistent with the "Object Type"
294 // setting in the valid parameterList if no string is passed and no
295 // parameterList is provided.
296 // 4. It should return the correct object consistent with the input string regardless of the parameterLists
297 // 4a. It should throw an exception if an invalid input string is provided
298 // 5. If no parameter list is provided, then it will use the valid parameter list to set parameters on the object
299 // 5a. If a parameter list is provided, then it will use that parameter list to set parameters on the object
300 // 6. It will throw an exception with a nice message if the factory creates a null RCP
301 // Under what conditions could this happen?
302 // 7. [03/05/09 tscoffe: found bug] create() uses objectValidator_, so
303 // getValidParameters must be valid at the beginning to avoid a null
304 // dereference of the objectValidator_ pointer in the case that we ask for an
305 // object by name and the validParamList_ has not been set up yet.
306 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, create) {
307  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo", "Foo Type");
308  TEST_EQUALITY_CONST( ob->create("None"), null ); // 7.
309  TEST_EQUALITY_CONST( ob->create(), null ); // 1.
310  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
311  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
312  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
313  out << "op.getValidParamters():\n";
314  printValidParameters(*ob, out);
315  const RCP<ParameterList> pl = parameterList();
316  pl->setParameters(*ob->getValidParameters());
317  pl->set("Foo Type","None");
318  ob->setParameterList(pl);
319  TEST_EQUALITY_CONST( ob->create(), null ); // 2.
320  pl->set("Foo Type", "Foo B");
321  pl->sublist("Foo B").set("String","BB");
322  pl->sublist("Foo C").set("String","CC");
323  {
324  const RCP<Foo> foo = ob->create();
325  const RCP<FooB> fooB = rcp_dynamic_cast<FooB>(foo,false);
326  TEST_EQUALITY_CONST( is_null(fooB), false ); // 3.
327  TEST_EQUALITY_CONST( foo->getString(), "BB" ); // 5a.
328  }
329  ob->unsetParameterList();
330  {
331  const RCP<Foo> foo = ob->create();
332  const RCP<FooC> fooC = rcp_dynamic_cast<FooC>(foo,false);
333  TEST_EQUALITY_CONST( is_null(fooC), false ); // 3a.
334  TEST_EQUALITY_CONST( foo->getString(), "C" ); // 5.
335  }
336  {
337  const RCP<Foo> foo = ob->create("Foo A");
338  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
339  TEST_EQUALITY_CONST( is_null(fooA), false ); // 4.
340  }
341  ob->setParameterList(pl);
342  {
343  const RCP<Foo> foo = ob->create("Foo A");
344  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
345  TEST_EQUALITY_CONST( is_null(fooA), false ); // 4.
346  }
347  {
348  RCP<Foo> foo;
349  TEST_THROW( foo = ob->create("Foo D"), std::logic_error ); // 4a.
350  }
351  // 6. ???
352 }
353 
354 #if !(__GNUC__ == 4 && __GNUC_MINOR__ == 8) && !(__GNUC__ == 4 && __GNUC_MINOR__ == 9) && !(__GNUC__ == 5 && __GNUC_MINOR__ == 3) && !(__GNUC__ == 6 && __GNUC_MINOR__ == 2)
355 
356 // There are many places that the parameter list is validated to ensure that we
357 // catch invalid parameter lists before we use them. This is particularly
358 // important because we're storing a pointer to the parameter list and the user
359 // can change it without ObjectBuilder knowing about it.
360 // The parameter list is validated in three places:
361 // 1. setParameterList
362 // 2. unsetParameterList (only in debug mode)
363 // 3. create (only in debug mode)
364 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setParameterList) {
365  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
366  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
368  TEST_NOTHROW( ob->setParameterList(pl) );
369  pl = parameterList();
370  TEST_NOTHROW( ob->setParameterList(pl) );
371  pl->set("Hello","World");
372  TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 1.
373 #ifdef TEUCHOS_DEBUG
374  TEST_THROW( ob->unsetParameterList(), std::logic_error ); // 2.
375  TEST_THROW( ob->create(), std::logic_error ); // 3.
376 #else // TEUCHOS_DEBUG
377  TEST_NOTHROW( ob->unsetParameterList() );
378  RCP<Foo> foo;
379  TEST_NOTHROW( foo = ob->create() );
380  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
381  TEST_EQUALITY_CONST( is_null(fooA), false );
382  TEST_NOTHROW( ob = null );
383 #endif // TEUCHOS_DEBUG
384 }
385 
386 #endif // GCC 4.8, 4.9, 5.3, 6.2
387 // For Some reason, with GCC 4.8.3, 4.9.3, 5.3.0, 6.2 the catch() statement
388 // refuses to catch the exception being thrown inside of the destructor. This
389 // use case is a very unusal use case and likley will not happen in real
390 // programs. This test passes with other compilers so it is not clear if this
391 // is a code defect or a compiler defect. In any case, exceptions should not
392 // be thrown from destrucrtors (see Trilinos GitHub #1303).
393 
394 
395 // Here we test
396 // 1. That it returns a null RCP before we give it a parameter list.
397 // 2. That we can set up a valid parameter list, give it to the ObjectBuilder, and get it back out.
398 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getParameterList) {
399  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
400  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
401  const RCP<const ParameterList> pl = ob->getParameterList();
402  TEST_EQUALITY_CONST( is_null(pl), true ); // 1.
403  const RCP<ParameterList> nonconstPL = parameterList();
404  nonconstPL->set("Object Type","None");
405  TEST_NOTHROW( ob->setParameterList(nonconstPL) );
406  {
407  const RCP<const ParameterList> newPL = ob->getParameterList();
408  TEST_EQUALITY_CONST( nonconstPL.get(), newPL.get() ); // 2.
409  }
410 }
411 
412 // Same as getParameterList
413 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getNonconstParameterList) {
414  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
415  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
416  RCP<ParameterList> pl = ob->getNonconstParameterList();
417  TEST_EQUALITY_CONST( is_null(pl), true );
418  pl = parameterList();
419  pl->set("Object Type","None");
420  TEST_NOTHROW( ob->setParameterList(pl) );
421  {
422  RCP<ParameterList> newPL = null;
423  newPL = ob->getNonconstParameterList();
424  TEST_EQUALITY_CONST( pl.get(), newPL.get() );
425  }
426 }
427 
428 #if !(__GNUC__ == 4 && __GNUC_MINOR__ == 8) && !(__GNUC__ == 4 && __GNUC_MINOR__ == 9) && !(__GNUC__ == 5 && __GNUC_MINOR__ == 3) && !(__GNUC__ == 6 && __GNUC_MINOR__ == 2)
429 
430 // Here we're checking:
431 // 1. That we can set a parameter list on it and it uses it and then we can
432 // unset it and it goes back to using the valid parameter list.
433 // 1a. We get back the same parameter list we set
434 // 2. In debug mode, the parameter list is validated when unsetParameterList
435 // is called.
436 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, unsetParameterList) {
437  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
438  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
439  const RCP<ParameterList> pl = parameterList();
440  pl->set("Object Type","None");
441  ob->setParameterList(pl);
442  RCP<Foo> foo = ob->create();
443  TEST_EQUALITY_CONST( is_null(foo), true );
444  RCP<ParameterList> newPL = ob->unsetParameterList();
445  TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a.
446  foo = ob->create();
447  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
448  TEST_EQUALITY_CONST( is_null(fooA), false ); // 1.
449  ob->setParameterList(pl);
450  pl->set("Hello","World");
451  newPL = null;
452 #ifdef TEUCHOS_DEBUG
453  TEST_THROW( newPL = ob->unsetParameterList(), std::logic_error ); // 2.
454  TEST_EQUALITY_CONST( is_null(newPL), true );
455 #else // TEUCHOS_DEBUG
456  TEST_NOTHROW( newPL = ob->unsetParameterList() );
457  TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a.
458  TEST_NOTHROW( ob = null );
459 #endif // TEUCHOS_DEBUG
460 }
461 
462 #endif // GCC 4.8, 4.9, 5.3, 6.2
463 
464 // This function does several things.
465 // 1. It creates the validParameterList whenever it is deleted [already tested in setObjectFactory]
466 // 2. It creates the objectValidator
467 // 3. It adds a docstring to the "Object Type" parameter in the parameter list [already tested in setNames]
468 // 4. It fills the parameter list out with the valid parameteres for each object it can create
469 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getValidParameters) {
470  {
471  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
472  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
473  const RCP<ParameterList> pl = parameterList();
474  pl->set("Object Type","Foo B");
475  TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 2.
476  }
477  {
478  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
479  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
480  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo B");
481  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo C");
482  const RCP<ParameterList> validPL = parameterList();
483  validPL->set("Object Type","Foo C");
484  validPL->sublist("Foo A").set("String","A");
485  validPL->sublist("Foo B").set("String","B");
486  validPL->sublist("Foo C").set("String","C");
487  Array<std::string> validObjectNames;
488  validObjectNames.push_back("None");
489  validObjectNames.push_back("Foo A");
490  validObjectNames.push_back("Foo B");
491  validObjectNames.push_back("Foo C");
493  objectValidator = rcp(
495  validObjectNames,"Object Type"
496  )
497  );
498  validPL->set(
499  "Object Type","Foo C"
500  ,(std::string("Determines the type of Object object that will be built.\n")
501  + "The parameters for each Object Type are specified in this sublist"
502  ).c_str()
503  ,objectValidator
504  );
505  const RCP<const ParameterList> pl = ob->getValidParameters();
506  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
507  validPL->set("Object Type","Foo A");
508  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
509  validPL->set("Object Type","Foo B");
510  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
511  validPL->set("Object Type","None");
512  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
513  }
514 }
515 
516 // Now we verify that the parameter lists are coming out with Used parameters in the correct state
517 // 1. Pass in empty parameter list and create an object. We should get a
518 // sublist and used parameters on the sublist for the object we created, but no
519 // other sublists.
520 // 2. Pass in a full parameter list and create an object. We should get
521 // used parameters for only the sublist of the object we created.
522 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, usedParameters) {
523  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
524  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
525  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
526  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
527  {
528  const RCP<ParameterList> pl = parameterList();
529  ob->setParameterList(pl);
530  const RCP<Foo> foo = ob->create("Foo A");
531  TEST_EQUALITY_CONST( foo->getString(), "A" );
532  TEST_EQUALITY_CONST( pl->isSublist("Foo A"), true ); // 1.
533  TEST_EQUALITY_CONST( pl->sublist("Foo A").isParameter("String"), true ); // 1.
534  const ParameterEntry& pe = pl->sublist("Foo A").getEntry("String");
535  TEST_EQUALITY_CONST( pe.isUsed(), true ); // 1.
536  TEST_EQUALITY_CONST( pe.isDefault(), true ); // 1.
537  // verify the other sublists are missing
538  TEST_EQUALITY_CONST( pl->isSublist("Foo B"), false ); // 1.
539  TEST_EQUALITY_CONST( pl->isSublist("Foo C"), false ); // 1.
540  ob->unsetParameterList();
541  }
542  {
543  RCP<ParameterList> pl = parameterList();
544  pl->setParameters(*ob->getValidParameters());
545  pl->sublist("Foo A").set("String","AA");
546  ob->setParameterList(pl);
547  pl = null;
548  const RCP<Foo> foo = ob->create("Foo A");
549  TEST_EQUALITY_CONST( foo->getString(), "AA" );
550  const RCP<const ParameterList> outPL = ob->getParameterList();
551  TEST_EQUALITY_CONST( outPL->isSublist("Foo A"), true );
552  TEST_EQUALITY_CONST( outPL->sublist("Foo A").isParameter("String"), true );
553  const ParameterEntry& pe = outPL->sublist("Foo A").getEntry("String");
554  TEST_EQUALITY_CONST( pe.isUsed(), true ); // 2.
555  TEST_EQUALITY_CONST( pe.isDefault(), false ); // 2.
556  // verify the other sublists are unused
557  TEST_EQUALITY_CONST( outPL->sublist("Foo B").getEntry("String").isUsed(), false ); // 2.
558  TEST_EQUALITY_CONST( outPL->sublist("Foo C").getEntry("String").isUsed(), false ); // 2.
559  ob->unsetParameterList();
560  }
561 }
562 
563 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withOneUsePL ) {
564  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
565  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
566  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
567  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
568  {
569  const RCP<ParameterList> pl = parameterList();
570  ob->setParameterList(pl);
571  const RCP<Foo> foo = ob->create();
572  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
573  TEST_ASSERT( !is_null(fooC) );
574  }
575  {
576  const RCP<ParameterList> pl = parameterList();
577  ob->setParameterList(pl);
578  ob->setDefaultObject("Foo A");
579  const RCP<Foo> foo = ob->create();
580  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
581  TEST_ASSERT( !is_null(fooA) );
582  }
583  {
584  const RCP<ParameterList> pl = parameterList();
585  ob->setParameterList(pl);
586  ob->setDefaultObject("None");
587  const RCP<Foo> foo = ob->create();
588  TEST_ASSERT( is_null(foo) );
589  }
590  {
591 #ifdef TEUCHOS_DEBUG
592  TEST_THROW(ob->setDefaultObject("Foo D"), std::logic_error);
593 #else
594  ob->setDefaultObject("Foo D");
595  TEST_THROW(ob->getValidParameters(), std::logic_error);
596 #endif // TEUCHOS_DEBUG
597  }
598 }
599 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withMultipleUsePL ) {
600  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
601  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
602  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
603  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
604  const RCP<ParameterList> pl = parameterList();
605  ob->setParameterList(pl);
606  {
607  const RCP<Foo> foo = ob->create();
608  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
609  TEST_ASSERT( !is_null(fooC) );
610  // Note: At this point, pl contains "Foo Type = Foo C"
611  // And this pl was set on the ObjectBuilder, so defaultObject does no good.
612  }
613  {
614  ob->setDefaultObject("Foo A");
615  const RCP<Foo> foo = ob->create();
616  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
617  TEST_ASSERT( is_null(fooA) );
618  }
619  {
620  ob->setDefaultObject("None");
621  const RCP<Foo> foo = ob->create();
622  TEST_ASSERT( !is_null(foo) );
623  }
624 }
625 
626 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withoutPL ) {
627  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
628  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
629  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
630  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
631  {
632  const RCP<Foo> foo = ob->create();
633  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
634  TEST_ASSERT( !is_null(fooC) );
635  }
636  {
637  ob->setDefaultObject("Foo A");
638  const RCP<Foo> foo = ob->create();
639  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
640  TEST_ASSERT( !is_null(fooA) );
641  }
642  {
643  ob->setDefaultObject("None");
644  const RCP<Foo> foo = ob->create();
645  TEST_ASSERT( is_null(foo) );
646  }
647 }
648 
649 } // namespace Teuchos
RCP< ParameterList > unsetParameterList()
Unset the parameter list that was set using setParameterList().
std::string getString() const
RCP< const ParameterList > getParameterList() const
Get const version of the parameter list that was set using setParameterList().
#define TEST_ASSERT(v1)
Assert the given statement is true.
virtual std::string getString() const =0
#define TEST_NOTHROW(code)
Asserr that the statement &#39;code&#39; does not thrown any excpetions.
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this-&gt;setParameterList(...) will accept, along with any validators.
T & get(const std::string &name, T def_value)
Return the parameter&#39;s value, or the default value if it is not there.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Set a parameter whose value has type T.
This object is held as the &quot;value&quot; in the Teuchos::ParameterList std::map.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
#define TEST_THROW(code, ExceptType)
Assert that the statement &#39;code&#39; throws the exception &#39;ExceptType&#39; (otherwise the test fails)...
T * get() const
Get the raw C++ pointer to the underlying object.
bool isParameter(const std::string &name) const
Whether the given parameter exists in this list.
TEUCHOS_UNIT_TEST(ConstNonconstObjectContainer, create)
const std::string ObjectType_name
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
Templated Parameter List class.
bool isSublist(const std::string &name) const
Whether the given sublist exists in this list.
RCP< ParameterList > getNonconstParameterList()
Get a nonconst version of the parameter list that was set using setParameterList().
virtual void setDefaults()=0
Unit testing support.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
TEUCHOSPARAMETERLIST_LIB_DLL_EXPORT void printValidParameters(const ParameterListAcceptor &paramListAccpetor, std::ostream &out, const bool showDoc=true)
Pretty print the valid parameters from a ParameterListAccpetor object.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
Validate the parameters in this list given valid selections in the input list.
ParameterList & setParameters(const ParameterList &source)
RCP< ParameterList > paramList_
Interface for objects that can accept a ParameterList.
void push_back(const value_type &x)
void setParameterList(const RCP< ParameterList > &paramList)
Set parameters from a parameter list and return with default values.
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this-&gt;setParameterList(...) will accept, along with any validators.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Creates an empty sublist and returns a reference to the sublist name. If the list already exists...
Smart reference counting pointer class for automatic garbage collection.
std::string docString() const
Return the (optional) documentation std::string.
ParameterEntry & getEntry(const std::string &name)
Retrieves an entry with the name name.
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this-&gt;setParameterList(...) will accept, along with any validators.
std::string getString() const
virtual RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this-&gt;setParameterList(...) will accept, along with any validators.
std::string getString() const