@sentry/wizard 6.11.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.
- package/CHANGELOG.md +64 -0
- package/dist/bin.js +16 -1
- package/dist/bin.js.map +1 -1
- package/dist/e2e-tests/tests/angular-17.test.js +3 -4
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +3 -4
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/cloudflare-worker.test.js +5 -0
- package/dist/e2e-tests/tests/cloudflare-worker.test.js.map +1 -1
- package/dist/e2e-tests/tests/flutter.test.js +60 -0
- package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
- package/dist/e2e-tests/tests/help-message.test.js +8 -3
- package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-3.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +12 -6
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/pnpm-workspace.test.js +8 -4
- package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +96 -0
- package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -0
- package/dist/e2e-tests/tests/react-router.test.js +6 -7
- package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +2 -4
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +24 -8
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +8 -4
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/lib/Constants.d.ts +1 -0
- package/dist/lib/Constants.js +5 -0
- package/dist/lib/Constants.js.map +1 -1
- package/dist/lib/Steps/Integrations/Electron.js +2 -2
- package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
- package/dist/src/android/android-wizard.js +3 -0
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/angular/codemods/main.d.ts +1 -1
- package/dist/src/angular/codemods/main.js +0 -1
- package/dist/src/angular/codemods/main.js.map +1 -1
- package/dist/src/apple/apple-wizard.js +2 -3
- package/dist/src/apple/apple-wizard.js.map +1 -1
- package/dist/src/apple/check-installed-cli.d.ts +1 -1
- package/dist/src/apple/check-installed-cli.js +13 -7
- package/dist/src/apple/check-installed-cli.js.map +1 -1
- package/dist/src/apple/code-tools.js +17 -3
- package/dist/src/apple/code-tools.js.map +1 -1
- package/dist/src/apple/configure-package-manager.js +18 -5
- package/dist/src/apple/configure-package-manager.js.map +1 -1
- package/dist/src/apple/configure-xcode-project.js +8 -1
- package/dist/src/apple/configure-xcode-project.js.map +1 -1
- package/dist/src/apple/lookup-xcode-project.d.ts +8 -5
- package/dist/src/apple/lookup-xcode-project.js +22 -17
- package/dist/src/apple/lookup-xcode-project.js.map +1 -1
- package/dist/src/apple/options.d.ts +5 -0
- package/dist/src/apple/options.js.map +1 -1
- package/dist/src/apple/sentry-swift-package.d.ts +4 -0
- package/dist/src/apple/sentry-swift-package.js +17 -0
- package/dist/src/apple/sentry-swift-package.js.map +1 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.d.ts +2 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js +251 -0
- package/dist/src/apple/snapshots/apple-snapshots-wizard.js.map +1 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.d.ts +13 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js +48 -0
- package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-test-file.d.ts +18 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js +122 -0
- package/dist/src/apple/snapshots/snapshot-test-file.js.map +1 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.d.ts +6 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js +147 -0
- package/dist/src/apple/snapshots/snapshot-verification-scheme.js.map +1 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.d.ts +4 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js +8 -0
- package/dist/src/apple/snapshots/snapshotpreviews-package.js.map +1 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.d.ts +23 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js +136 -0
- package/dist/src/apple/snapshots/snapshots-cli-preflight.js.map +1 -0
- package/dist/src/apple/xcode-manager.d.ts +59 -1
- package/dist/src/apple/xcode-manager.js +507 -106
- package/dist/src/apple/xcode-manager.js.map +1 -1
- package/dist/src/cloudflare/cloudflare-wizard.js +5 -0
- package/dist/src/cloudflare/cloudflare-wizard.js.map +1 -1
- package/dist/src/cloudflare/sdk-setup.d.ts +1 -0
- package/dist/src/cloudflare/sdk-setup.js.map +1 -1
- package/dist/src/cloudflare/templates.d.ts +1 -0
- package/dist/src/cloudflare/templates.js +7 -1
- package/dist/src/cloudflare/templates.js.map +1 -1
- package/dist/src/cloudflare/wrap-worker.d.ts +1 -0
- package/dist/src/cloudflare/wrap-worker.js +7 -0
- package/dist/src/cloudflare/wrap-worker.js.map +1 -1
- package/dist/src/flutter/flutter-wizard.js +3 -0
- package/dist/src/flutter/flutter-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.js +12 -6
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/templates.js +12 -6
- package/dist/src/nuxt/templates.js.map +1 -1
- package/dist/src/react-native/expo.d.ts +6 -0
- package/dist/src/react-native/expo.js +27 -1
- package/dist/src/react-native/expo.js.map +1 -1
- package/dist/src/react-native/git.d.ts +5 -0
- package/dist/src/react-native/git.js +32 -1
- package/dist/src/react-native/git.js.map +1 -1
- package/dist/src/react-native/javascript.js +3 -1
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +12 -6
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
- package/dist/src/react-router/codemods/client.entry.js +124 -26
- package/dist/src/react-router/codemods/client.entry.js.map +1 -1
- package/dist/src/react-router/codemods/react-router-config.js +1 -1
- package/dist/src/react-router/codemods/react-router-config.js.map +1 -1
- package/dist/src/react-router/codemods/server-entry.d.ts +1 -1
- package/dist/src/react-router/codemods/server-entry.js +40 -4
- package/dist/src/react-router/codemods/server-entry.js.map +1 -1
- package/dist/src/react-router/codemods/vite.js +46 -1
- package/dist/src/react-router/codemods/vite.js.map +1 -1
- package/dist/src/react-router/react-router-wizard.js +62 -21
- package/dist/src/react-router/react-router-wizard.js.map +1 -1
- package/dist/src/react-router/sdk-setup.d.ts +5 -3
- package/dist/src/react-router/sdk-setup.js +44 -16
- package/dist/src/react-router/sdk-setup.js.map +1 -1
- package/dist/src/react-router/templates.d.ts +2 -4
- package/dist/src/react-router/templates.js +89 -87
- package/dist/src/react-router/templates.js.map +1 -1
- package/dist/src/remix/sdk-setup.js +1 -2
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/run.d.ts +4 -1
- package/dist/src/run.js +13 -0
- package/dist/src/run.js.map +1 -1
- package/dist/src/sourcemaps/tools/remix.js +4 -4
- package/dist/src/sourcemaps/tools/remix.js.map +1 -1
- package/dist/src/sourcemaps/tools/vite.js +1 -1
- package/dist/src/sourcemaps/tools/vite.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/setup.js +17 -4
- package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js +1 -1
- package/dist/src/sveltekit/sdk-setup/vite.js.map +1 -1
- package/dist/src/sveltekit/templates.js +12 -6
- package/dist/src/sveltekit/templates.js.map +1 -1
- package/dist/src/utils/ast-utils.d.ts +10 -0
- package/dist/src/utils/ast-utils.js +19 -1
- package/dist/src/utils/ast-utils.js.map +1 -1
- package/dist/src/utils/clack/index.d.ts +2 -1
- package/dist/src/utils/clack/index.js +17 -6
- package/dist/src/utils/clack/index.js.map +1 -1
- package/dist/src/utils/files.d.ts +2 -0
- package/dist/src/utils/files.js +58 -0
- package/dist/src/utils/files.js.map +1 -0
- package/dist/src/utils/git.d.ts +3 -1
- package/dist/src/utils/git.js +2 -1
- package/dist/src/utils/git.js.map +1 -1
- package/dist/src/utils/line-endings.d.ts +1 -0
- package/dist/src/utils/line-endings.js +76 -0
- package/dist/src/utils/line-endings.js.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/version.js.map +1 -1
- package/dist/test/angular/angular-wizard.test.js +0 -5
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +78 -0
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/configure-package-manager.test.d.ts +1 -0
- package/dist/test/apple/configure-package-manager.test.js +161 -0
- package/dist/test/apple/configure-package-manager.test.js.map +1 -0
- package/dist/test/apple/lookup-xcode-project.test.d.ts +1 -0
- package/dist/test/apple/lookup-xcode-project.test.js +167 -0
- package/dist/test/apple/lookup-xcode-project.test.js.map +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.d.ts +1 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js +487 -0
- package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js.map +1 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.d.ts +24 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js +191 -0
- package/dist/test/apple/snapshots/hosted-test-target-fixture.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js +110 -0
- package/dist/test/apple/snapshots/snapshot-test-file.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js +146 -0
- package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js +186 -0
- package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js.map +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.d.ts +1 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js +192 -0
- package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js.map +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.d.ts +1 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js +77 -0
- package/dist/test/apple/snapshots/source-file-insertion.test.js.map +1 -0
- package/dist/test/apple/xcode-manager.test.js +452 -43
- package/dist/test/apple/xcode-manager.test.js.map +1 -1
- package/dist/test/cloudflare/sdk-setup.test.js +20 -2
- package/dist/test/cloudflare/sdk-setup.test.js.map +1 -1
- package/dist/test/cloudflare/templates.test.js +54 -0
- package/dist/test/cloudflare/templates.test.js.map +1 -1
- package/dist/test/cloudflare/wrap-worker.test.js +74 -11
- package/dist/test/cloudflare/wrap-worker.test.js.map +1 -1
- package/dist/test/constants.test.d.ts +1 -0
- package/dist/test/constants.test.js +12 -0
- package/dist/test/constants.test.js.map +1 -0
- package/dist/test/nextjs/templates.test.js +66 -33
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/nuxt/templates.test.js +66 -36
- package/dist/test/nuxt/templates.test.js.map +1 -1
- package/dist/test/react-native/expo.test.js +140 -0
- package/dist/test/react-native/expo.test.js.map +1 -1
- package/dist/test/react-native/git.test.d.ts +1 -0
- package/dist/test/react-native/git.test.js +160 -0
- package/dist/test/react-native/git.test.js.map +1 -0
- package/dist/test/react-router/codemods/client-entry.test.js +38 -5
- package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/server-entry.test.js +83 -0
- package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
- package/dist/test/react-router/codemods/vite.test.js +89 -0
- package/dist/test/react-router/codemods/vite.test.js.map +1 -1
- package/dist/test/react-router/sdk-setup.test.js +98 -6
- package/dist/test/react-router/sdk-setup.test.js.map +1 -1
- package/dist/test/react-router/templates.test.js +50 -38
- package/dist/test/react-router/templates.test.js.map +1 -1
- package/dist/test/remix/build-script.test.d.ts +1 -0
- package/dist/test/remix/build-script.test.js +124 -0
- package/dist/test/remix/build-script.test.js.map +1 -0
- package/dist/test/remix/client-entry.test.js +4 -10
- package/dist/test/remix/client-entry.test.js.map +1 -1
- package/dist/test/run.test.d.ts +1 -0
- package/dist/test/run.test.js +137 -0
- package/dist/test/run.test.js.map +1 -0
- package/dist/test/sourcemaps/tools/vite.test.js +12 -8
- package/dist/test/sourcemaps/tools/vite.test.js.map +1 -1
- package/dist/test/sveltekit/templates.test.js +78 -27
- package/dist/test/sveltekit/templates.test.js.map +1 -1
- package/dist/test/utils/ast-utils.test.js +22 -0
- package/dist/test/utils/ast-utils.test.js.map +1 -1
- package/dist/test/utils/clack/index.test.js +101 -0
- package/dist/test/utils/clack/index.test.js.map +1 -1
- package/dist/test/utils/git.test.js +10 -0
- package/dist/test/utils/git.test.js.map +1 -1
- package/dist/test/utils/line-endings.test.d.ts +1 -0
- package/dist/test/utils/line-endings.test.js +103 -0
- package/dist/test/utils/line-endings.test.js.map +1 -0
- package/package.json +2 -2
- package/dist/src/react-router/codemods/root.d.ts +0 -1
- package/dist/src/react-router/codemods/root.js +0 -171
- package/dist/src/react-router/codemods/root.js.map +0 -1
- package/dist/test/react-router/codemods/root.test.js +0 -178
- package/dist/test/react-router/codemods/root.test.js.map +0 -1
- /package/dist/{test/react-router/codemods/root.test.d.ts → e2e-tests/tests/react-router-instrumentation-api.test.d.ts} +0 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const fs = __importStar(require("node:fs"));
|
|
27
|
+
const path = __importStar(require("node:path"));
|
|
28
|
+
const vitest_1 = require("vitest");
|
|
29
|
+
const configure_snapshotpreviews_xcode_project_1 = require("../../../src/apple/snapshots/configure-snapshotpreviews-xcode-project");
|
|
30
|
+
const snapshot_test_file_1 = require("../../../src/apple/snapshots/snapshot-test-file");
|
|
31
|
+
const snapshotpreviews_package_1 = require("../../../src/apple/snapshots/snapshotpreviews-package");
|
|
32
|
+
const xcode_manager_1 = require("../../../src/apple/xcode-manager");
|
|
33
|
+
const hosted_test_target_fixture_1 = require("./hosted-test-target-fixture");
|
|
34
|
+
vitest_1.vi.mock('@clack/prompts', () => ({
|
|
35
|
+
log: {
|
|
36
|
+
info: vitest_1.vi.fn(),
|
|
37
|
+
success: vitest_1.vi.fn(),
|
|
38
|
+
step: vitest_1.vi.fn(),
|
|
39
|
+
},
|
|
40
|
+
}));
|
|
41
|
+
const projectObjectId = 'D4E604C52D50CEEC00CAB00F';
|
|
42
|
+
const productsGroupId = 'D4E604CE2D50CEEC00CAB00F';
|
|
43
|
+
const hostedTestTargetIds = {
|
|
44
|
+
targetId: 'AAAABBBBCCCCDDDDEEEE0001',
|
|
45
|
+
frameworksBuildPhaseId: 'AAAABBBBCCCCDDDDEEEE0002',
|
|
46
|
+
sourcesBuildPhaseId: 'AAAABBBBCCCCDDDDEEEE0003',
|
|
47
|
+
debugBuildConfigurationId: 'AAAABBBBCCCCDDDDEEEE0004',
|
|
48
|
+
releaseBuildConfigurationId: 'AAAABBBBCCCCDDDDEEEE0005',
|
|
49
|
+
buildConfigurationListId: 'AAAABBBBCCCCDDDDEEEE0006',
|
|
50
|
+
productReferenceId: 'AAAABBBBCCCCDDDDEEEE0007',
|
|
51
|
+
};
|
|
52
|
+
function getTargetByName(xcodeProject, targetName) {
|
|
53
|
+
const target = Object.values(xcodeProject.objects.PBXNativeTarget ?? {}).find((candidate) => {
|
|
54
|
+
return typeof candidate !== 'string' && candidate.name === targetName;
|
|
55
|
+
});
|
|
56
|
+
if (!target) {
|
|
57
|
+
throw new Error(`Target not found: ${targetName}`);
|
|
58
|
+
}
|
|
59
|
+
return target;
|
|
60
|
+
}
|
|
61
|
+
function getProductDependencyIds(xcodeProject, productName) {
|
|
62
|
+
return Object.entries(xcodeProject.objects.XCSwiftPackageProductDependency ?? {}).reduce((ids, [id, productDependency]) => {
|
|
63
|
+
if (id.endsWith('_comment') ||
|
|
64
|
+
typeof productDependency === 'string' ||
|
|
65
|
+
productDependency.productName !== productName) {
|
|
66
|
+
return ids;
|
|
67
|
+
}
|
|
68
|
+
return ids.concat(id);
|
|
69
|
+
}, new Array());
|
|
70
|
+
}
|
|
71
|
+
function getProductDependency(xcodeProject, productDependencyId) {
|
|
72
|
+
const productDependency = xcodeProject.objects.XCSwiftPackageProductDependency?.[productDependencyId];
|
|
73
|
+
if (!productDependency || typeof productDependency === 'string') {
|
|
74
|
+
throw new Error(`Product dependency not found: ${productDependencyId}`);
|
|
75
|
+
}
|
|
76
|
+
return productDependency;
|
|
77
|
+
}
|
|
78
|
+
function getFrameworkProductRefs(xcodeProject, targetName) {
|
|
79
|
+
return (getTargetByName(xcodeProject, targetName).buildPhases ?? []).reduce((productRefs, buildPhaseReference) => {
|
|
80
|
+
const buildPhase = xcodeProject.objects.PBXFrameworksBuildPhase?.[buildPhaseReference.value];
|
|
81
|
+
if (!buildPhase || typeof buildPhase === 'string') {
|
|
82
|
+
return productRefs;
|
|
83
|
+
}
|
|
84
|
+
return productRefs.concat((buildPhase.files ?? []).flatMap((file) => {
|
|
85
|
+
const buildFile = xcodeProject.objects.PBXBuildFile?.[file.value];
|
|
86
|
+
return buildFile &&
|
|
87
|
+
typeof buildFile !== 'string' &&
|
|
88
|
+
typeof buildFile.productRef === 'string'
|
|
89
|
+
? [buildFile.productRef]
|
|
90
|
+
: [];
|
|
91
|
+
}));
|
|
92
|
+
}, new Array());
|
|
93
|
+
}
|
|
94
|
+
function getSnapshotPreviewsPackageReferenceIds(xcodeProject) {
|
|
95
|
+
return Object.entries(xcodeProject.objects.XCRemoteSwiftPackageReference ?? {}).reduce((ids, [id, packageReference]) => {
|
|
96
|
+
if (id.endsWith('_comment') ||
|
|
97
|
+
typeof packageReference === 'string' ||
|
|
98
|
+
packageReference.repositoryURL !== `"${snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PACKAGE_URL}"`) {
|
|
99
|
+
return ids;
|
|
100
|
+
}
|
|
101
|
+
return ids.concat(id);
|
|
102
|
+
}, new Array());
|
|
103
|
+
}
|
|
104
|
+
(0, vitest_1.describe)('SnapshotPreviews hosted XCTest Xcode project smoke coverage', () => {
|
|
105
|
+
(0, vitest_1.it)('mutates, reparses, and reruns without duplicating package or source membership', () => {
|
|
106
|
+
const pbxprojPath = (0, hosted_test_target_fixture_1.copySingleTargetProjectToTemp)('snapshotpreviews-xcode-smoke-');
|
|
107
|
+
const xcodeProject = new xcode_manager_1.XcodeProject(pbxprojPath);
|
|
108
|
+
(0, hosted_test_target_fixture_1.addHostedUnitTestTarget)(xcodeProject, {
|
|
109
|
+
ids: hostedTestTargetIds,
|
|
110
|
+
includeSourcesBuildPhase: true,
|
|
111
|
+
projectObjectId,
|
|
112
|
+
productsGroupId,
|
|
113
|
+
});
|
|
114
|
+
const snapshotTestResult = (0, snapshot_test_file_1.ensureSnapshotTestFile)({
|
|
115
|
+
xcodeProject,
|
|
116
|
+
hostedTestTargetName: 'ProjectTests',
|
|
117
|
+
});
|
|
118
|
+
const packageResult = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
|
|
119
|
+
xcodeProject,
|
|
120
|
+
hostedTestTargetName: 'ProjectTests',
|
|
121
|
+
previewTargetNames: ['Project'],
|
|
122
|
+
});
|
|
123
|
+
xcodeProject.write();
|
|
124
|
+
(0, vitest_1.expect)(snapshotTestResult.changed).toBe(true);
|
|
125
|
+
(0, vitest_1.expect)(snapshotTestResult.included).toBe(true);
|
|
126
|
+
if (!snapshotTestResult.included) {
|
|
127
|
+
throw new Error('Expected snapshot test file to be included');
|
|
128
|
+
}
|
|
129
|
+
(0, vitest_1.expect)(snapshotTestResult.filePath).toBe(path.join(xcodeProject.baseDir, 'ProjectTests', 'ProjectTestsSnapshotTest.swift'));
|
|
130
|
+
(0, vitest_1.expect)(packageResult).toEqual({
|
|
131
|
+
changed: true,
|
|
132
|
+
failedSnapshotPreferencesTargetNames: [],
|
|
133
|
+
linked: true,
|
|
134
|
+
});
|
|
135
|
+
const firstSerializedProject = fs.readFileSync(pbxprojPath, 'utf8');
|
|
136
|
+
const reparsedProject = new xcode_manager_1.XcodeProject(pbxprojPath);
|
|
137
|
+
(0, vitest_1.expect)(reparsedProject.getUnitTestTargetNames()).toContain('ProjectTests');
|
|
138
|
+
(0, vitest_1.expect)(getSnapshotPreviewsPackageReferenceIds(reparsedProject)).toHaveLength(1);
|
|
139
|
+
const snapshottingTestsProductDependencyIds = getProductDependencyIds(reparsedProject, snapshotpreviews_package_1.SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT);
|
|
140
|
+
const snapshotPreferencesProductDependencyIds = getProductDependencyIds(reparsedProject, snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT);
|
|
141
|
+
(0, vitest_1.expect)(snapshottingTestsProductDependencyIds).toHaveLength(1);
|
|
142
|
+
(0, vitest_1.expect)(snapshotPreferencesProductDependencyIds).toHaveLength(1);
|
|
143
|
+
(0, vitest_1.expect)(getProductDependency(reparsedProject, snapshottingTestsProductDependencyIds[0]).package).toBe(getSnapshotPreviewsPackageReferenceIds(reparsedProject)[0]);
|
|
144
|
+
(0, vitest_1.expect)(getProductDependency(reparsedProject, snapshotPreferencesProductDependencyIds[0]).package).toBe(getSnapshotPreviewsPackageReferenceIds(reparsedProject)[0]);
|
|
145
|
+
(0, vitest_1.expect)(getFrameworkProductRefs(reparsedProject, 'ProjectTests')).toEqual([
|
|
146
|
+
snapshottingTestsProductDependencyIds[0],
|
|
147
|
+
]);
|
|
148
|
+
(0, vitest_1.expect)(getFrameworkProductRefs(reparsedProject, 'Project')).toEqual([
|
|
149
|
+
snapshotPreferencesProductDependencyIds[0],
|
|
150
|
+
]);
|
|
151
|
+
(0, vitest_1.expect)(getTargetByName(reparsedProject, 'ProjectTests')
|
|
152
|
+
.packageProductDependencies).toEqual([
|
|
153
|
+
{
|
|
154
|
+
value: snapshottingTestsProductDependencyIds[0],
|
|
155
|
+
comment: snapshotpreviews_package_1.SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,
|
|
156
|
+
},
|
|
157
|
+
]);
|
|
158
|
+
(0, vitest_1.expect)(getTargetByName(reparsedProject, 'Project').packageProductDependencies).toEqual([
|
|
159
|
+
{
|
|
160
|
+
value: snapshotPreferencesProductDependencyIds[0],
|
|
161
|
+
comment: snapshotpreviews_package_1.SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,
|
|
162
|
+
},
|
|
163
|
+
]);
|
|
164
|
+
(0, vitest_1.expect)(reparsedProject
|
|
165
|
+
.getSourceFilesForTarget('ProjectTests')
|
|
166
|
+
?.filter((sourceFilePath) => sourceFilePath.endsWith('ProjectTests/ProjectTestsSnapshotTest.swift'))).toHaveLength(1);
|
|
167
|
+
const secondSnapshotTestResult = (0, snapshot_test_file_1.ensureSnapshotTestFile)({
|
|
168
|
+
xcodeProject: reparsedProject,
|
|
169
|
+
hostedTestTargetName: 'ProjectTests',
|
|
170
|
+
});
|
|
171
|
+
const secondPackageResult = (0, configure_snapshotpreviews_xcode_project_1.configureSnapshotPreviewsXcodeProject)({
|
|
172
|
+
xcodeProject: reparsedProject,
|
|
173
|
+
hostedTestTargetName: 'ProjectTests',
|
|
174
|
+
previewTargetNames: ['Project'],
|
|
175
|
+
});
|
|
176
|
+
reparsedProject.write();
|
|
177
|
+
(0, vitest_1.expect)(secondSnapshotTestResult.changed).toBe(false);
|
|
178
|
+
(0, vitest_1.expect)(secondPackageResult).toEqual({
|
|
179
|
+
changed: false,
|
|
180
|
+
failedSnapshotPreferencesTargetNames: [],
|
|
181
|
+
linked: true,
|
|
182
|
+
});
|
|
183
|
+
(0, vitest_1.expect)(fs.readFileSync(pbxprojPath, 'utf8')).toBe(firstSerializedProject);
|
|
184
|
+
}, 15000);
|
|
185
|
+
});
|
|
186
|
+
//# sourceMappingURL=snapshotpreviews-xcode-smoke.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshotpreviews-xcode-smoke.test.js","sourceRoot":"","sources":["../../../../test/apple/snapshots/snapshotpreviews-xcode-smoke.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { describe, expect, it, vi } from 'vitest';\nimport type { PBXNativeTarget } from 'xcode';\n\nimport { configureSnapshotPreviewsXcodeProject } from '../../../src/apple/snapshots/configure-snapshotpreviews-xcode-project';\nimport { ensureSnapshotTestFile } from '../../../src/apple/snapshots/snapshot-test-file';\nimport {\n SNAPSHOTPREVIEWS_PACKAGE_URL,\n SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,\n SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,\n} from '../../../src/apple/snapshots/snapshotpreviews-package';\nimport { XcodeProject } from '../../../src/apple/xcode-manager';\nimport {\n addHostedUnitTestTarget,\n copySingleTargetProjectToTemp,\n} from './hosted-test-target-fixture';\n\nvi.mock('@clack/prompts', () => ({\n log: {\n info: vi.fn(),\n success: vi.fn(),\n step: vi.fn(),\n },\n}));\n\nconst projectObjectId = 'D4E604C52D50CEEC00CAB00F';\nconst productsGroupId = 'D4E604CE2D50CEEC00CAB00F';\n\nconst hostedTestTargetIds = {\n targetId: 'AAAABBBBCCCCDDDDEEEE0001',\n frameworksBuildPhaseId: 'AAAABBBBCCCCDDDDEEEE0002',\n sourcesBuildPhaseId: 'AAAABBBBCCCCDDDDEEEE0003',\n debugBuildConfigurationId: 'AAAABBBBCCCCDDDDEEEE0004',\n releaseBuildConfigurationId: 'AAAABBBBCCCCDDDDEEEE0005',\n buildConfigurationListId: 'AAAABBBBCCCCDDDDEEEE0006',\n productReferenceId: 'AAAABBBBCCCCDDDDEEEE0007',\n};\n\nfunction getTargetByName(\n xcodeProject: XcodeProject,\n targetName: string,\n): PBXNativeTarget {\n const target = Object.values(xcodeProject.objects.PBXNativeTarget ?? {}).find(\n (candidate) => {\n return typeof candidate !== 'string' && candidate.name === targetName;\n },\n ) as PBXNativeTarget | undefined;\n\n if (!target) {\n throw new Error(`Target not found: ${targetName}`);\n }\n\n return target;\n}\n\nfunction getProductDependencyIds(\n xcodeProject: XcodeProject,\n productName: string,\n): string[] {\n return Object.entries(\n xcodeProject.objects.XCSwiftPackageProductDependency ?? {},\n ).reduce((ids, [id, productDependency]) => {\n if (\n id.endsWith('_comment') ||\n typeof productDependency === 'string' ||\n productDependency.productName !== productName\n ) {\n return ids;\n }\n\n return ids.concat(id);\n }, new Array<string>());\n}\n\nfunction getProductDependency(\n xcodeProject: XcodeProject,\n productDependencyId: string,\n) {\n const productDependency =\n xcodeProject.objects.XCSwiftPackageProductDependency?.[productDependencyId];\n if (!productDependency || typeof productDependency === 'string') {\n throw new Error(`Product dependency not found: ${productDependencyId}`);\n }\n\n return productDependency;\n}\n\nfunction getFrameworkProductRefs(\n xcodeProject: XcodeProject,\n targetName: string,\n): string[] {\n return (getTargetByName(xcodeProject, targetName).buildPhases ?? []).reduce(\n (productRefs, buildPhaseReference) => {\n const buildPhase =\n xcodeProject.objects.PBXFrameworksBuildPhase?.[\n buildPhaseReference.value\n ];\n if (!buildPhase || typeof buildPhase === 'string') {\n return productRefs;\n }\n\n return productRefs.concat(\n (buildPhase.files ?? []).flatMap((file) => {\n const buildFile = xcodeProject.objects.PBXBuildFile?.[file.value];\n return buildFile &&\n typeof buildFile !== 'string' &&\n typeof buildFile.productRef === 'string'\n ? [buildFile.productRef]\n : [];\n }),\n );\n },\n new Array<string>(),\n );\n}\n\nfunction getSnapshotPreviewsPackageReferenceIds(\n xcodeProject: XcodeProject,\n): string[] {\n return Object.entries(\n xcodeProject.objects.XCRemoteSwiftPackageReference ?? {},\n ).reduce((ids, [id, packageReference]) => {\n if (\n id.endsWith('_comment') ||\n typeof packageReference === 'string' ||\n packageReference.repositoryURL !== `\"${SNAPSHOTPREVIEWS_PACKAGE_URL}\"`\n ) {\n return ids;\n }\n\n return ids.concat(id);\n }, new Array<string>());\n}\n\ndescribe('SnapshotPreviews hosted XCTest Xcode project smoke coverage', () => {\n it('mutates, reparses, and reruns without duplicating package or source membership', () => {\n const pbxprojPath = copySingleTargetProjectToTemp(\n 'snapshotpreviews-xcode-smoke-',\n );\n const xcodeProject = new XcodeProject(pbxprojPath);\n addHostedUnitTestTarget(xcodeProject, {\n ids: hostedTestTargetIds,\n includeSourcesBuildPhase: true,\n projectObjectId,\n productsGroupId,\n });\n\n const snapshotTestResult = ensureSnapshotTestFile({\n xcodeProject,\n hostedTestTargetName: 'ProjectTests',\n });\n const packageResult = configureSnapshotPreviewsXcodeProject({\n xcodeProject,\n hostedTestTargetName: 'ProjectTests',\n previewTargetNames: ['Project'],\n });\n xcodeProject.write();\n\n expect(snapshotTestResult.changed).toBe(true);\n expect(snapshotTestResult.included).toBe(true);\n if (!snapshotTestResult.included) {\n throw new Error('Expected snapshot test file to be included');\n }\n expect(snapshotTestResult.filePath).toBe(\n path.join(\n xcodeProject.baseDir,\n 'ProjectTests',\n 'ProjectTestsSnapshotTest.swift',\n ),\n );\n expect(packageResult).toEqual({\n changed: true,\n failedSnapshotPreferencesTargetNames: [],\n linked: true,\n });\n\n const firstSerializedProject = fs.readFileSync(pbxprojPath, 'utf8');\n const reparsedProject = new XcodeProject(pbxprojPath);\n\n expect(reparsedProject.getUnitTestTargetNames()).toContain('ProjectTests');\n expect(\n getSnapshotPreviewsPackageReferenceIds(reparsedProject),\n ).toHaveLength(1);\n\n const snapshottingTestsProductDependencyIds = getProductDependencyIds(\n reparsedProject,\n SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,\n );\n const snapshotPreferencesProductDependencyIds = getProductDependencyIds(\n reparsedProject,\n SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,\n );\n expect(snapshottingTestsProductDependencyIds).toHaveLength(1);\n expect(snapshotPreferencesProductDependencyIds).toHaveLength(1);\n expect(\n getProductDependency(\n reparsedProject,\n snapshottingTestsProductDependencyIds[0],\n ).package,\n ).toBe(getSnapshotPreviewsPackageReferenceIds(reparsedProject)[0]);\n expect(\n getProductDependency(\n reparsedProject,\n snapshotPreferencesProductDependencyIds[0],\n ).package,\n ).toBe(getSnapshotPreviewsPackageReferenceIds(reparsedProject)[0]);\n expect(getFrameworkProductRefs(reparsedProject, 'ProjectTests')).toEqual([\n snapshottingTestsProductDependencyIds[0],\n ]);\n expect(getFrameworkProductRefs(reparsedProject, 'Project')).toEqual([\n snapshotPreferencesProductDependencyIds[0],\n ]);\n\n expect(\n getTargetByName(reparsedProject, 'ProjectTests')\n .packageProductDependencies,\n ).toEqual([\n {\n value: snapshottingTestsProductDependencyIds[0],\n comment: SNAPSHOTPREVIEWS_SNAPSHOT_TESTS_PRODUCT,\n },\n ]);\n expect(\n getTargetByName(reparsedProject, 'Project').packageProductDependencies,\n ).toEqual([\n {\n value: snapshotPreferencesProductDependencyIds[0],\n comment: SNAPSHOTPREVIEWS_PREFERENCES_PRODUCT,\n },\n ]);\n expect(\n reparsedProject\n .getSourceFilesForTarget('ProjectTests')\n ?.filter((sourceFilePath) =>\n sourceFilePath.endsWith(\n 'ProjectTests/ProjectTestsSnapshotTest.swift',\n ),\n ),\n ).toHaveLength(1);\n\n const secondSnapshotTestResult = ensureSnapshotTestFile({\n xcodeProject: reparsedProject,\n hostedTestTargetName: 'ProjectTests',\n });\n const secondPackageResult = configureSnapshotPreviewsXcodeProject({\n xcodeProject: reparsedProject,\n hostedTestTargetName: 'ProjectTests',\n previewTargetNames: ['Project'],\n });\n reparsedProject.write();\n\n expect(secondSnapshotTestResult.changed).toBe(false);\n expect(secondPackageResult).toEqual({\n changed: false,\n failedSnapshotPreferencesTargetNames: [],\n linked: true,\n });\n expect(fs.readFileSync(pbxprojPath, 'utf8')).toBe(firstSerializedProject);\n }, 15_000);\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const fs = __importStar(require("node:fs"));
|
|
27
|
+
const os = __importStar(require("node:os"));
|
|
28
|
+
const path = __importStar(require("node:path"));
|
|
29
|
+
const vitest_1 = require("vitest");
|
|
30
|
+
const mocks = vitest_1.vi.hoisted(() => ({
|
|
31
|
+
askToInstallSentryCLI: vitest_1.vi.fn(),
|
|
32
|
+
executeSync: vitest_1.vi.fn(),
|
|
33
|
+
hasSentryCLI: vitest_1.vi.fn(),
|
|
34
|
+
info: vitest_1.vi.fn(),
|
|
35
|
+
installSentryCLI: vitest_1.vi.fn(),
|
|
36
|
+
setTag: vitest_1.vi.fn(),
|
|
37
|
+
success: vitest_1.vi.fn(),
|
|
38
|
+
warn: vitest_1.vi.fn(),
|
|
39
|
+
}));
|
|
40
|
+
vitest_1.vi.mock('@clack/prompts', () => ({
|
|
41
|
+
default: {
|
|
42
|
+
log: {
|
|
43
|
+
info: mocks.info,
|
|
44
|
+
success: mocks.success,
|
|
45
|
+
warn: mocks.warn,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
vitest_1.vi.mock('@sentry/node', () => ({
|
|
50
|
+
setTag: mocks.setTag,
|
|
51
|
+
}));
|
|
52
|
+
vitest_1.vi.mock('../../../src/telemetry', () => ({
|
|
53
|
+
traceStep: async (_name, callback) => await callback(),
|
|
54
|
+
}));
|
|
55
|
+
vitest_1.vi.mock('../../../src/utils/bash', () => ({
|
|
56
|
+
executeSync: mocks.executeSync,
|
|
57
|
+
hasSentryCLI: mocks.hasSentryCLI,
|
|
58
|
+
installSentryCLI: mocks.installSentryCLI,
|
|
59
|
+
}));
|
|
60
|
+
vitest_1.vi.mock('../../../src/utils/clack', () => ({
|
|
61
|
+
askToInstallSentryCLI: mocks.askToInstallSentryCLI,
|
|
62
|
+
}));
|
|
63
|
+
const snapshots_cli_preflight_1 = require("../../../src/apple/snapshots/snapshots-cli-preflight");
|
|
64
|
+
function getVerificationGuidance(projectDir) {
|
|
65
|
+
return {
|
|
66
|
+
appId: 'com.getsentry.App',
|
|
67
|
+
hostedTestTargetName: 'AppTests',
|
|
68
|
+
projectDir,
|
|
69
|
+
projectPath: path.join(projectDir, 'App.xcodeproj'),
|
|
70
|
+
schemeName: 'App',
|
|
71
|
+
snapshotTestClassName: 'AppTestsSnapshotTest',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
(0, vitest_1.describe)('snapshots CLI preflight', () => {
|
|
75
|
+
(0, vitest_1.beforeEach)(() => {
|
|
76
|
+
vitest_1.vi.clearAllMocks();
|
|
77
|
+
});
|
|
78
|
+
(0, vitest_1.it)('offers to install sentry-cli with snapshots-aware warning when missing', async () => {
|
|
79
|
+
mocks.hasSentryCLI.mockReturnValue(false);
|
|
80
|
+
mocks.askToInstallSentryCLI.mockResolvedValue(false);
|
|
81
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-missing-'));
|
|
82
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
83
|
+
projectDir,
|
|
84
|
+
nonInteractive: false,
|
|
85
|
+
verificationGuidance: getVerificationGuidance(projectDir),
|
|
86
|
+
});
|
|
87
|
+
(0, vitest_1.expect)(mocks.askToInstallSentryCLI).toHaveBeenCalledTimes(1);
|
|
88
|
+
(0, vitest_1.expect)(mocks.warn).toHaveBeenCalledWith(vitest_1.expect.stringContaining('upload snapshots to Sentry'));
|
|
89
|
+
(0, vitest_1.expect)(mocks.executeSync).not.toHaveBeenCalled();
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.it)('does not prompt to install sentry-cli in non-interactive mode', async () => {
|
|
92
|
+
mocks.hasSentryCLI.mockReturnValue(false);
|
|
93
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-non-interactive-'));
|
|
94
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
95
|
+
projectDir,
|
|
96
|
+
nonInteractive: true,
|
|
97
|
+
verificationGuidance: getVerificationGuidance(projectDir),
|
|
98
|
+
});
|
|
99
|
+
(0, vitest_1.expect)(mocks.askToInstallSentryCLI).not.toHaveBeenCalled();
|
|
100
|
+
(0, vitest_1.expect)(mocks.warn).toHaveBeenCalledWith(vitest_1.expect.stringContaining('upload snapshots to Sentry'));
|
|
101
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('sentry-cli snapshots upload'));
|
|
102
|
+
(0, vitest_1.expect)(mocks.executeSync).not.toHaveBeenCalled();
|
|
103
|
+
});
|
|
104
|
+
(0, vitest_1.it)('verifies snapshots upload support and prefers existing Fastlane guidance', async () => {
|
|
105
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));
|
|
106
|
+
const fastlaneDir = path.join(projectDir, 'fastlane');
|
|
107
|
+
fs.mkdirSync(fastlaneDir);
|
|
108
|
+
fs.writeFileSync(path.join(fastlaneDir, 'Fastfile'), 'platform :ios do\n lane :upload_sentry_snapshots do |options|\n sentry_upload_snapshots(path: options[:path])\n end\nend\n');
|
|
109
|
+
mocks.hasSentryCLI.mockReturnValue(true);
|
|
110
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
111
|
+
projectDir,
|
|
112
|
+
nonInteractive: false,
|
|
113
|
+
verificationGuidance: getVerificationGuidance(projectDir),
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.expect)(mocks.executeSync).toHaveBeenCalledWith('sentry-cli snapshots upload --help');
|
|
116
|
+
(0, vitest_1.expect)(mocks.success).toHaveBeenCalledWith('sentry-cli snapshots upload is available.');
|
|
117
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('xcodebuild test'));
|
|
118
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('-project App.xcodeproj'));
|
|
119
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('-scheme App'));
|
|
120
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('-only-testing:AppTests/AppTestsSnapshotTest'));
|
|
121
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('bundle exec fastlane ios upload_sentry_snapshots'));
|
|
122
|
+
});
|
|
123
|
+
(0, vitest_1.it)('prints xcodebuild export and sentry-cli upload guidance', async () => {
|
|
124
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));
|
|
125
|
+
mocks.hasSentryCLI.mockReturnValue(true);
|
|
126
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
127
|
+
projectDir,
|
|
128
|
+
nonInteractive: false,
|
|
129
|
+
verificationGuidance: getVerificationGuidance(projectDir),
|
|
130
|
+
});
|
|
131
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('TEST_RUNNER_SNAPSHOTS_EXPORT_DIR'));
|
|
132
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('-only-testing:AppTests/AppTestsSnapshotTest'));
|
|
133
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('sentry-cli snapshots upload'));
|
|
134
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('--app-id com.getsentry.App'));
|
|
135
|
+
});
|
|
136
|
+
(0, vitest_1.it)('uses the provided snapshot test class name in xcodebuild guidance', async () => {
|
|
137
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));
|
|
138
|
+
mocks.hasSentryCLI.mockReturnValue(true);
|
|
139
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
140
|
+
projectDir,
|
|
141
|
+
nonInteractive: false,
|
|
142
|
+
verificationGuidance: {
|
|
143
|
+
...getVerificationGuidance(projectDir),
|
|
144
|
+
snapshotTestClassName: 'CustomSnapshots',
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('-only-testing:AppTests/CustomSnapshots'));
|
|
148
|
+
(0, vitest_1.expect)(mocks.info).not.toHaveBeenCalledWith(vitest_1.expect.stringContaining('-only-testing:AppTests/AppTestsSnapshotTest'));
|
|
149
|
+
});
|
|
150
|
+
(0, vitest_1.it)('uses a scheme placeholder when no verification scheme was detected', async () => {
|
|
151
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));
|
|
152
|
+
mocks.hasSentryCLI.mockReturnValue(true);
|
|
153
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
154
|
+
projectDir,
|
|
155
|
+
nonInteractive: false,
|
|
156
|
+
verificationGuidance: {
|
|
157
|
+
...getVerificationGuidance(projectDir),
|
|
158
|
+
schemeName: undefined,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('-scheme <scheme>'));
|
|
162
|
+
(0, vitest_1.expect)(mocks.info).not.toHaveBeenCalledWith(vitest_1.expect.stringContaining("-scheme '<scheme>'"));
|
|
163
|
+
});
|
|
164
|
+
(0, vitest_1.it)('uses an explicit app id placeholder when the bundle identifier is unavailable', async () => {
|
|
165
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));
|
|
166
|
+
const verificationGuidance = {
|
|
167
|
+
...getVerificationGuidance(projectDir),
|
|
168
|
+
appId: undefined,
|
|
169
|
+
};
|
|
170
|
+
mocks.hasSentryCLI.mockReturnValue(true);
|
|
171
|
+
await (0, snapshots_cli_preflight_1.checkInstalledCLISnapshots)({
|
|
172
|
+
projectDir,
|
|
173
|
+
nonInteractive: false,
|
|
174
|
+
verificationGuidance,
|
|
175
|
+
});
|
|
176
|
+
(0, vitest_1.expect)(mocks.info).toHaveBeenCalledWith(vitest_1.expect.stringContaining('--app-id YOUR_APP_BUNDLE_ID'));
|
|
177
|
+
(0, vitest_1.expect)(mocks.info).not.toHaveBeenCalledWith(vitest_1.expect.stringContaining('com.example.MyApp'));
|
|
178
|
+
(0, vitest_1.expect)(mocks.info).not.toHaveBeenCalledWith(vitest_1.expect.stringContaining('<your-app-bundle-id>'));
|
|
179
|
+
});
|
|
180
|
+
(0, vitest_1.it)('detects existing Fastlane snapshots upload support', () => {
|
|
181
|
+
const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-fastlane-'));
|
|
182
|
+
const fastlaneDir = path.join(projectDir, 'fastlane');
|
|
183
|
+
fs.mkdirSync(fastlaneDir);
|
|
184
|
+
fs.writeFileSync(path.join(fastlaneDir, 'Fastfile'), 'lane :upload_sentry_snapshots do\n sentry_upload_snapshots(path: "snapshot-images")\nend\n');
|
|
185
|
+
(0, vitest_1.expect)((0, snapshots_cli_preflight_1.getSnapshotFastlaneGuidance)(projectDir)).toEqual({
|
|
186
|
+
fastfilePath: path.join(fastlaneDir, 'Fastfile'),
|
|
187
|
+
hasUploadLane: true,
|
|
188
|
+
hasSentryUploadAction: true,
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
//# sourceMappingURL=snapshots-cli-preflight.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshots-cli-preflight.test.js","sourceRoot":"","sources":["../../../../test/apple/snapshots/snapshots-cli-preflight.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\n\nconst mocks = vi.hoisted(() => ({\n askToInstallSentryCLI: vi.fn(),\n executeSync: vi.fn(),\n hasSentryCLI: vi.fn(),\n info: vi.fn(),\n installSentryCLI: vi.fn(),\n setTag: vi.fn(),\n success: vi.fn(),\n warn: vi.fn(),\n}));\n\nvi.mock('@clack/prompts', () => ({\n default: {\n log: {\n info: mocks.info,\n success: mocks.success,\n warn: mocks.warn,\n },\n },\n}));\n\nvi.mock('@sentry/node', () => ({\n setTag: mocks.setTag,\n}));\n\nvi.mock('../../../src/telemetry', () => ({\n traceStep: async (_name: string, callback: () => Promise<boolean>) =>\n await callback(),\n}));\n\nvi.mock('../../../src/utils/bash', () => ({\n executeSync: mocks.executeSync,\n hasSentryCLI: mocks.hasSentryCLI,\n installSentryCLI: mocks.installSentryCLI,\n}));\n\nvi.mock('../../../src/utils/clack', () => ({\n askToInstallSentryCLI: mocks.askToInstallSentryCLI,\n}));\n\nimport {\n checkInstalledCLISnapshots,\n getSnapshotFastlaneGuidance,\n} from '../../../src/apple/snapshots/snapshots-cli-preflight';\n\nfunction getVerificationGuidance(projectDir: string) {\n return {\n appId: 'com.getsentry.App',\n hostedTestTargetName: 'AppTests',\n projectDir,\n projectPath: path.join(projectDir, 'App.xcodeproj'),\n schemeName: 'App',\n snapshotTestClassName: 'AppTestsSnapshotTest',\n };\n}\n\ndescribe('snapshots CLI preflight', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it('offers to install sentry-cli with snapshots-aware warning when missing', async () => {\n mocks.hasSentryCLI.mockReturnValue(false);\n mocks.askToInstallSentryCLI.mockResolvedValue(false);\n\n const projectDir = fs.mkdtempSync(\n path.join(os.tmpdir(), 'snapshot-cli-missing-'),\n );\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: false,\n verificationGuidance: getVerificationGuidance(projectDir),\n });\n\n expect(mocks.askToInstallSentryCLI).toHaveBeenCalledTimes(1);\n expect(mocks.warn).toHaveBeenCalledWith(\n expect.stringContaining('upload snapshots to Sentry'),\n );\n expect(mocks.executeSync).not.toHaveBeenCalled();\n });\n\n it('does not prompt to install sentry-cli in non-interactive mode', async () => {\n mocks.hasSentryCLI.mockReturnValue(false);\n\n const projectDir = fs.mkdtempSync(\n path.join(os.tmpdir(), 'snapshot-cli-non-interactive-'),\n );\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: true,\n verificationGuidance: getVerificationGuidance(projectDir),\n });\n\n expect(mocks.askToInstallSentryCLI).not.toHaveBeenCalled();\n expect(mocks.warn).toHaveBeenCalledWith(\n expect.stringContaining('upload snapshots to Sentry'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('sentry-cli snapshots upload'),\n );\n expect(mocks.executeSync).not.toHaveBeenCalled();\n });\n\n it('verifies snapshots upload support and prefers existing Fastlane guidance', async () => {\n const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));\n const fastlaneDir = path.join(projectDir, 'fastlane');\n fs.mkdirSync(fastlaneDir);\n fs.writeFileSync(\n path.join(fastlaneDir, 'Fastfile'),\n 'platform :ios do\\n lane :upload_sentry_snapshots do |options|\\n sentry_upload_snapshots(path: options[:path])\\n end\\nend\\n',\n );\n mocks.hasSentryCLI.mockReturnValue(true);\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: false,\n verificationGuidance: getVerificationGuidance(projectDir),\n });\n\n expect(mocks.executeSync).toHaveBeenCalledWith(\n 'sentry-cli snapshots upload --help',\n );\n expect(mocks.success).toHaveBeenCalledWith(\n 'sentry-cli snapshots upload is available.',\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('xcodebuild test'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('-project App.xcodeproj'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('-scheme App'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('-only-testing:AppTests/AppTestsSnapshotTest'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining(\n 'bundle exec fastlane ios upload_sentry_snapshots',\n ),\n );\n });\n\n it('prints xcodebuild export and sentry-cli upload guidance', async () => {\n const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));\n mocks.hasSentryCLI.mockReturnValue(true);\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: false,\n verificationGuidance: getVerificationGuidance(projectDir),\n });\n\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('TEST_RUNNER_SNAPSHOTS_EXPORT_DIR'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('-only-testing:AppTests/AppTestsSnapshotTest'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('sentry-cli snapshots upload'),\n );\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('--app-id com.getsentry.App'),\n );\n });\n\n it('uses the provided snapshot test class name in xcodebuild guidance', async () => {\n const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));\n mocks.hasSentryCLI.mockReturnValue(true);\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: false,\n verificationGuidance: {\n ...getVerificationGuidance(projectDir),\n snapshotTestClassName: 'CustomSnapshots',\n },\n });\n\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('-only-testing:AppTests/CustomSnapshots'),\n );\n expect(mocks.info).not.toHaveBeenCalledWith(\n expect.stringContaining('-only-testing:AppTests/AppTestsSnapshotTest'),\n );\n });\n\n it('uses a scheme placeholder when no verification scheme was detected', async () => {\n const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));\n mocks.hasSentryCLI.mockReturnValue(true);\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: false,\n verificationGuidance: {\n ...getVerificationGuidance(projectDir),\n schemeName: undefined,\n },\n });\n\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('-scheme <scheme>'),\n );\n expect(mocks.info).not.toHaveBeenCalledWith(\n expect.stringContaining(\"-scheme '<scheme>'\"),\n );\n });\n\n it('uses an explicit app id placeholder when the bundle identifier is unavailable', async () => {\n const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'snapshot-cli-'));\n const verificationGuidance = {\n ...getVerificationGuidance(projectDir),\n appId: undefined,\n };\n mocks.hasSentryCLI.mockReturnValue(true);\n\n await checkInstalledCLISnapshots({\n projectDir,\n nonInteractive: false,\n verificationGuidance,\n });\n\n expect(mocks.info).toHaveBeenCalledWith(\n expect.stringContaining('--app-id YOUR_APP_BUNDLE_ID'),\n );\n expect(mocks.info).not.toHaveBeenCalledWith(\n expect.stringContaining('com.example.MyApp'),\n );\n expect(mocks.info).not.toHaveBeenCalledWith(\n expect.stringContaining('<your-app-bundle-id>'),\n );\n });\n\n it('detects existing Fastlane snapshots upload support', () => {\n const projectDir = fs.mkdtempSync(\n path.join(os.tmpdir(), 'snapshot-fastlane-'),\n );\n const fastlaneDir = path.join(projectDir, 'fastlane');\n fs.mkdirSync(fastlaneDir);\n fs.writeFileSync(\n path.join(fastlaneDir, 'Fastfile'),\n 'lane :upload_sentry_snapshots do\\n sentry_upload_snapshots(path: \"snapshot-images\")\\nend\\n',\n );\n\n expect(getSnapshotFastlaneGuidance(projectDir)).toEqual({\n fastfilePath: path.join(fastlaneDir, 'Fastfile'),\n hasUploadLane: true,\n hasSentryUploadAction: true,\n });\n });\n});\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const fs = __importStar(require("node:fs"));
|
|
27
|
+
const path = __importStar(require("node:path"));
|
|
28
|
+
const vitest_1 = require("vitest");
|
|
29
|
+
const xcode_manager_1 = require("../../../src/apple/xcode-manager");
|
|
30
|
+
const hosted_test_target_fixture_1 = require("./hosted-test-target-fixture");
|
|
31
|
+
vitest_1.vi.mock('@clack/prompts', () => ({
|
|
32
|
+
log: {
|
|
33
|
+
info: vitest_1.vi.fn(),
|
|
34
|
+
success: vitest_1.vi.fn(),
|
|
35
|
+
step: vitest_1.vi.fn(),
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
function sourceBuildPhaseFiles(xcodeProject) {
|
|
39
|
+
const phase = xcodeProject.objects.PBXSourcesBuildPhase?.['D4E604C92D50CEEC00CAB00F'];
|
|
40
|
+
return phase?.files ?? [];
|
|
41
|
+
}
|
|
42
|
+
(0, vitest_1.describe)('XcodeProject Swift source-file insertion', () => {
|
|
43
|
+
(0, vitest_1.beforeEach)(() => {
|
|
44
|
+
vitest_1.vi.clearAllMocks();
|
|
45
|
+
});
|
|
46
|
+
(0, vitest_1.it)('adds a Swift source file to a classic PBXSourcesBuildPhase once', () => {
|
|
47
|
+
const xcodeProject = new xcode_manager_1.XcodeProject((0, hosted_test_target_fixture_1.copySingleTargetProjectToTemp)('snapshot-source-file-'));
|
|
48
|
+
const filePath = path.join(xcodeProject.baseDir, 'ProjectTests', 'SnapshotTest.swift');
|
|
49
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
50
|
+
fs.writeFileSync(filePath, 'import SnapshottingTests\n', 'utf8');
|
|
51
|
+
const firstResult = xcodeProject.addSwiftSourceFileToTarget({
|
|
52
|
+
targetName: 'Project',
|
|
53
|
+
filePath,
|
|
54
|
+
});
|
|
55
|
+
const secondResult = xcodeProject.addSwiftSourceFileToTarget({
|
|
56
|
+
targetName: 'Project',
|
|
57
|
+
filePath,
|
|
58
|
+
});
|
|
59
|
+
(0, vitest_1.expect)(firstResult).toEqual({ changed: true, included: true });
|
|
60
|
+
(0, vitest_1.expect)(secondResult).toEqual({ changed: false, included: true });
|
|
61
|
+
(0, vitest_1.expect)(sourceBuildPhaseFiles(xcodeProject)).toHaveLength(1);
|
|
62
|
+
(0, vitest_1.expect)(Object.values(xcodeProject.objects.PBXFileReference ?? {}).filter((fileReference) => typeof fileReference === 'object' &&
|
|
63
|
+
fileReference.path === 'ProjectTests/SnapshotTest.swift')).toHaveLength(1);
|
|
64
|
+
});
|
|
65
|
+
(0, vitest_1.it)('uses synchronized root group inclusion when the file is inside a target synchronized folder', () => {
|
|
66
|
+
const xcodeProject = new xcode_manager_1.XcodeProject((0, hosted_test_target_fixture_1.copySingleTargetProjectToTemp)('snapshot-source-file-'));
|
|
67
|
+
const filePath = path.join(xcodeProject.baseDir, 'Sources', 'SnapshotTest.swift');
|
|
68
|
+
fs.writeFileSync(filePath, 'import SnapshottingTests\n', 'utf8');
|
|
69
|
+
const result = xcodeProject.addSwiftSourceFileToTarget({
|
|
70
|
+
targetName: 'Project',
|
|
71
|
+
filePath,
|
|
72
|
+
});
|
|
73
|
+
(0, vitest_1.expect)(result).toEqual({ changed: false, included: true });
|
|
74
|
+
(0, vitest_1.expect)(sourceBuildPhaseFiles(xcodeProject)).toEqual([]);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=source-file-insertion.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-file-insertion.test.js","sourceRoot":"","sources":["../../../../test/apple/snapshots/source-file-insertion.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { beforeEach, describe, expect, it, vi } from 'vitest';\nimport type { PBXSourcesBuildPhase } from 'xcode';\n\nimport { XcodeProject } from '../../../src/apple/xcode-manager';\nimport { copySingleTargetProjectToTemp } from './hosted-test-target-fixture';\n\nvi.mock('@clack/prompts', () => ({\n log: {\n info: vi.fn(),\n success: vi.fn(),\n step: vi.fn(),\n },\n}));\n\nfunction sourceBuildPhaseFiles(xcodeProject: XcodeProject): unknown[] {\n const phase = xcodeProject.objects.PBXSourcesBuildPhase?.[\n 'D4E604C92D50CEEC00CAB00F'\n ] as PBXSourcesBuildPhase | undefined;\n return phase?.files ?? [];\n}\n\ndescribe('XcodeProject Swift source-file insertion', () => {\n beforeEach(() => {\n vi.clearAllMocks();\n });\n\n it('adds a Swift source file to a classic PBXSourcesBuildPhase once', () => {\n const xcodeProject = new XcodeProject(\n copySingleTargetProjectToTemp('snapshot-source-file-'),\n );\n const filePath = path.join(\n xcodeProject.baseDir,\n 'ProjectTests',\n 'SnapshotTest.swift',\n );\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, 'import SnapshottingTests\\n', 'utf8');\n\n const firstResult = xcodeProject.addSwiftSourceFileToTarget({\n targetName: 'Project',\n filePath,\n });\n const secondResult = xcodeProject.addSwiftSourceFileToTarget({\n targetName: 'Project',\n filePath,\n });\n\n expect(firstResult).toEqual({ changed: true, included: true });\n expect(secondResult).toEqual({ changed: false, included: true });\n expect(sourceBuildPhaseFiles(xcodeProject)).toHaveLength(1);\n expect(\n Object.values(xcodeProject.objects.PBXFileReference ?? {}).filter(\n (fileReference) =>\n typeof fileReference === 'object' &&\n fileReference.path === 'ProjectTests/SnapshotTest.swift',\n ),\n ).toHaveLength(1);\n });\n\n it('uses synchronized root group inclusion when the file is inside a target synchronized folder', () => {\n const xcodeProject = new XcodeProject(\n copySingleTargetProjectToTemp('snapshot-source-file-'),\n );\n const filePath = path.join(\n xcodeProject.baseDir,\n 'Sources',\n 'SnapshotTest.swift',\n );\n fs.writeFileSync(filePath, 'import SnapshottingTests\\n', 'utf8');\n\n const result = xcodeProject.addSwiftSourceFileToTarget({\n targetName: 'Project',\n filePath,\n });\n\n expect(result).toEqual({ changed: false, included: true });\n expect(sourceBuildPhaseFiles(xcodeProject)).toEqual([]);\n });\n});\n"]}
|