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