Skip to content

Commit a8ae092

Browse files
authored
Merge pull request #97 from nschloe/expected-output-whitespace
Expected output whitespace
2 parents f58c700 + e3cef24 commit a8ae092

File tree

6 files changed

+51
-13
lines changed

6 files changed

+51
-13
lines changed

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
<p align="center">Test code blocks in your READMEs.</p>
44
</p>
55

6-
[![PyPi Version](https://img.shields.io/pypi/v/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest-codeblocks/)
6+
[![PyPi Version](https://img.shields.io/pypi/v/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest_codeblocks/)
77
[![Anaconda Cloud](https://anaconda.org/conda-forge/pytest-codeblocks/badges/version.svg?=style=flat-square)](https://anaconda.org/conda-forge/pytest-codeblocks/)
8-
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest-codeblocks/)
8+
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest_codeblocks/)
99
[![GitHub stars](https://img.shields.io/github/stars/nschloe/pytest-codeblocks.svg?style=flat-square&logo=github&label=Stars&logoColor=white)](https://github.com/nschloe/pytest-codeblocks)
10-
[![Downloads](https://pepy.tech/badge/pytest-codeblocks/month?style=flat-square)](https://pepy.tech/project/pytest-codeblocks)
10+
[![Downloads](https://static.pepy.tech/badge/pytest-codeblocks/month?style=flat-square)](https://www.pepy.tech/projects/pytest-codeblocks)
1111

1212
<!--[![PyPi downloads](https://img.shields.io/pypi/dm/pytest-codeblocks.svg?style=flat-square)](https://pypistats.org/packages/pytest-codeblocks)-->
1313

14-
[![gh-actions](https://img.shields.io/github/workflow/status/nschloe/pytest-codeblocks/ci?style=flat-square)](https://github.com/nschloe/pytest-codeblocks/actions?query=workflow%3Aci)
14+
[![gh-actions](https://img.shields.io/github/actions/workflow/status/nschloe/pytest-codeblocks/tests?style=flat-square)](https://github.com/nschloe/pytest-codeblocks/actions?query=workflow%3Atests)
1515
[![codecov](https://img.shields.io/codecov/c/github/nschloe/pytest-codeblocks.svg?style=flat-square)](https://app.codecov.io/gh/nschloe/pytest-codeblocks)
1616
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)
1717

@@ -156,5 +156,8 @@ gives
156156
```
157157
````
158158

159+
Use `expected-output-ignore-whitespace` if you'd like whitespace differences to
160+
be ignored.
161+
159162
(Conditionally) Skipping the output verfication works by prepending the first
160163
block with `skip`/`skipif` (see [above](#skipping-code-blocks)).

pyproject.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
requires = ["setuptools>=61"]
33
build-backend = "setuptools.build_meta"
44

5-
[tool.isort]
6-
profile = "black"
7-
85
[project]
96
name = "pytest_codeblocks"
107
authors = [{name = "Nico Schlömer", email = "[email protected]"}]

src/pytest_codeblocks/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.16.1"
1+
__version__ = "0.16.2"

src/pytest_codeblocks/main.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class CodeBlock:
1818
lineno: int
1919
syntax: str | None = None
2020
expected_output: str | None = None
21+
expected_output_ignore_whitespace: bool = False
2122
importorskip: str | None = None
2223
marks: list[str] = field(default_factory=lambda: [])
2324

@@ -34,6 +35,7 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
3435
marks = []
3536
continued_block = None
3637
expected_output_block = None
38+
expected_output_ignore_whitespace = False
3739
importorskip = None
3840
k = 1
3941

@@ -58,18 +60,21 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
5860
if m is not None:
5961
keyword = m.group(1).strip("- ")
6062
# handle special tags
61-
if keyword == "expected-output":
63+
if keyword in {"expected-output", "expected-output-ignore-whitespace"}:
6264
if len(out) == 0:
6365
raise RuntimeError(
64-
"Found <!--pytest-codeblocks-expected-output--> "
66+
f"Found <!--pytest-codeblocks-{keyword}--> "
6567
+ "but no previous code block."
6668
)
6769
if out[-1].expected_output is not None:
6870
raise RuntimeError(
69-
"Found <!--pytest-codeblocks-expected-output--> "
71+
f"Found <!--pytest-codeblocks-{keyword}--> "
7072
+ "but block already has expected_output."
7173
)
7274
expected_output_block = out[-1]
75+
if keyword == "expected-output-ignore-whitespace":
76+
# \s: regex matches all whitespace characters
77+
expected_output_ignore_whitespace = True
7378

7479
elif keyword == "cont":
7580
if len(out) == 0:
@@ -115,7 +120,7 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
115120
marks.append("pytest.mark.xfail")
116121

117122
else:
118-
raise RuntimeError(f'Unknown pytest-codeblocks keyword "{keyword}."')
123+
raise RuntimeError(f'Unknown pytest-codeblocks keyword "{keyword}"')
119124

120125
continue
121126

@@ -162,6 +167,9 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
162167

163168
elif expected_output_block:
164169
expected_output_block.expected_output = code
170+
expected_output_block.expected_output_ignore_whitespace = (
171+
expected_output_ignore_whitespace
172+
)
165173
expected_output_block = None
166174

167175
else:

src/pytest_codeblocks/plugin.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#
55
import subprocess
66
from pathlib import Path
7+
import re
78

89
import pytest
910

@@ -103,7 +104,14 @@ def runtest(self):
103104
output = ret.stdout.decode()
104105

105106
if output is not None and self.obj.expected_output is not None:
106-
if self.obj.expected_output != output:
107+
str0 = self.obj.expected_output
108+
str1 = output
109+
110+
if self.obj.expected_output_ignore_whitespace:
111+
str0 = re.sub(r"^\s+", "", str0, flags=re.MULTILINE)
112+
str1 = re.sub(r"^\s+", "", str1, flags=re.MULTILINE)
113+
114+
if str0 != str1:
107115
raise RuntimeError(
108116
f"{self.name}, line {self.obj.lineno}:\n```\n"
109117
+ f"Expected output\n```\n{self.obj.expected_output}```\n"

tests/test_expected_output.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,25 @@ def test_expected_output_fail(testdir):
3434
testdir.makefile(".md", string)
3535
result = testdir.runpytest("--codeblocks")
3636
result.assert_outcomes(failed=1)
37+
38+
39+
def test_expected_output_ignore_whitespace(testdir):
40+
string = """
41+
Lorem ipsum
42+
```python
43+
print(1 + 3)
44+
print(1 - 3)
45+
print(1 * 3)
46+
```
47+
dolor sit amet
48+
<!--pytest-codeblocks:expected-output-ignore-whitespace-->
49+
```
50+
4
51+
-2
52+
53+
3
54+
```
55+
"""
56+
testdir.makefile(".md", string)
57+
result = testdir.runpytest("--codeblocks")
58+
result.assert_outcomes(passed=1)

0 commit comments

Comments
 (0)