• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright (C) 2022 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import unittest
18
19from ninja_syntax import (Variable, Rule, RuleException, BuildAction,
20                          BuildActionException, Pool)
21
22
23class TestVariable(unittest.TestCase):
24    def test_assignment(self):
25        variable = Variable(name="key", value="value")
26        self.assertEqual("key = value", next(variable.stream()))
27        variable = Variable(name="key", value="value with spaces")
28        self.assertEqual("key = value with spaces", next(variable.stream()))
29        variable = Variable(name="key", value="$some_other_variable")
30        self.assertEqual("key = $some_other_variable", next(variable.stream()))
31
32    def test_indentation(self):
33        variable = Variable(name="key", value="value", indent=0)
34        self.assertEqual("key = value", next(variable.stream()))
35        variable = Variable(name="key", value="value", indent=1)
36        self.assertEqual("  key = value", next(variable.stream()))
37
38
39class TestRule(unittest.TestCase):
40    def test_rulename_comes_first(self):
41        rule = Rule(name="myrule")
42        rule.add_variable("command", "/bin/bash echo")
43        self.assertEqual("rule myrule", next(rule.stream()))
44
45    def test_command_is_a_required_variable(self):
46        rule = Rule(name="myrule")
47        with self.assertRaises(RuleException):
48            next(rule.stream())
49
50    def test_bad_rule_variable(self):
51        rule = Rule(name="myrule")
52        with self.assertRaises(RuleException):
53            rule.add_variable(name="unrecognize_rule_variable", value="value")
54
55    def test_rule_variables_are_indented(self):
56        rule = Rule(name="myrule")
57        rule.add_variable("command", "/bin/bash echo")
58        stream = rule.stream()
59        self.assertEqual("rule myrule",
60                         next(stream))  # top-level rule should not be indented
61        self.assertEqual("  command = /bin/bash echo", next(stream))
62
63    def test_rule_equality(self):
64        r1 = Rule("rule", (("description", "desc"), ("command", "cmd")))
65        r2 = Rule("rule", (("description", "desc"), ("command", "cmd")))
66        self.assertEqual(r1, r1)
67        self.assertEqual(r1, r2)
68
69        r1 = Rule("rule", (("description", "desc"), ("command", "cmd")))
70        r2 = Rule("RULE", (("description", "desc"), ("command", "cmd")))
71        r3 = Rule("rule", (("description", "DESC"), ("command", "cmd")))
72        r4 = Rule("rule", (("description", "desc"), ("command", "CMD")))
73        self.assertNotEqual(r1, r2)
74        self.assertNotEqual(r1, r3)
75        self.assertNotEqual(r1, r4)
76
77    def test_rule_variables_are_sorted(self):
78        rule = Rule(name="myrule")
79        rule.add_variable("description", "Adding description before command")
80        rule.add_variable("command", "/bin/bash echo")
81        stream = rule.stream()
82        self.assertEqual("rule myrule",
83                         next(stream))  # rule always comes first
84        self.assertEqual("  command = /bin/bash echo", next(stream))
85        self.assertEqual("  description = Adding description before command",
86                         next(stream))
87
88
89class TestBuildAction(unittest.TestCase):
90    def test_no_inputs(self):
91        build = BuildAction(output="out", rule="phony")
92        stream = build.stream()
93        self.assertEqual("build out: phony", next(stream))
94        # Empty output
95        build = BuildAction(output="", rule="phony")
96        with self.assertRaises(BuildActionException):
97            next(build.stream())
98        # Empty rule
99        build = BuildAction(output="out", rule="")
100        with self.assertRaises(BuildActionException):
101            next(build.stream())
102
103    def test_nonkeyword_inputs(self):
104        """Verify that non-keyword args are rejected."""
105        with self.assertRaises(TypeError):
106            BuildAction("out")
107
108    def test_inputs(self):
109        build = BuildAction(output="out",
110                            rule="cat",
111                            inputs=["input1", "input2"])
112        self.assertEqual("build out: cat input1 input2", next(build.stream()))
113        build = BuildAction(output="out",
114                            rule="cat",
115                            inputs=["input1", "input2"],
116                            implicits=["implicits1", "implicits2"],
117                            order_only=("order_only1", "order_only2")) # tuple args
118        self.assertEqual(
119            "build out: cat input1 input2 | implicits1 implicits2 || " +
120            "order_only1 order_only2", next(build.stream()))
121
122    def test_variables(self):
123        build = BuildAction(output="out",
124                            rule="cat",
125                            inputs=["input1", "input2"])
126        build.add_variable(name="myvar", value="myval")
127        stream = build.stream()
128        next(stream)
129        self.assertEqual("  myvar = myval", next(stream))
130
131
132class TestPool(unittest.TestCase):
133    def test_pool(self):
134        pool = Pool(name="mypool", depth=10)
135        stream = pool.stream()
136        self.assertEqual("pool mypool", next(stream))
137        self.assertEqual("  depth = 10", next(stream))
138
139
140if __name__ == "__main__":
141    unittest.main()
142