00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef TESTSUITE_WHITEBOX_COMPONENT_C_DEFINED
00039 #define TESTSUITE_WHITEBOX_COMPONENT_C_DEFINED
00040
00041 #include "Component/ModelManager.H"
00042 #include "Component/ModelOptionDef.H"
00043 #include "Component/ModelParam.H"
00044 #include "Component/OptionManager.H"
00045 #include "Component/ParamClient.H"
00046 #include "Component/ParamMap.H"
00047 #include "TestSuite/TestSuite.H"
00048 #include "Util/sformat.H"
00049
00050 #include <exception>
00051 #include <vector>
00052
00053 namespace
00054 {
00055
00056
00057 class TestParamClient : public ParamClient
00058 {
00059 public:
00060 bool param_has_registered,
00061 param_has_unregistered,
00062 param_has_changed,
00063 should_reject_changes;
00064
00065 TestParamClient() :
00066 param_has_registered(false),
00067 param_has_unregistered(false),
00068 param_has_changed(false),
00069 should_reject_changes(false) {}
00070
00071 virtual ~TestParamClient() {}
00072
00073 virtual void registerParam(ModelParamBase*)
00074 { param_has_registered = true; }
00075
00076 virtual void registerOptionedParam(OptionedModelParam*, int)
00077 { param_has_registered = true; }
00078
00079 virtual void unregisterParam(const ModelParamBase*)
00080 { param_has_unregistered = true; }
00081
00082 virtual void paramChanged(ModelParamBase* param,
00083 const bool valueChanged,
00084 ParamClient::ChangeStatus* status)
00085 {
00086 param_has_changed = true;
00087 if (should_reject_changes)
00088 *status = ParamClient::CHANGE_REJECTED;
00089 }
00090 };
00091
00092 const ModelOptionDef OPT_testOption =
00093 {
00094 MODOPT_ARG(int),
00095 "testOption",
00096 &MOC_GENERAL,
00097 OPTEXP_CORE,
00098 "this is a test option",
00099 "call-it-like-this",
00100 's',
00101 NULL,
00102 "1"
00103 };
00104
00105 class TestComponent : public ModelComponent
00106 {
00107 public:
00108 TestComponent(OptionManager& m) :
00109 ModelComponent(m, "test", "test") {}
00110 };
00111
00112
00113 class TestComponent2 : public virtual ModelComponent
00114 {
00115 public:
00116 TestComponent2(OptionManager& m) :
00117 ModelComponent(m, "test2", "test2") {}
00118 };
00119
00120 class SlaveComponent : public ModelComponent
00121 {
00122 public:
00123 SlaveComponent(OptionManager& m) :
00124 ModelComponent(m, "slave", "slave"),
00125 itsParam(&OPT_testOption, this)
00126 {}
00127
00128 OModelParam<int> itsParam;
00129 };
00130
00131 class MasterComponent : public ModelComponent
00132 {
00133 public:
00134 MasterComponent(OptionManager& m) :
00135 ModelComponent(m, "master", "master"),
00136 itsSub(new SlaveComponent(m)),
00137 itsParam(&OPT_testOption, this)
00138 {
00139 this->addSubComponent(itsSub);
00140 }
00141
00142 virtual void paramChanged(ModelParamBase* const param,
00143 const bool valueChanged,
00144 ParamClient::ChangeStatus* status)
00145 {
00146 if (param == &itsParam)
00147 {
00148 itsSub->setModelParamString("testOption", "42");
00149 }
00150 }
00151
00152 nub::ref<SlaveComponent> itsSub;
00153
00154 OModelParam<int> itsParam;
00155 };
00156 }
00157
00158 struct WeirdParamType
00159 {
00160 int x;
00161
00162 bool operator==(const WeirdParamType& that) { return this->x == that.x; }
00163 };
00164
00165 void convertFromString(const std::string& str, WeirdParamType& p)
00166 {
00167
00168
00169
00170
00171 p.x = -1;
00172 conversion_error::raise<WeirdParamType>(str);
00173 }
00174
00175 std::string convertToString(const WeirdParamType& p)
00176 {
00177 return convertToString(p.x);
00178 }
00179
00180 static void modelparam_xx_getset_xx_1(TestSuite& suite)
00181 {
00182
00183
00184
00185
00186 TestParamClient client;
00187
00188 NModelParam<int> p1("foo", &client, 1);
00189
00190 p1.setVal(2);
00191 REQUIRE_EQ(p1.getVal(), 2);
00192
00193 p1.setValString("13579");
00194 REQUIRE_EQ(p1.getVal(), 13579);
00195
00196 p1.setVal(-45);
00197 REQUIRE_EQ(p1.getValString(), "-45");
00198
00199
00200
00201
00202 bool caught;
00203
00204 try { caught = false; p1.setValString("abcde"); }
00205 catch (conversion_error& e) { caught = true; }
00206 REQUIRE(caught);
00207
00208 try { caught = false; p1.setValString(""); }
00209 catch (conversion_error& e) { caught = true; }
00210 REQUIRE(caught);
00211 }
00212
00213 static void modelparam_xx_getset_xx_2(TestSuite& suite)
00214 {
00215 TestParamClient client;
00216
00217 WeirdParamType v; v.x = 42;
00218 NModelParam<WeirdParamType> p1("foo", &client, v);
00219
00220 REQUIRE_EQ(p1.getValString(), std::string("42"));
00221
00222 bool caught;
00223 try { caught = false; p1.setValString(""); }
00224 catch (conversion_error& e) { caught = true; }
00225 REQUIRE(caught);
00226
00227
00228
00229 REQUIRE_EQ(p1.getValString(), std::string("42"));
00230 }
00231
00232 static void modelparam_xx_getset_xx_3(TestSuite& suite)
00233 {
00234
00235
00236
00237
00238 TestParamClient client;
00239
00240 NModelParam<int> p1("foo", &client, 0);
00241 REQUIRE_EQ(p1.getVal(), 0);
00242
00243 p1.setVal(1);
00244 REQUIRE_EQ(p1.getVal(), 1);
00245
00246 client.should_reject_changes = true;
00247 p1.setVal(2);
00248
00249
00250 REQUIRE_EQ(p1.getVal(), 1);
00251
00252 client.should_reject_changes = false;
00253 p1.setVal(3);
00254
00255 REQUIRE_EQ(p1.getVal(), 3);
00256 }
00257
00258 static void modelparam_xx_readfrom_xx_1(TestSuite& suite)
00259 {
00260
00261
00262
00263 TestParamClient client;
00264
00265 REQUIRE(!client.param_has_registered);
00266 REQUIRE(!client.param_has_unregistered);
00267 REQUIRE(!client.param_has_changed);
00268
00269 {
00270 NModelParam<int> param("foo", &client, 42);
00271
00272
00273 REQUIRE(client.param_has_registered);
00274 REQUIRE(!client.param_has_unregistered);
00275 REQUIRE(!client.param_has_changed);
00276
00277
00278
00279 ParamMap pmap1;
00280 pmap1.putIntParam("foo", 42);
00281 param.readFrom(pmap1, false);
00282
00283 REQUIRE(client.param_has_registered);
00284 REQUIRE(!client.param_has_unregistered);
00285 REQUIRE(!client.param_has_changed);
00286
00287
00288
00289 ParamMap pmap2;
00290 pmap2.putIntParam("foo", 49);
00291
00292 param.readFrom(pmap2, false);
00293
00294 REQUIRE(client.param_has_registered);
00295 REQUIRE(!client.param_has_unregistered);
00296 REQUIRE(client.param_has_changed);
00297 }
00298
00299
00300
00301
00302 REQUIRE(client.param_has_registered);
00303 REQUIRE(client.param_has_unregistered);
00304 REQUIRE(client.param_has_changed);
00305 }
00306
00307 static void modelparam_xx_writeto_xx_1(TestSuite& suite)
00308 {
00309 TestParamClient client;
00310
00311 NModelParam<double> param("foo", &client, 3.5);
00312
00313 ParamMap pmap;
00314 param.writeTo(pmap);
00315
00316 REQUIRE_EQ(pmap.getDoubleParam("foo", 0.0), 3.5);
00317 }
00318
00319 static void modelmanager_xx_findoptiondef_xx_1(TestSuite& suite)
00320 {
00321 ModelManager m;
00322 m.setOptionValString(&OPT_testOption, "59");
00323 std::string s = std::string("test") + "Option";
00324 REQUIRE(m.findOptionDef(s.c_str()) == &OPT_testOption);
00325 REQUIRE_EQ(m.getOptionValString(&OPT_testOption), "59");
00326 }
00327
00328 static void modelmanager_xx_defaultvalue_xx_1(TestSuite& suite)
00329 {
00330 ModelManager m;
00331
00332 ModelComponent c1(m, "c1", "c1"), c2(m, "c2", "c2");
00333
00334
00335 OModelParam<int> p1(&OPT_testOption, &c1);
00336 REQUIRE_EQ(p1.getVal(), 1);
00337 p1.setVal(5);
00338 REQUIRE_EQ(p1.getVal(), 5);
00339 m.requestOption(p1, false);
00340 REQUIRE_EQ(p1.getVal(), 1);
00341
00342
00343 OModelParam<int> p2(&OPT_testOption, &c2, 6, USE_MY_VAL);
00344 REQUIRE_EQ(p1.getVal(), 1);
00345 REQUIRE_EQ(p2.getVal(), 6);
00346 m.requestOption(p2, true);
00347 REQUIRE_EQ(p1.getVal(), 6);
00348 REQUIRE_EQ(p2.getVal(), 6);
00349
00350 m.setOptionValString(&OPT_testOption, "42");
00351 REQUIRE_EQ(p1.getVal(), 42);
00352 REQUIRE_EQ(p1.getVal(), 42);
00353 }
00354
00355 static void modelcomponent_xx_forbidsharedptr_xx_1(TestSuite& suite)
00356 {
00357 ModelManager m;
00358
00359 bool got_exception = false;
00360 try { rutz::shared_ptr<ModelComponent> p(new TestComponent(m)); }
00361 catch (std::exception& e) { got_exception = true; }
00362
00363 REQUIRE(got_exception);
00364 }
00365
00366 static void modelcomponent_xx_forbidsharedptr_xx_2(TestSuite& suite)
00367 {
00368 ModelManager m;
00369
00370 try { rutz::shared_ptr<ModelComponent> p(new TestComponent2(m)); }
00371 catch (std::exception& e) {}
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 }
00382
00383 static void modelcomponent_xx_root_object_xx_1(TestSuite& suite)
00384 {
00385 ModelManager m;
00386
00387 REQUIRE(m.getRootObject() == &m);
00388 REQUIRE(m.getParent() == 0);
00389
00390 nub::soft_ref<ModelComponent> c1(new TestComponent(m));
00391
00392 REQUIRE(c1->getRootObject() == c1.get());
00393 REQUIRE(c1->getParent() == 0);
00394
00395 m.addSubComponent(c1);
00396
00397 REQUIRE(c1->getRootObject() == &m);
00398 REQUIRE(c1->getParent() == &m);
00399
00400 nub::soft_ref<ModelComponent> c2(new TestComponent2(m));
00401
00402 c1->addSubComponent(c2);
00403
00404 REQUIRE(c2->getRootObject() == &m);
00405 REQUIRE(c2->getParent() == c1.get());
00406 }
00407
00408 #include "Util/Assert.H"
00409
00410 namespace
00411 {
00412 class ReentrantTester : public ModelComponent
00413 {
00414 public:
00415 ReentrantTester(OptionManager& mgr)
00416 :
00417 ModelComponent(mgr, "Reentrant Tester", "ReentrantTester"),
00418 itsOption(&OPT_testOption, this)
00419 {}
00420
00421 virtual void paramChanged(ModelParamBase* const param,
00422 const bool valueChanged,
00423 ParamClient::ChangeStatus* status)
00424 {
00425 if (param == &itsOption)
00426 {
00427 for (int i = 0; i < 10000; ++i)
00428 {
00429 itsNewParams.push_back
00430 (NModelParam<int>::make(sformat("foo%d", i), this, i));
00431 }
00432 }
00433 }
00434
00435 OModelParam<int> itsOption;
00436 std::vector<rutz::shared_ptr<NModelParam<int> > > itsNewParams;
00437 };
00438 }
00439
00440 static void modelcomponent_xx_reentrant_pinfos_xx_1(TestSuite& suite)
00441 {
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 ModelManager m;
00454
00455 nub::ref<ReentrantTester> r(new ReentrantTester(m));
00456
00457 m.addSubComponent(r);
00458
00459 m.exportOptions(MC_RECURSE);
00460
00461 REQUIRE_EQ(r->getNumModelParams(), size_t(10001));
00462 }
00463
00464 static void modelcomponent_xx_master_slave_export_xx_1(TestSuite& suite)
00465 {
00466 ModelManager m;
00467 nub::ref<MasterComponent> master(new MasterComponent(m));
00468 m.addSubComponent(master);
00469 m.exportOptions(MC_RECURSE);
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 REQUIRE_EQ(master->itsSub->itsParam.getVal(), 42);
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 int main(int argc, const char** argv)
00489 {
00490 TestSuite suite;
00491
00492 suite.ADD_TEST(modelparam_xx_getset_xx_1);
00493 suite.ADD_TEST(modelparam_xx_getset_xx_2);
00494 suite.ADD_TEST(modelparam_xx_getset_xx_3);
00495 suite.ADD_TEST(modelparam_xx_readfrom_xx_1);
00496 suite.ADD_TEST(modelparam_xx_writeto_xx_1);
00497 suite.ADD_TEST(modelmanager_xx_findoptiondef_xx_1);
00498 suite.ADD_TEST(modelmanager_xx_defaultvalue_xx_1);
00499 #if defined(GVX_MEM_DEBUG)
00500 suite.ADD_TEST(modelcomponent_xx_forbidsharedptr_xx_1);
00501 suite.ADD_TEST(modelcomponent_xx_forbidsharedptr_xx_2);
00502 #else
00503
00504 (void) &modelcomponent_xx_forbidsharedptr_xx_1;
00505 (void) &modelcomponent_xx_forbidsharedptr_xx_2;
00506 #endif
00507 suite.ADD_TEST(modelcomponent_xx_root_object_xx_1);
00508
00509 suite.ADD_TEST(modelcomponent_xx_reentrant_pinfos_xx_1);
00510
00511 suite.ADD_TEST(modelcomponent_xx_master_slave_export_xx_1);
00512
00513 suite.parseAndRun(argc, argv);
00514
00515 return 0;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524 #endif // TESTSUITE_WHITEBOX_COMPONENT_C_DEFINED