|
14 | 14 | import pytest
|
15 | 15 |
|
16 | 16 | from coverage import env
|
17 |
| -from coverage.exceptions import NoCode, NoSource |
| 17 | +from coverage.exceptions import NoCode, NoSource, ExceptionDuringRun |
18 | 18 | from coverage.execfile import run_python_file, run_python_module
|
19 | 19 | from coverage.files import python_reported_file
|
20 | 20 |
|
@@ -102,6 +102,91 @@ def test_directory_without_main(self):
|
102 | 102 | with pytest.raises(NoSource, match="Can't find '__main__' module in 'without_main'"):
|
103 | 103 | run_python_file(["without_main"])
|
104 | 104 |
|
| 105 | + def test_code_throws(self): |
| 106 | + self.make_file("throw.py", """\ |
| 107 | + class MyException(Exception): |
| 108 | + pass |
| 109 | +
|
| 110 | + def f1(): |
| 111 | + print("about to raise..") |
| 112 | + raise MyException("hey!") |
| 113 | +
|
| 114 | + def f2(): |
| 115 | + f1() |
| 116 | +
|
| 117 | + f2() |
| 118 | + """) |
| 119 | + |
| 120 | + with pytest.raises(SystemExit) as exc_info: |
| 121 | + run_python_file(["throw.py"]) |
| 122 | + assert exc_info.value.args == (1,) |
| 123 | + assert self.stdout() == "about to raise..\n" |
| 124 | + assert self.stderr() == "" |
| 125 | + |
| 126 | + def test_code_exits(self): |
| 127 | + self.make_file("exit.py", """\ |
| 128 | + import sys |
| 129 | + def f1(): |
| 130 | + print("about to exit..") |
| 131 | + sys.exit(17) |
| 132 | +
|
| 133 | + def f2(): |
| 134 | + f1() |
| 135 | +
|
| 136 | + f2() |
| 137 | + """) |
| 138 | + |
| 139 | + with pytest.raises(SystemExit) as exc_info: |
| 140 | + run_python_file(["exit.py"]) |
| 141 | + assert exc_info.value.args == (17,) |
| 142 | + assert self.stdout() == "about to exit..\n" |
| 143 | + assert self.stderr() == "" |
| 144 | + |
| 145 | + @pytest.mark.skipif(not env.CPYTHON, |
| 146 | + reason="non-CPython handles excepthook exits differently, punt for now." |
| 147 | + ) |
| 148 | + def test_excepthook_exit(self): |
| 149 | + self.make_file("excepthook_exit.py", """\ |
| 150 | + import sys |
| 151 | +
|
| 152 | + def excepthook(*args): |
| 153 | + print('in excepthook') |
| 154 | + sys.exit(0) |
| 155 | +
|
| 156 | + sys.excepthook = excepthook |
| 157 | +
|
| 158 | + raise RuntimeError('Error Outside') |
| 159 | + """) |
| 160 | + with pytest.raises(SystemExit): |
| 161 | + run_python_file(["excepthook_exit.py"]) |
| 162 | + cov_out = self.stdout() |
| 163 | + assert cov_out == "in excepthook\n" |
| 164 | + |
| 165 | + @pytest.mark.skipif(env.PYPY, reason="PyPy handles excepthook throws differently.") |
| 166 | + def test_excepthook_throw(self): |
| 167 | + self.make_file("excepthook_throw.py", """\ |
| 168 | + import sys |
| 169 | +
|
| 170 | + def excepthook(*args): |
| 171 | + # Write this message to stderr so that we don't have to deal |
| 172 | + # with interleaved stdout/stderr comparisons in the assertions |
| 173 | + # in the test. |
| 174 | + sys.stderr.write('in excepthook\\n') |
| 175 | + raise RuntimeError('Error Inside') |
| 176 | +
|
| 177 | + sys.excepthook = excepthook |
| 178 | +
|
| 179 | + raise RuntimeError('Error Outside') |
| 180 | + """) |
| 181 | + with pytest.raises(ExceptionDuringRun) as exc_info: |
| 182 | + run_python_file(["excepthook_throw.py"]) |
| 183 | + # The ExceptionDuringRun exception has the RuntimeError as its argument. |
| 184 | + assert exc_info.value.args[1].args[0] == "Error Outside" |
| 185 | + stderr = self.stderr() |
| 186 | + assert "in excepthook\n" in stderr |
| 187 | + assert "Error in sys.excepthook:\n" in stderr |
| 188 | + assert "RuntimeError: Error Inside" in stderr |
| 189 | + |
105 | 190 |
|
106 | 191 | class RunPycFileTest(CoverageTest):
|
107 | 192 | """Test cases for `run_python_file`."""
|
|
0 commit comments