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