Sketch of next generation of simplification.
Chris Pressey
6 years ago
172 | 172 | >>> b = Block() |
173 | 173 | >>> b.append(u'-> This is a pragma.') |
174 | 174 | >>> b.append(u'-> which extends over two lines') |
175 | >>> print b.classify() | |
175 | >>> print b.split() | |
176 | 176 | [Pragma(line_num=1)] |
177 | 177 | |
178 | 178 | >>> b = Block() |
179 | 179 | >>> b.append(u'| Test body here.') |
180 | 180 | >>> b.append(u'= Expected result here.') |
181 | >>> print b.classify() | |
181 | >>> print b.split() | |
182 | 182 | [TestBody(line_num=1), ExpectedResult(line_num=1)] |
183 | 183 | |
184 | 184 | >>> b = Block() |
185 | 185 | >>> b.append(u'| Test body here.') |
186 | 186 | >>> b.append(u'? Expected error here.') |
187 | >>> print b.classify() | |
187 | >>> print b.split() | |
188 | 188 | [TestBody(line_num=1), ExpectedError(line_num=1)] |
189 | 189 | |
190 | 190 | """ |
260 | 260 | |
261 | 261 | return pairs |
262 | 262 | |
263 | def classify(self): | |
263 | def split(self): | |
264 | 264 | """Return a list of Blocks of more specific classes.""" |
265 | 265 | |
266 | 266 | pattern = self.deconstruct() |
293 | 293 | ] |
294 | 294 | if pattern_prefixes in valid_patterns: |
295 | 295 | return [self.PREFIX_MAP[prefix](line_num=self.line_num, filename=self.filename, lines=lines) for (prefix, lines) in pattern] |
296 | raise FalderalSyntaxError( | |
297 | ("line %d: " % self.line_num) + | |
298 | "incorrectly formatted test block") | |
299 | ||
300 | def classify(self, current_functionality=None, last_desc_block=None): | |
301 | """Return the Test or Pragma that this Block represents.""" | |
302 | ||
303 | pattern = self.deconstruct() | |
304 | pattern_prefixes = [p[0] for p in pattern] | |
305 | ||
306 | if '' in pattern_prefixes: | |
307 | # There is plain, non-prefixed text embedded somewhere in this Block. | |
308 | # TODO: interpret this according to the new, not-yet-written rules. | |
309 | return [] | |
310 | ||
311 | if pattern_prefixes in [[u'= '], [u'? ']]: | |
312 | raise FalderalSyntaxError( | |
313 | ("line %d: " % self.line_num) + | |
314 | "expectation must be preceded by test body or test input") | |
315 | ||
316 | if pattern_prefixes in [[u'| ']]: | |
317 | raise FalderalSyntaxError( | |
318 | ("line %d: " % self.line_num) + | |
319 | "test body must be followed by expectation or test input") | |
320 | ||
321 | if pattern_prefixes == [u'->']: | |
322 | # Pragma | |
323 | pass | |
324 | elif pattern_prefixes[-1] in [u'= ', u'? ']: | |
325 | # TODO: valid patterns, several other things | |
326 | ||
327 | if current_functionality is None: | |
328 | raise FalderalSyntaxError( | |
329 | ("line %d: " % self.line_num) + | |
330 | "functionality under test not specified") | |
331 | ||
332 | body_block = make_block_from_pattern(pattern, u'| ') | |
333 | input_block = make_block_from_pattern(pattern, u'+ ') | |
334 | expectation_block = make_block_from_pattern(pattern, pattern_prefixes[-1]) | |
335 | ||
336 | test = Test(body_block=body_block, | |
337 | input_block=input_block, | |
338 | expectation=expectation_block, | |
339 | functionality=current_functionality, | |
340 | desc_block=last_desc_block) | |
341 | ||
342 | return test | |
343 | else: | |
296 | 344 | raise FalderalSyntaxError( |
297 | 345 | ("line %d: " % self.line_num) + |
298 | 346 | "incorrectly formatted test block") |
425 | 473 | continue |
426 | 474 | new_blocks.append(block) |
427 | 475 | else: |
428 | new_blocks.extend(block.classify()) | |
476 | new_blocks.extend(block.split()) | |
429 | 477 | self.blocks = new_blocks |
478 | ||
479 | def parse_lines_to_tests(self): | |
480 | r"""Parse the lines of the Document into Tests. | |
481 | ||
482 | """ | |
483 | indent = None | |
484 | blocks = [] | |
485 | line_num = 1 | |
486 | block = None | |
487 | ||
488 | for line in self.lines: | |
489 | # make sure we get a Block to start with | |
490 | if indent is None: | |
491 | if line.startswith(u' '): | |
492 | indent = u'' | |
493 | else: | |
494 | indent = u' ' | |
495 | ||
496 | if indent == u'': | |
497 | if line.startswith(u' '): | |
498 | indent = u' ' | |
499 | if block is not None: | |
500 | blocks.append(block) | |
501 | block = Block( | |
502 | line_num=line_num, | |
503 | filename=self.filename | |
504 | ) | |
505 | elif indent == u' ': | |
506 | if not line.startswith(u' '): | |
507 | indent = u'' | |
508 | if block is not None: | |
509 | blocks.append(block) | |
510 | block = InterveningText( | |
511 | line_num=line_num, | |
512 | filename=self.filename | |
513 | ) | |
514 | ||
515 | line = line[len(indent):] | |
516 | ||
517 | block.append(line) | |
518 | line_num += 1 | |
519 | ||
520 | if block is not None: | |
521 | blocks.append(block) | |
522 | ||
523 | # now process Blocks into Tests | |
524 | ||
525 | last_desc_block = None | |
526 | last_test_body_block = None | |
527 | last_used_test_body_block = None | |
528 | last_test_input_block = None | |
529 | ||
530 | tests = [] | |
531 | for block in blocks: | |
532 | if isinstance(block, InterveningText): | |
533 | if block.is_empty(): | |
534 | continue | |
535 | last_desc_block = block | |
536 | continue | |
537 | ||
538 | test_or_pragma = block.classify() | |
539 | ||
540 | if isinstance(test_or_pragma, Test): | |
541 | tests.append(test_or_pragma) | |
542 | elif isinstance(test_or_pragma, Pragma): | |
543 | pass | |
544 | # execute the pragma | |
545 | else: | |
546 | raise NotImplementedError('need Pragma or Test') | |
547 | ||
548 | return tests | |
430 | 549 | |
431 | 550 | def parse_blocks_to_tests(self, functionalities): |
432 | 551 | r"""Assemble a list of Tests from the blocks in this Document. |