• 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_utils module."""
15
16import unittest
17
18from pw_build.gn_utils import GnLabel, GnPath, GnVisibility
19
20
21class TestGnPath(unittest.TestCase):
22    """Tests for gn_utils.GnPath."""
23
24    def test_from_bazel(self):
25        """Tests creating a GN path from a Bazel string."""
26        path = GnPath('$dir_3p_test', bazel='//foo:bar/baz.txt')
27        self.assertEqual(path.file(), 'baz.txt')
28        self.assertEqual(path.name(), 'baz')
29        self.assertEqual(path.extension(), 'txt')
30        self.assertEqual(path.dir(), '$dir_3p_test/foo/bar')
31
32    def test_from_gn(self):
33        """Tests creating a GN path from a GN string."""
34        path = GnPath('$dir_3p_test', gn='foo/bar/baz.txt')
35        self.assertEqual(path.file(), 'baz.txt')
36        self.assertEqual(path.name(), 'baz')
37        self.assertEqual(path.extension(), 'txt')
38        self.assertEqual(path.dir(), '$dir_3p_test/foo/bar')
39
40    def test_from_str(self):
41        """Tests creating a GN path from a raw string."""
42        path = GnPath('$dir_3p_test/foo/bar/baz.txt')
43        self.assertEqual(path.file(), 'baz.txt')
44        self.assertEqual(path.name(), 'baz')
45        self.assertEqual(path.extension(), 'txt')
46        self.assertEqual(path.dir(), '$dir_3p_test/foo/bar')
47
48
49class TestGnLabel(unittest.TestCase):
50    """Tests for gn_utils.GnLabel."""
51
52    def test_from_bazel_with_name(self):
53        """Tests creating a GN label from a Bazel string including a name."""
54        label = GnLabel('$dir_3p/test', bazel='//foo/bar:baz')
55        self.assertEqual(label.name(), 'baz')
56        self.assertEqual(label.dir(), '$dir_3p/test/foo/bar')
57        self.assertEqual(label.no_toolchain(), '$dir_3p/test/foo/bar:baz')
58        self.assertEqual(
59            label.with_toolchain(),
60            '$dir_3p/test/foo/bar:baz(default_toolchain)',
61        )
62        self.assertFalse(label.repo())
63
64    def test_from_bazel_without_name(self):
65        """Tests creating a GN label from a Bazel string without a name."""
66        label = GnLabel('$dir_3p/test', bazel='//foo/bar')
67        self.assertEqual(label.name(), 'bar')
68        self.assertEqual(label.dir(), '$dir_3p/test/foo/bar')
69        self.assertEqual(label.no_toolchain(), '$dir_3p/test/foo/bar')
70        self.assertEqual(
71            label.with_toolchain(), '$dir_3p/test/foo/bar(default_toolchain)'
72        )
73        self.assertFalse(label.repo())
74
75    def test_from_bazel_with_external_repo(self):
76        """Tests creating a GN label from a Bazel string with a repo."""
77        label = GnLabel('$dir_3p/test', bazel='@com_corp_project//foo/bar:baz')
78        self.assertEqual(label.name(), 'baz')
79        self.assertEqual(label.dir(), '$repo/foo/bar')
80        self.assertEqual(label.no_toolchain(), '$repo/foo/bar:baz')
81        self.assertEqual(
82            label.with_toolchain(),
83            '$repo/foo/bar:baz(default_toolchain)',
84        )
85        self.assertEqual(label.repo(), 'com_corp_project')
86
87    def test_from_gn_absolute(self):
88        """Tests creating a GN label from an absolute GN label string."""
89        label = GnLabel('$dir_3p/test', gn='//foo/bar:baz')
90        self.assertEqual(label.name(), 'baz')
91        self.assertEqual(label.dir(), '//foo/bar')
92        self.assertEqual(label.no_toolchain(), '//foo/bar:baz')
93        self.assertEqual(
94            label.with_toolchain(), '//foo/bar:baz(default_toolchain)'
95        )
96
97    def test_from_gn_with_variable(self):
98        """Tests creating a GN label from a GN string with a variable."""
99        label = GnLabel('$dir_3p/test', gn='$dir_pw_build/foo/bar')
100        self.assertEqual(label.name(), 'bar')
101        self.assertEqual(label.dir(), '$dir_pw_build/foo/bar')
102        self.assertEqual(label.no_toolchain(), '$dir_pw_build/foo/bar')
103        self.assertEqual(
104            label.with_toolchain(), '$dir_pw_build/foo/bar(default_toolchain)'
105        )
106
107    def test_from_gn_relative(self):
108        """Tests creating a GN label from a relative GN label string."""
109        label = GnLabel('$dir_3p/test', gn='foo/bar')
110        self.assertEqual(label.name(), 'bar')
111        self.assertEqual(label.dir(), '$dir_3p/test/foo/bar')
112        self.assertEqual(label.no_toolchain(), '$dir_3p/test/foo/bar')
113        self.assertEqual(
114            label.with_toolchain(), '$dir_3p/test/foo/bar(default_toolchain)'
115        )
116
117    def test_from_gn_with_dotdot(self):
118        """Tests creating a GN label from a GN string that ascends the tree."""
119        label = GnLabel('$dir_3p/test', gn='../../../foo/../bar')
120        self.assertEqual(label.name(), 'bar')
121        self.assertEqual(label.dir(), '../bar')
122        self.assertEqual(label.no_toolchain(), '../bar')
123        self.assertEqual(label.with_toolchain(), '../bar(default_toolchain)')
124
125    def test_from_str_with_name(self):
126        """Tests creating a GN label from a raw string with a target name."""
127        label = GnLabel('$dir_3p/test/foo/bar:baz')
128        self.assertEqual(label.name(), 'baz')
129        self.assertEqual(label.dir(), '$dir_3p/test/foo/bar')
130        self.assertEqual(label.no_toolchain(), '$dir_3p/test/foo/bar:baz')
131        self.assertEqual(
132            label.with_toolchain(),
133            '$dir_3p/test/foo/bar:baz(default_toolchain)',
134        )
135
136    def test_from_str_without_name(self):
137        """Tests creating a GN label from a raw string without a name."""
138        label = GnLabel('$dir_3p/test/foo/bar')
139        self.assertEqual(label.name(), 'bar')
140        self.assertEqual(label.dir(), '$dir_3p/test/foo/bar')
141        self.assertEqual(label.no_toolchain(), '$dir_3p/test/foo/bar')
142        self.assertEqual(
143            label.with_toolchain(), '$dir_3p/test/foo/bar(default_toolchain)'
144        )
145
146    def test_relative_to_with_name(self):
147        """Tests creating a relative label from a GN label with a name."""
148        label = GnLabel('$dir_3p/foo/bar:baz')
149        self.assertEqual(label.relative_to('$dir_3p'), 'foo/bar:baz')
150        self.assertEqual(label.relative_to('$dir_3p/foo'), 'bar:baz')
151        self.assertEqual(label.relative_to('$dir_3p/foo/bar'), ':baz')
152        self.assertEqual(label.relative_to('$dir_3p/bar'), '../foo/bar:baz')
153        self.assertEqual(label.relative_to('//'), '$dir_3p/foo/bar:baz')
154        self.assertEqual(label.relative_to('$other'), '$dir_3p/foo/bar:baz')
155
156    def test_relative_to_without_name(self):
157        """Tests creating a relative label from a GN label without a name."""
158        label = GnLabel('$dir_3p/foo/bar')
159        self.assertEqual(label.relative_to('$dir_3p/foo/bar'), ':bar')
160
161    def test_relative_to_absolute_with_name(self):
162        """Tests creating a relative label from a named absolute GN label."""
163        label = GnLabel('//foo/bar:baz')
164        self.assertEqual(label.relative_to('//'), 'foo/bar:baz')
165        self.assertEqual(label.relative_to('//bar/baz'), '../../foo/bar:baz')
166
167    def test_relative_to_absolute_without_name(self):
168        """Tests creating a relative label from an unnamed absolute GN label."""
169        label = GnLabel('//foo/bar')
170        self.assertEqual(label.relative_to('//foo/bar'), ':bar')
171
172    def test_resolve_repo_without_repo(self):
173        """Tests trying to set the repo placeholder for a local label."""
174        label = GnLabel('$dir_3p/test', bazel='//foo/bar:baz')
175        self.assertEqual(str(label), '$dir_3p/test/foo/bar:baz')
176        self.assertFalse(label.repo())
177        label.resolve_repo('my-external_repo')
178        self.assertEqual(str(label), '$dir_3p/test/foo/bar:baz')
179        self.assertFalse(label.repo())
180
181    def test_resolve_repowith_repo(self):
182        """Tests setting the repo placeholder."""
183        label = GnLabel('$dir_3p/test', bazel='@com_corp_project//foo/bar:baz')
184        self.assertEqual(str(label), '$repo/foo/bar:baz')
185        self.assertEqual(label.repo(), 'com_corp_project')
186        label.resolve_repo('my-external_repo')
187        self.assertEqual(
188            str(label), '$dir_pw_third_party/my-external_repo/foo/bar:baz'
189        )
190        self.assertEqual(label.repo(), 'com_corp_project')
191
192
193class TestGnVisibility(unittest.TestCase):
194    """Tests for gn_utils.GnVisibility."""
195
196    def test_from_bazel_public(self):
197        """Tests creating a public visibility scope from a Bazel string."""
198        scope = GnVisibility(
199            '$dir_3p/test', '$dir_3p/test/foo', bazel='//visibility:public'
200        )
201        self.assertEqual(str(scope), '//*')
202
203    def test_from_bazel_private(self):
204        """Tests creating a private visibility scope from a Bazel string."""
205        scope = GnVisibility(
206            '$dir_3p/test', '$dir_3p/test/foo', bazel='//visibility:private'
207        )
208        self.assertEqual(str(scope), '$dir_3p/test/foo:*')
209
210    def test_from_bazel_same_subpackage(self):
211        """Tests creating a visibility for the same subpackage."""
212        scope = GnVisibility(
213            '$dir_3p/test', '$dir_3p/test/foo', bazel='//foo:__subpackages__'
214        )
215        self.assertEqual(str(scope), '$dir_3p/test/foo/*')
216
217    def test_from_bazel_same_package(self):
218        """Tests creating a visibility for the same package."""
219        scope = GnVisibility(
220            '$dir_3p/test', '$dir_3p/test/foo', bazel='//foo:__pkg__'
221        )
222        self.assertEqual(str(scope), '$dir_3p/test/foo:*')
223
224    def test_from_bazel_other_subpackages(self):
225        """Tests creating a visibility for a different subpackage."""
226        scope = GnVisibility(
227            '$dir_3p/test', '$dir_3p/test/foo', bazel='//bar:__subpackages__'
228        )
229        self.assertEqual(str(scope), '$dir_3p/test/bar/*')
230
231    def test_from_bazel_other_package(self):
232        """Tests creating a visibility for a different package."""
233        scope = GnVisibility(
234            '$dir_3p/test', '$dir_3p/test/foo', bazel='//bar:__pkg__'
235        )
236        self.assertEqual(str(scope), '$dir_3p/test/bar:*')
237
238    def test_from_gn_relative(self):
239        """Tests creating a visibility from a relative GN string."""
240        scope = GnVisibility('$dir_3p/test', '$dir_3p/test/foo', gn=':*')
241        self.assertEqual(str(scope), '$dir_3p/test/foo:*')
242
243    def test_from_gn_with_dotdot(self):
244        """Tests creating a visibility from a string that ascends the tree."""
245        scope = GnVisibility('$dir_3p/test', '$dir_3p/test/foo', gn='../*')
246        self.assertEqual(str(scope), '$dir_3p/test/*')
247
248    def test_from_gn_absolute(self):
249        """Tests creating a visibility from an absolute GN string."""
250        scope = GnVisibility('$dir_3p/test', '$dir_3p/test/foo', gn='$dir_3p/*')
251        self.assertEqual(str(scope), '$dir_3p/*')
252
253    def test_from_str(self):
254        """Tests creating a visibility from a raw string."""
255        scope = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:*')
256        self.assertEqual(str(scope), '$dir_3p/test/foo/bar:*')
257
258    def test_within_equal_discrete(self):
259        """Tests that two equal, discrete visibilities are within each other."""
260        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:baz')
261        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:baz')
262        self.assertTrue(scope1.within(scope2))
263        self.assertTrue(scope2.within(scope1))
264
265    def test_within_equal_globbed(self):
266        """Tests that two equal, globbed visibilities are within each other."""
267        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:*')
268        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:*')
269        self.assertTrue(scope1.within(scope2))
270        self.assertTrue(scope2.within(scope1))
271
272    def test_within_equal_subtree(self):
273        """Tests that two equal, subtree visibilities are within each other."""
274        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar/*')
275        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar/*')
276        self.assertTrue(scope1.within(scope2))
277        self.assertTrue(scope2.within(scope1))
278
279    def test_within_not_equal_both_discrete(self):
280        """Tests that two unrelated visibilities are not within each other."""
281        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:baz')
282        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:qux')
283        self.assertFalse(scope1.within(scope2))
284        self.assertFalse(scope2.within(scope1))
285
286    def test_within_not_equal_both_globbed(self):
287        """Tests that two unrelated visibilities are not within each other."""
288        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:*')
289        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/baz:*')
290        self.assertFalse(scope1.within(scope2))
291        self.assertFalse(scope2.within(scope1))
292
293    def test_within_not_equal_both_subtree(self):
294        """Tests that two unrelated visibilities are not within each other."""
295        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar/*')
296        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/baz/*')
297        self.assertFalse(scope1.within(scope2))
298        self.assertFalse(scope2.within(scope1))
299
300    def test_within_subset_discrete_in_globbed(self):
301        """Tests a discrete visibility that is within a globbed one."""
302        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:baz')
303        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:*')
304        self.assertTrue(scope1.within(scope2))
305        self.assertFalse(scope2.within(scope1))
306
307    def test_within_subset_discrete_in_subtree(self):
308        """Tests a discrete visibility that is within a subtree."""
309        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:baz')
310        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/*')
311        public_scope = GnVisibility('$dir_3p/test', '//*')
312        self.assertTrue(scope1.within(scope2))
313        self.assertTrue(scope1.within(public_scope))
314        self.assertFalse(scope2.within(scope1))
315        self.assertFalse(public_scope.within(scope1))
316
317    def test_within_subset_globbed_in_subtree(self):
318        """Tests a globbed visibility that is within a subtree."""
319        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar:*')
320        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/*')
321        public_scope = GnVisibility('$dir_3p/test', '//*')
322        self.assertTrue(scope1.within(scope2))
323        self.assertTrue(scope1.within(public_scope))
324        self.assertFalse(scope2.within(scope1))
325        self.assertFalse(public_scope.within(scope1))
326
327    def test_within_subset_subtree_in_subtree(self):
328        """Tests a subtree visibility that is within a subtree."""
329        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/bar/*')
330        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/*')
331        public_scope = GnVisibility('$dir_3p/test', '//*')
332        self.assertTrue(scope1.within(scope2))
333        self.assertTrue(scope1.within(public_scope))
334        self.assertFalse(scope2.within(scope1))
335        self.assertFalse(public_scope.within(scope1))
336
337    def test_within_disjoint(self):
338        """Tests that disjoint visibilities are not within each other."""
339        scope1 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo:bar')
340        scope2 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/baz:*')
341        scope3 = GnVisibility('$dir_3p/test', '$dir_3p/test/foo/qux/*')
342        self.assertFalse(scope1.within(scope2))
343        self.assertFalse(scope1.within(scope3))
344        self.assertFalse(scope2.within(scope1))
345        self.assertFalse(scope2.within(scope3))
346        self.assertFalse(scope3.within(scope1))
347        self.assertFalse(scope3.within(scope2))
348
349
350if __name__ == '__main__':
351    unittest.main()
352