Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
3 changes: 0 additions & 3 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,7 @@ function createEsbuildPlugin(filteredPkgList) {
}

const pkgList = {
react: "@preact/signals-react",
"react/utils": "@preact/signals-react/utils",
"react/runtime": "@preact/signals-react/runtime",
"react-transform": "@preact/signals-react-transform",
};

module.exports = function (config) {
Expand Down
6 changes: 1 addition & 5 deletions mangle.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@
},
"minify": {
"mangle": {
"reserved": [
"useSignal",
"useComputed",
"useSignalEffect"
],
"reserved": ["useSignal", "useComputed", "useSignalEffect"],
"keep_classnames": true,
"properties": {
"regex": "^_[^_]",
Expand Down
31 changes: 5 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,11 @@
"lint:oxlint": "oxlint 'packages/**/*.{ts,tsx,js,jsx}'",
"lint:tsc": "tsc -p tsconfig.json --noEmit",
"lint-staged": "lint-staged",
"test": "pnpm test:karma && pnpm test:mocha && pnpm test:vitest",
"test:minify": "pnpm test:karma:minify && pnpm test:mocha",
"test:prod": "pnpm test:karma:prod && pnpm test:mocha:prod",
"test:karma": "cross-env COVERAGE=true karma start karma.conf.js --single-run",
"test:karma:minify": "cross-env COVERAGE=true MINIFY=true karma start karma.conf.js --single-run",
"test:karma:watch": "karma start karma.conf.js --no-single-run",
"test:karma:prod": "cross-env MINIFY=true NODE_ENV=production karma start karma.conf.js --single-run",
"test:karma:prod:watch": "cross-env NODE_ENV=production karma start karma.conf.js --no-single-run",
"test:mocha": "cross-env COVERAGE=true mocha --require test/node/setup.js --recursive packages/*/test/node/**.test.tsx --ignore \"packages/{preact/utils,preact,core}\"",
"test:mocha:prod": "cross-env COVERAGE=true NODE_ENV=production mocha --require test/node/setup.js --recursive packages/*/test/node/**.test.tsx --ignore \"packages/{preact/utils,preact,core}\"",
"test": "pnpm test:vitest",
"test:minify": "pnpm test:vitest:prod",
"test:prod": "pnpm test:vitest:prod",
"test:vitest": "cross-env COVERAGE=true vitest run",
"test:vitest:prod": "cross-env COVERAGE=true MINIFY=true vitest run",
"docs:start": "cd docs && pnpm start",
"docs:build": "cd docs && pnpm build",
"docs:preview": "cd docs && pnpm preview",
Expand Down Expand Up @@ -60,40 +54,25 @@
"@babel/standalone": "^7.27.7",
"@changesets/changelog-github": "^0.5.0",
"@changesets/cli": "^2.27.1",
"@preact/signals-react-transform": "workspace:*",
"@types/babel__traverse": "^7.18.5",
"@types/chai": "^4.3.3",
"@types/mocha": "^9.1.1",
"@types/node": "^18.19.103",
"@types/sinon": "^10.0.13",
"@types/sinon-chai": "^3.2.8",
"@vitest/browser": "^3.2.4",
"@vitest/coverage-v8": "^3.2.4",
"babel-plugin-istanbul": "^6.1.1",
"babel-plugin-transform-rename-properties": "^0.1.0",
"buffer": "^6.0.3",
"chai": "^4.3.6",
"cross-env": "^7.0.3",
"errorstacks": "^2.4.0",
"esbuild": "^0.14.54",
"husky": "^8.0.1",
"karma": "6.4.2",
"karma-chai-sinon": "^0.1.5",
"karma-chrome-launcher": "^3.1.1",
"karma-coverage": "^2.2.0",
"karma-esbuild": "^2.2.5",
"karma-mocha": "^2.0.1",
"karma-mocha-reporter": "^2.2.5",
"karma-sinon": "^1.0.5",
"kolorist": "^1.5.1",
"lint-staged": "^14.0.1",
"microbundle": "^0.15.1",
"mocha": "^10.0.0",
"oxlint": "^1.3.0",
"playwright": "^1.53.1",
"prettier": "^3.6.2",
"shx": "^0.3.4",
"sinon": "^14.0.0",
"sinon-chai": "^3.7.0",
"typescript": "~5.8.3",
"vitest": "^3.2.4",
"vite": "^6.3.5"
Expand Down
1 change: 1 addition & 0 deletions packages/react-transform/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
},
"devDependencies": {
"@babel/core": "^7.22.8",
"@preact/signals-core": "workspace:*",
"@types/babel__core": "^7.20.1",
"@types/babel__helper-module-imports": "^7.18.0",
"@types/babel__helper-plugin-utils": "^7.10.0",
Expand Down
6 changes: 3 additions & 3 deletions packages/react-transform/test/browser/e2e.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
createRoot,
getConsoleErrorSpy,
} from "../../../react/test/shared/utils";
import { describe, beforeEach, afterEach, expect, it } from "vitest";
import "../../../../test/browser/babel.js";

const customSource = "useSignals-custom-source";
const modules: Record<string, any> = {
Expand All @@ -32,8 +34,6 @@ function testRequire(name: string) {
}

async function createComponent(code: string, options?: PluginOptions) {
// `transformSignalCode` is a global helper function added to the global
// namespace by a test helper we've included in the Karma config.
const cjsCode = transformSignalCode(code, options);
// console.log(cjsCode); // Useful when debugging tests.

Expand All @@ -55,7 +55,7 @@ describe("React Signals babel transfrom - browser E2E tests", () => {
scratch = document.createElement("div");
document.body.appendChild(scratch);
root = await createRoot(scratch);
getConsoleErrorSpy().resetHistory();
getConsoleErrorSpy().mockClear();
});

afterEach(async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/react-transform/test/node/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
objMethodComp,
variableHooks,
} from "./helpers";
import { it, describe, expect } from "vitest";

// To help interactively debug a specific test case, add the test ids of the
// test cases you want to debug to the `debugTestIds` array, e.g. (["258",
Expand Down
3 changes: 3 additions & 0 deletions packages/react/runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"@preact/signals-core": "workspace:^1.3.0",
"use-sync-external-store": "^1.2.0"
},
"devDependencies": {
"@preact/signals-react": "workspace:*"
},
"peerDependencies": {
"react": "^16.14.0 || 17.x || 18.x"
}
Expand Down
3 changes: 2 additions & 1 deletion packages/react/runtime/test/browser/mounts.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
createRoot,
type Root,
} from "../../../test/shared/utils.js";
import { describe, beforeEach, afterEach } from "vitest";

describe("@preact/signals-react/runtime", () => {
describe("mounting", () => {
Expand All @@ -25,7 +26,7 @@ describe("@preact/signals-react/runtime", () => {
beforeEach(async () => {
scratch = document.createElement("div");
document.body.appendChild(scratch);
getConsoleErrorSpy().resetHistory();
getConsoleErrorSpy().mockClear();

root = await createRoot(scratch);
});
Expand Down
3 changes: 2 additions & 1 deletion packages/react/runtime/test/browser/suspense.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
checkHangingAct,
getConsoleErrorSpy,
} from "../../../test/shared/utils";
import { beforeEach, afterEach, describe, it, expect } from "vitest";

describe("Suspense", () => {
let scratch: HTMLDivElement;
Expand All @@ -28,7 +29,7 @@ describe("Suspense", () => {
scratch = document.createElement("div");
document.body.appendChild(scratch);
root = await createRoot(scratch);
getConsoleErrorSpy().resetHistory();
getConsoleErrorSpy().mockClear();
});

afterEach(async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/react/runtime/test/browser/updates.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

import { updateSignalsTests } from "../../../test/shared/updates";
import { describe } from "vitest";

describe("@preact/signals-react/runtime", () => {
describe("updating", () => {
Expand Down
73 changes: 37 additions & 36 deletions packages/react/runtime/test/browser/useSignals.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
checkHangingAct,
getConsoleErrorSpy,
} from "../../../test/shared/utils";
import { describe, expect, beforeEach, afterEach, vi, it } from "vitest";

const MANAGED_COMPONENT = 1;
const MANAGED_HOOK = 2;
Expand Down Expand Up @@ -52,7 +53,7 @@ describe("useSignals", () => {
scratch = document.createElement("div");
document.body.appendChild(scratch);
root = await createRoot(scratch);
getConsoleErrorSpy().resetHistory();
getConsoleErrorSpy().mockClear();
});

afterEach(async () => {
Expand Down Expand Up @@ -142,23 +143,23 @@ describe("useSignals", () => {
});

it("should not rerender components when signals they use do not change", async () => {
const child1Spy = sinon.spy();
const child1Spy = vi.fn();
const signal1 = signal(0);
function Child1() {
child1Spy();
useSignals();
return <p>{signal1.value}</p>;
}

const child2Spy = sinon.spy();
const child2Spy = vi.fn();
const signal2 = signal(0);
function Child2() {
child2Spy();
useSignals();
return <p>{signal2.value}</p>;
}

const parentSpy = sinon.spy();
const parentSpy = vi.fn();
function Parent() {
parentSpy();
return (
Expand All @@ -170,39 +171,39 @@ describe("useSignals", () => {
}

function resetSpies() {
child1Spy.resetHistory();
child2Spy.resetHistory();
parentSpy.resetHistory();
child1Spy.mockClear();
child2Spy.mockClear();
parentSpy.mockClear();
}

resetSpies();
await render(<Parent />);
expect(scratch.innerHTML).to.equal("<p>0</p><p>0</p>");
expect(child1Spy).to.have.been.calledOnce;
expect(child2Spy).to.have.been.calledOnce;
expect(parentSpy).to.have.been.calledOnce;
expect(child1Spy).toHaveBeenCalledOnce();
expect(child2Spy).toHaveBeenCalledOnce();
expect(parentSpy).toHaveBeenCalledOnce();

resetSpies();
await act(() => {
signal1.value += 1;
});
expect(scratch.innerHTML).to.equal("<p>1</p><p>0</p>");
expect(child1Spy).to.have.been.calledOnce;
expect(child2Spy).to.not.have.been.called;
expect(parentSpy).to.not.have.been.called;
expect(child1Spy).toHaveBeenCalledOnce();
expect(child2Spy).not.toHaveBeenCalled();
expect(parentSpy).not.toHaveBeenCalled();

resetSpies();
await act(() => {
signal2.value += 1;
});
expect(scratch.innerHTML).to.equal("<p>1</p><p>1</p>");
expect(child1Spy).to.not.have.been.called;
expect(child2Spy).to.have.been.calledOnce;
expect(parentSpy).to.not.have.been.called;
expect(child1Spy).not.toHaveBeenCalled();
expect(child2Spy).toHaveBeenCalledOnce();
expect(parentSpy).not.toHaveBeenCalled();
});

it("should not rerender components when signals they use change but they are not mounted", async () => {
const child1Spy = sinon.spy();
const child1Spy = vi.fn();
const signal1 = signal(0);
function Child() {
child1Spy();
Expand Down Expand Up @@ -231,11 +232,11 @@ describe("useSignals", () => {
await act(() => {
signal1.value += 1;
});
expect(child1Spy).to.have.been.calledTwice;
expect(child1Spy).toHaveBeenCalledTimes(2);
});

it("should not rerender components that only update signals in event handlers", async () => {
const buttonSpy = sinon.spy();
const buttonSpy = vi.fn();
function AddOneButton({ num }: { num: Signal<number> }) {
useSignals();
buttonSpy();
Expand All @@ -250,7 +251,7 @@ describe("useSignals", () => {
);
}

const displaySpy = sinon.spy();
const displaySpy = vi.fn();
function DisplayNumber({ num }: { num: Signal<number> }) {
useSignals();
displaySpy();
Expand All @@ -269,20 +270,20 @@ describe("useSignals", () => {

await render(<App />);
expect(scratch.innerHTML).to.equal("<button>Add One</button><p>0</p>");
expect(buttonSpy).to.have.been.calledOnce;
expect(displaySpy).to.have.been.calledOnce;
expect(buttonSpy).toHaveBeenCalledOnce();
expect(displaySpy).toHaveBeenCalledOnce();

await act(() => {
scratch.querySelector("button")!.click();
});

expect(scratch.innerHTML).to.equal("<button>Add One</button><p>1</p>");
expect(buttonSpy).to.have.been.calledOnce;
expect(displaySpy).to.have.been.calledTwice;
expect(buttonSpy).toHaveBeenCalledOnce();
expect(displaySpy).toHaveBeenCalledTimes(2);
});

it("should not rerender components that only read signals in event handlers", async () => {
const buttonSpy = sinon.spy();
const buttonSpy = vi.fn();
function AddOneButton({ num }: { num: Signal<number> }) {
useSignals();
buttonSpy();
Expand All @@ -297,7 +298,7 @@ describe("useSignals", () => {
);
}

const displaySpy = sinon.spy();
const displaySpy = vi.fn();
function DisplayNumber({ num }: { num: Signal<number> }) {
useSignals();
displaySpy();
Expand All @@ -316,42 +317,42 @@ describe("useSignals", () => {
}

function resetSpies() {
buttonSpy.resetHistory();
displaySpy.resetHistory();
buttonSpy.mockClear();
displaySpy.mockClear();
}

resetSpies();
await render(<App />);
expect(scratch.innerHTML).to.equal("<button>Add One</button><p>0</p>");
expect(buttonSpy).to.have.been.calledOnce;
expect(displaySpy).to.have.been.calledOnce;
expect(buttonSpy).toHaveBeenCalledOnce();
expect(displaySpy).toHaveBeenCalledOnce();

resetSpies();
await act(() => {
scratch.querySelector("button")!.click();
});

expect(scratch.innerHTML).to.equal("<button>Add One</button><p>2</p>");
expect(buttonSpy).to.not.have.been.called;
expect(displaySpy).to.have.been.calledOnce;
expect(buttonSpy).not.toHaveBeenCalled();
expect(displaySpy).toHaveBeenCalledOnce();

resetSpies();
await act(() => {
adder.value += 1;
});

expect(scratch.innerHTML).to.equal("<button>Add One</button><p>2</p>");
expect(buttonSpy).to.not.have.been.called;
expect(displaySpy).to.not.have.been.called;
expect(buttonSpy).not.toHaveBeenCalled();
expect(displaySpy).not.toHaveBeenCalled();

resetSpies();
await act(() => {
scratch.querySelector("button")!.click();
});

expect(scratch.innerHTML).to.equal("<button>Add One</button><p>5</p>");
expect(buttonSpy).to.not.have.been.called;
expect(displaySpy).to.have.been.calledOnce;
expect(buttonSpy).not.toHaveBeenCalled();
expect(displaySpy).toHaveBeenCalledOnce();
});

it("should properly rerender components that use custom hooks", async () => {
Expand Down
Loading
Loading