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