Mercurial > jouvence
comparison tests/conftest.py @ 1:74b83e3d921e
Add more states, add more tests.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Mon, 02 Jan 2017 21:54:59 -0800 |
parents | 243401c49520 |
children | 59fe8cb6190d |
comparison
equal
deleted
inserted
replaced
0:243401c49520 | 1:74b83e3d921e |
---|---|
2 import logging | 2 import logging |
3 import yaml | 3 import yaml |
4 import pytest | 4 import pytest |
5 from fontaine.document import ( | 5 from fontaine.document import ( |
6 FontaineSceneElement, | 6 FontaineSceneElement, |
7 TYPE_ACTION, TYPE_CHARACTER, TYPE_DIALOG, TYPE_PARENTHETICAL) | 7 TYPE_ACTION, TYPE_CENTEREDACTION, TYPE_CHARACTER, TYPE_DIALOG, |
8 TYPE_PARENTHETICAL, TYPE_TRANSITION, TYPE_LYRICS, TYPE_PAGEBREAK, | |
9 _scene_element_type_str) | |
8 from fontaine.parser import FontaineParser, FontaineParserError | 10 from fontaine.parser import FontaineParser, FontaineParserError |
11 from fontaine.renderer import BaseRenderer | |
9 | 12 |
10 | 13 |
11 def pytest_addoption(parser): | 14 def pytest_addoption(parser): |
12 parser.addoption( | 15 parser.addoption( |
13 '--log-debug', | 16 '--log-debug', |
65 | 68 |
66 def _d(text): | 69 def _d(text): |
67 return FontaineSceneElement(TYPE_DIALOG, text) | 70 return FontaineSceneElement(TYPE_DIALOG, text) |
68 | 71 |
69 | 72 |
73 def _t(text): | |
74 return FontaineSceneElement(TYPE_TRANSITION, text) | |
75 | |
76 | |
77 def _l(text): | |
78 return FontaineSceneElement(TYPE_LYRICS, text) | |
79 | |
80 | |
81 class UnexpectedScriptOutput(Exception): | |
82 def __init__(self, actual, expected): | |
83 self.actual = actual | |
84 self.expected = expected | |
85 | |
86 | |
70 class FontaineScriptTestFile(pytest.File): | 87 class FontaineScriptTestFile(pytest.File): |
71 def collect(self): | 88 def collect(self): |
72 spec = yaml.load_all(self.fspath.open(encoding='utf8')) | 89 spec = yaml.load_all(self.fspath.open(encoding='utf8')) |
73 for i, item in enumerate(spec): | 90 for i, item in enumerate(spec): |
74 name = '%s_%d' % (self.fspath.basename, i) | 91 name = '%s_%d' % (self.fspath.basename, i) |
94 | 111 |
95 parser = FontaineParser() | 112 parser = FontaineParser() |
96 doc = parser.parseString(intext) | 113 doc = parser.parseString(intext) |
97 if title is not None: | 114 if title is not None: |
98 assert title == doc.title_values | 115 assert title == doc.title_values |
99 assert_scenes(doc.scenes, make_scenes(expected)) | 116 |
117 exp_scenes = make_scenes(expected) | |
118 try: | |
119 assert_scenes(doc.scenes, exp_scenes) | |
120 except AssertionError: | |
121 raise UnexpectedScriptOutput(doc.scenes, exp_scenes) | |
100 | 122 |
101 def repr_failure(self, excinfo): | 123 def repr_failure(self, excinfo): |
102 if isinstance(excinfo.value, FontaineParserError): | 124 if isinstance(excinfo.value, FontaineParserError): |
103 return ('\n'.join( | 125 return ('\n'.join( |
104 ['Parser error:', str(excinfo.value)])) | 126 ['Parser error:', str(excinfo.value)])) |
127 if isinstance(excinfo.value, UnexpectedScriptOutput): | |
128 return ('\n'.join( | |
129 ['Unexpected output:'] + | |
130 ['', 'Actual:'] + | |
131 list(_repr_doc_scenes(excinfo.value.actual)) + | |
132 ['', 'Expected:'] + | |
133 list(_repr_expected_scenes(excinfo.value.expected)))) | |
105 return super().repr_failure(excinfo) | 134 return super().repr_failure(excinfo) |
135 | |
136 | |
137 def _repr_doc_scenes(scenes): | |
138 for s in scenes: | |
139 yield 'Scene: "%s"' % s.header | |
140 for p in s.paragraphs: | |
141 yield ' %s: "%s"' % (_scene_element_type_str(p.type), | |
142 p.text) | |
143 | |
144 | |
145 def _repr_expected_scenes(scenes): | |
146 for s in scenes: | |
147 yield 'Scene: "%s"' % s[0] | |
148 for p in s[1:]: | |
149 if isinstance(p, str): | |
150 yield ' ACTION: "%s"' % p | |
151 else: | |
152 yield ' %s: "%s"' % (_scene_element_type_str(p.type), | |
153 p.text) | |
106 | 154 |
107 | 155 |
108 def make_scenes(spec): | 156 def make_scenes(spec): |
109 if not isinstance(spec, list): | 157 if not isinstance(spec, list): |
110 raise Exception("Script specs must be lists.") | 158 raise Exception("Script specs must be lists.") |
112 out = [] | 160 out = [] |
113 cur_header = None | 161 cur_header = None |
114 cur_paras = [] | 162 cur_paras = [] |
115 | 163 |
116 for item in spec: | 164 for item in spec: |
165 if item == '<pagebreak>': | |
166 cur_paras.append(FontaineSceneElement(TYPE_PAGEBREAK, None)) | |
167 continue | |
168 | |
117 token = item[:1] | 169 token = item[:1] |
118 if token == '.': | 170 if token == '.': |
119 if cur_header or cur_paras: | 171 if cur_header or cur_paras: |
120 out.append([cur_header] + cur_paras) | 172 out.append([cur_header] + cur_paras) |
121 cur_header = item[1:] | 173 cur_header = item[1:] |
174 cur_paras = [] | |
122 elif token == '!': | 175 elif token == '!': |
123 cur_paras.append(item[1:]) | 176 if item[1:3] == '><': |
177 cur_paras.append( | |
178 FontaineSceneElement(TYPE_CENTEREDACTION, item[3:])) | |
179 else: | |
180 cur_paras.append(item[1:]) | |
124 elif token == '@': | 181 elif token == '@': |
125 cur_paras.append(_c(item[1:])) | 182 cur_paras.append(_c(item[1:])) |
126 elif token == '=': | 183 elif token == '=': |
127 cur_paras.append(_d(item[1:])) | 184 cur_paras.append(_d(item[1:])) |
128 elif token == '_': | 185 elif token == '_': |
129 cur_paras.append(_p(item[1:])) | 186 cur_paras.append(_p(item[1:])) |
187 elif token == '>': | |
188 cur_paras.append(_t(item[1:])) | |
189 elif token == '~': | |
190 cur_paras.append(_l(item[1:])) | |
130 else: | 191 else: |
131 raise Exception("Unknown token: %s" % token) | 192 raise Exception("Unknown token: %s" % token) |
132 if cur_header or cur_paras: | 193 if cur_header or cur_paras: |
133 out.append([cur_header] + cur_paras) | 194 out.append([cur_header] + cur_paras) |
134 return out | 195 return out |
196 | |
197 | |
198 class TestRenderer(BaseRenderer): | |
199 def write_bold(self, text): | |
200 pass | |
201 | |
202 def write_italics(self, text): | |
203 pass | |
204 | |
205 def write_underline(self, text): | |
206 pass |