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_future();
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;
88 class TestCollection: public DataFile::Collection
97 Foo *create_foo(const string &);
101 CollectionTests::CollectionTests()
103 add(&CollectionTests::load, "Load objects");
104 add(&CollectionTests::contains, "Containment test");
105 add(&CollectionTests::contains_base, "Base class containment test");
106 add(&CollectionTests::contains_future, "Future containment test");
107 add(&CollectionTests::names, "List object names");
108 add(&CollectionTests::names_base, "List base class object names");
109 add(&CollectionTests::names_future, "List future object names");
110 add(&CollectionTests::fetch, "Fetch objects");
111 add(&CollectionTests::nonexistent, "Nonexistent object").expect_throw<key_error>();
112 add(&CollectionTests::type_mismatch, "Type mismatch").expect_throw<Msp::type_mismatch>();
113 add(&CollectionTests::create, "Create object");
114 add(&CollectionTests::list_future, "List future objects");
115 add(&CollectionTests::name_collision, "Name collision").expect_throw<Msp::key_error>();
117 collection = new TestCollection;
120 CollectionTests::~CollectionTests()
125 void CollectionTests::load()
128 "foo \"a\" { tag 1; };\n"
129 "foo \"b\" { tag 2; };\n"
130 "bar \"c\" { tag 3; };\n"
131 "sub \"d\" { tag 4; };\n"
132 "bus \"e\" { tag 5; };\n";
134 IO::Memory mem(input, sizeof(input)-1);
135 DataFile::Parser parser(mem, "-");
136 TestCollection::Loader loader(*collection);
140 void CollectionTests::contains()
142 const TestCollection *ccoll = collection;
143 EXPECT(ccoll->contains<Foo>("a"));
144 EXPECT(ccoll->contains<Bar>("c"));
145 EXPECT(!ccoll->contains<Foo>("c"));
148 void CollectionTests::contains_base()
150 const TestCollection *ccoll = collection;
151 EXPECT(ccoll->contains<Bar>("d"));
152 EXPECT(ccoll->contains<Sub>("d"));
155 void CollectionTests::contains_future()
157 const TestCollection *ccoll = collection;
158 EXPECT(!ccoll->contains<Foo>("f"));
159 EXPECT(collection->contains<Foo>("f"));
162 void CollectionTests::names()
164 const TestCollection *ccoll = collection;
165 list<string> nm = ccoll->get_names<Foo>();
166 EXPECT_EQUAL(nm.size(), 2);
167 set<string> nm_set(nm.begin(), nm.end());
168 EXPECT_EQUAL(nm_set.count("a"), 1);
169 EXPECT_EQUAL(nm_set.count("b"), 1);
172 void CollectionTests::names_base()
174 const TestCollection *ccoll = collection;
175 list<string> nm = ccoll->get_names<Bar>();
176 EXPECT_EQUAL(nm.size(), 3);
177 set<string> nm_set(nm.begin(), nm.end());
178 EXPECT_EQUAL(nm_set.count("c"), 1);
179 EXPECT_EQUAL(nm_set.count("d"), 1);
180 EXPECT_EQUAL(nm_set.count("e"), 1);
183 void CollectionTests::names_future()
185 list<string> nm = collection->get_names<Foo>();
186 EXPECT_EQUAL(nm.size(), 3);
187 set<string> nm_set(nm.begin(), nm.end());
188 EXPECT_EQUAL(nm_set.count("f"), 1);
191 void CollectionTests::fetch()
193 const TestCollection *ccoll = collection;
194 EXPECT_EQUAL(ccoll->get<Foo>("a").get_tag(), 1);
195 EXPECT_EQUAL(ccoll->get<Foo>("b").get_tag(), 2);
196 EXPECT_EQUAL(ccoll->get<Bar>("c").get_tag(), 3);
197 EXPECT_EQUAL(ccoll->get<Bar>("d").get_tag(), 4);
198 EXPECT_EQUAL(ccoll->get<Sub>("d").get_tag(), 4);
201 void CollectionTests::nonexistent()
203 collection->get<Bar>("z");
206 void CollectionTests::type_mismatch()
208 collection->get<Foo>("c");
211 void CollectionTests::create()
213 unsigned foo_count = Foo::get_create_count();
214 Foo &f = collection->get<Foo>("f");
215 Foo &f2 = collection->get<Foo>("f");
216 EXPECT_EQUAL(&f2, &f);
217 EXPECT(Foo::get_create_count()>foo_count);
220 void CollectionTests::list_future()
222 list<Foo *> nm = collection->get_list<Foo>();
223 EXPECT_EQUAL(nm.size(), 3);
224 set<Foo *> nm_set(nm.begin(), nm.end());
225 EXPECT_EQUAL(nm_set.size(), nm.size());
228 void CollectionTests::name_collision()
230 RefPtr<Foo> a = new Foo;
231 collection->add("a", a.get());
241 Base::Loader::Loader(Base &b):
242 DataFile::ObjectLoader<Base>(b)
244 add("tag", &Base::tag);
248 unsigned Foo::create_count = 0;
256 bool TestSource::is_loadable(const DataFile::CollectionItemTypeBase &, const string &name) const
261 DataFile::CollectionSource::NameList TestSource::get_names(const DataFile::CollectionItemTypeBase &) const
264 names.push_back("f");
268 void TestSource::load(DataFile::Collection &coll, const DataFile::CollectionItemTypeBase &, const string &name) const
271 coll.add("f", new Foo);
275 TestCollection::TestCollection()
277 add_type<Foo>().keyword("foo").creator(&TestCollection::create_foo);
278 add_type<Bar>().keyword("bar");
279 add_type<Sub>().keyword("sub").base<Bar>();
280 add_type<Bus>().keyword("bus").base<Bar>();
284 Foo *TestCollection::create_foo(const string &)