• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2023 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Tests for the pw_build.gn_target module."""
15
16import unittest
17
18from pw_build.bazel_query import BazelRule
19from pw_build.gn_target import GnTarget
20from pw_build.gn_utils import GnLabel, MalformedGnError
21
22
23class TestGnTarget(unittest.TestCase):
24    """Tests for gn_target.GnTarget."""
25
26    def setUp(self):
27        self.rule = BazelRule('//my-package:my-target', 'cc_library')
28
29    def test_from_bazel_rule_label(self):
30        """Tests the GN target name and package derived from a Bazel rule."""
31        target = GnTarget('$build', '$src', bazel=self.rule)
32        self.assertEqual(target.name(), 'my-target')
33        self.assertEqual(target.package(), 'my-package')
34
35    def test_from_bazel_rule_type_source_set(self):
36        """Tests creating a `pw_source_set` from a Bazel rule."""
37        target = GnTarget('$build', '$src', bazel=self.rule)
38        self.assertEqual(target.type(), 'pw_source_set')
39
40    def test_from_bazel_rule_type_static_lib(self):
41        """Tests creating a `pw_static_library` from a Bazel rule."""
42        self.rule.set_attr('linkstatic', True)
43        target = GnTarget('$build', '$src', bazel=self.rule)
44        self.assertEqual(target.type(), 'pw_static_library')
45
46    def test_from_bazel_rule_type_invalid(self):
47        """Tests creating an invalid type from a Bazel rule."""
48        with self.assertRaises(MalformedGnError):
49            rule = BazelRule('//my-package:my-target', 'custom_type')
50            GnTarget('$build', '$src', bazel=rule)
51
52    def test_from_bazel_rule_visibility(self):
53        """Tests getting the GN visibility from a Bazel rule."""
54        self.rule.set_attr(
55            'visibility',
56            [
57                '//foo:__subpackages__',
58                '//foo/bar:__pkg__',
59                '//baz:__pkg__',
60            ],
61        )
62        target = GnTarget('$build', '$src', bazel=self.rule)
63        self.assertEqual(
64            {str(scope) for scope in target.visibility},
65            {
66                '$build/my-package:*',
67                '$build/foo/*',
68                '$build/baz:*',
69            },
70        )
71
72    def test_from_bazel_rule_visibility_public(self):
73        """Tests that 'public' overrides any other visibility"""
74        self.rule.set_attr(
75            'visibility',
76            [
77                '//visibility:private',
78                '//visibility:public',
79            ],
80        )
81        target = GnTarget('$build', '$src', bazel=self.rule)
82        self.assertEqual({str(scope) for scope in target.visibility}, {'//*'})
83
84    def test_from_bazel_rule_visibility_invalid(self):
85        """Tests that and invalid visibility raises an error."""
86        self.rule.set_attr('visibility', ['invalid'])
87        with self.assertRaises(MalformedGnError):
88            GnTarget('$build', '$src', bazel=self.rule)
89
90    def test_from_bazel_rule_testonly_unset(self):
91        """Tests that omitting `testonly` defaults it to False."""
92        target = GnTarget('$build', '$src', bazel=self.rule)
93        self.assertFalse(target.testonly)
94
95    def test_from_bazel_rule_testonly_false(self):
96        """Tests setting `testonly` to False."""
97        self.rule.set_attr('testonly', False)
98        target = GnTarget('$build', '$src', bazel=self.rule)
99        self.assertFalse(target.testonly)
100
101    def test_from_bazel_rule_testonly_true(self):
102        """Tests setting `testonly` to True."""
103        self.rule.set_attr('testonly', True)
104        target = GnTarget('$build', '$src', bazel=self.rule)
105        self.assertTrue(target.testonly)
106
107    def test_from_bazel_rule_public(self):
108        """Tests getting the GN public headers from a Bazel rule."""
109        self.rule.set_attr('hdrs', ['//foo:bar.h', '//:baz.h'])
110        target = GnTarget('$build', '$src', bazel=self.rule)
111        self.assertEqual(
112            {str(path) for path in target.public},
113            {
114                '$src/foo/bar.h',
115                '$src/baz.h',
116            },
117        )
118
119    def test_from_bazel_rule_sources(self):
120        """Tests getting the GN source files from a Bazel rule."""
121        self.rule.set_attr('srcs', ['//foo:bar.cc', '//:baz.cc'])
122        target = GnTarget('$build', '$src', bazel=self.rule)
123        self.assertEqual(
124            {str(path) for path in target.sources},
125            {
126                '$src/foo/bar.cc',
127                '$src/baz.cc',
128            },
129        )
130
131    def test_from_bazel_rule_inputs(self):
132        """Tests getting the GN input files from a Bazel rule."""
133        self.rule.set_attr(
134            'additional_linker_inputs', ['//foo:bar.data', '//:baz.data']
135        )
136        target = GnTarget('$build', '$src', bazel=self.rule)
137        self.assertEqual(
138            {str(path) for path in target.inputs},
139            {
140                '$src/foo/bar.data',
141                '$src/baz.data',
142            },
143        )
144
145    def test_from_bazel_rule_include_dirs(self):
146        """Tests getting the GN include directories from a Bazel rule."""
147        self.rule.set_attr('includes', ['//foo'])
148        target = GnTarget('$build', '$src', bazel=self.rule)
149        self.assertEqual(
150            set(target.config.get('include_dirs')),
151            {
152                '$src',
153                '$src/foo',
154            },
155        )
156
157    def test_from_bazel_rule_configs(self):
158        """Tests getting the GN config flags from a Bazel rule."""
159        self.rule.set_attr('defines', ['KEY1=VAL1'])
160        self.rule.set_attr('copts', ['-frobinator'])
161        self.rule.set_attr('linkopts', ['-fizzbuzzer'])
162        self.rule.set_attr('local_defines', ['KEY2=VAL2', 'KEY3=VAL3'])
163        target = GnTarget('$build', '$src', bazel=self.rule)
164        self.assertEqual(
165            set(target.config.get('public_defines')), {'KEY1=VAL1'}
166        )
167        self.assertEqual(set(target.config.get('cflags')), {'-frobinator'})
168        self.assertEqual(set(target.config.get('ldflags')), {'-fizzbuzzer'})
169        self.assertEqual(
170            set(target.config.get('defines')), {'KEY2=VAL2', 'KEY3=VAL3'}
171        )
172
173    def test_from_bazel_rule_deps(self):
174        """Tests getting the GN dependencies from a Bazel rule."""
175        self.rule.set_attr(
176            'deps', ['//my-package:foo', '@com_corp_project//bar']
177        )
178        self.rule.set_attr(
179            'implementation_deps',
180            [
181                '//other-pkg/subdir',
182                '@com_corp_project//:top-level',
183            ],
184        )
185        target = GnTarget('$build', '$src', bazel=self.rule)
186        self.assertEqual(
187            {str(label) for label in target.public_deps},
188            {
189                '$build/my-package:foo',
190                '$repo/bar',
191            },
192        )
193        self.assertEqual(
194            {str(label) for label in target.deps},
195            {
196                '$build/other-pkg/subdir',
197                '$repo:top-level',
198            },
199        )
200
201    def test_make_relative_adjacent(self):
202        """Tests rebasing labels for a target."""
203        target = GnTarget('$build/pkg', '$src')
204        label = target.make_relative(GnLabel('$build/pkg:adjacent-config'))
205        self.assertEqual(label, ":adjacent-config")
206
207    def test_make_relative_absolute(self):
208        """Tests rebasing labels for a target."""
209        target = GnTarget('$build/pkg', '$src')
210        label = target.make_relative(GnLabel('//absolute:config'))
211        self.assertEqual(label, "//absolute:config")
212
213    def test_make_relative_descend(self):
214        """Tests rebasing labels for a target."""
215        target = GnTarget('$build/pkg', '$src')
216        label = target.make_relative(GnLabel('$build/pkg/relative:dep'))
217        self.assertEqual(label, "relative:dep")
218
219    def test_make_relative_ascend(self):
220        """Tests rebasing labels for a target."""
221        target = GnTarget('$build/pkg', '$src')
222        label = target.make_relative(GnLabel('$build/dotdot/relative'))
223        self.assertEqual(label, "../dotdot/relative")
224
225
226if __name__ == '__main__':
227    unittest.main()
228