test_model.cc
Go to the documentation of this file.
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 }


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Thu Jan 2 2014 11:38:41