Skip to content

Commit

Permalink
introduce options in flutter templates
Browse files Browse the repository at this point in the history
  • Loading branch information
denrase committed Dec 16, 2024
1 parent 51e0fd4 commit d3ae482
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 14 deletions.
10 changes: 9 additions & 1 deletion src/flutter/code-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,15 @@ export function patchMainContent(dsn: string, mainContent: string): string {
// Find and replace `runApp(...)`
mainContent = mainContent.replace(
/runApp\(([\s\S]*?)\);/g, // Match the `runApp(...)` invocation
(_, runAppArgs) => initSnippet(dsn, runAppArgs as string)
(_, runAppArgs) => initSnippet(
dsn,
{
tracing: true,
profiling: true,
replay: true,
},
runAppArgs as string
)
);

// Make the `main` function async if it's not already
Expand Down
40 changes: 32 additions & 8 deletions src/flutter/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,45 @@ export function sentryProperties(authToken: string): string {
return `auth_token=${authToken}`;
}

export function initSnippet(dsn: string, runApp: string): string {
return `await SentryFlutter.init(
export function initSnippet(
dsn: string,
selectedFeaturesMap: {
tracing: boolean;
profiling: boolean;
replay: boolean;
},
runApp: string,
): string {
let snippet = `await SentryFlutter.init(
(options) {
options.dsn = '${dsn}';
options.dsn = '${dsn}';`

if (selectedFeaturesMap.tracing) {
snippet += `
// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1.0;
options.tracesSampleRate = 1.0;`;
}

if (selectedFeaturesMap.profiling && selectedFeaturesMap.tracing) {
snippet += `
// The sampling rate for profiling is relative to tracesSampleRate
// Setting to 1.0 will profile 100% of sampled transactions:
// Note: Profiling alpha is available for iOS and macOS since SDK version 7.12.0
options.profilesSampleRate = 1.0;
options.profilesSampleRate = 1.0;`;
}

if (selectedFeaturesMap.replay) {
snippet += `
options.experimental.replay.sessionSampleRate = 1.0;
options.experimental.replay.onErrorSampleRate = 1.0;`;
}

snippet += `
},
appRunner: () => runApp(${runApp}),
);
// TODO: Remove this line after sending the first sample event to sentry.
await Sentry.captureMessage('This is a sample exception.');
`
await Sentry.captureMessage('This is a sample exception.');`

return snippet;
}
4 changes: 2 additions & 2 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { runReactNativeWizard } from './react-native/react-native-wizard';

import { run as legacyRun } from '../lib/Setup';
import type { PreselectedProject, WizardOptions } from './utils/types';
import { runFlutterWizzard } from './flutter/flutter-wizzard';
import { runFlutterWizard } from './flutter/flutter-wizard';
import { runAndroidWizard } from './android/android-wizard';
import { runAppleWizard } from './apple/apple-wizard';
import { runNextjsWizard } from './nextjs/nextjs-wizard';
Expand Down Expand Up @@ -143,7 +143,7 @@ export async function run(argv: Args) {
break;

case 'flutter':
await runFlutterWizzard(wizardOptions);
await runFlutterWizard(wizardOptions);
break;

case 'ios':
Expand Down
12 changes: 9 additions & 3 deletions test/flutter/code-tools.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ void main() {
}
`;

const selectedFeaturesMap = {
tracing: true,
profiling: true,
replay: true,
};

const simpleRunAppPatched = `import 'package:flutter/widgets.dart';
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
${initSnippet('dsn', 'const MyApp()')}
${initSnippet('dsn', selectedFeaturesMap, 'const MyApp()')}
}
`;

Expand All @@ -57,7 +63,7 @@ import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
await someFunction();
${initSnippet('dsn', 'MyApp(param: SomeParam())')}
${initSnippet('dsn', selectedFeaturesMap, 'MyApp(param: SomeParam())')}
await anotherFunction();
}
`;
Expand All @@ -80,7 +86,7 @@ void main() {
import 'package:sentry_flutter/sentry_flutter.dart';
Future<void> main() async {
${initSnippet('dsn', `
${initSnippet('dsn', selectedFeaturesMap, `
MyApp(
param: Param(),
multi: Another(1),
Expand Down
138 changes: 138 additions & 0 deletions test/flutter/templates.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import {
pubspecOptions,
sentryProperties,
initSnippet,
} from '../../src/flutter/templates';

describe('Flutter code templates', () => {
describe('pubspec', () => {
it('generates pubspec with project and org', () => {
const template = pubspecOptions(
'fixture-project',
'fixture-org',
);
expect(template).toMatchInlineSnapshot(`
"sentry:
upload_source_maps: true
upload_sources: true
project: fixture-project
org: fixture-org
"
`);
});
});
describe('sentry.properties', () => {
it('generates sentry.properties with token', () => {
const template = sentryProperties(
'fixture-token',
);
expect(template).toMatchInlineSnapshot(`"auth_token=fixture-token"`);
});
});
describe('init', () => {
it('generates Sentry config with all features enabled', () => {
const template = initSnippet(
'my-dsn',
{
tracing: true,
profiling: true,
replay: true,
},
'const MyApp()',
);
expect(template).toMatchInlineSnapshot(`
"await SentryFlutter.init(
(options) {
options.dsn = 'my-dsn';
// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1.0;
// The sampling rate for profiling is relative to tracesSampleRate
// Setting to 1.0 will profile 100% of sampled transactions:
options.profilesSampleRate = 1.0;
options.experimental.replay.sessionSampleRate = 1.0;
options.experimental.replay.onErrorSampleRate = 1.0;
},
appRunner: () => runApp(const MyApp()),
);
// TODO: Remove this line after sending the first sample event to sentry.
await Sentry.captureMessage('This is a sample exception.');"
`);
});

it('generates Sentry config with replay disabled', () => {
const template = initSnippet(
'my-dsn',
{
tracing: true,
profiling: true,
replay: false,
},
'const MyApp()',
);
expect(template).toMatchInlineSnapshot(`
"await SentryFlutter.init(
(options) {
options.dsn = 'my-dsn';
// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1.0;
// The sampling rate for profiling is relative to tracesSampleRate
// Setting to 1.0 will profile 100% of sampled transactions:
options.profilesSampleRate = 1.0;
},
appRunner: () => runApp(const MyApp()),
);
// TODO: Remove this line after sending the first sample event to sentry.
await Sentry.captureMessage('This is a sample exception.');"
`);
});

it('generates Sentry config with profiling disabled', () => {
const template = initSnippet(
'my-dsn',
{
tracing: true,
profiling: false,
replay: false,
},
'const MyApp()',
);
expect(template).toMatchInlineSnapshot(`
"await SentryFlutter.init(
(options) {
options.dsn = 'my-dsn';
// Set tracesSampleRate to 1.0 to capture 100% of transactions for tracing.
// We recommend adjusting this value in production.
options.tracesSampleRate = 1.0;
},
appRunner: () => runApp(const MyApp()),
);
// TODO: Remove this line after sending the first sample event to sentry.
await Sentry.captureMessage('This is a sample exception.');"
`);
});

it('generates Sentry config with tracing disabled', () => {
const template = initSnippet(
'my-dsn',
{
tracing: false,
profiling: false,
replay: false,
},
'const MyApp()',
);
expect(template).toMatchInlineSnapshot(`
"await SentryFlutter.init(
(options) {
options.dsn = 'my-dsn';
},
appRunner: () => runApp(const MyApp()),
);
// TODO: Remove this line after sending the first sample event to sentry.
await Sentry.captureMessage('This is a sample exception.');"
`);
});
});
});

0 comments on commit d3ae482

Please sign in to comment.