##// END OF EJS Templates
Add a test
Jessica B. Hamrick -
Show More
@@ -0,0 +1,49 b''
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {
7 "collapsed": false
8 },
9 "outputs": [
10 {
11 "ename": "KeyboardInterrupt",
12 "evalue": "",
13 "output_type": "error",
14 "traceback": [
15 "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
16 "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
17 "\u001b[0;32m<ipython-input-1-31d18a52bf41>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mwhile\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;32mcontinue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
18 "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
19 ]
20 }
21 ],
22 "source": [
23 "while True: continue"
24 ]
25 },
26 {
27 "cell_type": "code",
28 "execution_count": 2,
29 "metadata": {
30 "collapsed": false
31 },
32 "outputs": [
33 {
34 "name": "stdout",
35 "output_type": "stream",
36 "text": [
37 "done\n"
38 ]
39 }
40 ],
41 "source": [
42 "print(\"done\")"
43 ]
44 }
45 ],
46 "metadata": {},
47 "nbformat": 4,
48 "nbformat_minor": 0
49 }
@@ -1,124 +1,137 b''
1 """
1 """
2 Module with tests for the execute preprocessor.
2 Module with tests for the execute preprocessor.
3 """
3 """
4
4
5 # Copyright (c) IPython Development Team.
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7
7
8 import copy
8 import copy
9 import glob
9 import glob
10 import io
10 import io
11 import os
11 import os
12 import re
12 import re
13
13
14 from IPython import nbformat
14 from IPython import nbformat
15
15
16 from .base import PreprocessorTestsBase
16 from .base import PreprocessorTestsBase
17 from ..execute import ExecutePreprocessor
17 from ..execute import ExecutePreprocessor
18
18
19 from IPython.nbconvert.filters import strip_ansi
19 from IPython.nbconvert.filters import strip_ansi
20
20
21 addr_pat = re.compile(r'0x[0-9a-f]{7,9}')
21 addr_pat = re.compile(r'0x[0-9a-f]{7,9}')
22
22
23 class TestExecute(PreprocessorTestsBase):
23 class TestExecute(PreprocessorTestsBase):
24 """Contains test functions for execute.py"""
24 """Contains test functions for execute.py"""
25
25
26 @staticmethod
26 @staticmethod
27 def normalize_output(output):
27 def normalize_output(output):
28 """
28 """
29 Normalizes outputs for comparison.
29 Normalizes outputs for comparison.
30 """
30 """
31 output = dict(output)
31 output = dict(output)
32 if 'metadata' in output:
32 if 'metadata' in output:
33 del output['metadata']
33 del output['metadata']
34 if 'text' in output:
34 if 'text' in output:
35 output['text'] = re.sub(addr_pat, '<HEXADDR>', output['text'])
35 output['text'] = re.sub(addr_pat, '<HEXADDR>', output['text'])
36 if 'text/plain' in output.get('data', {}):
36 if 'text/plain' in output.get('data', {}):
37 output['data']['text/plain'] = \
37 output['data']['text/plain'] = \
38 re.sub(addr_pat, '<HEXADDR>', output['data']['text/plain'])
38 re.sub(addr_pat, '<HEXADDR>', output['data']['text/plain'])
39 if 'traceback' in output:
39 if 'traceback' in output:
40 tb = []
40 tb = []
41 for line in output['traceback']:
41 for line in output['traceback']:
42 tb.append(strip_ansi(line))
42 tb.append(strip_ansi(line))
43 output['traceback'] = tb
43 output['traceback'] = tb
44
44
45 return output
45 return output
46
46
47
47
48 def assert_notebooks_equal(self, expected, actual):
48 def assert_notebooks_equal(self, expected, actual):
49 expected_cells = expected['cells']
49 expected_cells = expected['cells']
50 actual_cells = actual['cells']
50 actual_cells = actual['cells']
51 self.assertEqual(len(expected_cells), len(actual_cells))
51 self.assertEqual(len(expected_cells), len(actual_cells))
52
52
53 for expected_cell, actual_cell in zip(expected_cells, actual_cells):
53 for expected_cell, actual_cell in zip(expected_cells, actual_cells):
54 expected_outputs = expected_cell.get('outputs', [])
54 expected_outputs = expected_cell.get('outputs', [])
55 actual_outputs = actual_cell.get('outputs', [])
55 actual_outputs = actual_cell.get('outputs', [])
56 normalized_expected_outputs = list(map(self.normalize_output, expected_outputs))
56 normalized_expected_outputs = list(map(self.normalize_output, expected_outputs))
57 normalized_actual_outputs = list(map(self.normalize_output, actual_outputs))
57 normalized_actual_outputs = list(map(self.normalize_output, actual_outputs))
58 self.assertEqual(normalized_expected_outputs, normalized_actual_outputs)
58 self.assertEqual(normalized_expected_outputs, normalized_actual_outputs)
59
59
60 expected_execution_count = expected_cell.get('execution_count', None)
60 expected_execution_count = expected_cell.get('execution_count', None)
61 actual_execution_count = actual_cell.get('execution_count', None)
61 actual_execution_count = actual_cell.get('execution_count', None)
62 self.assertEqual(expected_execution_count, actual_execution_count)
62 self.assertEqual(expected_execution_count, actual_execution_count)
63
63
64
64
65 def build_preprocessor(self):
65 def build_preprocessor(self, opts):
66 """Make an instance of a preprocessor"""
66 """Make an instance of a preprocessor"""
67 preprocessor = ExecutePreprocessor()
67 preprocessor = ExecutePreprocessor()
68 preprocessor.enabled = True
68 preprocessor.enabled = True
69 for opt in opts:
70 setattr(preprocessor, opt, opts[opt])
69 return preprocessor
71 return preprocessor
70
72
71
73
72 def test_constructor(self):
74 def test_constructor(self):
73 """Can a ExecutePreprocessor be constructed?"""
75 """Can a ExecutePreprocessor be constructed?"""
74 self.build_preprocessor()
76 self.build_preprocessor({})
75
77
76
78
79 def run_notebook(self, filename, opts, resources):
80 """Loads and runs a notebook, returning both the version prior to
81 running it and the version after running it.
82
83 """
84 with io.open(filename) as f:
85 input_nb = nbformat.read(f, 4)
86 preprocessor = self.build_preprocessor(opts)
87 cleaned_input_nb = copy.deepcopy(input_nb)
88 for cell in cleaned_input_nb.cells:
89 if 'execution_count' in cell:
90 del cell['execution_count']
91 cell['outputs'] = []
92 output_nb, _ = preprocessor(cleaned_input_nb, resources)
93 return input_nb, output_nb
94
77 def test_run_notebooks(self):
95 def test_run_notebooks(self):
78 """Runs a series of test notebooks and compares them to their actual output"""
96 """Runs a series of test notebooks and compares them to their actual output"""
79 current_dir = os.path.dirname(__file__)
97 current_dir = os.path.dirname(__file__)
80 input_files = glob.glob(os.path.join(current_dir, 'files', '*.ipynb'))
98 input_files = glob.glob(os.path.join(current_dir, 'files', '*.ipynb'))
81 for filename in input_files:
99 for filename in input_files:
82 with io.open(filename) as f:
83 input_nb = nbformat.read(f, 4)
84 res = self.build_resources()
85 res['metadata']['path'] = os.path.dirname(filename)
86 preprocessor = self.build_preprocessor()
87 cleaned_input_nb = copy.deepcopy(input_nb)
88 for cell in cleaned_input_nb.cells:
89 if 'execution_count' in cell:
90 del cell['execution_count']
91 cell['outputs'] = []
92 output_nb, _ = preprocessor(cleaned_input_nb, res)
93
94 if os.path.basename(filename) == "Disable Stdin.ipynb":
100 if os.path.basename(filename) == "Disable Stdin.ipynb":
95 # We need to special-case this particular notebook, because the
101 continue
96 # traceback contains machine-specific stuff like where IPython
102 elif os.path.basename(filename) == "Interrupt.ipynb":
97 # is installed. It is sufficient here to just check that an error
103 opts = dict(timeout=1, interrupt_on_timeout=True)
98 # was thrown, and that it was a StdinNotImplementedError
99 self.assertEqual(len(output_nb['cells']), 1)
100 self.assertEqual(len(output_nb['cells'][0]['outputs']), 1)
101 output = output_nb['cells'][0]['outputs'][0]
102 self.assertEqual(output['output_type'], 'error')
103 self.assertEqual(output['ename'], 'StdinNotImplementedError')
104 self.assertEqual(output['evalue'], 'raw_input was called, but this frontend does not support input requests.')
105
106 else:
104 else:
107 self.assert_notebooks_equal(output_nb, input_nb)
105 opts = {}
106 res = self.build_resources()
107 res['metadata']['path'] = os.path.dirname(filename)
108 input_nb, output_nb = self.run_notebook(filename, opts, res)
109 self.assert_notebooks_equal(input_nb, output_nb)
108
110
109 def test_empty_path(self):
111 def test_empty_path(self):
110 """Can the kernel be started when the path is empty?"""
112 """Can the kernel be started when the path is empty?"""
111 current_dir = os.path.dirname(__file__)
113 current_dir = os.path.dirname(__file__)
112 filename = os.path.join(current_dir, 'files', 'HelloWorld.ipynb')
114 filename = os.path.join(current_dir, 'files', 'HelloWorld.ipynb')
113 with io.open(filename) as f:
114 input_nb = nbformat.read(f, 4)
115 res = self.build_resources()
115 res = self.build_resources()
116 res['metadata']['path'] = ''
116 res['metadata']['path'] = ''
117 preprocessor = self.build_preprocessor()
117 input_nb, output_nb = self.run_notebook(filename, {}, res)
118 cleaned_input_nb = copy.deepcopy(input_nb)
118 self.assert_notebooks_equal(input_nb, output_nb)
119 for cell in cleaned_input_nb.cells:
119
120 if 'execution_count' in cell:
120 def test_disable_stdin(self):
121 del cell['execution_count']
121 """Test disabling standard input"""
122 cell['outputs'] = []
122 current_dir = os.path.dirname(__file__)
123 output_nb, _ = preprocessor(cleaned_input_nb, res)
123 filename = os.path.join(current_dir, 'files', 'Disable Stdin.ipynb')
124 self.assert_notebooks_equal(output_nb, input_nb)
124 res = self.build_resources()
125 res['metadata']['path'] = os.path.dirname(filename)
126 input_nb, output_nb = self.run_notebook(filename, {}, res)
127
128 # We need to special-case this particular notebook, because the
129 # traceback contains machine-specific stuff like where IPython
130 # is installed. It is sufficient here to just check that an error
131 # was thrown, and that it was a StdinNotImplementedError
132 self.assertEqual(len(output_nb['cells']), 1)
133 self.assertEqual(len(output_nb['cells'][0]['outputs']), 1)
134 output = output_nb['cells'][0]['outputs'][0]
135 self.assertEqual(output['output_type'], 'error')
136 self.assertEqual(output['ename'], 'StdinNotImplementedError')
137 self.assertEqual(output['evalue'], 'raw_input was called, but this frontend does not support input requests.')
General Comments 0
You need to be logged in to leave comments. Login now