##// END OF EJS Templates
another dedent test
Matthias Bussonnier -
Show More
@@ -1,169 +1,168 b''
1 """Tests for the decorators we've created for IPython.
1 """Tests for the decorators we've created for IPython.
2 """
2 """
3
3
4 # Module imports
4 # Module imports
5 # Std lib
5 # Std lib
6 import inspect
6 import inspect
7 import sys
7 import sys
8
8
9 # Our own
9 # Our own
10 from IPython.testing import decorators as dec
10 from IPython.testing import decorators as dec
11 from IPython.testing.skipdoctest import skip_doctest
11 from IPython.testing.skipdoctest import skip_doctest
12 from IPython.utils.text import dedent
12 from IPython.utils.text import dedent
13
13
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15 # Utilities
15 # Utilities
16
16
17 # Note: copied from OInspect, kept here so the testing stuff doesn't create
17 # Note: copied from OInspect, kept here so the testing stuff doesn't create
18 # circular dependencies and is easier to reuse.
18 # circular dependencies and is easier to reuse.
19 def getargspec(obj):
19 def getargspec(obj):
20 """Get the names and default values of a function's arguments.
20 """Get the names and default values of a function's arguments.
21
21
22 A tuple of four things is returned: (args, varargs, varkw, defaults).
22 A tuple of four things is returned: (args, varargs, varkw, defaults).
23 'args' is a list of the argument names (it may contain nested lists).
23 'args' is a list of the argument names (it may contain nested lists).
24 'varargs' and 'varkw' are the names of the * and ** arguments or None.
24 'varargs' and 'varkw' are the names of the * and ** arguments or None.
25 'defaults' is an n-tuple of the default values of the last n arguments.
25 'defaults' is an n-tuple of the default values of the last n arguments.
26
26
27 Modified version of inspect.getargspec from the Python Standard
27 Modified version of inspect.getargspec from the Python Standard
28 Library."""
28 Library."""
29
29
30 if inspect.isfunction(obj):
30 if inspect.isfunction(obj):
31 func_obj = obj
31 func_obj = obj
32 elif inspect.ismethod(obj):
32 elif inspect.ismethod(obj):
33 func_obj = obj.__func__
33 func_obj = obj.__func__
34 else:
34 else:
35 raise TypeError('arg is not a Python function')
35 raise TypeError('arg is not a Python function')
36 args, varargs, varkw = inspect.getargs(func_obj.__code__)
36 args, varargs, varkw = inspect.getargs(func_obj.__code__)
37 return args, varargs, varkw, func_obj.__defaults__
37 return args, varargs, varkw, func_obj.__defaults__
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Testing functions
40 # Testing functions
41
41
42 @dec.as_unittest
42 @dec.as_unittest
43 def trivial():
43 def trivial():
44 """A trivial test"""
44 """A trivial test"""
45 pass
45 pass
46
46
47
47
48 @dec.skip()
48 @dec.skip()
49 def test_deliberately_broken():
49 def test_deliberately_broken():
50 """A deliberately broken test - we want to skip this one."""
50 """A deliberately broken test - we want to skip this one."""
51 1/0
51 1/0
52
52
53 @dec.skip('Testing the skip decorator')
53 @dec.skip('Testing the skip decorator')
54 def test_deliberately_broken2():
54 def test_deliberately_broken2():
55 """Another deliberately broken test - we want to skip this one."""
55 """Another deliberately broken test - we want to skip this one."""
56 1/0
56 1/0
57
57
58
58
59 # Verify that we can correctly skip the doctest for a function at will, but
59 # Verify that we can correctly skip the doctest for a function at will, but
60 # that the docstring itself is NOT destroyed by the decorator.
60 # that the docstring itself is NOT destroyed by the decorator.
61 @skip_doctest
61 @skip_doctest
62 def doctest_bad(x,y=1,**k):
62 def doctest_bad(x,y=1,**k):
63 """A function whose doctest we need to skip.
63 """A function whose doctest we need to skip.
64
64
65 >>> 1+1
65 >>> 1+1
66 3
66 3
67 """
67 """
68 print('x:',x)
68 print('x:',x)
69 print('y:',y)
69 print('y:',y)
70 print('k:',k)
70 print('k:',k)
71
71
72
72
73 def call_doctest_bad():
73 def call_doctest_bad():
74 """Check that we can still call the decorated functions.
74 """Check that we can still call the decorated functions.
75
75
76 >>> doctest_bad(3,y=4)
76 >>> doctest_bad(3,y=4)
77 x: 3
77 x: 3
78 y: 4
78 y: 4
79 k: {}
79 k: {}
80 """
80 """
81 pass
81 pass
82
82
83
83
84 def test_skip_dt_decorator():
84 def test_skip_dt_decorator():
85 """Doctest-skipping decorator should preserve the docstring.
85 """Doctest-skipping decorator should preserve the docstring.
86 """
86 """
87 # Careful: 'check' must be a *verbatim* copy of the doctest_bad docstring!
87 # Careful: 'check' must be a *verbatim* copy of the doctest_bad docstring!
88 check = dedent(
88 check = """A function whose doctest we need to skip.
89 """A function whose doctest we need to skip.
90
89
91 >>> 1+1
90 >>> 1+1
92 3
91 3
93 """
92 """
94 )
93
95 # Fetch the docstring from doctest_bad after decoration.
94 # Fetch the docstring from doctest_bad after decoration.
96 val = doctest_bad.__doc__
95 val = doctest_bad.__doc__
97
96
98 assert check == val, "doctest_bad docstrings don't match"
97 assert dedent(check) == dedent(val), "doctest_bad docstrings don't match"
99
98
100
99
101 # Doctest skipping should work for class methods too
100 # Doctest skipping should work for class methods too
102 class FooClass(object):
101 class FooClass(object):
103 """FooClass
102 """FooClass
104
103
105 Example:
104 Example:
106
105
107 >>> 1+1
106 >>> 1+1
108 2
107 2
109 """
108 """
110
109
111 @skip_doctest
110 @skip_doctest
112 def __init__(self,x):
111 def __init__(self,x):
113 """Make a FooClass.
112 """Make a FooClass.
114
113
115 Example:
114 Example:
116
115
117 >>> f = FooClass(3)
116 >>> f = FooClass(3)
118 junk
117 junk
119 """
118 """
120 print('Making a FooClass.')
119 print('Making a FooClass.')
121 self.x = x
120 self.x = x
122
121
123 @skip_doctest
122 @skip_doctest
124 def bar(self,y):
123 def bar(self,y):
125 """Example:
124 """Example:
126
125
127 >>> ff = FooClass(3)
126 >>> ff = FooClass(3)
128 >>> ff.bar(0)
127 >>> ff.bar(0)
129 boom!
128 boom!
130 >>> 1/0
129 >>> 1/0
131 bam!
130 bam!
132 """
131 """
133 return 1/y
132 return 1/y
134
133
135 def baz(self,y):
134 def baz(self,y):
136 """Example:
135 """Example:
137
136
138 >>> ff2 = FooClass(3)
137 >>> ff2 = FooClass(3)
139 Making a FooClass.
138 Making a FooClass.
140 >>> ff2.baz(3)
139 >>> ff2.baz(3)
141 True
140 True
142 """
141 """
143 return self.x==y
142 return self.x==y
144
143
145
144
146 def test_skip_dt_decorator2():
145 def test_skip_dt_decorator2():
147 """Doctest-skipping decorator should preserve function signature.
146 """Doctest-skipping decorator should preserve function signature.
148 """
147 """
149 # Hardcoded correct answer
148 # Hardcoded correct answer
150 dtargs = (['x', 'y'], None, 'k', (1,))
149 dtargs = (['x', 'y'], None, 'k', (1,))
151 # Introspect out the value
150 # Introspect out the value
152 dtargsr = getargspec(doctest_bad)
151 dtargsr = getargspec(doctest_bad)
153 assert dtargsr==dtargs, \
152 assert dtargsr==dtargs, \
154 "Incorrectly reconstructed args for doctest_bad: %s" % (dtargsr,)
153 "Incorrectly reconstructed args for doctest_bad: %s" % (dtargsr,)
155
154
156
155
157 @dec.skip_linux
156 @dec.skip_linux
158 def test_linux():
157 def test_linux():
159 assert sys.platform.startswith("linux") is False, "This test can't run under linux"
158 assert sys.platform.startswith("linux") is False, "This test can't run under linux"
160
159
161
160
162 @dec.skip_win32
161 @dec.skip_win32
163 def test_win32():
162 def test_win32():
164 assert sys.platform != "win32", "This test can't run under windows"
163 assert sys.platform != "win32", "This test can't run under windows"
165
164
166
165
167 @dec.skip_osx
166 @dec.skip_osx
168 def test_osx():
167 def test_osx():
169 assert sys.platform != "darwin", "This test can't run under osx"
168 assert sys.platform != "darwin", "This test can't run under osx"
General Comments 0
You need to be logged in to leave comments. Login now