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
00063 BOOST_REQUIRE(*ra.get("/int32_t") != *rb.get("/int32_t"));
00064 BOOST_REQUIRE(ra.get("/int32_t")->isSame(*rb.get("/int32_t")));
00065
00066 BOOST_REQUIRE(!ra.get("/int32_t")->isSame(*ra.get("/float")));
00067 BOOST_REQUIRE(!ra.get("/int32_t")->isSame(*ra.get("/uint32_t")));
00068 BOOST_REQUIRE(!ra.get("/int16_t")->isSame(*ra.get("/int32_t")));
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
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
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
00113
00114
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
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
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
00157 BOOST_REQUIRE(*ra.get("/int32_t") != *rb.get("/int32_t"));
00158 BOOST_REQUIRE(ra.get("/int32_t")->canCastTo(*rb.get("/int32_t")));
00159
00160 BOOST_REQUIRE(ra.get("/int16_t")->canCastTo(*rb.get("/short")));
00161 BOOST_REQUIRE(!ra.get("/int32_t")->canCastTo(*ra.get("/float")));
00162 BOOST_REQUIRE(!ra.get("/int32_t")->canCastTo(*ra.get("/uint32_t")));
00163 BOOST_REQUIRE(!ra.get("/int16_t")->canCastTo(*ra.get("/int32_t")));
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
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
00200 str_a_dup->setSize(str_a->getSize() + 5);
00201 ra.add(str_a_dup);
00202
00203 { Compound str_c("/C");
00204
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
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
00219
00220
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
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
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 }