chore: replace eslint & prettier w/ biomejs (#21)
* chore: replace eslint & prettier w/ biomejs * fix syntax error in ci.yml workflow * ensure that build CI jobs only run if check job succeeds to save resources
This commit is contained in:
parent
73135dd4b5
commit
5118a8174b
44 changed files with 2408 additions and 5691 deletions
|
|
@ -1,2 +0,0 @@
|
|||
node_modules/
|
||||
dist/
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint", "prettier"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"settings": {
|
||||
"react": {
|
||||
"pragma": "createElement"
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"@typescript-eslint/no-namespace": "off",
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"react/prop-types": "off",
|
||||
"react/jsx-key": "off"
|
||||
}
|
||||
}
|
||||
9
.github/workflows/ci.yml
vendored
9
.github/workflows/ci.yml
vendored
|
|
@ -6,7 +6,16 @@ on:
|
|||
branches: [mainline]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- run: npm ci
|
||||
- run: npm run check
|
||||
|
||||
build:
|
||||
needs: check
|
||||
strategy:
|
||||
matrix:
|
||||
os: [windows-latest, ubuntu-latest, macos-latest]
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
node_modules/
|
||||
dist/
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"endOfLine": "lf",
|
||||
"singleQuote": false,
|
||||
"trailingComma": "all",
|
||||
"tabWidth": 4,
|
||||
"semi": true
|
||||
}
|
||||
36
biome.json
Normal file
36
biome.json
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.8.3/schema.json",
|
||||
"organizeImports": {
|
||||
"enabled": true,
|
||||
"ignore": ["dist", "node_modules", ".temp"]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"ignore": ["dist", "node_modules", ".temp"]
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"ignore": ["dist", "node_modules", ".temp"],
|
||||
"rules": {
|
||||
"recommended": true,
|
||||
"style": {
|
||||
"useShorthandFunctionType": "off"
|
||||
},
|
||||
"correctness": {
|
||||
"useJsxKeyInIterable": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"include": ["test"],
|
||||
"linter": {
|
||||
"rules": {
|
||||
"a11y": {
|
||||
"useHtmlLang": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { stylesheet } from "typestyle";
|
||||
import { Component, createElement } from "websnacks";
|
||||
import { type Component, createElement } from "websnacks";
|
||||
|
||||
const styles = stylesheet({
|
||||
header: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { normalize } from "csstips";
|
||||
import { stylesheet } from "typestyle";
|
||||
import { Component, createElement } from "websnacks";
|
||||
import { type Component, createElement } from "websnacks";
|
||||
|
||||
import { stylesheetPath } from "../config";
|
||||
import { Header } from "./header";
|
||||
|
|
@ -46,10 +46,7 @@ export const Layout: Component<LayoutProps> = ({ children, headline }) => (
|
|||
{headline && ` | ${headline}`}
|
||||
</title>
|
||||
<meta name="description" content="" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1"
|
||||
/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href={stylesheetPath} />
|
||||
</head>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { stylesheet } from "typestyle";
|
||||
import { Component, createElement } from "websnacks";
|
||||
import { type Component, createElement } from "websnacks";
|
||||
|
||||
const styles = stylesheet({
|
||||
navbar: {
|
||||
|
|
|
|||
1198
examples/personal-site/package-lock.json
generated
1198
examples/personal-site/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"name": "websnacks-example-personal-site",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "websnacks -r ts-node/register build",
|
||||
"dev": "websnacks -r ts-node/register dev"
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
import { Component, createElement } from "websnacks";
|
||||
import { type Component, createElement } from "websnacks";
|
||||
|
||||
import { Layout } from "../components/layout";
|
||||
|
||||
export const page: Component = () => (
|
||||
<Layout>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur
|
||||
dapibus condimentum mauris et egestas. Quisque orci nulla, consequat
|
||||
at erat laoreet, malesuada sodales nisi. Sed in lorem semper lorem
|
||||
placerat fermentum a id arcu. Curabitur non aliquam tellus, sed
|
||||
auctor lacus. Nunc sit amet lectus ultrices, sodales nisl sit amet,
|
||||
luctus nisl. Nunc mollis imperdiet quam, eget sollicitudin leo
|
||||
tincidunt vel. Duis felis dui, imperdiet aliquam bibendum sed,
|
||||
auctor et dolor. Vivamus odio ipsum, venenatis in felis sed, aliquam
|
||||
dictum turpis. Pellentesque pellentesque consequat neque, id
|
||||
imperdiet diam molestie nec. Nullam ut vestibulum est. Pellentesque
|
||||
orci urna, porta vel porta quis, semper ut enim. Donec sit amet urna
|
||||
arcu. Nam tincidunt fermentum ligula a pharetra.{" "}
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur dapibus
|
||||
condimentum mauris et egestas. Quisque orci nulla, consequat at erat
|
||||
laoreet, malesuada sodales nisi. Sed in lorem semper lorem placerat
|
||||
fermentum a id arcu. Curabitur non aliquam tellus, sed auctor lacus. Nunc
|
||||
sit amet lectus ultrices, sodales nisl sit amet, luctus nisl. Nunc mollis
|
||||
imperdiet quam, eget sollicitudin leo tincidunt vel. Duis felis dui,
|
||||
imperdiet aliquam bibendum sed, auctor et dolor. Vivamus odio ipsum,
|
||||
venenatis in felis sed, aliquam dictum turpis. Pellentesque pellentesque
|
||||
consequat neque, id imperdiet diam molestie nec. Nullam ut vestibulum est.
|
||||
Pellentesque orci urna, porta vel porta quis, semper ut enim. Donec sit
|
||||
amet urna arcu. Nam tincidunt fermentum ligula a pharetra.{" "}
|
||||
</p>
|
||||
</Layout>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { stylesheet } from "typestyle";
|
||||
import { Component, createElement } from "websnacks";
|
||||
import { type Component, createElement } from "websnacks";
|
||||
|
||||
import { Layout } from "../components/layout";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import { Config } from "websnacks";
|
||||
import { promises as fs } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import type { Config } from "websnacks";
|
||||
|
||||
import { stylesheetPath } from "./config";
|
||||
|
||||
|
|
@ -23,4 +23,3 @@ const config: Config = {
|
|||
},
|
||||
},
|
||||
};
|
||||
export = config;
|
||||
|
|
|
|||
2404
package-lock.json
generated
2404
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -24,6 +24,7 @@
|
|||
],
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"check": "biome check .",
|
||||
"clean": "ts-node scripts/clean.ts",
|
||||
"prepublishOnly": "npm run reset && npm test",
|
||||
"pretest": "npm run build",
|
||||
|
|
@ -35,15 +36,9 @@
|
|||
"test:e2e": "cd test && ts-node --script-mode ./run-e2e.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.8.3",
|
||||
"@types/node": "~18",
|
||||
"@types/ws": "^7.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.15.2",
|
||||
"@typescript-eslint/parser": "^4.15.2",
|
||||
"eslint": "^7.21.0",
|
||||
"eslint-config-prettier": "^8.1.0",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-react": "^7.22.0",
|
||||
"prettier": "=2.2.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "~4.9.5"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
const ROOT_DIR = path.resolve(__dirname, "..");
|
||||
const DIST_DIR = path.join(ROOT_DIR, "dist");
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import { promises as fs } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { Config, ConfigPaths } from "./config";
|
||||
import type { Config, ConfigPaths } from "./config";
|
||||
import { renderPage } from "./render";
|
||||
import { decacheModule, walkDir } from "./utils";
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ const renderPagesToHtml = async ({
|
|||
`page source at ${srcPath} does not export a "page" variable`,
|
||||
);
|
||||
}
|
||||
let compiledHtml;
|
||||
let compiledHtml: string;
|
||||
try {
|
||||
compiledHtml = renderPage(pageSrc.page());
|
||||
} catch (error) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { renderSite } from "../../build";
|
||||
import { loadConfig } from "../../config";
|
||||
import { Command, UsageError } from "../types";
|
||||
import { type Command, UsageError } from "../types";
|
||||
|
||||
const helpText = `\
|
||||
Usage: websnacks build [ROOT_DIR]
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { existsSync, promises as fs, watch } from "fs";
|
||||
import * as http from "http";
|
||||
import * as path from "path";
|
||||
import { promises as fs, existsSync, watch } from "node:fs";
|
||||
import * as http from "node:http";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { renderSite } from "../../build";
|
||||
import { Config, loadConfig } from "../../config";
|
||||
import { type Config, loadConfig } from "../../config";
|
||||
import { isErrnoException } from "../../utils/error";
|
||||
import { Command, UsageError } from "../types";
|
||||
import { type Command, UsageError } from "../types";
|
||||
|
||||
const DEFAULT_SERVER_PORT = 8080;
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ const injectLiveReloadScript = (htmlContents: string, port: number): string =>
|
|||
);
|
||||
|
||||
const guessMimeType = (ext: string): string => {
|
||||
let mimeType;
|
||||
let mimeType: string;
|
||||
switch (ext) {
|
||||
case ".apng":
|
||||
mimeType = "image/apng";
|
||||
|
|
@ -149,7 +149,7 @@ const startHttpServer = async (publicDir: string): Promise<http.Server> => {
|
|||
reqExt = ".html";
|
||||
}
|
||||
|
||||
let contents;
|
||||
let contents: Buffer | string;
|
||||
try {
|
||||
contents = await fs.readFile(path.join(publicDir, reqPath));
|
||||
} catch (error) {
|
||||
|
|
@ -196,7 +196,7 @@ const startWebSocketServer = async (
|
|||
httpServer: http.Server,
|
||||
): Promise<import("ws").Server | undefined> => {
|
||||
// Attempt to load the ws module, aborting if it isn't available.
|
||||
let ws;
|
||||
let ws: typeof import("ws");
|
||||
try {
|
||||
ws = await import("ws");
|
||||
} catch (error) {
|
||||
|
|
@ -237,7 +237,7 @@ const watchFolders = async (
|
|||
}
|
||||
console.warn(
|
||||
`'node-watch' module not found, falling back to fs.watch (may ` +
|
||||
`result in file watch issues on some OSes)`,
|
||||
"result in file watch issues on some OSes)",
|
||||
);
|
||||
}
|
||||
// NOTE: fs.watch has significant cross-platform issues, including
|
||||
|
|
@ -298,12 +298,10 @@ const devCommand: Command = {
|
|||
await watchFolders(watchedFolders, async (event, filePath) => {
|
||||
const filePathForLog = filePath || "<UNKNOWN_FILE>";
|
||||
const eventForLog = event || "<UNKNOWN_EVENT>";
|
||||
console.log(
|
||||
`${filePathForLog}:${eventForLog} triggering rebuild...`,
|
||||
);
|
||||
console.log(`${filePathForLog}:${eventForLog} triggering rebuild...`);
|
||||
await rebuild();
|
||||
if (wsServer != null) {
|
||||
console.log(`rebuild finished, reloading browsers...`);
|
||||
console.log("rebuild finished, reloading browsers...");
|
||||
for (const ws of wsServer.clients) {
|
||||
ws.send("reload");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Command, UsageError } from "./types";
|
||||
import { type Command, UsageError } from "./types";
|
||||
|
||||
const globalHelpText = `\
|
||||
Usage: websnacks [...globalOptions] <command>
|
||||
|
|
@ -45,7 +45,7 @@ const parseArgs = (
|
|||
const moduleName = args.shift();
|
||||
if (moduleName == null) {
|
||||
throw new UsageError(
|
||||
`-r requires a valid module name`,
|
||||
"-r requires a valid module name",
|
||||
globalHelpText,
|
||||
);
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ const _main = async (args: string[]): Promise<void> => {
|
|||
return;
|
||||
}
|
||||
if (commandName == null) {
|
||||
throw new UsageError(`must specify a valid command`, globalHelpText);
|
||||
throw new UsageError("must specify a valid command", globalHelpText);
|
||||
}
|
||||
for (const moduleName of options.require) {
|
||||
await import(moduleName);
|
||||
|
|
@ -82,10 +82,7 @@ const _main = async (args: string[]): Promise<void> => {
|
|||
command = await import("./commands/dev");
|
||||
break;
|
||||
default:
|
||||
throw new UsageError(
|
||||
`unknown command ${commandName}`,
|
||||
globalHelpText,
|
||||
);
|
||||
throw new UsageError(`unknown command ${commandName}`, globalHelpText);
|
||||
}
|
||||
// NOTE: Should this just delegate to the command?
|
||||
for (const arg of commandArgs) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export type Element =
|
|||
/**
|
||||
* Custom HTMLElement factory that can be parameterized by props.
|
||||
*/
|
||||
export interface Component<P extends object = {}> {
|
||||
export interface Component<P extends object = Record<string, unknown>> {
|
||||
(
|
||||
props: P & {
|
||||
children?: Element[];
|
||||
|
|
@ -45,7 +45,7 @@ export interface Component<P extends object = {}> {
|
|||
): HTMLElement;
|
||||
}
|
||||
|
||||
export const Fragment: Component<{}> = ({ children }) => ({
|
||||
export const Fragment: Component = ({ children }) => ({
|
||||
tag: "#fragment",
|
||||
attributes: {},
|
||||
children: children || [],
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import * as path from "path";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { decacheModule } from "./utils";
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ const noop = () => {};
|
|||
* @return Fully-realized configuration.
|
||||
*/
|
||||
export const loadConfig = async (rootDir: string): Promise<Config> => {
|
||||
let configPath;
|
||||
let configPath = "";
|
||||
let userConfig: UserConfig = {};
|
||||
// Attempt to load a websnacks.ts/js file in rootDir.
|
||||
try {
|
||||
|
|
@ -74,7 +74,7 @@ export const loadConfig = async (rootDir: string): Promise<Config> => {
|
|||
const staticAssetsDir = path.join(rootDir, "static");
|
||||
|
||||
const watch = [pagesDir, staticAssetsDir];
|
||||
if (configPath != null) {
|
||||
if (configPath) {
|
||||
watch.push(path.relative(rootDir, configPath));
|
||||
}
|
||||
if (userConfig.watch != null) {
|
||||
|
|
@ -97,3 +97,5 @@ export const loadConfig = async (rootDir: string): Promise<Config> => {
|
|||
watch,
|
||||
};
|
||||
};
|
||||
|
||||
export const defineConfig = (userConfig: UserConfig): UserConfig => userConfig;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Component, Element, HTMLElement } from "./component";
|
||||
import { HTMLAttributes } from "./jsx";
|
||||
import type { Component, Element, HTMLElement } from "./component";
|
||||
import type { HTMLAttributes } from "./jsx";
|
||||
import { flatDeep } from "./utils";
|
||||
|
||||
/**
|
||||
|
|
@ -38,8 +38,7 @@ export function createElement(
|
|||
...children: Element[]
|
||||
): HTMLElement;
|
||||
export function createElement(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
type: string | Component<any>,
|
||||
type: string | Component,
|
||||
props: object | null,
|
||||
...children: Element[]
|
||||
): HTMLElement {
|
||||
|
|
@ -68,9 +67,7 @@ export function createElement(
|
|||
typeof value !== "number" &&
|
||||
typeof value !== "boolean"
|
||||
) {
|
||||
console.warn(
|
||||
`non-primitive attribute ${key} = ${JSON.stringify(value)}`,
|
||||
);
|
||||
console.warn(`non-primitive attribute ${key} = ${JSON.stringify(value)}`);
|
||||
continue;
|
||||
}
|
||||
attrs[key] = value;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,6 @@
|
|||
*/
|
||||
|
||||
export { HTMLElement, Component, Fragment } from "./component";
|
||||
export { UserConfig as Config } from "./config";
|
||||
export { UserConfig as Config, defineConfig } from "./config";
|
||||
export { createElement } from "./create-element";
|
||||
export * from "./jsx";
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import { HTMLElement } from "./component";
|
||||
import type { HTMLElement } from "./component";
|
||||
|
||||
export interface RdfaAttributes {
|
||||
about?: string;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Element, HTMLElement } from "./component";
|
||||
import type { Element, HTMLElement } from "./component";
|
||||
|
||||
const HTML_ESCAPES: { [char: string]: string } = {
|
||||
"&": "&",
|
||||
|
|
@ -71,9 +71,7 @@ const startTag = (elem: HTMLElement): string => {
|
|||
if (attrValue === true) {
|
||||
output += ` ${normalizedAttrName}=""`;
|
||||
} else {
|
||||
output += ` ${normalizedAttrName}="${escapeAttr(
|
||||
attrValue.toString(),
|
||||
)}"`;
|
||||
output += ` ${normalizedAttrName}="${escapeAttr(attrValue.toString())}"`;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -97,8 +95,8 @@ const endTag = (elem: HTMLElement): string => {
|
|||
* @return Fully rendered HTML document as a string.
|
||||
*/
|
||||
export const renderPage = (rootElem: Element): string => {
|
||||
if (rootElem == undefined) {
|
||||
throw new Error(`root page element cannot be null`);
|
||||
if (rootElem == null) {
|
||||
throw new Error("root page element cannot be null");
|
||||
}
|
||||
if (typeof rootElem !== "object" || !("tag" in rootElem)) {
|
||||
throw new Error(
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import { promises as fs } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
export { decacheModule } from "./decache-module";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,14 +3,14 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import { promises as fs } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import {
|
||||
npmCmd,
|
||||
runCommand,
|
||||
WEBSNACKS_BIN_PATH,
|
||||
WEBSNACKS_REPO_ROOT,
|
||||
npmCmd,
|
||||
runCommand,
|
||||
withTempDir,
|
||||
} from "../helpers/e2e";
|
||||
import { testSuite } from "../lib";
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import { promises as fs } from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import {
|
||||
WEBSNACKS_BIN_PATH,
|
||||
WEBSNACKS_REPO_ROOT,
|
||||
npmCmd,
|
||||
runCommand,
|
||||
wait,
|
||||
WEBSNACKS_BIN_PATH,
|
||||
WEBSNACKS_REPO_ROOT,
|
||||
withTempDir,
|
||||
} from "../helpers/e2e";
|
||||
import { testSuite } from "../lib";
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { ChildProcess, spawn } from "child_process";
|
||||
import { promises as fs } from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import { type ChildProcess, spawn } from "node:child_process";
|
||||
import { promises as fs } from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
|
||||
/**
|
||||
* Set a timeout and wait for at least the specified number of milliseconds,
|
||||
|
|
@ -137,9 +137,7 @@ export const runCommand = (
|
|||
threwError = true;
|
||||
process.kill();
|
||||
reject(
|
||||
new Error(
|
||||
`max timeout of ${optionsWithDefaults.timeoutMs}ms reached`,
|
||||
),
|
||||
new Error(`max timeout of ${optionsWithDefaults.timeoutMs}ms reached`),
|
||||
);
|
||||
}, optionsWithDefaults.timeoutMs);
|
||||
process.on("exit", (code) => {
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export class Expect<T> {
|
|||
public toEqual(expected: T): void {
|
||||
if (!areEqual(this.value, expected)) {
|
||||
throw new ExpectError(
|
||||
`value does not equal expected`,
|
||||
"value does not equal expected",
|
||||
expected,
|
||||
this.value,
|
||||
);
|
||||
|
|
@ -71,7 +71,7 @@ export class StringExpect extends Expect<string> {
|
|||
public toMatch(pattern: RegExp): void {
|
||||
if (!this.value.match(pattern)) {
|
||||
throw new ExpectError(
|
||||
`value does not match expected pattern`,
|
||||
"value does not match expected pattern",
|
||||
pattern,
|
||||
this.value,
|
||||
);
|
||||
|
|
@ -89,7 +89,7 @@ export class StringExpect extends Expect<string> {
|
|||
public toStartWith(prefix: string): void {
|
||||
if (!this.value.startsWith(prefix)) {
|
||||
throw new ExpectError(
|
||||
`value does not start with expected prefix`,
|
||||
"value does not start with expected prefix",
|
||||
prefix,
|
||||
this.value,
|
||||
);
|
||||
|
|
@ -107,7 +107,7 @@ export class StringExpect extends Expect<string> {
|
|||
public toEndWith(suffix: string): void {
|
||||
if (!this.value.endsWith(suffix)) {
|
||||
throw new ExpectError(
|
||||
`value does not end with expected suffix`,
|
||||
"value does not end with expected suffix",
|
||||
suffix,
|
||||
this.value,
|
||||
);
|
||||
|
|
@ -135,11 +135,7 @@ export class FunctionExpect<T> extends Expect<() => T> {
|
|||
this.value();
|
||||
} catch (error) {
|
||||
if (!(error instanceof Error)) {
|
||||
throw new ExpectError(
|
||||
`function threw non-Error value`,
|
||||
pattern,
|
||||
error,
|
||||
);
|
||||
throw new ExpectError("function threw non-Error value", pattern, error);
|
||||
}
|
||||
if (!matches(error.message, pattern)) {
|
||||
throw new ExpectError(
|
||||
|
|
@ -151,7 +147,7 @@ export class FunctionExpect<T> extends Expect<() => T> {
|
|||
return;
|
||||
}
|
||||
throw new ExpectError(
|
||||
`function did not throw expected error`,
|
||||
"function did not throw expected error",
|
||||
pattern,
|
||||
null,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -39,9 +39,7 @@ const runTest = async (test: Test): Promise<TestResult> => {
|
|||
error:
|
||||
error instanceof Error
|
||||
? error
|
||||
: new Error(
|
||||
`threw non-error object: ${displayValue(error)}`,
|
||||
),
|
||||
: new Error(`threw non-error object: ${displayValue(error)}`),
|
||||
};
|
||||
}
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export const shuffle = <T>(arr: T[]): void => {
|
|||
};
|
||||
|
||||
const areArraysEqual = <T>(a: T[], b: T[]): boolean => {
|
||||
if (a.length != b.length) {
|
||||
if (a.length !== b.length) {
|
||||
return false;
|
||||
}
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { fork } from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { fork } from "node:child_process";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { shuffle } from "./lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { fork } from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import { fork } from "node:child_process";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
|
||||
import { shuffle } from "./lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Component, createElement, Fragment } from "../../dist";
|
||||
import { type Component, Fragment, createElement } from "../../dist";
|
||||
import { renderPage } from "../../dist/render";
|
||||
import { testSuite } from "../lib";
|
||||
|
||||
|
|
@ -20,9 +20,7 @@ testSuite("renderPage", ({ test, expect }) => {
|
|||
});
|
||||
|
||||
test("escapes HTML in tag names", () => {
|
||||
const html = renderPage(
|
||||
<html>{createElement("div></div", null)}</html>,
|
||||
);
|
||||
const html = renderPage(<html>{createElement("div></div", null)}</html>);
|
||||
expect(html).toEqual(
|
||||
"<!DOCTYPE html><html><div></div></div></div></html>",
|
||||
);
|
||||
|
|
@ -57,9 +55,7 @@ testSuite("renderPage", ({ test, expect }) => {
|
|||
|
||||
test("renders text nodes", () => {
|
||||
const html = renderPage(<html>There are three lights!</html>);
|
||||
expect(html).toEqual(
|
||||
"<!DOCTYPE html><html>There are three lights!</html>",
|
||||
);
|
||||
expect(html).toEqual("<!DOCTYPE html><html>There are three lights!</html>");
|
||||
});
|
||||
|
||||
test("renders spliced number nodes", () => {
|
||||
|
|
@ -122,6 +118,7 @@ testSuite("renderPage", ({ test, expect }) => {
|
|||
const html = renderPage(
|
||||
<html>
|
||||
<div
|
||||
// biome-ignore lint/security/noDangerouslySetInnerHtml: explicit test
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: "<div>red alert!</div>",
|
||||
}}
|
||||
|
|
@ -138,6 +135,8 @@ testSuite("renderPage", ({ test, expect }) => {
|
|||
renderPage(
|
||||
<html>
|
||||
<div
|
||||
// biome-ignore lint/security/noDangerouslySetInnerHtml: explicit test
|
||||
// biome-ignore lint/security/noDangerouslySetInnerHtmlWithChildren: explicit test
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: "<div>set phasers to kill</div>",
|
||||
}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue