1 """unittest module for logilab.comon.testlib"""
2
3 __revision__ = '$Id: unittest_testlib.py,v 1.5 2006-02-09 22:37:46 nico Exp $'
4
5 import unittest
6 import os
7 import sys
8 from os.path import join, dirname, isdir, isfile, abspath, exists
9 from cStringIO import StringIO
10 import tempfile
11 import shutil
12
13 from logilab.common.compat import sorted
14
15 try:
16 __file__
17 except NameError:
18 __file__ = sys.argv[0]
19
20
21 from unittest import TestSuite
22
23 from logilab.common.testlib import TestCase, SkipAwareTextTestRunner, Tags
24 from logilab.common.testlib import mock_object, NonStrictTestLoader, create_files
25 from logilab.common.testlib import capture_stdout, unittest_main, InnerTest
26 from logilab.common.testlib import with_tempdir, tag
27 from logilab.common.testlib import require_version, require_module
33
34 - def fail(self, msg):
36
38
40 obj = mock_object(foo='bar', baz='bam')
41 self.assertEquals(obj.foo, 'bar')
42 self.assertEquals(obj.baz, 'bam')
43
44
46 chroot = tempfile.mkdtemp()
47 path_to = lambda path: join(chroot, path)
48 dircontent = lambda path: sorted(os.listdir(join(chroot, path)))
49 try:
50 self.failIf(isdir(path_to('a/')))
51 create_files(['a/b/foo.py', 'a/b/c/', 'a/b/c/d/e.py'], chroot)
52
53 self.failUnless(isdir(path_to('a')))
54 self.failUnless(isdir(path_to('a/b')))
55 self.failUnless(isdir(path_to('a/b/c')))
56 self.failUnless(isdir(path_to('a/b/c/d')))
57
58 self.failUnless(isfile(path_to('a/b/foo.py')))
59 self.failUnless(isfile(path_to('a/b/c/d/e.py')))
60
61 self.assertEquals(dircontent('a'), ['b'])
62 self.assertEquals(dircontent('a/b'), ['c', 'foo.py'])
63 self.assertEquals(dircontent('a/b/c'), ['d'])
64 self.assertEquals(dircontent('a/b/c/d'), ['e.py'])
65 finally:
66 shutil.rmtree(chroot)
67
70
71 capture = True
72
74 if not exists(path):
75 self._dirs.add(path)
76 os.mkdir(path)
77
81
83 while(self._dirs):
84 shutil.rmtree(self._dirs.pop(), ignore_errors=True)
85
87 """tests TestCase.assertDictEquals"""
88 d1 = {'a' : 1, 'b' : 2}
89 d2 = {'a' : 1, 'b' : 3}
90 d3 = dict(d1)
91 self.assertRaises(AssertionError, self.tc.assertDictEquals, d1, d2)
92 self.tc.assertDictEquals(d1, d3)
93 self.tc.assertDictEquals(d3, d1)
94 self.tc.assertDictEquals(d1, d1)
95
97 """tests TestCase.assertListEquals"""
98 l1 = range(10)
99 l2 = range(5)
100 l3 = range(10)
101 self.assertRaises(AssertionError, self.tc.assertListEquals, l1, l2)
102 self.tc.assertListEquals(l1, l1)
103 self.tc.assertListEquals(l1, l3)
104 self.tc.assertListEquals(l3, l1)
105
107 """tests assertLineEquals"""
108 t1 = """some
109 text
110 """
111 t2 = """some
112
113 text"""
114 t3 = """some
115 text"""
116 self.assertRaises(AssertionError, self.tc.assertLinesEquals, t1, t2)
117 self.tc.assertLinesEquals(t1, t3)
118 self.tc.assertLinesEquals(t3, t1)
119 self.tc.assertLinesEquals(t1, t1)
120
122 """tests xml is valid"""
123 valid = """<root>
124 <hello />
125 <world>Logilab</world>
126 </root>"""
127 invalid = """<root><h2> </root>"""
128 self.tc.assertXMLStringWellFormed(valid)
129 self.assertRaises(AssertionError, self.tc.assertXMLStringWellFormed, invalid)
130 invalid = """<root><h2 </h2> </root>"""
131 self.assertRaises(AssertionError, self.tc.assertXMLStringWellFormed, invalid)
132
133
135 l1 = [0, 1, 2]
136 l2 = [1, 2, 3]
137 self.assertRaises(AssertionError, self.tc.assertUnorderedIterableEquals, l1, l2)
138 self.tc.assertUnorderedIterableEquals(l1, l1)
139 self.tc.assertUnorderedIterableEquals([], [])
140 l1 = [0, 1, 1]
141 l2 = [0, 1]
142 self.assertRaises(AssertionError, self.tc.assertUnorderedIterableEquals, l1, l2)
143 self.tc.assertUnorderedIterableEquals(l1, l1)
144
145
147 d1 = {'a' : 1, 'b' : 2}
148 d2 = {'a' : 1}
149 self.assertRaises(AssertionError, self.tc.assertUnorderedIterableEquals, d1, d2)
150 self.tc.assertUnorderedIterableEquals(d1, d1)
151 self.tc.assertUnorderedIterableEquals({}, {})
152
154 self.assertRaises(AssertionError, self.tc.assertUnorderedIterableEquals, xrange(5), xrange(6))
155 self.tc.assertUnorderedIterableEquals(xrange(5), range(5))
156 self.tc.assertUnorderedIterableEquals([], ())
157
159 s1 = set('ab')
160 s2 = set('a')
161 self.assertRaises(AssertionError, self.tc.assertSetEquals, s1, s2)
162 self.tc.assertSetEquals(s1, s1)
163 self.tc.assertSetEquals(set(), set())
164
166 foo = join(dirname(__file__), 'data', 'foo.txt')
167 spam = join(dirname(__file__), 'data', 'spam.txt')
168 self.assertRaises(AssertionError, self.tc.assertFileEqual, foo, spam)
169 self.tc.assertFileEqual(foo, foo)
170
172 ref = join(dirname(__file__), 'data', 'reference_dir')
173 same = join(dirname(__file__), 'data', 'same_dir')
174 subdir_differ = join(dirname(__file__), 'data', 'subdir_differ_dir')
175 file_differ = join(dirname(__file__), 'data', 'file_differ_dir')
176 content_differ = join(dirname(__file__), 'data', 'content_differ_dir')
177 ed1 = join(dirname(__file__), 'data', 'empty_dir_1')
178 ed2 = join(dirname(__file__), 'data', 'empty_dir_2')
179
180 for path in (ed1, ed2, join(subdir_differ,'unexpected')):
181 self.mkdir(path)
182
183 self.assertDirEquals(ed1, ed2)
184 self.assertDirEquals(ref, ref)
185 self.assertDirEquals( ref, same)
186 self.assertRaises(AssertionError, self.assertDirEquals, ed1, ref)
187 self.assertRaises(AssertionError, self.assertDirEquals, ref, ed2)
188 self.assertRaises(AssertionError, self.assertDirEquals, subdir_differ, ref)
189 self.assertRaises(AssertionError, self.assertDirEquals, file_differ, ref)
190 self.assertRaises(AssertionError, self.assertDirEquals, ref, content_differ)
191
193 foo = join(dirname(__file__), 'data', 'foo.txt')
194 spam = join(dirname(__file__), 'data', 'spam.txt')
195 stream1 = file(foo)
196 self.tc.assertStreamEqual(stream1, stream1)
197 stream1 = file(foo)
198 stream2 = file(spam)
199 self.assertRaises(AssertionError, self.tc.assertStreamEqual, stream1, stream2)
200
202 self.assertRaises(AssertionError, self.tc.assertTextEqual, "toto", 12)
203 self.assertRaises(AssertionError, self.tc.assertTextEqual, "toto", None)
204 self.assertRaises(AssertionError, self.tc.assertTextEqual, 3.12, u"toto")
205 self.assertRaises(AssertionError, self.tc.assertTextEqual, None, u"toto")
206
207 foo = join(dirname(__file__), 'data', 'foo.txt')
208 spam = join(dirname(__file__), 'data', 'spam.txt')
209 text1 = file(foo).read()
210 self.tc.assertTextEqual(text1, text1)
211 text2 = file(spam).read()
212 self.assertRaises(AssertionError, self.tc.assertTextEqual, text1, text2)
213
214
216 exc = self.tc.assertRaises(KeyError, {}.__getitem__, 'foo')
217 self.failUnless(isinstance(exc, KeyError))
218 self.assertEquals(exc.args, ('foo',))
219
220
222 expected_datadir = join(dirname(abspath(__file__)), 'data')
223 self.assertEquals(self.datadir, expected_datadir)
224 self.assertEquals(self.datapath('foo'), join(expected_datadir, 'foo'))
225
227 class MyTC(TestCase):
228 datadir = 'foo'
229 def test_1(self): pass
230
231
232 tc = MyTC('test_1')
233 self.assertEquals(tc.datapath('bar'), join('foo', 'bar'))
234
235 self.skip('should this really works?')
236 tc.datadir = 'spam'
237 self.assertEquals(tc.datapath('bar'), join('spam', 'bar'))
238
239
241 """test datadir is cached on the class"""
242 class MyTC(TestCase):
243 def test_1(self): pass
244
245 expected_datadir = join(dirname(abspath(__file__)), 'data')
246 tc = MyTC('test_1')
247 self.assertEquals(tc.datadir, expected_datadir)
248
249 MyTC.__module__ = 'os'
250 self.assertEquals(tc.datadir, expected_datadir)
251
252 tc2 = MyTC('test_1')
253 self.assertEquals(tc2.datadir, expected_datadir)
254
256 obj_1 = []
257 obj_2 = []
258 self.assertIs(obj_1,obj_1)
259 self.assertRaises(AssertionError, self.assertIs, obj_1, obj_2)
260
262 obj_1 = []
263 obj_2 = []
264 self.assertIsNot(obj_1,obj_2)
265 self.assertRaises(AssertionError, self.assertIsNot, obj_1, obj_1)
266
268 self.assertNone(None)
269 self.assertRaises(AssertionError, self.assertNone, object())
270
272 self.assertNotNone(object())
273 self.assertRaises(AssertionError, self.assertNotNone, None)
274
276 self.assertIn("a", "dsqgaqg")
277 obj, seq = 'a', ('toto', "azf", "coin")
278 self.assertRaises(AssertionError, self.assertIn, obj, seq)
279
281 self.assertNotIn('a', ('toto', "azf", "coin"))
282 self.assertRaises(AssertionError, self.assertNotIn, 'a', "dsqgaqg")
283
286
288 output = StringIO()
289 self.runner = SkipAwareTextTestRunner(stream=output)
290
292 class FooTC(TestCase):
293 def test_generative(self):
294 for i in xrange(10):
295 yield self.assertEquals, i, i
296 result = self.runner.run(FooTC('test_generative'))
297 self.assertEquals(result.testsRun, 10)
298 self.assertEquals(len(result.failures), 0)
299 self.assertEquals(len(result.errors), 0)
300
301
303 class FooTC(TestCase):
304 def test_generative(self):
305 for i in xrange(10):
306 yield self.assertEquals, i%2, 0
307 result = self.runner.run(FooTC('test_generative'))
308 self.assertEquals(result.testsRun, 10)
309 self.assertEquals(len(result.failures), 5)
310 self.assertEquals(len(result.errors), 0)
311
312
314 class FooTC(TestCase):
315 def test_generative(self):
316 for i in xrange(10):
317 if i == 5:
318 raise ValueError('STOP !')
319 yield self.assertEquals, i, i
320
321 result = self.runner.run(FooTC('test_generative'))
322 self.assertEquals(result.testsRun, 5)
323 self.assertEquals(len(result.failures), 0)
324 self.assertEquals(len(result.errors), 1)
325
326
328 class FooTC(TestCase):
329 def test_generative(self):
330 for i in xrange(10):
331 if i == 5:
332 yield self.ouch
333 yield self.assertEquals, i, i
334 def ouch(self): raise ValueError('stop !')
335 result = self.runner.run(FooTC('test_generative'))
336 self.assertEquals(result.testsRun, 6)
337 self.assertEquals(len(result.failures), 0)
338 self.assertEquals(len(result.errors), 1)
339
340
342 class FooTC(TestCase):
343 def setUp(self):
344 raise ValueError('STOP !')
345 def test_generative(self):
346 for i in xrange(10):
347 yield self.assertEquals, i, i
348
349 result = self.runner.run(FooTC('test_generative'))
350 self.assertEquals(result.testsRun, 1)
351 self.assertEquals(len(result.failures), 0)
352 self.assertEquals(len(result.errors), 1)
353
357 output = StringIO()
358 self.runner = SkipAwareTextTestRunner(stream=output, exitfirst=True)
359
361 class FooTC(TestCase):
362 def test_1(self): pass
363 def test_2(self): assert False
364 def test_3(self): pass
365 tests = [FooTC('test_1'), FooTC('test_2')]
366 result = self.runner.run(TestSuite(tests))
367 self.assertEquals(result.testsRun, 2)
368 self.assertEquals(len(result.failures), 1)
369 self.assertEquals(len(result.errors), 0)
370
371
373 class FooTC(TestCase):
374 def test_1(self): pass
375 def test_2(self): raise ValueError()
376 def test_3(self): pass
377 tests = [FooTC('test_1'), FooTC('test_2'), FooTC('test_3')]
378 result = self.runner.run(TestSuite(tests))
379 self.assertEquals(result.testsRun, 2)
380 self.assertEquals(len(result.failures), 0)
381 self.assertEquals(len(result.errors), 1)
382
384 class FooTC(TestCase):
385 def test_generative(self):
386 for i in xrange(10):
387 yield self.assert_, False
388 result = self.runner.run(FooTC('test_generative'))
389 self.assertEquals(result.testsRun, 1)
390 self.assertEquals(len(result.failures), 1)
391 self.assertEquals(len(result.errors), 0)
392
395
400
403
404
406 self.loader = NonStrictTestLoader()
407 self.module = TestLoaderTC
408 self.output = StringIO()
409 self.runner = SkipAwareTextTestRunner(stream=self.output)
410
411 - def assertRunCount(self, pattern, module, expected_count, skipped=()):
412 if pattern:
413 suite = self.loader.loadTestsFromNames([pattern], module)
414 else:
415 suite = self.loader.loadTestsFromModule(module)
416 self.runner.test_pattern = pattern
417 self.runner.skipped_patterns = skipped
418 result = self.runner.run(suite)
419 self.runner.test_pattern = None
420 self.runner.skipped_patterns = ()
421 self.assertEquals(result.testsRun, expected_count)
422
424 """make sure we don't change the default behaviour
425 for loadTestsFromModule() and loadTestsFromTestCase
426 """
427 testsuite = self.loader.loadTestsFromModule(self.module)
428 self.assertEquals(len(testsuite._tests), 2)
429 suite1, suite2 = testsuite._tests
430 self.assertEquals(len(suite1._tests) + len(suite2._tests), 4)
431
435
437 data = [('FooTC.test_foo1', 1), ('FooTC.test_foo', 2), ('FooTC.test_fo', 2),
438 ('FooTC.foo1', 1), ('FooTC.foo', 2), ('FooTC.whatever', 0)
439 ]
440 for pattern, expected_count in data:
441 yield self.assertRunCount, pattern, self.module, expected_count
442
444 data = [('test_foo1', 1), ('test_foo', 2), ('test_bar', 2),
445 ('foo1', 1), ('foo', 2), ('bar', 2), ('ba', 2),
446 ('test', 4), ('ab', 0),
447 ]
448 for pattern, expected_count in data:
449 yield self.assertRunCount, pattern, self.module, expected_count
450
459 data = [('test_foo1', 1), ('test_foo', 2), ('test_bar', 1),
460 ('foo1', 1), ('foo', 2), ('bar', 1), ('ba', 1),
461 ('test', 3), ('ab', 0),
462 ('MyTestCase.test_foo1', 1), ('MyTestCase.test_foo', 2),
463 ('MyTestCase.test_fo', 2), ('MyTestCase.foo1', 1),
464 ('MyTestCase.foo', 2), ('MyTestCase.whatever', 0)
465 ]
466 for pattern, expected_count in data:
467 yield self.assertRunCount, pattern, MyMod, expected_count
468
469
471 testdata = [ (['foo1'], 3), (['foo'], 2),
472 (['foo', 'bar'], 0),
473 ]
474 for skipped, expected_count in testdata:
475 yield self.assertRunCount, None, self.module, expected_count, skipped
476
477
479 testdata = [ ('bar', ['foo1'], 2), ('bar', [], 2),
480 ('bar', ['bar'], 0), ]
481
482 for runpattern, skipped, expected_count in testdata:
483 yield self.assertRunCount, runpattern, self.module, expected_count, skipped
484
489
491 testdata = [ ('bar', ['BarTC'], 1), ('foo', ['FooTC'], 0), ]
492 for runpattern, skipped, expected_count in testdata:
493 yield self.assertRunCount, runpattern, self.module, expected_count, skipped
494
495
498
499
501 class MyMod:
502 class MyTestCase(TestCase):
503 def test_foo(self): pass
504 def test_foobar(self):
505 for i in xrange(5):
506 if i%2 == 0:
507 yield InnerTest('even', lambda: None)
508 else:
509 yield InnerTest('odd', lambda: None)
510 yield lambda: None
511
512 data = [('foo', 7), ('test_foobar', 6), ('even', 3), ('odd', 2),
513 ]
514 for pattern, expected_count in data:
515 yield self.assertRunCount, pattern, MyMod, expected_count
516
518 class MyMod:
519 class MyTestCase(TestCase):
520 def test_foo(self): pass
521 def test_bar(self): pass
522 class FooTC(TestCase):
523 def test_foo(self): pass
524 self.assertRunCount('foo', MyMod, 2)
525 self.assertRunCount(None, MyMod, 3)
526 self.loader.skipped_patterns = self.runner.skipped_patterns = ['FooTC']
527 self.assertRunCount('foo', MyMod, 1)
528 self.assertRunCount(None, MyMod, 2)
529
531 class MyMod:
532 class _Base(TestCase):
533 def test_1(self): pass
534 class MyTestCase(_Base):
535 def test_2(self): pass
536 self.assertRunCount(None, MyMod, 2)
537
540 """sys.stdout will be evaluated at function parsing time"""
541
542 output.write(msg)
543
545
547 sys.stdout = sys.stderr = StringIO()
548 self.runner = SkipAwareTextTestRunner(stream=StringIO(), exitfirst=True, capture=True)
549
551 sys.stdout = sys.__stdout__
552 sys.stderr = sys.__stderr__
553
555 class FooTC(TestCase):
556 def test_stdout(self):
557 print "foo"
558 self.assert_(False)
559 test = FooTC('test_stdout')
560 result = self.runner.run(test)
561 captured_out, captured_err = test.captured_output()
562 self.assertEqual(captured_out.strip(), "foo")
563 self.assertEqual(captured_err.strip(), "")
564
566 class FooTC(TestCase):
567 def test_stderr(self):
568 print >> sys.stderr, "foo"
569 self.assert_(False)
570 test = FooTC('test_stderr')
571 result = self.runner.run(test)
572 captured_out, captured_err = test.captured_output()
573 self.assertEqual(captured_out.strip(), "")
574 self.assertEqual(captured_err.strip(), "foo")
575
576
578 class FooTC(TestCase):
579 def test_stderr(self):
580 print >> sys.stderr, "foo"
581 print "bar"
582 self.assert_(False)
583 test = FooTC('test_stderr')
584 result = self.runner.run(test)
585 captured_out, captured_err = test.captured_output()
586 self.assertEqual(captured_out.strip(), "bar")
587 self.assertEqual(captured_err.strip(), "foo")
588
590 class FooTC(TestCase):
591 def test_stderr(self):
592 print >> sys.stderr, "foo"
593 print "bar"
594 self.assert_(False)
595 test = FooTC('test_stderr')
596
597 runner = SkipAwareTextTestRunner(stream=StringIO(), exitfirst=True)
598 result = runner.run(test)
599 captured_out, captured_err = test.captured_output()
600 self.assertEqual(captured_out.strip(), "")
601 self.assertEqual(captured_err.strip(), "")
602
603
605
606
607
608 output = capture_stdout()
609 bootstrap_print("hello")
610 self.assertEquals(output.restore(), "hello")
611
613 class FooTC(TestCase):
614 def test_xxx(self):
615 raise Exception(u'\xe9')
616 test = FooTC('test_xxx')
617
618 result = self.runner.run(test)
619
621 class FooTC(TestCase):
622 def test_xxx(self):
623 raise Exception('\xe9')
624 test = FooTC('test_xxx')
625
626 result = self.runner.run(test)
627
630
631 @with_tempdir
633
634
635 tempdir = tempfile.gettempdir()
636
637 self.assertListEquals(list(os.walk(tempdir)),
638 [(tempdir,[],[])])
639
640 witness = []
641
642 @with_tempdir
643 def createfile(list):
644 fd1, fn1 = tempfile.mkstemp()
645 fd2, fn2 = tempfile.mkstemp()
646 dir = tempfile.mkdtemp()
647 fd3, fn3 = tempfile.mkstemp(dir=dir)
648 tempfile.mkdtemp()
649 list.append(True)
650 for fd in (fd1, fd2, fd3):
651 os.close(fd)
652
653 self.assertFalse(witness)
654 createfile(witness)
655 self.assertTrue(witness)
656
657 self.assertEquals(tempfile.gettempdir(), tempdir)
658
659
660 self.assertListEquals(list(os.walk(tempdir)),
661 [(tempdir,[],[])])
662
663 @with_tempdir
665
666 tempdir = tempfile.gettempdir()
667
668 self.assertListEquals(list(os.walk(tempfile.tempdir)),
669 [(tempfile.tempdir,[],[])])
670
671
672 class WitnessException(Exception):
673 pass
674
675 @with_tempdir
676 def createfile():
677 fd1, fn1 = tempfile.mkstemp()
678 fd2, fn2 = tempfile.mkstemp()
679 dir = tempfile.mkdtemp()
680 fd3, fn3 = tempfile.mkstemp(dir=dir)
681 tempfile.mkdtemp()
682 for fd in (fd1, fd2, fd3):
683 os.close(fd)
684 raise WitnessException()
685
686 self.assertRaises(WitnessException, createfile)
687
688
689
690 self.assertEquals(tempfile.gettempdir(), tempdir)
691
692
693 self.assertListEquals(list(os.walk(tempdir)),
694 [(tempdir,[],[])])
695
696
699
702
704 """ should return the same function
705 """
706 def func() :
707 pass
708 sys.version_info = (2, 5, 5, 'final', 4)
709 current = sys.version_info[:3]
710 compare = ('2.4', '2.5', '2.5.4', '2.5.5')
711 for version in compare:
712 decorator = require_version(version)
713 self.assertEquals(func, decorator(func), '%s =< %s : function \
714 return by the decorator should be the same.' % (version,
715 '.'.join([str(element) for element in current])))
716
718 """ should return a different function : skipping test
719 """
720 def func() :
721 pass
722 sys.version_info = (2, 5, 5, 'final', 4)
723 current = sys.version_info[:3]
724 compare = ('2.5.6', '2.6', '2.6.5')
725 for version in compare:
726 decorator = require_version(version)
727 self.assertNotEquals(func, decorator(func), '%s >= %s : function \
728 return by the decorator should NOT be the same.'
729 % ('.'.join([str(element) for element in current]), version))
730
732 """ should throw a ValueError exception
733 """
734 def func() :
735 pass
736 compare = ('2.5.a', '2.a', 'azerty')
737 for version in compare:
738 decorator = require_version(version)
739 self.assertRaises(ValueError, decorator, func)
740
742 """ should return the same function
743 """
744 def func() :
745 pass
746 module = 'sys'
747 decorator = require_module(module)
748 self.assertEquals(func, decorator(func), 'module %s exists : function \
749 return by the decorator should be the same.' % module)
750
752 """ should return a different function : skipping test
753 """
754 def func() :
755 pass
756 modules = ('bla', 'blo', 'bli')
757 for module in modules:
758 try:
759 __import__(module)
760 pass
761 except ImportError:
762 decorator = require_module(module)
763 self.assertNotEquals(func, decorator(func), 'module %s does \
764 not exist : function return by the decorator should \
765 NOT be the same.' % module)
766 return
767 print 'all modules in %s exist. Could not test %s' % (', '.join(modules),
768 sys._getframe().f_code.co_name)
769
771
773 @tag('testing', 'bob')
774 def bob(a, b, c):
775 return (a + b) * c
776
777 self.func = bob
778
779 class TagTestTC(TestCase):
780 tags = Tags(('one', 'two'))
781
782 def test_one(self):
783 self.assertTrue(True)
784
785 @tag('two', 'three')
786 def test_two(self):
787 self.assertTrue(True)
788
789 @tag('three')
790 def test_three(self):
791 self.assertTrue(True)
792 self.cls = TagTestTC
793
795 bob = self.func
796
797 self.assertEquals(bob(2, 3, 7), 35)
798 self.assertTrue(hasattr(bob, 'tags'))
799 self.assertSetEquals(bob.tags, set(['testing','bob']))
800
801
807
821
823 def options(tags):
824 class Options(object):
825 tags_pattern = tags
826 return Options()
827
828 cls = self.cls
829
830 runner = SkipAwareTextTestRunner()
831 self.assertTrue(runner.does_match_tags(cls.test_one))
832 self.assertTrue(runner.does_match_tags(cls.test_two))
833 self.assertTrue(runner.does_match_tags(cls.test_three))
834
835 runner = SkipAwareTextTestRunner(options=options('one'))
836 self.assertTrue(runner.does_match_tags(cls.test_one))
837 self.assertFalse(runner.does_match_tags(cls.test_two))
838 self.assertFalse(runner.does_match_tags(cls.test_three))
839
840 runner = SkipAwareTextTestRunner(options=options('two'))
841 self.assertTrue(runner.does_match_tags(cls.test_one))
842 self.assertTrue(runner.does_match_tags(cls.test_two))
843 self.assertFalse(runner.does_match_tags(cls.test_three))
844
845 runner = SkipAwareTextTestRunner(options=options('three'))
846 self.assertFalse(runner.does_match_tags(cls.test_one))
847 self.assertTrue(runner.does_match_tags(cls.test_two))
848 self.assertTrue(runner.does_match_tags(cls.test_three))
849
850 runner = SkipAwareTextTestRunner(options=options('two or three'))
851 self.assertTrue(runner.does_match_tags(cls.test_one))
852 self.assertTrue(runner.does_match_tags(cls.test_two))
853 self.assertTrue(runner.does_match_tags(cls.test_three))
854
855 runner = SkipAwareTextTestRunner(options=options('two and three'))
856 self.assertFalse(runner.does_match_tags(cls.test_one))
857 self.assertTrue(runner.does_match_tags(cls.test_two))
858 self.assertFalse(runner.does_match_tags(cls.test_three))
859
860
861
862 if __name__ == '__main__':
863 unittest_main()
864