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 BOOST_CHECK_EQUAL("/A/", getMinimalPathTo("/A/B", "/C/A"));
00097 }
00098
00099 BOOST_AUTO_TEST_CASE( test_registry_namespaces )
00100 {
00101
00102 Registry registry;
00103 registry.add( new Numeric("/NS1/Test", 1, Numeric::SInt) );
00104 registry.add( new Numeric("/NS2/Test", 2, Numeric::SInt) );
00105
00106 registry.setDefaultNamespace("/NS2");
00107 BOOST_REQUIRE_EQUAL("/NS2/Test", registry.getFullName("Test"));
00108 BOOST_REQUIRE_EQUAL("/NS2/NS3/Test", registry.getFullName("NS3/Test"));
00109 BOOST_REQUIRE_EQUAL("/Test", registry.getFullName("/Test"));
00110 registry.add( new Numeric("/NS2/NS3/Test", 3, Numeric::SInt) );
00111 registry.add( new Numeric("/Test", 4, Numeric::SInt) );
00112 registry.setDefaultNamespace("");
00113
00114 Numeric const* ns1, *ns2, *ns3, *ns;
00115 BOOST_REQUIRE(( ns1 = dynamic_cast<Numeric const*>(registry.get("/NS1/Test")) ));
00116 BOOST_REQUIRE(( ns2 = dynamic_cast<Numeric const*>(registry.get("/NS2/Test")) ));
00117 BOOST_REQUIRE(( ns3 = dynamic_cast<Numeric const*>(registry.get("/NS2/NS3/Test")) ));
00118 BOOST_REQUIRE(( ns = dynamic_cast<Numeric const*>(registry.get("/Test")) ));
00119
00120 BOOST_REQUIRE_EQUAL(1, ns1->getSize());
00121 BOOST_REQUIRE_EQUAL(2, ns2->getSize());
00122 BOOST_REQUIRE_EQUAL(3, ns3->getSize());
00123 BOOST_REQUIRE_EQUAL(4, ns->getSize());
00124
00125 { registry.setDefaultNamespace("/NS2");
00126 Type const* relative;
00127 BOOST_REQUIRE(( relative = registry.get("Test") ));
00128 BOOST_REQUIRE_EQUAL(relative, ns2);
00129 BOOST_REQUIRE(( relative = registry.get("NS3/Test") ));
00130 BOOST_REQUIRE_EQUAL(relative, ns3);
00131 BOOST_REQUIRE(( relative = registry.get("/Test") ));
00132 BOOST_REQUIRE_EQUAL(relative, ns);
00133 BOOST_REQUIRE(( relative = registry.get("/NS1/Test") ));
00134 BOOST_REQUIRE_EQUAL(relative, ns1);
00135 }
00136
00137 }
00138
00139 BOOST_AUTO_TEST_CASE( test_namespace_update_at_insertion )
00140 {
00141 Registry registry;
00142 registry.setDefaultNamespace("/A/B/B");
00143 registry.add( new Numeric("/A/B/B/Test", 3, Numeric::SInt) );
00144 BOOST_REQUIRE(( registry.get("Test") ));
00145 BOOST_REQUIRE(( registry.get("B/Test") ));
00146 BOOST_REQUIRE(( registry.get("B/B/Test") ));
00147 BOOST_REQUIRE(( registry.get("A/B/B/Test") ));
00148
00149 registry.add( new Numeric("/A/B/Test", 3, Numeric::SInt) );
00150 BOOST_REQUIRE(( registry.get("Test") ));
00151 BOOST_REQUIRE(( registry.get("B/Test") ));
00152 BOOST_REQUIRE(( registry.get("B/B/Test") ));
00153 BOOST_REQUIRE(( registry.get("A/B/B/Test") ));
00154 BOOST_REQUIRE(( registry.get("A/B/Test") ));
00155
00156 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/Test"), registry.get("Test"));
00157 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/Test"), registry.get("B/Test"));
00158
00159 registry.setDefaultNamespace("/A/B/B/B");
00160 registry.add( new Numeric("/A/B/B/B/Test", 3, Numeric::SInt) );
00161 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/B/Test"), registry.get("Test"));
00162 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/B/Test"), registry.get("B/Test"));
00163 BOOST_REQUIRE_EQUAL(registry.get("/A/B/B/B/Test"), registry.get("B/B/Test"));
00164 }
00165
00166 static void assert_registries_equal(Registry const& registry, Registry const& ref)
00167 {
00168 BOOST_REQUIRE_EQUAL(ref.size(), registry.size());
00169
00170 Registry::Iterator
00171 t_it = registry.begin(),
00172 t_end = registry.end(),
00173 r_it = ref.begin(),
00174 r_end = ref.end();
00175
00176 for (; t_it != t_end && r_it != r_end; ++t_it, ++r_it)
00177 {
00178 BOOST_REQUIRE_EQUAL(t_it.getName(), r_it.getName());
00179 BOOST_REQUIRE_EQUAL(t_it->getName(), r_it->getName());
00180 BOOST_REQUIRE_MESSAGE(t_it->isSame(*r_it), "definitions of " << t_it->getName() << " differ: " << *t_it << "\n" << *r_it);
00181 }
00182
00183 BOOST_REQUIRE(t_it == t_end);
00184 BOOST_REQUIRE(r_it == r_end);
00185 }
00186
00187 BOOST_AUTO_TEST_CASE( test_repositories_merge )
00188 {
00189 static const char* test_file = TEST_DATA_PATH("test_cimport.tlb");
00190
00191 utilmm::config_set config;
00192 PluginManager::self manager;
00193
00194 std::auto_ptr<Registry> ref( manager->load("tlb", test_file, config));
00195 Registry target;
00196 target.merge(*ref);
00197 assert_registries_equal(target, *ref);
00198
00199 target.merge(*ref);
00200 assert_registries_equal(target, *ref);
00201 }
00202
00203 BOOST_AUTO_TEST_CASE( test_array_auto_alias )
00204 {
00205 Registry registry;
00206 Typelib::CXX::addStandardTypes(registry);
00207 registry.alias("/int", "/A");
00208 registry.add(new Array(*registry.get("/int"), 10));
00209 BOOST_REQUIRE(registry.get("/A[10]"));
00210 BOOST_REQUIRE(*registry.get("/A[10]") == *registry.get("/int[10]"));
00211 registry.alias("/int", "/B");
00212 BOOST_REQUIRE(registry.get("/B[10]"));
00213 BOOST_REQUIRE(*registry.get("/B[10]") == *registry.get("/int[10]"));
00214 }
00215
00216 BOOST_AUTO_TEST_CASE( test_registry_merge_keeps_alias_persistent_flag )
00217 {
00218 Registry registry;
00219 Typelib::CXX::addStandardTypes(registry);
00220
00221 registry.alias("/int", "/Persistent", true);
00222 registry.alias("/int", "/Temporary", false);
00223 BOOST_REQUIRE(registry.get("/Persistent"));
00224 BOOST_REQUIRE(registry.find("/Persistent") != registry.end());
00225
00226 Registry target;
00227 target.merge(registry);
00228 { RegistryIterator it = target.find("/Persistent");
00229 BOOST_REQUIRE(it != target.end());
00230 BOOST_REQUIRE(it.isPersistent());
00231 }
00232
00233 { RegistryIterator it = target.find("/Temporary");
00234 BOOST_REQUIRE(it != target.end());
00235 BOOST_REQUIRE(!it.isPersistent());
00236 }
00237 }
00238
00239 BOOST_AUTO_TEST_CASE( test_registry_minimal_keeps_alias_persistent_flag )
00240 {
00241 Registry registry;
00242 Typelib::CXX::addStandardTypes(registry);
00243 Registry target;
00244 Typelib::CXX::addStandardTypes(target);
00245 target.alias("/int", "/Persistent", true);
00246 target.alias("/int", "/Temporary", false);
00247
00248 target.minimal(registry);
00249 { RegistryIterator it = target.find("/Persistent");
00250 BOOST_REQUIRE(it != target.end());
00251 BOOST_REQUIRE(it.isPersistent());
00252 }
00253
00254 { RegistryIterator it = target.find("/Temporary");
00255 BOOST_REQUIRE(it != target.end());
00256 BOOST_REQUIRE(!it.isPersistent());
00257 }
00258 }
00259
00260 BOOST_AUTO_TEST_CASE( test_registry_range )
00261 {
00262 Registry registry;
00263 Typelib::CXX::addStandardTypes(registry);
00264 registry.alias("/int", "/A/A", true);
00265 registry.alias("/int", "/A/C", true);
00266 registry.alias("/int", "/A/F", true);
00267 registry.alias("/int", "/A/B/A", true);
00268 registry.alias("/int", "/A/B/C", true);
00269 registry.alias("/int", "/A/B/F", true);
00270 registry.alias("/int", "/B/A", true);
00271 registry.alias("/int", "/B/C", true);
00272 registry.alias("/int", "/B/F", true);
00273
00274 BOOST_REQUIRE_EQUAL("/A/A", registry.begin("/A").getName());
00275 BOOST_REQUIRE_EQUAL("/B/A", registry.end("/A").getName());
00276 }
00277