Skip to content

Commit

Permalink
Merge pull request #97 from nschloe/expected-output-whitespace
Browse files Browse the repository at this point in the history
Expected output whitespace
  • Loading branch information
nschloe authored Sep 17, 2023
2 parents f58c700 + e3cef24 commit a8ae092
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 13 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
<p align="center">Test code blocks in your READMEs.</p>
</p>

[![PyPi Version](https://img.shields.io/pypi/v/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest-codeblocks/)
[![PyPi Version](https://img.shields.io/pypi/v/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest_codeblocks/)
[![Anaconda Cloud](https://anaconda.org/conda-forge/pytest-codeblocks/badges/version.svg?=style=flat-square)](https://anaconda.org/conda-forge/pytest-codeblocks/)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest-codeblocks/)
[![PyPI pyversions](https://img.shields.io/pypi/pyversions/pytest-codeblocks.svg?style=flat-square)](https://pypi.org/project/pytest_codeblocks/)
[![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)
[![Downloads](https://pepy.tech/badge/pytest-codeblocks/month?style=flat-square)](https://pepy.tech/project/pytest-codeblocks)
[![Downloads](https://static.pepy.tech/badge/pytest-codeblocks/month?style=flat-square)](https://www.pepy.tech/projects/pytest-codeblocks)

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

[![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)
[![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)
[![codecov](https://img.shields.io/codecov/c/github/nschloe/pytest-codeblocks.svg?style=flat-square)](https://app.codecov.io/gh/nschloe/pytest-codeblocks)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)

Expand Down Expand Up @@ -156,5 +156,8 @@ gives
```
````

Use `expected-output-ignore-whitespace` if you'd like whitespace differences to
be ignored.

(Conditionally) Skipping the output verfication works by prepending the first
block with `skip`/`skipif` (see [above](#skipping-code-blocks)).
3 changes: 0 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"

[tool.isort]
profile = "black"

[project]
name = "pytest_codeblocks"
authors = [{name = "Nico Schlömer", email = "nico.schloemer@gmail.com"}]
Expand Down
2 changes: 1 addition & 1 deletion src/pytest_codeblocks/__about__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.16.1"
__version__ = "0.16.2"
16 changes: 12 additions & 4 deletions src/pytest_codeblocks/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class CodeBlock:
lineno: int
syntax: str | None = None
expected_output: str | None = None
expected_output_ignore_whitespace: bool = False
importorskip: str | None = None
marks: list[str] = field(default_factory=lambda: [])

Expand All @@ -34,6 +35,7 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
marks = []
continued_block = None
expected_output_block = None
expected_output_ignore_whitespace = False
importorskip = None
k = 1

Expand All @@ -58,18 +60,21 @@ def extract_from_buffer(f, max_num_lines: int = 10000) -> list[CodeBlock]:
if m is not None:
keyword = m.group(1).strip("- ")
# handle special tags
if keyword == "expected-output":
if keyword in {"expected-output", "expected-output-ignore-whitespace"}:
if len(out) == 0:
raise RuntimeError(
"Found <!--pytest-codeblocks-expected-output--> "
f"Found <!--pytest-codeblocks-{keyword}--> "
+ "but no previous code block."
)
if out[-1].expected_output is not None:
raise RuntimeError(
"Found <!--pytest-codeblocks-expected-output--> "
f"Found <!--pytest-codeblocks-{keyword}--> "
+ "but block already has expected_output."
)
expected_output_block = out[-1]
if keyword == "expected-output-ignore-whitespace":
# \s: regex matches all whitespace characters
expected_output_ignore_whitespace = True

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

else:
raise RuntimeError(f'Unknown pytest-codeblocks keyword "{keyword}."')
raise RuntimeError(f'Unknown pytest-codeblocks keyword "{keyword}"')

continue

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

elif expected_output_block:
expected_output_block.expected_output = code
expected_output_block.expected_output_ignore_whitespace = (
expected_output_ignore_whitespace
)
expected_output_block = None

else:
Expand Down
10 changes: 9 additions & 1 deletion src/pytest_codeblocks/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#
import subprocess
from pathlib import Path
import re

import pytest

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

if output is not None and self.obj.expected_output is not None:
if self.obj.expected_output != output:
str0 = self.obj.expected_output
str1 = output

if self.obj.expected_output_ignore_whitespace:
str0 = re.sub(r"^\s+", "", str0, flags=re.MULTILINE)
str1 = re.sub(r"^\s+", "", str1, flags=re.MULTILINE)

if str0 != str1:
raise RuntimeError(
f"{self.name}, line {self.obj.lineno}:\n```\n"
+ f"Expected output\n```\n{self.obj.expected_output}```\n"
Expand Down
22 changes: 22 additions & 0 deletions tests/test_expected_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,25 @@ def test_expected_output_fail(testdir):
testdir.makefile(".md", string)
result = testdir.runpytest("--codeblocks")
result.assert_outcomes(failed=1)


def test_expected_output_ignore_whitespace(testdir):
string = """
Lorem ipsum
```python
print(1 + 3)
print(1 - 3)
print(1 * 3)
```
dolor sit amet
<!--pytest-codeblocks:expected-output-ignore-whitespace-->
```
4
-2
3
```
"""
testdir.makefile(".md", string)
result = testdir.runpytest("--codeblocks")
result.assert_outcomes(passed=1)

0 comments on commit a8ae092

Please sign in to comment.