diff options
author | Ned Batchelder <ned@nedbatchelder.com> | 2016-09-24 18:39:17 -0400 |
---|---|---|
committer | Ned Batchelder <ned@nedbatchelder.com> | 2016-09-24 18:39:17 -0400 |
commit | 798c38e9f6d6598dc59ea6f5d71fce96cdeb7ae7 (patch) | |
tree | b360c9f30acb6469dcc0882fb52e06920604925e | |
parent | 894b7a67537eac5e8fb5171d80503a3e6b537f69 (diff) | |
download | python-coveragepy-git-798c38e9f6d6598dc59ea6f5d71fce96cdeb7ae7.tar.gz |
Test short_stack, and give it a skip parameter for better output.
-rw-r--r-- | coverage/debug.py | 7 | ||||
-rw-r--r-- | tests/test_debug.py | 37 |
2 files changed, 41 insertions, 3 deletions
diff --git a/coverage/debug.py b/coverage/debug.py index 4cf0f3e5..3d67c611 100644 --- a/coverage/debug.py +++ b/coverage/debug.py @@ -87,7 +87,7 @@ def info_formatter(info): yield "%*s: %s" % (label_len, label, data) -def short_stack(limit=None): # pragma: debugging +def short_stack(limit=None, skip=0): """Return a string summarizing the call stack. The string is multi-line, with one line per stack frame. Each line shows @@ -101,8 +101,11 @@ def short_stack(limit=None): # pragma: debugging `limit` is the number of frames to include, defaulting to all of them. + `skip` is the number of frames to skip, so that debugging functions can + call this and not be included in the result. + """ - stack = inspect.stack()[limit:0:-1] + stack = inspect.stack()[limit:skip:-1] return "\n".join("%30s : %s @%d" % (t[3], t[1], t[2]) for t in stack) diff --git a/tests/test_debug.py b/tests/test_debug.py index 4d9e9271..8309395b 100644 --- a/tests/test_debug.py +++ b/tests/test_debug.py @@ -8,7 +8,8 @@ import re import coverage from coverage.backward import StringIO -from coverage.debug import info_formatter, info_header +from coverage.debug import info_formatter, info_header, short_stack + from tests.coveragetest import CoverageTest @@ -132,6 +133,40 @@ class DebugTraceTest(CoverageTest): ) +def f_one(*args, **kwargs): + """First of the chain of functions for testing `short_stack`.""" + return f_two(*args, **kwargs) + +def f_two(*args, **kwargs): + """Second of the chain of functions for testing `short_stack`.""" + return f_three(*args, **kwargs) + +def f_three(*args, **kwargs): + """Third of the chain of functions for testing `short_stack`.""" + return short_stack(*args, **kwargs) + + +class ShortStackTest(CoverageTest): + """Tests of coverage.debug.short_stack.""" + + run_in_temp_dir = False + + def test_short_stack(self): + stack = f_one().splitlines() + self.assertGreater(len(stack), 10) + self.assertIn("f_three", stack[-1]) + self.assertIn("f_two", stack[-2]) + self.assertIn("f_one", stack[-3]) + + def test_short_stack_limit(self): + stack = f_one(limit=5).splitlines() + self.assertEqual(len(stack), 5) + + def test_short_stack_skip(self): + stack = f_one(skip=1).splitlines() + self.assertIn("f_two", stack[-1]) + + def lines_matching(lines, pat): """Gives the list of lines from `lines` that match `pat`.""" return [l for l in lines if re.search(pat, l)] |