##// END OF EJS Templates
[terminal][tests][interactiveshell] Remove nose
Samuel Gaist -
Show More
@@ -1,193 +1,225 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tests for the TerminalInteractiveShell and related pieces."""
2 """Tests for the TerminalInteractiveShell and related pieces."""
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import sys
6 import sys
7 import unittest
7 import unittest
8 import os
8 import os
9
9
10 from IPython.core.inputtransformer import InputTransformer
10 from IPython.core.inputtransformer import InputTransformer
11 from IPython.testing import tools as tt
11 from IPython.testing import tools as tt
12 from IPython.utils.capture import capture_output
12 from IPython.utils.capture import capture_output
13
13
14 from IPython.terminal.ptutils import _elide, _adjust_completion_text_based_on_context
14 from IPython.terminal.ptutils import _elide, _adjust_completion_text_based_on_context
15 import nose.tools as nt
16
15
17 class TestElide(unittest.TestCase):
18
16
17 class TestElide(unittest.TestCase):
19 def test_elide(self):
18 def test_elide(self):
20 _elide('concatenate((a1, a2, ...), axis', '') # do not raise
19 _elide("concatenate((a1, a2, ...), axis", "") # do not raise
21 _elide('concatenate((a1, a2, ..), . axis', '') # do not raise
20 _elide("concatenate((a1, a2, ..), . axis", "") # do not raise
22 nt.assert_equal(_elide('aaaa.bbbb.ccccc.dddddd.eeeee.fffff.gggggg.hhhhhh',''), 'aaaa.b…g.hhhhhh')
21 self.assertEqual(
23
22 _elide("aaaa.bbbb.ccccc.dddddd.eeeee.fffff.gggggg.hhhhhh", ""),
24 test_string = os.sep.join(['', 10*'a', 10*'b', 10*'c', ''])
23 "aaaa.b…g.hhhhhh",
25 expect_stirng = os.sep + 'a' + '\N{HORIZONTAL ELLIPSIS}' + 'b' + os.sep + 10*'c'
24 )
26 nt.assert_equal(_elide(test_string, ''), expect_stirng)
25
26 test_string = os.sep.join(["", 10 * "a", 10 * "b", 10 * "c", ""])
27 expect_stirng = (
28 os.sep + "a" + "\N{HORIZONTAL ELLIPSIS}" + "b" + os.sep + 10 * "c"
29 )
30 self.assertEqual(_elide(test_string, ""), expect_stirng)
27
31
28 def test_elide_typed_normal(self):
32 def test_elide_typed_normal(self):
29 nt.assert_equal(_elide('the quick brown fox jumped over the lazy dog', 'the quick brown fox', min_elide=10), 'the…fox jumped over the lazy dog')
33 self.assertEqual(
30
34 _elide(
35 "the quick brown fox jumped over the lazy dog",
36 "the quick brown fox",
37 min_elide=10,
38 ),
39 "the…fox jumped over the lazy dog",
40 )
31
41
32 def test_elide_typed_short_match(self):
42 def test_elide_typed_short_match(self):
33 """
43 """
34 if the match is too short we don't elide.
44 if the match is too short we don't elide.
35 avoid the "the...the"
45 avoid the "the...the"
36 """
46 """
37 nt.assert_equal(_elide('the quick brown fox jumped over the lazy dog', 'the', min_elide=10), 'the quick brown fox jumped over the lazy dog')
47 self.assertEqual(
48 _elide("the quick brown fox jumped over the lazy dog", "the", min_elide=10),
49 "the quick brown fox jumped over the lazy dog",
50 )
38
51
39 def test_elide_typed_no_match(self):
52 def test_elide_typed_no_match(self):
40 """
53 """
41 if the match is too short we don't elide.
54 if the match is too short we don't elide.
42 avoid the "the...the"
55 avoid the "the...the"
43 """
56 """
44 # here we typed red instead of brown
57 # here we typed red instead of brown
45 nt.assert_equal(_elide('the quick brown fox jumped over the lazy dog', 'the quick red fox', min_elide=10), 'the quick brown fox jumped over the lazy dog')
58 self.assertEqual(
59 _elide(
60 "the quick brown fox jumped over the lazy dog",
61 "the quick red fox",
62 min_elide=10,
63 ),
64 "the quick brown fox jumped over the lazy dog",
65 )
46
66
47 class TestContextAwareCompletion(unittest.TestCase):
48
67
68 class TestContextAwareCompletion(unittest.TestCase):
49 def test_adjust_completion_text_based_on_context(self):
69 def test_adjust_completion_text_based_on_context(self):
50 # Adjusted case
70 # Adjusted case
51 nt.assert_equal(_adjust_completion_text_based_on_context('arg1=', 'func1(a=)', 7), 'arg1')
71 self.assertEqual(
72 _adjust_completion_text_based_on_context("arg1=", "func1(a=)", 7), "arg1"
73 )
52
74
53 # Untouched cases
75 # Untouched cases
54 nt.assert_equal(_adjust_completion_text_based_on_context('arg1=', 'func1(a)', 7), 'arg1=')
76 self.assertEqual(
55 nt.assert_equal(_adjust_completion_text_based_on_context('arg1=', 'func1(a', 7), 'arg1=')
77 _adjust_completion_text_based_on_context("arg1=", "func1(a)", 7), "arg1="
56 nt.assert_equal(_adjust_completion_text_based_on_context('%magic', 'func1(a=)', 7), '%magic')
78 )
57 nt.assert_equal(_adjust_completion_text_based_on_context('func2', 'func1(a=)', 7), 'func2')
79 self.assertEqual(
80 _adjust_completion_text_based_on_context("arg1=", "func1(a", 7), "arg1="
81 )
82 self.assertEqual(
83 _adjust_completion_text_based_on_context("%magic", "func1(a=)", 7), "%magic"
84 )
85 self.assertEqual(
86 _adjust_completion_text_based_on_context("func2", "func1(a=)", 7), "func2"
87 )
88
58
89
59 # Decorator for interaction loop tests -----------------------------------------
90 # Decorator for interaction loop tests -----------------------------------------
60
91
92
61 class mock_input_helper(object):
93 class mock_input_helper(object):
62 """Machinery for tests of the main interact loop.
94 """Machinery for tests of the main interact loop.
63
95
64 Used by the mock_input decorator.
96 Used by the mock_input decorator.
65 """
97 """
66 def __init__(self, testgen):
98 def __init__(self, testgen):
67 self.testgen = testgen
99 self.testgen = testgen
68 self.exception = None
100 self.exception = None
69 self.ip = get_ipython()
101 self.ip = get_ipython()
70
102
71 def __enter__(self):
103 def __enter__(self):
72 self.orig_prompt_for_code = self.ip.prompt_for_code
104 self.orig_prompt_for_code = self.ip.prompt_for_code
73 self.ip.prompt_for_code = self.fake_input
105 self.ip.prompt_for_code = self.fake_input
74 return self
106 return self
75
107
76 def __exit__(self, etype, value, tb):
108 def __exit__(self, etype, value, tb):
77 self.ip.prompt_for_code = self.orig_prompt_for_code
109 self.ip.prompt_for_code = self.orig_prompt_for_code
78
110
79 def fake_input(self):
111 def fake_input(self):
80 try:
112 try:
81 return next(self.testgen)
113 return next(self.testgen)
82 except StopIteration:
114 except StopIteration:
83 self.ip.keep_running = False
115 self.ip.keep_running = False
84 return u''
116 return u''
85 except:
117 except:
86 self.exception = sys.exc_info()
118 self.exception = sys.exc_info()
87 self.ip.keep_running = False
119 self.ip.keep_running = False
88 return u''
120 return u''
89
121
90 def mock_input(testfunc):
122 def mock_input(testfunc):
91 """Decorator for tests of the main interact loop.
123 """Decorator for tests of the main interact loop.
92
124
93 Write the test as a generator, yield-ing the input strings, which IPython
125 Write the test as a generator, yield-ing the input strings, which IPython
94 will see as if they were typed in at the prompt.
126 will see as if they were typed in at the prompt.
95 """
127 """
96 def test_method(self):
128 def test_method(self):
97 testgen = testfunc(self)
129 testgen = testfunc(self)
98 with mock_input_helper(testgen) as mih:
130 with mock_input_helper(testgen) as mih:
99 mih.ip.interact()
131 mih.ip.interact()
100
132
101 if mih.exception is not None:
133 if mih.exception is not None:
102 # Re-raise captured exception
134 # Re-raise captured exception
103 etype, value, tb = mih.exception
135 etype, value, tb = mih.exception
104 import traceback
136 import traceback
105 traceback.print_tb(tb, file=sys.stdout)
137 traceback.print_tb(tb, file=sys.stdout)
106 del tb # Avoid reference loop
138 del tb # Avoid reference loop
107 raise value
139 raise value
108
140
109 return test_method
141 return test_method
110
142
111 # Test classes -----------------------------------------------------------------
143 # Test classes -----------------------------------------------------------------
112
144
113 class InteractiveShellTestCase(unittest.TestCase):
145 class InteractiveShellTestCase(unittest.TestCase):
114 def rl_hist_entries(self, rl, n):
146 def rl_hist_entries(self, rl, n):
115 """Get last n readline history entries as a list"""
147 """Get last n readline history entries as a list"""
116 return [rl.get_history_item(rl.get_current_history_length() - x)
148 return [rl.get_history_item(rl.get_current_history_length() - x)
117 for x in range(n - 1, -1, -1)]
149 for x in range(n - 1, -1, -1)]
118
150
119 @mock_input
151 @mock_input
120 def test_inputtransformer_syntaxerror(self):
152 def test_inputtransformer_syntaxerror(self):
121 ip = get_ipython()
153 ip = get_ipython()
122 ip.input_transformers_post.append(syntax_error_transformer)
154 ip.input_transformers_post.append(syntax_error_transformer)
123
155
124 try:
156 try:
125 #raise Exception
157 #raise Exception
126 with tt.AssertPrints('4', suppress=False):
158 with tt.AssertPrints('4', suppress=False):
127 yield u'print(2*2)'
159 yield u'print(2*2)'
128
160
129 with tt.AssertPrints('SyntaxError: input contains', suppress=False):
161 with tt.AssertPrints('SyntaxError: input contains', suppress=False):
130 yield u'print(2345) # syntaxerror'
162 yield u'print(2345) # syntaxerror'
131
163
132 with tt.AssertPrints('16', suppress=False):
164 with tt.AssertPrints('16', suppress=False):
133 yield u'print(4*4)'
165 yield u'print(4*4)'
134
166
135 finally:
167 finally:
136 ip.input_transformers_post.remove(syntax_error_transformer)
168 ip.input_transformers_post.remove(syntax_error_transformer)
137
169
138 def test_plain_text_only(self):
170 def test_plain_text_only(self):
139 ip = get_ipython()
171 ip = get_ipython()
140 formatter = ip.display_formatter
172 formatter = ip.display_formatter
141 assert formatter.active_types == ['text/plain']
173 assert formatter.active_types == ['text/plain']
142 assert not formatter.ipython_display_formatter.enabled
174 assert not formatter.ipython_display_formatter.enabled
143
175
144 class Test(object):
176 class Test(object):
145 def __repr__(self):
177 def __repr__(self):
146 return "<Test %i>" % id(self)
178 return "<Test %i>" % id(self)
147
179
148 def _repr_html_(self):
180 def _repr_html_(self):
149 return '<html>'
181 return '<html>'
150
182
151 # verify that HTML repr isn't computed
183 # verify that HTML repr isn't computed
152 obj = Test()
184 obj = Test()
153 data, _ = formatter.format(obj)
185 data, _ = formatter.format(obj)
154 self.assertEqual(data, {'text/plain': repr(obj)})
186 self.assertEqual(data, {'text/plain': repr(obj)})
155
187
156 class Test2(Test):
188 class Test2(Test):
157 def _ipython_display_(self):
189 def _ipython_display_(self):
158 from IPython.display import display
190 from IPython.display import display
159 display('<custom>')
191 display('<custom>')
160
192
161 # verify that _ipython_display_ shortcut isn't called
193 # verify that _ipython_display_ shortcut isn't called
162 obj = Test2()
194 obj = Test2()
163 with capture_output() as captured:
195 with capture_output() as captured:
164 data, _ = formatter.format(obj)
196 data, _ = formatter.format(obj)
165
197
166 self.assertEqual(data, {'text/plain': repr(obj)})
198 self.assertEqual(data, {'text/plain': repr(obj)})
167 assert captured.stdout == ''
199 assert captured.stdout == ''
168
200
169 def syntax_error_transformer(lines):
201 def syntax_error_transformer(lines):
170 """Transformer that throws SyntaxError if 'syntaxerror' is in the code."""
202 """Transformer that throws SyntaxError if 'syntaxerror' is in the code."""
171 for line in lines:
203 for line in lines:
172 pos = line.find('syntaxerror')
204 pos = line.find('syntaxerror')
173 if pos >= 0:
205 if pos >= 0:
174 e = SyntaxError('input contains "syntaxerror"')
206 e = SyntaxError('input contains "syntaxerror"')
175 e.text = line
207 e.text = line
176 e.offset = pos + 1
208 e.offset = pos + 1
177 raise e
209 raise e
178 return lines
210 return lines
179
211
180
212
181 class TerminalMagicsTestCase(unittest.TestCase):
213 class TerminalMagicsTestCase(unittest.TestCase):
182 def test_paste_magics_blankline(self):
214 def test_paste_magics_blankline(self):
183 """Test that code with a blank line doesn't get split (gh-3246)."""
215 """Test that code with a blank line doesn't get split (gh-3246)."""
184 ip = get_ipython()
216 ip = get_ipython()
185 s = ('def pasted_func(a):\n'
217 s = ('def pasted_func(a):\n'
186 ' b = a+1\n'
218 ' b = a+1\n'
187 '\n'
219 '\n'
188 ' return b')
220 ' return b')
189
221
190 tm = ip.magics_manager.registry['TerminalMagics']
222 tm = ip.magics_manager.registry['TerminalMagics']
191 tm.store_or_execute(s, name=None)
223 tm.store_or_execute(s, name=None)
192
224
193 self.assertEqual(ip.user_ns['pasted_func'](54), 55)
225 self.assertEqual(ip.user_ns['pasted_func'](54), 55)
General Comments 0
You need to be logged in to leave comments. Login now