Skip to content

Commit

Permalink
Add auto pkg & run react runtimes tests against auto & transform runt…
Browse files Browse the repository at this point in the history
…imes (#443)

* Update caniuse-lite

* Add auto subpackage to signals-react

* Remove auto from allowed exports until next major release

* Separate and duplicate tests for runtime & transform from auto tests

* Transform test files to test transform on react test files

* Add note about how to test react-transform on some test files

* Skip tests transform doesn't support

* Fix mounting tests in SSR

* Add browser and SSR tests for auto and transform react runtimes

* Improve testing naming & nesting

* Change ts-ignore to expect-error in test files
  • Loading branch information
andrewiggins authored Nov 21, 2023
1 parent 76babcb commit 020982d
Show file tree
Hide file tree
Showing 20 changed files with 309 additions and 131 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-paws-switch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@preact/signals-react": patch
---

Setup internal infrastructure for upcoming major change
33 changes: 32 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ var localLaunchers = {
},
};

/* eslint-disable no-console */
const signalsTransformPath = require.resolve("./packages/react-transform");
console.log(`Transforming tests using ${signalsTransformPath}.`);
console.log(
`Manually re-compile & re-run tests to validate changes to react-transform`
);

const subPkgPath = pkgName => {
if (!minify) {
return path.join(__dirname, pkgName, "src", "index.ts");
Expand Down Expand Up @@ -62,6 +69,8 @@ function createEsbuildPlugin() {
"@preact/signals-core": subPkgPath("./packages/core"),
"@preact/signals": subPkgPath("./packages/preact"),
"@preact/signals-react": subPkgPath("./packages/react"),
"@preact/signals-react/auto": subPkgPath("./packages/react/auto"),
"@preact/signals-react/runtime": subPkgPath("./packages/react/runtime"),
"@preact/signals-react-transform": subPkgPath("./packages/react-transform"),
};

Expand Down Expand Up @@ -145,6 +154,20 @@ function createEsbuildPlugin() {
},
];

/** @type {any} */
let signalsTransform = false;
if (
args.path.includes("packages/react/test/shared") ||
args.path.includes("packages/react/runtime/test")
) {
signalsTransform = [
signalsTransformPath,
{
mode: "auto",
},
];
}

const downlevelPlugin = [
"@babel/preset-env",
{
Expand All @@ -168,6 +191,7 @@ function createEsbuildPlugin() {
sourceMaps: "inline",
presets: downlevel ? [ts, jsx, downlevelPlugin] : [ts, jsx],
plugins: [
signalsTransform,
coverage && coveragePlugin,
minify && renamePlugin,
].filter(Boolean),
Expand Down Expand Up @@ -198,7 +222,14 @@ function createEsbuildPlugin() {
};
}

const pkgList = ["core", "preact", "react", "react/runtime", "react-transform"];
const pkgList = [
"core",
"preact",
"react",
"react/auto",
"react/runtime",
"react-transform",
];

module.exports = function (config) {
config.set({
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
"private": true,
"scripts": {
"prebuild": "rimraf packages/core/dist/ packages/preact/dist",
"build": "pnpm build:core && pnpm build:preact && pnpm build:react-runtime && pnpm build:react && pnpm build:react-transform",
"build": "pnpm build:core && pnpm build:preact && pnpm build:react-runtime && pnpm build:react-auto && pnpm build:react && pnpm build:react-transform",
"_build": "microbundle --raw --globals @preact/signals-core=preactSignalsCore,preact/hooks=preactHooks",
"build:core": "pnpm _build --cwd packages/core && pnpm postbuild:core",
"build:preact": "pnpm _build --cwd packages/preact && pnpm postbuild:preact",
"build:react": "pnpm _build --cwd packages/react && pnpm postbuild:react",
"build:react-auto": "pnpm _build --cwd packages/react/auto && pnpm postbuild:react-auto",
"build:react-runtime": "pnpm _build --cwd packages/react/runtime && pnpm postbuild:react-runtime",
"build:react-transform": "pnpm _build --no-compress --cwd packages/react-transform",
"postbuild:core": "cd packages/core/dist && mv -f index.d.ts signals-core.d.ts",
"postbuild:preact": "cd packages/preact/dist && mv -f preact/src/index.d.ts signals.d.ts && rm -dr preact",
"postbuild:react": "cd packages/react/dist && mv -f react/src/index.d.ts signals.d.ts && rm -dr react",
"postbuild:react-auto": "cd packages/react/auto/dist && mv -f react/auto/src/*.d.ts . && rm -dr react",
"postbuild:react-runtime": "cd packages/react/runtime/dist && mv -f react/runtime/src/*.d.ts . && rm -dr react",
"postbuild": "node ./scripts/node-13-exports.js",
"lint": "pnpm lint:eslint && pnpm lint:tsc",
Expand Down
25 changes: 25 additions & 0 deletions packages/react/auto/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@preact/signals-react-auto",
"description": "Sub package for @preact/signals-react that patches React to automatically update when signals change",
"private": true,
"amdName": "reactSignalsAuto",
"main": "dist/auto.js",
"module": "dist/auto.module.js",
"unpkg": "dist/auto.min.js",
"types": "dist/index.d.ts",
"mangle": "../../../mangle.json",
"exports": {
".": {
"types": "./dist/index.d.ts",
"browser": "./dist/auto.module.js",
"import": "./dist/auto.mjs",
"require": "./dist/auto.js"
}
},
"dependencies": {},
"peerDependencies": {
"@preact/signals-core": "workspace:^1.3.0",
"@preact/signals-react": "workspace:*",
"react": "^16.14.0 || 17.x || 18.x"
}
}
2 changes: 2 additions & 0 deletions packages/react/auto/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { installAutoSignalTracking } from "@preact/signals-react/runtime";
installAutoSignalTracking();
42 changes: 42 additions & 0 deletions packages/react/auto/test/browser/mounts.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// @ts-expect-error
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

import { mountSignalsTests } from "../../../test/shared/mounting";
import {
act,
getConsoleErrorSpy,
checkConsoleErrorLogs,
createRoot,
type Root,
} from "../../../test/shared/utils.js";

import "@preact/signals-react/auto";

describe("@preact/signals-react/auto", () => {
describe("mounting", () => {
let scratch: HTMLDivElement;
let root: Root;

async function render(element: JSX.Element): Promise<string> {
await act(() => {
root.render(element);
});
return scratch.innerHTML;
}

beforeEach(async () => {
scratch = document.createElement("div");
document.body.appendChild(scratch);
getConsoleErrorSpy().resetHistory();

root = await createRoot(scratch);
});

afterEach(async () => {
scratch.remove();
checkConsoleErrorLogs();
});

mountSignalsTests(render);
});
});
12 changes: 12 additions & 0 deletions packages/react/auto/test/browser/updates.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @ts-expect-error
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

import { updateSignalsTests } from "../../../test/shared/updates";
import "@preact/signals-react/auto";

describe("@preact/signals-react/auto", () => {
describe("updating", () => {
// calledOnce
updateSignalsTests();
});
});
24 changes: 24 additions & 0 deletions packages/react/auto/test/node/renderToStaticMarkup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { signal, useSignalEffect } from "@preact/signals-react";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { mountSignalsTests } from "../../../test/shared/mounting";

describe("@preact/signals-react/auto", () => {
describe("renderToStaticMarkup", () => {
mountSignalsTests(el => Promise.resolve(renderToStaticMarkup(el)));

it("should not invoke useSignalEffect", async () => {
const spy = sinon.spy();
const sig = signal("foo");

function App() {
useSignalEffect(() => spy(sig.value));
return <p>{sig.value}</p>;
}

const html = await renderToStaticMarkup(<App />);
expect(html).to.equal("<p>foo</p>");
expect(spy.called).to.be.false;
});
});
});
2 changes: 1 addition & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"README.md"
],
"scripts": {
"prepublishOnly": "cd ../.. && pnpm build:react-runtime && pnpm build:react"
"prepublishOnly": "cd ../.. && pnpm build:react-runtime && pnpm build:react-auto && pnpm build:react"
},
"dependencies": {
"@preact/signals-core": "workspace:^1.4.0",
Expand Down
40 changes: 40 additions & 0 deletions packages/react/runtime/test/browser/mounts.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// @ts-expect-error
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

import { mountSignalsTests } from "../../../test/shared/mounting";
import {
act,
getConsoleErrorSpy,
checkConsoleErrorLogs,
createRoot,
type Root,
} from "../../../test/shared/utils.js";

describe("@preact/signals-react/runtime", () => {
describe("mounting", () => {
let scratch: HTMLDivElement;
let root: Root;

async function render(element: JSX.Element): Promise<string> {
await act(() => {
root.render(element);
});
return scratch.innerHTML;
}

beforeEach(async () => {
scratch = document.createElement("div");
document.body.appendChild(scratch);
getConsoleErrorSpy().resetHistory();

root = await createRoot(scratch);
});

afterEach(async () => {
scratch.remove();
checkConsoleErrorLogs();
});

mountSignalsTests(render);
});
});
10 changes: 10 additions & 0 deletions packages/react/runtime/test/browser/updates.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// @ts-expect-error
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

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

describe("@preact/signals-react/runtime", () => {
describe("updating", () => {
updateSignalsTests(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
checkHangingAct,
getConsoleErrorSpy,
checkConsoleErrorLogs,
} from "../../test/shared/utils";
} from "../../../test/shared/utils";

describe("useSignals", () => {
let scratch: HTMLDivElement;
Expand Down
24 changes: 24 additions & 0 deletions packages/react/runtime/test/node/renderToStaticMarkup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { signal, useSignalEffect } from "@preact/signals-react";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { mountSignalsTests } from "../../../test/shared/mounting";

describe("@preact/signals-react/runtime", () => {
describe("renderToStaticMarkup", () => {
mountSignalsTests(el => Promise.resolve(renderToStaticMarkup(el)));

it("should not invoke useSignalEffect", async () => {
const spy = sinon.spy();
const sig = signal("foo");

function App() {
useSignalEffect(() => spy(sig.value));
return <p>{sig.value}</p>;
}

const html = await renderToStaticMarkup(<App />);
expect(html).to.equal("<p>foo</p>");
expect(spy.called).to.be.false;
});
});
});
8 changes: 6 additions & 2 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import {
untracked,
} from "@preact/signals-core";
import type { ReactElement } from "react";
import { useSignal, useComputed, useSignalEffect } from "../runtime";
import { installAutoSignalTracking } from "../runtime/src/auto";
import {
useSignal,
useComputed,
useSignalEffect,
installAutoSignalTracking,
} from "../runtime/src/index"; // TODO: This duplicates runtime code between main and sub runtime packages

export {
signal,
Expand Down
32 changes: 0 additions & 32 deletions packages/react/test/browser/mounts.test.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion packages/react/test/browser/react-router.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// @ts-ignore-next-line
// @ts-expect-error
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

import { signal } from "@preact/signals-react";
Expand Down
2 changes: 1 addition & 1 deletion packages/react/test/node/renderToStaticMarkup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { renderToStaticMarkup } from "react-dom/server";
import { mountSignalsTests } from "../shared/mounting";

describe("renderToStaticMarkup", () => {
mountSignalsTests(renderToStaticMarkup);
mountSignalsTests(el => Promise.resolve(renderToStaticMarkup(el)));

it("should not invoke useSignalEffect", async () => {
const spy = sinon.spy();
Expand Down
23 changes: 3 additions & 20 deletions packages/react/test/shared/mounting.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,11 @@
// @ts-ignore-next-line
globalThis.IS_REACT_ACT_ENVIRONMENT = true;

import {
signal,
computed,
useComputed,
useSignal,
} from "@preact/signals-react";
import { signal, computed } from "@preact/signals-core";
import { useComputed, useSignal } from "@preact/signals-react/runtime";
import { expect } from "chai";
import { createElement, useReducer, StrictMode, useState } from "react";

import { getConsoleErrorSpy, checkConsoleErrorLogs } from "./utils";

export function mountSignalsTests(
render: (element: JSX.Element) => string | Promise<string>
render: (element: JSX.Element) => Promise<string>
) {
beforeEach(async () => {
getConsoleErrorSpy().resetHistory();
});

afterEach(async () => {
checkConsoleErrorLogs();
});

describe("mount text bindings", () => {
it("should render text without signals", async () => {
const html = await render(<span>test</span>);
Expand Down
Loading

0 comments on commit 020982d

Please sign in to comment.