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"; }
27 void contains_loadable();
30 void names_loadable();
36 void name_collision();
43 class Loader: public DataFile::ObjectLoader<Base>
55 int get_tag() const { return tag; }
58 class Foo: public Base
61 static unsigned create_count;
66 static unsigned get_create_count() { return create_count; }
69 class Bar: public Base
79 class TestSource: public DataFile::CollectionSource
82 virtual bool is_loadable(const DataFile::CollectionItemTypeBase &, const std::string &) const;
83 virtual NameList get_names(const DataFile::CollectionItemTypeBase &) const;
84 virtual void load(DataFile::Collection &, const DataFile::CollectionItemTypeBase &, const std::string &) const;
85 virtual IO::Seekable *open(const string &) const { return 0; }
89 class TestCollection: public DataFile::Collection
98 Foo *create_foo(const string &);
102 CollectionTests::CollectionTests()
104 add(&CollectionTests::load, "Load objects");
105 add(&CollectionTests::contains, "Containment test");
106 add(&CollectionTests::contains_base, "Base class containment test");
107 add(&CollectionTests::contains_loadable, "Loadable containment test");
108 add(&CollectionTests::names, "List object names");
109 add(&CollectionTests::names_base, "List base class object names");
110 add(&CollectionTests::names_loadable, "List loadable object names");
111 add(&CollectionTests::fetch, "Fetch objects");
112 add(&CollectionTests::nonexistent, "Nonexistent object").expect_throw<key_error>();
113 add(&CollectionTests::type_mismatch, "Type mismatch").expect_throw<Msp::type_mismatch>();
114 add(&CollectionTests::create, "Create object");
115 add(&CollectionTests::list_loadable, "List loadable objects");
116 add(&CollectionTests::name_collision, "Name collision").expect_throw<Msp::key_error>();
118 collection = new TestCollection;
121 CollectionTests::~CollectionTests()
126 void CollectionTests::load()
129 "foo \"a\" { tag 1; };\n"
130 "foo \"b\" { tag 2; };\n"
131 "bar \"c\" { tag 3; };\n"
132 "sub \"d\" { tag 4; };\n"
133 "bus \"e\" { tag 5; };\n";
135 IO::Memory mem(input, sizeof(input)-1);
136 DataFile::Parser parser(mem, "-");
137 TestCollection::Loader loader(*collection);
141 void CollectionTests::contains()
143 const TestCollection *ccoll = collection;
144 EXPECT(ccoll->contains<Foo>("a"));
145 EXPECT(ccoll->contains<Bar>("c"));
146 EXPECT(!ccoll->contains<Foo>("c"));
149 void CollectionTests::contains_base()
151 const TestCollection *ccoll = collection;
152 EXPECT(ccoll->contains<Bar>("d"));
153 EXPECT(ccoll->contains<Sub>("d"));
156 void CollectionTests::contains_loadable()
158 const TestCollection *ccoll = collection;
159 EXPECT(!ccoll->contains<Foo>("f"));
160 EXPECT(collection->contains<Foo>("f"));
163 void CollectionTests::names()
165 const TestCollection *ccoll = collection;
166 list<string> nm = ccoll->get_names<Foo>();
167 EXPECT_EQUAL(nm.size(), 2);
168 set<string> nm_set(nm.begin(), nm.end());
169 EXPECT_EQUAL(nm_set.count("a"), 1);
170 EXPECT_EQUAL(nm_set.count("b"), 1);
173 void CollectionTests::names_base()
175 const TestCollection *ccoll = collection;
176 list<string> nm = ccoll->get_names<Bar>();
177 EXPECT_EQUAL(nm.size(), 3);
178 set<string> nm_set(nm.begin(), nm.end());
179 EXPECT_EQUAL(nm_set.count("c"), 1);
180 EXPECT_EQUAL(nm_set.count("d"), 1);
181 EXPECT_EQUAL(nm_set.count("e"), 1);
184 void CollectionTests::names_loadable()
186 list<string> nm = collection->get_names<Foo>();
187 EXPECT_EQUAL(nm.size(), 3);
188 set<string> nm_set(nm.begin(), nm.end());
189 EXPECT_EQUAL(nm_set.count("f"), 1);
192 void CollectionTests::fetch()
194 const TestCollection *ccoll = collection;
195 EXPECT_EQUAL(ccoll->get<Foo>("a").get_tag(), 1);
196 EXPECT_EQUAL(ccoll->get<Foo>("b").get_tag(), 2);
197 EXPECT_EQUAL(ccoll->get<Bar>("c").get_tag(), 3);
198 EXPECT_EQUAL(ccoll->get<Bar>("d").get_tag(), 4);
199 EXPECT_EQUAL(ccoll->get<Sub>("d").get_tag(), 4);
202 void CollectionTests::nonexistent()
204 collection->get<Bar>("z");
207 void CollectionTests::type_mismatch()
209 collection->get<Foo>("c");
212 void CollectionTests::create()
214 unsigned foo_count = Foo::get_create_count();
215 Foo &f = collection->get<Foo>("f");
216 Foo &f2 = collection->get<Foo>("f");
217 EXPECT_EQUAL(&f2, &f);
218 EXPECT(Foo::get_create_count()>foo_count);
221 void CollectionTests::list_loadable()
223 list<Foo *> nm = collection->get_list<Foo>();
224 EXPECT_EQUAL(nm.size(), 3);
225 set<Foo *> nm_set(nm.begin(), nm.end());
226 EXPECT_EQUAL(nm_set.size(), nm.size());
229 void CollectionTests::name_collision()
231 RefPtr<Foo> a = new Foo;
232 collection->add("a", a.get());
242 Base::Loader::Loader(Base &b):
243 DataFile::ObjectLoader<Base>(b)
245 add("tag", &Base::tag);
249 unsigned Foo::create_count = 0;
257 bool TestSource::is_loadable(const DataFile::CollectionItemTypeBase &, const string &name) const
262 DataFile::CollectionSource::NameList TestSource::get_names(const DataFile::CollectionItemTypeBase &) const
265 names.push_back("f");
269 void TestSource::load(DataFile::Collection &coll, const DataFile::CollectionItemTypeBase &, const string &name) const
272 coll.add("f", new Foo);
276 TestCollection::TestCollection()
278 add_type<Foo>().keyword("foo").creator(&TestCollection::create_foo);
279 add_type<Bar>().keyword("bar");
280 add_type<Sub>().keyword("sub").base<Bar>();
281 add_type<Bus>().keyword("bus").base<Bar>();
285 Foo *TestCollection::create_foo(const string &)