$search
00001 #include <boost/test/auto_unit_test.hpp> 00002 00003 #include <lang/csupport/standard_types.hh> 00004 00005 #include <test/testsuite.hh> 00006 #include <utilmm/configfile/configset.hh> 00007 #include <typelib/pluginmanager.hh> 00008 #include <typelib/importer.hh> 00009 #include <typelib/typemodel.hh> 00010 #include <typelib/registry.hh> 00011 #include "test_cimport.1" 00012 #include <boost/tuple/tuple.hpp> 00013 using namespace Typelib; 00014 using namespace std; 00015 using boost::tie; 00016 00017 static pair<Compound*, Compound*> recursive_types(Registry& reg) 00018 { 00019 Compound* direct = new Compound("/R"); 00020 reg.add(direct); 00021 direct->addField("recursive", *reg.build("/R*"), 0); 00022 00023 Compound* indirect = new Compound("/R_indirect"); 00024 Compound* indirect_temp = new Compound("/R_temp"); 00025 reg.add(indirect); 00026 reg.add(indirect_temp); 00027 indirect_temp->addField("recursive", *reg.build("/R_indirect*"), 0); 00028 indirect->addField("temp", *indirect_temp, 0); 00029 00030 return make_pair(direct, indirect); 00031 } 00032 00033 BOOST_AUTO_TEST_CASE( test_compound_size ) 00034 { 00035 Registry r; 00036 Typelib::CXX::addStandardTypes(r); 00037 00038 Compound str(""); 00039 str.addField("a", *r.get("/int32_t"), 0); 00040 BOOST_REQUIRE_EQUAL(4U, str.getSize()); 00041 str.addField("b", *r.get("/int32_t"), 4); 00042 BOOST_REQUIRE_EQUAL(8U, str.getSize()); 00043 str.addField("c", *r.get("/int64_t"), 2); 00044 BOOST_REQUIRE_EQUAL(10U, str.getSize()); 00045 str.addField("e", *r.get("/int64_t"), 0); 00046 BOOST_REQUIRE_EQUAL(10U, str.getSize()); 00047 00048 Compound *direct, *indirect; 00049 tie(direct, indirect) = recursive_types(r); 00050 BOOST_REQUIRE_EQUAL(direct->getSize(), sizeof(int*)); 00051 BOOST_REQUIRE_EQUAL(indirect->getSize(), sizeof(int*)); 00052 } 00053 00054 BOOST_AUTO_TEST_CASE( test_equality ) 00055 { 00056 Registry ra, rb; 00057 Typelib::CXX::addStandardTypes(ra); 00058 Typelib::CXX::addStandardTypes(rb); 00059 00061 BOOST_REQUIRE(*ra.get("/int32_t") == *ra.get("/int32_t")); 00062 // different repositories, same type 00063 BOOST_REQUIRE(*ra.get("/int32_t") != *rb.get("/int32_t")); 00064 BOOST_REQUIRE(ra.get("/int32_t")->isSame(*rb.get("/int32_t"))); 00065 // same type but different names 00066 BOOST_REQUIRE(!ra.get("/int32_t")->isSame(*ra.get("/float"))); // numeric category differs 00067 BOOST_REQUIRE(!ra.get("/int32_t")->isSame(*ra.get("/uint32_t"))); // numeric category differs 00068 BOOST_REQUIRE(!ra.get("/int16_t")->isSame(*ra.get("/int32_t"))); // size differs 00069 00071 BOOST_REQUIRE(*ra.build("/int[16]") != *rb.build("/int[16]")); 00072 BOOST_REQUIRE(*ra.get("/int[16]") == *ra.get("/int[16]")); 00073 BOOST_REQUIRE(!ra.get("/int[16]")->isSame(*rb.build("/int"))); 00074 BOOST_REQUIRE( ra.get("/int[16]")->isSame(*rb.build("/int[16]"))); 00075 BOOST_REQUIRE(!ra.get("/int[16]")->isSame(*rb.build("/int[32]"))); 00076 BOOST_REQUIRE(!ra.get("/int[16]")->isSame(*rb.build("/float[16]"))); 00077 00079 BOOST_REQUIRE(*ra.build("/int*") != *rb.build("/int*")); 00080 BOOST_REQUIRE(*ra.get("/int*") == *ra.get("/int*")); 00081 BOOST_REQUIRE(ra.get("/int*")->isSame(*rb.build("/int*"))); 00082 BOOST_REQUIRE(!ra.get("/int*")->isSame(*rb.build("/float*"))); 00083 00085 Compound str_a("/A"); 00086 str_a.addField("a", *ra.build("/int[16]"), 0); 00087 str_a.addField("b", *ra.build("/float*"), 1); 00088 str_a.addField("c", *ra.get("/int32_t"), 2); 00089 00090 Compound str_b("/B"); 00091 str_b.addField("a", str_a, 0); 00092 str_b.addField("b", *ra.build("/nil*"), 1); 00093 00094 BOOST_REQUIRE(str_a.isSame(str_a)); 00095 BOOST_REQUIRE(str_b.isSame(str_b)); 00096 BOOST_REQUIRE(!str_a.isSame(str_b)); 00097 00098 // same type than str_a, to test checking on str_b 00099 Compound str_a_dup("/A"); 00100 str_a_dup.addField("a", *rb.build("/int[16]"), 0); 00101 str_a_dup.addField("b", *rb.build("/float*"), 1); 00102 str_a_dup.addField("c", *rb.get("/int32_t"), 2); 00103 00104 { Compound str_c("/C"); 00105 // type name changed 00106 str_c.addField("a", str_a_dup, 0); 00107 str_c.addField("b", *rb.build("/nil*"), 1); 00108 BOOST_REQUIRE(str_c.isSame(str_b)); 00109 } 00110 00111 { Compound str_c("/B"); 00112 // field offsets changed 00113 // the structure size should remain the same 00114 // in order to really check offset checking 00115 str_c.addField("a", str_a_dup, 0); 00116 str_c.addField("b", *rb.build("/nil*"), 0); 00117 BOOST_REQUIRE_EQUAL(str_c.getSize(), str_b.getSize()); 00118 BOOST_REQUIRE(!str_c.isSame(str_b)); 00119 } 00120 00121 { Compound str_c("/B"); 00122 // field name change 00123 str_c.addField("a", str_a_dup, 0); 00124 str_c.addField("c", *rb.build("/nil*"), 1); 00125 BOOST_REQUIRE(!str_c.isSame(str_b)); 00126 } 00127 00128 // Directly recursive type 00129 { 00130 Compound* direct_a, *indirect_a; 00131 Compound* direct_b, *indirect_b; 00132 tie(direct_a, indirect_a) = recursive_types(ra); 00133 tie(direct_b, indirect_b) = recursive_types(rb); 00134 00135 BOOST_REQUIRE(direct_a->isSame(*direct_b)); 00136 BOOST_REQUIRE(indirect_a->isSame(*indirect_b)); 00137 BOOST_REQUIRE(!direct_a->isSame(*indirect_b)); 00138 BOOST_REQUIRE(!indirect_a->isSame(*direct_b)); 00139 } 00140 00142 Container const& container_a = Container::createContainer(ra, "/std/vector", str_a); 00143 Container const& container_a_dup = Container::createContainer(ra, "/std/vector", str_a_dup); 00144 BOOST_REQUIRE(container_a.isSame(container_a_dup)); 00145 00146 } 00147 00148 BOOST_AUTO_TEST_CASE( test_cast ) 00149 { 00150 Registry ra, rb; 00151 Typelib::CXX::addStandardTypes(ra); 00152 Typelib::CXX::addStandardTypes(rb); 00153 00155 BOOST_REQUIRE(*ra.get("/int32_t") == *ra.get("/int32_t")); 00156 // different repositories, same type 00157 BOOST_REQUIRE(*ra.get("/int32_t") != *rb.get("/int32_t")); 00158 BOOST_REQUIRE(ra.get("/int32_t")->canCastTo(*rb.get("/int32_t"))); 00159 // same type but different names 00160 BOOST_REQUIRE(ra.get("/int16_t")->canCastTo(*rb.get("/short"))); 00161 BOOST_REQUIRE(!ra.get("/int32_t")->canCastTo(*ra.get("/float"))); // numeric category differs 00162 BOOST_REQUIRE(!ra.get("/int32_t")->canCastTo(*ra.get("/uint32_t"))); // numeric category differs 00163 BOOST_REQUIRE(!ra.get("/int16_t")->canCastTo(*ra.get("/int32_t"))); // size differs 00164 00166 BOOST_REQUIRE(*ra.build("/int[16]") != *rb.build("/int[16]")); 00167 BOOST_REQUIRE(*ra.get("/int[16]") == *ra.get("/int[16]")); 00168 BOOST_REQUIRE(!ra.get("/int[16]")->canCastTo(*rb.build("/int"))); 00169 BOOST_REQUIRE(ra.get("/int[16]")->canCastTo(*rb.build("/int[16]"))); 00170 BOOST_REQUIRE(!ra.get("/int[16]")->canCastTo(*rb.build("/int[32]"))); 00171 BOOST_REQUIRE(!ra.get("/int[16]")->canCastTo(*rb.build("/float[16]"))); 00172 00174 BOOST_REQUIRE(*ra.build("/int*") != *rb.build("/int*")); 00175 BOOST_REQUIRE(*ra.get("/int*") == *ra.get("/int*")); 00176 BOOST_REQUIRE(ra.get("/int*")->canCastTo(*rb.build("/int*"))); 00177 BOOST_REQUIRE(!ra.get("/int*")->canCastTo(*rb.build("/float*"))); 00178 00180 Compound* str_a = new Compound("/A"); 00181 str_a->addField("a", *ra.build("/int[16]"), 0); 00182 str_a->addField("b", *ra.build("/float*"), 1); 00183 str_a->addField("c", *ra.get("/int32_t"), 2); 00184 ra.add(str_a); 00185 00186 Compound str_b("/B"); 00187 str_b.addField("a", *str_a, 0); 00188 str_b.addField("b", *ra.build("/nil*"), 1); 00189 00190 BOOST_REQUIRE(str_a->canCastTo(*str_a)); 00191 BOOST_REQUIRE(str_b.canCastTo(str_b)); 00192 BOOST_REQUIRE(!str_a->canCastTo(str_b)); 00193 00194 // same type than str_a, to test checking on str_b 00195 Compound* str_a_dup = new Compound("/A_dup"); 00196 str_a_dup->addField("a", *rb.build("/int[16]"), 0); 00197 str_a_dup->addField("b", *rb.build("/float*"), 1); 00198 str_a_dup->addField("c", *rb.get("/int32_t"), 2); 00199 // Add some fake padding bytes 00200 str_a_dup->setSize(str_a->getSize() + 5); 00201 ra.add(str_a_dup); 00202 00203 { Compound str_c("/C"); 00204 // type name changed 00205 str_c.addField("a", *str_a, 0); 00206 str_c.addField("b", *rb.build("/nil*"), 1); 00207 BOOST_REQUIRE(str_c.canCastTo(str_b)); 00208 } 00209 00210 { Compound str_c("/C"); 00211 // packing changes 00212 str_c.addField("a", *str_a_dup, 0); 00213 str_c.addField("b", *rb.build("/nil*"), 1); 00214 BOOST_REQUIRE(str_c.canCastTo(str_b)); 00215 } 00216 00217 { Compound str_c("/B"); 00218 // field offsets changed 00219 // the structure size should remain the same 00220 // in order to really check offset checking 00221 str_c.addField("a", *str_a_dup, 0); 00222 str_c.addField("b", *rb.build("/nil*"), 0); 00223 BOOST_REQUIRE(!str_c.canCastTo(str_b)); 00224 } 00225 00226 { Compound str_c("/B"); 00227 // field name change 00228 str_c.addField("a", *str_a_dup, 0); 00229 str_c.addField("c", *rb.build("/nil*"), 1); 00230 BOOST_REQUIRE(!str_c.canCastTo(str_b)); 00231 } 00232 00233 // Directly recursive type 00234 { 00235 Compound* direct_a, *indirect_a; 00236 Compound* direct_b, *indirect_b; 00237 tie(direct_a, indirect_a) = recursive_types(ra); 00238 tie(direct_b, indirect_b) = recursive_types(rb); 00239 00240 BOOST_REQUIRE(direct_a->canCastTo(*direct_b)); 00241 BOOST_REQUIRE(indirect_a->canCastTo(*indirect_b)); 00242 BOOST_REQUIRE(!direct_a->canCastTo(*indirect_b)); 00243 BOOST_REQUIRE(!indirect_a->canCastTo(*direct_b)); 00244 } 00245 00247 Container const& container_a = Container::createContainer(ra, "/std/vector", *str_a); 00248 Container const& container_a_dup = Container::createContainer(ra, "/std/vector", *str_a_dup); 00249 BOOST_REQUIRE(container_a.canCastTo(container_a)); 00250 BOOST_REQUIRE(!container_a.canCastTo(container_a_dup)); 00251 00252 BOOST_REQUIRE(!ra.build("/A[16]")->canCastTo(*ra.build("/A_dup[16]"))); 00253 } 00254 00255 BOOST_AUTO_TEST_CASE( test_model_merge ) 00256 { 00257 Registry ra, rb; 00258 Typelib::CXX::addStandardTypes(ra); 00259 Typelib::CXX::addStandardTypes(rb); 00260 00262 Compound* str_a = new Compound("/A"); 00263 str_a->addField("a", *rb.build("/int[16]"), 0); 00264 str_a->addField("b", *rb.build("/float*"), 1); 00265 str_a->addField("c", *rb.get("/int32_t"), 2); 00266 rb.add(str_a, ""); 00267 00268 Compound* str_b = new Compound("/B"); 00269 str_b->addField("a", *str_a, 0); 00270 str_b->addField("b", *rb.build("/nil*"), 1); 00271 rb.add(str_b, ""); 00272 rb.alias("/A", "/C"); 00273 rb.alias("/B", "/D"); 00274 00276 recursive_types(rb); 00277 00278 ra.merge(rb); 00279 00280 BOOST_REQUIRE(ra.get("/int[16]") != rb.get("/int[16]")); 00281 BOOST_REQUIRE(ra.get("/int[16]")->isSame(*rb.get("/int[16]"))); 00282 BOOST_REQUIRE(ra.get("/nil*") != rb.get("/nil*")); 00283 BOOST_REQUIRE(ra.get("/nil*")->isSame(*rb.get("/nil*"))); 00284 BOOST_REQUIRE(ra.get("/A") != rb.get("/A")); 00285 BOOST_REQUIRE(ra.get("/A")->isSame(*str_a)); 00286 BOOST_REQUIRE(ra.get("/B") != rb.get("/B")); 00287 BOOST_REQUIRE(ra.get("/B")->isSame(*str_b)); 00288 BOOST_REQUIRE(*ra.get("/A") == *ra.get("/C")); 00289 BOOST_REQUIRE(*ra.get("/B") == *ra.get("/D")); 00290 BOOST_REQUIRE(*ra.get("/R") != *rb.get("/R")); 00291 BOOST_REQUIRE(*ra.get("/R_indirect") != *rb.get("/R_indirect")); 00292 BOOST_REQUIRE(ra.get("/R")->isSame(*rb.get("/R"))); 00293 BOOST_REQUIRE(ra.get("/R_indirect")->isSame(*rb.get("/R_indirect"))); 00294 00295 BOOST_REQUIRE(static_cast<Compound const*>(ra.get("/A"))->getField("a")->getType() == *ra.get("/int[16]")); 00296 BOOST_REQUIRE(static_cast<Compound const*>(ra.get("/A"))->getField("b")->getType() == *ra.get("/float*")); 00297 BOOST_REQUIRE(static_cast<Compound const*>(ra.get("/A"))->getField("c")->getType() == *ra.get("/int32_t")); 00298 BOOST_REQUIRE(static_cast<Compound const*>(ra.get("/B"))->getField("a")->getType() == *ra.get("/A")); 00299 BOOST_REQUIRE(static_cast<Compound const*>(ra.get("/B"))->getField("b")->getType() == *ra.get("/nil*")); 00300 BOOST_REQUIRE(static_cast<Compound const*>(rb.get("/A"))->getField("a")->getType() == *rb.get("/int[16]")); 00301 BOOST_REQUIRE(static_cast<Compound const*>(rb.get("/A"))->getField("b")->getType() == *rb.get("/float*")); 00302 BOOST_REQUIRE(static_cast<Compound const*>(rb.get("/A"))->getField("c")->getType() == *rb.get("/int32_t")); 00303 BOOST_REQUIRE(static_cast<Compound const*>(rb.get("/B"))->getField("a")->getType() == *rb.get("/A")); 00304 BOOST_REQUIRE(static_cast<Compound const*>(rb.get("/B"))->getField("b")->getType() == *rb.get("/nil*")); 00305 }