chore: update * pin prettier version & format code
This commit is contained in:
parent
274fe7778e
commit
45d96fae9f
18 changed files with 93 additions and 78 deletions
2
.prettierignore
Normal file
2
.prettierignore
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
{
|
{
|
||||||
"endOfLine": "lf"
|
"endOfLine": "lf",
|
||||||
|
"singleQuote": false,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -1219,9 +1219,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"version": "2.0.5",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz",
|
||||||
"integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==",
|
"integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"prettier-linter-helpers": {
|
"prettier-linter-helpers": {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
"eslint-config-prettier": "^6.11.0",
|
"eslint-config-prettier": "^6.11.0",
|
||||||
"eslint-plugin-prettier": "^3.1.3",
|
"eslint-plugin-prettier": "^3.1.3",
|
||||||
"eslint-plugin-react": "^7.20.0",
|
"eslint-plugin-react": "^7.20.0",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "=2.2.1",
|
||||||
"ts-node": "^8.10.2",
|
"ts-node": "^8.10.2",
|
||||||
"typescript": "~3.9.3"
|
"typescript": "~3.9.3"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ const renderPagesToHtml = async ({
|
||||||
const pageSrc = require(srcPath);
|
const pageSrc = require(srcPath);
|
||||||
if (!("page" in pageSrc)) {
|
if (!("page" in pageSrc)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`page source at ${srcPath} does not export a "page" variable`
|
`page source at ${srcPath} does not export a "page" variable`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let compiledHtml;
|
let compiledHtml;
|
||||||
|
|
@ -35,7 +35,7 @@ const renderPagesToHtml = async ({
|
||||||
compiledHtml = renderPage(pageSrc.page());
|
compiledHtml = renderPage(pageSrc.page());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`failed to compile ${srcPath}: ${error.stack ?? error}`
|
`failed to compile ${srcPath}: ${error.stack ?? error}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const relPath = path.relative(pagesDir, path.dirname(srcPath));
|
const relPath = path.relative(pagesDir, path.dirname(srcPath));
|
||||||
|
|
@ -48,7 +48,7 @@ const renderPagesToHtml = async ({
|
||||||
(async () => {
|
(async () => {
|
||||||
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
||||||
await fs.writeFile(destPath, compiledHtml);
|
await fs.writeFile(destPath, compiledHtml);
|
||||||
})()
|
})(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await Promise.all(deferred);
|
await Promise.all(deferred);
|
||||||
|
|
@ -73,7 +73,7 @@ const copyStaticAssets = async ({
|
||||||
(async () => {
|
(async () => {
|
||||||
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
||||||
await fs.copyFile(assetPath, destPath);
|
await fs.copyFile(assetPath, destPath);
|
||||||
})()
|
})(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
await Promise.all(deferred);
|
await Promise.all(deferred);
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const injectLiveReloadScript = (htmlContents: string, port: number): string =>
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
`
|
`,
|
||||||
);
|
);
|
||||||
|
|
||||||
const guessMimeType = (ext: string): string => {
|
const guessMimeType = (ext: string): string => {
|
||||||
|
|
@ -126,7 +126,7 @@ const portFromServer = (server: Pick<net.Server, "address">): number => {
|
||||||
}
|
}
|
||||||
if (typeof addrInfo === "string") {
|
if (typeof addrInfo === "string") {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`server address is a string (this should never happen!)`
|
`server address is a string (this should never happen!)`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return addrInfo.port;
|
return addrInfo.port;
|
||||||
|
|
@ -187,7 +187,7 @@ const startHttpServer = async (publicDir: string): Promise<http.Server> => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const startWebSocketServer = async (
|
const startWebSocketServer = async (
|
||||||
httpServer: http.Server
|
httpServer: http.Server,
|
||||||
): Promise<import("ws").Server | undefined> => {
|
): Promise<import("ws").Server | undefined> => {
|
||||||
// Attempt to load the ws module, aborting if it isn't available.
|
// Attempt to load the ws module, aborting if it isn't available.
|
||||||
let ws;
|
let ws;
|
||||||
|
|
@ -209,7 +209,7 @@ const startWebSocketServer = async (
|
||||||
|
|
||||||
const watchFolders = async (
|
const watchFolders = async (
|
||||||
folders: string[],
|
folders: string[],
|
||||||
listener: (eventType: "update" | "remove", fileName: string) => void
|
listener: (eventType: "update" | "remove", fileName: string) => void,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
// Try to load node-watch, falling back to fs watch if node-watch isn't
|
// Try to load node-watch, falling back to fs watch if node-watch isn't
|
||||||
// available.
|
// available.
|
||||||
|
|
@ -223,7 +223,7 @@ const watchFolders = async (
|
||||||
}
|
}
|
||||||
console.warn(
|
console.warn(
|
||||||
`'node-watch' module not found, falling back to fs.watch (may ` +
|
`'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
|
// NOTE: fs.watch has significant cross-platform issues, including
|
||||||
|
|
@ -279,7 +279,7 @@ const devCommand: Command = {
|
||||||
const httpServer = await startHttpServer(outDir);
|
const httpServer = await startHttpServer(outDir);
|
||||||
const wsServer = await startWebSocketServer(httpServer);
|
const wsServer = await startWebSocketServer(httpServer);
|
||||||
const watchedFolders = config.watch.filter((filePath) =>
|
const watchedFolders = config.watch.filter((filePath) =>
|
||||||
existsSync(filePath)
|
existsSync(filePath),
|
||||||
);
|
);
|
||||||
await watchFolders(watchedFolders, async (event, filePath) => {
|
await watchFolders(watchedFolders, async (event, filePath) => {
|
||||||
console.log(`${filePath}:${event} triggering rebuild...`);
|
console.log(`${filePath}:${event} triggering rebuild...`);
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ interface Options {
|
||||||
}
|
}
|
||||||
|
|
||||||
const parseArgs = (
|
const parseArgs = (
|
||||||
args: string[]
|
args: string[],
|
||||||
): { options: Options; commandName?: string; commandArgs: string[] } => {
|
): { options: Options; commandName?: string; commandArgs: string[] } => {
|
||||||
const options: Options = {
|
const options: Options = {
|
||||||
showHelp: false,
|
showHelp: false,
|
||||||
|
|
@ -46,7 +46,7 @@ const parseArgs = (
|
||||||
if (moduleName == null) {
|
if (moduleName == null) {
|
||||||
throw new UsageError(
|
throw new UsageError(
|
||||||
`-r requires a valid module name`,
|
`-r requires a valid module name`,
|
||||||
globalHelpText
|
globalHelpText,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
options.require.push(moduleName);
|
options.require.push(moduleName);
|
||||||
|
|
@ -84,7 +84,7 @@ const _main = async (args: string[]): Promise<void> => {
|
||||||
default:
|
default:
|
||||||
throw new UsageError(
|
throw new UsageError(
|
||||||
`unknown command ${commandName}`,
|
`unknown command ${commandName}`,
|
||||||
globalHelpText
|
globalHelpText,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// NOTE: Should this just delegate to the command?
|
// NOTE: Should this just delegate to the command?
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export interface Component<P extends object = {}> {
|
||||||
(
|
(
|
||||||
props: P & {
|
props: P & {
|
||||||
children?: Element[];
|
children?: Element[];
|
||||||
}
|
},
|
||||||
): HTMLElement;
|
): HTMLElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ export function createElement(
|
||||||
typeof value !== "boolean"
|
typeof value !== "boolean"
|
||||||
) {
|
) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`non-primitive attribute ${key} = ${JSON.stringify(value)}`
|
`non-primitive attribute ${key} = ${JSON.stringify(value)}`,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ const startTag = (elem: HTMLElement): string => {
|
||||||
output += ` ${normalizedAttrName}=""`;
|
output += ` ${normalizedAttrName}=""`;
|
||||||
} else {
|
} else {
|
||||||
output += ` ${normalizedAttrName}="${escapeAttr(
|
output += ` ${normalizedAttrName}="${escapeAttr(
|
||||||
attrValue.toString()
|
attrValue.toString(),
|
||||||
)}"`;
|
)}"`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -94,13 +94,13 @@ export const renderPage = (rootElem: Element): string => {
|
||||||
if (typeof rootElem !== "object" || !("tag" in rootElem)) {
|
if (typeof rootElem !== "object" || !("tag" in rootElem)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`root page element must be a valid HTMLElement, got ${JSON.stringify(
|
`root page element must be a valid HTMLElement, got ${JSON.stringify(
|
||||||
rootElem
|
rootElem,
|
||||||
)}`
|
)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (rootElem.tag.toLowerCase() !== "html") {
|
if (rootElem.tag.toLowerCase() !== "html") {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`attempted to render page with non-HTML root element ${rootElem.tag}`
|
`attempted to render page with non-HTML root element ${rootElem.tag}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export { decacheModule } from "./decache-module";
|
||||||
* @return Generator that yields the files found while walking the directory.
|
* @return Generator that yields the files found while walking the directory.
|
||||||
*/
|
*/
|
||||||
export const walkDir = async function* (
|
export const walkDir = async function* (
|
||||||
dirPath: string
|
dirPath: string,
|
||||||
): AsyncGenerator<string> {
|
): AsyncGenerator<string> {
|
||||||
const dirEnts = await fs.readdir(dirPath, { withFileTypes: true });
|
const dirEnts = await fs.readdir(dirPath, { withFileTypes: true });
|
||||||
for (const dirEnt of dirEnts) {
|
for (const dirEnt of dirEnts) {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,11 @@ import { promises as fs } from "fs";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
npmCmd, runCommand, WEBSNACKS_BIN_PATH, WEBSNACKS_REPO_ROOT, withTempDir
|
npmCmd,
|
||||||
|
runCommand,
|
||||||
|
WEBSNACKS_BIN_PATH,
|
||||||
|
WEBSNACKS_REPO_ROOT,
|
||||||
|
withTempDir,
|
||||||
} from "../helpers/e2e";
|
} from "../helpers/e2e";
|
||||||
import { testSuite } from "../lib";
|
import { testSuite } from "../lib";
|
||||||
|
|
||||||
|
|
@ -35,7 +39,7 @@ testSuite("build command", ({ test }) => {
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
path.join(tempDirPath, "websnacks.ts"),
|
path.join(tempDirPath, "websnacks.ts"),
|
||||||
|
|
@ -48,7 +52,7 @@ testSuite("build command", ({ test }) => {
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const pagesPath = path.join(tempDirPath, "pages");
|
const pagesPath = path.join(tempDirPath, "pages");
|
||||||
await fs.mkdir(pagesPath);
|
await fs.mkdir(pagesPath);
|
||||||
|
|
@ -60,7 +64,7 @@ testSuite("build command", ({ test }) => {
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
path.join(tempDirPath, "package.json"),
|
path.join(tempDirPath, "package.json"),
|
||||||
|
|
@ -69,7 +73,7 @@ testSuite("build command", ({ test }) => {
|
||||||
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{ encoding: "utf8" }
|
{ encoding: "utf8" },
|
||||||
);
|
);
|
||||||
await runCommand(npmCmd, ["install", "--silent"], {
|
await runCommand(npmCmd, ["install", "--silent"], {
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
|
|
@ -79,7 +83,7 @@ testSuite("build command", ({ test }) => {
|
||||||
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "build"],
|
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "build"],
|
||||||
{
|
{
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await cmd.complete;
|
await cmd.complete;
|
||||||
});
|
});
|
||||||
|
|
@ -108,7 +112,7 @@ testSuite("build command", ({ test }) => {
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const pagesPath = path.join(tempDirPath, "pages");
|
const pagesPath = path.join(tempDirPath, "pages");
|
||||||
await fs.mkdir(pagesPath);
|
await fs.mkdir(pagesPath);
|
||||||
|
|
@ -120,7 +124,7 @@ testSuite("build command", ({ test }) => {
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
path.join(tempDirPath, "package.json"),
|
path.join(tempDirPath, "package.json"),
|
||||||
|
|
@ -129,7 +133,7 @@ testSuite("build command", ({ test }) => {
|
||||||
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{ encoding: "utf8" }
|
{ encoding: "utf8" },
|
||||||
);
|
);
|
||||||
await runCommand(npmCmd, ["install", "--silent"], {
|
await runCommand(npmCmd, ["install", "--silent"], {
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
|
|
@ -139,7 +143,7 @@ testSuite("build command", ({ test }) => {
|
||||||
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "build"],
|
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "build"],
|
||||||
{
|
{
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await cmd.complete;
|
await cmd.complete;
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,12 @@ import { promises as fs } from "fs";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
npmCmd, runCommand, wait, WEBSNACKS_BIN_PATH, WEBSNACKS_REPO_ROOT, withTempDir
|
npmCmd,
|
||||||
|
runCommand,
|
||||||
|
wait,
|
||||||
|
WEBSNACKS_BIN_PATH,
|
||||||
|
WEBSNACKS_REPO_ROOT,
|
||||||
|
withTempDir,
|
||||||
} from "../helpers/e2e";
|
} from "../helpers/e2e";
|
||||||
import { testSuite } from "../lib";
|
import { testSuite } from "../lib";
|
||||||
|
|
||||||
|
|
@ -35,7 +40,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
path.join(tempDirPath, "websnacks.ts"),
|
path.join(tempDirPath, "websnacks.ts"),
|
||||||
|
|
@ -48,7 +53,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const pagesPath = path.join(tempDirPath, "pages");
|
const pagesPath = path.join(tempDirPath, "pages");
|
||||||
await fs.mkdir(pagesPath);
|
await fs.mkdir(pagesPath);
|
||||||
|
|
@ -60,7 +65,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
path.join(tempDirPath, "package.json"),
|
path.join(tempDirPath, "package.json"),
|
||||||
|
|
@ -69,7 +74,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{ encoding: "utf8" }
|
{ encoding: "utf8" },
|
||||||
);
|
);
|
||||||
await runCommand(npmCmd, ["install", "--silent"], {
|
await runCommand(npmCmd, ["install", "--silent"], {
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
|
|
@ -79,7 +84,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "dev"],
|
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "dev"],
|
||||||
{
|
{
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
// FIXME: This test is a bit brittle due to relying on timeouts.
|
// FIXME: This test is a bit brittle due to relying on timeouts.
|
||||||
await wait(10_000);
|
await wait(10_000);
|
||||||
|
|
@ -112,7 +117,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
const pagesPath = path.join(tempDirPath, "pages");
|
const pagesPath = path.join(tempDirPath, "pages");
|
||||||
await fs.mkdir(pagesPath);
|
await fs.mkdir(pagesPath);
|
||||||
|
|
@ -124,7 +129,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
`,
|
`,
|
||||||
{
|
{
|
||||||
encoding: "utf8",
|
encoding: "utf8",
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
await fs.writeFile(
|
await fs.writeFile(
|
||||||
path.join(tempDirPath, "package.json"),
|
path.join(tempDirPath, "package.json"),
|
||||||
|
|
@ -133,7 +138,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
websnacks: `file:${WEBSNACKS_REPO_ROOT}`,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{ encoding: "utf8" }
|
{ encoding: "utf8" },
|
||||||
);
|
);
|
||||||
await runCommand(npmCmd, ["install", "--silent"], {
|
await runCommand(npmCmd, ["install", "--silent"], {
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
|
|
@ -143,7 +148,7 @@ testSuite("dev command", ({ test, expect }) => {
|
||||||
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "dev"],
|
[WEBSNACKS_BIN_PATH, "-r", "ts-node/register", "dev"],
|
||||||
{
|
{
|
||||||
cwd: tempDirPath,
|
cwd: tempDirPath,
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
// FIXME: This test is a bit brittle due to relying on timeouts.
|
// FIXME: This test is a bit brittle due to relying on timeouts.
|
||||||
await wait(10_000);
|
await wait(10_000);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const TEMP_PATH = path.resolve(__dirname, "..", "..", ".temp");
|
||||||
* directory path as its only argument.
|
* directory path as its only argument.
|
||||||
*/
|
*/
|
||||||
export const withTempDir = async (
|
export const withTempDir = async (
|
||||||
op: (tempDirPath: string) => Promise<void> | void
|
op: (tempDirPath: string) => Promise<void> | void,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
await fs.mkdir(TEMP_PATH, { recursive: true });
|
await fs.mkdir(TEMP_PATH, { recursive: true });
|
||||||
const tempDirPath = await fs.mkdtemp(`${TEMP_PATH}/`);
|
const tempDirPath = await fs.mkdtemp(`${TEMP_PATH}/`);
|
||||||
|
|
@ -57,7 +57,7 @@ export const WEBSNACKS_REPO_ROOT = path.resolve(__dirname, "..", "..");
|
||||||
export const WEBSNACKS_BIN_PATH = path.join(
|
export const WEBSNACKS_BIN_PATH = path.join(
|
||||||
WEBSNACKS_REPO_ROOT,
|
WEBSNACKS_REPO_ROOT,
|
||||||
"bin",
|
"bin",
|
||||||
"websnacks.js"
|
"websnacks.js",
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -113,7 +113,7 @@ const DEFAULT_CLI_OPTIONS = {
|
||||||
export const runCommand = (
|
export const runCommand = (
|
||||||
command: string,
|
command: string,
|
||||||
args: string[] = [],
|
args: string[] = [],
|
||||||
options?: CliOptions
|
options?: CliOptions,
|
||||||
): AsyncCommand => {
|
): AsyncCommand => {
|
||||||
const optionsWithDefaults = { ...DEFAULT_CLI_OPTIONS, ...options };
|
const optionsWithDefaults = { ...DEFAULT_CLI_OPTIONS, ...options };
|
||||||
const process = spawn(command, args, {
|
const process = spawn(command, args, {
|
||||||
|
|
@ -138,8 +138,8 @@ export const runCommand = (
|
||||||
process.kill();
|
process.kill();
|
||||||
reject(
|
reject(
|
||||||
new Error(
|
new Error(
|
||||||
`max timeout of ${optionsWithDefaults.timeoutMs}ms reached`
|
`max timeout of ${optionsWithDefaults.timeoutMs}ms reached`,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}, optionsWithDefaults.timeoutMs);
|
}, optionsWithDefaults.timeoutMs);
|
||||||
process.on("exit", (code) => {
|
process.on("exit", (code) => {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ class ExpectError extends Error {
|
||||||
super(
|
super(
|
||||||
`${reason}\n` +
|
`${reason}\n` +
|
||||||
`\texpected: ${displayValue(expected)}\n` +
|
`\texpected: ${displayValue(expected)}\n` +
|
||||||
`\tactual : ${displayValue(actual)}`
|
`\tactual : ${displayValue(actual)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ export class Expect<T> {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`value does not equal expected`,
|
`value does not equal expected`,
|
||||||
expected,
|
expected,
|
||||||
this.value
|
this.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ export class StringExpect extends Expect<string> {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`value does not match expected pattern`,
|
`value does not match expected pattern`,
|
||||||
pattern,
|
pattern,
|
||||||
this.value
|
this.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -91,7 +91,7 @@ export class StringExpect extends Expect<string> {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`value does not start with expected prefix`,
|
`value does not start with expected prefix`,
|
||||||
prefix,
|
prefix,
|
||||||
this.value
|
this.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +109,7 @@ export class StringExpect extends Expect<string> {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`value does not end with expected suffix`,
|
`value does not end with expected suffix`,
|
||||||
suffix,
|
suffix,
|
||||||
this.value
|
this.value,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,14 +138,14 @@ export class FunctionExpect<T> extends Expect<() => T> {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`function threw non-Error value`,
|
`function threw non-Error value`,
|
||||||
pattern,
|
pattern,
|
||||||
error
|
error,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!matches(error.message, pattern)) {
|
if (!matches(error.message, pattern)) {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`thrown Error's message does not match pattern`,
|
`thrown Error's message does not match pattern`,
|
||||||
pattern,
|
pattern,
|
||||||
error.message
|
error.message,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
@ -153,7 +153,7 @@ export class FunctionExpect<T> extends Expect<() => T> {
|
||||||
throw new ExpectError(
|
throw new ExpectError(
|
||||||
`function did not throw expected error`,
|
`function did not throw expected error`,
|
||||||
pattern,
|
pattern,
|
||||||
null
|
null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ const runTest = async (test: Test): Promise<TestResult> => {
|
||||||
error instanceof Error
|
error instanceof Error
|
||||||
? error
|
? error
|
||||||
: new Error(
|
: new Error(
|
||||||
`threw non-error object: ${displayValue(error)}`
|
`threw non-error object: ${displayValue(error)}`,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +86,7 @@ export interface TestSuiteContext {
|
||||||
*/
|
*/
|
||||||
export const testSuite = (
|
export const testSuite = (
|
||||||
suiteName: string,
|
suiteName: string,
|
||||||
def: (ctx: TestSuiteContext) => void
|
def: (ctx: TestSuiteContext) => void,
|
||||||
): void => {
|
): void => {
|
||||||
const tests: Test[] = [];
|
const tests: Test[] = [];
|
||||||
const test = (name: string, runTest: () => void | Promise<void>): void => {
|
const test = (name: string, runTest: () => void | Promise<void>): void => {
|
||||||
|
|
@ -104,14 +104,14 @@ export const testSuite = (
|
||||||
if (testResult.result === "fail") {
|
if (testResult.result === "fail") {
|
||||||
console.error(
|
console.error(
|
||||||
`[TEST FAILURE] "${suiteName}": "${testResult.testName}": ` +
|
`[TEST FAILURE] "${suiteName}": "${testResult.testName}": ` +
|
||||||
`${testResult.error.stack}\n`
|
`${testResult.error.stack}\n`,
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
passed += 1;
|
passed += 1;
|
||||||
}
|
}
|
||||||
console.info(
|
console.info(
|
||||||
`[TEST] suite "${suiteName}": ${passed} of ${tests.length} succeeded\n\n`
|
`[TEST] suite "${suiteName}": ${passed} of ${tests.length} succeeded\n\n`,
|
||||||
);
|
);
|
||||||
if (passed < tests.length) {
|
if (passed < tests.length) {
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ const areArraysEqual = <T>(a: T[], b: T[]): boolean => {
|
||||||
|
|
||||||
const areObjectsEqual = <T extends Record<string, unknown>>(
|
const areObjectsEqual = <T extends Record<string, unknown>>(
|
||||||
a: T,
|
a: T,
|
||||||
b: T
|
b: T,
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const aKeys = Object.keys(a) as Array<keyof T>;
|
const aKeys = Object.keys(a) as Array<keyof T>;
|
||||||
const bKeys = Object.keys(b) as Array<keyof T>;
|
const bKeys = Object.keys(b) as Array<keyof T>;
|
||||||
|
|
@ -67,7 +67,7 @@ export const areEqual = <T>(a: T, b: T): boolean => {
|
||||||
if (typeof a === "object" && typeof b === "object") {
|
if (typeof a === "object" && typeof b === "object") {
|
||||||
return areObjectsEqual(
|
return areObjectsEqual(
|
||||||
a as Record<string, unknown>,
|
a as Record<string, unknown>,
|
||||||
b as Record<string, unknown>
|
b as Record<string, unknown>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return a === b;
|
return a === b;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import { testSuite } from "../lib";
|
||||||
testSuite("renderPage", ({ test, expect }) => {
|
testSuite("renderPage", ({ test, expect }) => {
|
||||||
test("throws an Error when root elem is not html tag", () => {
|
test("throws an Error when root elem is not html tag", () => {
|
||||||
expect(() => renderPage(<div />)).toThrowErrorMatching(
|
expect(() => renderPage(<div />)).toThrowErrorMatching(
|
||||||
"attempted to render page with non-HTML root element div"
|
"attempted to render page with non-HTML root element div",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -21,10 +21,10 @@ testSuite("renderPage", ({ test, expect }) => {
|
||||||
|
|
||||||
test("escapes HTML in tag names", () => {
|
test("escapes HTML in tag names", () => {
|
||||||
const html = renderPage(
|
const html = renderPage(
|
||||||
<html>{createElement("div></div", null)}</html>
|
<html>{createElement("div></div", null)}</html>,
|
||||||
);
|
);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
"<!DOCTYPE html><html><div></div></div></div></html>"
|
"<!DOCTYPE html><html><div></div></div></div></html>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -32,10 +32,10 @@ testSuite("renderPage", ({ test, expect }) => {
|
||||||
const html = renderPage(
|
const html = renderPage(
|
||||||
<html>
|
<html>
|
||||||
<div className="test" id="1" />
|
<div className="test" id="1" />
|
||||||
</html>
|
</html>,
|
||||||
);
|
);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
'<!DOCTYPE html><html><div class="test" id="1"></div></html>'
|
'<!DOCTYPE html><html><div class="test" id="1"></div></html>',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -48,17 +48,17 @@ testSuite("renderPage", ({ test, expect }) => {
|
||||||
<body>
|
<body>
|
||||||
<div />
|
<div />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>,
|
||||||
);
|
);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
"<!DOCTYPE html><html><head><title></title></head><body><div></div></body></html>"
|
"<!DOCTYPE html><html><head><title></title></head><body><div></div></body></html>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("renders text nodes", () => {
|
test("renders text nodes", () => {
|
||||||
const html = renderPage(<html>There are three lights!</html>);
|
const html = renderPage(<html>There are three lights!</html>);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
"<!DOCTYPE html><html>There are three lights!</html>"
|
"<!DOCTYPE html><html>There are three lights!</html>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -80,10 +80,10 @@ testSuite("renderPage", ({ test, expect }) => {
|
||||||
<Light lightN={lightN} />
|
<Light lightN={lightN} />
|
||||||
))}{" "}
|
))}{" "}
|
||||||
lights!
|
lights!
|
||||||
</html>
|
</html>,
|
||||||
);
|
);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
"<!DOCTYPE html><html>There are <div>1</div><div>2</div><div>3</div> lights!</html>"
|
"<!DOCTYPE html><html>There are <div>1</div><div>2</div><div>3</div> lights!</html>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -97,10 +97,10 @@ testSuite("renderPage", ({ test, expect }) => {
|
||||||
const html = renderPage(
|
const html = renderPage(
|
||||||
<html>
|
<html>
|
||||||
There are <Light nLights={3} />!
|
There are <Light nLights={3} />!
|
||||||
</html>
|
</html>,
|
||||||
);
|
);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
"<!DOCTYPE html><html>There are <div>3 lights</div>!</html>"
|
"<!DOCTYPE html><html>There are <div>3 lights</div>!</html>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -111,10 +111,10 @@ testSuite("renderPage", ({ test, expect }) => {
|
||||||
<div>test of</div>
|
<div>test of</div>
|
||||||
<div>fragments</div>
|
<div>fragments</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
</html>
|
</html>,
|
||||||
);
|
);
|
||||||
expect(html).toEqual(
|
expect(html).toEqual(
|
||||||
"<!DOCTYPE html><html><div>test of</div><div>fragments</div></html>"
|
"<!DOCTYPE html><html><div>test of</div><div>fragments</div></html>",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue