Skip to content

Commit 843812e

Browse files
committed
Add tests
1 parent 5ceb123 commit 843812e

File tree

11 files changed

+572
-21
lines changed

11 files changed

+572
-21
lines changed

packages/solid/test/errorboundary.test.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('withSentryErrorBoundary', () => {
4444
it('calls `captureException` when an error occurs`', () => {
4545
render(() => (
4646
<SentryErrorBoundary fallback={<div>Ooops, an error occurred.</div>}>
47+
{/* @ts-expect-error: component doesn't exist on purpose */}
4748
<NonExistentComponent />
4849
</SentryErrorBoundary>
4950
));
@@ -55,6 +56,7 @@ describe('withSentryErrorBoundary', () => {
5556
it('renders the fallback component', async () => {
5657
const { findByText } = render(() => (
5758
<SentryErrorBoundary fallback={<div>Ooops, an error occurred.</div>}>
59+
{/* @ts-expect-error: component doesn't exist on purpose */}
5860
<NonExistentComponent />
5961
</SentryErrorBoundary>
6062
));
@@ -65,11 +67,12 @@ describe('withSentryErrorBoundary', () => {
6567
it('passes the `error` and `reset` function to the fallback component', () => {
6668
const mockFallback = vi.fn();
6769

68-
render(() => {
70+
render(() => (
6971
<SentryErrorBoundary fallback={mockFallback}>
72+
{/* @ts-expect-error: component doesn't exist on purpose */}
7073
<NonExistentComponent />
71-
</SentryErrorBoundary>;
72-
});
74+
</SentryErrorBoundary>
75+
));
7376

7477
expect(mockFallback).toHaveBeenCalledTimes(1);
7578
expect(mockFallback).toHaveBeenCalledWith(
@@ -81,6 +84,7 @@ describe('withSentryErrorBoundary', () => {
8184
it('calls `captureException` again after resetting', async () => {
8285
const { findByRole } = render(() => (
8386
<SentryErrorBoundary fallback={(_, reset) => <button onClick={reset}>Reset</button>}>
87+
{/* @ts-expect-error: component doesn't exist on purpose */}
8488
<NonExistentComponent />
8589
</SentryErrorBoundary>
8690
));

packages/solid/test/sdk.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { init as solidInit } from '../src/sdk';
66

77
const browserInit = vi.spyOn(SentryBrowser, 'init');
88

9-
describe('Initialize Solid SDk', () => {
9+
describe('Initialize Solid SDK', () => {
1010
beforeEach(() => {
1111
vi.clearAllMocks();
1212
});

packages/solidstart/README.md

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111
[![npm dt](https://img.shields.io/npm/dt/@sentry/solidstart.svg)](https://www.npmjs.com/package/@sentry/solidstart)
1212

1313
This SDK is considered ⚠️ **experimental and in an alpha state**. It may experience breaking changes. Please reach out
14-
on [GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose) if you have any feedback or concerns.
15-
This SDK is for [Solid Start](https://start.solidjs.com/).
16-
If you're using [Solid](https://www.solidjs.com/) see our Solid SDK here.
17-
14+
on [GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose) if you have any feedback or concerns. This
15+
SDK is for [Solid Start](https://start.solidjs.com/). If you're using [Solid](https://www.solidjs.com/) see our Solid
16+
SDK here.
1817

1918
## Links
2019

@@ -33,41 +32,41 @@ If the setup through the wizard doesn't work for you, you can also set up the SD
3332

3433
Install the Sentry Solid Start SDK:
3534

36-
```bash
37-
# Using npm
38-
npm install @sentry/solidstart
35+
```bash
36+
# Using npm
37+
npm install @sentry/solidstart
3938

40-
# Using yarn
41-
yarn add @sentry/solidstart
42-
```
39+
# Using yarn
40+
yarn add @sentry/solidstart
41+
```
4342

4443
### 2. Client-side Setup
4544

4645
Initialize the SDK in `entry-client.jsx`
4746

4847
```jsx
4948
import * as Sentry from '@sentry/solidstart';
50-
import { mount, StartClient } from "@solidjs/start/client";
49+
import { mount, StartClient } from '@solidjs/start/client';
5150

5251
Sentry.init({
5352
dsn: '__PUBLIC_DSN__',
5453
tracesSampleRate: 1.0, // Capture 100% of the transactions
5554
});
5655

57-
mount(() => <StartClient />, document.getElementById("app"));
56+
mount(() => <StartClient />, document.getElementById('app'));
5857
```
5958

6059
### 3. Server-side Setup
6160

6261
Create an instrumentation file named `instrument.server.mjs` and add your initialization code for the server-side SDK.
6362

6463
```javascript
65-
import * as Sentry from "@sentry/solidstart";
64+
import * as Sentry from '@sentry/solidstart';
6665

6766
Sentry.init({
68-
dsn: "https://[email protected]/4507459091824640",
69-
tracesSampleRate: 1.0, // Capture 100% of the transactions
70-
})
67+
dsn: 'https://[email protected]/4507459091824640',
68+
tracesSampleRate: 1.0, // Capture 100% of the transactions
69+
});
7170
```
7271

7372
### 4. Run your application
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/* eslint-disable @typescript-eslint/unbound-method */
2+
import type * as SentryBrowser from '@sentry/browser';
3+
import { createTransport, getCurrentScope, setCurrentClient } from '@sentry/core';
4+
import { render } from '@solidjs/testing-library';
5+
import userEvent from '@testing-library/user-event';
6+
import { vi } from 'vitest';
7+
8+
import { ErrorBoundary } from 'solid-js';
9+
import { BrowserClient, withSentryErrorBoundary } from '../../src/client';
10+
11+
const mockCaptureException = vi.fn();
12+
vi.mock('@sentry/browser', async () => {
13+
const actual = await vi.importActual<typeof SentryBrowser>('@sentry/browser');
14+
return {
15+
...actual,
16+
captureException: (...args) => mockCaptureException(...args),
17+
} as typeof SentryBrowser;
18+
});
19+
20+
const user = userEvent.setup();
21+
const SentryErrorBoundary = withSentryErrorBoundary(ErrorBoundary);
22+
23+
describe('withSentryErrorBoundary', () => {
24+
function createMockBrowserClient(): BrowserClient {
25+
return new BrowserClient({
26+
integrations: [],
27+
tracesSampleRate: 1,
28+
transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => Promise.resolve({})),
29+
stackParser: () => [],
30+
});
31+
}
32+
33+
beforeEach(() => {
34+
vi.clearAllMocks();
35+
36+
const client = createMockBrowserClient();
37+
setCurrentClient(client);
38+
});
39+
40+
afterEach(() => {
41+
getCurrentScope().setClient(undefined);
42+
});
43+
44+
it('calls `captureException` when an error occurs`', () => {
45+
render(() => (
46+
<SentryErrorBoundary fallback={<div>Ooops, an error occurred.</div>}>
47+
{/* @ts-expect-error: component doesn't exist on purpose */}
48+
<NonExistentComponent />
49+
</SentryErrorBoundary>
50+
));
51+
52+
expect(mockCaptureException).toHaveBeenCalledTimes(1);
53+
expect(mockCaptureException).toHaveBeenLastCalledWith(new ReferenceError('NonExistentComponent is not defined'));
54+
});
55+
56+
it('renders the fallback component', async () => {
57+
const { findByText } = render(() => (
58+
<SentryErrorBoundary fallback={<div>Ooops, an error occurred.</div>}>
59+
{/* @ts-expect-error: component doesn't exist on purpose */}
60+
<NonExistentComponent />
61+
</SentryErrorBoundary>
62+
));
63+
64+
expect(await findByText('Ooops, an error occurred.')).toBeInTheDocument();
65+
});
66+
67+
it('passes the `error` and `reset` function to the fallback component', () => {
68+
const mockFallback = vi.fn();
69+
70+
render(() => (
71+
<SentryErrorBoundary fallback={mockFallback}>
72+
{/* @ts-expect-error: component doesn't exist on purpose */}
73+
<NonExistentComponent />
74+
</SentryErrorBoundary>
75+
));
76+
77+
expect(mockFallback).toHaveBeenCalledTimes(1);
78+
expect(mockFallback).toHaveBeenCalledWith(
79+
new ReferenceError('NonExistentComponent is not defined'),
80+
expect.any(Function),
81+
);
82+
});
83+
84+
it('calls `captureException` again after resetting', async () => {
85+
const { findByRole } = render(() => (
86+
<SentryErrorBoundary fallback={(_, reset) => <button onClick={reset}>Reset</button>}>
87+
{/* @ts-expect-error: component doesn't exist on purpose */}
88+
<NonExistentComponent />
89+
</SentryErrorBoundary>
90+
));
91+
92+
expect(mockCaptureException).toHaveBeenCalledTimes(1);
93+
expect(mockCaptureException).toHaveBeenNthCalledWith(1, new ReferenceError('NonExistentComponent is not defined'));
94+
95+
const button = await findByRole('button');
96+
await user.click(button);
97+
98+
expect(mockCaptureException).toHaveBeenCalledTimes(2);
99+
expect(mockCaptureException).toHaveBeenNthCalledWith(2, new ReferenceError('NonExistentComponent is not defined'));
100+
});
101+
102+
it('renders children when there is no error', async () => {
103+
const { queryByText } = render(() => (
104+
<SentryErrorBoundary fallback={<div>Oops, an error occurred.</div>}>
105+
<div>Adopt a cat</div>
106+
</SentryErrorBoundary>
107+
));
108+
109+
expect(await queryByText('Adopt a cat')).toBeInTheDocument();
110+
expect(await queryByText('Ooops, an error occurred')).not.toBeInTheDocument();
111+
});
112+
});
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { SDK_VERSION } from '@sentry/solid';
2+
import * as SentrySolid from '@sentry/solid';
3+
4+
import { vi } from 'vitest';
5+
import { init as solidStartInit } from '../../src/client';
6+
7+
const browserInit = vi.spyOn(SentrySolid, 'init');
8+
9+
describe('Initialize Solid Start SDK', () => {
10+
beforeEach(() => {
11+
vi.clearAllMocks();
12+
});
13+
14+
it('has the correct metadata', () => {
15+
const client = solidStartInit({
16+
dsn: 'https://[email protected]/1337',
17+
});
18+
19+
const expectedMetadata = {
20+
_metadata: {
21+
sdk: {
22+
name: 'sentry.javascript.solidstart',
23+
packages: [
24+
{ name: 'npm:@sentry/solidstart', version: SDK_VERSION },
25+
{ name: 'npm:@sentry/solid', version: SDK_VERSION },
26+
],
27+
version: SDK_VERSION,
28+
},
29+
},
30+
};
31+
32+
expect(client).not.toBeUndefined();
33+
expect(browserInit).toHaveBeenCalledTimes(1);
34+
expect(browserInit).toHaveBeenLastCalledWith(expect.objectContaining(expectedMetadata));
35+
});
36+
37+
it('sets the runtime tag on the isolation scope', () => {
38+
solidStartInit({ dsn: 'https://[email protected]/1337' });
39+
40+
expect(SentrySolid.getIsolationScope().getScopeData().tags).toEqual({ runtime: 'browser' });
41+
});
42+
});

0 commit comments

Comments
 (0)