@sentry/wizard 6.12.0 → 6.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/bin.js +16 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/e2e-tests/tests/angular-17.test.js +3 -4
  5. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
  6. package/dist/e2e-tests/tests/angular-19.test.js +3 -4
  7. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
  8. package/dist/e2e-tests/tests/flutter.test.js +60 -0
  9. package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
  10. package/dist/e2e-tests/tests/help-message.test.js +8 -3
  11. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  12. package/dist/e2e-tests/tests/nuxt-3.test.js +12 -6
  13. package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/nuxt-4.test.js +12 -6
  15. package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
  16. package/dist/e2e-tests/tests/pnpm-workspace.test.js +6 -3
  17. package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
  18. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +4 -4
  19. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -1
  20. package/dist/e2e-tests/tests/react-router.test.js +3 -6
  21. package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
  22. package/dist/e2e-tests/tests/remix.test.js +2 -4
  23. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  24. package/dist/e2e-tests/tests/sveltekit-hooks.test.js +24 -8
  25. package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
  26. package/dist/e2e-tests/tests/sveltekit-tracing.test.js +6 -3
  27. package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
  28. package/dist/lib/Constants.d.ts +1 -0
  29. package/dist/lib/Constants.js +5 -0
  30. package/dist/lib/Constants.js.map +1 -1
  31. package/dist/lib/Steps/Integrations/Electron.js +2 -2
  32. package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
  33. package/dist/src/android/android-wizard.js +3 -0
  34. package/dist/src/android/android-wizard.js.map +1 -1
  35. package/dist/src/angular/codemods/main.d.ts +1 -1
  36. package/dist/src/angular/codemods/main.js +0 -1
  37. package/dist/src/angular/codemods/main.js.map +1 -1
  38. package/dist/src/apple/apple-wizard.js +2 -3
  39. package/dist/src/apple/apple-wizard.js.map +1 -1
  40. package/dist/src/apple/check-installed-cli.d.ts +1 -1
  41. package/dist/src/apple/check-installed-cli.js +13 -7
  42. package/dist/src/apple/check-installed-cli.js.map +1 -1
  43. package/dist/src/apple/configure-xcode-project.js +8 -1
  44. package/dist/src/apple/configure-xcode-project.js.map +1 -1
  45. package/dist/src/apple/lookup-xcode-project.d.ts +8 -5
  46. package/dist/src/apple/lookup-xcode-project.js +22 -17
  47. package/dist/src/apple/lookup-xcode-project.js.map +1 -1
  48. package/dist/src/apple/options.d.ts +5 -0
  49. package/dist/src/apple/options.js.map +1 -1
  50. package/dist/src/apple/sentry-swift-package.d.ts +4 -0
  51. package/dist/src/apple/sentry-swift-package.js +17 -0
  52. package/dist/src/apple/sentry-swift-package.js.map +1 -0
  53. package/dist/src/apple/snapshots/apple-snapshots-wizard.d.ts +2 -0
  54. package/dist/src/apple/snapshots/apple-snapshots-wizard.js +251 -0
  55. package/dist/src/apple/snapshots/apple-snapshots-wizard.js.map +1 -0
  56. package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.d.ts +13 -0
  57. package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js +48 -0
  58. package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js.map +1 -0
  59. package/dist/src/apple/snapshots/snapshot-test-file.d.ts +18 -0
  60. package/dist/src/apple/snapshots/snapshot-test-file.js +122 -0
  61. package/dist/src/apple/snapshots/snapshot-test-file.js.map +1 -0
  62. package/dist/src/apple/snapshots/snapshot-verification-scheme.d.ts +6 -0
  63. package/dist/src/apple/snapshots/snapshot-verification-scheme.js +147 -0
  64. package/dist/src/apple/snapshots/snapshot-verification-scheme.js.map +1 -0
  65. package/dist/src/apple/snapshots/snapshotpreviews-package.d.ts +4 -0
  66. package/dist/src/apple/snapshots/snapshotpreviews-package.js +8 -0
  67. package/dist/src/apple/snapshots/snapshotpreviews-package.js.map +1 -0
  68. package/dist/src/apple/snapshots/snapshots-cli-preflight.d.ts +23 -0
  69. package/dist/src/apple/snapshots/snapshots-cli-preflight.js +136 -0
  70. package/dist/src/apple/snapshots/snapshots-cli-preflight.js.map +1 -0
  71. package/dist/src/apple/xcode-manager.d.ts +59 -1
  72. package/dist/src/apple/xcode-manager.js +507 -106
  73. package/dist/src/apple/xcode-manager.js.map +1 -1
  74. package/dist/src/flutter/flutter-wizard.js +3 -0
  75. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  76. package/dist/src/nextjs/templates.js +12 -6
  77. package/dist/src/nextjs/templates.js.map +1 -1
  78. package/dist/src/nuxt/templates.js +12 -6
  79. package/dist/src/nuxt/templates.js.map +1 -1
  80. package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
  81. package/dist/src/react-router/codemods/client.entry.js +93 -52
  82. package/dist/src/react-router/codemods/client.entry.js.map +1 -1
  83. package/dist/src/react-router/codemods/server-entry.js +8 -7
  84. package/dist/src/react-router/codemods/server-entry.js.map +1 -1
  85. package/dist/src/react-router/react-router-wizard.js +13 -19
  86. package/dist/src/react-router/react-router-wizard.js.map +1 -1
  87. package/dist/src/react-router/sdk-setup.d.ts +2 -2
  88. package/dist/src/react-router/sdk-setup.js +16 -15
  89. package/dist/src/react-router/sdk-setup.js.map +1 -1
  90. package/dist/src/react-router/templates.d.ts +1 -3
  91. package/dist/src/react-router/templates.js +24 -92
  92. package/dist/src/react-router/templates.js.map +1 -1
  93. package/dist/src/remix/sdk-setup.js +1 -2
  94. package/dist/src/remix/sdk-setup.js.map +1 -1
  95. package/dist/src/run.d.ts +4 -1
  96. package/dist/src/run.js +13 -0
  97. package/dist/src/run.js.map +1 -1
  98. package/dist/src/sourcemaps/tools/remix.js +4 -4
  99. package/dist/src/sourcemaps/tools/remix.js.map +1 -1
  100. package/dist/src/sveltekit/sdk-setup/setup.js +17 -4
  101. package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
  102. package/dist/src/sveltekit/templates.js +12 -6
  103. package/dist/src/sveltekit/templates.js.map +1 -1
  104. package/dist/src/utils/clack/index.d.ts +2 -1
  105. package/dist/src/utils/clack/index.js +17 -6
  106. package/dist/src/utils/clack/index.js.map +1 -1
  107. package/dist/src/utils/files.d.ts +2 -0
  108. package/dist/src/utils/files.js +58 -0
  109. package/dist/src/utils/files.js.map +1 -0
  110. package/dist/src/utils/git.d.ts +3 -1
  111. package/dist/src/utils/git.js +2 -1
  112. package/dist/src/utils/git.js.map +1 -1
  113. package/dist/src/utils/line-endings.d.ts +1 -0
  114. package/dist/src/utils/line-endings.js +76 -0
  115. package/dist/src/utils/line-endings.js.map +1 -0
  116. package/dist/src/version.d.ts +1 -1
  117. package/dist/src/version.js +1 -1
  118. package/dist/src/version.js.map +1 -1
  119. package/dist/test/angular/angular-wizard.test.js +0 -5
  120. package/dist/test/angular/angular-wizard.test.js.map +1 -1
  121. package/dist/test/apple/lookup-xcode-project.test.js +167 -0
  122. package/dist/test/apple/lookup-xcode-project.test.js.map +1 -0
  123. package/dist/test/apple/snapshots/apple-snapshots-wizard.test.d.ts +1 -0
  124. package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js +487 -0
  125. package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js.map +1 -0
  126. package/dist/test/apple/snapshots/hosted-test-target-fixture.d.ts +24 -0
  127. package/dist/test/apple/snapshots/hosted-test-target-fixture.js +191 -0
  128. package/dist/test/apple/snapshots/hosted-test-target-fixture.js.map +1 -0
  129. package/dist/test/apple/snapshots/snapshot-test-file.test.d.ts +1 -0
  130. package/dist/test/apple/snapshots/snapshot-test-file.test.js +110 -0
  131. package/dist/test/apple/snapshots/snapshot-test-file.test.js.map +1 -0
  132. package/dist/test/apple/snapshots/snapshot-verification-scheme.test.d.ts +1 -0
  133. package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js +146 -0
  134. package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js.map +1 -0
  135. package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.d.ts +1 -0
  136. package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js +186 -0
  137. package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js.map +1 -0
  138. package/dist/test/apple/snapshots/snapshots-cli-preflight.test.d.ts +1 -0
  139. package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js +192 -0
  140. package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js.map +1 -0
  141. package/dist/test/apple/snapshots/source-file-insertion.test.d.ts +1 -0
  142. package/dist/test/apple/snapshots/source-file-insertion.test.js +77 -0
  143. package/dist/test/apple/snapshots/source-file-insertion.test.js.map +1 -0
  144. package/dist/test/apple/xcode-manager.test.js +452 -43
  145. package/dist/test/apple/xcode-manager.test.js.map +1 -1
  146. package/dist/test/constants.test.d.ts +1 -0
  147. package/dist/test/constants.test.js +12 -0
  148. package/dist/test/constants.test.js.map +1 -0
  149. package/dist/test/nextjs/templates.test.js +66 -33
  150. package/dist/test/nextjs/templates.test.js.map +1 -1
  151. package/dist/test/nuxt/templates.test.js +66 -36
  152. package/dist/test/nuxt/templates.test.js.map +1 -1
  153. package/dist/test/react-router/codemods/client-entry.test.js +15 -11
  154. package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
  155. package/dist/test/react-router/codemods/server-entry.test.js +21 -8
  156. package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
  157. package/dist/test/react-router/sdk-setup.test.js +46 -10
  158. package/dist/test/react-router/sdk-setup.test.js.map +1 -1
  159. package/dist/test/react-router/templates.test.js +26 -64
  160. package/dist/test/react-router/templates.test.js.map +1 -1
  161. package/dist/test/remix/build-script.test.d.ts +1 -0
  162. package/dist/test/remix/build-script.test.js +124 -0
  163. package/dist/test/remix/build-script.test.js.map +1 -0
  164. package/dist/test/remix/client-entry.test.js +4 -10
  165. package/dist/test/remix/client-entry.test.js.map +1 -1
  166. package/dist/test/run.test.d.ts +1 -0
  167. package/dist/test/run.test.js +137 -0
  168. package/dist/test/run.test.js.map +1 -0
  169. package/dist/test/sveltekit/templates.test.js +78 -27
  170. package/dist/test/sveltekit/templates.test.js.map +1 -1
  171. package/dist/test/utils/clack/index.test.js +101 -0
  172. package/dist/test/utils/clack/index.test.js.map +1 -1
  173. package/dist/test/utils/git.test.js +10 -0
  174. package/dist/test/utils/git.test.js.map +1 -1
  175. package/dist/test/utils/line-endings.test.d.ts +1 -0
  176. package/dist/test/utils/line-endings.test.js +103 -0
  177. package/dist/test/utils/line-endings.test.js.map +1 -0
  178. package/package.json +2 -2
  179. package/dist/src/react-router/codemods/root.d.ts +0 -1
  180. package/dist/src/react-router/codemods/root.js +0 -170
  181. package/dist/src/react-router/codemods/root.js.map +0 -1
  182. package/dist/test/react-router/codemods/root.test.js +0 -182
  183. package/dist/test/react-router/codemods/root.test.js.map +0 -1
  184. /package/dist/test/{react-router/codemods/root.test.d.ts → apple/lookup-xcode-project.test.d.ts} +0 -0
@@ -31,8 +31,11 @@ const os = __importStar(require("node:os"));
31
31
  const path = __importStar(require("node:path"));
32
32
  const node_process_1 = __importDefault(require("node:process"));
33
33
  const vitest_1 = require("vitest");
34
+ const configure_snapshotpreviews_xcode_project_1 = require("../../src/apple/snapshots/configure-snapshotpreviews-xcode-project");
35
+ const sentry_swift_package_1 = require("../../src/apple/sentry-swift-package");
34
36
  const templates_1 = require("../../src/apple/templates");
35
37
  const xcode_manager_1 = require("../../src/apple/xcode-manager");
38
+ const hosted_test_target_fixture_1 = require("./snapshots/hosted-test-target-fixture");
36
39
  vitest_1.vi.mock('node:fs', async () => ({
37
40
  __esModule: true,
38
41
  ...(await vitest_1.vi.importActual('node:fs')),
@@ -61,6 +64,28 @@ const projectData = {
61
64
  },
62
65
  keys: [{ dsn: { public: 'https://sentry.io/1234567890' } }],
63
66
  };
67
+ const appFrameworksBuildPhaseId = 'D4E604CA2D50CEEC00CAB00F';
68
+ const sentrySwiftPackageProductLinkOptions = {
69
+ product: sentry_swift_package_1.sentrySwiftPackageProductSpec,
70
+ existingFrameworkComment: sentry_swift_package_1.SENTRY_SPM_ALREADY_LINKED_FRAMEWORK_COMMENT,
71
+ successMessage: 'Added Sentry SPM dependency to your project',
72
+ };
73
+ const projectObjectId = 'D4E604C52D50CEEC00CAB00F';
74
+ const productsGroupId = 'D4E604CE2D50CEEC00CAB00F';
75
+ function objectKeysWithoutComments(object) {
76
+ return Object.keys((object ?? {})).filter((key) => {
77
+ return !key.endsWith('_comment');
78
+ });
79
+ }
80
+ function getTargetByName(xcodeProject, targetName) {
81
+ const target = Object.values(xcodeProject.objects.PBXNativeTarget ?? {}).find((candidate) => {
82
+ return typeof candidate !== 'string' && candidate.name === targetName;
83
+ });
84
+ if (!target) {
85
+ throw new Error(`Target not found: ${targetName}`);
86
+ }
87
+ return target;
88
+ }
64
89
  (0, vitest_1.describe)('XcodeManager', () => {
65
90
  (0, vitest_1.beforeEach)(() => {
66
91
  if (node_process_1.default.platform !== 'darwin') {
@@ -124,6 +149,338 @@ const projectData = {
124
149
  });
125
150
  });
126
151
  });
152
+ (0, vitest_1.describe)('target type detection', () => {
153
+ (0, vitest_1.it)('lists application and unit-test targets by name', () => {
154
+ // -- Arrange --
155
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
156
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
157
+ projectObjectId,
158
+ productsGroupId,
159
+ });
160
+ // -- Act & Assert --
161
+ (0, vitest_1.expect)(xcodeProject.getAllTargets()).toEqual(['Project']);
162
+ (0, vitest_1.expect)(xcodeProject.getUnitTestTargetNames()).toEqual(['ProjectTests']);
163
+ });
164
+ (0, vitest_1.it)('returns multiple unit-test targets by name', () => {
165
+ // -- Arrange --
166
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
167
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
168
+ name: 'ProjectTests',
169
+ projectObjectId,
170
+ productsGroupId,
171
+ });
172
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
173
+ name: 'ProjectSnapshotTests',
174
+ projectObjectId,
175
+ productsGroupId,
176
+ });
177
+ // -- Act & Assert --
178
+ (0, vitest_1.expect)(xcodeProject.getUnitTestTargetNames()).toEqual([
179
+ 'ProjectTests',
180
+ 'ProjectSnapshotTests',
181
+ ]);
182
+ });
183
+ (0, vitest_1.it)('returns only unit-test targets with TEST_HOST configured', () => {
184
+ // -- Arrange --
185
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
186
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
187
+ name: 'ProjectTests',
188
+ projectObjectId,
189
+ productsGroupId,
190
+ });
191
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
192
+ name: 'UnhostedProjectTests',
193
+ projectObjectId,
194
+ productsGroupId,
195
+ testHost: '""',
196
+ });
197
+ // -- Act & Assert --
198
+ (0, vitest_1.expect)(xcodeProject.getUnitTestTargetNames()).toEqual([
199
+ 'ProjectTests',
200
+ 'UnhostedProjectTests',
201
+ ]);
202
+ (0, vitest_1.expect)(xcodeProject.getHostedUnitTestTargetNames()).toEqual([
203
+ 'ProjectTests',
204
+ ]);
205
+ });
206
+ (0, vitest_1.it)('returns only unit-test targets hosted by the selected application target', () => {
207
+ // -- Arrange --
208
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
209
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
210
+ name: 'ProjectTests',
211
+ projectObjectId,
212
+ productsGroupId,
213
+ });
214
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
215
+ hostAppName: 'OtherApp',
216
+ name: 'OtherAppTests',
217
+ projectObjectId,
218
+ productsGroupId,
219
+ });
220
+ // -- Act & Assert --
221
+ (0, vitest_1.expect)(xcodeProject.getHostedUnitTestTargetNamesForApplicationTarget('Project')).toEqual(['ProjectTests']);
222
+ });
223
+ (0, vitest_1.it)('matches hosted unit-test targets by app product name', () => {
224
+ // -- Arrange --
225
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
226
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
227
+ name: 'ProjectTests',
228
+ projectObjectId,
229
+ productsGroupId,
230
+ testHost: '"$(BUILT_PRODUCTS_DIR)/SentryWizardSampleBlank.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SentryWizardSampleBlank"',
231
+ });
232
+ // -- Act & Assert --
233
+ (0, vitest_1.expect)(xcodeProject.getHostedUnitTestTargetNamesForApplicationTarget('Project')).toEqual(['ProjectTests']);
234
+ });
235
+ (0, vitest_1.it)('returns no hosted unit-test targets for an unknown application target', () => {
236
+ // -- Arrange --
237
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
238
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
239
+ name: 'ProjectTests',
240
+ projectObjectId,
241
+ productsGroupId,
242
+ });
243
+ // -- Act & Assert --
244
+ (0, vitest_1.expect)(xcodeProject.getHostedUnitTestTargetNamesForApplicationTarget('MissingApp')).toEqual([]);
245
+ });
246
+ });
247
+ (0, vitest_1.describe)('ensureSwiftPackageProductLinked', () => {
248
+ let xcodeProject;
249
+ let hostedTestTargetIds;
250
+ (0, vitest_1.beforeEach)(() => {
251
+ xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
252
+ hostedTestTargetIds = (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
253
+ projectObjectId,
254
+ productsGroupId,
255
+ });
256
+ });
257
+ (0, vitest_1.it)('links a Swift package product only to the selected target', () => {
258
+ // -- Act --
259
+ const result = xcodeProject.ensureSwiftPackageProductLinked('ProjectTests', configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec);
260
+ // -- Assert --
261
+ (0, vitest_1.expect)(result).toEqual({ changed: true, linked: true });
262
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCRemoteSwiftPackageReference)).toHaveLength(1);
263
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toHaveLength(1);
264
+ const appTarget = getTargetByName(xcodeProject, 'Project');
265
+ const hostedTestTarget = getTargetByName(xcodeProject, 'ProjectTests');
266
+ (0, vitest_1.expect)(appTarget.packageProductDependencies).toEqual([]);
267
+ (0, vitest_1.expect)(hostedTestTarget.packageProductDependencies).toEqual([
268
+ vitest_1.expect.objectContaining({ comment: 'SnapshottingTests' }),
269
+ ]);
270
+ const appFrameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[appFrameworksBuildPhaseId];
271
+ const testFrameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[hostedTestTargetIds.frameworksBuildPhaseId];
272
+ (0, vitest_1.expect)(typeof appFrameworksBuildPhase !== 'string'
273
+ ? appFrameworksBuildPhase?.files
274
+ : undefined).toEqual([]);
275
+ (0, vitest_1.expect)(typeof testFrameworksBuildPhase !== 'string'
276
+ ? testFrameworksBuildPhase?.files
277
+ : undefined).toEqual([
278
+ vitest_1.expect.objectContaining({
279
+ comment: 'SnapshottingTests in Frameworks',
280
+ }),
281
+ ]);
282
+ });
283
+ (0, vitest_1.it)('is idempotent across repeated runs', () => {
284
+ // -- Act --
285
+ const firstResult = xcodeProject.ensureSwiftPackageProductLinked('ProjectTests', configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec);
286
+ const secondResult = xcodeProject.ensureSwiftPackageProductLinked('ProjectTests', configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec);
287
+ // -- Assert --
288
+ (0, vitest_1.expect)(firstResult).toEqual({ changed: true, linked: true });
289
+ (0, vitest_1.expect)(secondResult).toEqual({ changed: false, linked: true });
290
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCRemoteSwiftPackageReference)).toHaveLength(1);
291
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toHaveLength(1);
292
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.PBXBuildFile)).toHaveLength(1);
293
+ });
294
+ (0, vitest_1.it)('reuses an existing product dependency with a quoted product name', () => {
295
+ // -- Arrange --
296
+ const packageRefId = 'EXISTINGPACKAGE000000000001';
297
+ const productDependencyId = 'EXISTINGPRODUCT000000000001';
298
+ xcodeProject.objects.XCRemoteSwiftPackageReference = {
299
+ [packageRefId]: {
300
+ isa: 'XCRemoteSwiftPackageReference',
301
+ repositoryURL: `"${configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec.package.repositoryURL}"`,
302
+ requirement: configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec.package.requirement,
303
+ },
304
+ [`${packageRefId}_comment`]: 'XCRemoteSwiftPackageReference "SnapshotPreviews"',
305
+ };
306
+ xcodeProject.objects.XCSwiftPackageProductDependency = {
307
+ [productDependencyId]: {
308
+ isa: 'XCSwiftPackageProductDependency',
309
+ package: packageRefId,
310
+ productName: '"SnapshottingTests"',
311
+ },
312
+ [`${productDependencyId}_comment`]: 'SnapshottingTests',
313
+ };
314
+ // -- Act --
315
+ const result = xcodeProject.ensureSwiftPackageProductLinked('ProjectTests', configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec);
316
+ // -- Assert --
317
+ (0, vitest_1.expect)(result).toEqual({ changed: true, linked: true });
318
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toEqual([productDependencyId]);
319
+ (0, vitest_1.expect)(getTargetByName(xcodeProject, 'ProjectTests')).toEqual(vitest_1.expect.objectContaining({
320
+ packageProductDependencies: [
321
+ vitest_1.expect.objectContaining({ value: productDependencyId }),
322
+ ],
323
+ }));
324
+ });
325
+ (0, vitest_1.it)('reuses an existing package reference with the same repository URL and updates a lower minimum version', () => {
326
+ // -- Arrange --
327
+ xcodeProject.objects.XCRemoteSwiftPackageReference = {
328
+ EXISTINGPACKAGE000000000001: {
329
+ isa: 'XCRemoteSwiftPackageReference',
330
+ repositoryURL: `"${configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec.package.repositoryURL}/"`,
331
+ requirement: {
332
+ kind: 'upToNextMajorVersion',
333
+ minimumVersion: '0.8.0',
334
+ },
335
+ },
336
+ EXISTINGPACKAGE000000000001_comment: 'XCRemoteSwiftPackageReference "SnapshotPreviews"',
337
+ };
338
+ // -- Act --
339
+ const result = xcodeProject.ensureSwiftPackageProductLinked('ProjectTests', configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec);
340
+ // -- Assert --
341
+ (0, vitest_1.expect)(result).toEqual({ changed: true, linked: true });
342
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCRemoteSwiftPackageReference)).toEqual(['EXISTINGPACKAGE000000000001']);
343
+ (0, vitest_1.expect)(xcodeProject.objects.XCRemoteSwiftPackageReference?.['EXISTINGPACKAGE000000000001']).toEqual(vitest_1.expect.objectContaining({
344
+ requirement: configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec.package.requirement,
345
+ }));
346
+ (0, vitest_1.expect)(xcodeProject.objects.XCSwiftPackageProductDependency?.[objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)[0]]).toEqual(vitest_1.expect.objectContaining({
347
+ package: 'EXISTINGPACKAGE000000000001',
348
+ productName: 'SnapshottingTests',
349
+ }));
350
+ });
351
+ (0, vitest_1.it)('does not partially mutate package state when the target has no Frameworks build phase', () => {
352
+ // -- Arrange --
353
+ const hostedTestTarget = getTargetByName(xcodeProject, 'ProjectTests');
354
+ hostedTestTarget.buildPhases = [];
355
+ // -- Act --
356
+ const result = xcodeProject.ensureSwiftPackageProductLinked('ProjectTests', configure_snapshotpreviews_xcode_project_1.snapshottingTestsProductSpec);
357
+ // -- Assert --
358
+ (0, vitest_1.expect)(result).toEqual({ changed: false, linked: false });
359
+ (0, vitest_1.expect)(xcodeProject.objects.XCRemoteSwiftPackageReference).toBeUndefined();
360
+ (0, vitest_1.expect)(xcodeProject.objects.XCSwiftPackageProductDependency).toBeUndefined();
361
+ (0, vitest_1.expect)(xcodeProject.objects.PBXBuildFile).toBeUndefined();
362
+ (0, vitest_1.expect)(hostedTestTarget.packageProductDependencies).toEqual([]);
363
+ });
364
+ });
365
+ (0, vitest_1.describe)('configureSnapshotPreviewsXcodeProject', () => {
366
+ (0, vitest_1.it)('links SnapshottingTests to the hosted test target and SnapshotPreferences only to selected preview targets', () => {
367
+ // -- Arrange --
368
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
369
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
370
+ projectObjectId,
371
+ productsGroupId,
372
+ });
373
+ // -- Act --
374
+ const result = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
375
+ xcodeProject,
376
+ hostedTestTargetName: 'ProjectTests',
377
+ previewTargetNames: ['Project'],
378
+ });
379
+ // -- Assert --
380
+ (0, vitest_1.expect)(result).toEqual({
381
+ changed: true,
382
+ failedSnapshotPreferencesTargetNames: [],
383
+ linked: true,
384
+ });
385
+ const appTarget = getTargetByName(xcodeProject, 'Project');
386
+ const hostedTestTarget = getTargetByName(xcodeProject, 'ProjectTests');
387
+ (0, vitest_1.expect)(appTarget.packageProductDependencies).toEqual([
388
+ vitest_1.expect.objectContaining({ comment: 'SnapshotPreferences' }),
389
+ ]);
390
+ (0, vitest_1.expect)(hostedTestTarget.packageProductDependencies).toEqual([
391
+ vitest_1.expect.objectContaining({ comment: 'SnapshottingTests' }),
392
+ ]);
393
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toHaveLength(2);
394
+ });
395
+ (0, vitest_1.it)('does not link SnapshotPreferences when no preview targets are selected', () => {
396
+ // -- Arrange --
397
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
398
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
399
+ projectObjectId,
400
+ productsGroupId,
401
+ });
402
+ // -- Act --
403
+ (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
404
+ xcodeProject,
405
+ hostedTestTargetName: 'ProjectTests',
406
+ });
407
+ // -- Assert --
408
+ const appTarget = getTargetByName(xcodeProject, 'Project');
409
+ const hostedTestTarget = getTargetByName(xcodeProject, 'ProjectTests');
410
+ (0, vitest_1.expect)(appTarget.packageProductDependencies).toEqual([]);
411
+ (0, vitest_1.expect)(hostedTestTarget.packageProductDependencies).toEqual([
412
+ vitest_1.expect.objectContaining({ comment: 'SnapshottingTests' }),
413
+ ]);
414
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toHaveLength(1);
415
+ });
416
+ (0, vitest_1.it)('continues when SnapshotPreferences cannot be linked to a preview target', () => {
417
+ // -- Arrange --
418
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
419
+ (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
420
+ projectObjectId,
421
+ productsGroupId,
422
+ });
423
+ const appTarget = getTargetByName(xcodeProject, 'Project');
424
+ appTarget.buildPhases = [];
425
+ // -- Act --
426
+ const result = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
427
+ xcodeProject,
428
+ hostedTestTargetName: 'ProjectTests',
429
+ previewTargetNames: ['Project'],
430
+ });
431
+ // -- Assert --
432
+ const hostedTestTarget = getTargetByName(xcodeProject, 'ProjectTests');
433
+ (0, vitest_1.expect)(result).toEqual({
434
+ changed: true,
435
+ failedSnapshotPreferencesTargetNames: ['Project'],
436
+ linked: true,
437
+ });
438
+ (0, vitest_1.expect)(appTarget.packageProductDependencies).toEqual([]);
439
+ (0, vitest_1.expect)(hostedTestTarget.packageProductDependencies).toEqual([
440
+ vitest_1.expect.objectContaining({ comment: 'SnapshottingTests' }),
441
+ ]);
442
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toHaveLength(1);
443
+ });
444
+ (0, vitest_1.it)('does not mutate package state when the hosted test target is missing', () => {
445
+ // -- Arrange --
446
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
447
+ // -- Act --
448
+ const result = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
449
+ xcodeProject,
450
+ hostedTestTargetName: 'MissingTests',
451
+ });
452
+ // -- Assert --
453
+ (0, vitest_1.expect)(result).toEqual({
454
+ changed: false,
455
+ failedSnapshotPreferencesTargetNames: [],
456
+ linked: false,
457
+ });
458
+ (0, vitest_1.expect)(xcodeProject.objects.XCRemoteSwiftPackageReference).toBeUndefined();
459
+ (0, vitest_1.expect)(xcodeProject.objects.XCSwiftPackageProductDependency).toBeUndefined();
460
+ (0, vitest_1.expect)(xcodeProject.objects.PBXBuildFile).toBeUndefined();
461
+ });
462
+ (0, vitest_1.it)('does not link SnapshotPreferences when the hosted test target is missing', () => {
463
+ // -- Arrange --
464
+ const xcodeProject = new xcode_manager_1.XcodeProject(singleTargetProjectPath);
465
+ // -- Act --
466
+ const result = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
467
+ xcodeProject,
468
+ hostedTestTargetName: 'MissingTests',
469
+ previewTargetNames: ['Project'],
470
+ });
471
+ // -- Assert --
472
+ const appTarget = getTargetByName(xcodeProject, 'Project');
473
+ (0, vitest_1.expect)(result).toEqual({
474
+ changed: false,
475
+ failedSnapshotPreferencesTargetNames: [],
476
+ linked: false,
477
+ });
478
+ (0, vitest_1.expect)(appTarget.packageProductDependencies).toEqual([]);
479
+ (0, vitest_1.expect)(xcodeProject.objects.XCRemoteSwiftPackageReference).toBeUndefined();
480
+ (0, vitest_1.expect)(xcodeProject.objects.XCSwiftPackageProductDependency).toBeUndefined();
481
+ (0, vitest_1.expect)(xcodeProject.objects.PBXBuildFile).toBeUndefined();
482
+ });
483
+ });
127
484
  (0, vitest_1.describe)('updateXcodeProject', () => {
128
485
  let sourceProjectPath;
129
486
  let tempProjectPath;
@@ -167,7 +524,7 @@ const projectData = {
167
524
  const generatedShellScript = (0, templates_1.getRunScriptTemplate)(projectData.organization.slug, projectData.slug, variant.uploadSource, variant.includeHomebrewPath);
168
525
  const expectedShellScript = `"${generatedShellScript.replace(/"/g, '\\"')}"`;
169
526
  // -- Act --
170
- xcodeProject.updateXcodeProject(projectData, 'Project', false, // Ignore SPM reference
527
+ xcodeProject.updateXcodeProject(projectData, 'Project', undefined, // Ignore SPM reference
171
528
  variant.uploadSource);
172
529
  // -- Assert --
173
530
  const updatedXcodeProject = new xcode_manager_1.XcodeProject(tempProjectPath);
@@ -207,7 +564,7 @@ const projectData = {
207
564
  (0, vitest_1.describe)('upload source is false', () => {
208
565
  (0, vitest_1.it)('should not update the Xcode project', () => {
209
566
  // -- Act --
210
- xcodeProject.updateXcodeProject(projectData, 'Project', false, // Ignore SPM reference
567
+ xcodeProject.updateXcodeProject(projectData, 'Project', undefined, // Ignore SPM reference
211
568
  false);
212
569
  // -- Assert --
213
570
  const expectedXcodeProject = new xcode_manager_1.XcodeProject(sourceProjectPath);
@@ -219,7 +576,7 @@ const projectData = {
219
576
  (0, vitest_1.describe)('named target not found', () => {
220
577
  (0, vitest_1.it)('should not update the flags in the Xcode project', () => {
221
578
  // -- Act --
222
- xcodeProject.updateXcodeProject(projectData, 'Invalid Target Name', false, // Ignore SPM reference
579
+ xcodeProject.updateXcodeProject(projectData, 'Invalid Target Name', undefined, // Ignore SPM reference
223
580
  uploadSource);
224
581
  // -- Assert --
225
582
  const originalXcodeProject = new xcode_manager_1.XcodeProject(sourceProjectPath);
@@ -230,7 +587,7 @@ const projectData = {
230
587
  (0, vitest_1.describe)('build configurations is undefined', () => {
231
588
  (0, vitest_1.it)('should not update the Xcode project', () => {
232
589
  // -- Act --
233
- xcodeProject.updateXcodeProject(projectData, 'Invalid Target Name', false, // Ignore SPM reference
590
+ xcodeProject.updateXcodeProject(projectData, 'Invalid Target Name', undefined, // Ignore SPM reference
234
591
  uploadSource);
235
592
  // -- Assert --
236
593
  const originalXcodeProject = new xcode_manager_1.XcodeProject(sourceProjectPath);
@@ -242,7 +599,7 @@ const projectData = {
242
599
  // -- Arrange --
243
600
  xcodeProject.objects.XCBuildConfiguration = {};
244
601
  // -- Act --
245
- xcodeProject.updateXcodeProject(projectData, 'Invalid Target Name', false, // Ignore SPM reference
602
+ xcodeProject.updateXcodeProject(projectData, 'Invalid Target Name', undefined, // Ignore SPM reference
246
603
  uploadSource);
247
604
  // -- Assert --
248
605
  (0, vitest_1.expect)(xcodeProject.objects.XCBuildConfiguration).toEqual({});
@@ -255,7 +612,7 @@ const projectData = {
255
612
  const releaseTargetBuildConfigurationListId = 'D4E604DE2D50CEEE00CAB00F';
256
613
  (0, vitest_1.it)('should update the target configuration lists', () => {
257
614
  // -- Act --
258
- xcodeProject.updateXcodeProject(projectData, 'Project', false, // Ignore SPM reference
615
+ xcodeProject.updateXcodeProject(projectData, 'Project', undefined, // Ignore SPM reference
259
616
  uploadSource);
260
617
  // -- Assert --
261
618
  (0, vitest_1.expect)(xcodeProject.objects.XCBuildConfiguration).toBeDefined();
@@ -276,7 +633,7 @@ const projectData = {
276
633
  });
277
634
  (0, vitest_1.it)('should not update the project configuration lists', () => {
278
635
  // -- Act --
279
- xcodeProject.updateXcodeProject(projectData, 'Project', false, // Ignore SPM reference
636
+ xcodeProject.updateXcodeProject(projectData, 'Project', undefined, // Ignore SPM reference
280
637
  uploadSource);
281
638
  // -- Assert --
282
639
  (0, vitest_1.expect)(xcodeProject.objects.XCBuildConfiguration).toBeDefined();
@@ -304,44 +661,76 @@ const projectData = {
304
661
  });
305
662
  });
306
663
  (0, vitest_1.describe)('add SPM reference', () => {
307
- const addSPMReference = true;
308
- (0, vitest_1.describe)('framework build phase already contains Sentry', () => {
309
- (0, vitest_1.it)('should not update the Xcode project', () => {
310
- // -- Arrange --
311
- xcodeProject.objects.PBXFrameworksBuildPhase = {
312
- 'framework-id': {
313
- isa: 'PBXFrameworksBuildPhase',
314
- files: [
315
- {
316
- value: '123',
317
- comment: 'Sentry in Frameworks',
318
- },
319
- ],
320
- },
321
- };
322
- // -- Act --
323
- xcodeProject.updateXcodeProject(projectData, 'Project', addSPMReference);
324
- // -- Assert --
325
- const expectedXcodeProject = new xcode_manager_1.XcodeProject(sourceProjectPath);
326
- expectedXcodeProject.objects.PBXFrameworksBuildPhase = {
327
- 'framework-id': {
328
- isa: 'PBXFrameworksBuildPhase',
329
- files: [
330
- {
331
- value: '123',
332
- comment: 'Sentry in Frameworks',
333
- },
334
- ],
335
- },
336
- };
337
- (0, vitest_1.expect)(xcodeProject.objects.PBXFrameworksBuildPhase).toEqual(expectedXcodeProject.objects.PBXFrameworksBuildPhase);
338
- (0, vitest_1.expect)(xcodeProject.objects.XCRemoteSwiftPackageReference).toEqual(expectedXcodeProject.objects.XCRemoteSwiftPackageReference);
339
- (0, vitest_1.expect)(xcodeProject.objects.XCSwiftPackageProductDependency).toEqual(expectedXcodeProject.objects.XCSwiftPackageProductDependency);
664
+ (0, vitest_1.it)('should treat an existing Sentry framework comment on the selected target as already installed', () => {
665
+ // -- Arrange --
666
+ const frameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[appFrameworksBuildPhaseId];
667
+ if (!frameworksBuildPhase ||
668
+ typeof frameworksBuildPhase === 'string') {
669
+ throw new Error('Frameworks build phase is undefined');
670
+ }
671
+ frameworksBuildPhase.files = [
672
+ {
673
+ value: '123',
674
+ comment: 'Sentry in Frameworks',
675
+ },
676
+ ];
677
+ // -- Act --
678
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
679
+ // -- Assert --
680
+ (0, vitest_1.expect)(frameworksBuildPhase.files).toEqual([
681
+ {
682
+ value: '123',
683
+ comment: 'Sentry in Frameworks',
684
+ },
685
+ ]);
686
+ (0, vitest_1.expect)(xcodeProject.objects.XCRemoteSwiftPackageReference).toBeUndefined();
687
+ (0, vitest_1.expect)(xcodeProject.objects.XCSwiftPackageProductDependency).toBeUndefined();
688
+ });
689
+ (0, vitest_1.it)('should not treat a Sentry framework comment on another target as installed on the selected target', () => {
690
+ // -- Arrange --
691
+ const hostedTestTargetIds = (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
692
+ projectObjectId,
693
+ productsGroupId,
340
694
  });
695
+ const testFrameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[hostedTestTargetIds.frameworksBuildPhaseId];
696
+ if (!testFrameworksBuildPhase ||
697
+ typeof testFrameworksBuildPhase === 'string') {
698
+ throw new Error('Frameworks build phase is undefined');
699
+ }
700
+ testFrameworksBuildPhase.files = [
701
+ {
702
+ value: '123',
703
+ comment: 'Sentry in Frameworks',
704
+ },
705
+ ];
706
+ // -- Act --
707
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
708
+ // -- Assert --
709
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCRemoteSwiftPackageReference)).toHaveLength(1);
710
+ const appFrameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[appFrameworksBuildPhaseId];
711
+ (0, vitest_1.expect)(typeof appFrameworksBuildPhase !== 'string'
712
+ ? appFrameworksBuildPhase?.files?.filter((file) => {
713
+ return file.comment === 'Sentry in Frameworks';
714
+ })
715
+ : []).toHaveLength(1);
716
+ });
717
+ (0, vitest_1.it)('should not duplicate the Sentry SPM dependency on repeated runs', () => {
718
+ // -- Act --
719
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
720
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
721
+ // -- Assert --
722
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCRemoteSwiftPackageReference)).toHaveLength(1);
723
+ (0, vitest_1.expect)(objectKeysWithoutComments(xcodeProject.objects.XCSwiftPackageProductDependency)).toHaveLength(1);
724
+ const frameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[appFrameworksBuildPhaseId];
725
+ (0, vitest_1.expect)(typeof frameworksBuildPhase !== 'string'
726
+ ? frameworksBuildPhase?.files?.filter((file) => {
727
+ return file.comment === 'Sentry in Frameworks';
728
+ })
729
+ : []).toHaveLength(1);
341
730
  });
342
731
  (0, vitest_1.it)('should add the SPM reference to the target', () => {
343
732
  // -- Act --
344
- xcodeProject.updateXcodeProject(projectData, 'Project', addSPMReference);
733
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
345
734
  // -- Assert --
346
735
  // Get the target
347
736
  const target = xcodeProject.objects.PBXNativeTarget?.['D4E604CC2D50CEEC00CAB00F'];
@@ -373,7 +762,7 @@ const projectData = {
373
762
  repositoryURL: '"https://github.com/getsentry/sentry-cocoa/"',
374
763
  requirement: {
375
764
  kind: 'upToNextMajorVersion',
376
- minimumVersion: '8.0.0',
765
+ minimumVersion: '9.0.0',
377
766
  },
378
767
  });
379
768
  (0, vitest_1.expect)(remoteSwiftPackageReferences?.[rspRefKeys[1]]).toBe('XCRemoteSwiftPackageReference "sentry-cocoa"');
@@ -396,6 +785,26 @@ const projectData = {
396
785
  productName: 'Sentry',
397
786
  });
398
787
  });
788
+ (0, vitest_1.it)('should link Sentry only to the selected target', () => {
789
+ // -- Arrange --
790
+ const hostedTestTargetIds = (0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
791
+ projectObjectId,
792
+ productsGroupId,
793
+ });
794
+ // -- Act --
795
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
796
+ // -- Assert --
797
+ const appTarget = getTargetByName(xcodeProject, 'Project');
798
+ const hostedTestTarget = getTargetByName(xcodeProject, 'ProjectTests');
799
+ (0, vitest_1.expect)(appTarget.packageProductDependencies).toEqual([
800
+ vitest_1.expect.objectContaining({ comment: 'Sentry' }),
801
+ ]);
802
+ (0, vitest_1.expect)(hostedTestTarget.packageProductDependencies).toEqual([]);
803
+ const testFrameworksBuildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[hostedTestTargetIds.frameworksBuildPhaseId];
804
+ (0, vitest_1.expect)(typeof testFrameworksBuildPhase !== 'string'
805
+ ? testFrameworksBuildPhase?.files
806
+ : undefined).toEqual([]);
807
+ });
399
808
  (0, vitest_1.it)('should initialize packageProductDependencies if not present', () => {
400
809
  // -- Arrange --
401
810
  // Ensure the target exists but has no packageProductDependencies initially
@@ -406,7 +815,7 @@ const projectData = {
406
815
  delete target.packageProductDependencies;
407
816
  }
408
817
  // -- Act --
409
- xcodeProject.updateXcodeProject(projectData, 'Project', addSPMReference);
818
+ xcodeProject.updateXcodeProject(projectData, 'Project', sentrySwiftPackageProductLinkOptions);
410
819
  // -- Assert --
411
820
  const updatedTarget = xcodeProject.objects.PBXNativeTarget?.[targetKey];
412
821
  (0, vitest_1.expect)(updatedTarget.packageProductDependencies).toBeDefined();