+#include <set>
#include <msp/datafile/collection.h>
#include <msp/datafile/objectloader.h>
#include <msp/io/memory.h>
private:
void load();
+ void contains();
+ void contains_base();
+ void contains_future();
+ void names();
+ void names_base();
+ void names_future();
void fetch();
void nonexistent();
void type_mismatch();
void create();
+ void list_future();
void name_collision();
};
+
class Base
{
public:
};
class Foo: public Base
-{ };
+{
+private:
+ static unsigned create_count;
+
+public:
+ Foo();
+
+ static unsigned get_create_count() { return create_count; }
+};
class Bar: public Base
{ };
class Sub: public Bar
{ };
+class Bus: public Bar
+{ };
+
+
+class TestSource: public DataFile::CollectionSource
+{
+public:
+ virtual bool is_loadable(const DataFile::CollectionItemTypeBase &, const std::string &) const;
+ virtual NameList get_names(const DataFile::CollectionItemTypeBase &) const;
+ virtual void load(DataFile::Collection &, const DataFile::CollectionItemTypeBase &, const std::string &) const;
+};
+
+
class TestCollection: public DataFile::Collection
{
+private:
+ TestSource source;
+
public:
TestCollection();
Foo *create_foo(const string &);
};
+
CollectionTests::CollectionTests()
{
add(&CollectionTests::load, "Load objects");
+ add(&CollectionTests::contains, "Containment test");
+ add(&CollectionTests::contains_base, "Base class containment test");
+ add(&CollectionTests::contains_future, "Future containment test");
+ add(&CollectionTests::names, "List object names");
+ add(&CollectionTests::names_base, "List base class object names");
+ add(&CollectionTests::names_future, "List future object names");
add(&CollectionTests::fetch, "Fetch objects");
add(&CollectionTests::nonexistent, "Nonexistent object").expect_throw<key_error>();
add(&CollectionTests::type_mismatch, "Type mismatch").expect_throw<Msp::type_mismatch>();
add(&CollectionTests::create, "Create object");
+ add(&CollectionTests::list_future, "List future objects");
add(&CollectionTests::name_collision, "Name collision").expect_throw<Msp::key_error>();
collection = new TestCollection;
"foo \"a\" { tag 1; };\n"
"foo \"b\" { tag 2; };\n"
"bar \"c\" { tag 3; };\n"
- "sub \"d\" { tag 4; };\n";
+ "sub \"d\" { tag 4; };\n"
+ "bus \"e\" { tag 5; };\n";
IO::Memory mem(input, sizeof(input)-1);
DataFile::Parser parser(mem, "-");
loader.load(parser);
}
+void CollectionTests::contains()
+{
+ const TestCollection *ccoll = collection;
+ EXPECT(ccoll->contains<Foo>("a"));
+ EXPECT(ccoll->contains<Bar>("c"));
+ EXPECT(!ccoll->contains<Foo>("c"));
+}
+
+void CollectionTests::contains_base()
+{
+ const TestCollection *ccoll = collection;
+ EXPECT(ccoll->contains<Bar>("d"));
+ EXPECT(ccoll->contains<Sub>("d"));
+}
+
+void CollectionTests::contains_future()
+{
+ const TestCollection *ccoll = collection;
+ EXPECT(!ccoll->contains<Foo>("f"));
+ EXPECT(collection->contains<Foo>("f"));
+}
+
+void CollectionTests::names()
+{
+ const TestCollection *ccoll = collection;
+ list<string> nm = ccoll->get_names<Foo>();
+ EXPECT_EQUAL(nm.size(), 2);
+ set<string> nm_set(nm.begin(), nm.end());
+ EXPECT_EQUAL(nm_set.count("a"), 1);
+ EXPECT_EQUAL(nm_set.count("b"), 1);
+}
+
+void CollectionTests::names_base()
+{
+ const TestCollection *ccoll = collection;
+ list<string> nm = ccoll->get_names<Bar>();
+ EXPECT_EQUAL(nm.size(), 3);
+ set<string> nm_set(nm.begin(), nm.end());
+ EXPECT_EQUAL(nm_set.count("c"), 1);
+ EXPECT_EQUAL(nm_set.count("d"), 1);
+ EXPECT_EQUAL(nm_set.count("e"), 1);
+}
+
+void CollectionTests::names_future()
+{
+ list<string> nm = collection->get_names<Foo>();
+ EXPECT_EQUAL(nm.size(), 3);
+ set<string> nm_set(nm.begin(), nm.end());
+ EXPECT_EQUAL(nm_set.count("f"), 1);
+}
+
void CollectionTests::fetch()
{
const TestCollection *ccoll = collection;
EXPECT_EQUAL(ccoll->get<Foo>("b").get_tag(), 2);
EXPECT_EQUAL(ccoll->get<Bar>("c").get_tag(), 3);
EXPECT_EQUAL(ccoll->get<Bar>("d").get_tag(), 4);
+ EXPECT_EQUAL(ccoll->get<Sub>("d").get_tag(), 4);
}
void CollectionTests::nonexistent()
void CollectionTests::create()
{
+ unsigned foo_count = Foo::get_create_count();
Foo &f = collection->get<Foo>("f");
Foo &f2 = collection->get<Foo>("f");
EXPECT_EQUAL(&f2, &f);
+ EXPECT(Foo::get_create_count()>foo_count);
+}
+
+void CollectionTests::list_future()
+{
+ list<Foo *> nm = collection->get_list<Foo>();
+ EXPECT_EQUAL(nm.size(), 3);
+ set<Foo *> nm_set(nm.begin(), nm.end());
+ EXPECT_EQUAL(nm_set.size(), nm.size());
}
void CollectionTests::name_collision()
a.release();
}
+
Base::Base():
tag(0)
{ }
+
Base::Loader::Loader(Base &b):
DataFile::ObjectLoader<Base>(b)
{
add("tag", &Base::tag);
}
+
+unsigned Foo::create_count = 0;
+
+Foo::Foo()
+{
+ ++create_count;
+}
+
+
+bool TestSource::is_loadable(const DataFile::CollectionItemTypeBase &, const string &name) const
+{
+ return name=="f";
+}
+
+DataFile::CollectionSource::NameList TestSource::get_names(const DataFile::CollectionItemTypeBase &) const
+{
+ NameList names;
+ names.push_back("f");
+ return names;
+}
+
+void TestSource::load(DataFile::Collection &coll, const DataFile::CollectionItemTypeBase &, const string &name) const
+{
+ if(name=="f")
+ coll.add("f", new Foo);
+}
+
+
TestCollection::TestCollection()
{
add_type<Foo>().keyword("foo").creator(&TestCollection::create_foo);
add_type<Bar>().keyword("bar");
- add_type<Sub>().keyword("sub").store_as<Bar>();
+ add_type<Sub>().keyword("sub").base<Bar>();
+ add_type<Bus>().keyword("bus").base<Bar>();
+ add_source(source);
}
Foo *TestCollection::create_foo(const string &)