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