Use only naked `{` and `}` for variable assignment
[normand.git] / tests / conftest.py
CommitLineData
bf8f3b38
PP
1# The MIT License (MIT)
2#
3# Copyright (c) 2023 Philippe Proulx <eeppeliteloop@gmail.com>
4#
5# Permission is hereby granted, free of charge, to any person obtaining
6# a copy of this software and associated documentation files (the
7# "Software"), to deal in the Software without restriction, including
8# without limitation the rights to use, copy, modify, merge, publish,
9# distribute, sublicense, and/or sell copies of the Software, and to
10# permit persons to whom the Software is furnished to do so, subject to
11# the following conditions:
12#
13# The above copyright notice and this permission notice shall be
14# included in all copies or substantial portions of the Software.
15#
16# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24import re
25
26import pytest
27
28import normand
29
30
31def pytest_collect_file(parent, file_path):
32 ext = ".nt"
33
34 if file_path.suffix != ext:
35 # Not a Normand test file: cancel
36 return
37
38 test_name = "test-{}".format(file_path.name.replace(ext, ""))
39
40 # Create the file node
41 if file_path.name.startswith("fail-"):
42 return _NormandTestFileFail.from_parent(parent, path=file_path, name=test_name)
43 elif file_path.name.startswith("pass-"):
44 return _NormandTestFilePass.from_parent(parent, path=file_path, name=test_name)
45 else:
46 # `.nt` file isn't a test case
47 return
48
49
50def _split_nt_file(path):
51 normand_lines = []
52 output_lines = []
53 cur_lines = normand_lines
54
55 with open(path) as f:
56 for line in f:
57 if line.rstrip() == "---" and len(output_lines) == 0:
58 cur_lines = output_lines
59 continue
60
61 cur_lines.append(line)
62
63 return "".join(normand_lines), "".join(output_lines).strip()
64
65
66class _NormandTestItem(pytest.Item):
67 def runtest(self):
68 self._runtest(*_split_nt_file(self.path))
69
70 def reportinfo(self):
71 return self.path, None, self.name
72
73
74class _NormandTestItemFail(_NormandTestItem):
75 def _runtest(self, normand_text, output):
76 with pytest.raises(normand.ParseError) as exc_info:
77 normand.parse(normand_text)
78
79 exc = exc_info.value
ee724c95 80 expected_msg = ""
f5dcb24c
PP
81
82 for msg in reversed(exc.messages):
83 expected_msg += "{}:{} - {}\n".format(
84 msg.text_location.line_no, msg.text_location.col_no, msg.text
85 )
86
87 assert output.strip() == expected_msg.strip()
bf8f3b38
PP
88
89
90class _NormandTestItemPass(_NormandTestItem):
91 @staticmethod
92 def _data_from_output(output):
93 hex_bytes = re.split(r"\s+", output.strip())
94 return bytearray([int(b, 16) for b in hex_bytes])
95
96 def _runtest(self, normand_text, output):
97 assert normand.parse(normand_text).data == self._data_from_output(output)
98
99
100class _NormandTestFile(pytest.File):
101 def __init__(self, name, **kwargs):
102 super().__init__(**kwargs)
103 self._name = name
104
105 def collect(self):
106 # Yield a single item
107 yield self._item_cls.from_parent(self, name=self._name)
108
109
110class _NormandTestFileFail(_NormandTestFile):
111 _item_cls = _NormandTestItemFail
112
113
114class _NormandTestFilePass(_NormandTestFile):
115 _item_cls = _NormandTestItemPass
This page took 0.026921 seconds and 4 git commands to generate.