Commit | Line | Data |
---|---|---|
b85894a3 MJ |
1 | # Copyright (c) 2016, Matt Layman |
2 | ||
3 | import os | |
4 | import unittest | |
5 | ||
6 | from tap.adapter import Adapter | |
7 | from tap.parser import Parser | |
8 | from tap.rules import Rules | |
9 | ||
10 | ||
11 | class Loader(object): | |
12 | """Load TAP lines into unittest-able objects.""" | |
13 | ||
14 | ignored_lines = set(['diagnostic', 'unknown']) | |
15 | ||
16 | def __init__(self): | |
17 | self._parser = Parser() | |
18 | ||
19 | def load(self, files): | |
20 | """Load any files found into a suite. | |
21 | ||
22 | Any directories are walked and their files are added as TAP files. | |
23 | ||
24 | :returns: A ``unittest.TestSuite`` instance | |
25 | """ | |
26 | suite = unittest.TestSuite() | |
27 | for filepath in files: | |
28 | if os.path.isdir(filepath): | |
29 | self._find_tests_in_directory(filepath, suite) | |
30 | else: | |
31 | suite.addTest(self.load_suite_from_file(filepath)) | |
32 | return suite | |
33 | ||
34 | def load_suite_from_file(self, filename): | |
35 | """Load a test suite with test lines from the provided TAP file. | |
36 | ||
37 | :returns: A ``unittest.TestSuite`` instance | |
38 | """ | |
39 | suite = unittest.TestSuite() | |
40 | rules = Rules(filename, suite) | |
41 | ||
42 | if not os.path.exists(filename): | |
43 | rules.handle_file_does_not_exist() | |
44 | return suite | |
45 | ||
46 | line_generator = self._parser.parse_file(filename) | |
47 | return self._load_lines(filename, line_generator, suite, rules) | |
48 | ||
49 | def load_suite_from_stdin(self): | |
50 | """Load a test suite with test lines from the TAP stream on STDIN. | |
51 | ||
52 | :returns: A ``unittest.TestSuite`` instance | |
53 | """ | |
54 | suite = unittest.TestSuite() | |
55 | rules = Rules('stream', suite) | |
56 | line_generator = self._parser.parse_stdin() | |
57 | return self._load_lines('stream', line_generator, suite, rules) | |
58 | ||
59 | def _find_tests_in_directory(self, directory, suite): | |
60 | """Find test files in the directory and add them to the suite.""" | |
61 | for dirpath, dirnames, filenames in os.walk(directory): | |
62 | for filename in filenames: | |
63 | filepath = os.path.join(dirpath, filename) | |
64 | suite.addTest(self.load_suite_from_file(filepath)) | |
65 | ||
66 | def _load_lines(self, filename, line_generator, suite, rules): | |
67 | """Load a suite with lines produced by the line generator.""" | |
68 | line_counter = 0 | |
69 | for line in line_generator: | |
70 | line_counter += 1 | |
71 | ||
72 | if line.category in self.ignored_lines: | |
73 | continue | |
74 | ||
75 | if line.category == 'test': | |
76 | suite.addTest(Adapter(filename, line)) | |
77 | rules.saw_test() | |
78 | elif line.category == 'plan': | |
79 | if line.skip: | |
80 | rules.handle_skipping_plan(line) | |
81 | return suite | |
82 | rules.saw_plan(line, line_counter) | |
83 | elif line.category == 'bail': | |
84 | rules.handle_bail(line) | |
85 | return suite | |
86 | elif line.category == 'version': | |
87 | rules.saw_version_at(line_counter) | |
88 | ||
89 | rules.check(line_counter) | |
90 | return suite |