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 // Teuchos: Common Tools Package
4 //
5 // Copyright 2004 NTESS and the Teuchos contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
13 
15 
16 namespace Teuchos {
17 
18 const std::string ObjectType_name = "Foo Type";
19 
20 class Foo : virtual public ParameterListAcceptor {
21  public:
22  Foo() {}
23  virtual ~Foo() {}
24  virtual std::string getString() const =0;
25  virtual void setDefaults() =0;
26  void setParameterList(const RCP<ParameterList> & paramList) {
27  if (!is_null(paramList)) {
28  paramList->validateParameters(*this->getValidParameters());
29  paramList_ = paramList;
30  }
31  setDefaults();
32  }
34  return paramList_;
35  }
38  paramList_ = null;
39  return pl;
40  }
42  return paramList_;
43  }
44  private:
46 };
47 class FooA : virtual public Foo {
48  public:
49  FooA() {
50  setDefaults();
51  }
52  virtual ~FooA() {}
53  std::string getString() const {
54  return foo_;
55  }
56  void setDefaults() {
58  if (is_null(pl)) {
59  foo_ = "A";
60  } else {
61  foo_ = pl->get("String",foo_);
62  }
63  }
65  static RCP<ParameterList> validPL;
66  if (is_null(validPL)) {
67  RCP<ParameterList> pl = parameterList();
68  pl->set( "String", foo_ );
69  validPL = pl;
70  }
71  return validPL;
72  }
73  private:
74  std::string foo_;
75 };
76 class FooB : virtual public Foo {
77  public:
78  FooB() {
79  setDefaults();
80  }
81  virtual ~FooB() {}
82  std::string getString() const {
83  return foo_;
84  }
85  void setDefaults() {
87  if (is_null(pl)) {
88  foo_ = "B";
89  } else {
90  foo_ = pl->get("String",foo_);
91  }
92  }
94  static RCP<ParameterList> validPL;
95  if (is_null(validPL)) {
96  RCP<ParameterList> pl = parameterList();
97  pl->set( "String", foo_ );
98  validPL = pl;
99  }
100  return validPL;
101  }
102  private:
103  std::string foo_;
104 };
105 class FooC : virtual public Foo {
106  public:
107  FooC() {
108  setDefaults();
109  }
110  virtual ~FooC() {}
111  std::string getString() const {
112  return foo_;
113  }
114  void setDefaults() {
116  if (is_null(pl)) {
117  foo_ = "C";
118  } else {
119  foo_ = pl->get("String",foo_);
120  }
121  }
123  static RCP<ParameterList> validPL;
124  if (is_null(validPL)) {
125  RCP<ParameterList> pl = parameterList();
126  pl->set( "String", foo_ );
127  validPL = pl;
128  }
129  return validPL;
130  }
131  private:
132  std::string foo_;
133 };
134 
135 // The following happens at construction:
136 // 1. initializeDefaults_ is called
137 // a) object_name_ = "Object"
138 // b) objectType_name_ = "Object Type"
139 // c) defaultObject_ = "None"
140 // d) validObjectNames_ just has "None"
141 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, constructor) {
142  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
143  TEST_EQUALITY_CONST( ob->getObjectName(), "None" );
144  TEST_EQUALITY_CONST( ob->create(), null );
146  TEST_NOTHROW( pl = ob->getValidParameters() );
147  TEST_EQUALITY_CONST( pl->get<std::string>("Object Type"), "None" );
148  TEST_NOTHROW( ob = null );
149 }
150 
151 // Tests setObjectName and setObectTypeName
152 // Note: it should throw an exception if the string is ""
153 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setNames) {
154  {
155  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
156  TEST_THROW( ob->setObjectName(""), std::logic_error );
157  TEST_THROW( ob->setObjectTypeName(""), std::logic_error );
158  }
159  {
161  TEST_THROW( ob = objectBuilder<Foo>("","Foo Type"), std::logic_error );
162  TEST_THROW( ob = objectBuilder<Foo>("Foo",""), std::logic_error );
163  TEST_THROW( ob = objectBuilder<Foo>("",""), std::logic_error );
164  }
165  {
166  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
167  ob->setObjectName("Foo");
168  ob->setObjectTypeName("Foo Type");
169  const RCP<const ParameterList> validpl = ob->getValidParameters();
170  // Now we check that the parameterlist is correct
171  TEST_EQUALITY_CONST( validpl->get<std::string>("Foo Type"), "None" );
172  const ParameterEntry pe = validpl->getEntry("Foo Type");
174  "Determines the type of Foo object that will be built.\nThe parameters for each Foo Type are specified in this sublist"
175  );
176  }
177  {
178  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
179  const RCP<const ParameterList> validpl = ob->getValidParameters();
180  // Now we check that the parameterlist is correct
181  TEST_EQUALITY_CONST( validpl->get<std::string>("Foo Type"), "None" );
182  const ParameterEntry pe = validpl->getEntry("Foo Type");
184  "Determines the type of Foo object that will be built.\nThe parameters for each Foo Type are specified in this sublist"
185  );
186  }
187 }
188 
189 // setObjectFactory does four things:
190 // 1. adds a new object name
191 // 1a. if object name is "" it throws an exception
192 // 2. adds a new object factory
193 // 3. sets defaultObject_
194 // 4. deletes the validParamList_
195 //
196 // Notes about how to sense the changes:
197 // 1. The new object name is appended to the list of valid names and shows up in the valid parameter list
198 // 2. The new object factory is appended to the list of factories and is only accessible through create
199 // 3. The default Object is accessible through both getObjectName and the valid parameter list.
200 // 4. The validParameterList is deleted and this can only be sensed through calling getValidParameters
201 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setObjectFactory) {
202  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
203  TEST_EQUALITY_CONST( ob->getObjectName(), "None" );
204  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
205  TEST_EQUALITY_CONST( ob->getObjectName(), "Foo A" ); // 3.
206  RCP<const ParameterList> pl = ob->getValidParameters();
207  TEST_EQUALITY_CONST( pl->get<std::string>("Foo Type"), "Foo A" ); // 1.
208  TEST_EQUALITY_CONST( pl->sublist("Foo A").get<std::string>("String"), "A" ); // 1.
209  const RCP<Foo> foo = ob->create();
210  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
211  TEST_EQUALITY_CONST( is_null(fooA), false ); // 2.
212  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
213  pl = ob->getValidParameters();
214  TEST_EQUALITY_CONST( pl->get<std::string>("Foo Type"), "Foo B" ); // 4.
215  TEST_THROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),""), std::logic_error ); // 1a.
216 }
217 
218 // We shouldn't be able to set two factories with the same name.
219 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setObjectFactory_bad ) {
220  {
221  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
222  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
223  // ObjectBuilder will let you add the object, but will not throw until getValidParameters is called
224 #ifdef TEUCHOS_DEBUG
225  TEST_THROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"), std::logic_error );
226 #else // TEUCHOS_DEBUG
227  TEST_NOTHROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A") );
228  TEST_THROW( ob->getValidParameters(), std::logic_error );
229 #endif // TEUCHOS_DEBUG
230  }
231  {
232  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
233  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
234  TEST_NOTHROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"New Foo A") );
235  TEST_NOTHROW( ob->getValidParameters() );
236  }
237 }
238 
239 // getObjectName returns the default in the parameter list (if given), or the
240 // default in the valid parameter list (if no parameter list is given)
241 // 1. no parameter list is given, uses default in valid parameter list.
242 // 2. parameter list is given, and uses its default
243 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getObjectName) {
244  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo", "Foo Type");
245  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
246  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
247  const RCP<ParameterList> pl = parameterList();
248  pl->setParameters(*ob->getValidParameters()); // copy parameters
249  pl->set("Foo Type", "Foo A"); // change default
250  // 1.
251  TEST_EQUALITY_CONST( ob->getObjectName(), "Foo B" );
252  // 2.
253  ob->setParameterList(pl);
254  TEST_EQUALITY_CONST( ob->getObjectName(), "Foo A" );
255 }
256 
257 // create has many cases
258 // 1. It should return a null RCP if no factories are set
259 // 2. It should return a null RCP if "Object Type" is set to "None" in the provided parameterList
260 // 3. It should return the correct object consistent with the "Object Type" setting in the parameterList if no string is passed
261 // 3a. It should return the correct object consistent with the "Object Type"
262 // setting in the valid parameterList if no string is passed and no
263 // parameterList is provided.
264 // 4. It should return the correct object consistent with the input string regardless of the parameterLists
265 // 4a. It should throw an exception if an invalid input string is provided
266 // 5. If no parameter list is provided, then it will use the valid parameter list to set parameters on the object
267 // 5a. If a parameter list is provided, then it will use that parameter list to set parameters on the object
268 // 6. It will throw an exception with a nice message if the factory creates a null RCP
269 // Under what conditions could this happen?
270 // 7. [03/05/09 tscoffe: found bug] create() uses objectValidator_, so
271 // getValidParameters must be valid at the beginning to avoid a null
272 // dereference of the objectValidator_ pointer in the case that we ask for an
273 // object by name and the validParamList_ has not been set up yet.
274 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, create) {
275  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo", "Foo Type");
276  TEST_EQUALITY_CONST( ob->create("None"), null ); // 7.
277  TEST_EQUALITY_CONST( ob->create(), null ); // 1.
278  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
279  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
280  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
281  out << "op.getValidParamters():\n";
282  printValidParameters(*ob, out);
283  const RCP<ParameterList> pl = parameterList();
284  pl->setParameters(*ob->getValidParameters());
285  pl->set("Foo Type","None");
286  ob->setParameterList(pl);
287  TEST_EQUALITY_CONST( ob->create(), null ); // 2.
288  pl->set("Foo Type", "Foo B");
289  pl->sublist("Foo B").set("String","BB");
290  pl->sublist("Foo C").set("String","CC");
291  {
292  const RCP<Foo> foo = ob->create();
293  const RCP<FooB> fooB = rcp_dynamic_cast<FooB>(foo,false);
294  TEST_EQUALITY_CONST( is_null(fooB), false ); // 3.
295  TEST_EQUALITY_CONST( foo->getString(), "BB" ); // 5a.
296  }
297  ob->unsetParameterList();
298  {
299  const RCP<Foo> foo = ob->create();
300  const RCP<FooC> fooC = rcp_dynamic_cast<FooC>(foo,false);
301  TEST_EQUALITY_CONST( is_null(fooC), false ); // 3a.
302  TEST_EQUALITY_CONST( foo->getString(), "C" ); // 5.
303  }
304  {
305  const RCP<Foo> foo = ob->create("Foo A");
306  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
307  TEST_EQUALITY_CONST( is_null(fooA), false ); // 4.
308  }
309  ob->setParameterList(pl);
310  {
311  const RCP<Foo> foo = ob->create("Foo A");
312  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
313  TEST_EQUALITY_CONST( is_null(fooA), false ); // 4.
314  }
315  {
316  RCP<Foo> foo;
317  TEST_THROW( foo = ob->create("Foo D"), std::logic_error ); // 4a.
318  }
319  // 6. ???
320 }
321 
322 #if !(__GNUC__ == 4 && __GNUC_MINOR__ == 8) && !(__GNUC__ == 4 && __GNUC_MINOR__ == 9) && !(__GNUC__ == 5 && __GNUC_MINOR__ == 3) && !(__GNUC__ == 6 && __GNUC_MINOR__ == 2)
323 
324 // There are many places that the parameter list is validated to ensure that we
325 // catch invalid parameter lists before we use them. This is particularly
326 // important because we're storing a pointer to the parameter list and the user
327 // can change it without ObjectBuilder knowing about it.
328 // The parameter list is validated in three places:
329 // 1. setParameterList
330 // 2. unsetParameterList (only in debug mode)
331 // 3. create (only in debug mode)
332 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setParameterList) {
333  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
334  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
336  TEST_NOTHROW( ob->setParameterList(pl) );
337  pl = parameterList();
338  TEST_NOTHROW( ob->setParameterList(pl) );
339  pl->set("Hello","World");
340  TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 1.
341 #ifdef TEUCHOS_DEBUG
342  TEST_THROW( ob->unsetParameterList(), std::logic_error ); // 2.
343  TEST_THROW( ob->create(), std::logic_error ); // 3.
344 #else // TEUCHOS_DEBUG
345  TEST_NOTHROW( ob->unsetParameterList() );
346  RCP<Foo> foo;
347  TEST_NOTHROW( foo = ob->create() );
348  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
349  TEST_EQUALITY_CONST( is_null(fooA), false );
350  TEST_NOTHROW( ob = null );
351 #endif // TEUCHOS_DEBUG
352 }
353 
354 #endif // GCC 4.8, 4.9, 5.3, 6.2
355 // For Some reason, with GCC 4.8.3, 4.9.3, 5.3.0, 6.2 the catch() statement
356 // refuses to catch the exception being thrown inside of the destructor. This
357 // use case is a very unusal use case and likley will not happen in real
358 // programs. This test passes with other compilers so it is not clear if this
359 // is a code defect or a compiler defect. In any case, exceptions should not
360 // be thrown from destrucrtors (see Trilinos GitHub #1303).
361 
362 
363 // Here we test
364 // 1. That it returns a null RCP before we give it a parameter list.
365 // 2. That we can set up a valid parameter list, give it to the ObjectBuilder, and get it back out.
366 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getParameterList) {
367  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
368  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
369  const RCP<const ParameterList> pl = ob->getParameterList();
370  TEST_EQUALITY_CONST( is_null(pl), true ); // 1.
371  const RCP<ParameterList> nonconstPL = parameterList();
372  nonconstPL->set("Object Type","None");
373  TEST_NOTHROW( ob->setParameterList(nonconstPL) );
374  {
375  const RCP<const ParameterList> newPL = ob->getParameterList();
376  TEST_EQUALITY_CONST( nonconstPL.get(), newPL.get() ); // 2.
377  }
378 }
379 
380 // Same as getParameterList
381 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getNonconstParameterList) {
382  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
383  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
384  RCP<ParameterList> pl = ob->getNonconstParameterList();
385  TEST_EQUALITY_CONST( is_null(pl), true );
386  pl = parameterList();
387  pl->set("Object Type","None");
388  TEST_NOTHROW( ob->setParameterList(pl) );
389  {
390  RCP<ParameterList> newPL = null;
391  newPL = ob->getNonconstParameterList();
392  TEST_EQUALITY_CONST( pl.get(), newPL.get() );
393  }
394 }
395 
396 #if !(__GNUC__ == 4 && __GNUC_MINOR__ == 8) && !(__GNUC__ == 4 && __GNUC_MINOR__ == 9) && !(__GNUC__ == 5 && __GNUC_MINOR__ == 3) && !(__GNUC__ == 6 && __GNUC_MINOR__ == 2)
397 
398 // Here we're checking:
399 // 1. That we can set a parameter list on it and it uses it and then we can
400 // unset it and it goes back to using the valid parameter list.
401 // 1a. We get back the same parameter list we set
402 // 2. In debug mode, the parameter list is validated when unsetParameterList
403 // is called.
404 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, unsetParameterList) {
405  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
406  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
407  const RCP<ParameterList> pl = parameterList();
408  pl->set("Object Type","None");
409  ob->setParameterList(pl);
410  RCP<Foo> foo = ob->create();
411  TEST_EQUALITY_CONST( is_null(foo), true );
412  RCP<ParameterList> newPL = ob->unsetParameterList();
413  TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a.
414  foo = ob->create();
415  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
416  TEST_EQUALITY_CONST( is_null(fooA), false ); // 1.
417  ob->setParameterList(pl);
418  pl->set("Hello","World");
419  newPL = null;
420 #ifdef TEUCHOS_DEBUG
421  TEST_THROW( newPL = ob->unsetParameterList(), std::logic_error ); // 2.
422  TEST_EQUALITY_CONST( is_null(newPL), true );
423 #else // TEUCHOS_DEBUG
424  TEST_NOTHROW( newPL = ob->unsetParameterList() );
425  TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a.
426  TEST_NOTHROW( ob = null );
427 #endif // TEUCHOS_DEBUG
428 }
429 
430 #endif // GCC 4.8, 4.9, 5.3, 6.2
431 
432 // This function does several things.
433 // 1. It creates the validParameterList whenever it is deleted [already tested in setObjectFactory]
434 // 2. It creates the objectValidator
435 // 3. It adds a docstring to the "Object Type" parameter in the parameter list [already tested in setNames]
436 // 4. It fills the parameter list out with the valid parameteres for each object it can create
437 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getValidParameters) {
438  {
439  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
440  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
441  const RCP<ParameterList> pl = parameterList();
442  pl->set("Object Type","Foo B");
443  TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 2.
444  }
445  {
446  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
447  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
448  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo B");
449  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo C");
450  const RCP<ParameterList> validPL = parameterList();
451  validPL->set("Object Type","Foo C");
452  validPL->sublist("Foo A").set("String","A");
453  validPL->sublist("Foo B").set("String","B");
454  validPL->sublist("Foo C").set("String","C");
455  Array<std::string> validObjectNames;
456  validObjectNames.push_back("None");
457  validObjectNames.push_back("Foo A");
458  validObjectNames.push_back("Foo B");
459  validObjectNames.push_back("Foo C");
461  objectValidator = rcp(
463  validObjectNames,"Object Type"
464  )
465  );
466  validPL->set(
467  "Object Type","Foo C"
468  ,(std::string("Determines the type of Object object that will be built.\n")
469  + "The parameters for each Object Type are specified in this sublist"
470  ).c_str()
471  ,objectValidator
472  );
473  const RCP<const ParameterList> pl = ob->getValidParameters();
474  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
475  validPL->set("Object Type","Foo A");
476  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
477  validPL->set("Object Type","Foo B");
478  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
479  validPL->set("Object Type","None");
480  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
481  }
482 }
483 
484 // Now we verify that the parameter lists are coming out with Used parameters in the correct state
485 // 1. Pass in empty parameter list and create an object. We should get a
486 // sublist and used parameters on the sublist for the object we created, but no
487 // other sublists.
488 // 2. Pass in a full parameter list and create an object. We should get
489 // used parameters for only the sublist of the object we created.
490 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, usedParameters) {
491  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
492  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
493  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
494  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
495  {
496  const RCP<ParameterList> pl = parameterList();
497  ob->setParameterList(pl);
498  const RCP<Foo> foo = ob->create("Foo A");
499  TEST_EQUALITY_CONST( foo->getString(), "A" );
500  TEST_EQUALITY_CONST( pl->isSublist("Foo A"), true ); // 1.
501  TEST_EQUALITY_CONST( pl->sublist("Foo A").isParameter("String"), true ); // 1.
502  const ParameterEntry& pe = pl->sublist("Foo A").getEntry("String");
503  TEST_EQUALITY_CONST( pe.isUsed(), true ); // 1.
504  TEST_EQUALITY_CONST( pe.isDefault(), true ); // 1.
505  // verify the other sublists are missing
506  TEST_EQUALITY_CONST( pl->isSublist("Foo B"), false ); // 1.
507  TEST_EQUALITY_CONST( pl->isSublist("Foo C"), false ); // 1.
508  ob->unsetParameterList();
509  }
510  {
511  RCP<ParameterList> pl = parameterList();
512  pl->setParameters(*ob->getValidParameters());
513  pl->sublist("Foo A").set("String","AA");
514  ob->setParameterList(pl);
515  pl = null;
516  const RCP<Foo> foo = ob->create("Foo A");
517  TEST_EQUALITY_CONST( foo->getString(), "AA" );
518  const RCP<const ParameterList> outPL = ob->getParameterList();
519  TEST_EQUALITY_CONST( outPL->isSublist("Foo A"), true );
520  TEST_EQUALITY_CONST( outPL->sublist("Foo A").isParameter("String"), true );
521  const ParameterEntry& pe = outPL->sublist("Foo A").getEntry("String");
522  TEST_EQUALITY_CONST( pe.isUsed(), true ); // 2.
523  TEST_EQUALITY_CONST( pe.isDefault(), false ); // 2.
524  // verify the other sublists are unused
525  TEST_EQUALITY_CONST( outPL->sublist("Foo B").getEntry("String").isUsed(), false ); // 2.
526  TEST_EQUALITY_CONST( outPL->sublist("Foo C").getEntry("String").isUsed(), false ); // 2.
527  ob->unsetParameterList();
528  }
529 }
530 
531 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withOneUsePL ) {
532  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
533  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
534  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
535  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
536  {
537  const RCP<ParameterList> pl = parameterList();
538  ob->setParameterList(pl);
539  const RCP<Foo> foo = ob->create();
540  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
541  TEST_ASSERT( !is_null(fooC) );
542  }
543  {
544  const RCP<ParameterList> pl = parameterList();
545  ob->setParameterList(pl);
546  ob->setDefaultObject("Foo A");
547  const RCP<Foo> foo = ob->create();
548  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
549  TEST_ASSERT( !is_null(fooA) );
550  }
551  {
552  const RCP<ParameterList> pl = parameterList();
553  ob->setParameterList(pl);
554  ob->setDefaultObject("None");
555  const RCP<Foo> foo = ob->create();
556  TEST_ASSERT( is_null(foo) );
557  }
558  {
559 #ifdef TEUCHOS_DEBUG
560  TEST_THROW(ob->setDefaultObject("Foo D"), std::logic_error);
561 #else
562  ob->setDefaultObject("Foo D");
563  TEST_THROW(ob->getValidParameters(), std::logic_error);
564 #endif // TEUCHOS_DEBUG
565  }
566 }
567 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withMultipleUsePL ) {
568  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
569  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
570  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
571  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
572  const RCP<ParameterList> pl = parameterList();
573  ob->setParameterList(pl);
574  {
575  const RCP<Foo> foo = ob->create();
576  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
577  TEST_ASSERT( !is_null(fooC) );
578  // Note: At this point, pl contains "Foo Type = Foo C"
579  // And this pl was set on the ObjectBuilder, so defaultObject does no good.
580  }
581  {
582  ob->setDefaultObject("Foo A");
583  const RCP<Foo> foo = ob->create();
584  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
585  TEST_ASSERT( is_null(fooA) );
586  }
587  {
588  ob->setDefaultObject("None");
589  const RCP<Foo> foo = ob->create();
590  TEST_ASSERT( !is_null(foo) );
591  }
592 }
593 
594 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withoutPL ) {
595  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
596  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
597  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
598  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
599  {
600  const RCP<Foo> foo = ob->create();
601  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
602  TEST_ASSERT( !is_null(fooC) );
603  }
604  {
605  ob->setDefaultObject("Foo A");
606  const RCP<Foo> foo = ob->create();
607  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
608  TEST_ASSERT( !is_null(fooA) );
609  }
610  {
611  ob->setDefaultObject("None");
612  const RCP<Foo> foo = ob->create();
613  TEST_ASSERT( is_null(foo) );
614  }
615 }
616 
617 } // 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.
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.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Templated set method.
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