2 #include <msp/datafile/collection.h>
3 #include <msp/datafile/objectloader.h>
4 #include <msp/io/memory.h>
5 #include <msp/test/test.h>
12 class CollectionTests: public Test::RegisteredTest<CollectionTests>
15 TestCollection *collection;
21 static const char *get_name() { return "Collection"; }
26 void contains_future();
33 void name_collision();
40 class Loader: public DataFile::ObjectLoader<Base>
52 int get_tag() const { return tag; }
55 class Foo: public Base
58 static unsigned create_count;
63 static unsigned get_create_count() { return create_count; }
66 class Bar: public Base
73 class TestSource: public DataFile::CollectionSource
76 virtual bool is_loadable(const DataFile::CollectionItemTypeBase &, const std::string &) const;
77 virtual NameList get_names(const DataFile::CollectionItemTypeBase &) const;
78 virtual void load(DataFile::Collection &, const DataFile::CollectionItemTypeBase &, const std::string &) const;
82 class TestCollection: public DataFile::Collection
91 Foo *create_foo(const string &);
95 CollectionTests::CollectionTests()
97 add(&CollectionTests::load, "Load objects");
98 add(&CollectionTests::contains, "Containment test");
99 add(&CollectionTests::contains_future, "Future containment test");
100 add(&CollectionTests::names, "List object names");
101 add(&CollectionTests::names_future, "List future object names");
102 add(&CollectionTests::fetch, "Fetch objects");
103 add(&CollectionTests::nonexistent, "Nonexistent object").expect_throw<key_error>();
104 add(&CollectionTests::type_mismatch, "Type mismatch").expect_throw<Msp::type_mismatch>();
105 add(&CollectionTests::create, "Create object");
106 add(&CollectionTests::name_collision, "Name collision").expect_throw<Msp::key_error>();
108 collection = new TestCollection;
111 CollectionTests::~CollectionTests()
116 void CollectionTests::load()
119 "foo \"a\" { tag 1; };\n"
120 "foo \"b\" { tag 2; };\n"
121 "bar \"c\" { tag 3; };\n"
122 "sub \"d\" { tag 4; };\n";
124 IO::Memory mem(input, sizeof(input)-1);
125 DataFile::Parser parser(mem, "-");
126 TestCollection::Loader loader(*collection);
130 void CollectionTests::contains()
132 const TestCollection *ccoll = collection;
133 EXPECT(ccoll->contains<Foo>("a"));
134 EXPECT(ccoll->contains<Bar>("c"));
135 EXPECT(!ccoll->contains<Foo>("c"));
138 void CollectionTests::contains_future()
140 const TestCollection *ccoll = collection;
141 EXPECT(!ccoll->contains<Foo>("f"));
142 EXPECT(collection->contains<Foo>("f"));
145 void CollectionTests::names()
147 const TestCollection *ccoll = collection;
148 list<string> nm = ccoll->get_names<Foo>();
149 EXPECT_EQUAL(nm.size(), 2);
150 set<string> nm_set(nm.begin(), nm.end());
151 EXPECT_EQUAL(nm_set.count("a"), 1);
152 EXPECT_EQUAL(nm_set.count("b"), 1);
155 void CollectionTests::names_future()
157 list<string> nm = collection->get_names<Foo>();
158 EXPECT_EQUAL(nm.size(), 3);
159 set<string> nm_set(nm.begin(), nm.end());
160 EXPECT_EQUAL(nm_set.count("f"), 1);
163 void CollectionTests::fetch()
165 const TestCollection *ccoll = collection;
166 EXPECT_EQUAL(ccoll->get<Foo>("a").get_tag(), 1);
167 EXPECT_EQUAL(ccoll->get<Foo>("b").get_tag(), 2);
168 EXPECT_EQUAL(ccoll->get<Bar>("c").get_tag(), 3);
169 EXPECT_EQUAL(ccoll->get<Bar>("d").get_tag(), 4);
170 EXPECT_EQUAL(ccoll->get<Sub>("d").get_tag(), 4);
173 void CollectionTests::nonexistent()
175 collection->get<Bar>("z");
178 void CollectionTests::type_mismatch()
180 collection->get<Foo>("c");
183 void CollectionTests::create()
185 unsigned foo_count = Foo::get_create_count();
186 Foo &f = collection->get<Foo>("f");
187 Foo &f2 = collection->get<Foo>("f");
188 EXPECT_EQUAL(&f2, &f);
189 EXPECT(Foo::get_create_count()>foo_count);
192 void CollectionTests::name_collision()
194 RefPtr<Foo> a = new Foo;
195 collection->add("a", a.get());
205 Base::Loader::Loader(Base &b):
206 DataFile::ObjectLoader<Base>(b)
208 add("tag", &Base::tag);
212 unsigned Foo::create_count = 0;
220 bool TestSource::is_loadable(const DataFile::CollectionItemTypeBase &, const string &name) const
225 DataFile::CollectionSource::NameList TestSource::get_names(const DataFile::CollectionItemTypeBase &) const
228 names.push_back("f");
232 void TestSource::load(DataFile::Collection &coll, const DataFile::CollectionItemTypeBase &, const string &name) const
235 coll.add("f", new Foo);
239 TestCollection::TestCollection()
241 add_type<Foo>().keyword("foo").creator(&TestCollection::create_foo);
242 add_type<Bar>().keyword("bar");
243 add_type<Sub>().keyword("sub").base<Bar>();
247 Foo *TestCollection::create_foo(const string &)