UNPKG

@sentry/wizard

Version:

Sentry wizard helping you to configure your project

862 lines (829 loc) 43.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const Sentry = __importStar(require("@sentry/node")); const fs = __importStar(require("fs")); const os = __importStar(require("os")); const path = __importStar(require("path")); const code_tools_1 = require("../../src/apple/code-tools"); // @ts-expect-error - clack is ESM and TS complains about that. It works though const clack = __importStar(require("@clack/prompts")); const vitest_1 = require("vitest"); vitest_1.vi.mock('@sentry/node', async () => { const actual = await vitest_1.vi.importActual('@sentry/node'); return { ...actual, setTag: vitest_1.vi.fn(), captureException: vitest_1.vi.fn(() => 'id'), }; }); // Test Constants const invalidAppDelegateSwift = `func application() {}`; const validAppDelegateSwift = ` import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } }`; const validAppDelegateSwiftWithSentry = ` import UIKit import Sentry @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { SentrySDK.start { options in options.dsn = "https://example.com/sentry-dsn" // Adds IP for users. // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/ options.sendDefaultPii = true // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. // We recommend adjusting this value in production. options.tracesSampleRate = 1.0 // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more. options.configureProfiling = { $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production. $0.lifecycle = .trace } // Uncomment the following lines to add more data to your events // options.attachScreenshot = true // This adds a screenshot to the error events // options.attachViewHierarchy = true // This adds the view hierarchy to the error events } // Remove the next line after confirming that your Sentry integration is working. SentrySDK.capture(message: "This app uses Sentry! :)") // Override point for customization after application launch. return true } }`; const invalidAppDelegateObjC = ` - (BOOL)application:(UIApplication *) { return NO; }`; const validAppDelegateObjC = ` #import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. return YES; } @end`; const validAppDelegateObjCWithSentry = `@import Sentry; #import "AppDelegate.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [SentrySDK startWithConfigureOptions:^(SentryOptions * options) { options.dsn = @"https://example.com/sentry-dsn"; // Adds IP for users. // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/ options.sendDefaultPii = YES; // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. // We recommend adjusting this value in production. options.tracesSampleRate = @1.0; // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more. options.configureProfiling = ^(SentryProfileOptions *profiling) { profiling.sessionSampleRate = 1.0; // We recommend adjusting this value in production. profiling.lifecycle = SentryProfilingLifecycleTrace; }; //Uncomment the following lines to add more data to your events //options.attachScreenshot = YES; //This will add a screenshot to the error events //options.attachViewHierarchy = YES; //This will add the view hierarchy to the error events }]; //Remove the next line after confirming that your Sentry integration is working. [SentrySDK captureMessage:@"This app uses Sentry!"]; // Override point for customization after application launch. return YES; } @end`; const invalidAppDelegateSwiftUI = ` struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!") } } }`; const validAppDelegateSwiftUI = ` import SwiftUI @main struct TestApp: App { var body: some Scene { WindowGroup { ContentView() } } }`; const validAppDelegateSwiftUIWithSentry = ` import SwiftUI import Sentry @main struct TestApp: App { init() { SentrySDK.start { options in options.dsn = "https://example.com/sentry-dsn" // Adds IP for users. // For more information, visit: https://docs.sentry.io/platforms/apple/data-management/data-collected/ options.sendDefaultPii = true // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. // We recommend adjusting this value in production. options.tracesSampleRate = 1.0 // Configure profiling. Visit https://docs.sentry.io/platforms/apple/profiling/ to learn more. options.configureProfiling = { $0.sessionSampleRate = 1.0 // We recommend adjusting this value in production. $0.lifecycle = .trace } // Uncomment the following lines to add more data to your events // options.attachScreenshot = true // This adds a screenshot to the error events // options.attachViewHierarchy = true // This adds the view hierarchy to the error events } // Remove the next line after confirming that your Sentry integration is working. SentrySDK.capture(message: "This app uses Sentry! :)") } var body: some Scene { WindowGroup { ContentView() } } }`; const prepareTempDir = () => { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-tools-test')); return tempDir; }; const prepareAppDelegateFile = (dir, content, ext) => { const filePath = path.join(dir, `AppDelegate.${ext}`); fs.writeFileSync(filePath, content, 'utf8'); return filePath; }; const dsn = 'https://example.com/sentry-dsn'; // Mock Setup vitest_1.vi.mock('../../src/utils/bash'); // Test Suite (0, vitest_1.describe)('code-tools', () => { (0, vitest_1.beforeEach)(() => { vitest_1.vi.spyOn(clack.log, 'info').mockImplementation(() => undefined); }); (0, vitest_1.afterEach)(() => { vitest_1.vi.clearAllMocks(); }); (0, vitest_1.describe)('#isAppDelegateFile', () => { const prepareTestFile = (content, ext) => { const tempDir = prepareTempDir(); return prepareAppDelegateFile(tempDir, content, ext); }; (0, vitest_1.describe)('swift files', () => { (0, vitest_1.describe)('swift app launch regex', () => { (0, vitest_1.describe)('valid cases', () => { const variations = [ { name: 'with underscores', code: 'func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {', }, { name: 'with different dictionary type', code: 'func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {', }, { name: 'with extra whitespace', code: ' func application ( _ application: UIApplication , didFinishLaunchingWithOptions launchOptions: [ NSObject : AnyObject ]? ) -> Bool { ', }, { name: 'macOS notification variant', code: 'func applicationDidFinishLaunching(_ aNotification: Notification) {', }, { name: 'macOS with extra whitespace', code: 'func applicationDidFinishLaunching ( _ aNotification: Notification ) {', }, ]; for (const variation of variations) { (0, vitest_1.describe)(`${variation.name}`, () => { (0, vitest_1.it)(`should return true`, () => { // -- Arrange -- const filePath = prepareTestFile(variation.code, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.isAppDelegateFile(filePath); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); }); }); } (0, vitest_1.describe)('invalid cases', () => { const variations = [ { name: 'missing application method', code: 'import UIKit', }, { name: 'typo in method name', code: 'func applicatioM(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {', }, { name: 'garbage input', code: 'asdf;jk23;uas()d{', }, ]; for (const variation of variations) { (0, vitest_1.describe)(`${variation.name}`, () => { (0, vitest_1.it)('should return false', () => { // -- Arrange -- const filePath = prepareTestFile(variation.code, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.isAppDelegateFile(filePath); // -- Assert -- (0, vitest_1.expect)(result).toBeFalsy(); }); }); } }); }); }); }); (0, vitest_1.describe)('objc files', () => { (0, vitest_1.describe)('valid cases', () => { const variations = [ { name: 'basic', code: '- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {', }, { name: 'with more whitespace', code: '- ( BOOL ) application: ( UIApplication * ) application didFinishLaunchingWithOptions: ( NSDictionary * ) launchOptions {', }, ]; for (const variation of variations) { (0, vitest_1.describe)(`${variation.name}`, () => { (0, vitest_1.it)('should return true', () => { // -- Arrange -- const filePath = prepareTestFile(variation.code, 'm'); // -- Act -- const result = code_tools_1.exportForTesting.isAppDelegateFile(filePath); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); }); }); } }); (0, vitest_1.describe)('invalid cases', () => { const variations = [ { name: 'missing application method', code: 'import UIKit', }, ]; for (const variation of variations) { (0, vitest_1.describe)(`${variation.name}`, () => { (0, vitest_1.it)('should return false', () => { // -- Arrange -- const filePath = prepareTestFile(variation.code, 'm'); // -- Act -- const result = code_tools_1.exportForTesting.isAppDelegateFile(filePath); // -- Assert -- (0, vitest_1.expect)(result).toBeFalsy(); }); }); } }); }); (0, vitest_1.describe)('swiftui files', () => { (0, vitest_1.describe)('valid cases', () => { const variations = [ { name: 'basic', code: '@main struct MyApp: App {', }, { name: 'with more whitespace', code: '@main struct MyApp: App {', }, { name: 'with SwiftUI namespace', code: '@main struct App: SwiftUI.App {', }, ]; for (const variation of variations) { (0, vitest_1.describe)(`${variation.name}`, () => { (0, vitest_1.it)('should return true', () => { // -- Arrange -- const filePath = prepareTestFile(variation.code, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.isAppDelegateFile(filePath); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); }); }); } }); (0, vitest_1.describe)('invalid cases', () => { const variations = [ { name: 'missing @main', code: 'struct App: App {', }, { name: 'missing super-type App', code: 'struct MyApp {', }, { name: 'imported not from SwiftUI', code: '@main struct App: MySwiftyUI.App {', }, { name: 'imported not from SwiftUI but similar', code: '@main struct App: MySwiftUI.App {', }, ]; for (const variation of variations) { (0, vitest_1.describe)(`${variation.name}`, () => { (0, vitest_1.it)('should return false', () => { // -- Arrange -- const filePath = prepareTestFile(variation.code, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.isAppDelegateFile(filePath); // -- Assert -- (0, vitest_1.expect)(result).toBeFalsy(); }); }); } }); }); (0, vitest_1.describe)('file not found', () => { (0, vitest_1.it)('should throw an error', () => { // -- Arrange -- const invalidPath = path.join(os.tmpdir(), 'invalid-path'); // -- Act & Assert -- (0, vitest_1.expect)(() => code_tools_1.exportForTesting.isAppDelegateFile(invalidPath)).toThrow(); }); }); }); (0, vitest_1.describe)('#findAppDidFinishLaunchingWithOptionsInDirectory', () => { (0, vitest_1.describe)('no files given', () => { (0, vitest_1.it)('should check files in directory', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBe(filePath); }); }); (0, vitest_1.describe)('SwiftUI file found', () => { (0, vitest_1.describe)('is app delegate', () => { (0, vitest_1.it)('should return the file path', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwiftUI, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBe(filePath); }); }); (0, vitest_1.describe)('is not app delegate', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); prepareAppDelegateFile(tempDir, invalidAppDelegateSwiftUI, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); }); (0, vitest_1.describe)('Swift file found', () => { (0, vitest_1.describe)('is app delegate', () => { (0, vitest_1.it)('should return the file path', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBe(filePath); }); }); (0, vitest_1.describe)('is not app delegate', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); prepareAppDelegateFile(tempDir, invalidAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); }); (0, vitest_1.describe)('Objective-C file found', () => { (0, vitest_1.describe)('is app delegate', () => { (0, vitest_1.it)('should return the file path', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjC, 'm'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBe(filePath); }); }); (0, vitest_1.describe)('is not app delegate', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); prepareAppDelegateFile(tempDir, invalidAppDelegateObjC, 'm'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); }); (0, vitest_1.describe)('Objective-C++ file found', () => { (0, vitest_1.describe)('is app delegate', () => { (0, vitest_1.it)('should return the file path', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjC, 'mm'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptions([ filePath, ]); // -- Assert -- (0, vitest_1.expect)(result).toBe(filePath); }); }); (0, vitest_1.describe)('is not app delegate', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); prepareAppDelegateFile(tempDir, invalidAppDelegateObjC, 'mm'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); }); (0, vitest_1.describe)('file in list not found', () => { (0, vitest_1.it)('should return null', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, invalidAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptions([ filePath, ]); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); (0, vitest_1.describe)('unrelated file found', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, invalidAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptions([ filePath, ]); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); (0, vitest_1.describe)('directory in list', () => { (0, vitest_1.describe)('name starts with dot', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); const hiddenDir = path.join(tempDir, '.hidden'); fs.mkdirSync(hiddenDir); prepareAppDelegateFile(hiddenDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); (0, vitest_1.describe)('name ends with .xcodeproj', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); const xcodeDir = path.join(tempDir, 'MyProject.xcodeproj'); fs.mkdirSync(xcodeDir); prepareAppDelegateFile(xcodeDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); (0, vitest_1.describe)('name ends with .xcassets', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); const xcassetsDir = path.join(tempDir, 'MyProject.xcassets'); fs.mkdirSync(xcassetsDir); prepareAppDelegateFile(xcassetsDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); (0, vitest_1.describe)('is not a directory', () => { (0, vitest_1.it)('should be ignored', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = path.join(tempDir, 'some-file'); fs.writeFileSync(filePath, validAppDelegateSwift, 'utf8'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); }); (0, vitest_1.describe)('multiple files could be app delegate', () => { (0, vitest_1.it)('should return the first one', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBe(filePath); }); }); (0, vitest_1.describe)('multiple nested directories with app delegate', () => { (0, vitest_1.it)('should return the first one', () => { // -- Arrange -- const tempDir = prepareTempDir(); const nestedDir = path.join(tempDir, 'nested'); fs.mkdirSync(nestedDir); const nestedFilePath = prepareAppDelegateFile(nestedDir, validAppDelegateSwift, 'swift'); const nestedDir2 = path.join(tempDir, 'nested2'); fs.mkdirSync(nestedDir2); prepareAppDelegateFile(nestedDir2, validAppDelegateSwift, 'swift'); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBe(nestedFilePath); }); }); (0, vitest_1.describe)('no app delegate found', () => { (0, vitest_1.it)('should return null', () => { // -- Arrange -- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-tools-test')); // -- Act -- const result = code_tools_1.exportForTesting.findAppDidFinishLaunchingWithOptionsInDirectory(tempDir); // -- Assert -- (0, vitest_1.expect)(result).toBeNull(); }); }); }); (0, vitest_1.describe)('#addCodeSnippetToProject', () => { (0, vitest_1.describe)('app delegate file is not found', () => { (0, vitest_1.it)('should return false', () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)(['AppDelegate.swift'], 'https://example.com/sentry-dsn', false); // -- Assert -- (0, vitest_1.expect)(result).toBeFalsy(); }); }); (0, vitest_1.describe)('app delegate file is found', () => { let tempDir; let appDelegatePath; (0, vitest_1.beforeEach)(() => { // -- Arrange -- tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'code-tools-test')); appDelegatePath = path.join(tempDir, 'AppDelegate.swift'); fs.writeFileSync(appDelegatePath, validAppDelegateSwift, 'utf8'); }); (0, vitest_1.describe)('is Swift file', () => { (0, vitest_1.describe)('Sentry is not initialized', () => { let tempDir; let filePath; (0, vitest_1.beforeEach)(() => { tempDir = prepareTempDir(); filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); }); (0, vitest_1.it)('should add the code snippet', () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const modifiedFileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(modifiedFileContent).toBe(validAppDelegateSwiftWithSentry); }); (0, vitest_1.it)("should set tag 'code-language'", () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); (0, vitest_1.expect)(Sentry.setTag).toHaveBeenCalledWith('code-language', 'swift'); }); (0, vitest_1.it)("should set tag 'ui-engine'", () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); (0, vitest_1.expect)(Sentry.setTag).toHaveBeenCalledWith('ui-engine', 'uikit'); }); }); (0, vitest_1.describe)('Sentry is already initialized', () => { (0, vitest_1.it)('should not add the code snippet', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwiftWithSentry, 'swift'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const modifiedFileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(modifiedFileContent).toBe(validAppDelegateSwiftWithSentry); }); }); (0, vitest_1.describe)('is SwiftUI file', () => { (0, vitest_1.describe)('Sentry is not initialized', () => { let tempDir; let filePath; (0, vitest_1.beforeEach)(() => { tempDir = prepareTempDir(); filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwiftUI, 'swift'); }); (0, vitest_1.it)('should add the code snippet', () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const modifiedFileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(modifiedFileContent).toBe(validAppDelegateSwiftUIWithSentry); }); (0, vitest_1.it)("should set tag 'code-language'", () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); (0, vitest_1.expect)(Sentry.setTag).toHaveBeenNthCalledWith(1, 'code-language', 'swift'); }); (0, vitest_1.it)("should set tag 'ui-engine'", () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); (0, vitest_1.expect)(Sentry.setTag).toHaveBeenNthCalledWith(2, 'ui-engine', 'swiftui'); }); }); (0, vitest_1.describe)('Sentry is already initialized', () => { (0, vitest_1.it)('should not add the code snippet', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwiftUIWithSentry, 'swift'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const modifiedFileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(modifiedFileContent).toBe(validAppDelegateSwiftUIWithSentry); }); }); }); (0, vitest_1.describe)('is not matching SwiftUI regex', () => { (0, vitest_1.it)('should not add the code snippet', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, invalidAppDelegateSwiftUI, 'swift'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeFalsy(); }); }); }); (0, vitest_1.describe)('is Objective-C file', () => { (0, vitest_1.describe)('Sentry is not initialized', () => { (0, vitest_1.it)('should add the code snippet', () => { // -- Act -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjC, 'm'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const modifiedFileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(modifiedFileContent).toBe(validAppDelegateObjCWithSentry); }); }); (0, vitest_1.describe)('Sentry is already initialized', () => { let tempDir; let filePath; (0, vitest_1.beforeEach)(() => { tempDir = prepareTempDir(); filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjCWithSentry, 'm'); }); (0, vitest_1.it)('should not add the code snippet', () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const modifiedFileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(modifiedFileContent).toBe(validAppDelegateObjCWithSentry); }); (0, vitest_1.it)('should log info', () => { // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); (0, vitest_1.expect)(clack.log.info).toHaveBeenCalledWith('Sentry is already initialized in your AppDelegate. Skipping adding the code snippet.'); }); }); (0, vitest_1.it)("should set tag 'code-language'", () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjC, 'm'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); (0, vitest_1.expect)(Sentry.setTag).toHaveBeenCalledWith('code-language', 'objc'); }); }); }); (0, vitest_1.describe)('with logs enabled', () => { (0, vitest_1.it)('should add logs option to Swift file', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, true); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const fileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(fileContent).toContain('options.experimental.enableLogs = true'); }); (0, vitest_1.it)('should add logs option to Objective-C file', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjC, 'm'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, true); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const fileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(fileContent).toContain('options.experimental.enableLogs = YES;'); }); }); (0, vitest_1.describe)('with logs disabled', () => { (0, vitest_1.it)('should not add logs option to Swift file', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateSwift, 'swift'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const fileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(fileContent).not.toContain('options.experimental.enableLogs = true'); }); (0, vitest_1.it)('should not add logs option to Objective-C file', () => { // -- Arrange -- const tempDir = prepareTempDir(); const filePath = prepareAppDelegateFile(tempDir, validAppDelegateObjC, 'm'); // -- Act -- const result = (0, code_tools_1.addCodeSnippetToProject)([filePath], dsn, false); // -- Assert -- (0, vitest_1.expect)(result).toBeTruthy(); const fileContent = fs.readFileSync(filePath, 'utf8'); (0, vitest_1.expect)(fileContent).not.toContain('options.experimental.enableLogs = YES;'); }); }); }); }); //# sourceMappingURL=code-tools.test.js.map