ObjectBuilder_UnitTests.cpp

Go to the documentation of this file.
00001 //@HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Teuchos Package
00005 //                 Copyright (2006) 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 Todd S. Coffey (tscoffe@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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Tue Oct 20 10:13:59 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1