00001 #include <boost/test/auto_unit_test.hpp>
00002
00003 #include <lang/csupport/standard_types.hh>
00004
00005 #include <test/testsuite.hh>
00006 #include <typelib/typemodel.hh>
00007 #include <typelib/typename.hh>
00008 #include <typelib/registry.hh>
00009 #include <typelib/typedisplay.hh>
00010 #include <typelib/registryiterator.hh>
00011 #include <typelib/pluginmanager.hh>
00012 using namespace Typelib;
00013
00014 BOOST_AUTO_TEST_CASE( test_typename_validation )
00015 {
00016 BOOST_CHECK(!isValidTypename("std::string", false));
00017 BOOST_CHECK(!isValidTypename("std::string", true));
00018 BOOST_CHECK(!isValidTypename("/std/string<double>", false));
00019 BOOST_CHECK(isValidTypename("/std/string</double>", false));
00020 BOOST_CHECK(isValidTypename("/std/string</double>", true));
00021 BOOST_CHECK(!isValidTypename("std/string<double>", false));
00022 BOOST_CHECK(isValidTypename("std/string</double>", false));
00023 BOOST_CHECK(!isValidTypename("std/string</double>", true));
00024
00025 BOOST_CHECK(isValidTypename("/std/string</double,9,/std/string>", true));
00026 BOOST_CHECK(isValidTypename("/std/string<3>", true));
00027
00028 BOOST_CHECK(isValidTypename("/double[3]", true));
00029 BOOST_CHECK(isValidTypename("/std/string</double[3]>", true));
00030 BOOST_CHECK(isValidTypename("/wrappers/Matrix</double,3,1>/Scalar", true));
00031 BOOST_CHECK(isValidTypename("/std/vector</wrappers/Matrix</double,3,1>>", true));
00032 BOOST_CHECK(isValidTypename("/std/vector</wrappers/Matrix</double,3,1>>[4]", true));
00033
00034 BOOST_CHECK(isValidTypename("s", false));
00035 BOOST_CHECK(!isValidTypename(":blabla", false));
00036 }
00037
00038 BOOST_AUTO_TEST_CASE( test_typename_is_in_namespace )
00039 {
00040 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/C" , false));
00041 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/C/" , false));
00042 BOOST_CHECK(!isInNamespace("/B/B/Type" , "/B/A" , false));
00043 BOOST_CHECK(!isInNamespace("/B/B/Type" , "/B/A/" , false));
00044 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/B/C" , false));
00045 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/B/C/" , false));
00046 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/C" , true));
00047 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/C/" , true));
00048 BOOST_CHECK(!isInNamespace("/B/B/Type" , "/B/A" , true));
00049 BOOST_CHECK(!isInNamespace("/B/B/Type" , "/B/A/" , true));
00050 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/B/C" , true));
00051 BOOST_CHECK(!isInNamespace("/A/B/Type" , "/A/B/C/" , true));
00052
00053 BOOST_CHECK(!isInNamespace("/A/B/C/Type" , "/A/B" , false));
00054 BOOST_CHECK(!isInNamespace("/A/B/C/Type" , "/A/B/" , false));
00055 BOOST_CHECK( isInNamespace("/A/B/Type" , "/A/B" , false));
00056 BOOST_CHECK( isInNamespace("/A/B/Type" , "/A/B/" , false));
00057 BOOST_CHECK( isInNamespace("/A/B/C/Type" , "/A/B" , true));
00058 BOOST_CHECK( isInNamespace("/A/B/C/Type" , "/A/B/" , true));
00059 BOOST_CHECK( isInNamespace("/A/B/Type" , "/A/B" , true));
00060 BOOST_CHECK( isInNamespace("/A/B/Type" , "/A/B/" , true));
00061 }
00062
00063 BOOST_AUTO_TEST_CASE( test_typename_manipulation )
00064 {
00065 BOOST_CHECK_EQUAL("/NS2/", getNormalizedNamespace("/NS2"));
00066 BOOST_CHECK_EQUAL("/NS2/", getNormalizedNamespace("/NS2/"));
00067 BOOST_CHECK_EQUAL("NS2/", getNormalizedNamespace("NS2/"));
00068 BOOST_CHECK_EQUAL("NS2/", getNormalizedNamespace("NS2"));
00069
00070 BOOST_CHECK_EQUAL("NS3/Test", getRelativeName("/NS2/NS3/Test", "/NS2"));
00071
00072 BOOST_CHECK_EQUAL("/NS2/NS3/", getNamespace("/NS2/NS3/Test"));
00073 BOOST_CHECK_EQUAL("/wrappers/Matrix</double,3,1>/", getNamespace("/wrappers/Matrix</double,3,1>/Scalar"));
00074 BOOST_CHECK_EQUAL("Scalar", getTypename("/wrappers/Matrix</double,3,1>/Scalar"));
00075 BOOST_CHECK_EQUAL("/wrappers/Matrix</double,3,1>/Gaussian</double,3>/", getNamespace("/wrappers/Matrix</double,3,1>/Gaussian</double,3>/Scalar"));
00076 BOOST_CHECK_EQUAL("Scalar", getTypename("/wrappers/Matrix</double,3,1>/Gaussian</double,3>/Scalar"));
00077 BOOST_CHECK_EQUAL("/std/", getNamespace("/std/vector</wrappers/Matrix</double,3,1>>"));
00078
00079 BOOST_CHECK_EQUAL("Test", getTypename("/NS2/NS3/Test"));
00080 BOOST_CHECK_EQUAL("Scalar", getTypename("/wrappers/Matrix</double,3,1>/Scalar"));
00081 BOOST_CHECK_EQUAL("vector</wrappers/Matrix</double,3,1>>", getTypename("/std/vector</wrappers/Matrix</double,3,1>>"));
00082 }
00083
00084 BOOST_AUTO_TEST_CASE( test_typename_path_to )
00085 {
00086 BOOST_CHECK_EQUAL("B/", getMinimalPathTo("/A/B/Type", "/A/C"));
00087 BOOST_CHECK_EQUAL("B/", getMinimalPathTo("/A/B/Type", "/A/C/"));
00088 BOOST_CHECK_EQUAL("B/B/", getMinimalPathTo("/B/B/Type", "/B/A"));
00089 BOOST_CHECK_EQUAL("B/B/", getMinimalPathTo("/B/B/Type", "/B/A/"));
00090 BOOST_CHECK_EQUAL("/A/B/", getMinimalPathTo("/A/B/Type", "/A/B/C"));
00091 BOOST_CHECK_EQUAL("/A/B/", getMinimalPathTo("/A/B/Type", "/A/B/C/"));
00092 BOOST_CHECK_EQUAL("C/", getMinimalPathTo("/A/B/C/Type", "/A/B"));
00093 BOOST_CHECK_EQUAL("C/", getMinimalPathTo("/A/B/C/Type", "/A/B/"));
00094 BOOST_CHECK_EQUAL("", getMinimalPathTo("/A/B/Type", "/A/B"));
00095 BOOST_CHECK_EQUAL("", getMinimalPathTo("/A/B/Type", "/A/B/"));
00096 }
00097
00098 BOOST_AUTO_TEST_CASE( test_registry_namespaces )
00099 {
00100
00101 Registry registry;
00102 registry.add( new Numeric("/NS1/Test", 1, Numeric::SInt) );
00103 registry.add( new Numeric("/NS2/Test", 2, Numeric::SInt) );
00104
00105 registry.setDefaultNamespace("/NS2");
00106 BOOST_REQUIRE_EQUAL("/NS2/Test", registry.getFullName("Test"));
00107 BOOST_REQUIRE_EQUAL("/NS2/NS3/Test", registry.getFullName("NS3/Test"));
00108 BOOST_REQUIRE_EQUAL("/Test", registry.getFullName("/Test"));
00109 registry.add( new Numeric("/NS2/NS3/Test", 3, Numeric::SInt) );
00110 registry.add( new Numeric("/Test", 4, Numeric::SInt) );
00111 registry.setDefaultNamespace("");
00112
00113 Numeric const* ns1, *ns2, *ns3, *ns;
00114 BOOST_REQUIRE(( ns1 = dynamic_cast<Numeric const*>(registry.get("/NS1/Test")) ));
00115 BOOST_REQUIRE(( ns2 = dynamic_cast<Numeric const*>(registry.get("/NS2/Test")) ));
00116 BOOST_REQUIRE(( ns3 = dynamic_cast<Numeric const*>(registry.get("/NS2/NS3/Test")) ));
00117 BOOST_REQUIRE(( ns = dynamic_cast<Numeric const*>(registry.get("/Test")) ));
00118
00119 BOOST_REQUIRE_EQUAL(1, ns1->getSize());
00120 BOOST_REQUIRE_EQUAL(2, ns2->getSize());
00121 BOOST_REQUIRE_EQUAL(3, ns3->getSize());
00122 BOOST_REQUIRE_EQUAL(4, ns->getSize());
00123
00124 { registry.setDefaultNamespace("/NS2");
00125 Type const* relative;
00126 BOOST_REQUIRE(( relative = registry.get("Test") ));
00127 BOOST_REQUIRE_EQUAL(relative, ns2);
00128 BOOST_REQUIRE(( relative = registry.get("NS3/Test") ));
00129 BOOST_REQUIRE_EQUAL(relative, ns3);
00130 BOOST_REQUIRE(( relative = registry.get("/Test") ));
00131 BOOST_REQUIRE_EQUAL(relative, ns);
00132 BOOST_REQUIRE(( relative = registry.get("/NS1/Test") ));
00133 BOOST_REQUIRE_EQUAL(relative, ns1);
00134 }
00135
00136 }
00137
00138 BOOST_AUTO_TEST_CASE( test_namespace_update_at_insertion )
00139 {
00140 Registry registry;
00141 registry.setDefaultNamespace("/A/B/B");
00142 registry.add( new Numeric("/A/B/B/Test", 3, Numeric::SInt) );
00143 BOOST_REQUIRE(( registry.get("Test") ));
00144 BOOST_REQUIRE(( registry.get("B/Test") ));
00145 BOOST_REQUIRE(( registry.get("B/B/Test") ));
00146 BOOST_REQUIRE(( registry.get("A/B/B/Test") ));
00147
00148 registry.add( new Numeric("/A/B/Test", 3, Numeric::SInt) );
00149 BOOST_REQUIRE(( registry.get("Test") ));
00150 BOOST_REQUIRE(( registry.get("B/Test") ));
00151 BOOST_REQUIRE(( registry.get("B/B/Test") ));
00152 BOOST_REQUIRE(( registry.get("A/B/B/Test") ));
00153 BOOST_REQUIRE(( registry.get("A/B/Test") ));
00154
00155 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/Test"), registry.get("Test"));
00156 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/Test"), registry.get("B/Test"));
00157
00158 registry.setDefaultNamespace("/A/B/B/B");
00159 registry.add( new Numeric("/A/B/B/B/Test", 3, Numeric::SInt) );
00160 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/B/Test"), registry.get("Test"));
00161 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/B/Test"), registry.get("B/Test"));
00162 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/B/Test"), registry.get("B/B/Test"));
00163 }
00164
00165 static void assert_registries_equal(Registry const& registry, Registry const& ref)
00166 {
00167 BOOST_REQUIRE_EQUAL(ref.size(), registry.size());
00168
00169 Registry::Iterator
00170 t_it = registry.begin(),
00171 t_end = registry.end(),
00172 r_it = ref.begin(),
00173 r_end = ref.end();
00174
00175 for (; t_it != t_end && r_it != r_end; ++t_it, ++r_it)
00176 {
00177 BOOST_REQUIRE_EQUAL(t_it.getName(), r_it.getName());
00178 BOOST_REQUIRE_EQUAL(t_it->getName(), r_it->getName());
00179 BOOST_REQUIRE_MESSAGE(t_it->isSame(*r_it), "definitions of " << t_it->getName() << " differ: " << *t_it << "\n" << *r_it);
00180 }
00181
00182 BOOST_REQUIRE(t_it == t_end);
00183 BOOST_REQUIRE(r_it == r_end);
00184 }
00185
00186 BOOST_AUTO_TEST_CASE( test_repositories_merge )
00187 {
00188 static const char* test_file = TEST_DATA_PATH("test_cimport.tlb");
00189
00190 utilmm::config_set config;
00191 PluginManager::self manager;
00192
00193 std::auto_ptr<Registry> ref( manager->load("tlb", test_file, config));
00194 Registry target;
00195 target.merge(*ref);
00196 assert_registries_equal(target, *ref);
00197
00198 target.merge(*ref);
00199 assert_registries_equal(target, *ref);
00200 }
00201
00202 BOOST_AUTO_TEST_CASE( test_array_auto_alias )
00203 {
00204 Registry registry;
00205 Typelib::CXX::addStandardTypes(registry);
00206 registry.alias("/int", "/A");
00207 registry.add(new Array(*registry.get("/int"), 10));
00208 BOOST_REQUIRE(registry.get("/A[10]"));
00209 BOOST_REQUIRE(*registry.get("/A[10]") == *registry.get("/int[10]"));
00210 registry.alias("/int", "/B");
00211 BOOST_REQUIRE(registry.get("/B[10]"));
00212 BOOST_REQUIRE(*registry.get("/B[10]") == *registry.get("/int[10]"));
00213 }
00214
00215 BOOST_AUTO_TEST_CASE( test_registry_merge_keeps_alias_persistent_flag )
00216 {
00217 Registry registry;
00218 Typelib::CXX::addStandardTypes(registry);
00219
00220 registry.alias("/int", "/Persistent", true);
00221 registry.alias("/int", "/Temporary", false);
00222 BOOST_REQUIRE(registry.get("/Persistent"));
00223 BOOST_REQUIRE(registry.find("/Persistent") != registry.end());
00224
00225 Registry target;
00226 target.merge(registry);
00227 { RegistryIterator it = target.find("/Persistent");
00228 BOOST_REQUIRE(it != target.end());
00229 BOOST_REQUIRE(it.isPersistent());
00230 }
00231
00232 { RegistryIterator it = target.find("/Temporary");
00233 BOOST_REQUIRE(it != target.end());
00234 BOOST_REQUIRE(!it.isPersistent());
00235 }
00236 }
00237
00238 BOOST_AUTO_TEST_CASE( test_registry_minimal_keeps_alias_persistent_flag )
00239 {
00240 Registry registry;
00241 Typelib::CXX::addStandardTypes(registry);
00242 Registry target;
00243 Typelib::CXX::addStandardTypes(target);
00244 target.alias("/int", "/Persistent", true);
00245 target.alias("/int", "/Temporary", false);
00246
00247 target.minimal(registry);
00248 { RegistryIterator it = target.find("/Persistent");
00249 BOOST_REQUIRE(it != target.end());
00250 BOOST_REQUIRE(it.isPersistent());
00251 }
00252
00253 { RegistryIterator it = target.find("/Temporary");
00254 BOOST_REQUIRE(it != target.end());
00255 BOOST_REQUIRE(!it.isPersistent());
00256 }
00257 }
00258
00259 BOOST_AUTO_TEST_CASE( test_registry_range )
00260 {
00261 Registry registry;
00262 Typelib::CXX::addStandardTypes(registry);
00263 registry.alias("/int", "/A/A", true);
00264 registry.alias("/int", "/A/C", true);
00265 registry.alias("/int", "/A/F", true);
00266 registry.alias("/int", "/A/B/A", true);
00267 registry.alias("/int", "/A/B/C", true);
00268 registry.alias("/int", "/A/B/F", true);
00269 registry.alias("/int", "/B/A", true);
00270 registry.alias("/int", "/B/C", true);
00271 registry.alias("/int", "/B/F", true);
00272
00273 BOOST_REQUIRE_EQUAL("/A/A", registry.begin("/A").getName());
00274 BOOST_REQUIRE_EQUAL("/B/A", registry.end("/A").getName());
00275 }
00276