Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/brisa/src/cli/build-standalone/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('cli/buildStandalone', () => {
afterEach(() => {
mockLog.mockRestore();
mockProcessExit.mockRestore();
fs.rmSync(BUILD_DIR, { recursive: true });
fs.rmSync(BUILD_DIR, { recursive: true, force: true });
});

it('should log "No standalone components provided" when no components are provided', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/brisa/src/core/test/api/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ describe('test api', () => {
BUILD_DIR,
SRC_DIR: BUILD_DIR,
ASSETS_DIR,
WORKSPACE: BUILD_DIR,
};
});

Expand Down
77 changes: 48 additions & 29 deletions packages/brisa/src/core/test/matchers/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import { expect, describe, it, beforeEach, afterEach } from 'bun:test';
import { GlobalRegistrator } from '@happy-dom/global-registrator';
import { greenLog, redLog } from '@/utils/log/log-color';

// Strip ANSI escape codes for color-agnostic comparison in error messages,
// since color support varies between isolated and full suite runs
const stripAnsi = (s: string) => s.replace(/\x1b\[[0-9;]*m/g, '');
function expectThrowContaining(fn: () => void, expected: string) {
try {
fn();
throw new Error('Expected function to throw');
} catch (e: any) {
expect(stripAnsi(e.message)).toContain(expected);
}
}

describe('test matchers', () => {
beforeEach(() => {
Expand Down Expand Up @@ -47,20 +58,18 @@ describe('test matchers', () => {
const div = document.createElement('div');
div.setAttribute('data-test', 'test-2');

expect(() =>
expect(div).toHaveAttribute('data-test', 'test'),
).toThrowError(
`Expected: ${greenLog('"test"')}\nReceived: ${redLog('"test-2"')}`,
expectThrowContaining(
() => expect(div).toHaveAttribute('data-test', 'test'),
'Expected: "test"\nReceived: "test-2"',
);
});

it('should not pass if the element has not the attribute specifing the attribute', () => {
const div = document.createElement('div');

expect(() =>
expect(div).toHaveAttribute('data-test', 'test'),
).toThrowError(
`Expected: ${greenLog('"test"')}\nReceived: ${redLog('null')}`,
expectThrowContaining(
() => expect(div).toHaveAttribute('data-test', 'test'),
'Expected: "test"\nReceived: null',
);
});

Expand Down Expand Up @@ -89,8 +98,9 @@ describe('test matchers', () => {
it('should fail if the element does not have the tag name', () => {
const div = document.createElement('div');

expect(() => expect(div).toHaveTagName('span')).toThrowError(
`Expected: ${greenLog('span')}\nReceived: ${redLog('div')}`,
expectThrowContaining(
() => expect(div).toHaveTagName('span'),
'Expected: span\nReceived: div',
);
});
});
Expand Down Expand Up @@ -135,16 +145,18 @@ describe('test matchers', () => {
const div = document.createElement('div');
div.textContent = 'test-2';

expect(() => expect(div).toHaveTextContent('test')).toThrowError(
`Expected: ${greenLog('"test"')}\nReceived: ${redLog('"test-2"')}`,
expectThrowContaining(
() => expect(div).toHaveTextContent('test'),
'Expected: "test"\nReceived: "test-2"',
);
});

it('should fail if the element does not have the rendered text', () => {
const div = document.createElement('div');

expect(() => expect(div).toHaveTextContent('test')).toThrowError(
`Expected: ${greenLog('"test"')}\nReceived: ${redLog('""')}`,
expectThrowContaining(
() => expect(div).toHaveTextContent('test'),
'Expected: "test"\nReceived: ""',
);
});
});
Expand Down Expand Up @@ -205,16 +217,18 @@ describe('test matchers', () => {
const div = document.createElement('div');
div.textContent = 'foo';

expect(() => expect(div).toContainTextContent('test')).toThrowError(
`Expected to contain: ${greenLog('"test"')}\nReceived: ${redLog('"foo"')}`,
expectThrowContaining(
() => expect(div).toContainTextContent('test'),
'Expected to contain: "test"\nReceived: "foo"',
);
});

it('should fail if the element does not contain the rendered text', () => {
const div = document.createElement('div');

expect(() => expect(div).toContainTextContent('test')).toThrowError(
`Expected to contain: ${greenLog('"test"')}\nReceived: ${redLog('""')}`,
expectThrowContaining(
() => expect(div).toContainTextContent('test'),
'Expected to contain: "test"\nReceived: ""',
);
});
});
Expand All @@ -231,16 +245,18 @@ describe('test matchers', () => {
const div = document.createElement('div');
div.style.color = 'red';

expect(() => expect(div).toHaveStyle('color', 'blue')).toThrowError(
`Expected: ${greenLog('"blue"')}\nReceived: ${redLog('"red"')}`,
expectThrowContaining(
() => expect(div).toHaveStyle('color', 'blue'),
'Expected: "blue"\nReceived: "red"',
);
});

it('should fail if the element does not have any style', () => {
const div = document.createElement('div');

expect(() => expect(div).toHaveStyle('color', 'blue')).toThrowError(
`Expected: ${greenLog('"blue"')}\nReceived: ${redLog('""')}`,
expectThrowContaining(
() => expect(div).toHaveStyle('color', 'blue'),
'Expected: "blue"\nReceived: ""',
);
});
});
Expand All @@ -257,8 +273,9 @@ describe('test matchers', () => {
it('should fail if the element does not have the class', () => {
const div = document.createElement('div');

expect(() => expect(div).toHaveClass('test')).toThrowError(
`Expected: ${greenLog('"test"')}\nReceived: ${redLog('""')}`,
expectThrowContaining(
() => expect(div).toHaveClass('test'),
'Expected: "test"\nReceived: ""',
);
});
});
Expand All @@ -274,8 +291,9 @@ describe('test matchers', () => {
it('should fail if the input does not have the value', () => {
const input = document.createElement('input');

expect(() => expect(input).toHaveValue('test')).toThrowError(
`Expected: ${greenLog('"test"')}\nReceived: ${redLog('""')}`,
expectThrowContaining(
() => expect(input).toHaveValue('test'),
'Expected: "test"\nReceived: ""',
);
});

Expand Down Expand Up @@ -520,8 +538,9 @@ describe('test matchers', () => {
const input = document.createElement('input');
input.type = 'text';

expect(() => expect(input).toBeInputTypeOf('number')).toThrowError(
`Expected: ${greenLog('"number"')}\nReceived: ${redLog('"text"')}`,
expectThrowContaining(
() => expect(input).toBeInputTypeOf('number'),
'Expected: "number"\nReceived: "text"',
);
});

Expand Down
39 changes: 39 additions & 0 deletions packages/brisa/src/utils/brisa-error-dialog/build-inject-code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Standalone build script spawned from inject-code.ts macro
// This avoids calling Bun.build inside a macro (deadlock in Bun >= 1.2)
import path from 'node:path';
import clientBuildPlugin from '@/utils/client-build-plugin';

const pathname = path.join(
import.meta.dir,
'web-components',
'brisa-error-dialog.tsx',
);
const internalComponentId = '__BRISA_CLIENT__brisaErrorDialog';

const { success, outputs } = await Bun.build({
throw: false,
entrypoints: [pathname],
target: 'browser',
external: ['brisa'],
define: {
__FILTER_DEV_RUNTIME_ERRORS__: '__FILTER_DEV_RUNTIME_ERRORS__',
},
plugins: [
{
name: 'dev-error-dialog-plugin',
setup(build) {
build.onLoad({ filter: /.*/ }, async ({ path, loader }) => ({
contents: clientBuildPlugin(
await Bun.readableStreamToText(Bun.file(path).stream()),
internalComponentId,
),
loader,
}));
},
},
],
});

if (success && outputs?.[0]) {
process.stdout.write(await outputs[0].text());
}
42 changes: 5 additions & 37 deletions packages/brisa/src/utils/brisa-error-dialog/inject-code.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,14 @@
import path from 'node:path';
import clientBuildPlugin from '@/utils/client-build-plugin';
import { logBuildError } from '@/utils/log/log-build';

// Should be used via macro
export async function injectBrisaDialogErrorCode() {
const pathname = path.join(
import.meta.dir,
'web-components',
'brisa-error-dialog.tsx',
);
const internalComponentId = '__BRISA_CLIENT__brisaErrorDialog';
const scriptPath = path.join(import.meta.dir, 'build-inject-code.ts');
const result = Bun.spawnSync(['bun', 'run', scriptPath]);

const { success, logs, outputs } = await Bun.build({
// TODO: adapt to Bun > 1.2 (for now this is to force the old behavior)
throw: false,
entrypoints: [pathname],
target: 'browser',
external: ['brisa'],
define: {
__FILTER_DEV_RUNTIME_ERRORS__: '__FILTER_DEV_RUNTIME_ERRORS__',
},
plugins: [
{
name: 'dev-error-dialog-plugin',
setup(build) {
build.onLoad({ filter: /.*/ }, async ({ path, loader }) => ({
contents: clientBuildPlugin(
// TODO: use (path).text() when Bun fix this issue:
// https://github.com/oven-sh/bun/issues/7611
await Bun.readableStreamToText(Bun.file(path).stream()),
internalComponentId,
),
loader,
}));
},
},
],
});

if (!success) {
logBuildError('Failed to use brisa dialog error in development', logs);
if (result.exitCode !== 0) {
logBuildError('Failed to use brisa dialog error in development', []);
}

return (await outputs?.[0]?.text?.()) ?? '';
return result.stdout.toString();
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe('build utils -> client build', () => {
it('should return the correct temp file name', () => {
const { BUILD_DIR } = getConstants();
const pagePath = '/path/to/page.tsx';
const expected = join(BUILD_DIR, '_brisa', 'temp-path-to-page.ts');
const expected = join(BUILD_DIR, '_brisa', 'temppage_tsx.ts');
const result = getTempPageName(pagePath);
expect(result).toBe(expected);
});
Expand All @@ -21,12 +21,12 @@ describe('build utils -> client build', () => {
const expected1 = join(
BUILD_DIR,
'_brisa',
'temp-path-to-page_example.ts',
'temppage_example_tsx.ts',
);
const expected2 = join(
BUILD_DIR,
'_brisa',
'temp-path-to-page-example.ts',
'tempexample_tsx.ts',
);

const result1 = getTempPageName(pagePath1);
Expand All @@ -39,7 +39,7 @@ describe('build utils -> client build', () => {
it('should handle page paths with multiple extensions correctly', () => {
const { BUILD_DIR } = getConstants();
const pagePath = '/path/to/page.min.tsx';
const expected = join(BUILD_DIR, '_brisa', 'temp-path-to-page.min.ts');
const expected = join(BUILD_DIR, '_brisa', 'temppage_min_tsx.ts');
const result = getTempPageName(pagePath);
expect(result).toBe(expected);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ const pageWebComponents = {
'native-some-example': allWebComponents['native-some-example'],
};

const i18nCode = 3653;
const i18nCode = 3733;
const brisaSize = 5738; // TODO: Reduce this size :/
const webComponents = 1453;
const unsuspenseSize = 213;
const rpcSize = 2499; // TODO: Reduce this size
const rpcSize = 2490; // TODO: Reduce this size
const lazyRPCSize = 4332; // TODO: Reduce this size
// lazyRPC is loaded after user interaction (action, link),
// so it's not included in the initial size
Expand Down
Loading
Loading