@sentry/wizard 6.4.0 → 6.6.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 +18 -0
- package/dist/e2e-tests/tests/angular-17.test.js +1 -0
- package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
- package/dist/e2e-tests/tests/angular-19.test.js +1 -0
- package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
- package/dist/e2e-tests/tests/expo.test.js +13 -3
- package/dist/e2e-tests/tests/expo.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-3.test.js +6 -0
- package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
- package/dist/e2e-tests/tests/nuxt-4.test.js +6 -0
- package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
- package/dist/e2e-tests/tests/react-native.test.js +14 -4
- package/dist/e2e-tests/tests/react-native.test.js.map +1 -1
- package/dist/e2e-tests/tests/remix.test.js +2 -1
- package/dist/e2e-tests/tests/remix.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js +13 -2
- package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js +4 -0
- package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
- package/dist/src/android/android-wizard.js +9 -1
- package/dist/src/android/android-wizard.js.map +1 -1
- package/dist/src/android/manifest.d.ts +1 -1
- package/dist/src/android/manifest.js +2 -2
- package/dist/src/android/manifest.js.map +1 -1
- package/dist/src/android/templates.d.ts +1 -1
- package/dist/src/android/templates.js +4 -1
- package/dist/src/android/templates.js.map +1 -1
- package/dist/src/angular/codemods/main.js +1 -0
- package/dist/src/angular/codemods/main.js.map +1 -1
- package/dist/src/apple/templates.js +0 -2
- package/dist/src/apple/templates.js.map +1 -1
- package/dist/src/nextjs/nextjs-wizard.js +1 -1
- package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
- package/dist/src/nextjs/templates.js +6 -4
- package/dist/src/nextjs/templates.js.map +1 -1
- package/dist/src/nuxt/templates.js +10 -2
- package/dist/src/nuxt/templates.js.map +1 -1
- package/dist/src/react-native/javascript.d.ts +6 -4
- package/dist/src/react-native/javascript.js +11 -7
- package/dist/src/react-native/javascript.js.map +1 -1
- package/dist/src/react-native/react-native-wizard.js +9 -0
- package/dist/src/react-native/react-native-wizard.js.map +1 -1
- package/dist/src/react-native/xcode.js +5 -3
- package/dist/src/react-native/xcode.js.map +1 -1
- package/dist/src/remix/sdk-setup.js +1 -0
- package/dist/src/remix/sdk-setup.js.map +1 -1
- package/dist/src/sveltekit/sdk-setup/setup.d.ts +6 -0
- package/dist/src/sveltekit/sdk-setup/setup.js +4 -1
- package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
- package/dist/src/sveltekit/templates.js +9 -0
- package/dist/src/sveltekit/templates.js.map +1 -1
- package/dist/src/utils/clack/index.js +4 -1
- package/dist/src/utils/clack/index.js.map +1 -1
- 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 +113 -17
- package/dist/test/angular/angular-wizard.test.js.map +1 -1
- package/dist/test/apple/code-tools.test.js +0 -3
- package/dist/test/apple/code-tools.test.js.map +1 -1
- package/dist/test/apple/templates.test.js +0 -4
- package/dist/test/apple/templates.test.js.map +1 -1
- package/dist/test/nextjs/templates.test.js +33 -22
- package/dist/test/nextjs/templates.test.js.map +1 -1
- package/dist/test/nuxt/templates.test.js +50 -10
- package/dist/test/nuxt/templates.test.js.map +1 -1
- package/dist/test/react-native/javascript.test.js +225 -0
- package/dist/test/react-native/javascript.test.js.map +1 -1
- package/dist/test/react-native/xcode.test.js +20 -2
- package/dist/test/react-native/xcode.test.js.map +1 -1
- package/dist/test/remix/client-entry.test.js +10 -4
- package/dist/test/remix/client-entry.test.js.map +1 -1
- package/dist/test/sveltekit/templates.test.js +214 -0
- package/dist/test/sveltekit/templates.test.js.map +1 -1
- package/package.json +3 -3
|
@@ -36,6 +36,9 @@ Sentry.init({
|
|
|
36
36
|
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
37
37
|
sendDefaultPii: true,
|
|
38
38
|
|
|
39
|
+
// Enable Logs
|
|
40
|
+
enableLogs: false,
|
|
41
|
+
|
|
39
42
|
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
40
43
|
// spotlight: __DEV__,
|
|
41
44
|
});
|
|
@@ -81,6 +84,9 @@ Sentry.init({
|
|
|
81
84
|
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
82
85
|
sendDefaultPii: true,
|
|
83
86
|
|
|
87
|
+
// Enable Logs
|
|
88
|
+
enableLogs: false,
|
|
89
|
+
|
|
84
90
|
// Configure Session Replay
|
|
85
91
|
replaysSessionSampleRate: 0.1,
|
|
86
92
|
replaysOnErrorSampleRate: 1,
|
|
@@ -133,6 +139,9 @@ Sentry.init({
|
|
|
133
139
|
// Adds more context data to events (IP address, cookies, user, etc.)
|
|
134
140
|
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
135
141
|
sendDefaultPii: true,
|
|
142
|
+
|
|
143
|
+
// Enable Logs
|
|
144
|
+
enableLogs: false,
|
|
136
145
|
integrations: [Sentry.feedbackIntegration()],
|
|
137
146
|
|
|
138
147
|
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
@@ -153,6 +162,108 @@ export default App;`;
|
|
|
153
162
|
enableFeedbackWidget: true,
|
|
154
163
|
})).toBe(expectedOutput);
|
|
155
164
|
});
|
|
165
|
+
(0, vitest_1.it)('adds sdk import and sentry init under last import in the file and enables logs', () => {
|
|
166
|
+
const input = `import * as React from 'react';
|
|
167
|
+
|
|
168
|
+
const test = 'test';
|
|
169
|
+
|
|
170
|
+
import { View } from 'react-native';
|
|
171
|
+
|
|
172
|
+
const App = () => {
|
|
173
|
+
return (
|
|
174
|
+
<View>
|
|
175
|
+
Test App
|
|
176
|
+
</View>
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export default App;`;
|
|
181
|
+
const expectedOutput = `import * as React from 'react';
|
|
182
|
+
|
|
183
|
+
const test = 'test';
|
|
184
|
+
|
|
185
|
+
import { View } from 'react-native';
|
|
186
|
+
import * as Sentry from '@sentry/react-native';
|
|
187
|
+
|
|
188
|
+
Sentry.init({
|
|
189
|
+
dsn: 'dsn',
|
|
190
|
+
|
|
191
|
+
// Adds more context data to events (IP address, cookies, user, etc.)
|
|
192
|
+
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
193
|
+
sendDefaultPii: true,
|
|
194
|
+
|
|
195
|
+
// Enable Logs
|
|
196
|
+
enableLogs: true,
|
|
197
|
+
|
|
198
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
199
|
+
// spotlight: __DEV__,
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const App = () => {
|
|
203
|
+
return (
|
|
204
|
+
<View>
|
|
205
|
+
Test App
|
|
206
|
+
</View>
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export default App;`;
|
|
211
|
+
(0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
|
|
212
|
+
dsn: 'dsn',
|
|
213
|
+
enableLogs: true,
|
|
214
|
+
})).toBe(expectedOutput);
|
|
215
|
+
});
|
|
216
|
+
(0, vitest_1.it)('adds sdk import and sentry init with logs disabled', () => {
|
|
217
|
+
const input = `import * as React from 'react';
|
|
218
|
+
|
|
219
|
+
const test = 'test';
|
|
220
|
+
|
|
221
|
+
import { View } from 'react-native';
|
|
222
|
+
|
|
223
|
+
const App = () => {
|
|
224
|
+
return (
|
|
225
|
+
<View>
|
|
226
|
+
Test App
|
|
227
|
+
</View>
|
|
228
|
+
);
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export default App;`;
|
|
232
|
+
const expectedOutput = `import * as React from 'react';
|
|
233
|
+
|
|
234
|
+
const test = 'test';
|
|
235
|
+
|
|
236
|
+
import { View } from 'react-native';
|
|
237
|
+
import * as Sentry from '@sentry/react-native';
|
|
238
|
+
|
|
239
|
+
Sentry.init({
|
|
240
|
+
dsn: 'dsn',
|
|
241
|
+
|
|
242
|
+
// Adds more context data to events (IP address, cookies, user, etc.)
|
|
243
|
+
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
244
|
+
sendDefaultPii: true,
|
|
245
|
+
|
|
246
|
+
// Enable Logs
|
|
247
|
+
enableLogs: false,
|
|
248
|
+
|
|
249
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
250
|
+
// spotlight: __DEV__,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const App = () => {
|
|
254
|
+
return (
|
|
255
|
+
<View>
|
|
256
|
+
Test App
|
|
257
|
+
</View>
|
|
258
|
+
);
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
export default App;`;
|
|
262
|
+
(0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
|
|
263
|
+
dsn: 'dsn',
|
|
264
|
+
enableLogs: false,
|
|
265
|
+
})).toBe(expectedOutput);
|
|
266
|
+
});
|
|
156
267
|
(0, vitest_1.it)('adds sdk import and sentry init under last import in the file and enables session replay and feedback widget', () => {
|
|
157
268
|
const input = `import * as React from 'react';
|
|
158
269
|
|
|
@@ -183,6 +294,9 @@ Sentry.init({
|
|
|
183
294
|
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
184
295
|
sendDefaultPii: true,
|
|
185
296
|
|
|
297
|
+
// Enable Logs
|
|
298
|
+
enableLogs: false,
|
|
299
|
+
|
|
186
300
|
// Configure Session Replay
|
|
187
301
|
replaysSessionSampleRate: 0.1,
|
|
188
302
|
replaysOnErrorSampleRate: 1,
|
|
@@ -207,6 +321,117 @@ export default App;`;
|
|
|
207
321
|
enableFeedbackWidget: true,
|
|
208
322
|
})).toBe(expectedOutput);
|
|
209
323
|
});
|
|
324
|
+
(0, vitest_1.it)('adds sdk import and sentry init with all features enabled', () => {
|
|
325
|
+
const input = `import * as React from 'react';
|
|
326
|
+
|
|
327
|
+
const test = 'test';
|
|
328
|
+
|
|
329
|
+
import { View } from 'react-native';
|
|
330
|
+
|
|
331
|
+
const App = () => {
|
|
332
|
+
return (
|
|
333
|
+
<View>
|
|
334
|
+
Test App
|
|
335
|
+
</View>
|
|
336
|
+
);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
export default App;`;
|
|
340
|
+
const expectedOutput = `import * as React from 'react';
|
|
341
|
+
|
|
342
|
+
const test = 'test';
|
|
343
|
+
|
|
344
|
+
import { View } from 'react-native';
|
|
345
|
+
import * as Sentry from '@sentry/react-native';
|
|
346
|
+
|
|
347
|
+
Sentry.init({
|
|
348
|
+
dsn: 'dsn',
|
|
349
|
+
|
|
350
|
+
// Adds more context data to events (IP address, cookies, user, etc.)
|
|
351
|
+
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
352
|
+
sendDefaultPii: true,
|
|
353
|
+
|
|
354
|
+
// Enable Logs
|
|
355
|
+
enableLogs: true,
|
|
356
|
+
|
|
357
|
+
// Configure Session Replay
|
|
358
|
+
replaysSessionSampleRate: 0.1,
|
|
359
|
+
replaysOnErrorSampleRate: 1,
|
|
360
|
+
integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],
|
|
361
|
+
|
|
362
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
363
|
+
// spotlight: __DEV__,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
const App = () => {
|
|
367
|
+
return (
|
|
368
|
+
<View>
|
|
369
|
+
Test App
|
|
370
|
+
</View>
|
|
371
|
+
);
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
export default App;`;
|
|
375
|
+
(0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
|
|
376
|
+
dsn: 'dsn',
|
|
377
|
+
enableSessionReplay: true,
|
|
378
|
+
enableFeedbackWidget: true,
|
|
379
|
+
enableLogs: true,
|
|
380
|
+
})).toBe(expectedOutput);
|
|
381
|
+
});
|
|
382
|
+
(0, vitest_1.it)('adds sdk import and sentry init with logs enabled and other features disabled', () => {
|
|
383
|
+
const input = `import * as React from 'react';
|
|
384
|
+
|
|
385
|
+
const test = 'test';
|
|
386
|
+
|
|
387
|
+
import { View } from 'react-native';
|
|
388
|
+
|
|
389
|
+
const App = () => {
|
|
390
|
+
return (
|
|
391
|
+
<View>
|
|
392
|
+
Test App
|
|
393
|
+
</View>
|
|
394
|
+
);
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
export default App;`;
|
|
398
|
+
const expectedOutput = `import * as React from 'react';
|
|
399
|
+
|
|
400
|
+
const test = 'test';
|
|
401
|
+
|
|
402
|
+
import { View } from 'react-native';
|
|
403
|
+
import * as Sentry from '@sentry/react-native';
|
|
404
|
+
|
|
405
|
+
Sentry.init({
|
|
406
|
+
dsn: 'dsn',
|
|
407
|
+
|
|
408
|
+
// Adds more context data to events (IP address, cookies, user, etc.)
|
|
409
|
+
// For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/
|
|
410
|
+
sendDefaultPii: true,
|
|
411
|
+
|
|
412
|
+
// Enable Logs
|
|
413
|
+
enableLogs: true,
|
|
414
|
+
|
|
415
|
+
// uncomment the line below to enable Spotlight (https://spotlightjs.com)
|
|
416
|
+
// spotlight: __DEV__,
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
const App = () => {
|
|
420
|
+
return (
|
|
421
|
+
<View>
|
|
422
|
+
Test App
|
|
423
|
+
</View>
|
|
424
|
+
);
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export default App;`;
|
|
428
|
+
(0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, {
|
|
429
|
+
dsn: 'dsn',
|
|
430
|
+
enableSessionReplay: false,
|
|
431
|
+
enableFeedbackWidget: false,
|
|
432
|
+
enableLogs: true,
|
|
433
|
+
})).toBe(expectedOutput);
|
|
434
|
+
});
|
|
210
435
|
(0, vitest_1.it)('does not add sdk import and sentry init in the file without imports', () => {
|
|
211
436
|
const input = `export const test = 'test';`;
|
|
212
437
|
(0, vitest_1.expect)((0, javascript_1.addSentryInitWithSdkImport)(input, { dsn: 'dsn' })).toBe(input);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"javascript.test.js","sourceRoot":"","sources":["../../../test/react-native/javascript.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addSentryInitWithSdkImport,\n checkAndWrapRootComponent,\n doesContainSentryWrap,\n doesJsCodeIncludeSdkSentryImport,\n SentryWrapResult,\n} from '../../src/react-native/javascript';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport * as t from '@babel/types';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('react-native javascript', () => {\n describe('addSentryInitWithSdkImport', () => {\n it('adds sdk import and sentry init under last import in the file', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(\n expectedOutput,\n );\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n integrations: [Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay and feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('does not add sdk import and sentry init in the file without imports', () => {\n const input = `export const test = 'test';`;\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n\n it('does not add sdk import and sentry init in the empty file', () => {\n const input = '';\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n });\n\n describe('doesJsCodeIncludeSdkSentryImport', () => {\n it('returns true if code has sdk import', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns true if code has sdk require', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nconst Sentry = require('@sentry/react-native');\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns false if code does not have sdk import', () => {\n const input = `export const test = 'test';`;\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n\n it('returns false for empty file', () => {\n const input = '';\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n });\n\n describe('addSentryWrap', () => {\n it('wraps the root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default AnotheWrapper.wrap(App);`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(AnotheWrapper.wrap(App));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a complex root function', () => {\n // This is the default export for a new Expo 52 project\n const mod =\n parseModule(`import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}\n`);\n\n const expectedOutput = `import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default Sentry.wrap(function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous complex function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a default class export', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('does not wrap a root app component if not found', () => {\n const input = `import * as React from 'react';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport { App };`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap a root app component if already wrapped', () => {\n const input = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.AlreadyWrapped);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap the root app component in an empty file', () => {\n const mod = parseModule(``);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(``);\n });\n });\n\n it('does detect Sentry.wrap if exists', () => {\n const mod = parseModule(`export default Sentry.wrap(App);`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeTruthy();\n });\n\n it('does not detect Sentry.wrap if not present', () => {\n const mod = parseModule(`export default App;`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeFalsy();\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"javascript.test.js","sourceRoot":"","sources":["../../../test/react-native/javascript.test.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addSentryInitWithSdkImport,\n checkAndWrapRootComponent,\n doesContainSentryWrap,\n doesJsCodeIncludeSdkSentryImport,\n SentryWrapResult,\n} from '../../src/react-native/javascript';\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport { generateCode, parseModule } from 'magicast';\nimport * as t from '@babel/types';\nimport { describe, expect, it } from 'vitest';\n\ndescribe('react-native javascript', () => {\n describe('addSentryInitWithSdkImport', () => {\n it('adds sdk import and sentry init under last import in the file', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(\n expectedOutput,\n );\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n integrations: [Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables logs', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableLogs: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init with logs disabled', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableLogs: false,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init under last import in the file and enables session replay and feedback widget', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: false,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n enableFeedbackWidget: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init with all features enabled', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: true,\n\n // Configure Session Replay\n replaysSessionSampleRate: 0.1,\n replaysOnErrorSampleRate: 1,\n integrations: [Sentry.mobileReplayIntegration(), Sentry.feedbackIntegration()],\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: true,\n enableFeedbackWidget: true,\n enableLogs: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('adds sdk import and sentry init with logs enabled and other features disabled', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n const expectedOutput = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'dsn',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // Enable Logs\n enableLogs: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n addSentryInitWithSdkImport(input, {\n dsn: 'dsn',\n enableSessionReplay: false,\n enableFeedbackWidget: false,\n enableLogs: true,\n }),\n ).toBe(expectedOutput);\n });\n\n it('does not add sdk import and sentry init in the file without imports', () => {\n const input = `export const test = 'test';`;\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n\n it('does not add sdk import and sentry init in the empty file', () => {\n const input = '';\n expect(addSentryInitWithSdkImport(input, { dsn: 'dsn' })).toBe(input);\n });\n });\n\n describe('doesJsCodeIncludeSdkSentryImport', () => {\n it('returns true if code has sdk import', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nimport * as Sentry from '@sentry/react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns true if code has sdk require', () => {\n const input = `import * as React from 'react';\n\nconst test = 'test';\n\nimport { View } from 'react-native';\nconst Sentry = require('@sentry/react-native');\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`;\n\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(true);\n });\n\n it('returns false if code does not have sdk import', () => {\n const input = `export const test = 'test';`;\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n\n it('returns false for empty file', () => {\n const input = '';\n expect(\n doesJsCodeIncludeSdkSentryImport(input, {\n sdkPackageName: '@sentry/react-native',\n }),\n ).toBe(false);\n });\n });\n\n describe('addSentryWrap', () => {\n it('wraps the root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default App;`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app component', () => {\n const mod = parseModule(`import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default AnotheWrapper.wrap(App);`);\n\n const expectedOutput = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(AnotheWrapper.wrap(App));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app named function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrapper(function RootLayout() {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n return (\n <View>\n Test App\n </View>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a wrapped root app anonymous function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n});`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(Another.wrap(() => {\n return (\n <View>\n Test App\n </View>\n );\n}));`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a complex root function', () => {\n // This is the default export for a new Expo 52 project\n const mod =\n parseModule(`import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}\n`);\n\n const expectedOutput = `import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';\nimport { useFonts } from 'expo-font';\nimport { Stack } from 'expo-router';\nimport * as SplashScreen from 'expo-splash-screen';\nimport { StatusBar } from 'expo-status-bar';\nimport { useEffect } from 'react';\nimport 'react-native-reanimated';\n\nimport { useColorScheme } from '@/hooks/useColorScheme';\nimport * as Sentry from '@sentry/react-native';\n\nSentry.init({\n dsn: 'https://sentry.io/123',\n\n // Adds more context data to events (IP address, cookies, user, etc.)\n // For more information, visit: https://docs.sentry.io/platforms/react-native/data-management/data-collected/\n sendDefaultPii: true,\n\n // uncomment the line below to enable Spotlight (https://spotlightjs.com)\n // spotlight: __DEV__,\n});\n\n// Prevent the splash screen from auto-hiding before asset loading is complete.\nSplashScreen.preventAutoHideAsync();\n\nexport default Sentry.wrap(function RootLayout() {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a root app anonymous complex function', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default () => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(() => {\n const colorScheme = useColorScheme();\n const [loaded] = useFonts({\n SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),\n });\n\n useEffect(() => {\n if (loaded) {\n SplashScreen.hideAsync();\n }\n }, [loaded]);\n\n if (!loaded) {\n return null;\n }\n\n return (\n <ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>\n <Stack>\n <Stack.Screen name=\"(tabs)\" options={{ headerShown: false }} />\n <Stack.Screen name=\"+not-found\" />\n </Stack>\n <StatusBar style=\"auto\" />\n </ThemeProvider>\n );\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('wraps a default class export', () => {\n const mod = parseModule(`import * as Sentry from '@sentry/react-native';\n\nexport default class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n}`);\n\n const expectedOutput = `import * as Sentry from '@sentry/react-native';\n\nexport default Sentry.wrap(class RootLayout extends React.Component {\n render() {\n return (\n <View>\n Test App\n </View>\n );\n }\n});`;\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.Success);\n expect(generateCode(mod.$ast).code).toBe(expectedOutput);\n });\n\n it('does not wrap a root app component if not found', () => {\n const input = `import * as React from 'react';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport { App };`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap a root app component if already wrapped', () => {\n const input = `import * as React from 'react';\nimport * as Sentry from '@sentry/react-native';\n\nimport { View } from 'react-native';\n\nconst App = () => {\n return (\n <View>\n Test App\n </View>\n );\n};\n\nexport default Sentry.wrap(App);`;\n const mod = parseModule(input);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.AlreadyWrapped);\n expect(generateCode(mod.$ast).code).toBe(input);\n });\n\n it('does not wrap the root app component in an empty file', () => {\n const mod = parseModule(``);\n\n const result = checkAndWrapRootComponent(mod);\n\n expect(result).toBe(SentryWrapResult.NotFound);\n expect(generateCode(mod.$ast).code).toBe(``);\n });\n });\n\n it('does detect Sentry.wrap if exists', () => {\n const mod = parseModule(`export default Sentry.wrap(App);`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeTruthy();\n });\n\n it('does not detect Sentry.wrap if not present', () => {\n const mod = parseModule(`export default App;`);\n\n const result = doesContainSentryWrap(mod.$ast as t.Program);\n\n expect(result).toBeFalsy();\n });\n});\n"]}
|
|
@@ -60,9 +60,27 @@ REACT_NATIVE_XCODE="../node_modules/react-native/scripts/react-native-xcode.sh"
|
|
|
60
60
|
const expectedOutput = `set -e
|
|
61
61
|
|
|
62
62
|
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
63
|
-
|
|
63
|
+
SENTRY_XCODE="../node_modules/@sentry/react-native/scripts/sentry-xcode.sh"
|
|
64
|
+
|
|
65
|
+
/bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"`;
|
|
66
|
+
(0, vitest_1.expect)((0, xcode_1.addSentryWithBundledScriptsToBundleShellScript)(input)).toBe(expectedOutput);
|
|
67
|
+
});
|
|
68
|
+
(0, vitest_1.it)('adds sentry cli to rn bundle build phase for versions of RN that use REACT_NATIVE_PATH env variable', () => {
|
|
69
|
+
const input = `set -e
|
|
70
|
+
|
|
71
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
72
|
+
REACT_NATIVE_XCODE="$REACT_NATIVE_PATH/scripts/react-native-xcode.sh"
|
|
73
|
+
|
|
74
|
+
/bin/sh -c "$WITH_ENVIRONMENT $REACT_NATIVE_XCODE"`;
|
|
75
|
+
// actual shell script looks like this:
|
|
76
|
+
// /bin/sh -c "$WITH_ENVIRONMENT \"$REACT_NATIVE_XCODE\""
|
|
77
|
+
// but during parsing xcode library removes the quotes
|
|
78
|
+
const expectedOutput = `set -e
|
|
79
|
+
|
|
80
|
+
WITH_ENVIRONMENT="../node_modules/react-native/scripts/xcode/with-environment.sh"
|
|
81
|
+
SENTRY_XCODE="$REACT_NATIVE_PATH/../@sentry/react-native/scripts/sentry-xcode.sh"
|
|
64
82
|
|
|
65
|
-
/bin/sh -c "$WITH_ENVIRONMENT
|
|
83
|
+
/bin/sh -c "$WITH_ENVIRONMENT $SENTRY_XCODE"`;
|
|
66
84
|
(0, vitest_1.expect)((0, xcode_1.addSentryWithBundledScriptsToBundleShellScript)(input)).toBe(expectedOutput);
|
|
67
85
|
});
|
|
68
86
|
(0, vitest_1.it)('does not add sentry cli to rn bundle build phase if $REACT_NATIVE_XCODE is not present and shows code snippet', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcode.test.js","sourceRoot":"","sources":["../../../test/react-native/xcode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-useless-escape */\nimport { describe, expect, it, afterEach, beforeEach, vi } from 'vitest';\nimport {\n addSentryWithBundledScriptsToBundleShellScript,\n doesBundlePhaseIncludeSentry,\n findBundlePhase,\n findDebugFilesUploadPhase,\n ErrorPatchSnippet,\n} from '../../src/react-native/xcode';\nimport chalk from 'chalk';\nimport { makeCodeSnippet } from '../../src/utils/clack';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n\nvi.mock('@clack/prompts', async () => ({\n __esModule: true,\n ...(await vi.importActual<typeof clack>('@clack/prompts')),\n}));\n\ndescribe('react-native xcode', () => {\n beforeEach(() => {\n vi.spyOn(clack.log, 'error').mockImplementation(() => {\n /* empty */\n });\n });\n\n afterEach(() => {\n vi.clearAllMocks();\n });\n\n describe('addSentryBundledScriptsToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\\\\\"\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('does not add sentry cli to rn bundle build phase if $REACT_NATIVE_XCODE is not present and shows code snippet', () => {\n const input = `set -e\n \n WITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\n REACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n \n /bin/sh -c \"$WITH_ENVIRONMENT $NOT_REACT_NATIVE_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(`WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT ${plus(\n `\\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh `,\n )}$REACT_NATIVE_XCODE${plus(`\\\\\"`)}\"\n`);\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n\n it('adds sentry cli to expo bundle build phase', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n\\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n const expectedOutput = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\` \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('if patching fails it does not add sentry cli to expo bundle build phase and shows code snippet', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n`;\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(\n `${plus(\n `/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\``,\n )} \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\``,\n );\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n });\n\n describe('findBundlePhase', () => {\n it('returns build phase with react native xcode shell script', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n const expected = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n };\n\n expect(findBundlePhase(inputMap)).toEqual(expected);\n });\n\n it('returns undefined if bundle phase not present', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n // note different path to the script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/unknown/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n expect(findBundlePhase(inputMap)).toBeUndefined();\n });\n });\n\n describe('doesBundlePhaseIncludeSentry', () => {\n it('returns true for script containing sentry cli calling react native xcode command', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI $REACT_NATIVE_XCODE\\\"\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns true for script containing sentry bundled script', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\\\\\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns false', () => {\n const input = {\n // note sentry-cli can be part of the script but doesn't call react native xcode script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\nsentry-cli --version\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeFalsy();\n });\n });\n\n describe('findDebugFilesUploadPhase', () => {\n it('returns debug files build phase using debug files command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase with sentry-cli absolute path', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using dsym command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using bundled scripts', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns undefined if build phase not present', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n // sentry-cli present but with different command\n shellScript: 'sentry-cli sourcempas upload',\n },\n };\n\n expect(findDebugFilesUploadPhase(input)).toBeUndefined();\n });\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"xcode.test.js","sourceRoot":"","sources":["../../../test/react-native/xcode.test.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable no-useless-escape */\nimport { describe, expect, it, afterEach, beforeEach, vi } from 'vitest';\nimport {\n addSentryWithBundledScriptsToBundleShellScript,\n doesBundlePhaseIncludeSentry,\n findBundlePhase,\n findDebugFilesUploadPhase,\n ErrorPatchSnippet,\n} from '../../src/react-native/xcode';\nimport chalk from 'chalk';\nimport { makeCodeSnippet } from '../../src/utils/clack';\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\n\nvi.mock('@clack/prompts', async () => ({\n __esModule: true,\n ...(await vi.importActual<typeof clack>('@clack/prompts')),\n}));\n\ndescribe('react-native xcode', () => {\n beforeEach(() => {\n vi.spyOn(clack.log, 'error').mockImplementation(() => {\n /* empty */\n });\n });\n\n afterEach(() => {\n vi.clearAllMocks();\n });\n\n describe('addSentryBundledScriptsToBundleShellScript', () => {\n it('adds sentry cli to rn bundle build phase', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nSENTRY_XCODE=\"../node_modules/@sentry/react-native/scripts/sentry-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $SENTRY_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('adds sentry cli to rn bundle build phase for versions of RN that use REACT_NATIVE_PATH env variable', () => {\n const input = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"`;\n // actual shell script looks like this:\n // /bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n // but during parsing xcode library removes the quotes\n const expectedOutput = `set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nSENTRY_XCODE=\"$REACT_NATIVE_PATH/../@sentry/react-native/scripts/sentry-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $SENTRY_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('does not add sentry cli to rn bundle build phase if $REACT_NATIVE_XCODE is not present and shows code snippet', () => {\n const input = `set -e\n \n WITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\n REACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n \n /bin/sh -c \"$WITH_ENVIRONMENT $NOT_REACT_NATIVE_XCODE\"`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(`WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT ${plus(\n `\\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh `,\n )}$REACT_NATIVE_XCODE${plus(`\\\\\"`)}\"\n`);\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n\n it('adds sentry cli to expo bundle build phase', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n\\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n const expectedOutput = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n# Source .xcode.env.updates if it exists to allow\n# SKIP_BUNDLING to be unset if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.updates\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.updates\"\nfi\n# Source local changes to allow overrides\n# if needed\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\` \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\`\n`;\n\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toBe(\n expectedOutput,\n );\n });\n\n it('if patching fails it does not add sentry cli to expo bundle build phase and shows code snippet', () => {\n const input = `\nif [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios absolute | tail -n 1)\"\nfi\n`;\n expect(addSentryWithBundledScriptsToBundleShellScript(input)).toEqual(\n new ErrorPatchSnippet(\n makeCodeSnippet(true, (unchanged, plus, _minus) => {\n return unchanged(\n `${plus(\n `/bin/sh \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode.sh'\"\\``,\n )} \\`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"\\``,\n );\n }),\n ),\n );\n expect(clack.log.error).toHaveBeenCalledWith(\n `Failed to patch ${chalk.cyan(\n 'Bundle React Native code and images',\n )} build phase.`,\n );\n });\n });\n\n describe('findBundlePhase', () => {\n it('returns build phase with react native xcode shell script', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n const expected = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n };\n\n expect(findBundlePhase(inputMap)).toEqual(expected);\n });\n\n it('returns undefined if bundle phase not present', () => {\n const inputMap = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: 'bar',\n },\n 3: {\n // note different path to the script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/unknown/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\n`,\n },\n 4: {\n shellScript: 'qux',\n },\n };\n\n expect(findBundlePhase(inputMap)).toBeUndefined();\n });\n });\n\n describe('doesBundlePhaseIncludeSentry', () => {\n it('returns true for script containing sentry cli calling react native xcode command', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$SENTRY_CLI $REACT_NATIVE_XCODE\\\"\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns true for script containing sentry bundled script', () => {\n const input = {\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\nSENTRY_CLI=\"sentry-cli react-native xcode\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\\\"/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode.sh $REACT_NATIVE_XCODE\"\\\\\"\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeTruthy();\n });\n\n it('returns false', () => {\n const input = {\n // note sentry-cli can be part of the script but doesn't call react native xcode script\n shellScript: `set -e\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT \\\"$REACT_NATIVE_XCODE\\\"\"\n\nsentry-cli --version\n`,\n };\n expect(doesBundlePhaseIncludeSentry(input)).toBeFalsy();\n });\n });\n\n describe('findDebugFilesUploadPhase', () => {\n it('returns debug files build phase using debug files command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase with sentry-cli absolute path', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\n/path/to/bin/sentry-cli debug-files upload path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using dsym command', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `set -e\nsentry-cli upload-dsym path/to/dsym --include-sources\n`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns debug files build phase using bundled scripts', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n };\n const expected = [\n '2',\n {\n shellScript: `/bin/sh ../node_modules/@sentry/react-native/scripts/sentry-xcode-debug-files.sh`,\n },\n ];\n expect(findDebugFilesUploadPhase(input)).toEqual(expected);\n });\n\n it('returns undefined if build phase not present', () => {\n const input = {\n 1: {\n shellScript: 'foo',\n },\n 2: {\n // sentry-cli present but with different command\n shellScript: 'sentry-cli sourcempas upload',\n },\n };\n\n expect(findDebugFilesUploadPhase(input)).toBeUndefined();\n });\n });\n});\n"]}
|
|
@@ -40,7 +40,8 @@ const vitest_1 = require("vitest");
|
|
|
40
40
|
})],
|
|
41
41
|
|
|
42
42
|
replaysSessionSampleRate: 0.1,
|
|
43
|
-
replaysOnErrorSampleRate: 1
|
|
43
|
+
replaysOnErrorSampleRate: 1,
|
|
44
|
+
sendDefaultPii: true
|
|
44
45
|
})"
|
|
45
46
|
`);
|
|
46
47
|
});
|
|
@@ -66,7 +67,8 @@ const vitest_1 = require("vitest");
|
|
|
66
67
|
})],
|
|
67
68
|
|
|
68
69
|
replaysSessionSampleRate: 0.1,
|
|
69
|
-
replaysOnErrorSampleRate: 1
|
|
70
|
+
replaysOnErrorSampleRate: 1,
|
|
71
|
+
sendDefaultPii: true
|
|
70
72
|
})"
|
|
71
73
|
`);
|
|
72
74
|
});
|
|
@@ -98,7 +100,9 @@ const vitest_1 = require("vitest");
|
|
|
98
100
|
useEffect,
|
|
99
101
|
useLocation,
|
|
100
102
|
useMatches
|
|
101
|
-
})]
|
|
103
|
+
})],
|
|
104
|
+
|
|
105
|
+
sendDefaultPii: true
|
|
102
106
|
})"
|
|
103
107
|
`);
|
|
104
108
|
});
|
|
@@ -150,7 +154,9 @@ const vitest_1 = require("vitest");
|
|
|
150
154
|
useEffect,
|
|
151
155
|
useLocation,
|
|
152
156
|
useMatches
|
|
153
|
-
})]
|
|
157
|
+
})],
|
|
158
|
+
|
|
159
|
+
sendDefaultPii: true
|
|
154
160
|
})"
|
|
155
161
|
`);
|
|
156
162
|
});
|