git @ Cat's Eye Technologies Falderal / ba1ec6d
Seeing light at end of tunnel, re-enable all the doctests. Chris Pressey 5 years ago
3 changed file(s) with 164 addition(s) and 137 deletion(s). Raw diff Collapse all Expand all
177177
178178 >>> b = Block()
179179 >>> b.append(u'| Test body here.')
180 >>> b.append(u'= Expected output here')
180 >>> b.append(u'= Expected result here.')
181181 >>> print b.classify()
182182 [TestBody(line_num=1), ExpectedResult(line_num=1)]
183
184 >>> b = Block()
185 >>> b.append(u'| Test body here.')
186 >>> b.append(u'? Expected error here.')
187 >>> print b.classify()
188 [TestBody(line_num=1), ExpectedError(line_num=1)]
183189
184190 """
185191
221227 def text(self, seperator='\n'):
222228 return seperator.join(self.lines)
223229
230 def is_empty(self):
231 return all([(not line or line.isspace()) for line in self.lines])
232
224233 def deconstruct(self):
225234 """Return a list of pairs of (prefix, list of lines) representing
226235 the contents of this Block. The pairs are in the order the runs
256265
257266 pattern = self.deconstruct()
258267 pattern_prefixes = [p[0] for p in pattern]
259 if len(pattern_prefixes) == 1:
260 return [self.PREFIX_MAP[pattern_prefixes[0]](lines=self.lines)]
261
262 if pattern_prefixes == [u'| ', u'= ']:
263 return [TestBody(lines=pattern[0][1]), ExpectedResult(lines=pattern[1][1])]
264
265 return []
268
269 if '' in pattern_prefixes:
270 # There is plain, non-prefixed text embedded somewhere in this Block.
271 # TODO: interpret this according to the new, not-yet-written rules.
272 return []
273 else:
274 valid_patterns = [
275 [u'->'],
276 [u'> '],
277 [u'| ', u'= '],
278 [u'| ', u'? '],
279 [u'| ', u'+ ', u'= '],
280 [u'| ', u'+ ', u'? '],
281 [u'+ ', u'= '],
282 [u'+ ', u'? '],
283 ]
284 if pattern_prefixes in valid_patterns:
285 return [self.PREFIX_MAP[prefix](line_num=self.line_num, filename=self.filename, lines=lines) for (prefix, lines) in pattern]
286 raise FalderalSyntaxError(
287 ("line %d: " % self.line_num) +
288 "test block must consist of test body and/or test input, then expectation, in that order")
266289
267290
268291 class LiterateCode(Block):
323346 def parse_lines_to_blocks(self):
324347 r"""Parse the lines of the Document into Blocks.
325348
326 | >>> d = Document()
327 | >>> d.append(u'This is a test file.')
328 | >>> d.append(u' -> This is a pragma.')
329 | >>> d.append(u'')
330 | >>> d.append(u" | This is some test input.\n")
331 | >>> d.append(u" | It extends over two lines.")
332 | >>> d.append(u' ? Expected Error')
333 | >>> d.append(u'')
334 | >>> d.append(u' | Test with input')
335 | >>> d.append(u' + input-for-test')
336 | >>> d.append(u' = Expected result on output')
337 | >>> d.parse_lines_to_blocks()
338 | >>> [b.__class__.__name__ for b in d.blocks]
339 | ['InterveningText', 'Pragma', 'TestBody', 'ExpectedError',
340 | 'TestBody', 'TestInput', 'ExpectedResult']
341 | >>> [b.line_num for b in d.blocks]
342 | [1, 2, 3, 5, 6, 7, 8]
349 >>> d = Document()
350 >>> d.append(u'This is a test file.')
351 >>> d.append(u' -> This is a pragma.')
352 >>> d.append(u'')
353 >>> d.append(u" | This is some test input.\n")
354 >>> d.append(u" | It extends over two lines.")
355 >>> d.append(u' ? Expected Error')
356 >>> d.append(u'')
357 >>> d.append(u' | Test with input')
358 >>> d.append(u' + input-for-test')
359 >>> d.append(u' = Expected result on output')
360 >>> d.parse_lines_to_blocks()
361 >>> [block.lines for block in d.blocks if isinstance(block, InterveningText)]
362 [[u'This is a test file.']]
363 >>> [b.__class__.__name__ for b in d.blocks]
364 ['InterveningText', 'Pragma', 'TestBody', 'ExpectedError',
365 'TestBody', 'TestInput', 'ExpectedResult']
366 >>> [b.line_num for b in d.blocks]
367 [1, 2, 4, 4, 8, 8, 8]
343368
344369 """
345370 indent = None
386411 new_blocks = []
387412 for block in blocks:
388413 if isinstance(block, InterveningText):
414 if block.is_empty():
415 continue
389416 new_blocks.append(block)
390417 else:
391418 new_blocks.extend(block.classify())
394421 def parse_blocks_to_tests(self, functionalities):
395422 r"""Assemble a list of Tests from the blocks in this Document.
396423
397 | >>> funs = {}
398 | >>> d = Document()
399 | >>> d.append(u"This is a text file.")
400 | >>> d.append(u'It contains NO tests.')
401 | >>> d.parse_blocks_to_tests(funs)
402 | []
403 |
404 | >>> d = Document()
405 | >>> d.append(u'This is a test file.')
406 | >>> d.append(u' -> Tests for functionality "Parse Thing"')
407 | >>> d.append(u" | This is some test body.")
408 | >>> d.append(u" | It extends over two lines.")
409 | >>> d.append(u' ? Expected Error')
410 | >>> d.append(u' | Test with input')
411 | >>> d.append(u' + input-for-test')
412 | >>> d.append(u' = Expected result on output')
413 | >>> d.append(u' + Other input-for-test')
414 | >>> d.append(u' = Other Expected result on output')
415 | >>> d.append(u' -> Tests for functionality "Run Thing"')
416 | >>> d.append(u" | Thing")
417 | >>> d.append(u' ? Oops')
418 | >>> d.parse_lines_to_blocks()
419 | >>> [b.__class__.__name__ for b in d.blocks]
420 | ['InterveningText', 'Pragma', 'TestBody', 'ExpectedError',
421 | 'TestBody', 'TestInput', 'ExpectedResult',
422 | 'TestInput', 'ExpectedResult', 'Pragma', 'TestBody', 'ExpectedError']
423 | >>> tests = d.parse_blocks_to_tests(funs)
424 | >>> [t.body for t in tests]
425 | [u'This is some test body.\nIt extends over two lines.',
426 | u'Test with input', u'Test with input', u'Thing']
427 | >>> [t.input_block for t in tests]
428 | [None, TestInput(u' + ', line_num=7, filename=None),
429 | TestInput(u' + ', line_num=9, filename=None), None]
430 | >>> tests[1].input_block.text()
431 | u'input-for-test'
432 | >>> tests[2].input_block.text()
433 | u'Other input-for-test'
434 | >>> [t.expectation for t in tests]
435 | [ErrorOutcome(u'Expected Error'),
436 | OutputOutcome(u'Expected result on output'),
437 | OutputOutcome(u'Other Expected result on output'),
438 | ErrorOutcome(u'Oops')]
439 | >>> [t.functionality.name for t in tests]
440 | [u'Parse Thing', u'Parse Thing', u'Parse Thing', u'Run Thing']
441 | >>> sorted(funs.keys())
442 | [u'Parse Thing', u'Run Thing']
443 |
444 | >>> d = Document()
445 | >>> d.append(u" | This is some test body.")
446 | >>> d.append(u' = Expected')
447 | >>> d.parse_blocks_to_tests({})
448 | Traceback (most recent call last):
449 | ...
450 | FalderalSyntaxError: line 2: functionality under test not specified
451 |
452 | >>> d = Document()
453 | >>> d.append(u'This is a test file.')
454 | >>> d.append(u' ? Expected Error')
455 | >>> d.parse_blocks_to_tests({})
456 | Traceback (most recent call last):
457 | ...
458 | FalderalSyntaxError: line 2: expectation must be preceded by test body or test input
459 |
460 | >>> d = Document()
461 | >>> d.append(u' -> Hello, this is pragma')
462 | >>> d.append(u' = Expected')
463 | >>> d.parse_blocks_to_tests({})
464 | Traceback (most recent call last):
465 | ...
466 | FalderalSyntaxError: line 2: expectation must be preceded by test body or test input
467 |
468 | >>> d = Document()
469 | >>> d.append(u' | This is test')
470 | >>> d.append(u'This is text')
471 | >>> d.parse_blocks_to_tests({})
472 | Traceback (most recent call last):
473 | ...
474 | FalderalSyntaxError: line 2: test body must be followed by expectation or test input
475 |
476 | >>> d = Document()
477 | >>> d.append(u' -> Hello, this is pragma')
478 | >>> d.append(u' + Input to where exactly?')
479 | >>> d.parse_blocks_to_tests({})
480 | Traceback (most recent call last):
481 | ...
482 | FalderalSyntaxError: line 2: test input must be preceded by test body
483 |
484 | >>> d = Document()
485 | >>> funs = {}
486 | >>> d.append(u' -> Functionality "Parse Stuff" is implemented by '
487 | ... u'shell command "parse"')
488 | >>> d.append(u'')
489 | >>> d.append(u' -> Functionality "Parse Stuff" is')
490 | >>> d.append(u' -> implemented by shell command "pxxxy"')
491 | >>> tests = d.parse_blocks_to_tests(funs)
492 | >>> len(funs.keys())
493 | 1
494 | >>> [i for i in funs["Parse Stuff"].implementations]
495 | [ShellImplementation(u'parse'), ShellImplementation(u'pxxxy')]
424 >>> funs = {}
425 >>> d = Document()
426 >>> d.append(u"This is a text file.")
427 >>> d.append(u'It contains NO tests.')
428 >>> d.parse_blocks_to_tests(funs)
429 []
430
431 >>> d = Document()
432 >>> d.append(u'This is a test file.')
433 >>> d.append(u' -> Tests for functionality "Parse Thing"')
434 >>> d.append(u" | This is some test body.")
435 >>> d.append(u" | It extends over two lines.")
436 >>> d.append(u' ? Expected Error')
437 >>> d.append(u' | Test with input')
438 >>> d.append(u' + input-for-test')
439 >>> d.append(u' = Expected result on output')
440 >>> d.append(u' + Other input-for-test')
441 >>> d.append(u' = Other Expected result on output')
442 >>> d.append(u' -> Tests for functionality "Run Thing"')
443 >>> d.append(u" | Thing")
444 >>> d.append(u' ? Oops')
445 >>> d.parse_lines_to_blocks()
446 >>> [b.__class__.__name__ for b in d.blocks]
447 ['InterveningText', 'Pragma', 'TestBody', 'ExpectedError',
448 'TestBody', 'TestInput', 'ExpectedResult',
449 'TestInput', 'ExpectedResult', 'Pragma', 'TestBody', 'ExpectedError']
450 >>> tests = d.parse_blocks_to_tests(funs)
451 >>> [t.body for t in tests]
452 [u'This is some test body.\nIt extends over two lines.',
453 u'Test with input', u'Test with input', u'Thing']
454 >>> [t.input_block for t in tests]
455 [None, TestInput(u' + ', line_num=7, filename=None),
456 TestInput(u' + ', line_num=9, filename=None), None]
457 >>> tests[1].input_block.text()
458 u'input-for-test'
459 >>> tests[2].input_block.text()
460 u'Other input-for-test'
461 >>> [t.expectation for t in tests]
462 [ErrorOutcome(u'Expected Error'),
463 OutputOutcome(u'Expected result on output'),
464 OutputOutcome(u'Other Expected result on output'),
465 ErrorOutcome(u'Oops')]
466 >>> [t.functionality.name for t in tests]
467 [u'Parse Thing', u'Parse Thing', u'Parse Thing', u'Run Thing']
468 >>> sorted(funs.keys())
469 [u'Parse Thing', u'Run Thing']
470
471 >>> d = Document()
472 >>> d.append(u" | This is some test body.")
473 >>> d.append(u' = Expected')
474 >>> d.parse_blocks_to_tests({})
475 Traceback (most recent call last):
476 ...
477 FalderalSyntaxError: line 2: functionality under test not specified
478
479 >>> d = Document()
480 >>> d.append(u'This is a test file.')
481 >>> d.append(u' ? Expected Error')
482 >>> d.parse_blocks_to_tests({})
483 Traceback (most recent call last):
484 ...
485 FalderalSyntaxError: line 2: expectation must be preceded by test body or test input
486
487 >>> d = Document()
488 >>> d.append(u' -> Hello, this is pragma')
489 >>> d.append(u' = Expected')
490 >>> d.parse_blocks_to_tests({})
491 Traceback (most recent call last):
492 ...
493 FalderalSyntaxError: line 2: expectation must be preceded by test body or test input
494
495 >>> d = Document()
496 >>> d.append(u' | This is test')
497 >>> d.append(u'This is text')
498 >>> d.parse_blocks_to_tests({})
499 Traceback (most recent call last):
500 ...
501 FalderalSyntaxError: line 2: test body must be followed by expectation or test input
502
503 >>> d = Document()
504 >>> d.append(u' -> Hello, this is pragma')
505 >>> d.append(u' + Input to where exactly?')
506 >>> d.parse_blocks_to_tests({})
507 Traceback (most recent call last):
508 ...
509 FalderalSyntaxError: line 2: test input must be preceded by test body
510
511 >>> d = Document()
512 >>> funs = {}
513 >>> d.append(u' -> Functionality "Parse Stuff" is implemented by '
514 ... u'shell command "parse"')
515 >>> d.append(u'')
516 >>> d.append(u' -> Functionality "Parse Stuff" is')
517 >>> d.append(u' -> implemented by shell command "pxxxy"')
518 >>> tests = d.parse_blocks_to_tests(funs)
519 >>> len(funs.keys())
520 1
521 >>> [i for i in funs["Parse Stuff"].implementations]
522 [ShellImplementation(u'parse'), ShellImplementation(u'pxxxy')]
496523
497524 """
498525 if self.blocks is None:
798825
799826 TODO: maybe write a helper function for that instead.
800827
801 | >>> b = TestBody(u' | ')
802 | >>> b.append(u' | foo')
803 | >>> b.append(u' | bar')
804 | >>> i = TestInput(u' + ')
805 | >>> i.append(u' + green')
806 | >>> t = Test(body_block=b, input_block=i)
807 | >>> print t.body
808 | foo
809 | bar
810 | >>> print t.input
811 | green
828 >>> b = TestBody(u' | ')
829 >>> b.append(u' | foo')
830 >>> b.append(u' | bar')
831 >>> i = TestInput(u' + ')
832 >>> i.append(u' + green')
833 >>> t = Test(body_block=b, input_block=i)
834 >>> print t.body
835 foo
836 bar
837 >>> print t.input
838 green
812839
813840 """
814841 def __init__(self, body_block=None, input_block=None, expectation=None,
0 FalderalSyntaxError: line 13: functionality under test not specified
0 FalderalSyntaxError: line 12: functionality under test not specified
0 FalderalSyntaxError: line 14: test body must be followed by expectation or test input
0 FalderalSyntaxError: line 13: test block must consist of test body and/or test input, then expectation, in that order