Mercurial > jouvence
annotate tests/conftest.py @ 28:c9850153e4b3
Don't render empty title pages by default.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Thu, 12 Jan 2017 00:45:07 -0800 |
parents | 2ef526c301cc |
children |
rev | line source |
---|---|
2
59fe8cb6190d
Add lots of tests, fix lots of bugs.
Ludovic Chabant <ludovic@chabant.com>
parents:
1
diff
changeset
|
1 import re |
0 | 2 import sys |
3 import logging | |
4 import yaml | |
5 import pytest | |
13 | 6 from jouvence.document import ( |
24
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
7 JouvenceSceneElement, JouvenceSceneSection, |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
8 TYPE_ACTION, TYPE_CENTEREDACTION, TYPE_CHARACTER, TYPE_DIALOG, |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
9 TYPE_PARENTHETICAL, TYPE_TRANSITION, TYPE_LYRICS, TYPE_PAGEBREAK, |
24
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
10 TYPE_SYNOPSIS, |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
11 _scene_element_type_str) |
13 | 12 from jouvence.parser import JouvenceParser, JouvenceParserError |
0 | 13 |
14 | |
15 def pytest_addoption(parser): | |
16 parser.addoption( | |
17 '--log-debug', | |
18 action='store_true', | |
13 | 19 help="Sets the Jouvence logger to output debug info to stdout.") |
0 | 20 |
21 | |
22 def pytest_configure(config): | |
23 if config.getoption('--log-debug'): | |
24 hdl = logging.StreamHandler(stream=sys.stdout) | |
13 | 25 logging.getLogger('jouvence').addHandler(hdl) |
26 logging.getLogger('jouvence').setLevel(logging.DEBUG) | |
0 | 27 |
28 | |
29 def pytest_collect_file(parent, path): | |
30 if path.ext == '.yaml' and path.basename.startswith("test"): | |
13 | 31 return JouvenceScriptTestFile(path, parent) |
0 | 32 return None |
33 | |
34 | |
35 def assert_scenes(actual, scenes): | |
36 assert len(actual) == len(scenes) | |
37 for a, e in zip(actual, scenes): | |
38 assert_scene(a, e[0], e[1:]) | |
39 | |
40 | |
41 def assert_scene(actual, header, paragraphs): | |
42 if header is not None: | |
43 assert actual.header == header | |
44 assert len(actual.paragraphs) == len(paragraphs) | |
45 for a, e in zip(actual.paragraphs, paragraphs): | |
46 assert_paragraph(a, e) | |
47 | |
48 | |
49 def assert_paragraph(actual, expected): | |
50 if isinstance(expected, str): | |
13 | 51 assert isinstance(actual, JouvenceSceneElement) |
0 | 52 assert actual.type == TYPE_ACTION |
53 assert actual.text == expected | |
13 | 54 elif isinstance(expected, JouvenceSceneElement): |
55 assert isinstance(actual, JouvenceSceneElement) | |
0 | 56 assert actual.type == expected.type |
57 assert actual.text == expected.text | |
58 else: | |
59 raise NotImplementedError("Don't know what this is: %s" % expected) | |
60 | |
61 | |
62 def _c(name): | |
13 | 63 return JouvenceSceneElement(TYPE_CHARACTER, name) |
0 | 64 |
65 | |
66 def _p(text): | |
13 | 67 return JouvenceSceneElement(TYPE_PARENTHETICAL, text) |
0 | 68 |
69 | |
70 def _d(text): | |
13 | 71 return JouvenceSceneElement(TYPE_DIALOG, text) |
0 | 72 |
73 | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
74 def _t(text): |
13 | 75 return JouvenceSceneElement(TYPE_TRANSITION, text) |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
76 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
77 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
78 def _l(text): |
13 | 79 return JouvenceSceneElement(TYPE_LYRICS, text) |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
80 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
81 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
82 class UnexpectedScriptOutput(Exception): |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
83 def __init__(self, actual, expected): |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
84 self.actual = actual |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
85 self.expected = expected |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
86 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
87 |
13 | 88 class JouvenceScriptTestFile(pytest.File): |
0 | 89 def collect(self): |
90 spec = yaml.load_all(self.fspath.open(encoding='utf8')) | |
91 for i, item in enumerate(spec): | |
92 name = '%s_%d' % (self.fspath.basename, i) | |
93 if 'test_name' in item: | |
94 name += '_%s' % item['test_name'] | |
13 | 95 yield JouvenceScriptTestItem(name, self, item) |
0 | 96 |
97 | |
13 | 98 class JouvenceScriptTestItem(pytest.Item): |
0 | 99 def __init__(self, name, parent, spec): |
100 super().__init__(name, parent) | |
101 self.spec = spec | |
102 | |
103 def reportinfo(self): | |
13 | 104 return self.fspath, 0, "jouvence script test: %s" % self.name |
0 | 105 |
106 def runtest(self): | |
107 intext = self.spec.get('in') | |
108 expected = self.spec.get('out') | |
109 title = self.spec.get('title') | |
110 if intext is None or expected is None: | |
111 raise Exception("No 'in' or 'out' specified.") | |
112 | |
13 | 113 parser = JouvenceParser() |
0 | 114 doc = parser.parseString(intext) |
115 if title is not None: | |
116 assert title == doc.title_values | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
117 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
118 exp_scenes = make_scenes(expected) |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
119 try: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
120 assert_scenes(doc.scenes, exp_scenes) |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
121 except AssertionError: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
122 raise UnexpectedScriptOutput(doc.scenes, exp_scenes) |
0 | 123 |
124 def repr_failure(self, excinfo): | |
13 | 125 if isinstance(excinfo.value, JouvenceParserError): |
0 | 126 return ('\n'.join( |
127 ['Parser error:', str(excinfo.value)])) | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
128 if isinstance(excinfo.value, UnexpectedScriptOutput): |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
129 return ('\n'.join( |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
130 ['Unexpected output:'] + |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
131 ['', 'Actual:'] + |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
132 list(_repr_doc_scenes(excinfo.value.actual)) + |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
133 ['', 'Expected:'] + |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
134 list(_repr_expected_scenes(excinfo.value.expected)))) |
0 | 135 return super().repr_failure(excinfo) |
136 | |
137 | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
138 def _repr_doc_scenes(scenes): |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
139 for s in scenes: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
140 yield 'Scene: "%s"' % s.header |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
141 for p in s.paragraphs: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
142 yield ' %s: "%s"' % (_scene_element_type_str(p.type), |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
143 p.text) |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
144 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
145 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
146 def _repr_expected_scenes(scenes): |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
147 for s in scenes: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
148 yield 'Scene: "%s"' % s[0] |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
149 for p in s[1:]: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
150 if isinstance(p, str): |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
151 yield ' ACTION: "%s"' % p |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
152 else: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
153 yield ' %s: "%s"' % (_scene_element_type_str(p.type), |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
154 p.text) |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
155 |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
156 |
2
59fe8cb6190d
Add lots of tests, fix lots of bugs.
Ludovic Chabant <ludovic@chabant.com>
parents:
1
diff
changeset
|
157 RE_BLANK_LINE = re.compile(r"^\s+$") |
59fe8cb6190d
Add lots of tests, fix lots of bugs.
Ludovic Chabant <ludovic@chabant.com>
parents:
1
diff
changeset
|
158 |
59fe8cb6190d
Add lots of tests, fix lots of bugs.
Ludovic Chabant <ludovic@chabant.com>
parents:
1
diff
changeset
|
159 |
0 | 160 def make_scenes(spec): |
161 if not isinstance(spec, list): | |
162 raise Exception("Script specs must be lists.") | |
163 | |
164 out = [] | |
165 cur_header = None | |
166 cur_paras = [] | |
167 | |
168 for item in spec: | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
169 if item == '<pagebreak>': |
13 | 170 cur_paras.append(JouvenceSceneElement(TYPE_PAGEBREAK, None)) |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
171 continue |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
172 |
0 | 173 token = item[:1] |
174 if token == '.': | |
175 if cur_header or cur_paras: | |
176 out.append([cur_header] + cur_paras) | |
177 cur_header = item[1:] | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
178 cur_paras = [] |
0 | 179 elif token == '!': |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
180 if item[1:3] == '><': |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
181 cur_paras.append( |
13 | 182 JouvenceSceneElement(TYPE_CENTEREDACTION, item[3:])) |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
183 else: |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
184 cur_paras.append(item[1:]) |
0 | 185 elif token == '@': |
186 cur_paras.append(_c(item[1:])) | |
187 elif token == '=': | |
188 cur_paras.append(_d(item[1:])) | |
189 elif token == '_': | |
190 cur_paras.append(_p(item[1:])) | |
1
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
191 elif token == '>': |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
192 cur_paras.append(_t(item[1:])) |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
193 elif token == '~': |
74b83e3d921e
Add more states, add more tests.
Ludovic Chabant <ludovic@chabant.com>
parents:
0
diff
changeset
|
194 cur_paras.append(_l(item[1:])) |
24
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
195 elif token == '#': |
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
196 cur_paras.append( |
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
197 JouvenceSceneSection(1, item[1:])) |
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
198 elif token == '+': |
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
199 cur_paras.append( |
2ef526c301cc
Add support for sections and synopsis.
Ludovic Chabant <ludovic@chabant.com>
parents:
13
diff
changeset
|
200 JouvenceSceneElement(TYPE_SYNOPSIS, item[1:])) |
0 | 201 else: |
202 raise Exception("Unknown token: %s" % token) | |
203 if cur_header or cur_paras: | |
204 out.append([cur_header] + cur_paras) | |
205 return out |