summaryrefslogtreecommitdiff
path: root/tests/test_cmdline.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_cmdline.py')
-rw-r--r--tests/test_cmdline.py702
1 files changed, 702 insertions, 0 deletions
diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py
new file mode 100644
index 00000000..33f90212
--- /dev/null
+++ b/tests/test_cmdline.py
@@ -0,0 +1,702 @@
+"""Test cmdline.py for coverage."""
+
+import pprint, re, shlex, sys, textwrap
+import mock
+import coverage
+import coverage.cmdline
+from coverage.misc import ExceptionDuringRun
+
+from test.coveragetest import CoverageTest, OK, ERR
+
+
+class CmdLineTest(CoverageTest):
+ """Tests of execution paths through the command line interpreter."""
+
+ run_in_temp_dir = False
+
+ INIT_LOAD = """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .load()\n"""
+
+ def model_object(self):
+ """Return a Mock suitable for use in CoverageScript."""
+ mk = mock.Mock()
+ mk.coverage.return_value = mk
+ return mk
+
+ def mock_command_line(self, args):
+ """Run `args` through the command line, with a Mock.
+
+ Returns the Mock it used and the status code returned.
+
+ """
+ m = self.model_object()
+ ret = coverage.CoverageScript(
+ _covpkg=m, _run_python_file=m.run_python_file,
+ _run_python_module=m.run_python_module, _help_fn=m.help_fn
+ ).command_line(shlex.split(args))
+ return m, ret
+
+ def cmd_executes(self, args, code, ret=OK):
+ """Assert that the `args` end up executing the sequence in `code`."""
+ m1, r1 = self.mock_command_line(args)
+ self.assertEqual(r1, ret,
+ "Wrong status: got %s, wanted %s" % (r1, ret)
+ )
+
+ # Remove all indentation, and change ".foo()" to "m2.foo()".
+ code = re.sub(r"(?m)^\s+", "", code)
+ code = re.sub(r"(?m)^\.", "m2.", code)
+ m2 = self.model_object()
+ code_obj = compile(code, "<code>", "exec")
+ eval(code_obj, globals(), { 'm2': m2 })
+ self.assert_same_method_calls(m1, m2)
+
+ def cmd_executes_same(self, args1, args2):
+ """Assert that the `args1` executes the same as `args2`."""
+ m1, r1 = self.mock_command_line(args1)
+ m2, r2 = self.mock_command_line(args2)
+ self.assertEqual(r1, r2)
+ self.assert_same_method_calls(m1, m2)
+
+ def assert_same_method_calls(self, m1, m2):
+ """Assert that `m1.method_calls` and `m2.method_calls` are the same."""
+ # Use a real equality comparison, but if it fails, use a nicer assert
+ # so we can tell what's going on. We have to use the real == first due
+ # to CmdOptionParser.__eq__
+ if m1.method_calls != m2.method_calls:
+ pp1 = pprint.pformat(m1.method_calls)
+ pp2 = pprint.pformat(m2.method_calls)
+ self.assertMultiLineEqual(pp1+'\n', pp2+'\n')
+
+ def cmd_help(self, args, help_msg=None, topic=None, ret=ERR):
+ """Run a command line, and check that it prints the right help.
+
+ Only the last function call in the mock is checked, which should be the
+ help message that we want to see.
+
+ """
+ m, r = self.mock_command_line(args)
+ self.assertEqual(r, ret,
+ "Wrong status: got %s, wanted %s" % (r, ret)
+ )
+ if help_msg:
+ self.assertEqual(m.method_calls[-1],
+ ('help_fn', (help_msg,), {})
+ )
+ else:
+ self.assertEqual(m.method_calls[-1],
+ ('help_fn', (), {'topic':topic})
+ )
+
+
+class CmdLineTestTest(CmdLineTest):
+ """Tests that our CmdLineTest helpers work."""
+ def test_assert_same_method_calls(self):
+ # All the other tests here use self.cmd_executes_same in successful
+ # ways, so here we just check that it fails.
+ self.assertRaises(AssertionError, self.cmd_executes_same, "-e", "-c")
+
+
+class ClassicCmdLineTest(CmdLineTest):
+ """Tests of the classic coverage.py command line."""
+
+ def test_erase(self):
+ # coverage -e
+ self.cmd_executes("-e", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .erase()
+ """)
+ self.cmd_executes_same("-e", "--erase")
+
+ def test_execute(self):
+ # coverage -x [-p] [-L] [--timid] MODULE.py [ARG1 ARG2 ...]
+
+ # -x calls coverage.load first.
+ self.cmd_executes("-x foo.py", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .load()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ # -e -x calls coverage.erase first.
+ self.cmd_executes("-e -x foo.py", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ # --timid sets a flag, and program arguments get passed through.
+ self.cmd_executes("-x --timid foo.py abc 123", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=True, branch=None, config_file=True, source=None, include=None, omit=None)
+ .load()
+ .start()
+ .run_python_file('foo.py', ['foo.py', 'abc', '123'])
+ .stop()
+ .save()
+ """)
+ # -L sets a flag, and flags for the program don't confuse us.
+ self.cmd_executes("-x -p -L foo.py -a -b", """\
+ .coverage(cover_pylib=True, data_suffix=True, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .load()
+ .start()
+ .run_python_file('foo.py', ['foo.py', '-a', '-b'])
+ .stop()
+ .save()
+ """)
+
+ # Check that long forms of flags do the same thing as short forms.
+ self.cmd_executes_same("-x f.py", "--execute f.py")
+ self.cmd_executes_same("-e -x f.py", "--erase --execute f.py")
+ self.cmd_executes_same("-x -p f.py", "-x --parallel-mode f.py")
+ self.cmd_executes_same("-x -L f.py", "-x --pylib f.py")
+
+ def test_combine(self):
+ # coverage -c
+ self.cmd_executes("-c", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .load()
+ .combine()
+ .save()
+ """)
+ self.cmd_executes_same("-c", "--combine")
+
+ def test_report(self):
+ # coverage -r [-m] [-i] [-o DIR,...] [FILE1 FILE2 ...]
+ self.cmd_executes("-r", self.INIT_LOAD + """\
+ .report(ignore_errors=None, omit=None, include=None, morfs=[],
+ show_missing=None)
+ """)
+ self.cmd_executes("-r -i", self.INIT_LOAD + """\
+ .report(ignore_errors=True, omit=None, include=None, morfs=[],
+ show_missing=None)
+ """)
+ self.cmd_executes("-r -m", self.INIT_LOAD + """\
+ .report(ignore_errors=None, omit=None, include=None, morfs=[],
+ show_missing=True)
+ """)
+ self.cmd_executes("-r -o fooey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey"])
+ .load()
+ .report(ignore_errors=None, omit=["fooey"], include=None,
+ morfs=[], show_missing=None)
+ """)
+ self.cmd_executes("-r -o fooey,booey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey", "booey"])
+ .load()
+ .report(ignore_errors=None, omit=["fooey", "booey"], include=None,
+ morfs=[], show_missing=None)
+ """)
+ self.cmd_executes("-r mod1", self.INIT_LOAD + """\
+ .report(ignore_errors=None, omit=None, include=None,
+ morfs=["mod1"], show_missing=None)
+ """)
+ self.cmd_executes("-r mod1 mod2 mod3", self.INIT_LOAD + """\
+ .report(ignore_errors=None, omit=None, include=None,
+ morfs=["mod1", "mod2", "mod3"], show_missing=None)
+ """)
+
+ self.cmd_executes_same("-r", "--report")
+ self.cmd_executes_same("-r -i", "-r --ignore-errors")
+ self.cmd_executes_same("-r -m", "-r --show-missing")
+ self.cmd_executes_same("-r -o f", "-r --omit=f")
+ self.cmd_executes_same("-r -o f", "-r --omit f")
+ self.cmd_executes_same("-r -o f,b", "-r --omit=f,b")
+ self.cmd_executes_same("-r -o f,b", "-r --omit f,b")
+ self.cmd_executes_same("-r -of", "-r --omit=f")
+ self.cmd_executes_same("-r -of,b", "-r --omit=f,b")
+
+ def test_annotate(self):
+ # coverage -a [-d DIR] [-i] [-o DIR,...] [FILE1 FILE2 ...]
+ self.cmd_executes("-a", self.INIT_LOAD + """\
+ .annotate(directory=None, ignore_errors=None,
+ omit=None, include=None, morfs=[])
+ """)
+ self.cmd_executes("-a -d dir1", self.INIT_LOAD + """\
+ .annotate(directory="dir1", ignore_errors=None,
+ omit=None, include=None, morfs=[])
+ """)
+ self.cmd_executes("-a -i", self.INIT_LOAD + """\
+ .annotate(directory=None, ignore_errors=True,
+ omit=None, include=None, morfs=[])
+ """)
+ self.cmd_executes("-a -o fooey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey"])
+ .load()
+ .annotate(directory=None, ignore_errors=None,
+ omit=["fooey"], include=None, morfs=[])
+ """)
+ self.cmd_executes("-a -o fooey,booey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey", "booey"])
+ .load()
+ .annotate(directory=None, ignore_errors=None,
+ omit=["fooey", "booey"], include=None, morfs=[])
+ """)
+ self.cmd_executes("-a mod1", self.INIT_LOAD + """\
+ .annotate(directory=None, ignore_errors=None,
+ omit=None, include=None, morfs=["mod1"])
+ """)
+ self.cmd_executes("-a mod1 mod2 mod3", self.INIT_LOAD + """\
+ .annotate(directory=None, ignore_errors=None,
+ omit=None, include=None, morfs=["mod1", "mod2", "mod3"])
+ """)
+
+ self.cmd_executes_same("-a", "--annotate")
+ self.cmd_executes_same("-a -d d1", "-a --directory=d1")
+ self.cmd_executes_same("-a -i", "-a --ignore-errors")
+ self.cmd_executes_same("-a -o f", "-a --omit=f")
+ self.cmd_executes_same("-a -o f", "-a --omit f")
+ self.cmd_executes_same("-a -o f,b", "-a --omit=f,b")
+ self.cmd_executes_same("-a -o f,b", "-a --omit f,b")
+ self.cmd_executes_same("-a -of", "-a --omit=f")
+ self.cmd_executes_same("-a -of,b", "-a --omit=f,b")
+
+ def test_html_report(self):
+ # coverage -b -d DIR [-i] [-o DIR,...] [FILE1 FILE2 ...]
+ self.cmd_executes("-b", self.INIT_LOAD + """\
+ .html_report(directory=None, ignore_errors=None, title=None,
+ omit=None, include=None, morfs=[])
+ """)
+ self.cmd_executes("-b -d dir1", self.INIT_LOAD + """\
+ .html_report(directory="dir1", ignore_errors=None, title=None,
+ omit=None, include=None, morfs=[])
+ """)
+ self.cmd_executes("-b -i", self.INIT_LOAD + """\
+ .html_report(directory=None, ignore_errors=True, title=None,
+ omit=None, include=None, morfs=[])
+ """)
+ self.cmd_executes("-b -o fooey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey"])
+ .load()
+ .html_report(directory=None, ignore_errors=None, title=None,
+ omit=["fooey"], include=None, morfs=[])
+ """)
+ self.cmd_executes("-b -o fooey,booey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey", "booey"])
+ .load()
+ .html_report(directory=None, ignore_errors=None, title=None,
+ omit=["fooey", "booey"], include=None, morfs=[])
+ """)
+ self.cmd_executes("-b mod1", self.INIT_LOAD + """\
+ .html_report(directory=None, ignore_errors=None, title=None,
+ omit=None, include=None, morfs=["mod1"])
+ """)
+ self.cmd_executes("-b mod1 mod2 mod3", self.INIT_LOAD + """\
+ .html_report(directory=None, ignore_errors=None, title=None,
+ omit=None, include=None, morfs=["mod1", "mod2", "mod3"])
+ """)
+
+ self.cmd_executes_same("-b", "--html")
+ self.cmd_executes_same("-b -d d1", "-b --directory=d1")
+ self.cmd_executes_same("-b -i", "-b --ignore-errors")
+ self.cmd_executes_same("-b -o f", "-b --omit=f")
+ self.cmd_executes_same("-b -o f,b", "-b --omit=f,b")
+ self.cmd_executes_same("-b -of", "-b --omit=f")
+ self.cmd_executes_same("-b -of,b", "-b --omit=f,b")
+
+ def test_help(self):
+ # coverage -h
+ self.cmd_help("-h", topic="help", ret=OK)
+ self.cmd_help("--help", topic="help", ret=OK)
+
+ def test_version(self):
+ # coverage --version
+ self.cmd_help("--version", topic="version", ret=OK)
+
+ ## Error cases
+
+ def test_argless_actions(self):
+ self.cmd_help("-e foo bar", "Unexpected arguments: foo bar")
+ self.cmd_help("-c baz quux", "Unexpected arguments: baz quux")
+
+ def test_need_action(self):
+ self.cmd_help("-p", "You must specify at least one of "
+ "-e, -x, -c, -r, -a, or -b.")
+
+ def test_bad_action_combinations(self):
+ self.cmd_help('-e -a',
+ "You can't specify the 'erase' and 'annotate' "
+ "options at the same time."
+ )
+ self.cmd_help('-e -r',
+ "You can't specify the 'erase' and 'report' "
+ "options at the same time."
+ )
+ self.cmd_help('-e -b',
+ "You can't specify the 'erase' and 'html' "
+ "options at the same time."
+ )
+ self.cmd_help('-e -c',
+ "You can't specify the 'erase' and 'combine' "
+ "options at the same time."
+ )
+ self.cmd_help('-x -a',
+ "You can't specify the 'execute' and 'annotate' "
+ "options at the same time."
+ )
+ self.cmd_help('-x -r',
+ "You can't specify the 'execute' and 'report' "
+ "options at the same time."
+ )
+ self.cmd_help('-x -b',
+ "You can't specify the 'execute' and 'html' "
+ "options at the same time."
+ )
+ self.cmd_help('-x -c',
+ "You can't specify the 'execute' and 'combine' "
+ "options at the same time."
+ )
+
+ def test_nothing_to_do(self):
+ self.cmd_help("-x", "Nothing to do.")
+
+ def test_unknown_option(self):
+ self.cmd_help("-z", "no such option: -z")
+
+
+class FakeCoverageForDebugData(object):
+ """Just enough of a fake coverage package for the 'debug data' tests."""
+ def __init__(self, summary):
+ self._summary = summary
+ self.filename = "FILENAME"
+ self.data = self
+
+ # package members
+ def coverage(self, *unused_args, **unused_kwargs):
+ """The coverage class in the package."""
+ return self
+
+ # coverage methods
+ def load(self):
+ """Fake coverage().load()"""
+ pass
+
+ # data methods
+ def has_arcs(self):
+ """Fake coverage().data.has_arcs()"""
+ return False
+
+ def summary(self, fullpath): # pylint: disable=W0613
+ """Fake coverage().data.summary()"""
+ return self._summary
+
+
+class NewCmdLineTest(CmdLineTest):
+ """Tests of the coverage.py command line."""
+
+ def test_annotate(self):
+ self.cmd_executes_same("annotate", "-a")
+ self.cmd_executes_same("annotate -i", "-a -i")
+ self.cmd_executes_same("annotate -d d1", "-a -d d1")
+ self.cmd_executes_same("annotate --omit f", "-a --omit f")
+ self.cmd_executes_same("annotate --omit f,b", "-a --omit f,b")
+ self.cmd_executes_same("annotate m1", "-a m1")
+ self.cmd_executes_same("annotate m1 m2 m3", "-a m1 m2 m3")
+
+ def test_combine(self):
+ self.cmd_executes_same("combine", "-c")
+
+ def test_debug(self):
+ self.cmd_help("debug", "What information would you like: data, sys?")
+ self.cmd_help("debug foo", "Don't know what you mean by 'foo'")
+
+ def test_debug_data(self):
+ fake = FakeCoverageForDebugData({
+ 'file1.py': 17, 'file2.py': 23,
+ })
+ self.command_line("debug data", _covpkg=fake)
+ self.assertMultiLineEqual(self.stdout(), textwrap.dedent("""\
+ -- data ---------------------------------------
+ path: FILENAME
+ has_arcs: False
+
+ 2 files:
+ file1.py: 17 lines
+ file2.py: 23 lines
+ """))
+
+ def test_debug_data_with_no_data(self):
+ fake = FakeCoverageForDebugData({})
+ self.command_line("debug data", _covpkg=fake)
+ self.assertMultiLineEqual(self.stdout(), textwrap.dedent("""\
+ -- data ---------------------------------------
+ path: FILENAME
+ has_arcs: False
+ No data collected
+ """))
+
+ def test_debug_sys(self):
+ self.command_line("debug sys")
+ out = self.stdout()
+ assert "version:" in out
+ assert "data_path:" in out
+
+ def test_erase(self):
+ self.cmd_executes_same("erase", "-e")
+
+ def test_help(self):
+ self.cmd_executes("help", ".help_fn(topic='help')")
+
+ def test_cmd_help(self):
+ self.cmd_executes("run --help",
+ ".help_fn(parser='<CmdOptionParser:run>')")
+ self.cmd_executes_same("help run", "run --help")
+
+ def test_html(self):
+ self.cmd_executes_same("html", "-b")
+ self.cmd_executes_same("html -i", "-b -i")
+ self.cmd_executes_same("html -d d1", "-b -d d1")
+ self.cmd_executes_same("html --omit f", "-b --omit f")
+ self.cmd_executes_same("html --omit f,b", "-b --omit f,b")
+ self.cmd_executes_same("html m1", "-b m1")
+ self.cmd_executes_same("html m1 m2 m3", "-b m1 m2 m3")
+ self.cmd_executes("html", self.INIT_LOAD + """\
+ .html_report(ignore_errors=None, omit=None, include=None, morfs=[],
+ directory=None, title=None)
+ """)
+ self.cmd_executes("html --title=Hello_there", self.INIT_LOAD + """\
+ .html_report(ignore_errors=None, omit=None, include=None, morfs=[],
+ directory=None, title='Hello_there')
+ """)
+
+ def test_report(self):
+ self.cmd_executes_same("report", "-r")
+ self.cmd_executes_same("report -i", "-r -i")
+ self.cmd_executes_same("report -m", "-r -m")
+ self.cmd_executes_same("report --omit f", "-r --omit f")
+ self.cmd_executes_same("report --omit f,b", "-r --omit f,b")
+ self.cmd_executes_same("report m1", "-r m1")
+ self.cmd_executes_same("report m1 m2 m3", "-r m1 m2 m3")
+
+ def test_run(self):
+ self.cmd_executes_same("run f.py", "-e -x f.py")
+ self.cmd_executes_same("run f.py -a arg -z", "-e -x f.py -a arg -z")
+ self.cmd_executes_same("run -a f.py", "-x f.py")
+ self.cmd_executes_same("run -p f.py", "-e -x -p f.py")
+ self.cmd_executes_same("run -L f.py", "-e -x -L f.py")
+ self.cmd_executes_same("run --timid f.py", "-e -x --timid f.py")
+ self.cmd_executes_same("run", "-x")
+ self.cmd_executes("run --branch foo.py", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=True, config_file=True, source=None, include=None, omit=None)
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run --rcfile=myrc.rc foo.py", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file="myrc.rc", source=None, include=None, omit=None)
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run --include=pre1,pre2 foo.py", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=["pre1", "pre2"], omit=None)
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run --omit=opre1,opre2 foo.py", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["opre1", "opre2"])
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run --include=pre1,pre2 --omit=opre1,opre2 foo.py",
+ """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None,
+ branch=None, config_file=True, source=None,
+ include=["pre1", "pre2"],
+ omit=["opre1", "opre2"])
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run --source=quux,hi.there,/home/bar foo.py",
+ """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None,
+ branch=None, config_file=True,
+ source=["quux", "hi.there", "/home/bar"], include=None,
+ omit=None)
+ .erase()
+ .start()
+ .run_python_file('foo.py', ['foo.py'])
+ .stop()
+ .save()
+ """)
+
+ def test_run_module(self):
+ self.cmd_executes("run -m mymodule", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .erase()
+ .start()
+ .run_python_module('mymodule', ['mymodule'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run -m mymodule -qq arg1 arg2", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=None)
+ .erase()
+ .start()
+ .run_python_module('mymodule', ['mymodule', '-qq', 'arg1', 'arg2'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes("run --branch -m mymodule", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=True, config_file=True, source=None, include=None, omit=None)
+ .erase()
+ .start()
+ .run_python_module('mymodule', ['mymodule'])
+ .stop()
+ .save()
+ """)
+ self.cmd_executes_same("run -m mymodule", "run --module mymodule")
+
+ def test_xml(self):
+ # coverage xml [-i] [--omit DIR,...] [FILE1 FILE2 ...]
+ self.cmd_executes("xml", self.INIT_LOAD + """\
+ .xml_report(ignore_errors=None, omit=None, include=None, morfs=[],
+ outfile=None)
+ """)
+ self.cmd_executes("xml -i", self.INIT_LOAD + """\
+ .xml_report(ignore_errors=True, omit=None, include=None, morfs=[],
+ outfile=None)
+ """)
+ self.cmd_executes("xml -o myxml.foo", self.INIT_LOAD + """\
+ .xml_report(ignore_errors=None, omit=None, include=None, morfs=[],
+ outfile="myxml.foo")
+ """)
+ self.cmd_executes("xml -o -", self.INIT_LOAD + """\
+ .xml_report(ignore_errors=None, omit=None, include=None, morfs=[],
+ outfile="-")
+ """)
+ self.cmd_executes("xml --omit fooey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey"])
+ .load()
+ .xml_report(ignore_errors=None, omit=["fooey"], include=None, morfs=[],
+ outfile=None)
+ """)
+ self.cmd_executes("xml --omit fooey,booey", """\
+ .coverage(cover_pylib=None, data_suffix=None, timid=None, branch=None, config_file=True, source=None, include=None, omit=["fooey", "booey"])
+ .load()
+ .xml_report(ignore_errors=None, omit=["fooey", "booey"], include=None,
+ morfs=[], outfile=None)
+ """)
+ self.cmd_executes("xml mod1", self.INIT_LOAD + """\
+ .xml_report(ignore_errors=None, omit=None, include=None, morfs=["mod1"],
+ outfile=None)
+ """)
+ self.cmd_executes("xml mod1 mod2 mod3", self.INIT_LOAD + """\
+ .xml_report(ignore_errors=None, omit=None, include=None,
+ morfs=["mod1", "mod2", "mod3"], outfile=None)
+ """)
+
+ def test_no_arguments_at_all(self):
+ self.cmd_help("", topic="minimum_help", ret=OK)
+
+ def test_bad_command(self):
+ self.cmd_help("xyzzy", "Unknown command: 'xyzzy'")
+
+
+class CmdLineStdoutTest(CmdLineTest):
+ """Test the command line with real stdout output."""
+
+ def test_minimum_help(self):
+ self.command_line("")
+ out = self.stdout()
+ assert "Code coverage for Python." in out
+ assert out.count("\n") < 4
+
+ def test_version(self):
+ self.command_line("--version")
+ out = self.stdout()
+ assert "ersion " in out
+ assert out.count("\n") < 4
+
+ def test_help(self):
+ self.command_line("help")
+ out = self.stdout()
+ assert "nedbatchelder.com" in out
+ assert out.count("\n") > 10
+
+ def test_cmd_help(self):
+ self.command_line("help run")
+ out = self.stdout()
+ assert "<pyfile>" in out
+ assert "--timid" in out
+ assert out.count("\n") > 10
+
+ def test_error(self):
+ self.command_line("fooey kablooey", ret=ERR)
+ out = self.stdout()
+ assert "fooey" in out
+ assert "help" in out
+
+
+class CmdMainTest(CoverageTest):
+ """Tests of coverage.cmdline.main(), using mocking for isolation."""
+
+ class CoverageScriptStub(object):
+ """A stub for coverage.cmdline.CoverageScript, used by CmdMainTest."""
+
+ def command_line(self, argv):
+ """Stub for command_line, the arg determines what it will do."""
+ if argv[0] == 'hello':
+ print("Hello, world!")
+ elif argv[0] == 'raise':
+ try:
+ raise Exception("oh noes!")
+ except:
+ raise ExceptionDuringRun(*sys.exc_info())
+ elif argv[0] == 'internalraise':
+ raise ValueError("coverage is broken")
+ elif argv[0] == 'exit':
+ sys.exit(23)
+ else:
+ raise AssertionError("Bad CoverageScriptStub: %r"% (argv,))
+ return 0
+
+ def setUp(self):
+ super(CmdMainTest, self).setUp()
+ self.old_CoverageScript = coverage.cmdline.CoverageScript
+ coverage.cmdline.CoverageScript = self.CoverageScriptStub
+
+ def tearDown(self):
+ coverage.cmdline.CoverageScript = self.old_CoverageScript
+ super(CmdMainTest, self).tearDown()
+
+ def test_normal(self):
+ ret = coverage.cmdline.main(['hello'])
+ self.assertEqual(ret, 0)
+ self.assertEqual(self.stdout(), "Hello, world!\n")
+
+ def test_raise(self):
+ ret = coverage.cmdline.main(['raise'])
+ self.assertEqual(ret, 1)
+ self.assertEqual(self.stdout(), "")
+ err = self.stderr().split('\n')
+ self.assertEqual(err[0], 'Traceback (most recent call last):')
+ self.assertEqual(err[-3], ' raise Exception("oh noes!")')
+ self.assertEqual(err[-2], 'Exception: oh noes!')
+
+ def test_internalraise(self):
+ self.assertRaisesRegexp(ValueError,
+ "coverage is broken",
+ coverage.cmdline.main, ['internalraise']
+ )
+
+ def test_exit(self):
+ ret = coverage.cmdline.main(['exit'])
+ self.assertEqual(ret, 23)