Teuchos Package Browser (Single Doxygen Collection)  Version of the Day
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)
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 four places:
361 // 1. setParameterList
362 // 2. unsetParameterList (only in debug mode)
363 // 3. create (only in debug mode)
364 // 4. destructor (only in debug mode)
365 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setParameterList) {
366  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
367  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
369  TEST_NOTHROW( ob->setParameterList(pl) );
370  pl = parameterList();
371  TEST_NOTHROW( ob->setParameterList(pl) );
372  pl->set("Hello","World");
373  TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 1.
374 #ifdef TEUCHOS_DEBUG
375  TEST_THROW( ob->unsetParameterList(), std::logic_error ); // 2.
376  TEST_THROW( ob->create(), std::logic_error ); // 3.
377  TEST_THROW( ob = null, std::logic_error ); // 4.
378 #else // TEUCHOS_DEBUG
379  TEST_NOTHROW( ob->unsetParameterList() );
380  RCP<Foo> foo;
381  TEST_NOTHROW( foo = ob->create() );
382  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
383  TEST_EQUALITY_CONST( is_null(fooA), false );
384  TEST_NOTHROW( ob = null );
385 #endif // TEUCHOS_DEBUG
386 }
387 
388 #endif // GCC 4.8
389 // For Some reason, with GCC 4.8.3, the catch() satement refuses to catch the
390 // exception being thrown inside of the destructor. This use case is a very
391 // unusal use case and likley will not happen in real programs. This test
392 // passes with ever other compiler (including GCC 4.9.x) so I am pretty sure
393 // this is a defect in GCC 4.8.x.
394 
395 
396 // Here we test
397 // 1. That it returns a null RCP before we give it a parameter list.
398 // 2. That we can set up a valid parameter list, give it to the ObjectBuilder, and get it back out.
399 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getParameterList) {
400  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
401  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
402  const RCP<const ParameterList> pl = ob->getParameterList();
403  TEST_EQUALITY_CONST( is_null(pl), true ); // 1.
404  const RCP<ParameterList> nonconstPL = parameterList();
405  nonconstPL->set("Object Type","None");
406  TEST_NOTHROW( ob->setParameterList(nonconstPL) );
407  {
408  const RCP<const ParameterList> newPL = ob->getParameterList();
409  TEST_EQUALITY_CONST( nonconstPL.get(), newPL.get() ); // 2.
410  }
411 }
412 
413 // Same as getParameterList
414 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getNonconstParameterList) {
415  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
416  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
417  RCP<ParameterList> pl = ob->getNonconstParameterList();
418  TEST_EQUALITY_CONST( is_null(pl), true );
419  pl = parameterList();
420  pl->set("Object Type","None");
421  TEST_NOTHROW( ob->setParameterList(pl) );
422  {
423  RCP<ParameterList> newPL = null;
424  newPL = ob->getNonconstParameterList();
425  TEST_EQUALITY_CONST( pl.get(), newPL.get() );
426  }
427 }
428 
429 #if !(__GNUC__ == 4 && __GNUC_MINOR__ == 8)
430 
431 // Here we're checking:
432 // 1. That we can set a parameter list on it and it uses it and then we can
433 // unset it and it goes back to using the valid parameter list.
434 // 1a. We get back the same parameter list we set
435 // 2. In debug mode, the parameter list is validated when unsetParameterList
436 // is called.
437 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, unsetParameterList) {
438  RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
439  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
440  const RCP<ParameterList> pl = parameterList();
441  pl->set("Object Type","None");
442  ob->setParameterList(pl);
443  RCP<Foo> foo = ob->create();
444  TEST_EQUALITY_CONST( is_null(foo), true );
445  RCP<ParameterList> newPL = ob->unsetParameterList();
446  TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a.
447  foo = ob->create();
448  const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false);
449  TEST_EQUALITY_CONST( is_null(fooA), false ); // 1.
450  ob->setParameterList(pl);
451  pl->set("Hello","World");
452  newPL = null;
453 #ifdef TEUCHOS_DEBUG
454  TEST_THROW( newPL = ob->unsetParameterList(), std::logic_error ); // 2.
455  TEST_EQUALITY_CONST( is_null(newPL), true );
456  TEST_THROW( ob = null, std::logic_error );
457 #else // TEUCHOS_DEBUG
458  TEST_NOTHROW( newPL = ob->unsetParameterList() );
459  TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a.
460  TEST_NOTHROW( ob = null );
461 #endif // TEUCHOS_DEBUG
462 }
463 
464 #endif // GCC 4.8
465 
466 // This function does several things.
467 // 1. It creates the validParameterList whenever it is deleted [already tested in setObjectFactory]
468 // 2. It creates the objectValidator
469 // 3. It adds a docstring to the "Object Type" parameter in the parameter list [already tested in setNames]
470 // 4. It fills the parameter list out with the valid parameteres for each object it can create
471 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getValidParameters) {
472  {
473  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
474  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
475  const RCP<ParameterList> pl = parameterList();
476  pl->set("Object Type","Foo B");
477  TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 2.
478  }
479  {
480  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>();
481  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
482  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo B");
483  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo C");
484  const RCP<ParameterList> validPL = parameterList();
485  validPL->set("Object Type","Foo C");
486  validPL->sublist("Foo A").set("String","A");
487  validPL->sublist("Foo B").set("String","B");
488  validPL->sublist("Foo C").set("String","C");
489  Array<std::string> validObjectNames;
490  validObjectNames.push_back("None");
491  validObjectNames.push_back("Foo A");
492  validObjectNames.push_back("Foo B");
493  validObjectNames.push_back("Foo C");
495  objectValidator = rcp(
497  validObjectNames,"Object Type"
498  )
499  );
500  validPL->set(
501  "Object Type","Foo C"
502  ,(std::string("Determines the type of Object object that will be built.\n")
503  + "The parameters for each Object Type are specified in this sublist"
504  ).c_str()
505  ,objectValidator
506  );
507  const RCP<const ParameterList> pl = ob->getValidParameters();
508  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
509  validPL->set("Object Type","Foo A");
510  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
511  validPL->set("Object Type","Foo B");
512  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
513  validPL->set("Object Type","None");
514  TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4.
515  }
516 }
517 
518 // Now we verify that the parameter lists are coming out with Used parameters in the correct state
519 // 1. Pass in empty parameter list and create an object. We should get a
520 // sublist and used parameters on the sublist for the object we created, but no
521 // other sublists.
522 // 2. Pass in a full parameter list and create an object. We should get
523 // used parameters for only the sublist of the object we created.
524 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, usedParameters) {
525  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
526  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
527  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
528  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
529  {
530  const RCP<ParameterList> pl = parameterList();
531  ob->setParameterList(pl);
532  const RCP<Foo> foo = ob->create("Foo A");
533  TEST_EQUALITY_CONST( foo->getString(), "A" );
534  TEST_EQUALITY_CONST( pl->isSublist("Foo A"), true ); // 1.
535  TEST_EQUALITY_CONST( pl->sublist("Foo A").isParameter("String"), true ); // 1.
536  const ParameterEntry& pe = pl->sublist("Foo A").getEntry("String");
537  TEST_EQUALITY_CONST( pe.isUsed(), true ); // 1.
538  TEST_EQUALITY_CONST( pe.isDefault(), true ); // 1.
539  // verify the other sublists are missing
540  TEST_EQUALITY_CONST( pl->isSublist("Foo B"), false ); // 1.
541  TEST_EQUALITY_CONST( pl->isSublist("Foo C"), false ); // 1.
542  ob->unsetParameterList();
543  }
544  {
545  RCP<ParameterList> pl = parameterList();
546  pl->setParameters(*ob->getValidParameters());
547  pl->sublist("Foo A").set("String","AA");
548  ob->setParameterList(pl);
549  pl = null;
550  const RCP<Foo> foo = ob->create("Foo A");
551  TEST_EQUALITY_CONST( foo->getString(), "AA" );
552  const RCP<const ParameterList> outPL = ob->getParameterList();
553  TEST_EQUALITY_CONST( outPL->isSublist("Foo A"), true );
554  TEST_EQUALITY_CONST( outPL->sublist("Foo A").isParameter("String"), true );
555  const ParameterEntry& pe = outPL->sublist("Foo A").getEntry("String");
556  TEST_EQUALITY_CONST( pe.isUsed(), true ); // 2.
557  TEST_EQUALITY_CONST( pe.isDefault(), false ); // 2.
558  // verify the other sublists are unused
559  TEST_EQUALITY_CONST( outPL->sublist("Foo B").getEntry("String").isUsed(), false ); // 2.
560  TEST_EQUALITY_CONST( outPL->sublist("Foo C").getEntry("String").isUsed(), false ); // 2.
561  ob->unsetParameterList();
562  }
563 }
564 
565 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withOneUsePL ) {
566  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
567  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
568  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
569  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
570  {
571  const RCP<ParameterList> pl = parameterList();
572  ob->setParameterList(pl);
573  const RCP<Foo> foo = ob->create();
574  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
575  TEST_ASSERT( !is_null(fooC) );
576  }
577  {
578  const RCP<ParameterList> pl = parameterList();
579  ob->setParameterList(pl);
580  ob->setDefaultObject("Foo A");
581  const RCP<Foo> foo = ob->create();
582  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
583  TEST_ASSERT( !is_null(fooA) );
584  }
585  {
586  const RCP<ParameterList> pl = parameterList();
587  ob->setParameterList(pl);
588  ob->setDefaultObject("None");
589  const RCP<Foo> foo = ob->create();
590  TEST_ASSERT( is_null(foo) );
591  }
592  {
593 #ifdef TEUCHOS_DEBUG
594  TEST_THROW(ob->setDefaultObject("Foo D"), std::logic_error);
595 #else
596  ob->setDefaultObject("Foo D");
597  TEST_THROW(ob->getValidParameters(), std::logic_error);
598 #endif // TEUCHOS_DEBUG
599  }
600 }
601 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withMultipleUsePL ) {
602  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
603  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
604  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
605  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
606  const RCP<ParameterList> pl = parameterList();
607  ob->setParameterList(pl);
608  {
609  const RCP<Foo> foo = ob->create();
610  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
611  TEST_ASSERT( !is_null(fooC) );
612  // Note: At this point, pl contains "Foo Type = Foo C"
613  // And this pl was set on the ObjectBuilder, so defaultObject does no good.
614  }
615  {
616  ob->setDefaultObject("Foo A");
617  const RCP<Foo> foo = ob->create();
618  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
619  TEST_ASSERT( is_null(fooA) );
620  }
621  {
622  ob->setDefaultObject("None");
623  const RCP<Foo> foo = ob->create();
624  TEST_ASSERT( !is_null(foo) );
625  }
626 }
627 
628 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withoutPL ) {
629  const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type");
630  ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A");
631  ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B");
632  ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C");
633  {
634  const RCP<Foo> foo = ob->create();
635  RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false);
636  TEST_ASSERT( !is_null(fooC) );
637  }
638  {
639  ob->setDefaultObject("Foo A");
640  const RCP<Foo> foo = ob->create();
641  RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false);
642  TEST_ASSERT( !is_null(fooA) );
643  }
644  {
645  ob->setDefaultObject("None");
646  const RCP<Foo> foo = ob->create();
647  TEST_ASSERT( is_null(foo) );
648  }
649 }
650 
651 } // namespace Teuchos
652 
653 
654 
RCP< ParameterList > unsetParameterList()
Unset the parameter list that was set using setParameterList().
virtual std::string getString() const =0
#define TEST_NOTHROW(code)
Asserr that the statement &#39;code&#39; does not thrown any excpetions.
T & get(const std::string &name, T def_value)
Return the parameter&#39;s value, or the default value if it is not there.
virtual RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(...) will accept, along with any validators.
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 "value" in the Teuchos::ParameterList std::map.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
std::string getString() const
bool isSublist(const std::string &name) const
Whether the given sublist exists in this list.
#define TEST_THROW(code, ExceptType)
Assert that the statement &#39;code&#39; throws the exception &#39;ExceptType&#39; (otherwise the test fails)...
RCP< const ParameterList > getParameterList() const
Get const version of the parameter list that was set using setParameterList().
T * get() const
Get the raw C++ pointer to the underlying 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.
std::string getString() const
TEUCHOS_UNIT_TEST(ConstNonconstObjectContainer, create)
const std::string ObjectType_name
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(...) will accept, along with any validators.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
Templated Parameter List class.
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.
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(...) will accept, along with any validators.
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.
TEST_ASSERT(castedDep1->getValuesAndValidators().size()==2)
bool isParameter(const std::string &name) const
Whether the given parameter exists in this list.
std::string docString() const
Return the (optional) documentation std::string.
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.
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(...) will accept, along with any validators.
std::string getString() const
ParameterEntry & getEntry(const std::string &name)
Retrieves an entry with the name name.