1 // Copyright 2011 The Kyua Authors.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 //   notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 //   notice, this list of conditions and the following disclaimer in the
12 //   documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 //   may be used to endorse or promote products derived from this software
15 //   without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include "engine/filters.hpp"
30 
31 #include <stdexcept>
32 
33 #include <atf-c++.hpp>
34 
35 namespace fs = utils::fs;
36 
37 
38 namespace {
39 
40 
41 /// Syntactic sugar to instantiate engine::test_filter objects.
42 ///
43 /// \param test_program Test program.
44 /// \param test_case Test case.
45 ///
46 /// \return A \p test_filter object, based on \p test_program and \p test_case.
47 inline engine::test_filter
mkfilter(const char * test_program,const char * test_case)48 mkfilter(const char* test_program, const char* test_case)
49 {
50     return engine::test_filter(fs::path(test_program), test_case);
51 }
52 
53 
54 }  // anonymous namespace
55 
56 
57 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__public_fields);
ATF_TEST_CASE_BODY(test_filter__public_fields)58 ATF_TEST_CASE_BODY(test_filter__public_fields)
59 {
60     const engine::test_filter filter(fs::path("foo/bar"), "baz");
61     ATF_REQUIRE_EQ(fs::path("foo/bar"), filter.test_program);
62     ATF_REQUIRE_EQ("baz", filter.test_case);
63 }
64 
65 
66 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__parse__ok);
ATF_TEST_CASE_BODY(test_filter__parse__ok)67 ATF_TEST_CASE_BODY(test_filter__parse__ok)
68 {
69     const engine::test_filter filter(engine::test_filter::parse("foo"));
70     ATF_REQUIRE_EQ(fs::path("foo"), filter.test_program);
71     ATF_REQUIRE(filter.test_case.empty());
72 }
73 
74 
75 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__parse__empty);
ATF_TEST_CASE_BODY(test_filter__parse__empty)76 ATF_TEST_CASE_BODY(test_filter__parse__empty)
77 {
78     ATF_REQUIRE_THROW_RE(std::runtime_error, "empty",
79                          engine::test_filter::parse(""));
80 }
81 
82 
83 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__parse__absolute);
ATF_TEST_CASE_BODY(test_filter__parse__absolute)84 ATF_TEST_CASE_BODY(test_filter__parse__absolute)
85 {
86     ATF_REQUIRE_THROW_RE(std::runtime_error, "'/foo/bar'.*relative",
87                          engine::test_filter::parse("/foo//bar"));
88 }
89 
90 
91 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__parse__bad_program_name);
ATF_TEST_CASE_BODY(test_filter__parse__bad_program_name)92 ATF_TEST_CASE_BODY(test_filter__parse__bad_program_name)
93 {
94     ATF_REQUIRE_THROW_RE(std::runtime_error, "Program name.*':foo'",
95                          engine::test_filter::parse(":foo"));
96 }
97 
98 
99 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__parse__bad_test_case);
ATF_TEST_CASE_BODY(test_filter__parse__bad_test_case)100 ATF_TEST_CASE_BODY(test_filter__parse__bad_test_case)
101 {
102     ATF_REQUIRE_THROW_RE(std::runtime_error, "Test case.*'bar/baz:'",
103                          engine::test_filter::parse("bar/baz:"));
104 }
105 
106 
107 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__parse__bad_path);
ATF_TEST_CASE_BODY(test_filter__parse__bad_path)108 ATF_TEST_CASE_BODY(test_filter__parse__bad_path)
109 {
110     // TODO(jmmv): Not implemented.  At the moment, the only reason for a path
111     // to be invalid is if it is empty... but we are checking this exact
112     // condition ourselves as part of the input validation.  So we can't mock in
113     // an argument with an invalid non-empty path...
114 }
115 
116 
117 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__str);
ATF_TEST_CASE_BODY(test_filter__str)118 ATF_TEST_CASE_BODY(test_filter__str)
119 {
120     const engine::test_filter filter(fs::path("foo/bar"), "baz");
121     ATF_REQUIRE_EQ("foo/bar:baz", filter.str());
122 }
123 
124 
125 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__contains__same);
ATF_TEST_CASE_BODY(test_filter__contains__same)126 ATF_TEST_CASE_BODY(test_filter__contains__same)
127 {
128     {
129         const engine::test_filter f(fs::path("foo/bar"), "baz");
130         ATF_REQUIRE(f.contains(f));
131     }
132     {
133         const engine::test_filter f(fs::path("foo/bar"), "");
134         ATF_REQUIRE(f.contains(f));
135     }
136     {
137         const engine::test_filter f(fs::path("foo"), "");
138         ATF_REQUIRE(f.contains(f));
139     }
140 }
141 
142 
143 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__contains__different);
ATF_TEST_CASE_BODY(test_filter__contains__different)144 ATF_TEST_CASE_BODY(test_filter__contains__different)
145 {
146     {
147         const engine::test_filter f1(fs::path("foo"), "");
148         const engine::test_filter f2(fs::path("foo"), "bar");
149         ATF_REQUIRE( f1.contains(f2));
150         ATF_REQUIRE(!f2.contains(f1));
151     }
152     {
153         const engine::test_filter f1(fs::path("foo/bar"), "");
154         const engine::test_filter f2(fs::path("foo/bar"), "baz");
155         ATF_REQUIRE( f1.contains(f2));
156         ATF_REQUIRE(!f2.contains(f1));
157     }
158     {
159         const engine::test_filter f1(fs::path("foo/bar"), "");
160         const engine::test_filter f2(fs::path("foo/baz"), "");
161         ATF_REQUIRE(!f1.contains(f2));
162         ATF_REQUIRE(!f2.contains(f1));
163     }
164     {
165         const engine::test_filter f1(fs::path("foo"), "");
166         const engine::test_filter f2(fs::path("foo/bar"), "");
167         ATF_REQUIRE( f1.contains(f2));
168         ATF_REQUIRE(!f2.contains(f1));
169     }
170     {
171         const engine::test_filter f1(fs::path("foo"), "bar");
172         const engine::test_filter f2(fs::path("foo/bar"), "");
173         ATF_REQUIRE(!f1.contains(f2));
174         ATF_REQUIRE(!f2.contains(f1));
175     }
176 }
177 
178 
179 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__matches_test_program)
ATF_TEST_CASE_BODY(test_filter__matches_test_program)180 ATF_TEST_CASE_BODY(test_filter__matches_test_program)
181 {
182     {
183         const engine::test_filter f(fs::path("top"), "unused");
184         ATF_REQUIRE( f.matches_test_program(fs::path("top")));
185         ATF_REQUIRE(!f.matches_test_program(fs::path("top2")));
186     }
187 
188     {
189         const engine::test_filter f(fs::path("dir1/dir2"), "");
190         ATF_REQUIRE( f.matches_test_program(fs::path("dir1/dir2/foo")));
191         ATF_REQUIRE( f.matches_test_program(fs::path("dir1/dir2/bar")));
192         ATF_REQUIRE( f.matches_test_program(fs::path("dir1/dir2/bar/baz")));
193         ATF_REQUIRE( f.matches_test_program(fs::path("dir1/dir2/bar/baz")));
194         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1")));
195         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1/bar/baz")));
196         ATF_REQUIRE(!f.matches_test_program(fs::path("dir2/bar/baz")));
197     }
198 
199     {
200         const engine::test_filter f(fs::path("dir1/dir2"), "unused");
201         ATF_REQUIRE( f.matches_test_program(fs::path("dir1/dir2")));
202         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1/dir2/foo")));
203         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1/dir2/bar")));
204         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1/dir2/bar/baz")));
205         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1/dir2/bar/baz")));
206         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1")));
207         ATF_REQUIRE(!f.matches_test_program(fs::path("dir1/bar/baz")));
208         ATF_REQUIRE(!f.matches_test_program(fs::path("dir2/bar/baz")));
209     }
210 }
211 
212 
213 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__matches_test_case)
ATF_TEST_CASE_BODY(test_filter__matches_test_case)214 ATF_TEST_CASE_BODY(test_filter__matches_test_case)
215 {
216     {
217         const engine::test_filter f(fs::path("top"), "foo");
218         ATF_REQUIRE( f.matches_test_case(fs::path("top"), "foo"));
219         ATF_REQUIRE(!f.matches_test_case(fs::path("top"), "bar"));
220     }
221 
222     {
223         const engine::test_filter f(fs::path("top"), "");
224         ATF_REQUIRE( f.matches_test_case(fs::path("top"), "foo"));
225         ATF_REQUIRE( f.matches_test_case(fs::path("top"), "bar"));
226         ATF_REQUIRE(!f.matches_test_case(fs::path("top2"), "foo"));
227     }
228 
229     {
230         const engine::test_filter f(fs::path("d1/d2/prog"), "t1");
231         ATF_REQUIRE( f.matches_test_case(fs::path("d1/d2/prog"), "t1"));
232         ATF_REQUIRE(!f.matches_test_case(fs::path("d1/d2/prog"), "t2"));
233     }
234 
235     {
236         const engine::test_filter f(fs::path("d1/d2"), "");
237         ATF_REQUIRE( f.matches_test_case(fs::path("d1/d2/prog"), "t1"));
238         ATF_REQUIRE( f.matches_test_case(fs::path("d1/d2/prog"), "t2"));
239         ATF_REQUIRE( f.matches_test_case(fs::path("d1/d2/prog2"), "t2"));
240         ATF_REQUIRE(!f.matches_test_case(fs::path("d1/d3"), "foo"));
241         ATF_REQUIRE(!f.matches_test_case(fs::path("d2"), "foo"));
242     }
243 }
244 
245 
246 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__operator_lt)
ATF_TEST_CASE_BODY(test_filter__operator_lt)247 ATF_TEST_CASE_BODY(test_filter__operator_lt)
248 {
249     {
250         const engine::test_filter f1(fs::path("d1/d2"), "");
251         ATF_REQUIRE(!(f1 < f1));
252     }
253     {
254         const engine::test_filter f1(fs::path("d1/d2"), "");
255         const engine::test_filter f2(fs::path("d1/d3"), "");
256         ATF_REQUIRE( (f1 < f2));
257         ATF_REQUIRE(!(f2 < f1));
258     }
259     {
260         const engine::test_filter f1(fs::path("d1/d2"), "");
261         const engine::test_filter f2(fs::path("d1/d2"), "foo");
262         ATF_REQUIRE( (f1 < f2));
263         ATF_REQUIRE(!(f2 < f1));
264     }
265     {
266         const engine::test_filter f1(fs::path("d1/d2"), "bar");
267         const engine::test_filter f2(fs::path("d1/d2"), "foo");
268         ATF_REQUIRE( (f1 < f2));
269         ATF_REQUIRE(!(f2 < f1));
270     }
271     {
272         const engine::test_filter f1(fs::path("d1/d2"), "bar");
273         const engine::test_filter f2(fs::path("d1/d3"), "");
274         ATF_REQUIRE( (f1 < f2));
275         ATF_REQUIRE(!(f2 < f1));
276     }
277 }
278 
279 
280 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__operator_eq)
ATF_TEST_CASE_BODY(test_filter__operator_eq)281 ATF_TEST_CASE_BODY(test_filter__operator_eq)
282 {
283     const engine::test_filter f1(fs::path("d1/d2"), "");
284     const engine::test_filter f2(fs::path("d1/d2"), "bar");
285     ATF_REQUIRE( (f1 == f1));
286     ATF_REQUIRE(!(f1 == f2));
287     ATF_REQUIRE(!(f2 == f1));
288     ATF_REQUIRE( (f2 == f2));
289 }
290 
291 
292 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__operator_ne)
ATF_TEST_CASE_BODY(test_filter__operator_ne)293 ATF_TEST_CASE_BODY(test_filter__operator_ne)
294 {
295     const engine::test_filter f1(fs::path("d1/d2"), "");
296     const engine::test_filter f2(fs::path("d1/d2"), "bar");
297     ATF_REQUIRE(!(f1 != f1));
298     ATF_REQUIRE( (f1 != f2));
299     ATF_REQUIRE( (f2 != f1));
300     ATF_REQUIRE(!(f2 != f2));
301 }
302 
303 
304 ATF_TEST_CASE_WITHOUT_HEAD(test_filter__output);
ATF_TEST_CASE_BODY(test_filter__output)305 ATF_TEST_CASE_BODY(test_filter__output)
306 {
307     {
308         std::ostringstream str;
309         str << engine::test_filter(fs::path("d1/d2"), "");
310         ATF_REQUIRE_EQ(
311             "test_filter{test_program=d1/d2}",
312             str.str());
313     }
314     {
315         std::ostringstream str;
316         str << engine::test_filter(fs::path("d1/d2"), "bar");
317         ATF_REQUIRE_EQ(
318             "test_filter{test_program=d1/d2, test_case=bar}",
319             str.str());
320     }
321 }
322 
323 
324 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__match_test_case__no_filters)
ATF_TEST_CASE_BODY(test_filters__match_test_case__no_filters)325 ATF_TEST_CASE_BODY(test_filters__match_test_case__no_filters)
326 {
327     const std::set< engine::test_filter > raw_filters;
328 
329     const engine::test_filters filters(raw_filters);
330     engine::test_filters::match match;
331 
332     match = filters.match_test_case(fs::path("foo"), "baz");
333     ATF_REQUIRE(match.first);
334     ATF_REQUIRE(!match.second);
335 
336     match = filters.match_test_case(fs::path("foo/bar"), "baz");
337     ATF_REQUIRE(match.first);
338     ATF_REQUIRE(!match.second);
339 }
340 
341 
342 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__match_test_case__some_filters)
ATF_TEST_CASE_BODY(test_filters__match_test_case__some_filters)343 ATF_TEST_CASE_BODY(test_filters__match_test_case__some_filters)
344 {
345     std::set< engine::test_filter > raw_filters;
346     raw_filters.insert(mkfilter("top_test", ""));
347     raw_filters.insert(mkfilter("subdir_1", ""));
348     raw_filters.insert(mkfilter("subdir_2/a_test", ""));
349     raw_filters.insert(mkfilter("subdir_2/b_test", "foo"));
350 
351     const engine::test_filters filters(raw_filters);
352     engine::test_filters::match match;
353 
354     match = filters.match_test_case(fs::path("top_test"), "a");
355     ATF_REQUIRE(match.first);
356     ATF_REQUIRE_EQ("top_test", match.second.get().str());
357 
358     match = filters.match_test_case(fs::path("subdir_1/foo"), "a");
359     ATF_REQUIRE(match.first);
360     ATF_REQUIRE_EQ("subdir_1", match.second.get().str());
361 
362     match = filters.match_test_case(fs::path("subdir_1/bar"), "z");
363     ATF_REQUIRE(match.first);
364     ATF_REQUIRE_EQ("subdir_1", match.second.get().str());
365 
366     match = filters.match_test_case(fs::path("subdir_2/a_test"), "bar");
367     ATF_REQUIRE(match.first);
368     ATF_REQUIRE_EQ("subdir_2/a_test", match.second.get().str());
369 
370     match = filters.match_test_case(fs::path("subdir_2/b_test"), "foo");
371     ATF_REQUIRE(match.first);
372     ATF_REQUIRE_EQ("subdir_2/b_test:foo", match.second.get().str());
373 
374     match = filters.match_test_case(fs::path("subdir_2/b_test"), "bar");
375     ATF_REQUIRE(!match.first);
376 
377     match = filters.match_test_case(fs::path("subdir_2/c_test"), "foo");
378     ATF_REQUIRE(!match.first);
379 
380     match = filters.match_test_case(fs::path("subdir_3"), "hello");
381     ATF_REQUIRE(!match.first);
382 }
383 
384 
385 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__match_test_program__no_filters)
ATF_TEST_CASE_BODY(test_filters__match_test_program__no_filters)386 ATF_TEST_CASE_BODY(test_filters__match_test_program__no_filters)
387 {
388     const std::set< engine::test_filter > raw_filters;
389 
390     const engine::test_filters filters(raw_filters);
391     ATF_REQUIRE(filters.match_test_program(fs::path("foo")));
392     ATF_REQUIRE(filters.match_test_program(fs::path("foo/bar")));
393 }
394 
395 
396 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__match_test_program__some_filters)
ATF_TEST_CASE_BODY(test_filters__match_test_program__some_filters)397 ATF_TEST_CASE_BODY(test_filters__match_test_program__some_filters)
398 {
399     std::set< engine::test_filter > raw_filters;
400     raw_filters.insert(mkfilter("top_test", ""));
401     raw_filters.insert(mkfilter("subdir_1", ""));
402     raw_filters.insert(mkfilter("subdir_2/a_test", ""));
403     raw_filters.insert(mkfilter("subdir_2/b_test", "foo"));
404 
405     const engine::test_filters filters(raw_filters);
406     ATF_REQUIRE( filters.match_test_program(fs::path("top_test")));
407     ATF_REQUIRE( filters.match_test_program(fs::path("subdir_1/foo")));
408     ATF_REQUIRE( filters.match_test_program(fs::path("subdir_1/bar")));
409     ATF_REQUIRE( filters.match_test_program(fs::path("subdir_2/a_test")));
410     ATF_REQUIRE( filters.match_test_program(fs::path("subdir_2/b_test")));
411     ATF_REQUIRE(!filters.match_test_program(fs::path("subdir_2/c_test")));
412     ATF_REQUIRE(!filters.match_test_program(fs::path("subdir_3")));
413 }
414 
415 
416 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__difference__no_filters);
ATF_TEST_CASE_BODY(test_filters__difference__no_filters)417 ATF_TEST_CASE_BODY(test_filters__difference__no_filters)
418 {
419     const std::set< engine::test_filter > in_filters;
420     const std::set< engine::test_filter > used;
421     const std::set< engine::test_filter > diff = engine::test_filters(
422         in_filters).difference(used);
423     ATF_REQUIRE(diff.empty());
424 }
425 
426 
427 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__difference__some_filters__all_used);
ATF_TEST_CASE_BODY(test_filters__difference__some_filters__all_used)428 ATF_TEST_CASE_BODY(test_filters__difference__some_filters__all_used)
429 {
430     std::set< engine::test_filter > in_filters;
431     in_filters.insert(mkfilter("a", ""));
432     in_filters.insert(mkfilter("b", "c"));
433 
434     const std::set< engine::test_filter > used = in_filters;
435 
436     const std::set< engine::test_filter > diff = engine::test_filters(
437         in_filters).difference(used);
438     ATF_REQUIRE(diff.empty());
439 }
440 
441 
442 ATF_TEST_CASE_WITHOUT_HEAD(test_filters__difference__some_filters__some_unused);
ATF_TEST_CASE_BODY(test_filters__difference__some_filters__some_unused)443 ATF_TEST_CASE_BODY(test_filters__difference__some_filters__some_unused)
444 {
445     std::set< engine::test_filter > in_filters;
446     in_filters.insert(mkfilter("a", ""));
447     in_filters.insert(mkfilter("b", "c"));
448     in_filters.insert(mkfilter("d", ""));
449     in_filters.insert(mkfilter("e", "f"));
450 
451     std::set< engine::test_filter > used;
452     used.insert(mkfilter("b", "c"));
453     used.insert(mkfilter("d", ""));
454 
455     const std::set< engine::test_filter > diff = engine::test_filters(
456         in_filters).difference(used);
457     ATF_REQUIRE_EQ(2, diff.size());
458     ATF_REQUIRE(diff.find(mkfilter("a", "")) != diff.end());
459     ATF_REQUIRE(diff.find(mkfilter("e", "f")) != diff.end());
460 }
461 
462 
463 ATF_TEST_CASE_WITHOUT_HEAD(check_disjoint_filters__ok);
ATF_TEST_CASE_BODY(check_disjoint_filters__ok)464 ATF_TEST_CASE_BODY(check_disjoint_filters__ok)
465 {
466     std::set< engine::test_filter > filters;
467     filters.insert(mkfilter("a", ""));
468     filters.insert(mkfilter("b", ""));
469     filters.insert(mkfilter("c", "a"));
470     filters.insert(mkfilter("c", "b"));
471 
472     engine::check_disjoint_filters(filters);
473 }
474 
475 
476 ATF_TEST_CASE_WITHOUT_HEAD(check_disjoint_filters__fail);
ATF_TEST_CASE_BODY(check_disjoint_filters__fail)477 ATF_TEST_CASE_BODY(check_disjoint_filters__fail)
478 {
479     std::set< engine::test_filter > filters;
480     filters.insert(mkfilter("a", ""));
481     filters.insert(mkfilter("b", ""));
482     filters.insert(mkfilter("c", "a"));
483     filters.insert(mkfilter("d", "b"));
484     filters.insert(mkfilter("c", ""));
485 
486     ATF_REQUIRE_THROW_RE(std::runtime_error, "'c'.*'c:a'.*not disjoint",
487                          engine::check_disjoint_filters(filters));
488 }
489 
490 
491 ATF_TEST_CASE_WITHOUT_HEAD(filters_state__match_test_program);
ATF_TEST_CASE_BODY(filters_state__match_test_program)492 ATF_TEST_CASE_BODY(filters_state__match_test_program)
493 {
494     std::set< engine::test_filter > filters;
495     filters.insert(mkfilter("foo/bar", ""));
496     filters.insert(mkfilter("baz", "tc"));
497     engine::filters_state state(filters);
498 
499     ATF_REQUIRE(state.match_test_program(fs::path("foo/bar/something")));
500     ATF_REQUIRE(state.match_test_program(fs::path("baz")));
501 
502     ATF_REQUIRE(!state.match_test_program(fs::path("foo/baz")));
503     ATF_REQUIRE(!state.match_test_program(fs::path("hello")));
504 }
505 
506 
507 ATF_TEST_CASE_WITHOUT_HEAD(filters_state__match_test_case);
ATF_TEST_CASE_BODY(filters_state__match_test_case)508 ATF_TEST_CASE_BODY(filters_state__match_test_case)
509 {
510     std::set< engine::test_filter > filters;
511     filters.insert(mkfilter("foo/bar", ""));
512     filters.insert(mkfilter("baz", "tc"));
513     engine::filters_state state(filters);
514 
515     ATF_REQUIRE(state.match_test_case(fs::path("foo/bar/something"), "any"));
516     ATF_REQUIRE(state.match_test_case(fs::path("baz"), "tc"));
517 
518     ATF_REQUIRE(!state.match_test_case(fs::path("foo/baz/something"), "tc"));
519     ATF_REQUIRE(!state.match_test_case(fs::path("baz"), "tc2"));
520 }
521 
522 
523 ATF_TEST_CASE_WITHOUT_HEAD(filters_state__unused__none);
ATF_TEST_CASE_BODY(filters_state__unused__none)524 ATF_TEST_CASE_BODY(filters_state__unused__none)
525 {
526     std::set< engine::test_filter > filters;
527     filters.insert(mkfilter("a/b", ""));
528     filters.insert(mkfilter("baz", "tc"));
529     filters.insert(mkfilter("hey/d", "yes"));
530     engine::filters_state state(filters);
531 
532     state.match_test_case(fs::path("a/b/c"), "any");
533     state.match_test_case(fs::path("baz"), "tc");
534     state.match_test_case(fs::path("hey/d"), "yes");
535 
536     ATF_REQUIRE(state.unused().empty());
537 }
538 
539 
540 ATF_TEST_CASE_WITHOUT_HEAD(filters_state__unused__some);
ATF_TEST_CASE_BODY(filters_state__unused__some)541 ATF_TEST_CASE_BODY(filters_state__unused__some)
542 {
543     std::set< engine::test_filter > filters;
544     filters.insert(mkfilter("a/b", ""));
545     filters.insert(mkfilter("baz", "tc"));
546     filters.insert(mkfilter("hey/d", "yes"));
547     engine::filters_state state(filters);
548 
549     state.match_test_program(fs::path("a/b/c"));
550     state.match_test_case(fs::path("baz"), "tc");
551 
552     std::set< engine::test_filter > exp_unused;
553     exp_unused.insert(mkfilter("a/b", ""));
554     exp_unused.insert(mkfilter("hey/d", "yes"));
555 
556     ATF_REQUIRE(exp_unused == state.unused());
557 }
558 
559 
ATF_INIT_TEST_CASES(tcs)560 ATF_INIT_TEST_CASES(tcs)
561 {
562     ATF_ADD_TEST_CASE(tcs, test_filter__public_fields);
563     ATF_ADD_TEST_CASE(tcs, test_filter__parse__ok);
564     ATF_ADD_TEST_CASE(tcs, test_filter__parse__empty);
565     ATF_ADD_TEST_CASE(tcs, test_filter__parse__absolute);
566     ATF_ADD_TEST_CASE(tcs, test_filter__parse__bad_program_name);
567     ATF_ADD_TEST_CASE(tcs, test_filter__parse__bad_test_case);
568     ATF_ADD_TEST_CASE(tcs, test_filter__parse__bad_path);
569     ATF_ADD_TEST_CASE(tcs, test_filter__str);
570     ATF_ADD_TEST_CASE(tcs, test_filter__contains__same);
571     ATF_ADD_TEST_CASE(tcs, test_filter__contains__different);
572     ATF_ADD_TEST_CASE(tcs, test_filter__matches_test_program);
573     ATF_ADD_TEST_CASE(tcs, test_filter__matches_test_case);
574     ATF_ADD_TEST_CASE(tcs, test_filter__operator_lt);
575     ATF_ADD_TEST_CASE(tcs, test_filter__operator_eq);
576     ATF_ADD_TEST_CASE(tcs, test_filter__operator_ne);
577     ATF_ADD_TEST_CASE(tcs, test_filter__output);
578 
579     ATF_ADD_TEST_CASE(tcs, test_filters__match_test_case__no_filters);
580     ATF_ADD_TEST_CASE(tcs, test_filters__match_test_case__some_filters);
581     ATF_ADD_TEST_CASE(tcs, test_filters__match_test_program__no_filters);
582     ATF_ADD_TEST_CASE(tcs, test_filters__match_test_program__some_filters);
583     ATF_ADD_TEST_CASE(tcs, test_filters__difference__no_filters);
584     ATF_ADD_TEST_CASE(tcs, test_filters__difference__some_filters__all_used);
585     ATF_ADD_TEST_CASE(tcs, test_filters__difference__some_filters__some_unused);
586 
587     ATF_ADD_TEST_CASE(tcs, check_disjoint_filters__ok);
588     ATF_ADD_TEST_CASE(tcs, check_disjoint_filters__fail);
589 
590     ATF_ADD_TEST_CASE(tcs, filters_state__match_test_program);
591     ATF_ADD_TEST_CASE(tcs, filters_state__match_test_case);
592     ATF_ADD_TEST_CASE(tcs, filters_state__unused__none);
593     ATF_ADD_TEST_CASE(tcs, filters_state__unused__some);
594 }
595