Skip to content

Commit

Permalink
Replace global is_peekable with a check on every file (#108)
Browse files Browse the repository at this point in the history
* Replace global is_peekable with a check on every file

Fixes #107

* peekable is only available in version 13 mode

* Add test for parsing mixed-version TAP files

* Fix linter errors by de-duplicating common idiom

* blacken
  • Loading branch information
ecederstrand committed Feb 28, 2020
1 parent f558832 commit 015c21c
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 25 deletions.
6 changes: 1 addition & 5 deletions tap/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class Parser(object):

TAP_MINIMUM_DECLARED_VERSION = 13

def __init__(self):
self._try_peeking = False

def parse_file(self, filename):
"""Parse a TAP file to an iterable of tap.line.Line objects.
Expand Down Expand Up @@ -103,7 +100,6 @@ def parse(self, fh):
if first_parsed.category == "version" and first_parsed.version >= 13:
if ENABLE_VERSION_13:
fh_new = peekable(itertools.chain([first_line], fh))
self._try_peeking = True
else: # pragma no cover
print(
"""
Expand Down Expand Up @@ -157,7 +153,7 @@ def _parse_result(self, ok, match, fh=None):
"""Parse a matching result line into a result instance."""
peek_match = None
try:
if fh is not None and self._try_peeking:
if fh is not None and ENABLE_VERSION_13 and isinstance(fh, peekable):
peek_match = self.yaml_block_start.match(fh.peek())
except StopIteration:
pass
Expand Down
90 changes: 70 additions & 20 deletions tap/tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@

from tap.parser import Parser

try:
import yaml
from more_itertools import peekable # noqa

have_yaml = True
except ImportError:
have_yaml = False


@contextmanager
def captured_output():
Expand Down Expand Up @@ -231,23 +239,74 @@ def test_parses_yaml(self):
for line in parser.parse_text(sample):
lines.append(line)

try:
import yaml
from more_itertools import peekable # noqa

if have_yaml:
converted_yaml = yaml.safe_load(u"""test: sample yaml""")
self.assertEqual(4, len(lines))
self.assertEqual(13, lines[0].version)
self.assertEqual(converted_yaml, lines[2].yaml_block)
self.assertEqual("test", lines[3].category)
self.assertIsNone(lines[3].yaml_block)
except ImportError:
else:
self.assertEqual(7, len(lines))
self.assertEqual(13, lines[0].version)
for l in list(range(3, 6)):
self.assertEqual("unknown", lines[l].category)
self.assertEqual("test", lines[6].category)

def test_parses_mixed(self):
# Test that we can parse both a version 13 and earlier version files
# using the same parser. Make sure that parsing works regardless of
# the order of the incoming documents.
sample_version_13 = inspect.cleandoc(
u"""TAP version 13
1..2
ok 1 A passing version 13 test
---
test: sample yaml
...
not ok 2 A failing version 13 test"""
)
sample_pre_13 = inspect.cleandoc(
"""1..2
ok 1 A passing pre-13 test
not ok 2 A failing pre-13 test"""
)

parser = Parser()
lines = []
lines.extend(parser.parse_text(sample_version_13))
lines.extend(parser.parse_text(sample_pre_13))
if have_yaml:
self.assertEqual(13, lines[0].version)
self.assertEqual("A passing version 13 test", lines[2].description)
self.assertEqual("A failing version 13 test", lines[3].description)
self.assertEqual("A passing pre-13 test", lines[5].description)
self.assertEqual("A failing pre-13 test", lines[6].description)
else:
self.assertEqual(13, lines[0].version)
self.assertEqual("A passing version 13 test", lines[2].description)
self.assertEqual("A failing version 13 test", lines[6].description)
self.assertEqual("A passing pre-13 test", lines[8].description)
self.assertEqual("A failing pre-13 test", lines[9].description)

# Test parsing documents in reverse order
parser = Parser()
lines = []
lines.extend(parser.parse_text(sample_pre_13))
lines.extend(parser.parse_text(sample_version_13))
if have_yaml:
self.assertEqual("A passing pre-13 test", lines[1].description)
self.assertEqual("A failing pre-13 test", lines[2].description)
self.assertEqual(13, lines[3].version)
self.assertEqual("A passing version 13 test", lines[5].description)
self.assertEqual("A failing version 13 test", lines[6].description)
else:
self.assertEqual("A passing pre-13 test", lines[1].description)
self.assertEqual("A failing pre-13 test", lines[2].description)
self.assertEqual(13, lines[3].version)
self.assertEqual("A passing version 13 test", lines[5].description)
self.assertEqual("A failing version 13 test", lines[9].description)

def test_parses_yaml_no_end(self):
sample = inspect.cleandoc(
u"""TAP version 13
Expand All @@ -263,17 +322,14 @@ def test_parses_yaml_no_end(self):
for line in parser.parse_text(sample):
lines.append(line)

try:
import yaml
from more_itertools import peekable # noqa

if have_yaml:
converted_yaml = yaml.safe_load(u"""test: sample yaml""")
self.assertEqual(4, len(lines))
self.assertEqual(13, lines[0].version)
self.assertEqual(converted_yaml, lines[2].yaml_block)
self.assertEqual("test", lines[3].category)
self.assertIsNone(lines[3].yaml_block)
except ImportError:
else:
self.assertEqual(6, len(lines))
self.assertEqual(13, lines[0].version)
for l in list(range(3, 5)):
Expand All @@ -300,10 +356,7 @@ def test_parses_yaml_more_complex(self):
for line in parser.parse_text(sample):
lines.append(line)

try:
import yaml
from more_itertools import peekable # noqa

if have_yaml:
converted_yaml = yaml.safe_load(
u"""
message: test
Expand All @@ -317,7 +370,7 @@ def test_parses_yaml_more_complex(self):
self.assertEqual(3, len(lines))
self.assertEqual(13, lines[0].version)
self.assertEqual(converted_yaml, lines[2].yaml_block)
except ImportError:
else:
self.assertEqual(11, len(lines))
self.assertEqual(13, lines[0].version)
for l in list(range(3, 11)):
Expand Down Expand Up @@ -395,10 +448,7 @@ def test_malformed_yaml(self):
for line in parser.parse_text(sample):
lines.append(line)

try:
import yaml # noqa
from more_itertools import peekable # noqa

if have_yaml:
self.assertEqual(4, len(lines))
self.assertEqual(13, lines[0].version)
with captured_output() as (out, _):
Expand All @@ -408,7 +458,7 @@ def test_malformed_yaml(self):
)
self.assertEqual("test", lines[3].category)
self.assertIsNone(lines[3].yaml_block)
except ImportError:
else:
self.assertEqual(8, len(lines))
self.assertEqual(13, lines[0].version)
for l in list(range(3, 7)):
Expand Down

0 comments on commit 015c21c

Please sign in to comment.