1# RUN: %{python} %s
2#
3# END.
4
5
6import unittest
7import platform
8import os.path
9import tempfile
10
11import lit
12from lit.TestRunner import ParserKind, IntegratedTestKeywordParser, \
13                           parseIntegratedTestScript
14
15
16class TestIntegratedTestKeywordParser(unittest.TestCase):
17    inputTestCase = None
18
19    @staticmethod
20    def load_keyword_parser_lit_tests():
21        """
22        Create and load the LIT test suite and test objects used by
23        TestIntegratedTestKeywordParser
24        """
25        # Create the global config object.
26        lit_config = lit.LitConfig.LitConfig(progname='lit',
27                                             path=[],
28                                             quiet=False,
29                                             useValgrind=False,
30                                             valgrindLeakCheck=False,
31                                             singleProcess=False,
32                                             valgrindArgs=[],
33                                             noExecute=False,
34                                             debug=False,
35                                             isWindows=(
36                                               platform.system() == 'Windows'),
37                                             params={})
38        TestIntegratedTestKeywordParser.litConfig = lit_config
39        # Perform test discovery.
40        test_path = os.path.dirname(os.path.dirname(__file__))
41        inputs = [os.path.join(test_path, 'Inputs/testrunner-custom-parsers/')]
42        assert os.path.isdir(inputs[0])
43        run = lit.run.Run(lit_config,
44                          lit.discovery.find_tests_for_inputs(lit_config, inputs))
45        assert len(run.tests) == 1 and "there should only be one test"
46        TestIntegratedTestKeywordParser.inputTestCase = run.tests[0]
47
48    @staticmethod
49    def make_parsers():
50        def custom_parse(line_number, line, output):
51            if output is None:
52                output = []
53            output += [part for part in line.split(' ') if part.strip()]
54            return output
55
56        return [
57            IntegratedTestKeywordParser("MY_TAG.", ParserKind.TAG),
58            IntegratedTestKeywordParser("MY_DNE_TAG.", ParserKind.TAG),
59            IntegratedTestKeywordParser("MY_LIST:", ParserKind.LIST),
60            IntegratedTestKeywordParser("MY_RUN:", ParserKind.COMMAND),
61            IntegratedTestKeywordParser("MY_CUSTOM:", ParserKind.CUSTOM,
62                                        custom_parse)
63        ]
64
65    @staticmethod
66    def get_parser(parser_list, keyword):
67        for p in parser_list:
68            if p.keyword == keyword:
69                return p
70        assert False and "parser not found"
71
72    @staticmethod
73    def parse_test(parser_list):
74        script = parseIntegratedTestScript(
75            TestIntegratedTestKeywordParser.inputTestCase,
76            additional_parsers=parser_list, require_script=False)
77        assert not isinstance(script, lit.Test.Result)
78        assert isinstance(script, list)
79        assert len(script) == 0
80
81    def test_tags(self):
82        parsers = self.make_parsers()
83        self.parse_test(parsers)
84        tag_parser = self.get_parser(parsers, 'MY_TAG.')
85        dne_tag_parser = self.get_parser(parsers, 'MY_DNE_TAG.')
86        self.assertTrue(tag_parser.getValue())
87        self.assertFalse(dne_tag_parser.getValue())
88
89    def test_lists(self):
90        parsers = self.make_parsers()
91        self.parse_test(parsers)
92        list_parser = self.get_parser(parsers, 'MY_LIST:')
93        self.assertEqual(list_parser.getValue(),
94                              ['one', 'two', 'three', 'four'])
95
96    def test_commands(self):
97        parsers = self.make_parsers()
98        self.parse_test(parsers)
99        cmd_parser = self.get_parser(parsers, 'MY_RUN:')
100        value = cmd_parser.getValue()
101        self.assertEqual(len(value), 2)  # there are only two run lines
102        self.assertEqual(value[0].strip(), "%dbg(MY_RUN: at line 4)  baz")
103        self.assertEqual(value[1].strip(), "%dbg(MY_RUN: at line 7)  foo  bar")
104
105    def test_custom(self):
106        parsers = self.make_parsers()
107        self.parse_test(parsers)
108        custom_parser = self.get_parser(parsers, 'MY_CUSTOM:')
109        value = custom_parser.getValue()
110        self.assertEqual(value, ['a', 'b', 'c'])
111
112    def test_bad_keywords(self):
113        def custom_parse(line_number, line, output):
114            return output
115
116        try:
117            IntegratedTestKeywordParser("TAG_NO_SUFFIX", ParserKind.TAG),
118            self.fail("TAG_NO_SUFFIX failed to raise an exception")
119        except ValueError as e:
120            pass
121        except BaseException as e:
122            self.fail("TAG_NO_SUFFIX raised the wrong exception: %r" % e)
123
124        try:
125            IntegratedTestKeywordParser("TAG_WITH_COLON:", ParserKind.TAG),
126            self.fail("TAG_WITH_COLON: failed to raise an exception")
127        except ValueError as e:
128            pass
129        except BaseException as e:
130            self.fail("TAG_WITH_COLON: raised the wrong exception: %r" % e)
131
132        try:
133            IntegratedTestKeywordParser("LIST_WITH_DOT.", ParserKind.LIST),
134            self.fail("LIST_WITH_DOT. failed to raise an exception")
135        except ValueError as e:
136            pass
137        except BaseException as e:
138            self.fail("LIST_WITH_DOT. raised the wrong exception: %r" % e)
139
140        try:
141            IntegratedTestKeywordParser("CUSTOM_NO_SUFFIX",
142                                        ParserKind.CUSTOM, custom_parse),
143            self.fail("CUSTOM_NO_SUFFIX failed to raise an exception")
144        except ValueError as e:
145            pass
146        except BaseException as e:
147            self.fail("CUSTOM_NO_SUFFIX raised the wrong exception: %r" % e)
148
149        # Both '.' and ':' are allowed for CUSTOM keywords.
150        try:
151            IntegratedTestKeywordParser("CUSTOM_WITH_DOT.",
152                                        ParserKind.CUSTOM, custom_parse),
153        except BaseException as e:
154            self.fail("CUSTOM_WITH_DOT. raised an exception: %r" % e)
155        try:
156            IntegratedTestKeywordParser("CUSTOM_WITH_COLON:",
157                                        ParserKind.CUSTOM, custom_parse),
158        except BaseException as e:
159            self.fail("CUSTOM_WITH_COLON: raised an exception: %r" % e)
160
161        try:
162            IntegratedTestKeywordParser("CUSTOM_NO_PARSER:",
163                                        ParserKind.CUSTOM),
164            self.fail("CUSTOM_NO_PARSER: failed to raise an exception")
165        except ValueError as e:
166            pass
167        except BaseException as e:
168            self.fail("CUSTOM_NO_PARSER: raised the wrong exception: %r" % e)
169
170if __name__ == '__main__':
171    TestIntegratedTestKeywordParser.load_keyword_parser_lit_tests()
172    unittest.main(verbosity=2)
173