Show More
@@ -0,0 +1,41 b'' | |||||
|
1 | # IPython: modified copy of numpy.testing.noseclasses, so | |||
|
2 | # IPython.external._decorators works without numpy being installed. | |||
|
3 | ||||
|
4 | # These classes implement a "known failure" error class. | |||
|
5 | ||||
|
6 | import os | |||
|
7 | ||||
|
8 | from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin | |||
|
9 | ||||
|
10 | class KnownFailureTest(Exception): | |||
|
11 | '''Raise this exception to mark a test as a known failing test.''' | |||
|
12 | pass | |||
|
13 | ||||
|
14 | ||||
|
15 | class KnownFailure(ErrorClassPlugin): | |||
|
16 | '''Plugin that installs a KNOWNFAIL error class for the | |||
|
17 | KnownFailureClass exception. When KnownFailureTest is raised, | |||
|
18 | the exception will be logged in the knownfail attribute of the | |||
|
19 | result, 'K' or 'KNOWNFAIL' (verbose) will be output, and the | |||
|
20 | exception will not be counted as an error or failure.''' | |||
|
21 | enabled = True | |||
|
22 | knownfail = ErrorClass(KnownFailureTest, | |||
|
23 | label='KNOWNFAIL', | |||
|
24 | isfailure=False) | |||
|
25 | ||||
|
26 | def options(self, parser, env=os.environ): | |||
|
27 | env_opt = 'NOSE_WITHOUT_KNOWNFAIL' | |||
|
28 | parser.add_option('--no-knownfail', action='store_true', | |||
|
29 | dest='noKnownFail', default=env.get(env_opt, False), | |||
|
30 | help='Disable special handling of KnownFailureTest ' | |||
|
31 | 'exceptions') | |||
|
32 | ||||
|
33 | def configure(self, options, conf): | |||
|
34 | if not self.can_configure: | |||
|
35 | return | |||
|
36 | self.conf = conf | |||
|
37 | disable = getattr(options, 'noKnownFail', False) | |||
|
38 | if disable: | |||
|
39 | self.enabled = False | |||
|
40 | ||||
|
41 |
@@ -20,6 +20,7 b' Authors' | |||||
20 | #----------------------------------------------------------------------------- |
|
20 | #----------------------------------------------------------------------------- | |
21 | # stdlib |
|
21 | # stdlib | |
22 | import unittest |
|
22 | import unittest | |
|
23 | from IPython.testing import decorators as dec | |||
23 |
|
24 | |||
24 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
25 | # Tests |
|
26 | # Tests | |
@@ -35,14 +36,14 b' class InteractiveShellTestCase(unittest.TestCase):' | |||||
35 | # And also multi-line cells |
|
36 | # And also multi-line cells | |
36 | ip.run_cell('"""a\nb"""\n') |
|
37 | ip.run_cell('"""a\nb"""\n') | |
37 | self.assertEquals(ip.user_ns['_'], 'a\nb') |
|
38 | self.assertEquals(ip.user_ns['_'], 'a\nb') | |
38 |
|
39 | |||
39 | def test_run_empty_cell(self): |
|
40 | def test_run_empty_cell(self): | |
40 | """Just make sure we don't get a horrible error with a blank |
|
41 | """Just make sure we don't get a horrible error with a blank | |
41 | cell of input. Yes, I did overlook that.""" |
|
42 | cell of input. Yes, I did overlook that.""" | |
42 | ip = get_ipython() |
|
43 | ip = get_ipython() | |
43 | ip.run_cell('') |
|
44 | ip.run_cell('') | |
44 |
|
45 | |||
45 | def test_run_cell_multilne(self): |
|
46 | def test_run_cell_multiline(self): | |
46 | """Multi-block, multi-line cells must execute correctly. |
|
47 | """Multi-block, multi-line cells must execute correctly. | |
47 | """ |
|
48 | """ | |
48 | ip = get_ipython() |
|
49 | ip = get_ipython() | |
@@ -54,4 +55,34 b' class InteractiveShellTestCase(unittest.TestCase):' | |||||
54 | ip.run_cell(src) |
|
55 | ip.run_cell(src) | |
55 | self.assertEquals(ip.user_ns['x'], 2) |
|
56 | self.assertEquals(ip.user_ns['x'], 2) | |
56 | self.assertEquals(ip.user_ns['y'], 3) |
|
57 | self.assertEquals(ip.user_ns['y'], 3) | |
57 |
|
58 | |||
|
59 | @dec.skip_known_failure | |||
|
60 | def test_multiline_string_cells(self): | |||
|
61 | "Code sprinkled with multiline strings should execute (GH-306)" | |||
|
62 | ip = get_ipython() | |||
|
63 | ip.run_cell('tmp=0') | |||
|
64 | self.assertEquals(ip.user_ns['tmp'], 0) | |||
|
65 | ip.run_cell('tmp=1;"""a\nb"""\n') | |||
|
66 | self.assertEquals(ip.user_ns['tmp'], 1) | |||
|
67 | ||||
|
68 | @dec.skip_known_failure | |||
|
69 | def test_dont_cache_with_semicolon(self): | |||
|
70 | "Ending a line with semicolon should not cache the returned object (GH-307)" | |||
|
71 | ip = get_ipython() | |||
|
72 | oldlen = len(ip.user_ns['Out']) | |||
|
73 | a = ip.run_cell('1;') | |||
|
74 | newlen = len(ip.user_ns['Out']) | |||
|
75 | self.assertEquals(oldlen, newlen) | |||
|
76 | #also test the default caching behavior | |||
|
77 | ip.run_cell('1') | |||
|
78 | newlen = len(ip.user_ns['Out']) | |||
|
79 | self.assertEquals(oldlen+1, newlen) | |||
|
80 | ||||
|
81 | def test_In_variable(self): | |||
|
82 | "Verify that In variable grows with user input (GH-284)" | |||
|
83 | ip = get_ipython() | |||
|
84 | oldlen = len(ip.user_ns['In']) | |||
|
85 | ip.run_cell('1;') | |||
|
86 | newlen = len(ip.user_ns['In']) | |||
|
87 | self.assertEquals(oldlen+1, newlen) | |||
|
88 | self.assertEquals(ip.user_ns['In'][-1],'1;') |
@@ -170,6 +170,26 b' class TestMagicRunSimple(tt.TempFileMixin):' | |||||
170 | "a = A()\n") |
|
170 | "a = A()\n") | |
171 | self.mktmp(src) |
|
171 | self.mktmp(src) | |
172 | tt.ipexec_validate(self.fname, 'object A deleted') |
|
172 | tt.ipexec_validate(self.fname, 'object A deleted') | |
|
173 | ||||
|
174 | @dec.skip_known_failure | |||
|
175 | def test_aggressive_namespace_cleanup(self): | |||
|
176 | """Test that namespace cleanup is not too aggressive GH-238 | |||
|
177 | ||||
|
178 | Returning from another run magic deletes the namespace""" | |||
|
179 | # see ticket https://github.com/ipython/ipython/issues/238 | |||
|
180 | class secondtmp(tt.TempFileMixin): pass | |||
|
181 | empty = secondtmp() | |||
|
182 | empty.mktmp('') | |||
|
183 | src = ("ip = get_ipython()\n" | |||
|
184 | "for i in range(5):\n" | |||
|
185 | " try:\n" | |||
|
186 | " ip.magic('run %s')\n" | |||
|
187 | " except NameError, e:\n" | |||
|
188 | " print i;break\n" % empty.fname) | |||
|
189 | self.mktmp(src) | |||
|
190 | _ip.magic('run %s' % self.fname) | |||
|
191 | _ip.runlines('ip == get_ipython()') | |||
|
192 | tt.assert_equals(_ip.user_ns['i'], 5) | |||
173 |
|
193 | |||
174 | @dec.skip_win32 |
|
194 | @dec.skip_win32 | |
175 | def test_tclass(self): |
|
195 | def test_tclass(self): |
@@ -15,8 +15,14 b' Authors:' | |||||
15 | #----------------------------------------------------------------------------- |
|
15 | #----------------------------------------------------------------------------- | |
16 |
|
16 | |||
17 | from IPython.lib.latextools import latex_to_png |
|
17 | from IPython.lib.latextools import latex_to_png | |
|
18 | from IPython.testing import decorators as dec | |||
|
19 | # use @dec.skipif_not_sympy to skip tests requiring sympy | |||
|
20 | ||||
|
21 | try: | |||
|
22 | from sympy import pretty, latex | |||
|
23 | except ImportError: | |||
|
24 | pass | |||
18 |
|
25 | |||
19 | from sympy import pretty, latex |
|
|||
20 |
|
26 | |||
21 | #----------------------------------------------------------------------------- |
|
27 | #----------------------------------------------------------------------------- | |
22 | # Definitions of magic functions for use with IPython |
|
28 | # Definitions of magic functions for use with IPython | |
@@ -44,7 +50,6 b' def print_png(o):' | |||||
44 |
|
50 | |||
45 | _loaded = False |
|
51 | _loaded = False | |
46 |
|
52 | |||
47 |
|
||||
48 | def load_ipython_extension(ip): |
|
53 | def load_ipython_extension(ip): | |
49 | """Load the extension in IPython.""" |
|
54 | """Load the extension in IPython.""" | |
50 | global _loaded |
|
55 | global _loaded |
@@ -1,4 +1,6 b'' | |||||
1 | try: |
|
1 | try: | |
2 | from numpy.testing.decorators import * |
|
2 | from numpy.testing.decorators import * | |
|
3 | from numpy.testing.noseclasses import KnownFailure | |||
3 | except ImportError: |
|
4 | except ImportError: | |
4 | from _decorators import * |
|
5 | from _decorators import * | |
|
6 | from _numpy_testing_noseclasses import KnownFailure |
@@ -14,18 +14,15 b' function name, setup and teardown functions and so on - see' | |||||
14 |
|
14 | |||
15 | """ |
|
15 | """ | |
16 | import warnings |
|
16 | import warnings | |
17 | import sys |
|
|||
18 |
|
17 | |||
19 | # IPython changes: make this work if numpy not available |
|
18 | # IPython changes: make this work if numpy not available | |
20 | # Original code: |
|
19 | # Original code: | |
21 | #from numpy.testing.utils import \ |
|
20 | #from numpy.testing.utils import \ | |
22 | # WarningManager, WarningMessage |
|
21 | # WarningManager, WarningMessage | |
23 | # Our version: |
|
22 | # Our version: | |
24 | try: |
|
23 | from _numpy_testing_utils import WarningManager | |
25 | from numpy.testing.utils import WarningManager, WarningMessage |
|
24 | from _numpy_testing_noseclasses import KnownFailureTest | |
26 | except ImportError: |
|
25 | ||
27 | from _numpy_testing_utils import WarningManager, WarningMessage |
|
|||
28 |
|
||||
29 | # End IPython changes |
|
26 | # End IPython changes | |
30 |
|
27 | |||
31 | def slow(t): |
|
28 | def slow(t): | |
@@ -34,7 +31,7 b' def slow(t):' | |||||
34 |
|
31 | |||
35 | The exact definition of a slow test is obviously both subjective and |
|
32 | The exact definition of a slow test is obviously both subjective and | |
36 | hardware-dependent, but in general any individual test that requires more |
|
33 | hardware-dependent, but in general any individual test that requires more | |
37 | than a second or two should be labeled as slow (the whole suite consits of |
|
34 | than a second or two should be labeled as slow (the whole suite consists of | |
38 | thousands of tests, so even a second is significant). |
|
35 | thousands of tests, so even a second is significant). | |
39 |
|
36 | |||
40 | Parameters |
|
37 | Parameters | |
@@ -172,7 +169,6 b' def skipif(skip_condition, msg=None):' | |||||
172 |
|
169 | |||
173 | return skip_decorator |
|
170 | return skip_decorator | |
174 |
|
171 | |||
175 |
|
||||
176 | def knownfailureif(fail_condition, msg=None): |
|
172 | def knownfailureif(fail_condition, msg=None): | |
177 | """ |
|
173 | """ | |
178 | Make function raise KnownFailureTest exception if given condition is true. |
|
174 | Make function raise KnownFailureTest exception if given condition is true. | |
@@ -216,7 +212,6 b' def knownfailureif(fail_condition, msg=None):' | |||||
216 | # Local import to avoid a hard nose dependency and only incur the |
|
212 | # Local import to avoid a hard nose dependency and only incur the | |
217 | # import time overhead at actual test-time. |
|
213 | # import time overhead at actual test-time. | |
218 | import nose |
|
214 | import nose | |
219 | from noseclasses import KnownFailureTest |
|
|||
220 | def knownfailer(*args, **kwargs): |
|
215 | def knownfailer(*args, **kwargs): | |
221 | if fail_val(): |
|
216 | if fail_val(): | |
222 | raise KnownFailureTest, msg |
|
217 | raise KnownFailureTest, msg | |
@@ -255,7 +250,6 b' def deprecated(conditional=True):' | |||||
255 | # Local import to avoid a hard nose dependency and only incur the |
|
250 | # Local import to avoid a hard nose dependency and only incur the | |
256 | # import time overhead at actual test-time. |
|
251 | # import time overhead at actual test-time. | |
257 | import nose |
|
252 | import nose | |
258 | from noseclasses import KnownFailureTest |
|
|||
259 |
|
253 | |||
260 | def _deprecated_imp(*args, **kwargs): |
|
254 | def _deprecated_imp(*args, **kwargs): | |
261 | # Poor man's replacement for the with statement |
|
255 | # Poor man's replacement for the with statement |
@@ -1,14 +1,10 b'' | |||||
1 |
# IPython: modified copy of numpy.testing.utils, so |
|
1 | # IPython: modified copy of numpy.testing.utils, so | |
2 | # works without numpy being installed. |
|
2 | # IPython.external._decorators works without numpy being installed. | |
3 | """ |
|
3 | """ | |
4 | Utility function to facilitate testing. |
|
4 | Utility function to facilitate testing. | |
5 | """ |
|
5 | """ | |
6 |
|
6 | |||
7 | import os |
|
|||
8 | import sys |
|
7 | import sys | |
9 | import re |
|
|||
10 | import operator |
|
|||
11 | import types |
|
|||
12 | import warnings |
|
8 | import warnings | |
13 |
|
9 | |||
14 | # The following two classes are copied from python 2.6 warnings module (context |
|
10 | # The following two classes are copied from python 2.6 warnings module (context |
@@ -24,9 +24,10 b' Lightweight testing that remains unittest-compatible.' | |||||
24 | recognize it as such. This will make it easier to migrate away from Nose if |
|
24 | recognize it as such. This will make it easier to migrate away from Nose if | |
25 | we ever need/want to while maintaining very lightweight tests. |
|
25 | we ever need/want to while maintaining very lightweight tests. | |
26 |
|
26 | |||
27 |
NOTE: This file contains IPython-specific decorators |
|
27 | NOTE: This file contains IPython-specific decorators. Using the machinery in | |
28 | numpy.testing.decorators file, which we've copied verbatim. Any of our own |
|
28 | IPython.external.decorators, we import either numpy.testing.decorators if numpy is | |
29 | code will be added at the bottom if we end up extending this. |
|
29 | available, OR use equivalent code in IPython.external._decorators, which | |
|
30 | we've copied verbatim from numpy. | |||
30 |
|
31 | |||
31 | Authors |
|
32 | Authors | |
32 | ------- |
|
33 | ------- | |
@@ -274,19 +275,19 b' def onlyif(condition, msg):' | |||||
274 |
|
275 | |||
275 | #----------------------------------------------------------------------------- |
|
276 | #----------------------------------------------------------------------------- | |
276 | # Utility functions for decorators |
|
277 | # Utility functions for decorators | |
277 |
def |
|
278 | def module_not_available(module): | |
278 |
"""Can |
|
279 | """Can module be imported? Returns true if module does NOT import. | |
279 |
|
280 | |||
280 |
This is used to make a decorator to skip tests that require |
|
281 | This is used to make a decorator to skip tests that require module to be | |
281 | available, but delay the 'import numpy' to test execution time. |
|
282 | available, but delay the 'import numpy' to test execution time. | |
282 | """ |
|
283 | """ | |
283 | try: |
|
284 | try: | |
284 | import numpy |
|
285 | mod = __import__(module) | |
285 |
|
|
286 | mod_not_avail = False | |
286 | except ImportError: |
|
287 | except ImportError: | |
287 |
|
|
288 | mod_not_avail = True | |
288 |
|
289 | |||
289 |
return |
|
290 | return mod_not_avail | |
290 |
|
291 | |||
291 | #----------------------------------------------------------------------------- |
|
292 | #----------------------------------------------------------------------------- | |
292 | # Decorators for public use |
|
293 | # Decorators for public use | |
@@ -315,9 +316,11 b" skip_if_not_osx = skipif(sys.platform != 'darwin'," | |||||
315 | "This test only runs under OSX") |
|
316 | "This test only runs under OSX") | |
316 |
|
317 | |||
317 | # Other skip decorators |
|
318 | # Other skip decorators | |
318 |
skipif_not_numpy = skipif( |
|
319 | skipif_not_numpy = skipif(module_not_available('numpy'),"This test requires numpy") | |
319 |
|
320 | |||
320 | skip_known_failure = skip('This test is known to fail') |
|
321 | skipif_not_sympy = skipif(module_not_available('sympy'),"This test requires sympy") | |
|
322 | ||||
|
323 | skip_known_failure = knownfailureif(True,'This test is known to fail') | |||
321 |
|
324 | |||
322 | # A null 'decorator', useful to make more readable code that needs to pick |
|
325 | # A null 'decorator', useful to make more readable code that needs to pick | |
323 | # between different decorators based on OS or other conditions |
|
326 | # between different decorators based on OS or other conditions |
@@ -53,6 +53,7 b' from IPython.utils.sysinfo import sys_info' | |||||
53 |
|
53 | |||
54 | from IPython.testing import globalipapp |
|
54 | from IPython.testing import globalipapp | |
55 | from IPython.testing.plugin.ipdoctest import IPythonDoctest |
|
55 | from IPython.testing.plugin.ipdoctest import IPythonDoctest | |
|
56 | from IPython.external.decorators import KnownFailure | |||
56 |
|
57 | |||
57 | pjoin = path.join |
|
58 | pjoin = path.join | |
58 |
|
59 | |||
@@ -357,7 +358,7 b' def run_iptest():' | |||||
357 |
|
358 | |||
358 | # Construct list of plugins, omitting the existing doctest plugin, which |
|
359 | # Construct list of plugins, omitting the existing doctest plugin, which | |
359 | # ours replaces (and extends). |
|
360 | # ours replaces (and extends). | |
360 | plugins = [IPythonDoctest(make_exclude())] |
|
361 | plugins = [IPythonDoctest(make_exclude()), KnownFailure()] | |
361 | for p in nose.plugins.builtin.plugins: |
|
362 | for p in nose.plugins.builtin.plugins: | |
362 | plug = p() |
|
363 | plug = p() | |
363 | if plug.name == 'doctest': |
|
364 | if plug.name == 'doctest': |
General Comments 0
You need to be logged in to leave comments.
Login now