Implement REUSE with SPDX identifiers
[normand.git] / tests / conftest.py
CommitLineData
d2d06893
MJ
1# SPDX-FileCopyrightText: 2023 Philippe Proulx <eeppeliteloop@gmail.com>
2# SPDX-License-Identifier: MIT
bf8f3b38
PP
3
4import re
5
6import pytest
7
8import normand
9
10
11def pytest_collect_file(parent, file_path):
12 ext = ".nt"
13
14 if file_path.suffix != ext:
15 # Not a Normand test file: cancel
16 return
17
18 test_name = "test-{}".format(file_path.name.replace(ext, ""))
19
20 # Create the file node
21 if file_path.name.startswith("fail-"):
22 return _NormandTestFileFail.from_parent(parent, path=file_path, name=test_name)
23 elif file_path.name.startswith("pass-"):
24 return _NormandTestFilePass.from_parent(parent, path=file_path, name=test_name)
25 else:
26 # `.nt` file isn't a test case
27 return
28
29
30def _split_nt_file(path):
31 normand_lines = []
32 output_lines = []
33 cur_lines = normand_lines
34
35 with open(path) as f:
36 for line in f:
37 if line.rstrip() == "---" and len(output_lines) == 0:
38 cur_lines = output_lines
39 continue
40
41 cur_lines.append(line)
42
43 return "".join(normand_lines), "".join(output_lines).strip()
44
45
46class _NormandTestItem(pytest.Item):
47 def runtest(self):
48 self._runtest(*_split_nt_file(self.path))
49
50 def reportinfo(self):
51 return self.path, None, self.name
52
53
54class _NormandTestItemFail(_NormandTestItem):
55 def _runtest(self, normand_text, output):
56 with pytest.raises(normand.ParseError) as exc_info:
57 normand.parse(normand_text)
58
59 exc = exc_info.value
ee724c95 60 expected_msg = ""
f5dcb24c
PP
61
62 for msg in reversed(exc.messages):
63 expected_msg += "{}:{} - {}\n".format(
64 msg.text_location.line_no, msg.text_location.col_no, msg.text
65 )
66
67 assert output.strip() == expected_msg.strip()
bf8f3b38
PP
68
69
70class _NormandTestItemPass(_NormandTestItem):
71 @staticmethod
72 def _data_from_output(output):
73 hex_bytes = re.split(r"\s+", output.strip())
74 return bytearray([int(b, 16) for b in hex_bytes])
75
76 def _runtest(self, normand_text, output):
77 assert normand.parse(normand_text).data == self._data_from_output(output)
78
79
80class _NormandTestFile(pytest.File):
81 def __init__(self, name, **kwargs):
82 super().__init__(**kwargs)
83 self._name = name
84
85 def collect(self):
86 # Yield a single item
87 yield self._item_cls.from_parent(self, name=self._name)
88
89
90class _NormandTestFileFail(_NormandTestFile):
91 _item_cls = _NormandTestItemFail
92
93
94class _NormandTestFilePass(_NormandTestFile):
95 _item_cls = _NormandTestItemPass
This page took 0.025755 seconds and 4 git commands to generate.