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