@sentry/wizard 3.39.0 → 3.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/README.md +21 -21
  3. package/bin.ts +5 -0
  4. package/codecov.yml +15 -0
  5. package/dist/bin.js +4 -0
  6. package/dist/bin.js.map +1 -1
  7. package/dist/e2e-tests/jest.config.d.ts +1 -0
  8. package/dist/e2e-tests/jest.config.js +1 -0
  9. package/dist/e2e-tests/jest.config.js.map +1 -1
  10. package/dist/e2e-tests/tests/flutter.test.d.ts +1 -0
  11. package/dist/e2e-tests/tests/flutter.test.js +190 -0
  12. package/dist/e2e-tests/tests/flutter.test.js.map +1 -0
  13. package/dist/e2e-tests/utils/index.d.ts +11 -0
  14. package/dist/e2e-tests/utils/index.js +36 -1
  15. package/dist/e2e-tests/utils/index.js.map +1 -1
  16. package/dist/lib/Constants.d.ts +1 -0
  17. package/dist/lib/Constants.js +5 -0
  18. package/dist/lib/Constants.js.map +1 -1
  19. package/dist/package.json +3 -2
  20. package/dist/src/apple/apple-wizard.js +2 -3
  21. package/dist/src/apple/apple-wizard.js.map +1 -1
  22. package/dist/src/apple/code-tools.d.ts +10 -0
  23. package/dist/src/apple/code-tools.js +16 -12
  24. package/dist/src/apple/code-tools.js.map +1 -1
  25. package/dist/src/apple/fastlane.d.ts +23 -0
  26. package/dist/src/apple/fastlane.js +11 -7
  27. package/dist/src/apple/fastlane.js.map +1 -1
  28. package/dist/src/apple/templates.d.ts +1 -1
  29. package/dist/src/apple/templates.js +0 -2
  30. package/dist/src/apple/templates.js.map +1 -1
  31. package/dist/src/apple/xcode-manager.d.ts +13 -9
  32. package/dist/src/apple/xcode-manager.js +146 -61
  33. package/dist/src/apple/xcode-manager.js.map +1 -1
  34. package/dist/src/flutter/code-tools.d.ts +17 -0
  35. package/dist/src/flutter/code-tools.js +263 -0
  36. package/dist/src/flutter/code-tools.js.map +1 -0
  37. package/dist/src/flutter/flutter-wizard.d.ts +2 -0
  38. package/dist/src/flutter/flutter-wizard.js +171 -0
  39. package/dist/src/flutter/flutter-wizard.js.map +1 -0
  40. package/dist/src/flutter/templates.d.ts +9 -0
  41. package/dist/src/flutter/templates.js +40 -0
  42. package/dist/src/flutter/templates.js.map +1 -0
  43. package/dist/src/nextjs/nextjs-wizard.js +5 -3
  44. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  45. package/dist/src/nuxt/nuxt-wizard.js +6 -4
  46. package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
  47. package/dist/src/nuxt/sdk-setup.d.ts +1 -1
  48. package/dist/src/nuxt/sdk-setup.js +2 -1
  49. package/dist/src/nuxt/sdk-setup.js.map +1 -1
  50. package/dist/src/react-native/react-native-wizard.js +5 -3
  51. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  52. package/dist/src/remix/remix-wizard.js +5 -3
  53. package/dist/src/remix/remix-wizard.js.map +1 -1
  54. package/dist/src/run.d.ts +2 -1
  55. package/dist/src/run.js +40 -32
  56. package/dist/src/run.js.map +1 -1
  57. package/dist/src/sveltekit/sveltekit-wizard.js +5 -3
  58. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  59. package/dist/src/utils/clack-utils.d.ts +4 -2
  60. package/dist/src/utils/clack-utils.js +18 -12
  61. package/dist/src/utils/clack-utils.js.map +1 -1
  62. package/dist/src/utils/package-manager.d.ts +1 -0
  63. package/dist/src/utils/package-manager.js +5 -0
  64. package/dist/src/utils/package-manager.js.map +1 -1
  65. package/dist/src/utils/types.d.ts +9 -0
  66. package/dist/src/utils/types.js.map +1 -1
  67. package/dist/test/apple/cocoapod.test.d.ts +1 -0
  68. package/dist/test/apple/cocoapod.test.js +409 -0
  69. package/dist/test/apple/cocoapod.test.js.map +1 -0
  70. package/dist/test/apple/code-tools.test.d.ts +1 -0
  71. package/dist/test/apple/code-tools.test.js +673 -0
  72. package/dist/test/apple/code-tools.test.js.map +1 -0
  73. package/dist/test/apple/fastfile.test.d.ts +1 -0
  74. package/dist/test/apple/fastfile.test.js +431 -0
  75. package/dist/test/apple/fastfile.test.js.map +1 -0
  76. package/dist/test/apple/templates.test.d.ts +1 -0
  77. package/dist/test/apple/templates.test.js +73 -0
  78. package/dist/test/apple/templates.test.js.map +1 -0
  79. package/dist/test/apple/xcode-manager.test.d.ts +1 -0
  80. package/dist/test/apple/xcode-manager.test.js +834 -0
  81. package/dist/test/apple/xcode-manager.test.js.map +1 -0
  82. package/dist/test/flutter/code-tools.test.d.ts +1 -0
  83. package/dist/test/flutter/code-tools.test.js +84 -0
  84. package/dist/test/flutter/code-tools.test.js.map +1 -0
  85. package/dist/test/flutter/templates.test.d.ts +1 -0
  86. package/dist/test/flutter/templates.test.js +41 -0
  87. package/dist/test/flutter/templates.test.js.map +1 -0
  88. package/dist/test/utils/clack-utils.test.js +89 -0
  89. package/dist/test/utils/clack-utils.test.js.map +1 -1
  90. package/e2e-tests/README.md +5 -1
  91. package/e2e-tests/jest.config.ts +1 -0
  92. package/e2e-tests/test-applications/apple/damaged-missing-configuration-list/Project.xcodeproj/project.pbxproj +52 -0
  93. package/e2e-tests/test-applications/apple/damaged-missing-configuration-list/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
  94. package/e2e-tests/test-applications/apple/no-targets/Project.xcodeproj/project.pbxproj +62 -0
  95. package/e2e-tests/test-applications/apple/no-targets/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
  96. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project.xcodeproj/project.pbxproj +470 -0
  97. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project.xcodeproj/xcshareddata/xcschemes/Project1.xcscheme +78 -0
  98. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project1/ContentView.swift +7 -0
  99. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project1/Project1App.swift +10 -0
  100. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project2/ContentView.swift +7 -0
  101. package/e2e-tests/test-applications/apple/spm-swiftui-multi-targets/Project2/Project2App.swift +10 -0
  102. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Project.xcodeproj/project.pbxproj +382 -0
  103. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Project.xcodeproj/xcshareddata/xcschemes/Project.xcscheme +78 -0
  104. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Sources/ContentView.swift +7 -0
  105. package/e2e-tests/test-applications/apple/spm-swiftui-single-target/Sources/MainApp.swift +10 -0
  106. package/e2e-tests/test-applications/flutter-test-app/.metadata +45 -0
  107. package/e2e-tests/test-applications/flutter-test-app/README.md +16 -0
  108. package/e2e-tests/test-applications/flutter-test-app/analysis_options.yaml +28 -0
  109. package/e2e-tests/test-applications/flutter-test-app/android/app/build.gradle +44 -0
  110. package/e2e-tests/test-applications/flutter-test-app/android/app/src/debug/AndroidManifest.xml +7 -0
  111. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/AndroidManifest.xml +45 -0
  112. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/kotlin/com/example/flutter_magic/MainActivity.kt +5 -0
  113. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/drawable/launch_background.xml +12 -0
  114. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
  115. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  116. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  117. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  118. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  119. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  120. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/values/styles.xml +18 -0
  121. package/e2e-tests/test-applications/flutter-test-app/android/app/src/main/res/values-night/styles.xml +18 -0
  122. package/e2e-tests/test-applications/flutter-test-app/android/app/src/profile/AndroidManifest.xml +7 -0
  123. package/e2e-tests/test-applications/flutter-test-app/android/build.gradle +18 -0
  124. package/e2e-tests/test-applications/flutter-test-app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  125. package/e2e-tests/test-applications/flutter-test-app/android/gradle.properties +3 -0
  126. package/e2e-tests/test-applications/flutter-test-app/android/settings.gradle +25 -0
  127. package/e2e-tests/test-applications/flutter-test-app/lib/main.dart +125 -0
  128. package/e2e-tests/test-applications/flutter-test-app/linux/CMakeLists.txt +145 -0
  129. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/CMakeLists.txt +88 -0
  130. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugin_registrant.cc +11 -0
  131. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugin_registrant.h +15 -0
  132. package/e2e-tests/test-applications/flutter-test-app/linux/flutter/generated_plugins.cmake +23 -0
  133. package/e2e-tests/test-applications/flutter-test-app/linux/main.cc +6 -0
  134. package/e2e-tests/test-applications/flutter-test-app/linux/my_application.cc +124 -0
  135. package/e2e-tests/test-applications/flutter-test-app/linux/my_application.h +18 -0
  136. package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
  137. package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/Flutter-Release.xcconfig +2 -0
  138. package/e2e-tests/test-applications/flutter-test-app/macos/Flutter/GeneratedPluginRegistrant.swift +10 -0
  139. package/e2e-tests/test-applications/flutter-test-app/macos/Podfile +43 -0
  140. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/AppDelegate.swift +9 -0
  141. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  142. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
  143. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
  144. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
  145. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
  146. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
  147. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
  148. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
  149. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Base.lproj/MainMenu.xib +343 -0
  150. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
  151. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Debug.xcconfig +2 -0
  152. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Release.xcconfig +2 -0
  153. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Configs/Warnings.xcconfig +13 -0
  154. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/DebugProfile.entitlements +12 -0
  155. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Info.plist +32 -0
  156. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/MainFlutterWindow.swift +15 -0
  157. package/e2e-tests/test-applications/flutter-test-app/macos/Runner/Release.entitlements +8 -0
  158. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/project.pbxproj +705 -0
  159. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  160. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +98 -0
  161. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcworkspace/contents.xcworkspacedata +7 -0
  162. package/e2e-tests/test-applications/flutter-test-app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  163. package/e2e-tests/test-applications/flutter-test-app/macos/RunnerTests/RunnerTests.swift +12 -0
  164. package/e2e-tests/test-applications/flutter-test-app/pubspec.lock +213 -0
  165. package/e2e-tests/test-applications/flutter-test-app/pubspec.yaml +89 -0
  166. package/e2e-tests/test-applications/flutter-test-app/test/widget_test.dart +30 -0
  167. package/e2e-tests/test-applications/flutter-test-app/web/favicon.png +0 -0
  168. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-192.png +0 -0
  169. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-512.png +0 -0
  170. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-maskable-192.png +0 -0
  171. package/e2e-tests/test-applications/flutter-test-app/web/icons/Icon-maskable-512.png +0 -0
  172. package/e2e-tests/test-applications/flutter-test-app/web/index.html +38 -0
  173. package/e2e-tests/test-applications/flutter-test-app/web/manifest.json +35 -0
  174. package/e2e-tests/test-applications/flutter-test-app/windows/CMakeLists.txt +108 -0
  175. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/CMakeLists.txt +109 -0
  176. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugin_registrant.cc +11 -0
  177. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugin_registrant.h +15 -0
  178. package/e2e-tests/test-applications/flutter-test-app/windows/flutter/generated_plugins.cmake +23 -0
  179. package/e2e-tests/test-applications/flutter-test-app/windows/runner/CMakeLists.txt +40 -0
  180. package/e2e-tests/test-applications/flutter-test-app/windows/runner/Runner.rc +121 -0
  181. package/e2e-tests/test-applications/flutter-test-app/windows/runner/flutter_window.cpp +71 -0
  182. package/e2e-tests/test-applications/flutter-test-app/windows/runner/flutter_window.h +33 -0
  183. package/e2e-tests/test-applications/flutter-test-app/windows/runner/main.cpp +43 -0
  184. package/e2e-tests/test-applications/flutter-test-app/windows/runner/resource.h +16 -0
  185. package/e2e-tests/test-applications/flutter-test-app/windows/runner/resources/app_icon.ico +0 -0
  186. package/e2e-tests/test-applications/flutter-test-app/windows/runner/runner.exe.manifest +14 -0
  187. package/e2e-tests/test-applications/flutter-test-app/windows/runner/utils.cpp +65 -0
  188. package/e2e-tests/test-applications/flutter-test-app/windows/runner/utils.h +19 -0
  189. package/e2e-tests/test-applications/flutter-test-app/windows/runner/win32_window.cpp +288 -0
  190. package/e2e-tests/test-applications/flutter-test-app/windows/runner/win32_window.h +102 -0
  191. package/e2e-tests/tests/flutter.test.ts +127 -0
  192. package/e2e-tests/utils/index.ts +33 -0
  193. package/lib/Constants.ts +5 -0
  194. package/package.json +3 -2
  195. package/src/apple/apple-wizard.ts +2 -3
  196. package/src/apple/code-tools.ts +21 -6
  197. package/src/apple/fastlane.ts +18 -2
  198. package/src/apple/templates.ts +2 -2
  199. package/src/apple/xcode-manager.ts +186 -99
  200. package/src/flutter/code-tools.ts +284 -0
  201. package/src/flutter/flutter-wizard.ts +164 -0
  202. package/src/flutter/templates.ts +90 -0
  203. package/src/nextjs/nextjs-wizard.ts +5 -2
  204. package/src/nuxt/nuxt-wizard.ts +6 -3
  205. package/src/nuxt/sdk-setup.ts +2 -0
  206. package/src/react-native/react-native-wizard.ts +5 -2
  207. package/src/remix/remix-wizard.ts +5 -2
  208. package/src/run.ts +9 -0
  209. package/src/sveltekit/sveltekit-wizard.ts +5 -2
  210. package/src/utils/clack-utils.ts +16 -4
  211. package/src/utils/package-manager.ts +6 -0
  212. package/src/utils/types.ts +10 -0
  213. package/test/apple/cocoapod.test.ts +306 -0
  214. package/test/apple/code-tools.test.ts +1042 -0
  215. package/test/apple/fastfile.test.ts +550 -0
  216. package/test/apple/templates.test.ts +191 -0
  217. package/test/apple/xcode-manager.test.ts +1066 -0
  218. package/test/flutter/code-tools.test.ts +212 -0
  219. package/test/flutter/templates.test.ts +100 -0
  220. package/test/utils/clack-utils.test.ts +92 -0
  221. package/types/xcode.d.ts +526 -0
@@ -0,0 +1,212 @@
1
+ //@ts-ignore
2
+ import {
3
+ patchMainContent,
4
+ getDependenciesLocation,
5
+ getDevDependenciesLocation,
6
+ getLastImportLineLocation,
7
+ } from '../../src/flutter/code-tools';
8
+ //@ts-ignore
9
+ import { initSnippet } from '../../src/flutter/templates';
10
+
11
+ describe('code-tools', () => {
12
+ const pubspec = `name: flutter_example
13
+ description: An example flutter app.
14
+ version: 1.0.0
15
+ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
16
+
17
+ environment:
18
+ sdk: '>=2.17.0 <4.0.0'
19
+ flutter: '>=3.0.0'
20
+
21
+ dependencies:
22
+ flutter:
23
+ sdk: flutter
24
+
25
+ dev_dependencies:
26
+ flutter_lints: ^2.0.0
27
+ `;
28
+
29
+ const simpleRunApp = `import 'package:flutter/widgets.dart';
30
+
31
+ void main() {
32
+ runApp(const MyApp());
33
+ }
34
+ `;
35
+
36
+ const asyncRunApp = `import 'package:flutter/widgets.dart';
37
+
38
+ void main() {
39
+ runApp(const MyApp());
40
+ }
41
+ `;
42
+
43
+ const selectedFeaturesMap = {
44
+ tracing: true,
45
+ profiling: true,
46
+ };
47
+
48
+ const simpleRunAppPatched = `import 'package:flutter/widgets.dart';
49
+ import 'package:sentry_flutter/sentry_flutter.dart';
50
+
51
+ Future<void> main() async {
52
+ ${initSnippet('dsn', selectedFeaturesMap, 'const MyApp()')}
53
+ }
54
+ `;
55
+
56
+ const paramRunApp = `import 'package:flutter/widgets.dart';
57
+
58
+ Future<void> main() async {
59
+ await someFunction();
60
+ runApp(MyApp(param: SomeParam()));
61
+ await anotherFunction();
62
+ }
63
+ `;
64
+
65
+ const paramRunAppPatched = `import 'package:flutter/widgets.dart';
66
+ import 'package:sentry_flutter/sentry_flutter.dart';
67
+
68
+ Future<void> main() async {
69
+ await someFunction();
70
+ ${initSnippet('dsn', selectedFeaturesMap, 'MyApp(param: SomeParam())')}
71
+ await anotherFunction();
72
+ }
73
+ `;
74
+
75
+ const multilineRunApp = `import 'package:flutter/widgets.dart';
76
+
77
+ void main() {
78
+ runApp(
79
+ MyApp(
80
+ param: Param(),
81
+ multi: Another(1),
82
+ line: await bites(the: "dust"),
83
+ ),
84
+ );
85
+ anotherFunction();
86
+ }
87
+ `;
88
+
89
+ const multilineRunAppPatched = `import 'package:flutter/widgets.dart';
90
+ import 'package:sentry_flutter/sentry_flutter.dart';
91
+
92
+ Future<void> main() async {
93
+ ${initSnippet(
94
+ 'dsn',
95
+ selectedFeaturesMap,
96
+ `
97
+ MyApp(
98
+ param: Param(),
99
+ multi: Another(1),
100
+ line: await bites(the: "dust"),
101
+ ),
102
+ `,
103
+ )}
104
+ anotherFunction();
105
+ }
106
+ `;
107
+
108
+ describe('patchMainContent', () => {
109
+ it('wraps simple runApp', () => {
110
+ expect(patchMainContent('dsn', simpleRunApp, selectedFeaturesMap)).toBe(
111
+ simpleRunAppPatched,
112
+ );
113
+ });
114
+
115
+ it('wraps async runApp', () => {
116
+ expect(patchMainContent('dsn', asyncRunApp, selectedFeaturesMap)).toBe(
117
+ simpleRunAppPatched,
118
+ );
119
+ });
120
+
121
+ it('wraps runApp with parameterized app', () => {
122
+ expect(patchMainContent('dsn', paramRunApp, selectedFeaturesMap)).toBe(
123
+ paramRunAppPatched,
124
+ );
125
+ });
126
+
127
+ it('wraps multiline runApp', () => {
128
+ expect(
129
+ patchMainContent('dsn', multilineRunApp, selectedFeaturesMap),
130
+ ).toBe(multilineRunAppPatched);
131
+ });
132
+ });
133
+
134
+ describe('pubspec', () => {
135
+ it('returns proper line index for dependencies', () => {
136
+ expect(getDependenciesLocation(pubspec)).toBe(
137
+ pubspec.indexOf(' flutter:\n'),
138
+ );
139
+ });
140
+
141
+ it('returns proper line index for dev-dependencies', () => {
142
+ expect(getDevDependenciesLocation(pubspec)).toBe(
143
+ pubspec.indexOf(' flutter_lints: ^2.0.0\n'),
144
+ );
145
+ });
146
+ });
147
+
148
+ describe('getLastImportLineLocation', () => {
149
+ it('returns proper line index', () => {
150
+ const code =
151
+ `import 'foo:bar';\n` + `//<insert-location>\n` + `class X {}`;
152
+ expect(getLastImportLineLocation(code)).toBe(
153
+ code.indexOf('//<insert-location>'),
154
+ );
155
+ });
156
+
157
+ it('returns proper line index when alias import is used', () => {
158
+ const code =
159
+ `import 'package:my_library/utils.dart' as utils;\n` +
160
+ `//<insert-location>\n` +
161
+ `class X {}`;
162
+ expect(getLastImportLineLocation(code)).toBe(
163
+ code.indexOf('//<insert-location>'),
164
+ );
165
+ });
166
+
167
+ it('returns proper line index when specific parts import is used', () => {
168
+ const code =
169
+ `import 'dart:math' show pi, sin;\n` +
170
+ `//<insert-location>\n` +
171
+ `class X {}`;
172
+ expect(getLastImportLineLocation(code)).toBe(
173
+ code.indexOf('//<insert-location>'),
174
+ );
175
+ });
176
+
177
+ it('returns proper line index when hide import is used', () => {
178
+ const code =
179
+ `import 'dart:math' hide Random;\n` +
180
+ `//<insert-location>\n` +
181
+ `class X {}`;
182
+ expect(getLastImportLineLocation(code)).toBe(
183
+ code.indexOf('//<insert-location>'),
184
+ );
185
+ });
186
+
187
+ it('returns proper line index when deferred import is used', () => {
188
+ const code =
189
+ `import 'package:my_library/large_library.dart' deferred as largeLibrary;\n` +
190
+ `//<insert-location>\n` +
191
+ `class X {}`;
192
+ expect(getLastImportLineLocation(code)).toBe(
193
+ code.indexOf('//<insert-location>'),
194
+ );
195
+ });
196
+
197
+ it('returns proper line index when multiple imports (with newlines) are present', () => {
198
+ const code =
199
+ `import 'foo:bar';\n` +
200
+ `import 'package:my_library/utils.dart' as utils;\n` +
201
+ `import 'dart:math' show pi, sin;\n` +
202
+ `import 'dart:math' hide Random;\n` +
203
+ `\n` +
204
+ `import 'package:my_library/large_library.dart' deferred as largeLibrary;\n` +
205
+ `//<insert-location>\n` +
206
+ `class X {}`;
207
+ expect(getLastImportLineLocation(code)).toBe(
208
+ code.indexOf('//<insert-location>'),
209
+ );
210
+ });
211
+ });
212
+ });
@@ -0,0 +1,100 @@
1
+ import {
2
+ pubspecOptions,
3
+ sentryProperties,
4
+ initSnippet,
5
+ } from '../../src/flutter/templates';
6
+
7
+ describe('Flutter code templates', () => {
8
+ describe('pubspec', () => {
9
+ it('generates pubspec with project and org', () => {
10
+ const template = pubspecOptions('fixture-project', 'fixture-org');
11
+ expect(template).toMatchInlineSnapshot(`
12
+ "sentry:
13
+ upload_debug_symbols: true
14
+ upload_source_maps: true
15
+ project: fixture-project
16
+ org: fixture-org
17
+ "
18
+ `);
19
+ });
20
+ });
21
+ describe('sentry.properties', () => {
22
+ it('generates sentry.properties with token', () => {
23
+ const template = sentryProperties('fixture-token');
24
+ expect(template).toMatchInlineSnapshot(`"auth_token=fixture-token"`);
25
+ });
26
+ });
27
+ describe('init', () => {
28
+ it('generates Sentry config with all features enabled', () => {
29
+ const template = initSnippet(
30
+ 'my-dsn',
31
+ {
32
+ tracing: true,
33
+ profiling: true,
34
+ },
35
+ 'const MyApp()',
36
+ );
37
+ expect(template).toMatchInlineSnapshot(`
38
+ "await SentryFlutter.init(
39
+ (options) {
40
+ options.dsn = 'my-dsn';
41
+ // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
42
+ // We recommend adjusting this value in production.
43
+ options.tracesSampleRate = 1.0;
44
+ // The sampling rate for profiling is relative to tracesSampleRate
45
+ // Setting to 1.0 will profile 100% of sampled transactions:
46
+ options.profilesSampleRate = 1.0;
47
+ },
48
+ appRunner: () => runApp(SentryWidget(child: const MyApp())),
49
+ );
50
+ // TODO: Remove this line after sending the first sample event to sentry.
51
+ await Sentry.captureException(Exception('This is a sample exception.'));"
52
+ `);
53
+ });
54
+
55
+ it('generates Sentry config with profiling disabled', () => {
56
+ const template = initSnippet(
57
+ 'my-dsn',
58
+ {
59
+ tracing: true,
60
+ profiling: false,
61
+ },
62
+ 'const MyApp()',
63
+ );
64
+ expect(template).toMatchInlineSnapshot(`
65
+ "await SentryFlutter.init(
66
+ (options) {
67
+ options.dsn = 'my-dsn';
68
+ // Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
69
+ // We recommend adjusting this value in production.
70
+ options.tracesSampleRate = 1.0;
71
+ },
72
+ appRunner: () => runApp(SentryWidget(child: const MyApp())),
73
+ );
74
+ // TODO: Remove this line after sending the first sample event to sentry.
75
+ await Sentry.captureException(Exception('This is a sample exception.'));"
76
+ `);
77
+ });
78
+
79
+ it('generates Sentry config with tracing disabled', () => {
80
+ const template = initSnippet(
81
+ 'my-dsn',
82
+ {
83
+ tracing: false,
84
+ profiling: false,
85
+ },
86
+ 'const MyApp()',
87
+ );
88
+ expect(template).toMatchInlineSnapshot(`
89
+ "await SentryFlutter.init(
90
+ (options) {
91
+ options.dsn = 'my-dsn';
92
+ },
93
+ appRunner: () => runApp(SentryWidget(child: const MyApp())),
94
+ );
95
+ // TODO: Remove this line after sending the first sample event to sentry.
96
+ await Sentry.captureException(Exception('This is a sample exception.'));"
97
+ `);
98
+ });
99
+ });
100
+ });
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  askForToolConfigPath,
3
3
  createNewConfigFile,
4
+ installPackage,
4
5
  } from '../../src/utils/clack-utils';
5
6
 
6
7
  import * as fs from 'fs';
8
+ import * as ChildProcess from 'child_process';
9
+ import { PackageManager } from '../../src/utils/package-manager';
7
10
 
8
11
  type ClackMock = {
9
12
  confirm: jest.Mock;
@@ -15,6 +18,7 @@ type ClackMock = {
15
18
  success: jest.Mock;
16
19
  warn: jest.Mock;
17
20
  };
21
+ spinner: () => { start: jest.Mock; stop: jest.Mock };
18
22
  };
19
23
 
20
24
  let clackMock: ClackMock;
@@ -31,6 +35,9 @@ jest.mock('@clack/prompts', () => {
31
35
  cancel: jest.fn(),
32
36
  // passthrough for abortIfCancelled
33
37
  isCancel: jest.fn().mockReturnValue(false),
38
+ spinner: jest
39
+ .fn()
40
+ .mockImplementation(() => ({ start: jest.fn(), stop: jest.fn() })),
34
41
  };
35
42
  return clackMock;
36
43
  });
@@ -140,3 +147,88 @@ describe('createNewConfigFile', () => {
140
147
  expect(result).toBe(false);
141
148
  });
142
149
  });
150
+
151
+ describe('installPackage', () => {
152
+ afterEach(() => {
153
+ jest.clearAllMocks();
154
+ });
155
+
156
+ it('force-installs a package if the forceInstall flag is set', async () => {
157
+ const packageManagerMock: PackageManager = {
158
+ name: 'npm',
159
+ label: 'NPM',
160
+ installCommand: 'npm install',
161
+ buildCommand: 'npm run build',
162
+ runScriptCommand: 'npm run',
163
+ flags: '',
164
+ forceInstallFlag: '--force',
165
+ detect: jest.fn(),
166
+ addOverride: jest.fn(),
167
+ };
168
+
169
+ const execSpy = jest
170
+ .spyOn(ChildProcess, 'exec')
171
+ // @ts-expect-error - don't care about the return value
172
+ .mockImplementationOnce((cmd, cb) => {
173
+ if (cb) {
174
+ // @ts-expect-error - don't care about the options value
175
+ cb(null, '', '');
176
+ }
177
+ });
178
+
179
+ await installPackage({
180
+ alreadyInstalled: false,
181
+ packageName: '@sentry/sveltekit',
182
+ packageNameDisplayLabel: '@sentry/sveltekit',
183
+ forceInstall: true,
184
+ askBeforeUpdating: false,
185
+ packageManager: packageManagerMock,
186
+ });
187
+
188
+ expect(execSpy).toHaveBeenCalledWith(
189
+ 'npm install @sentry/sveltekit --force',
190
+ expect.any(Function),
191
+ );
192
+ });
193
+
194
+ it.each([false, undefined])(
195
+ "doesn't force-install a package if the forceInstall flag is %s",
196
+ async (flag) => {
197
+ const packageManagerMock: PackageManager = {
198
+ name: 'npm',
199
+ label: 'NPM',
200
+ installCommand: 'npm install',
201
+ buildCommand: 'npm run build',
202
+ runScriptCommand: 'npm run',
203
+ flags: '',
204
+ forceInstallFlag: '--force',
205
+ detect: jest.fn(),
206
+ addOverride: jest.fn(),
207
+ };
208
+
209
+ const execSpy = jest
210
+ .spyOn(ChildProcess, 'exec')
211
+ // @ts-expect-error - don't care about the return value
212
+ .mockImplementationOnce((cmd, cb) => {
213
+ if (cb) {
214
+ // @ts-expect-error - don't care about the options value
215
+ cb(null, '', '');
216
+ }
217
+ });
218
+
219
+ await installPackage({
220
+ alreadyInstalled: false,
221
+ packageName: '@sentry/sveltekit',
222
+ packageNameDisplayLabel: '@sentry/sveltekit',
223
+ forceInstall: flag,
224
+ askBeforeUpdating: false,
225
+ packageManager: packageManagerMock,
226
+ });
227
+
228
+ expect(execSpy).toHaveBeenCalledWith(
229
+ 'npm install @sentry/sveltekit ',
230
+ expect.any(Function),
231
+ );
232
+ },
233
+ );
234
+ });