|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #include "Teuchos_ObjectBuilder.hpp" 00030 #include "Teuchos_ParameterList.hpp" 00031 #include "Teuchos_ParameterListAcceptorHelpers.hpp" 00032 00033 #include "Teuchos_UnitTestHarness.hpp" 00034 00035 namespace Teuchos { 00036 00037 const std::string ObjectType_name = "Foo Type"; 00038 00039 class Foo : virtual public ParameterListAcceptor { 00040 public: 00041 Foo() {} 00042 virtual ~Foo() {} 00043 virtual std::string getString() const =0; 00044 virtual void setDefaults() =0; 00045 void setParameterList(const RCP<ParameterList> & paramList) { 00046 if (!is_null(paramList)) { 00047 paramList->validateParameters(*this->getValidParameters()); 00048 paramList_ = paramList; 00049 } 00050 setDefaults(); 00051 } 00052 RCP<ParameterList> getNonconstParameterList() { 00053 return paramList_; 00054 } 00055 RCP<ParameterList> unsetParameterList() { 00056 RCP<ParameterList> pl = paramList_; 00057 paramList_ = null; 00058 return pl; 00059 } 00060 RCP<const ParameterList> getParameterList() const { 00061 return paramList_; 00062 } 00063 private: 00064 RCP<ParameterList> paramList_; 00065 }; 00066 class FooA : virtual public Foo { 00067 public: 00068 FooA() { 00069 setDefaults(); 00070 } 00071 virtual ~FooA() {} 00072 std::string getString() const { 00073 return foo_; 00074 } 00075 void setDefaults() { 00076 RCP<ParameterList> pl = this->getNonconstParameterList(); 00077 if (is_null(pl)) { 00078 foo_ = "A"; 00079 } else { 00080 foo_ = pl->get("String",foo_); 00081 } 00082 } 00083 RCP<const ParameterList> getValidParameters() const { 00084 static RCP<ParameterList> validPL; 00085 if (is_null(validPL)) { 00086 RCP<ParameterList> pl = parameterList(); 00087 pl->set( "String", foo_ ); 00088 validPL = pl; 00089 } 00090 return validPL; 00091 } 00092 private: 00093 std::string foo_; 00094 }; 00095 class FooB : virtual public Foo { 00096 public: 00097 FooB() { 00098 setDefaults(); 00099 } 00100 virtual ~FooB() {} 00101 std::string getString() const { 00102 return foo_; 00103 } 00104 void setDefaults() { 00105 RCP<ParameterList> pl = this->getNonconstParameterList(); 00106 if (is_null(pl)) { 00107 foo_ = "B"; 00108 } else { 00109 foo_ = pl->get("String",foo_); 00110 } 00111 } 00112 RCP<const ParameterList> getValidParameters() const { 00113 static RCP<ParameterList> validPL; 00114 if (is_null(validPL)) { 00115 RCP<ParameterList> pl = parameterList(); 00116 pl->set( "String", foo_ ); 00117 validPL = pl; 00118 } 00119 return validPL; 00120 } 00121 private: 00122 std::string foo_; 00123 }; 00124 class FooC : virtual public Foo { 00125 public: 00126 FooC() { 00127 setDefaults(); 00128 } 00129 virtual ~FooC() {} 00130 std::string getString() const { 00131 return foo_; 00132 } 00133 void setDefaults() { 00134 RCP<ParameterList> pl = this->getNonconstParameterList(); 00135 if (is_null(pl)) { 00136 foo_ = "C"; 00137 } else { 00138 foo_ = pl->get("String",foo_); 00139 } 00140 } 00141 RCP<const ParameterList> getValidParameters() const { 00142 static RCP<ParameterList> validPL; 00143 if (is_null(validPL)) { 00144 RCP<ParameterList> pl = parameterList(); 00145 pl->set( "String", foo_ ); 00146 validPL = pl; 00147 } 00148 return validPL; 00149 } 00150 private: 00151 std::string foo_; 00152 }; 00153 00154 // The following happens at construction: 00155 // 1. initializeDefaults_ is called 00156 // a) object_name_ = "Object" 00157 // b) objectType_name_ = "Object Type" 00158 // c) defaultObject_ = "None" 00159 // d) validObjectNames_ just has "None" 00160 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, constructor) { 00161 RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00162 TEST_EQUALITY_CONST( ob->getObjectName(), "None" ); 00163 TEST_EQUALITY_CONST( ob->create(), null ); 00164 RCP<const ParameterList> pl; 00165 TEST_NOTHROW( pl = ob->getValidParameters() ); 00166 TEST_EQUALITY_CONST( pl->get<std::string>("Object Type"), "None" ); 00167 TEST_NOTHROW( ob = null ); 00168 } 00169 00170 // Tests setObjectName and setObectTypeName 00171 // Note: it should throw an exception if the string is "" 00172 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setNames) { 00173 { 00174 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00175 TEST_THROW( ob->setObjectName(""), std::logic_error ); 00176 TEST_THROW( ob->setObjectTypeName(""), std::logic_error ); 00177 } 00178 { 00179 RCP<ObjectBuilder<Foo> > ob; 00180 TEST_THROW( ob = objectBuilder<Foo>("","Foo Type"), std::logic_error ); 00181 TEST_THROW( ob = objectBuilder<Foo>("Foo",""), std::logic_error ); 00182 TEST_THROW( ob = objectBuilder<Foo>("",""), std::logic_error ); 00183 } 00184 { 00185 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00186 ob->setObjectName("Foo"); 00187 ob->setObjectTypeName("Foo Type"); 00188 const RCP<const ParameterList> validpl = ob->getValidParameters(); 00189 // Now we check that the parameterlist is correct 00190 TEST_EQUALITY_CONST( validpl->get<std::string>("Foo Type"), "None" ); 00191 const ParameterEntry pe = validpl->getEntry("Foo Type"); 00192 TEST_EQUALITY_CONST( pe.docString(), 00193 "Determines the type of Foo object that will be built.\nThe parameters for each Foo Type are specified in this sublist" 00194 ); 00195 } 00196 { 00197 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00198 const RCP<const ParameterList> validpl = ob->getValidParameters(); 00199 // Now we check that the parameterlist is correct 00200 TEST_EQUALITY_CONST( validpl->get<std::string>("Foo Type"), "None" ); 00201 const ParameterEntry pe = validpl->getEntry("Foo Type"); 00202 TEST_EQUALITY_CONST( pe.docString(), 00203 "Determines the type of Foo object that will be built.\nThe parameters for each Foo Type are specified in this sublist" 00204 ); 00205 } 00206 } 00207 00208 // setObjectFactory does four things: 00209 // 1. adds a new object name 00210 // 1a. if object name is "" it throws an exception 00211 // 2. adds a new object factory 00212 // 3. sets defaultObject_ 00213 // 4. deletes the validParamList_ 00214 // 00215 // Notes about how to sense the changes: 00216 // 1. The new object name is appended to the list of valid names and shows up in the valid parameter list 00217 // 2. The new object factory is appended to the list of factories and is only accessible through create 00218 // 3. The default Object is accessible through both getObjectName and the valid parameter list. 00219 // 4. The validParameterList is deleted and this can only be sensed through calling getValidParameters 00220 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setObjectFactory) { 00221 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00222 TEST_EQUALITY_CONST( ob->getObjectName(), "None" ); 00223 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00224 TEST_EQUALITY_CONST( ob->getObjectName(), "Foo A" ); // 3. 00225 RCP<const ParameterList> pl = ob->getValidParameters(); 00226 TEST_EQUALITY_CONST( pl->get<std::string>("Foo Type"), "Foo A" ); // 1. 00227 TEST_EQUALITY_CONST( pl->sublist("Foo A").get<std::string>("String"), "A" ); // 1. 00228 const RCP<Foo> foo = ob->create(); 00229 const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false); 00230 TEST_EQUALITY_CONST( is_null(fooA), false ); // 2. 00231 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00232 pl = ob->getValidParameters(); 00233 TEST_EQUALITY_CONST( pl->get<std::string>("Foo Type"), "Foo B" ); // 4. 00234 TEST_THROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),""), std::logic_error ); // 1a. 00235 } 00236 00237 // We shouldn't be able to set two factories with the same name. 00238 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setObjectFactory_bad ) { 00239 { 00240 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00241 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00242 // ObjectBuilder will let you add the object, but will not throw until getValidParameters is called 00243 #ifdef TEUCHOS_DEBUG 00244 TEST_THROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"), std::logic_error ); 00245 #else // TEUCHOS_DEBUG 00246 TEST_NOTHROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A") ); 00247 TEST_THROW( ob->getValidParameters(), std::logic_error ); 00248 #endif // TEUCHOS_DEBUG 00249 } 00250 { 00251 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00252 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00253 TEST_NOTHROW( ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"New Foo A") ); 00254 TEST_NOTHROW( ob->getValidParameters() ); 00255 } 00256 } 00257 00258 // getObjectName returns the default in the parameter list (if given), or the 00259 // default in the valid parameter list (if no parameter list is given) 00260 // 1. no parameter list is given, uses default in valid parameter list. 00261 // 2. parameter list is given, and uses its default 00262 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getObjectName) { 00263 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo", "Foo Type"); 00264 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00265 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00266 const RCP<ParameterList> pl = parameterList(); 00267 pl->setParameters(*ob->getValidParameters()); // copy parameters 00268 pl->set("Foo Type", "Foo A"); // change default 00269 // 1. 00270 TEST_EQUALITY_CONST( ob->getObjectName(), "Foo B" ); 00271 // 2. 00272 ob->setParameterList(pl); 00273 TEST_EQUALITY_CONST( ob->getObjectName(), "Foo A" ); 00274 } 00275 00276 // create has many cases 00277 // 1. It should return a null RCP if no factories are set 00278 // 2. It should return a null RCP if "Object Type" is set to "None" in the provided parameterList 00279 // 3. It should return the correct object consistent with the "Object Type" setting in the parameterList if no string is passed 00280 // 3a. It should return the correct object consistent with the "Object Type" 00281 // setting in the valid parameterList if no string is passed and no 00282 // parameterList is provided. 00283 // 4. It should return the correct object consistent with the input string regardless of the parameterLists 00284 // 4a. It should throw an exception if an invalid input string is provided 00285 // 5. If no parameter list is provided, then it will use the valid parameter list to set parameters on the object 00286 // 5a. If a parameter list is provided, then it will use that parameter list to set parameters on the object 00287 // 6. It will throw an exception with a nice message if the factory creates a null RCP 00288 // Under what conditions could this happen? 00289 // 7. [03/05/09 tscoffe: found bug] create() uses objectValidator_, so 00290 // getValidParameters must be valid at the beginning to avoid a null 00291 // dereference of the objectValidator_ pointer in the case that we ask for an 00292 // object by name and the validParamList_ has not been set up yet. 00293 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, create) { 00294 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo", "Foo Type"); 00295 TEST_EQUALITY_CONST( ob->create("None"), null ); // 7. 00296 TEST_EQUALITY_CONST( ob->create(), null ); // 1. 00297 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00298 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00299 ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C"); 00300 out << "op.getValidParamters():\n"; 00301 printValidParameters(*ob, out); 00302 const RCP<ParameterList> pl = parameterList(); 00303 pl->setParameters(*ob->getValidParameters()); 00304 pl->set("Foo Type","None"); 00305 ob->setParameterList(pl); 00306 TEST_EQUALITY_CONST( ob->create(), null ); // 2. 00307 pl->set("Foo Type", "Foo B"); 00308 pl->sublist("Foo B").set("String","BB"); 00309 pl->sublist("Foo C").set("String","CC"); 00310 { 00311 const RCP<Foo> foo = ob->create(); 00312 const RCP<FooB> fooB = rcp_dynamic_cast<FooB>(foo,false); 00313 TEST_EQUALITY_CONST( is_null(fooB), false ); // 3. 00314 TEST_EQUALITY_CONST( foo->getString(), "BB" ); // 5a. 00315 } 00316 ob->unsetParameterList(); 00317 { 00318 const RCP<Foo> foo = ob->create(); 00319 const RCP<FooC> fooC = rcp_dynamic_cast<FooC>(foo,false); 00320 TEST_EQUALITY_CONST( is_null(fooC), false ); // 3a. 00321 TEST_EQUALITY_CONST( foo->getString(), "C" ); // 5. 00322 } 00323 { 00324 const RCP<Foo> foo = ob->create("Foo A"); 00325 const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false); 00326 TEST_EQUALITY_CONST( is_null(fooA), false ); // 4. 00327 } 00328 ob->setParameterList(pl); 00329 { 00330 const RCP<Foo> foo = ob->create("Foo A"); 00331 const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false); 00332 TEST_EQUALITY_CONST( is_null(fooA), false ); // 4. 00333 } 00334 { 00335 RCP<Foo> foo; 00336 TEST_THROW( foo = ob->create("Foo D"), std::logic_error ); // 4a. 00337 } 00338 // 6. ??? 00339 } 00340 00341 // There are many places that the parameter list is validated to ensure that we 00342 // catch invalid parameter lists before we use them. This is particularly 00343 // important because we're storing a pointer to the parameter list and the user 00344 // can change it without ObjectBuilder knowing about it. 00345 // The parameter list is validated in four places: 00346 // 1. setParameterList 00347 // 2. unsetParameterList (only in debug mode) 00348 // 3. create (only in debug mode) 00349 // 4. destructor (only in debug mode) 00350 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setParameterList) { 00351 RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00352 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00353 RCP<ParameterList> pl = null; 00354 TEST_NOTHROW( ob->setParameterList(pl) ); 00355 pl = parameterList(); 00356 TEST_NOTHROW( ob->setParameterList(pl) ); 00357 pl->set("Hello","World"); 00358 TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 1. 00359 #ifdef TEUCHOS_DEBUG 00360 TEST_THROW( ob->unsetParameterList(), std::logic_error ); // 2. 00361 TEST_THROW( ob->create(), std::logic_error ); // 3. 00362 TEST_THROW( ob = null, std::logic_error ); // 4. 00363 #else // TEUCHOS_DEBUG 00364 TEST_NOTHROW( ob->unsetParameterList() ); 00365 RCP<Foo> foo; 00366 TEST_NOTHROW( foo = ob->create() ); 00367 const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false); 00368 TEST_EQUALITY_CONST( is_null(fooA), false ); 00369 TEST_NOTHROW( ob = null ); 00370 #endif // TEUCHOS_DEBUG 00371 } 00372 00373 // Here we test 00374 // 1. That it returns a null RCP before we give it a parameter list. 00375 // 2. That we can set up a valid parameter list, give it to the ObjectBuilder, and get it back out. 00376 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getParameterList) { 00377 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00378 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00379 const RCP<const ParameterList> pl = ob->getParameterList(); 00380 TEST_EQUALITY_CONST( is_null(pl), true ); // 1. 00381 const RCP<ParameterList> nonconstPL = parameterList(); 00382 nonconstPL->set("Object Type","None"); 00383 TEST_NOTHROW( ob->setParameterList(nonconstPL) ); 00384 { 00385 const RCP<const ParameterList> newPL = ob->getParameterList(); 00386 TEST_EQUALITY_CONST( nonconstPL.get(), newPL.get() ); // 2. 00387 } 00388 } 00389 00390 // Same as getParameterList 00391 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getNonconstParameterList) { 00392 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00393 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00394 RCP<ParameterList> pl = ob->getNonconstParameterList(); 00395 TEST_EQUALITY_CONST( is_null(pl), true ); 00396 pl = parameterList(); 00397 pl->set("Object Type","None"); 00398 TEST_NOTHROW( ob->setParameterList(pl) ); 00399 { 00400 RCP<ParameterList> newPL = null; 00401 newPL = ob->getNonconstParameterList(); 00402 TEST_EQUALITY_CONST( pl.get(), newPL.get() ); 00403 } 00404 } 00405 00406 // Here we're checking: 00407 // 1. That we can set a parameter list on it and it uses it and then we can 00408 // unset it and it goes back to using the valid parameter list. 00409 // 1a. We get back the same parameter list we set 00410 // 2. In debug mode, the parameter list is validated when unsetParameterList 00411 // is called. 00412 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, unsetParameterList) { 00413 RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00414 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00415 const RCP<ParameterList> pl = parameterList(); 00416 pl->set("Object Type","None"); 00417 ob->setParameterList(pl); 00418 RCP<Foo> foo = ob->create(); 00419 TEST_EQUALITY_CONST( is_null(foo), true ); 00420 RCP<ParameterList> newPL = ob->unsetParameterList(); 00421 TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a. 00422 foo = ob->create(); 00423 const RCP<FooA> fooA = rcp_dynamic_cast<FooA>(foo,false); 00424 TEST_EQUALITY_CONST( is_null(fooA), false ); // 1. 00425 ob->setParameterList(pl); 00426 pl->set("Hello","World"); 00427 newPL = null; 00428 #ifdef TEUCHOS_DEBUG 00429 TEST_THROW( newPL = ob->unsetParameterList(), std::logic_error ); // 2. 00430 TEST_EQUALITY_CONST( is_null(newPL), true ); 00431 TEST_THROW( ob = null, std::logic_error ); 00432 #else // TEUCHOS_DEBUG 00433 TEST_NOTHROW( newPL = ob->unsetParameterList() ); 00434 TEST_EQUALITY_CONST( pl.get(), newPL.get() ); // 1a. 00435 TEST_NOTHROW( ob = null ); 00436 #endif // TEUCHOS_DEBUG 00437 } 00438 00439 // This function does several things. 00440 // 1. It creates the validParameterList whenever it is deleted [already tested in setObjectFactory] 00441 // 2. It creates the objectValidator 00442 // 3. It adds a docstring to the "Object Type" parameter in the parameter list [already tested in setNames] 00443 // 4. It fills the parameter list out with the valid parameteres for each object it can create 00444 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, getValidParameters) { 00445 { 00446 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00447 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00448 const RCP<ParameterList> pl = parameterList(); 00449 pl->set("Object Type","Foo B"); 00450 TEST_THROW( ob->setParameterList(pl), std::logic_error ); // 2. 00451 } 00452 { 00453 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>(); 00454 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00455 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo B"); 00456 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo C"); 00457 const RCP<ParameterList> validPL = parameterList(); 00458 validPL->set("Object Type","Foo C"); 00459 validPL->sublist("Foo A").set("String","A"); 00460 validPL->sublist("Foo B").set("String","B"); 00461 validPL->sublist("Foo C").set("String","C"); 00462 Array<std::string> validObjectNames; 00463 validObjectNames.push_back("None"); 00464 validObjectNames.push_back("Foo A"); 00465 validObjectNames.push_back("Foo B"); 00466 validObjectNames.push_back("Foo C"); 00467 const RCP<const StringToIntegralParameterEntryValidator<int> > 00468 objectValidator = rcp( 00469 new StringToIntegralParameterEntryValidator<int>( 00470 validObjectNames,"Object Type" 00471 ) 00472 ); 00473 validPL->set( 00474 "Object Type","Foo C" 00475 ,(std::string("Determines the type of Object object that will be built.\n") 00476 + "The parameters for each Object Type are specified in this sublist" 00477 ).c_str() 00478 ,objectValidator 00479 ); 00480 const RCP<const ParameterList> pl = ob->getValidParameters(); 00481 TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4. 00482 validPL->set("Object Type","Foo A"); 00483 TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4. 00484 validPL->set("Object Type","Foo B"); 00485 TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4. 00486 validPL->set("Object Type","None"); 00487 TEST_NOTHROW( pl->validateParameters(*validPL) ); // 4. 00488 } 00489 } 00490 00491 // Now we verify that the parameter lists are coming out with Used parameters in the correct state 00492 // 1. Pass in empty parameter list and create an object. We should get a 00493 // sublist and used parameters on the sublist for the object we created, but no 00494 // other sublists. 00495 // 2. Pass in a full parameter list and create an object. We should get 00496 // used parameters for only the sublist of the object we created. 00497 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, usedParameters) { 00498 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00499 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00500 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00501 ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C"); 00502 { 00503 const RCP<ParameterList> pl = parameterList(); 00504 ob->setParameterList(pl); 00505 const RCP<Foo> foo = ob->create("Foo A"); 00506 TEST_EQUALITY_CONST( foo->getString(), "A" ); 00507 TEST_EQUALITY_CONST( pl->isSublist("Foo A"), true ); // 1. 00508 TEST_EQUALITY_CONST( pl->sublist("Foo A").isParameter("String"), true ); // 1. 00509 const ParameterEntry& pe = pl->sublist("Foo A").getEntry("String"); 00510 TEST_EQUALITY_CONST( pe.isUsed(), true ); // 1. 00511 TEST_EQUALITY_CONST( pe.isDefault(), true ); // 1. 00512 // verify the other sublists are missing 00513 TEST_EQUALITY_CONST( pl->isSublist("Foo B"), false ); // 1. 00514 TEST_EQUALITY_CONST( pl->isSublist("Foo C"), false ); // 1. 00515 ob->unsetParameterList(); 00516 } 00517 { 00518 RCP<ParameterList> pl = parameterList(); 00519 pl->setParameters(*ob->getValidParameters()); 00520 pl->sublist("Foo A").set("String","AA"); 00521 ob->setParameterList(pl); 00522 pl = null; 00523 const RCP<Foo> foo = ob->create("Foo A"); 00524 TEST_EQUALITY_CONST( foo->getString(), "AA" ); 00525 const RCP<const ParameterList> outPL = ob->getParameterList(); 00526 TEST_EQUALITY_CONST( outPL->isSublist("Foo A"), true ); 00527 TEST_EQUALITY_CONST( outPL->sublist("Foo A").isParameter("String"), true ); 00528 const ParameterEntry& pe = outPL->sublist("Foo A").getEntry("String"); 00529 TEST_EQUALITY_CONST( pe.isUsed(), true ); // 2. 00530 TEST_EQUALITY_CONST( pe.isDefault(), false ); // 2. 00531 // verify the other sublists are unused 00532 TEST_EQUALITY_CONST( outPL->sublist("Foo B").getEntry("String").isUsed(), false ); // 2. 00533 TEST_EQUALITY_CONST( outPL->sublist("Foo C").getEntry("String").isUsed(), false ); // 2. 00534 ob->unsetParameterList(); 00535 } 00536 } 00537 00538 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withOneUsePL ) { 00539 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00540 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00541 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00542 ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C"); 00543 { 00544 const RCP<ParameterList> pl = parameterList(); 00545 ob->setParameterList(pl); 00546 const RCP<Foo> foo = ob->create(); 00547 RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false); 00548 TEST_ASSERT( !is_null(fooC) ); 00549 } 00550 { 00551 const RCP<ParameterList> pl = parameterList(); 00552 ob->setParameterList(pl); 00553 ob->setDefaultObject("Foo A"); 00554 const RCP<Foo> foo = ob->create(); 00555 RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false); 00556 TEST_ASSERT( !is_null(fooA) ); 00557 } 00558 { 00559 const RCP<ParameterList> pl = parameterList(); 00560 ob->setParameterList(pl); 00561 ob->setDefaultObject("None"); 00562 const RCP<Foo> foo = ob->create(); 00563 TEST_ASSERT( is_null(foo) ); 00564 } 00565 { 00566 #ifdef TEUCHOS_DEBUG 00567 TEST_THROW(ob->setDefaultObject("Foo D"), std::logic_error); 00568 #else 00569 ob->setDefaultObject("Foo D"); 00570 TEST_THROW(ob->getValidParameters(), std::logic_error); 00571 #endif // TEUCHOS_DEBUG 00572 } 00573 } 00574 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withMultipleUsePL ) { 00575 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00576 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00577 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00578 ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C"); 00579 const RCP<ParameterList> pl = parameterList(); 00580 ob->setParameterList(pl); 00581 { 00582 const RCP<Foo> foo = ob->create(); 00583 RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false); 00584 TEST_ASSERT( !is_null(fooC) ); 00585 // Note: At this point, pl contains "Foo Type = Foo C" 00586 // And this pl was set on the ObjectBuilder, so defaultObject does no good. 00587 } 00588 { 00589 ob->setDefaultObject("Foo A"); 00590 const RCP<Foo> foo = ob->create(); 00591 RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false); 00592 TEST_ASSERT( is_null(fooA) ); 00593 } 00594 { 00595 ob->setDefaultObject("None"); 00596 const RCP<Foo> foo = ob->create(); 00597 TEST_ASSERT( !is_null(foo) ); 00598 } 00599 } 00600 00601 TEUCHOS_UNIT_TEST( Teuchos_ObjectBuilder, setDefaultObject_withoutPL ) { 00602 const RCP<ObjectBuilder<Foo> > ob = objectBuilder<Foo>("Foo","Foo Type"); 00603 ob->setObjectFactory(abstractFactoryStd<Foo,FooA>(),"Foo A"); 00604 ob->setObjectFactory(abstractFactoryStd<Foo,FooB>(),"Foo B"); 00605 ob->setObjectFactory(abstractFactoryStd<Foo,FooC>(),"Foo C"); 00606 { 00607 const RCP<Foo> foo = ob->create(); 00608 RCP<FooC> fooC = Teuchos::rcp_dynamic_cast<FooC>(foo,false); 00609 TEST_ASSERT( !is_null(fooC) ); 00610 } 00611 { 00612 ob->setDefaultObject("Foo A"); 00613 const RCP<Foo> foo = ob->create(); 00614 RCP<FooA> fooA = Teuchos::rcp_dynamic_cast<FooA>(foo,false); 00615 TEST_ASSERT( !is_null(fooA) ); 00616 } 00617 { 00618 ob->setDefaultObject("None"); 00619 const RCP<Foo> foo = ob->create(); 00620 TEST_ASSERT( is_null(foo) ); 00621 } 00622 } 00623 00624 } // namespace Teuchos 00625 00626 00627
1.7.4