From af9cfdb395f458aaca81b4e056495847cc1f1c68 Mon Sep 17 00:00:00 2001 From: Dale Myers Date: Fri, 1 Dec 2023 10:17:20 +0000 Subject: [PATCH] Add extra test cases for groups that don't have paths --- .../collateral/One.xcodeproj/project.pbxproj | 11 +++ tests/test_basics.py | 96 ++++++++++++------- xcodeproj/pathobjects.py | 1 + 3 files changed, 76 insertions(+), 32 deletions(-) diff --git a/tests/collateral/One.xcodeproj/project.pbxproj b/tests/collateral/One.xcodeproj/project.pbxproj index 5dc5c68..2d94c5d 100644 --- a/tests/collateral/One.xcodeproj/project.pbxproj +++ b/tests/collateral/One.xcodeproj/project.pbxproj @@ -82,6 +82,8 @@ DD62471C25AF30BD0081F68F /* CLJTest-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CLJTest-Bridging-Header.h"; sourceTree = ""; }; DD62471D25AF30BE0081F68F /* test.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = test.m; sourceTree = ""; }; DD624D1825B05ED30081F68F /* CocoaLumberjack.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = CocoaLumberjack.xcframework; path = Carthage/Build/CocoaLumberjack.xcframework; sourceTree = SOURCE_ROOT; }; + DD624D1825B05ED300899999 /* Foo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Foo.swift; sourceTree = ""; }; + 99999D1825B05ED300899999 /* Bar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bar.swift; sourceTree = ""; }; DD624D1D25B05EED0081F68F /* wat.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = wat.app; sourceTree = BUILT_PRODUCTS_DIR; }; DD624D2025B05EED0081F68F /* wat WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "wat WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; DD624D2625B05EED0081F68F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; @@ -163,6 +165,7 @@ DD624D3325B05EEE0081F68F /* wat WatchKit Extension */, DD74C32725AF302A00C4A922 /* Products */, DD62471925AF30980081F68F /* Frameworks */, + DD74C32825AF302A00C99999 /* FakeFolder */, ); sourceTree = ""; }; @@ -194,6 +197,14 @@ path = CLJTest; sourceTree = ""; }; + DD74C32825AF302A00C99999 /* FakeFolder */ = { + isa = PBXGroup; + children = ( + DD624D1825B05ED300899999 /* Foo.swift */, + 99999D1825B05ED300899999 /* Bar.swift */, + ); + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ diff --git a/tests/test_basics.py b/tests/test_basics.py index bb34322..c1bda90 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -60,14 +60,14 @@ def test_targets(one: xcodeproj.XcodeProject) -> None: targets = one.targets() assert len(targets) == 4 - watch_extension = targets[0] - assert watch_extension.product_name == "wat WatchKit Extension" - assert watch_extension.object_key == "DD624D2E25B05EEE0081F68F" - - cljtest = targets[1] + cljtest = targets[0] assert cljtest.product_name == "CLJTest" assert cljtest.object_key == "DD74C32525AF302A00C4A922" + watch_extension = targets[1] + assert watch_extension.product_name == "wat WatchKit Extension" + assert watch_extension.object_key == "DD624D2E25B05EEE0081F68F" + watch_app = targets[2] assert watch_app.product_name == "wat WatchKit App" assert watch_app.object_key == "DD624D1F25B05EED0081F68F" @@ -98,7 +98,7 @@ def test_get_paths(one: xcodeproj.XcodeProject, two: xcodeproj.XcodeProject) -> :param two: A different project """ - expected = [ + expected_paths = [ "wat WatchKit App/Info.plist", "wat WatchKit Extension/ComplicationController.swift", "wat WatchKit Extension/InterfaceController.swift", @@ -123,20 +123,27 @@ def test_get_paths(one: xcodeproj.XcodeProject, two: xcodeproj.XcodeProject) -> "wat.app", "CLJTest/Base.lproj/Main.storyboard", "wat WatchKit App.app", + "Foo.swift", + "Bar.swift", ] - for index, item in enumerate(one.fetch_type(xcodeproj.PBXFileReference).values()): - assert item.relative_path() == expected[index] - absolute_path = item.absolute_path() + expected_paths.sort() + + found_items = list(one.fetch_type(xcodeproj.PBXFileReference).values()) + found_items.sort(key=lambda x: x.relative_path() or "") + + for expected, found in zip(expected_paths, found_items): + assert expected == found.relative_path() + absolute_path = found.absolute_path() assert absolute_path is not None if absolute_path.startswith("$(BUILT_PRODUCTS_DIR)/"): - assert absolute_path == "$(BUILT_PRODUCTS_DIR)/" + expected[index] + assert absolute_path == "$(BUILT_PRODUCTS_DIR)/" + expected else: - assert absolute_path == os.path.join(COLLATERAL_PATH, expected[index]) + assert absolute_path == os.path.join(COLLATERAL_PATH, expected) - groups = [ + groups: list[str | None] = [ "wat WatchKit App", None, "CLJTest", @@ -147,14 +154,19 @@ def test_get_paths(one: xcodeproj.XcodeProject, two: xcodeproj.XcodeProject) -> None, "wat WatchKit Extension", "wat WatchKit Extension", + None, # FakeFolder ] - for index, group in enumerate(one.fetch_type(xcodeproj.PBXGroup).values()): - value = groups[index] - assert group.relative_path() == value - if value is None: + groups.sort(key=lambda x: x or "") + + found_groups = list(one.fetch_type(xcodeproj.PBXGroup).values()) + found_groups.sort(key=lambda x: x.relative_path() or "") + + for expected_group, found_group in zip(groups, found_groups): + assert found_group.relative_path() == expected_group + if expected_group is None: continue - assert group.absolute_path() == os.path.join(COLLATERAL_PATH, value) + assert found_group.absolute_path() == os.path.join(COLLATERAL_PATH, expected_group) for index, version_group in enumerate(two.fetch_type(xcodeproj.XCVersionGroup).values()): if index == 0: @@ -167,17 +179,15 @@ def test_get_paths(one: xcodeproj.XcodeProject, two: xcodeproj.XcodeProject) -> assert version_group.absolute_path() is None -def test_get_paths_prepopulated(one: xcodeproj.XcodeProject, two: xcodeproj.XcodeProject) -> None: +def test_get_paths_prepopulated_1(one: xcodeproj.XcodeProject) -> None: """Test that path determination works :param one: The project - :param two: A different project """ one.populate_paths() - two.populate_paths() - expected = [ + expected_paths = [ "wat WatchKit App/Info.plist", "wat WatchKit Extension/ComplicationController.swift", "wat WatchKit Extension/InterfaceController.swift", @@ -202,20 +212,27 @@ def test_get_paths_prepopulated(one: xcodeproj.XcodeProject, two: xcodeproj.Xcod "wat.app", "CLJTest/Base.lproj/Main.storyboard", "wat WatchKit App.app", + "Foo.swift", + "Bar.swift", ] - for index, item in enumerate(one.fetch_type(xcodeproj.PBXFileReference).values()): - assert item.relative_path() == expected[index] - absolute_path = item.absolute_path() + expected_paths.sort() + + found_items = list(one.fetch_type(xcodeproj.PBXFileReference).values()) + found_items.sort(key=lambda x: x.relative_path() or "") + + for expected, found in zip(expected_paths, found_items): + assert expected == found.relative_path() + absolute_path = found.absolute_path() assert absolute_path is not None if absolute_path.startswith("$(BUILT_PRODUCTS_DIR)/"): - assert absolute_path == "$(BUILT_PRODUCTS_DIR)/" + expected[index] + assert absolute_path == "$(BUILT_PRODUCTS_DIR)/" + expected else: - assert absolute_path == os.path.join(COLLATERAL_PATH, expected[index]) + assert absolute_path == os.path.join(COLLATERAL_PATH, expected) - groups = [ + groups: list[str | None] = [ "wat WatchKit App", None, "CLJTest", @@ -226,14 +243,28 @@ def test_get_paths_prepopulated(one: xcodeproj.XcodeProject, two: xcodeproj.Xcod None, "wat WatchKit Extension", "wat WatchKit Extension", + None, # FakeFolder ] - for index, group in enumerate(one.fetch_type(xcodeproj.PBXGroup).values()): - value = groups[index] - assert group.relative_path() == value - if value is None: + groups.sort(key=lambda x: x or "") + + found_groups = list(one.fetch_type(xcodeproj.PBXGroup).values()) + found_groups.sort(key=lambda x: x.relative_path() or "") + + for expected_group, found_group in zip(groups, found_groups): + assert found_group.relative_path() == expected_group + if expected_group is None: continue - assert group.absolute_path() == os.path.join(COLLATERAL_PATH, value) + assert found_group.absolute_path() == os.path.join(COLLATERAL_PATH, expected_group) + + +def test_get_paths_prepopulated_2(two: xcodeproj.XcodeProject) -> None: + """Test that path determination works + + :param two: A project + """ + + two.populate_paths() for index, version_group in enumerate(two.fetch_type(xcodeproj.XCVersionGroup).values()): if index == 0: @@ -328,6 +359,7 @@ def test_file_paths(one: xcodeproj.XcodeProject) -> None: "DD74C31D25AF302A00C4A922", # Root of the project "DD74C32725AF302A00C4A922", # Products "DD62471925AF30980081F68F", # Frameworks + "DD74C32825AF302A00C99999", # FakeFolder ]: continue diff --git a/xcodeproj/pathobjects.py b/xcodeproj/pathobjects.py index 7cceb46..2d2e187 100755 --- a/xcodeproj/pathobjects.py +++ b/xcodeproj/pathobjects.py @@ -94,6 +94,7 @@ def relative_path(self) -> Optional[str]: parent = self.parent_group() if not parent: + # If there is no parent, then we are in the root group. return None parent_path = parent.relative_path()