Skip to content

Commit

Permalink
tabs: align expansion to multiples of 8
Browse files Browse the repository at this point in the history
  • Loading branch information
ctheune committed Oct 18, 2024
1 parent ff638b8 commit 94fa4ca
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 5 deletions.
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,27 @@ def test_zen(patterns, zen_patterns):
assert full_pattern == zen
```

## Handling tabs and whitespace

When copying and pasting output from commands its easy to turn tabs from an
original source into spaces and then accidentally not aligning things right.

As its more typical to not insert tabs in your code pytest-patterns converts
tabs to spaces (properly aligned to 8 character stops as terminals render them):

```python
def test_tabs_and_spaces(patterns):
data = """
pre>\taligned text
prefix>\tmore aligned text
"""
tabs = patterns.tabs
tabs.in_order("""
pre> aligned text
prefix> aligned text
""")
assert tabs == data
```

# Development

Expand All @@ -378,8 +399,7 @@ $ hatch run test

-> whitespace (pattern and tested content)
-> strip whitespace at beginning and end
-> replace tabs with spaces
-> fold multiple spaces into single spaces
-> fold multiple spaces into single spaces (makes it harder to diagnose things)

* [ ] proper release process with tagging, version updates, etc.

Expand Down
12 changes: 9 additions & 3 deletions src/pytest_patterns/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import enum
import re
from typing import Any, Iterator
from typing import Any, Iterator, List, Set, Tuple

import pytest

Expand Down Expand Up @@ -45,13 +45,19 @@ def symbol(self) -> str:

EMPTY_LINE_PATTERN = "<empty-line>"

def tab_replace(line: str) -> str:
while (position := line.find("\t")) != -1:
fill = " " * (8 - (position % 8))
line = line.replace("\t", fill)
return line


def match(pattern: str, line: str) -> bool | re.Match[str] | None:
if pattern == EMPTY_LINE_PATTERN:
if not line:
return True
pattern = pattern.replace("\t", " " * 8)
line = line.replace("\t", " " * 8)

line = tab_replace(line)
pattern = re.escape(pattern)
pattern = pattern.replace(r"\.\.\.", ".*?")
re_pattern = re.compile("^" + pattern + "$")
Expand Down
14 changes: 14 additions & 0 deletions tests/test_basics.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@
"",
]

def test_tab_replace() -> None:
from pytest_patterns.plugin import tab_replace

assert tab_replace("\t") == " " * 8
assert tab_replace("1\t9") == "1 9"
assert tab_replace("12\t9") == "12 9"
assert tab_replace("123\t9") == "123 9"
assert tab_replace("1234\t9") == "1234 9"
assert tab_replace("12345\t9") == "12345 9"
assert tab_replace("123456\t9") == "123456 9"
assert tab_replace("1234567\t9") == "1234567 9"
assert tab_replace("12345678\t9") == "12345678 9"
assert tab_replace("123456789\t0") == "123456789 0"


def test_patternslib_multiple_accesses(patterns: PatternsLib) -> None:
assert patterns.foo is patterns.foo
Expand Down

0 comments on commit 94fa4ca

Please sign in to comment.