Show More
@@ -0,0 +1,101 b'' | |||||
|
1 | #!/usr/bin/env python | |||
|
2 | """Master test runner for IPython - EXPERIMENTAL CODE!!! | |||
|
3 | ||||
|
4 | This tries | |||
|
5 | ||||
|
6 | XXX - Big limitation right now: we don't summarize the total test counts. That | |||
|
7 | would require parsing the output of the subprocesses. | |||
|
8 | """ | |||
|
9 | import os.path as path | |||
|
10 | import subprocess as subp | |||
|
11 | import time | |||
|
12 | ||||
|
13 | class IPTester(object): | |||
|
14 | """Object to call iptest with specific parameters. | |||
|
15 | """ | |||
|
16 | def __init__(self,runner='iptest',params=None): | |||
|
17 | """ """ | |||
|
18 | if runner == 'iptest': | |||
|
19 | self.runner = ['iptest','-v'] | |||
|
20 | else: | |||
|
21 | self.runner = ['trial'] | |||
|
22 | if params is None: | |||
|
23 | params = [] | |||
|
24 | if isinstance(params,str): | |||
|
25 | params = [params] | |||
|
26 | self.params = params | |||
|
27 | ||||
|
28 | # Assemble call | |||
|
29 | self.call_args = self.runner+self.params | |||
|
30 | ||||
|
31 | def run(self): | |||
|
32 | """Run the stored commands""" | |||
|
33 | return subp.call(self.call_args) | |||
|
34 | ||||
|
35 | ||||
|
36 | def make_runners(): | |||
|
37 | top_mod = \ | |||
|
38 | ['background_jobs.py', 'ColorANSI.py', 'completer.py', 'ConfigLoader.py', | |||
|
39 | 'CrashHandler.py', 'Debugger.py', 'deep_reload.py', 'demo.py', | |||
|
40 | 'DPyGetOpt.py', 'dtutils.py', 'excolors.py', 'FakeModule.py', | |||
|
41 | 'generics.py', 'genutils.py', 'Gnuplot2.py', 'GnuplotInteractive.py', | |||
|
42 | 'GnuplotRuntime.py', 'history.py', 'hooks.py', 'ipapi.py', | |||
|
43 | 'iplib.py', 'ipmaker.py', 'ipstruct.py', 'irunner.py', 'Itpl.py', | |||
|
44 | 'Logger.py', 'macro.py', 'Magic.py', 'numutils.py', 'OInspect.py', | |||
|
45 | 'OutputTrap.py', 'platutils_dummy.py', 'platutils_posix.py', | |||
|
46 | 'platutils.py', 'platutils_win32.py', 'prefilter.py', 'Prompts.py', | |||
|
47 | 'PyColorize.py', 'Release.py', 'rlineimpl.py', 'shadowns.py', | |||
|
48 | 'shellglobals.py', 'Shell.py', 'strdispatch.py', 'twshell.py', | |||
|
49 | 'ultraTB.py', 'upgrade_dir.py', 'usage.py', 'wildcard.py', | |||
|
50 | 'winconsole.py'] | |||
|
51 | ||||
|
52 | top_pack = ['config','Extensions','frontend','gui','kernel', | |||
|
53 | 'testing','tests','tools','UserConfig'] | |||
|
54 | ||||
|
55 | modules = ['IPython.%s' % m for m in top_mod ] | |||
|
56 | packages = ['IPython.%s' % m for m in top_pack ] | |||
|
57 | ||||
|
58 | # Make runners | |||
|
59 | runners = dict(zip(top_pack, [IPTester(params=v) for v in packages])) | |||
|
60 | runners['trial'] = IPTester('trial',['IPython']) | |||
|
61 | ||||
|
62 | return runners | |||
|
63 | ||||
|
64 | ||||
|
65 | def main(): | |||
|
66 | runners = make_runners() | |||
|
67 | # Run all test runners, tracking execution time | |||
|
68 | failed = {} | |||
|
69 | t_start = time.time() | |||
|
70 | for name,runner in runners.iteritems(): | |||
|
71 | print '*'*77 | |||
|
72 | print 'IPython test set:',name | |||
|
73 | res = runner.run() | |||
|
74 | if res: | |||
|
75 | failed[name] = res | |||
|
76 | t_end = time.time() | |||
|
77 | t_tests = t_end - t_start | |||
|
78 | nrunners = len(runners) | |||
|
79 | nfail = len(failed) | |||
|
80 | # summarize results | |||
|
81 | ||||
|
82 | print '*'*77 | |||
|
83 | print 'Ran %s test sets in %.3fs' % (nrunners, t_tests) | |||
|
84 | ||||
|
85 | if not failed: | |||
|
86 | print 'OK' | |||
|
87 | else: | |||
|
88 | # If anything went wrong, point out what command to rerun manually to | |||
|
89 | # see the actual errors and individual summary | |||
|
90 | print 'ERROR - %s out of %s test sets failed.' % (nfail, nrunners) | |||
|
91 | for name in failed: | |||
|
92 | failed_runner = runners[name] | |||
|
93 | print '-'*40 | |||
|
94 | print 'Runner failed:',name | |||
|
95 | print 'You may wish to rerun this one individually, with:' | |||
|
96 | print ' '.join(failed_runner.call_args) | |||
|
97 | ||||
|
98 | ||||
|
99 | ||||
|
100 | if __name__ == '__main__': | |||
|
101 | main() |
@@ -99,16 +99,14 b' def main():' | |||||
99 | #import readline |
|
99 | #import readline | |
100 | #readline.parse_and_bind('set completion-query-items 1000') |
|
100 | #readline.parse_and_bind('set completion-query-items 1000') | |
101 | #readline.parse_and_bind('set page-completions no') |
|
101 | #readline.parse_and_bind('set page-completions no') | |
102 |
|
102 | |||
103 |
|
103 | |||
104 |
|
||||
105 |
|
||||
106 | # some config helper functions you can use |
|
104 | # some config helper functions you can use | |
107 | def import_all(modules): |
|
105 | def import_all(modules): | |
108 | """ Usage: import_all("os sys") """ |
|
106 | """ Usage: import_all("os sys") """ | |
109 | for m in modules.split(): |
|
107 | for m in modules.split(): | |
110 | ip.ex("from %s import *" % m) |
|
108 | ip.ex("from %s import *" % m) | |
111 |
|
109 | |||
112 | def execf(fname): |
|
110 | def execf(fname): | |
113 | """ Execute a file in user namespace """ |
|
111 | """ Execute a file in user namespace """ | |
114 | ip.ex('execfile("%s")' % os.path.expanduser(fname)) |
|
112 | ip.ex('execfile("%s")' % os.path.expanduser(fname)) |
@@ -64,13 +64,18 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||||
64 |
|
64 | |||
65 | debug = False |
|
65 | debug = False | |
66 |
|
66 | |||
67 | def __init__(self, ipython0=None, *args, **kwargs): |
|
67 | def __init__(self, ipython0=None, argv=None, *args, **kwargs): | |
68 | """ Parameters: |
|
68 | """ Parameters: | |
69 | ----------- |
|
69 | ----------- | |
70 |
|
70 | |||
71 | ipython0: an optional ipython0 instance to use for command |
|
71 | ipython0: an optional ipython0 instance to use for command | |
72 | prefiltering and completion. |
|
72 | prefiltering and completion. | |
|
73 | ||||
|
74 | argv : list, optional | |||
|
75 | Used as the instance's argv value. If not given, [] is used. | |||
73 | """ |
|
76 | """ | |
|
77 | if argv is None: | |||
|
78 | argv = [] | |||
74 | # This is a hack to avoid the IPython exception hook to trigger |
|
79 | # This is a hack to avoid the IPython exception hook to trigger | |
75 | # on exceptions (https://bugs.launchpad.net/bugs/337105) |
|
80 | # on exceptions (https://bugs.launchpad.net/bugs/337105) | |
76 | # XXX: This is horrible: module-leve monkey patching -> side |
|
81 | # XXX: This is horrible: module-leve monkey patching -> side | |
@@ -98,7 +103,7 b' class PrefilterFrontEnd(LineFrontEndBase):' | |||||
98 | old_rawinput = __builtin__.raw_input |
|
103 | old_rawinput = __builtin__.raw_input | |
99 | __builtin__.raw_input = my_rawinput |
|
104 | __builtin__.raw_input = my_rawinput | |
100 | # XXX: argv=[] is a bit bold. |
|
105 | # XXX: argv=[] is a bit bold. | |
101 |
ipython0 = make_IPython(argv= |
|
106 | ipython0 = make_IPython(argv=argv, | |
102 | user_ns=self.shell.user_ns, |
|
107 | user_ns=self.shell.user_ns, | |
103 | user_global_ns=self.shell.user_global_ns) |
|
108 | user_global_ns=self.shell.user_global_ns) | |
104 | __builtin__.raw_input = old_rawinput |
|
109 | __builtin__.raw_input = old_rawinput |
@@ -12,14 +12,16 b' __docformat__ = "restructuredtext en"' | |||||
12 | # in the file COPYING, distributed as part of this software. |
|
12 | # in the file COPYING, distributed as part of this software. | |
13 | #------------------------------------------------------------------------------- |
|
13 | #------------------------------------------------------------------------------- | |
14 |
|
14 | |||
|
15 | from copy import copy, deepcopy | |||
15 | from cStringIO import StringIO |
|
16 | from cStringIO import StringIO | |
16 | import string |
|
17 | import string | |
17 |
|
18 | |||
18 | from nose.tools import assert_equal |
|
19 | from nose.tools import assert_equal | |
19 |
|
20 | |||
20 | from IPython.ipapi import get as get_ipython0 |
|
|||
21 | from IPython.frontend.prefilterfrontend import PrefilterFrontEnd |
|
21 | from IPython.frontend.prefilterfrontend import PrefilterFrontEnd | |
22 | from copy import copy, deepcopy |
|
22 | from IPython.ipapi import get as get_ipython0 | |
|
23 | from IPython.testing.plugin.ipdoctest import default_argv | |||
|
24 | ||||
23 |
|
25 | |||
24 | def safe_deepcopy(d): |
|
26 | def safe_deepcopy(d): | |
25 | """ Deep copy every key of the given dict, when possible. Elsewhere |
|
27 | """ Deep copy every key of the given dict, when possible. Elsewhere | |
@@ -45,7 +47,7 b' class TestPrefilterFrontEnd(PrefilterFrontEnd):' | |||||
45 |
|
47 | |||
46 | def __init__(self): |
|
48 | def __init__(self): | |
47 | self.out = StringIO() |
|
49 | self.out = StringIO() | |
48 | PrefilterFrontEnd.__init__(self) |
|
50 | PrefilterFrontEnd.__init__(self,argv=default_argv()) | |
49 | # Some more code for isolation (yeah, crazy) |
|
51 | # Some more code for isolation (yeah, crazy) | |
50 | self._on_enter() |
|
52 | self._on_enter() | |
51 | self.out.flush() |
|
53 | self.out.flush() | |
@@ -64,7 +66,7 b' def isolate_ipython0(func):' | |||||
64 | """ Decorator to isolate execution that involves an iptyhon0. |
|
66 | """ Decorator to isolate execution that involves an iptyhon0. | |
65 |
|
67 | |||
66 | Notes |
|
68 | Notes | |
67 |
----- |
|
69 | ----- | |
68 |
|
70 | |||
69 | Apply only to functions with no arguments. Nose skips functions |
|
71 | Apply only to functions with no arguments. Nose skips functions | |
70 | with arguments. |
|
72 | with arguments. | |
@@ -153,6 +155,12 b' def test_magic():' | |||||
153 | This test is fairly fragile and will break when magics change. |
|
155 | This test is fairly fragile and will break when magics change. | |
154 | """ |
|
156 | """ | |
155 | f = TestPrefilterFrontEnd() |
|
157 | f = TestPrefilterFrontEnd() | |
|
158 | # Before checking the interactive namespace, make sure it's clear (it can | |||
|
159 | # otherwise pick up things stored in the user's local db) | |||
|
160 | f.input_buffer += '%reset -f' | |||
|
161 | f._on_enter() | |||
|
162 | f.complete_current_input() | |||
|
163 | # Now, run the %who magic and check output | |||
156 | f.input_buffer += '%who' |
|
164 | f.input_buffer += '%who' | |
157 | f._on_enter() |
|
165 | f._on_enter() | |
158 | out_value = f.out.getvalue() |
|
166 | out_value = f.out.getvalue() |
@@ -55,9 +55,9 b' from IPython.iplib import InteractiveShell' | |||||
55 | from IPython.usage import cmd_line_usage,interactive_usage |
|
55 | from IPython.usage import cmd_line_usage,interactive_usage | |
56 | from IPython.genutils import * |
|
56 | from IPython.genutils import * | |
57 |
|
57 | |||
58 | def force_import(modname): |
|
58 | def force_import(modname,force_reload=False): | |
59 | if modname in sys.modules: |
|
59 | if modname in sys.modules and force_reload: | |
60 |
|
|
60 | info("reloading: %s" % modname) | |
61 | reload(sys.modules[modname]) |
|
61 | reload(sys.modules[modname]) | |
62 | else: |
|
62 | else: | |
63 | __import__(modname) |
|
63 | __import__(modname) | |
@@ -625,25 +625,25 b" object? -> Details about 'object'. ?object also works, ?? prints more." | |||||
625 | except: |
|
625 | except: | |
626 | IP.InteractiveTB() |
|
626 | IP.InteractiveTB() | |
627 | import_fail_info('ipy_system_conf') |
|
627 | import_fail_info('ipy_system_conf') | |
628 |
|
628 | |||
629 | # only import prof module if ipythonrc-PROF was not found |
|
629 | # only import prof module if ipythonrc-PROF was not found | |
630 | if opts_all.profile and not profile_handled_by_legacy: |
|
630 | if opts_all.profile and not profile_handled_by_legacy: | |
631 | profmodname = 'ipy_profile_' + opts_all.profile |
|
631 | profmodname = 'ipy_profile_' + opts_all.profile | |
632 | try: |
|
632 | try: | |
633 |
|
||||
634 | force_import(profmodname) |
|
633 | force_import(profmodname) | |
635 | except: |
|
634 | except: | |
636 | IP.InteractiveTB() |
|
635 | IP.InteractiveTB() | |
637 |
print "Error importing",profmodname, |
|
636 | print "Error importing",profmodname,\ | |
|
637 | "- perhaps you should run %upgrade?" | |||
638 | import_fail_info(profmodname) |
|
638 | import_fail_info(profmodname) | |
639 | else: |
|
639 | else: | |
640 | opts.profile = opts_all.profile |
|
640 | opts.profile = opts_all.profile | |
641 | else: |
|
641 | else: | |
642 | force_import('ipy_profile_none') |
|
642 | force_import('ipy_profile_none') | |
|
643 | # XXX - this is wrong: ipy_user_conf should not be loaded unconditionally, | |||
|
644 | # since the user could have specified a config file path by hand. | |||
643 | try: |
|
645 | try: | |
644 |
|
||||
645 | force_import('ipy_user_conf') |
|
646 | force_import('ipy_user_conf') | |
646 |
|
||||
647 | except: |
|
647 | except: | |
648 | conf = opts_all.ipythondir + "/ipy_user_conf.py" |
|
648 | conf = opts_all.ipythondir + "/ipy_user_conf.py" | |
649 | IP.InteractiveTB() |
|
649 | IP.InteractiveTB() |
@@ -35,12 +35,15 b' from IPython.testing.plugin.ipdoctest import IPythonDoctest' | |||||
35 | EXCLUDE = ['IPython/external/', |
|
35 | EXCLUDE = ['IPython/external/', | |
36 | 'IPython/platutils_win32', |
|
36 | 'IPython/platutils_win32', | |
37 | 'IPython/frontend/cocoa', |
|
37 | 'IPython/frontend/cocoa', | |
|
38 | 'IPython/frontend/process/winprocess.py', | |||
38 | 'IPython_doctest_plugin', |
|
39 | 'IPython_doctest_plugin', | |
39 | 'IPython/Gnuplot', |
|
40 | 'IPython/Gnuplot', | |
40 | 'IPython/Extensions/ipy_', |
|
41 | 'IPython/Extensions/ipy_', | |
41 | 'IPython/Extensions/clearcmd', |
|
42 | 'IPython/Extensions/clearcmd', | |
42 | 'IPython/Extensions/PhysicalQIn', |
|
43 | 'IPython/Extensions/PhysicalQIn', | |
43 | 'IPython/Extensions/scitedirector', |
|
44 | 'IPython/Extensions/scitedirector', | |
|
45 | 'IPython/Extensions/numeric_formats', | |||
|
46 | 'IPython/testing/attic', | |||
44 | ] |
|
47 | ] | |
45 |
|
48 | |||
46 | #----------------------------------------------------------------------------- |
|
49 | #----------------------------------------------------------------------------- | |
@@ -60,7 +63,7 b' def main():' | |||||
60 | # test suite back into working shape. Our nose |
|
63 | # test suite back into working shape. Our nose | |
61 | # plugin needs to be gone through with a fine |
|
64 | # plugin needs to be gone through with a fine | |
62 | # toothed comb to find what is causing the problem. |
|
65 | # toothed comb to find what is causing the problem. | |
63 |
|
|
66 | '--with-ipdoctest', | |
64 | '--ipdoctest-tests','--ipdoctest-extension=txt', |
|
67 | '--ipdoctest-tests','--ipdoctest-extension=txt', | |
65 | '--detailed-errors', |
|
68 | '--detailed-errors', | |
66 |
|
69 |
@@ -59,6 +59,19 b' log = logging.getLogger(__name__)' | |||||
59 | # machinery into a fit. This code should be considered a gross hack, but it |
|
59 | # machinery into a fit. This code should be considered a gross hack, but it | |
60 | # gets the job done. |
|
60 | # gets the job done. | |
61 |
|
61 | |||
|
62 | def default_argv(): | |||
|
63 | """Return a valid default argv for creating testing instances of ipython""" | |||
|
64 | ||||
|
65 | # Get the install directory for the user configuration and tell ipython to | |||
|
66 | # use the default profile from there. | |||
|
67 | from IPython import UserConfig | |||
|
68 | ipcdir = os.path.dirname(UserConfig.__file__) | |||
|
69 | #ipconf = os.path.join(ipcdir,'ipy_user_conf.py') | |||
|
70 | ipconf = os.path.join(ipcdir,'ipythonrc') | |||
|
71 | #print 'conf:',ipconf # dbg | |||
|
72 | ||||
|
73 | return ['--colors=NoColor','--noterm_title','-rcfile=%s' % ipconf] | |||
|
74 | ||||
62 |
|
75 | |||
63 | # Hack to modify the %run command so we can sync the user's namespace with the |
|
76 | # Hack to modify the %run command so we can sync the user's namespace with the | |
64 | # test globals. Once we move over to a clean magic system, this will be done |
|
77 | # test globals. Once we move over to a clean magic system, this will be done | |
@@ -148,10 +161,11 b' def start_ipython():' | |||||
148 | _excepthook = sys.excepthook |
|
161 | _excepthook = sys.excepthook | |
149 | _main = sys.modules.get('__main__') |
|
162 | _main = sys.modules.get('__main__') | |
150 |
|
163 | |||
|
164 | argv = default_argv() | |||
|
165 | ||||
151 | # Start IPython instance. We customize it to start with minimal frills. |
|
166 | # Start IPython instance. We customize it to start with minimal frills. | |
152 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) |
|
167 | user_ns,global_ns = IPython.ipapi.make_user_namespaces(ipnsdict(),dict()) | |
153 | IPython.Shell.IPShell(['--colors=NoColor','--noterm_title'], |
|
168 | IPython.Shell.IPShell(argv,user_ns,global_ns) | |
154 | user_ns,global_ns) |
|
|||
155 |
|
169 | |||
156 | # Deactivate the various python system hooks added by ipython for |
|
170 | # Deactivate the various python system hooks added by ipython for | |
157 | # interactive convenience so we don't confuse the doctest system |
|
171 | # interactive convenience so we don't confuse the doctest system |
@@ -295,3 +295,12 b' def test_popkey_3():' | |||||
295 | nt.assert_equal(dct, dict(c=3)) |
|
295 | nt.assert_equal(dct, dict(c=3)) | |
296 | nt.assert_equal(genutils.popkey(dct, "c"), 3) |
|
296 | nt.assert_equal(genutils.popkey(dct, "c"), 3) | |
297 | nt.assert_equal(dct, dict()) |
|
297 | nt.assert_equal(dct, dict()) | |
|
298 | ||||
|
299 | ||||
|
300 | def test_filefind(): | |||
|
301 | """Various tests for filefind""" | |||
|
302 | f = tempfile.NamedTemporaryFile() | |||
|
303 | print 'fname:',f.name | |||
|
304 | alt_dirs = genutils.get_ipython_dir() | |||
|
305 | t = genutils.filefind(f.name,alt_dirs) | |||
|
306 | print 'found:',t |
General Comments 0
You need to be logged in to leave comments.
Login now