1 : // -*- mode: c++; tab-width: 4; indent-tabs-mode: t -*-
2 : /**
3 : * @file
4 : * @author Enrico Zini (enrico) <enrico@enricozini.org>
5 : */
6 :
7 : /*
8 : * Test for the Debtags data provider
9 : *
10 : * Copyright (C) 2003-2007 Enrico Zini <enrico@debian.org>
11 : *
12 : * This library is free software; you can redistribute it and/or
13 : * modify it under the terms of the GNU Lesser General Public
14 : * License as published by the Free Software Foundation; either
15 : * version 2.1 of the License, or (at your option) any later version.
16 : *
17 : * This library is distributed in the hope that it will be useful,
18 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 : * Lesser General Public License for more details.
21 : *
22 : * You should have received a copy of the GNU Lesser General Public
23 : * License along with this library; if not, write to the Free Software
24 : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 : */
26 :
27 :
28 : #include <ept/debtags/debtags.h>
29 : #include <ept/core/apt.h>
30 :
31 : #include <tagcoll/coll/simple.h>
32 : #include <tagcoll/stream/sink.h>
33 :
34 : #include <wibble/operators.h>
35 :
36 : #include <ept/test.h>
37 :
38 : #ifndef EPT_DEBTAGS_TESTH
39 : #define EPT_DEBTAGS_TESTH
40 :
41 : using namespace tagcoll;
42 : using namespace std;
43 : using namespace ept;
44 : using namespace ept::debtags;
45 : using namespace wibble::operators;
46 :
47 : struct TestDebtags : DebtagsTestEnvironment
48 5 : {
49 : Debtags debtags;
50 :
51 5 : TestDebtags() {}
52 :
53 10 : Vocabulary& voc() { return debtags.vocabulary(); }
54 :
55 1 : Test _1() {
56 21146 : for (Debtags::const_iterator i = debtags.begin(); i != debtags.end(); ++i)
57 : {
58 21145 : *i;
59 21145 : i->first;
60 21145 : i->second;
61 1 : }
62 1 : int items = 0, tags = 0;
63 1 : debtags.outputSystem(stream::countingSink(items, tags));
64 :
65 1 : int pitems = 0, ptags = 0;
66 1 : debtags.outputPatched(stream::countingSink(pitems, ptags));
67 :
68 2 : assert(items > 10);
69 2 : assert(tags > 10);
70 2 : assert(items <= pitems);
71 2 : assert(tags <= ptags);
72 1 : }
73 :
74 1 : Test _2()
75 : {
76 1 : string p("debtags");
77 1 : std::set<Tag> tags = debtags.getTagsOfItem(p);
78 1 : assert( !tags.empty() );
79 :
80 : #if 0
81 : for ( std::set< Tag >::iterator i = tags.begin(); i != tags.end(); ++ i ) {
82 : std::cerr << i->id() << ": " << i->fullname() << std::endl;
83 : }
84 : std::cerr << "---" << std::endl;
85 : Tag t = voc().tagByName( "interface::commandline" );
86 : std::cerr << t.id() << ": " << t.fullname() << std::endl;
87 : #endif
88 :
89 2 : assert_eq( tags.size(), 8u );
90 2 : assert( voc().tagByName( "devel::buildtools" ) <= tags );
91 2 : assert( voc().tagByName( "implemented-in::c++" ) <= tags );
92 2 : assert( voc().tagByName( "interface::commandline" ) <= tags );
93 2 : assert( voc().tagByName( "role::program" ) <= tags );
94 2 : assert( voc().tagByName( "scope::application" ) <= tags );
95 2 : assert( voc().tagByName( "suite::debian" ) <= tags );
96 2 : assert( voc().tagByName( "use::searching" ) <= tags );
97 2 : assert( voc().tagByName( "works-with::software:package" ) <= tags );
98 1 : }
99 :
100 1 : Test _3()
101 : {
102 : using namespace std;
103 :
104 : /* Get the 'debtags' package */
105 1 : string p("debtags");
106 :
107 : /* Get its tags */
108 1 : std::set<Tag> tags = debtags.getTagsOfItem(p);
109 1 : assert(!tags.empty());
110 :
111 : /*
112 : cerr << "Intersection size: " << endl;
113 : using namespace wibble::operators;
114 : std::set<Tag>::const_iterator dbgi = tags.begin();
115 : cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl;
116 : std::set<int> dbgres = debtags.tagdb().getItemsHavingTag(dbgi->id());
117 : std::set<Package> dbgpres = debtags.getItemsHavingTag(*dbgi);
118 : cerr << " #pkgs " << dbgres.size() << " == " << dbgpres.size() << endl;
119 : cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl;
120 : cerr << " "; ppset(dbgpres); cerr << endl;
121 : cerr << " "; piset(dbgres); cerr << endl;
122 : for (++dbgi ; dbgi != tags.end(); ++dbgi)
123 : {
124 : cerr << "* " << dbgi->fullname() << ": " << dbgi->id() << endl;
125 : std::set<Package> dbgpkgs = debtags.getItemsHavingTag(*dbgi);
126 : std::set<int> dbgids = debtags.tagdb().getItemsHavingTag(dbgi->id());
127 : cerr << " "; ppset(dbgpkgs); cerr << endl;
128 : cerr << " "; piset(dbgids); cerr << endl;
129 : cerr << " #pkgs " << dbgpkgs.size() << " == " << dbgids.size() << endl;
130 : dbgres &= dbgids;
131 : dbgpres &= dbgpkgs;
132 : cerr << " #isec " << dbgres.size() << " == " << dbgpres.size() << endl;
133 : }
134 : cerr << " " << dbgres.size() << endl << "Results: " << endl;
135 : for (std::set<int>::const_iterator i = dbgres.begin(); i != dbgres.end(); ++i)
136 : cerr << " " << *i << endl;
137 : */
138 :
139 :
140 : // cerr << "Tags of debtags: ";
141 : // for (std::set<Tag>::const_iterator i = tags.begin(); i != tags.end(); ++i)
142 : // {
143 : // cerr << " " + i->fullname() << endl;
144 : // std::set<Package> packages = debtags.getItemsHavingTag(*i);
145 : // for (std::set<Package>::const_iterator p = packages.begin();
146 : // p != packages.end(); ++p)
147 : // cerr << " PKG " << p->name() << endl;
148 : // }
149 : // cerr << endl;
150 :
151 : /* Get the items for the tagset of 'debtags' */
152 1 : std::set<string> packages = debtags.getItemsHavingTags(tags);
153 : //cerr << packages.size() << endl;
154 1 : assert(!packages.empty());
155 : /*
156 : for ( std::set< Package >::iterator i = packages.begin(); i != packages.end(); ++ i )
157 : std::cerr << i->name() << std::endl;
158 : std::cerr << "---" << std::endl;
159 : std::cerr << p.name() << std::endl;
160 : */
161 : /* They should at least contain 'debtags' */
162 2 : assert( p <= packages );
163 :
164 : /* Get one of the tags of 'debtags' */
165 2 : Tag tag = *tags.begin();
166 1 : assert(tag);
167 :
168 : /* Get its items */
169 : {
170 : /* Need this workaround until I figure out how to tell the new GCC
171 : * that TagDB is a TDBReadonlyDiskIndex and should behave as such
172 : */
173 1 : std::set<Tag> ts;
174 1 : ts.insert(tag);
175 1 : packages = debtags.getItemsHavingTags(ts);
176 : }
177 : //packages = c.debtags().tagdb().getItems(tag);
178 1 : assert(!packages.empty());
179 : /* They should at least contain 'debtags' */
180 2 : assert( p <= packages );
181 :
182 : //c.debtags().getTags(""); // XXX HACK AWW!
183 1 : }
184 :
185 1 : Test _4()
186 : {
187 1 : std::string patchfile = Path::debtagsUserSourceDir() + "patch";
188 1 : unlink(patchfile.c_str());
189 :
190 1 : string p("debtags");
191 :
192 : /* Get its tags */
193 1 : std::set<Tag> tags = debtags.getTagsOfItem(p);
194 1 : assert(!tags.empty());
195 :
196 : // Ensure that it's not tagged with gameplaying
197 2 : Tag t = voc().tagByName("use::gameplaying");
198 2 : assert(! (t <= tags) );
199 :
200 : // Add the gameplaying tag
201 1 : PatchList<string, Tag> change;
202 1 : change.addPatch(Patch<string, Tag>(p, wibble::singleton(t), wibble::Empty<Tag>()));
203 1 : debtags.applyChange(change);
204 :
205 : // See that the patch is non empty
206 1 : PatchList<string, Tag> tmp = debtags.changes();
207 1 : assert(tmp.size() > 0);
208 2 : assert_eq(tmp.size(), 1u);
209 :
210 : // Ensure that the tag has been added
211 2 : tags = debtags.getTagsOfItem(p);
212 1 : assert(!tags.empty());
213 :
214 2 : t = voc().tagByName("use::gameplaying");
215 2 : assert( t <= tags );
216 :
217 : // Save the patch
218 1 : debtags.savePatch();
219 :
220 : // Check that the saved patch is correct
221 1 : FILE* in = fopen(patchfile.c_str(), "r");
222 1 : string writtenPatch;
223 : int c;
224 29 : while ((c = getc(in)) != EOF)
225 27 : writtenPatch += c;
226 1 : fclose(in);
227 :
228 1 : assert_eq(writtenPatch, string("debtags: +use::gameplaying\n"));
229 :
230 2 : unlink(patchfile.c_str());
231 :
232 : // Reapply the patch and see that it doesn't disrept things
233 1 : debtags.applyChange(change);
234 :
235 : // The patch should not have changed
236 1 : tmp = debtags.changes();
237 1 : assert_eq(tmp.size(), 1u);
238 2 : assert_eq(tmp.begin()->first, p);
239 1 : assert_eq(tmp.begin()->second.item, p);
240 1 : }
241 :
242 : // If there is no data, Debtags should work as an empty collection
243 1 : Test _5()
244 : {
245 1 : Path::OverrideDebtagsSourceDir odsd("./empty");
246 2 : Path::OverrideDebtagsIndexDir odid("./empty");
247 2 : Path::OverrideDebtagsUserSourceDir odusd("./empty");
248 2 : Path::OverrideDebtagsUserIndexDir oduid("./empty");
249 1 : Debtags empty;
250 :
251 1 : assert(empty.begin() == empty.end());
252 1 : assert_eq(empty.timestamp(), 0);
253 2 : assert(!empty.hasData());
254 :
255 1 : tagcoll::PatchList<std::string, Tag> patches = empty.changes();
256 1 : assert(patches.empty());
257 :
258 2 : set<Tag> res = empty.getTagsOfItem("apt");
259 2 : assert(res.empty());
260 2 : res = empty.getTagsOfItems(wibble::singleton(string("apt")));
261 2 : assert(res.empty());
262 :
263 2 : res = empty.getAllTags();
264 1 : assert(res.empty());
265 :
266 1 : tagcoll::coll::Simple<string, Tag> coll;
267 1 : empty.outputSystem(tagcoll::coll::inserter(coll));
268 1 : assert_eq(coll.itemCount(), 0u);
269 :
270 1 : coll.clear();
271 :
272 1 : empty.outputPatched(tagcoll::coll::inserter(coll));
273 1 : assert_eq(coll.itemCount(), 0u);
274 1 : }
275 :
276 : };
277 :
278 : #include <ept/debtags/debtags.tcc>
279 : #include <tagcoll/coll/simple.tcc>
280 :
281 : #endif
282 :
283 : // vim:set ts=4 sw=4:
|