diff --git a/Sources/XcodeGenKit/PBXProjGenerator.swift b/Sources/XcodeGenKit/PBXProjGenerator.swift index 9c3292ac..661c1d68 100644 --- a/Sources/XcodeGenKit/PBXProjGenerator.swift +++ b/Sources/XcodeGenKit/PBXProjGenerator.swift @@ -665,8 +665,13 @@ public class PBXProjGenerator { } let sourcesBuildPhaseFiles = getBuildFilesForPhase(.sources) - let sourcesBuildPhase = addObject(PBXSourcesBuildPhase(files: sourcesBuildPhaseFiles)) - buildPhases.append(sourcesBuildPhase) + // Sticker packs should not include a compile sources build phase as they + // are purely based on a set of image files, and nothing else. + let shouldSkipSourcesBuildPhase = sourcesBuildPhaseFiles.isEmpty && target.type == .stickerPack + if !shouldSkipSourcesBuildPhase { + let sourcesBuildPhase = addObject(PBXSourcesBuildPhase(files: sourcesBuildPhaseFiles)) + buildPhases.append(sourcesBuildPhase) + } buildPhases += try target.postCompileScripts.map { try generateBuildScript(targetName: target.name, buildScript: $0) } diff --git a/Tests/Fixtures/TestProject/IMessage Stickers/Assets.xcassets/AppIcon.appiconset/Contents.json b/Tests/Fixtures/TestProject/IMessage Stickers/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d8db8d65 --- /dev/null +++ b/Tests/Fixtures/TestProject/IMessage Stickers/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Tests/Fixtures/TestProject/IMessage Stickers/Assets.xcassets/Contents.json b/Tests/Fixtures/TestProject/IMessage Stickers/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/Tests/Fixtures/TestProject/IMessage Stickers/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Tests/Fixtures/TestProject/IMessage Stickers/Info.plist b/Tests/Fixtures/TestProject/IMessage Stickers/Info.plist new file mode 100644 index 00000000..4222ac2d --- /dev/null +++ b/Tests/Fixtures/TestProject/IMessage Stickers/Info.plist @@ -0,0 +1,43 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj index e216c5ef..dc0d55c3 100644 --- a/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj +++ b/Tests/Fixtures/TestProject/Project.xcodeproj/project.pbxproj @@ -37,6 +37,7 @@ 262B4F15CB0780B21C37D89F5EA9FE80 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A58A16491CDDF968B0D56DE7EB96D92 /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; 29A79F030DD325754FD2C82C4A6E0AE6 /* Result.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C5AC2545AE4D4F7F44E2E9B53F03FF0 /* Result.framework */; }; 2DE309130A6F5A7E2E7E13169357C316 /* MyFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A58A16491CDDF968B0D56DE7EB96D92 /* MyFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2DFBC735559B5AC7702C7DD1F54FBFFE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9390121B4ECBB1B796C7CBBDD32C4DD4 /* Assets.xcassets */; }; 319B977623307E83E948E9E4CEBB432E /* StaticLibrary_ObjC.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 5A2B916A11DCC2565241359FD0114B0C /* StaticLibrary_ObjC.h */; }; 3474A5D469F41494C4CB871D75C77106 /* module.modulemap in CopyFiles */ = {isa = PBXBuildFile; fileRef = F2950763C4C568CC85021D185A35C1FB /* module.modulemap */; }; 36152E299B36BCA0F25AD1FC9B002835 /* MoreUnder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA8718C7CD3BE86D9B1F51203A548A51 /* MoreUnder.swift */; }; @@ -434,6 +435,7 @@ 4BF4D16042A80576D259160C97AD2C2E /* Model 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Model 3.xcdatamodel"; sourceTree = ""; }; 4D0BF47DF71A6DBA33ED23FD22D023EF /* StaticLibrary_ObjC.a */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = archive.ar; path = StaticLibrary_ObjC.a; sourceTree = BUILT_PRODUCTS_DIR; }; 5116B3B58070BCD09F1487BAFC210EE0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 564E35E83C95F5591345B7722A59AA4E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57FF8864B8EBAB5777DC12E62D66732F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 587B9E9A3533E965CA602B763210583F /* TestProjectUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestProjectUITests.swift; sourceTree = ""; }; 5A2B916A11DCC2565241359FD0114B0C /* StaticLibrary_ObjC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StaticLibrary_ObjC.h; sourceTree = ""; }; @@ -456,6 +458,7 @@ 814822136AF3C64428D69DD62246E8A2 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 8A9274BE42A03DC5DA1FAD04992ED6E3 /* Framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 8CAF6C55B555E3E1352645B630CCB23E /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; + 9390121B4ECBB1B796C7CBBDD32C4DD4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 9A87A926D563773658FB87FEEE4DD132 /* iMessageApp.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = iMessageApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9F27382DD66E26C059E26EFE8D6BEF4D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; A0DC40025AB59B688E758829FB7EDB95 /* Framework2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Framework2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -470,6 +473,7 @@ BA040F1F7D6CA08878323A551349F18D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; BB178D03E75929F3F5B10C56838882EC /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Result.framework; sourceTree = ""; }; C2F3574CCEF023755DDB1A06C6FE315C /* Mintfile */ = {isa = PBXFileReference; path = Mintfile; sourceTree = ""; }; + C53ACB2962FED621389C36A2E1AE6E28 /* iMessageStickersExtension.appex */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "wrapper.app-extension"; path = iMessageStickersExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; C5ABEA2284F13483EFDF7C0E050F0450 /* MessagesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = ""; }; C7809CE9FE9852C2AA87ACE57B5DEF9E /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.module; path = module.modulemap; sourceTree = ""; }; C934C1F7A68CCD0AB6B384782470EE7B /* NotificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationController.swift; sourceTree = ""; }; @@ -641,6 +645,7 @@ 1A57D1EE1FBC13598F6B5CB018E7D348 /* Framework */, B370CE9C04C41EBC52D4E4EA1F3EB767 /* iMessage */, 0A989C35EEBD58B9B98C41A75CE9CE00 /* iMessage MessagesExtension */, + D1B8D50CE1D32597CD569AB52E84F9C2 /* iMessage Stickers */, 9EDF27BB8A57733E6639D36D66958B76 /* Resources */, 9DB22CB08CFAA455518700DBA5CAD7DE /* StandaloneFiles */, BDA839814AF73F01F771051894A708E8 /* StaticLibrary_ObjC */, @@ -778,6 +783,7 @@ AB055761199DF36DB0C629A608A4EF3A /* Framework2.framework */, 9A87A926D563773658FB87FEEE4DD132 /* iMessageApp.app */, D629E142AB87C681D4EC90F7106F7299 /* iMessageExtension.appex */, + C53ACB2962FED621389C36A2E1AE6E28 /* iMessageStickersExtension.appex */, 4D0BF47DF71A6DBA33ED23FD22D023EF /* StaticLibrary_ObjC.a */, 056A43A09CE7E88D578696D83330E45F /* StaticLibrary_ObjC.a */, 1313F043F19B484A5046E0748579814C /* StaticLibrary_ObjC.a */, @@ -825,6 +831,15 @@ path = StaticLibrary_Swift; sourceTree = ""; }; + D1B8D50CE1D32597CD569AB52E84F9C2 /* iMessage Stickers */ = { + isa = PBXGroup; + children = ( + 9390121B4ECBB1B796C7CBBDD32C4DD4 /* Assets.xcassets */, + 564E35E83C95F5591345B7722A59AA4E /* Info.plist */, + ); + path = "iMessage Stickers"; + sourceTree = ""; + }; D557819B1EE5B42A0A3DD4D1F3D982C4 /* tvOS */ = { isa = PBXGroup; children = ( @@ -1029,6 +1044,21 @@ productReference = 4D0BF47DF71A6DBA33ED23FD22D023EF /* StaticLibrary_ObjC.a */; productType = "com.apple.product-type.library.static"; }; + 192C574D74079A99AF1AD0B16DEF8F76 /* iMessageStickersExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = B40D2F785317445D9A9C8C122B3BFFD3 /* Build configuration list for PBXNativeTarget "iMessageStickersExtension" */; + buildPhases = ( + AA12B5909FEE45016F469C78D3F4941B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iMessageStickersExtension; + productName = iMessageStickersExtension; + productReference = C53ACB2962FED621389C36A2E1AE6E28 /* iMessageStickersExtension.appex */; + productType = "com.apple.product-type.app-extension.messages-sticker-pack"; + }; 19BFB84599B0AA1275A9662DCB5C0E50 /* StaticLibrary_Swift */ = { isa = PBXNativeTarget; buildConfigurationList = 4A036BD16A0E9D22AE065AC9D8232B5B /* Build configuration list for PBXNativeTarget "StaticLibrary_Swift" */; @@ -1412,6 +1442,7 @@ E7815F2F0D9CDECF9185AAF3A6B474C1 /* XPC Service */, 834F55973F05AC8A18144DB04FF6F2C7 /* iMessageApp */, 1C26A6A0BC446191F311D470FDFF54F8 /* iMessageExtension */, + 192C574D74079A99AF1AD0B16DEF8F76 /* iMessageStickersExtension */, ); }; /* End PBXProject section */ @@ -1468,6 +1499,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + AA12B5909FEE45016F469C78D3F4941B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DFBC735559B5AC7702C7DD1F54FBFFE /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; B7B71FA7D279029BF7A7FC7C08E41BB0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -2993,6 +3032,17 @@ }; name = "Production Debug"; }; + 59416DBF97224D8A1B28D6102CE1A723 /* Production Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = "IMessage Stickers/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.project.iMessageStickersExtension; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Production Release"; + }; 5A9C67C1F423247AE1541F63C53C88B5 /* Test Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3557,6 +3607,17 @@ }; name = "Production Release"; }; + 9E0CC963DE7E2ED71A4C16C1DC243AD9 /* Staging Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = "IMessage Stickers/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.project.iMessageStickersExtension; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Staging Debug"; + }; 9E38571B33C3CE5CA10C8452AE897DF8 /* Staging Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3604,6 +3665,17 @@ }; name = "Test Debug"; }; + A0C50DBBF4AC5D30C92B19F78B9CC141 /* Test Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = "IMessage Stickers/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.project.iMessageStickersExtension; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Test Release"; + }; A2EBD902E6DE2B2BD12C4484D36B6B76 /* Production Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3903,6 +3975,17 @@ }; name = "Production Debug"; }; + B4297CD61108CE066C29984455AA0CE0 /* Staging Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = "IMessage Stickers/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.project.iMessageStickersExtension; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Staging Release"; + }; B928E061A126AC8D17D81D1E4DC11629 /* Staging Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3962,6 +4045,17 @@ }; name = "Test Release"; }; + BF2F04729CC0602591655B251D13DD47 /* Production Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = "IMessage Stickers/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.project.iMessageStickersExtension; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Production Debug"; + }; C0D5765142C68AF68B954B3F748538C2 /* Production Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -4718,6 +4812,17 @@ }; name = "Staging Release"; }; + FC4A8130B924FC04E9190AB603D97A24 /* Test Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = "IMessage Stickers/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.project.iMessageStickersExtension; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Test Debug"; + }; FE029D76C57D0661E4B8F13B132169CA /* Staging Release */ = { isa = XCBuildConfiguration; buildSettings = { @@ -4987,6 +5092,19 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = ""; }; + B40D2F785317445D9A9C8C122B3BFFD3 /* Build configuration list for PBXNativeTarget "iMessageStickersExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BF2F04729CC0602591655B251D13DD47 /* Production Debug */, + 59416DBF97224D8A1B28D6102CE1A723 /* Production Release */, + 9E0CC963DE7E2ED71A4C16C1DC243AD9 /* Staging Debug */, + B4297CD61108CE066C29984455AA0CE0 /* Staging Release */, + FC4A8130B924FC04E9190AB603D97A24 /* Test Debug */, + A0C50DBBF4AC5D30C92B19F78B9CC141 /* Test Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = ""; + }; BE0FF81B67730F081F45BC783F30F309 /* Build configuration list for PBXLegacyTarget "Legacy" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Tests/Fixtures/TestProject/project.yml b/Tests/Fixtures/TestProject/project.yml index 0f6111cc..6d387766 100644 --- a/Tests/Fixtures/TestProject/project.yml +++ b/Tests/Fixtures/TestProject/project.yml @@ -151,6 +151,12 @@ targets: settings: PRODUCT_BUNDLE_IDENTIFIER: com.project.iMessageApp.extension + iMessageStickersExtension: + type: app-extension.messages-sticker-pack + platform: iOS + sources: + - path: iMessage Stickers + StaticLibrary_ObjC: type: library.static platform: [iOS, tvOS, watchOS, macOS] diff --git a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift index 48b45771..89b523d1 100644 --- a/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift +++ b/Tests/XcodeGenKitTests/ProjectGeneratorTests.swift @@ -552,7 +552,20 @@ class ProjectGeneratorTests: XCTestCase { iosFrameworkB.filename, ]) - let targets = [app, iosFrameworkZ, staticLibrary, resourceBundle, iosFrameworkA, iosFrameworkB, appTest, appTestWithoutTransitive] + let stickerPack = Target( + name: "MyStickerApp", + type: .stickerPack, + platform: .iOS, + dependencies: [ + Dependency(type: .sdk, reference: "NotificationCenter.framework") + ] + ) + expectedResourceFiles[stickerPack.name] = nil + expectedLinkedFiles[stickerPack.name] = Set([ + "NotificationCenter.framework" + ]) + + let targets = [app, iosFrameworkZ, staticLibrary, resourceBundle, iosFrameworkA, iosFrameworkB, appTest, appTestWithoutTransitive, stickerPack] let project = Project( basePath: "", @@ -566,19 +579,28 @@ class ProjectGeneratorTests: XCTestCase { guard let nativeTarget = pbxProject.nativeTargets.first(where: { $0.name == target.name }) else { throw failure("PBXNativeTarget for \(target) not found") } + let buildPhases = nativeTarget.buildPhases let resourcesPhases = pbxProject.resourcesBuildPhases.filter { buildPhases.contains($0) } let frameworkPhases = pbxProject.frameworksBuildPhases.filter { buildPhases.contains($0) } let copyFilesPhases = pbxProject.copyFilesBuildPhases.filter { buildPhases.contains($0) } - // ensure only the right resources are copies, no more, no less - let expectedResourceFiles = expectedResourceFiles[target.name]! - try expect(resourcesPhases.count) == (expectedResourceFiles.isEmpty ? 0 : 1) - if !expectedResourceFiles.isEmpty { - let resourceFiles = resourcesPhases[0].files - .compactMap { $0.file } - .map { $0.nameOrPath } - try expect(Set(resourceFiles)) == expectedResourceFiles + // All targets should have a compile sources phase, + // except for the sticker pack one + let sourcesPhases = pbxProject.sourcesBuildPhases + try expect(sourcesPhases.count) == targets.count - 1 + + // ensure only the right resources are copied, no more, no less + if let expectedResourceFiles = expectedResourceFiles[target.name] { + try expect(resourcesPhases.count) == (expectedResourceFiles.isEmpty ? 0 : 1) + if !expectedResourceFiles.isEmpty { + let resourceFiles = resourcesPhases[0].files + .compactMap { $0.file } + .map { $0.nameOrPath } + try expect(Set(resourceFiles)) == expectedResourceFiles + } + } else { + try expect(resourcesPhases.count) == 0 } // ensure only the right things are linked, no more, no less @@ -591,12 +613,15 @@ class ProjectGeneratorTests: XCTestCase { } // ensure only the right things are embedded, no more, no less - let expectedEmbeddedFrameworks = expectedEmbeddedFrameworks[target.name]! - try expect(copyFilesPhases.count) == (expectedEmbeddedFrameworks.isEmpty ? 0 : 1) - if !expectedEmbeddedFrameworks.isEmpty { - let copyFiles = copyFilesPhases[0].files - .compactMap { $0.file?.nameOrPath } - try expect(Set(copyFiles)) == expectedEmbeddedFrameworks + if let expectedEmbeddedFrameworks = expectedEmbeddedFrameworks[target.name] { + try expect(copyFilesPhases.count) == (expectedEmbeddedFrameworks.isEmpty ? 0 : 1) + if !expectedEmbeddedFrameworks.isEmpty { + let copyFiles = copyFilesPhases[0].files + .compactMap { $0.file?.nameOrPath } + try expect(Set(copyFiles)) == expectedEmbeddedFrameworks + } + } else { + try expect(copyFilesPhases.count) == 0 } } }