##// END OF EJS Templates
Commiting fixes for running our test suite using trial and nose....
Brian Granger -
Show More
@@ -0,0 +1,132 b''
1 # encoding: utf-8
2 """
3 Testing related decorators for use with twisted.trial.
4
5 The decorators in this files are designed to follow the same API as those
6 in the decorators module (in this same directory). But they can be used
7 with twisted.trial
8 """
9
10 #-----------------------------------------------------------------------------
11 # Copyright (C) 2008-2009 The IPython Development Team
12 #
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
15 #-----------------------------------------------------------------------------
16
17 #-----------------------------------------------------------------------------
18 # Imports
19 #-----------------------------------------------------------------------------
20
21 import os
22 import sys
23
24 from IPython.testing.decorators import make_label_dec
25
26 #-----------------------------------------------------------------------------
27 # Testing decorators
28 #-----------------------------------------------------------------------------
29
30
31 def skipif(skip_condition, msg=None):
32 """Create a decorator that marks a test function for skipping.
33
34 The is a decorator factory that returns a decorator that will
35 conditionally skip a test based on the value of skip_condition. The
36 skip_condition argument can either be a boolean or a callable that returns
37 a boolean.
38
39 Parameters
40 ----------
41 skip_condition : boolean or callable
42 If this evaluates to True, the test is skipped.
43 msg : str
44 The message to print if the test is skipped.
45
46 Returns
47 -------
48 decorator : function
49 The decorator function that can be applied to the test function.
50 """
51
52 def skip_decorator(f):
53
54 # Allow for both boolean or callable skip conditions.
55 if callable(skip_condition):
56 skip_val = lambda : skip_condition()
57 else:
58 skip_val = lambda : skip_condition
59
60 if msg is None:
61 out = 'Test skipped due to test condition.'
62 else:
63 out = msg
64 final_msg = "Skipping test: %s. %s" % (f.__name__,out)
65
66 if skip_val():
67 f.skip = final_msg
68
69 return f
70 return skip_decorator
71
72
73 def skip(msg=None):
74 """Create a decorator that marks a test function for skipping.
75
76 This is a decorator factory that returns a decorator that will cause
77 tests to be skipped.
78
79 Parameters
80 ----------
81 msg : str
82 Optional message to be added.
83
84 Returns
85 -------
86 decorator : function
87 Decorator, which, when applied to a function, sets the skip
88 attribute of the function causing `twisted.trial` to skip it.
89 """
90
91 return skipif(True,msg)
92
93
94 def numpy_not_available():
95 """Can numpy be imported? Returns true if numpy does NOT import.
96
97 This is used to make a decorator to skip tests that require numpy to be
98 available, but delay the 'import numpy' to test execution time.
99 """
100 try:
101 import numpy
102 np_not_avail = False
103 except ImportError:
104 np_not_avail = True
105
106 return np_not_avail
107
108 #-----------------------------------------------------------------------------
109 # Decorators for public use
110 #-----------------------------------------------------------------------------
111
112 # Decorators to skip certain tests on specific platforms.
113 skip_win32 = skipif(sys.platform == 'win32',
114 "This test does not run under Windows")
115 skip_linux = skipif(sys.platform == 'linux2',
116 "This test does not run under Linux")
117 skip_osx = skipif(sys.platform == 'darwin',"This test does not run under OS X")
118
119 # Decorators to skip tests if not on specific platforms.
120 skip_if_not_win32 = skipif(sys.platform != 'win32',
121 "This test only runs under Windows")
122 skip_if_not_linux = skipif(sys.platform != 'linux2',
123 "This test only runs under Linux")
124 skip_if_not_osx = skipif(sys.platform != 'darwin',
125 "This test only runs under OSX")
126
127 # Other skip decorators
128 skipif_not_numpy = skipif(numpy_not_available,"This test requires numpy")
129
130 skipknownfailure = skip('This test is known to fail')
131
132
@@ -0,0 +1,52 b''
1 # encoding: utf-8
2 """
3 Tests for decorators_trial.py
4 """
5
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2009 The IPython Development Team
8 #
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 # Tell nose to skip this module
18 __test__ = {}
19
20 import os
21 import sys
22
23 from twisted.trial import unittest
24 import IPython.testing.decorators_trial as dec
25
26 #-----------------------------------------------------------------------------
27 # Tests
28 #-----------------------------------------------------------------------------
29
30 class TestDecoratorsTrial(unittest.TestCase):
31
32 @dec.skip()
33 def test_deliberately_broken(self):
34 """A deliberately broken test - we want to skip this one."""
35 1/0
36
37 @dec.skip('Testing the skip decorator')
38 def test_deliberately_broken2(self):
39 """Another deliberately broken test - we want to skip this one."""
40 1/0
41
42 @dec.skip_linux
43 def test_linux(self):
44 self.assertNotEquals(sys.platform,'linux2',"This test can't run under linux")
45
46 @dec.skip_win32
47 def test_win32(self):
48 self.assertNotEquals(sys.platform,'win32',"This test can't run under windows")
49
50 @dec.skip_osx
51 def test_osx(self):
52 self.assertNotEquals(sys.platform,'darwin',"This test can't run under osx") No newline at end of file
@@ -1,64 +1,62 b''
1 1 # encoding: utf-8
2 2
3 3 """This file contains unittests for the interpreter.py module."""
4 4
5 __docformat__ = "restructuredtext en"
6
7 5 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008-2009 The IPython Development Team
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
6 # Copyright (C) 2008-2009 The IPython Development Team
7 #
8 # Distributed under the terms of the BSD License. The full license is
9 # in the file COPYING, distributed as part of this software.
12 10 #-----------------------------------------------------------------------------
13 11
14 12 #-----------------------------------------------------------------------------
15 # Imports
13 # Imports
16 14 #-----------------------------------------------------------------------------
17 15
18 import unittest
16 # Tell nose to skip this module
17 __test__ = {}
18
19 from twisted.trial import unittest
19 20 from IPython.kernel.core.interpreter import Interpreter
20 21
21 22 #-----------------------------------------------------------------------------
22 # Tests
23 # Tests
23 24 #-----------------------------------------------------------------------------
24 25
25 # Tell nose to skip this module
26 __test__ = {}
27
28 26 class TestInterpreter(unittest.TestCase):
29 27
30 28 def test_unicode(self):
31 29 """ Test unicode handling with the interpreter."""
32 30 i = Interpreter()
33 31 i.execute_python(u'print "ΓΉ"')
34 32 i.execute_python('print "ΓΉ"')
35 33
36 34 def test_ticket266993(self):
37 35 """ Test for ticket 266993."""
38 36 i = Interpreter()
39 37 i.execute('str("""a\nb""")')
40 38
41 39 def test_ticket364347(self):
42 40 """Test for ticket 364347."""
43 41 i = Interpreter()
44 42 i.split_commands('str("a\\nb")')
45 43
46 44 def test_split_commands(self):
47 45 """ Test that commands are indeed individually split."""
48 46 i = Interpreter()
49 47 test_atoms = [('(1\n + 1)', ),
50 48 ('1', '1', ),
51 49 ]
52 50 for atoms in test_atoms:
53 51 atoms = [atom.rstrip() + '\n' for atom in atoms]
54 52 self.assertEquals(i.split_commands(''.join(atoms)),atoms)
55 53
56 54 def test_long_lines(self):
57 55 """ Test for spurious syntax error created by the interpreter."""
58 56 test_strings = [u'( 1 +\n 1\n )\n\n',
59 57 u'(1 \n + 1\n )\n\n',
60 58 ]
61 59 i = Interpreter()
62 60 for s in test_strings:
63 61 i.execute(s)
64 62
@@ -1,174 +1,161 b''
1 1 # encoding: utf-8
2 2
3 3 """This file contains unittests for the notification.py module."""
4 4
5 __docformat__ = "restructuredtext en"
6
7 5 #-----------------------------------------------------------------------------
8 # Copyright (C) 2008 The IPython Development Team
9 #
10 # Distributed under the terms of the BSD License. The full license is in
11 # the file COPYING, distributed as part of this software.
6 # Copyright (C) 2008-2009 The IPython Development Team
7 #
8 # Distributed under the terms of the BSD License. The full license is
9 # in the file COPYING, distributed as part of this software.
12 10 #-----------------------------------------------------------------------------
13
11
14 12 #-----------------------------------------------------------------------------
15 # Imports
13 # Imports
16 14 #-----------------------------------------------------------------------------
17 15
18 16 # Tell nose to skip this module
19 17 __test__ = {}
20 18
21 import unittest
19 from twisted.trial import unittest
22 20 import IPython.kernel.core.notification as notification
23 from nose.tools import timed
24 21
25 #
26 # Supporting test classes
27 #
22 #-----------------------------------------------------------------------------
23 # Support Classes
24 #-----------------------------------------------------------------------------
28 25
29 26 class Observer(object):
30 27 """docstring for Observer"""
31 28 def __init__(self, expectedType, expectedSender,
32 29 center=notification.sharedCenter, **kwargs):
33 30 super(Observer, self).__init__()
34 31 self.expectedType = expectedType
35 32 self.expectedSender = expectedSender
36 33 self.expectedKwArgs = kwargs
37 34 self.recieved = False
38 35 center.add_observer(self.callback,
39 36 self.expectedType,
40 37 self.expectedSender)
41 38
42
43 39 def callback(self, theType, sender, args={}):
44 40 """callback"""
45 41
46 42 assert(theType == self.expectedType or
47 43 self.expectedType == None)
48 44 assert(sender == self.expectedSender or
49 45 self.expectedSender == None)
50 46 assert(args == self.expectedKwArgs)
51 47 self.recieved = True
52 48
53
54 49 def verify(self):
55 50 """verify"""
56 51
57 52 assert(self.recieved)
58 53
59 54 def reset(self):
60 55 """reset"""
61 56
62 57 self.recieved = False
63
64 58
65 59
66 60 class Notifier(object):
67 61 """docstring for Notifier"""
68 62 def __init__(self, theType, **kwargs):
69 63 super(Notifier, self).__init__()
70 64 self.theType = theType
71 65 self.kwargs = kwargs
72 66
73 67 def post(self, center=notification.sharedCenter):
74 68 """fire"""
75 69
76 70 center.post_notification(self.theType, self,
77 71 **self.kwargs)
78
79 72
80 #
81 # Test Cases
82 #
73 #-----------------------------------------------------------------------------
74 # Tests
75 #-----------------------------------------------------------------------------
83 76
84 77 class NotificationTests(unittest.TestCase):
85 78 """docstring for NotificationTests"""
86 79
87 80 def tearDown(self):
88 81 notification.sharedCenter.remove_all_observers()
89 82
90 83 def test_notification_delivered(self):
91 84 """Test that notifications are delivered"""
92 85 expectedType = 'EXPECTED_TYPE'
93 86 sender = Notifier(expectedType)
94 87 observer = Observer(expectedType, sender)
95 88
96 89 sender.post()
97 90
98 91 observer.verify()
99 92
100
101 93 def test_type_specificity(self):
102 94 """Test that observers are registered by type"""
103 95
104 96 expectedType = 1
105 97 unexpectedType = "UNEXPECTED_TYPE"
106 98 sender = Notifier(expectedType)
107 99 unexpectedSender = Notifier(unexpectedType)
108 100 observer = Observer(expectedType, sender)
109 101
110 102 sender.post()
111 103 unexpectedSender.post()
112 104
113 105 observer.verify()
114 106
115
116 107 def test_sender_specificity(self):
117 108 """Test that observers are registered by sender"""
118 109
119 110 expectedType = "EXPECTED_TYPE"
120 111 sender1 = Notifier(expectedType)
121 112 sender2 = Notifier(expectedType)
122 113 observer = Observer(expectedType, sender1)
123 114
124 115 sender1.post()
125 116 sender2.post()
126 117
127 118 observer.verify()
128 119
129
130 120 def test_remove_all_observers(self):
131 121 """White-box test for remove_all_observers"""
132 122
133 123 for i in xrange(10):
134 124 Observer('TYPE', None, center=notification.sharedCenter)
135 125
136 126 self.assert_(len(notification.sharedCenter.observers[('TYPE',None)]) >= 10,
137 127 "observers registered")
138 128
139 129 notification.sharedCenter.remove_all_observers()
140 130
141 131 self.assert_(len(notification.sharedCenter.observers) == 0, "observers removed")
142
143
132
144 133 def test_any_sender(self):
145 134 """test_any_sender"""
146 135
147 136 expectedType = "EXPECTED_TYPE"
148 137 sender1 = Notifier(expectedType)
149 138 sender2 = Notifier(expectedType)
150 139 observer = Observer(expectedType, None)
151 140
152 141
153 142 sender1.post()
154 143 observer.verify()
155 144
156 145 observer.reset()
157 146 sender2.post()
158 147 observer.verify()
159
160
161 @timed(.01)
148
162 149 def test_post_performance(self):
163 150 """Test that post_notification, even with many registered irrelevant
164 151 observers is fast"""
165 152
166 153 for i in xrange(10):
167 154 Observer("UNRELATED_TYPE", None)
168 155
169 156 o = Observer('EXPECTED_TYPE', None)
170 157
171 158 notification.sharedCenter.post_notification('EXPECTED_TYPE', self)
172 159
173 160 o.verify()
174
161
@@ -1,70 +1,78 b''
1 1 # encoding: utf-8
2 2 """
3 3 Test the output capture at the OS level, using file descriptors.
4 4 """
5
6 __docformat__ = "restructuredtext en"
7
8 #-------------------------------------------------------------------------------
9 # Copyright (C) 2008 The IPython Development Team
5 #-----------------------------------------------------------------------------
6 # Copyright (C) 2008-2009 The IPython Development Team
10 7 #
11 8 # Distributed under the terms of the BSD License. The full license is
12 9 # in the file COPYING, distributed as part of this software.
13 #-------------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
14 15
15 16 # Tell nose to skip this module
16 17 __test__ = {}
17 18
18 import os
19 19 from cStringIO import StringIO
20 import os
21
22 from twisted.trial import unittest
20 23
21 from IPython.testing import decorators as dec
24 from IPython.testing import decorators_trial as dec
22 25
23 26 #-----------------------------------------------------------------------------
24 # Test functions
27 # Tests
28 #-----------------------------------------------------------------------------
25 29
26 @dec.skip_win32
27 def test_redirector():
28 """ Checks that the redirector can be used to do synchronous capture.
29 """
30 from IPython.kernel.core.fd_redirector import FDRedirector
31 r = FDRedirector()
32 out = StringIO()
33 try:
34 r.start()
35 for i in range(10):
36 os.system('echo %ic' % i)
37 print >>out, r.getvalue(),
38 print >>out, i
39 except:
40 r.stop()
41 raise
42 r.stop()
43 result1 = out.getvalue()
44 result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10))
45 assert result1 == result2
46 30
31 class TestRedirector(unittest.TestCase):
47 32
48 @dec.skip_win32
49 def test_redirector_output_trap():
50 """ This test check not only that the redirector_output_trap does
33 @dec.skip_win32
34 def test_redirector(self):
35 """Checks that the redirector can be used to do synchronous capture.
36 """
37 from IPython.kernel.core.fd_redirector import FDRedirector
38 r = FDRedirector()
39 out = StringIO()
40 try:
41 r.start()
42 for i in range(10):
43 os.system('echo %ic' % i)
44 print >>out, r.getvalue(),
45 print >>out, i
46 except:
47 r.stop()
48 raise
49 r.stop()
50 result1 = out.getvalue()
51 result2 = "".join("%ic\n%i\n" %(i, i) for i in range(10))
52 self.assertEquals(result1, result2)
53
54 @dec.skip_win32
55 def test_redirector_output_trap(self):
56 """Check the greedy trapping behavior of the traps.
57
58 This test check not only that the redirector_output_trap does
51 59 trap the output, but also that it does it in a gready way, that
52 60 is by calling the callback ASAP.
53 """
54 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
55 out = StringIO()
56 trap = RedirectorOutputTrap(out.write, out.write)
57 try:
58 trap.set()
59 for i in range(10):
60 os.system('echo %ic' % i)
61 print "%ip" % i
62 print >>out, i
63 except:
61 """
62 from IPython.kernel.core.redirector_output_trap import RedirectorOutputTrap
63 out = StringIO()
64 trap = RedirectorOutputTrap(out.write, out.write)
65 try:
66 trap.set()
67 for i in range(10):
68 os.system('echo %ic' % i)
69 print "%ip" % i
70 print >>out, i
71 except:
72 trap.unset()
73 raise
64 74 trap.unset()
65 raise
66 trap.unset()
67 result1 = out.getvalue()
68 result2 = "".join("%ic\n%ip\n%i\n" %(i, i, i) for i in range(10))
69 assert result1 == result2
70
75 result1 = out.getvalue()
76 result2 = "".join("%ic\n%ip\n%i\n" %(i, i, i) for i in range(10))
77 self.assertEquals(result1, result2)
78
@@ -1,161 +1,161 b''
1 1 """Tests for the decorators we've created for IPython.
2 2 """
3 3
4 4 # Module imports
5 5 # Std lib
6 6 import inspect
7 7 import sys
8 8
9 9 # Third party
10 10 import nose.tools as nt
11 11
12 12 # Our own
13 13 from IPython.testing import decorators as dec
14 14
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Utilities
18 18
19 19 # Note: copied from OInspect, kept here so the testing stuff doesn't create
20 20 # circular dependencies and is easier to reuse.
21 21 def getargspec(obj):
22 22 """Get the names and default values of a function's arguments.
23 23
24 24 A tuple of four things is returned: (args, varargs, varkw, defaults).
25 25 'args' is a list of the argument names (it may contain nested lists).
26 26 'varargs' and 'varkw' are the names of the * and ** arguments or None.
27 27 'defaults' is an n-tuple of the default values of the last n arguments.
28 28
29 29 Modified version of inspect.getargspec from the Python Standard
30 30 Library."""
31 31
32 32 if inspect.isfunction(obj):
33 33 func_obj = obj
34 34 elif inspect.ismethod(obj):
35 35 func_obj = obj.im_func
36 36 else:
37 37 raise TypeError, 'arg is not a Python function'
38 38 args, varargs, varkw = inspect.getargs(func_obj.func_code)
39 39 return args, varargs, varkw, func_obj.func_defaults
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Testing functions
43 43
44 44 @dec.skip
45 45 def test_deliberately_broken():
46 46 """A deliberately broken test - we want to skip this one."""
47 47 1/0
48 48
49 @dec.skip('foo')
49 @dec.skip('Testing the skip decorator')
50 50 def test_deliberately_broken2():
51 51 """Another deliberately broken test - we want to skip this one."""
52 52 1/0
53 53
54 54
55 55 # Verify that we can correctly skip the doctest for a function at will, but
56 56 # that the docstring itself is NOT destroyed by the decorator.
57 57 @dec.skip_doctest
58 58 def doctest_bad(x,y=1,**k):
59 59 """A function whose doctest we need to skip.
60 60
61 61 >>> 1+1
62 62 3
63 63 """
64 64 print 'x:',x
65 65 print 'y:',y
66 66 print 'k:',k
67 67
68 68
69 69 def call_doctest_bad():
70 70 """Check that we can still call the decorated functions.
71 71
72 72 >>> doctest_bad(3,y=4)
73 73 x: 3
74 74 y: 4
75 75 k: {}
76 76 """
77 77 pass
78 78
79 79
80 80 def test_skip_dt_decorator():
81 81 """Doctest-skipping decorator should preserve the docstring.
82 82 """
83 83 # Careful: 'check' must be a *verbatim* copy of the doctest_bad docstring!
84 84 check = """A function whose doctest we need to skip.
85 85
86 86 >>> 1+1
87 87 3
88 88 """
89 89 # Fetch the docstring from doctest_bad after decoration.
90 90 val = doctest_bad.__doc__
91 91
92 92 assert check==val,"doctest_bad docstrings don't match"
93 93
94 94 # Doctest skipping should work for class methods too
95 95 class foo(object):
96 96 """Foo
97 97
98 98 Example:
99 99
100 100 >>> 1+1
101 101 2
102 102 """
103 103
104 104 @dec.skip_doctest
105 105 def __init__(self,x):
106 106 """Make a foo.
107 107
108 108 Example:
109 109
110 110 >>> f = foo(3)
111 111 junk
112 112 """
113 113 print 'Making a foo.'
114 114 self.x = x
115 115
116 116 @dec.skip_doctest
117 117 def bar(self,y):
118 118 """Example:
119 119
120 120 >>> f = foo(3)
121 121 >>> f.bar(0)
122 122 boom!
123 123 >>> 1/0
124 124 bam!
125 125 """
126 126 return 1/y
127 127
128 128 def baz(self,y):
129 129 """Example:
130 130
131 131 >>> f = foo(3)
132 132 Making a foo.
133 133 >>> f.baz(3)
134 134 True
135 135 """
136 136 return self.x==y
137 137
138 138
139 139
140 140 def test_skip_dt_decorator2():
141 141 """Doctest-skipping decorator should preserve function signature.
142 142 """
143 143 # Hardcoded correct answer
144 144 dtargs = (['x', 'y'], None, 'k', (1,))
145 145 # Introspect out the value
146 146 dtargsr = getargspec(doctest_bad)
147 147 assert dtargsr==dtargs, \
148 148 "Incorrectly reconstructed args for doctest_bad: %s" % (dtargsr,)
149 149
150 150
151 151 @dec.skip_linux
152 152 def test_linux():
153 153 nt.assert_not_equals(sys.platform,'linux2',"This test can't run under linux")
154 154
155 155 @dec.skip_win32
156 156 def test_win32():
157 157 nt.assert_not_equals(sys.platform,'win32',"This test can't run under windows")
158 158
159 159 @dec.skip_osx
160 160 def test_osx():
161 161 nt.assert_not_equals(sys.platform,'darwin',"This test can't run under osx")
General Comments 0
You need to be logged in to leave comments. Login now