Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
48namespace Teuchos {
49
50const std::string ObjectType_name = "Foo Type";
51
52class 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 }
64 }
66 return paramList_;
67 }
71 return pl;
72 }
74 return paramList_;
75 }
76 private:
78};
79class FooA : virtual public Foo {
80 public:
81 FooA() {
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};
108class FooB : virtual public Foo {
109 public:
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};
137class FooC : virtual public Foo {
138 public:
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"
173TEUCHOS_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 ""
185TEUCHOS_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
233TEUCHOS_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.
251TEUCHOS_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
275TEUCHOS_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.
306TEUCHOS_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)
364TEUCHOS_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.
398TEUCHOS_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
413TEUCHOS_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.
436TEUCHOS_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
469TEUCHOS_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.
522TEUCHOS_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
563TEUCHOS_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}
599TEUCHOS_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
626TEUCHOS_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
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
#define TEST_NOTHROW(code)
Asserr that the statement 'code' does not thrown any excpetions.
#define TEST_THROW(code, ExceptType)
Assert that the statement 'code' throws the exception 'ExceptType' (otherwise the test fails).
Templated Parameter List class.
Unit testing support.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
void push_back(const value_type &x)
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(....
std::string getString() const
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(....
std::string getString() const
RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(....
std::string getString() const
RCP< ParameterList > unsetParameterList()
Unset the parameter list that was set using setParameterList().
virtual void setDefaults()=0
RCP< const ParameterList > getParameterList() const
Get const version of the parameter list that was set using setParameterList().
RCP< ParameterList > getNonconstParameterList()
Get a nonconst version of the parameter list that was set using setParameterList().
void setParameterList(const RCP< ParameterList > &paramList)
Set parameters from a parameter list and return with default values.
RCP< ParameterList > paramList_
virtual std::string getString() const =0
This object is held as the "value" in the Teuchos::ParameterList std::map.
bool isUsed() const
Return whether or not the value has been used; i.e., whether or not the value has been retrieved via ...
std::string docString() const
Return the (optional) documentation std::string.
bool isDefault() const
Indicate whether this entry takes on the default value.
Interface for objects that can accept a ParameterList.
virtual RCP< const ParameterList > getValidParameters() const
Return a ParameterList containing all of the valid parameters that this->setParameterList(....
Smart reference counting pointer class for automatic garbage collection.
T * get() const
Get the raw C++ pointer to the underlying object.
Standard implementation of a ParameterEntryValidator that maps from a list of strings to an enum or i...
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
const std::string ObjectType_name
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.