| # Copyright 2023 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| """Tests for the pw_build.gn_target module.""" |
| |
| import unittest |
| |
| from pw_build.bazel_query import BazelRule |
| from pw_build.gn_target import GnTarget |
| from pw_build.gn_utils import GnLabel, MalformedGnError |
| |
| |
| class TestGnTarget(unittest.TestCase): |
| """Tests for gn_target.GnTarget.""" |
| |
| def setUp(self): |
| self.rule = BazelRule('//my-package:my-target', 'cc_library') |
| |
| def test_from_bazel_rule_label(self): |
| """Tests the GN target name and package derived from a Bazel rule.""" |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual(target.name(), 'my-target') |
| self.assertEqual(target.package(), 'my-package') |
| |
| def test_from_bazel_rule_type_source_set(self): |
| """Tests creating a `pw_source_set` from a Bazel rule.""" |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual(target.type(), 'pw_source_set') |
| |
| def test_from_bazel_rule_type_static_lib(self): |
| """Tests creating a `pw_static_library` from a Bazel rule.""" |
| self.rule.set_attr('linkstatic', True) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual(target.type(), 'pw_static_library') |
| |
| def test_from_bazel_rule_type_invalid(self): |
| """Tests creating an invalid type from a Bazel rule.""" |
| with self.assertRaises(MalformedGnError): |
| rule = BazelRule('//my-package:my-target', 'custom_type') |
| GnTarget('$build', '$src', bazel=rule) |
| |
| def test_from_bazel_rule_visibility(self): |
| """Tests getting the GN visibility from a Bazel rule.""" |
| self.rule.set_attr( |
| 'visibility', |
| [ |
| '//foo:__subpackages__', |
| '//foo/bar:__pkg__', |
| '//baz:__pkg__', |
| ], |
| ) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| {str(scope) for scope in target.visibility}, |
| { |
| '$build/my-package:*', |
| '$build/foo/*', |
| '$build/baz:*', |
| }, |
| ) |
| |
| def test_from_bazel_rule_visibility_public(self): |
| """Tests that 'public' overrides any other visibility""" |
| self.rule.set_attr( |
| 'visibility', |
| [ |
| '//visibility:private', |
| '//visibility:public', |
| ], |
| ) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual({str(scope) for scope in target.visibility}, {'//*'}) |
| |
| def test_from_bazel_rule_visibility_invalid(self): |
| """Tests that and invalid visibility raises an error.""" |
| self.rule.set_attr('visibility', ['invalid']) |
| with self.assertRaises(MalformedGnError): |
| GnTarget('$build', '$src', bazel=self.rule) |
| |
| def test_from_bazel_rule_testonly_unset(self): |
| """Tests that omitting `testonly` defaults it to False.""" |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertFalse(target.testonly) |
| |
| def test_from_bazel_rule_testonly_false(self): |
| """Tests setting `testonly` to False.""" |
| self.rule.set_attr('testonly', False) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertFalse(target.testonly) |
| |
| def test_from_bazel_rule_testonly_true(self): |
| """Tests setting `testonly` to True.""" |
| self.rule.set_attr('testonly', True) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertTrue(target.testonly) |
| |
| def test_from_bazel_rule_public(self): |
| """Tests getting the GN public headers from a Bazel rule.""" |
| self.rule.set_attr('hdrs', ['//foo:bar.h', '//:baz.h']) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| {str(path) for path in target.public}, |
| { |
| '$src/foo/bar.h', |
| '$src/baz.h', |
| }, |
| ) |
| |
| def test_from_bazel_rule_sources(self): |
| """Tests getting the GN source files from a Bazel rule.""" |
| self.rule.set_attr('srcs', ['//foo:bar.cc', '//:baz.cc']) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| {str(path) for path in target.sources}, |
| { |
| '$src/foo/bar.cc', |
| '$src/baz.cc', |
| }, |
| ) |
| |
| def test_from_bazel_rule_inputs(self): |
| """Tests getting the GN input files from a Bazel rule.""" |
| self.rule.set_attr( |
| 'additional_linker_inputs', ['//foo:bar.data', '//:baz.data'] |
| ) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| {str(path) for path in target.inputs}, |
| { |
| '$src/foo/bar.data', |
| '$src/baz.data', |
| }, |
| ) |
| |
| def test_from_bazel_rule_include_dirs(self): |
| """Tests getting the GN include directories from a Bazel rule.""" |
| self.rule.set_attr('includes', ['//foo']) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| set(target.config.get('include_dirs')), |
| { |
| '$src', |
| '$src/foo', |
| }, |
| ) |
| |
| def test_from_bazel_rule_configs(self): |
| """Tests getting the GN config flags from a Bazel rule.""" |
| self.rule.set_attr('defines', ['KEY1=VAL1']) |
| self.rule.set_attr('copts', ['-frobinator']) |
| self.rule.set_attr('linkopts', ['-fizzbuzzer']) |
| self.rule.set_attr('local_defines', ['KEY2=VAL2', 'KEY3=VAL3']) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| set(target.config.get('public_defines')), {'KEY1=VAL1'} |
| ) |
| self.assertEqual(set(target.config.get('cflags')), {'-frobinator'}) |
| self.assertEqual(set(target.config.get('ldflags')), {'-fizzbuzzer'}) |
| self.assertEqual( |
| set(target.config.get('defines')), {'KEY2=VAL2', 'KEY3=VAL3'} |
| ) |
| |
| def test_from_bazel_rule_deps(self): |
| """Tests getting the GN dependencies from a Bazel rule.""" |
| self.rule.set_attr( |
| 'deps', ['//my-package:foo', '@com_corp_project//bar'] |
| ) |
| self.rule.set_attr( |
| 'implementation_deps', |
| [ |
| '//other-pkg/subdir', |
| '@com_corp_project//:top-level', |
| ], |
| ) |
| target = GnTarget('$build', '$src', bazel=self.rule) |
| self.assertEqual( |
| {str(label) for label in target.public_deps}, |
| { |
| '$build/my-package:foo', |
| '$repo/bar', |
| }, |
| ) |
| self.assertEqual( |
| {str(label) for label in target.deps}, |
| { |
| '$build/other-pkg/subdir', |
| '$repo:top-level', |
| }, |
| ) |
| |
| def test_make_relative_adjacent(self): |
| """Tests rebasing labels for a target.""" |
| target = GnTarget('$build/pkg', '$src') |
| label = target.make_relative(GnLabel('$build/pkg:adjacent-config')) |
| self.assertEqual(label, ":adjacent-config") |
| |
| def test_make_relative_absolute(self): |
| """Tests rebasing labels for a target.""" |
| target = GnTarget('$build/pkg', '$src') |
| label = target.make_relative(GnLabel('//absolute:config')) |
| self.assertEqual(label, "//absolute:config") |
| |
| def test_make_relative_descend(self): |
| """Tests rebasing labels for a target.""" |
| target = GnTarget('$build/pkg', '$src') |
| label = target.make_relative(GnLabel('$build/pkg/relative:dep')) |
| self.assertEqual(label, "relative:dep") |
| |
| def test_make_relative_ascend(self): |
| """Tests rebasing labels for a target.""" |
| target = GnTarget('$build/pkg', '$src') |
| label = target.make_relative(GnLabel('$build/dotdot/relative')) |
| self.assertEqual(label, "../dotdot/relative") |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |