Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use cross-spawn for CLI testing #63

Merged
merged 1 commit into from
Jan 4, 2024
Merged
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
11 changes: 11 additions & 0 deletions package-lock.json

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

2 changes: 2 additions & 0 deletions packages/unified-latex-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
"homepage": "https://github.com/siefkenj/unified-latex#readme",
"private": true,
"devDependencies": {
"@types/cross-spawn": "^6.0.6",
"cross-spawn": "^7.0.3",
"source-map-support": "^0.5.21"
}
}
206 changes: 129 additions & 77 deletions packages/unified-latex-cli/tests/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "../../test-common";
import { exec as _exec } from "node:child_process";
import * as fsLegacy from "node:fs";
import * as path from "node:path";
import spawn from "cross-spawn";

const exec = util.promisify(_exec);

Expand All @@ -18,87 +19,138 @@ console.log = (...args) => {
const exePath = path.resolve(__dirname, "../dist/unified-latex-cli.mjs");
const examplesPath = path.resolve(__dirname, "examples");

describe("unified-latex-cli", () => {
let stdout: string, stderr: string;
it("executable exists", async () => {
expect(fsLegacy.existsSync(exePath)).toBeTruthy();
});
it("can execute without error", async () => {
let { stdout, stderr } = await exec(`node ${exePath} -h`);
expect(stdout).toBeTruthy();
});
it("can format document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/needs-fixing.tex`
);
expect(stdout).toMatchSnapshot();
});
it("can expand macro", async () => {
{
describe(
"unified-latex-cli",
() => {
let stdout: string, stderr: string;
it("executable exists", async () => {
expect(fsLegacy.existsSync(exePath)).toBeTruthy();
});
it("can execute without error", async () => {
let { stdout, stderr } = await exec(`node ${exePath} -h`);
expect(stdout).toBeTruthy();
});
it("can format document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/needs-expanding.tex -e '\\newcommand{foo}[1]{FOO(#1)}' -e '{name: "bar", body: "baz"}'`
`node ${exePath} ${examplesPath}/needs-fixing.tex`
);
expect(stdout).toMatchSnapshot();
}
{
// Make sure we don't lose spaces in math mode
});
it("can expand macro", async () => {
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/needs-expanding.tex`,
`-e`,
"\\newcommand{foo}[1]{FOO(#1)}",
`-e`,
'{name: "bar", body: "baz"}',
]);
expect(stdout).toMatchSnapshot();
}
{
// Make sure we don't lose spaces in math mode
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/needs-expanding.tex`,
`-e`,
"\\newcommand{foo}[1]{$\\x #1$}",
`-e`,
'{name: "bar", body: "baz"}',
]);
expect(stdout).toMatchSnapshot();
}
});
it("can expand macros defined in document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/needs-expanding.tex -e '\\newcommand{foo}[1]{$\\x #1$}' -e '{name: "bar", body: "baz"}'`
`node ${exePath} ${examplesPath}/has-definition.tex --stats-json`
);
expect(stdout).toMatchSnapshot();
}
});
it("can expand macros defined in document", async () => {
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-definition.tex --stats-json`
);
const { newcommands } = JSON.parse(stdout) as {
newcommands: { name: string }[];
};
const newcommandNames = newcommands.map((c) => c.name);
expect(newcommandNames).toEqual(["foo", "baz"]);
const { newcommands } = JSON.parse(stdout) as {
newcommands: { name: string }[];
};
const newcommandNames = newcommands.map((c) => c.name);
expect(newcommandNames).toEqual(["foo", "baz"]);

{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-definition.tex --expand-document-macro foo --expand-document-macro baz`
);
expect(stdout).toMatchSnapshot();
}
});
it("can override default macros", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-existing-definition.tex`
);
expect(stdout).toMatchSnapshot();
}
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-existing-definition.tex -e '\\newcommand{mathbb}{\\mathbb}'`
);
expect(stdout).toMatchSnapshot();
}
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-existing-definition.tex -e '\\newcommand{mathbb}[2]{\\mathbb{#1}{#2}}'`
);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to html", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --html`
);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to markdown", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --markdown`
);
expect(stdout).toMatchSnapshot();
}
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/has-definition.tex --expand-document-macro foo --expand-document-macro baz`
);
expect(stdout).toMatchSnapshot();
}
});
it("can override default macros", async () => {
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/has-existing-definition.tex`,
]);
expect(stdout).toMatchSnapshot();
}
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/has-existing-definition.tex`,
`-e`,
"\\newcommand{mathbb}{\\mathbb}",
]);
expect(stdout).toMatchSnapshot();
}
{
let stdout = await executeCommand(`node`, [
exePath,
`${examplesPath}/has-existing-definition.tex`,
`-e`,
"\\newcommand{mathbb}[2]{\\mathbb{#1}{#2}}",
]);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to html", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --html`
);
expect(stdout).toMatchSnapshot();
}
});
it("can convert to markdown", async () => {
{
let { stdout, stderr } = await exec(
`node ${exePath} ${examplesPath}/simple.tex --markdown`
);
expect(stdout).toMatchSnapshot();
}
});
},
{
timeout: 60 * 1000,
}
);

/**
* Run commands with arguments using "cross-spawn", which correctly escapes arguments
* so that end results are the same across different shells.
*/
async function executeCommand(executablePath: string, args: string[]) {
return new Promise((resolve, reject) => {
const childProcess = spawn(executablePath, args, { stdio: "pipe" });

let stdoutData = "";

childProcess.stdout!.on("data", (data) => {
stdoutData += data.toString();
});

childProcess.on("error", (err) => {
reject(err);
});

childProcess.on("close", (code) => {
if (code === 0) {
resolve(stdoutData);
} else {
reject(new Error(`Child process exited with code ${code}`));
}
});
});
});
}
2 changes: 1 addition & 1 deletion packages/unified-latex-to-hast/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export * from "./libs/convert-to-html";
* import { printRaw } from "@unified-latex/unified-latex-util-print-raw";
* import { unifiedLatexToHast } from "@unified-latex/unified-latex-to-hast";
* import { unifiedLatexFromString } from "@unified-latex/unified-latex-util-parse";
* import { getArgsContent } from "@unified-latex/unified-latex-util-arguments";
* import { getArgsContent } from "@unified-latex/unified-latex-util-arguments";
*
* const convert = (value) =>
* unified()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,5 @@ export const environmentReplacements: Record<
content: env.content,
attributes: { className: "environment quote" },
});
}
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,20 @@ describe("unified-latex-to-mdast:convert-to-markdown", () => {
`### My Section\n\nHi there\n\nAnd here $x^{2}$ math\n`
);
});

it("display math converts to $$...$$", () => {
let ast = unified()
.use(unifiedLatexFromString)
.parse("my\\[math\\]yay!");
markdown = convertToMarkdown(ast);
expect(markdown).toEqual(
`my\n\n\`\`\`math\nmath\n\`\`\`\n\nyay!\n`
);
expect(markdown).toEqual(`my\n\n\`\`\`math\nmath\n\`\`\`\n\nyay!\n`);
});

it("math isn't mangled when it is rendered", () => {
let ast = unified()
.use(unifiedLatexFromString)
.parse("$\\sum_x^{y} x+Y$");
markdown = convertToMarkdown(ast);
expect(markdown).toEqual(
`$\\sum_{x}^{y}x+Y$\n`
);
expect(markdown).toEqual(`$\\sum_{x}^{y}x+Y$\n`);
});
});
2 changes: 1 addition & 1 deletion packages/unified-latex-util-catcode/libs/regions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export function refineRegions(regions: Region[]): {
*/
export function splitByRegions<
T,
RegionRecord extends Record<string, Region[]>
RegionRecord extends Record<string, Region[]>,
>(array: T[], regionsRecord: RegionRecord) {
const ret: [keyof RegionRecord | null, T[]][] = [];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const SUBSTITUTION_MAP: Map<string, Ast.String> = new Map([
["- - -", makeString("—")],
["- -", makeString("–")],
["` `", makeString("“")],
["\"", makeString("”")],
['"', makeString("”")],
["' '", makeString("”")],
["`", makeString("‘")],
["'", makeString("’")],
Expand Down
2 changes: 1 addition & 1 deletion packages/unified-latex-util-visit/libs/visit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ type GuardTypeOf<T extends (x: any, ...y: any[]) => boolean> =
*/
type GuardFromOptions<
Opts extends VisitOptions,
PossibleTypes = Ast.Ast
PossibleTypes = Ast.Ast,
> = Opts extends {
test: infer R;
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/package-consistency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async function getImportsInDir(dirname): Promise<string[]> {
for (const line of contents.split("\n")) {
// Lines that start with ` * ` are comments; we don't track them.
if (line.match(/^\s*\*\s/)) {
continue
continue;
}
for (const m of line.matchAll(/from "([^"]+)"/g)) {
const imp = m[1];
Expand Down
Loading