diff --git a/apps/vscode/src/test/examples/generated_snapshots/roundtripped-invalid.qmd b/apps/vscode/src/test/examples/generated_snapshots/roundtripped-invalid.qmd new file mode 100644 index 00000000..9fe21ec5 --- /dev/null +++ b/apps/vscode/src/test/examples/generated_snapshots/roundtripped-invalid.qmd @@ -0,0 +1,3 @@ +\[missing close curly bracket\]{ + +\[missing close parenthesis\](https://example.com \ No newline at end of file diff --git a/apps/vscode/src/test/examples/generated_snapshots/roundtripped-valid-basics.qmd b/apps/vscode/src/test/examples/generated_snapshots/roundtripped-valid-basics.qmd new file mode 100644 index 00000000..b5705cf4 --- /dev/null +++ b/apps/vscode/src/test/examples/generated_snapshots/roundtripped-valid-basics.qmd @@ -0,0 +1,41 @@ +- Item one +- Item two +- Item three + +This is `inline code` text + +``` +function hello() { + return "world" +} +``` + +This is *emphasized* text + +# Main Header + +Line one Line two + +[a link](./hello "out"){#fig .class key="value"} + +This is inline math $E = mc^2$ and more text + +This is display math + +$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$ + +More inline math $\alpha + \beta = \gamma$ here + +This is a simple paragraph + +'single quote' "double quote" + +a [span]{#with-id .class key="value"} + +~~strikeout~~ + +This is **strong** text + +^superscript^ + +[underlined]{.underline} [underline]{.underline} \ No newline at end of file diff --git a/apps/vscode/src/test/examples/invalid.qmd b/apps/vscode/src/test/examples/invalid.qmd new file mode 100644 index 00000000..b12bf379 --- /dev/null +++ b/apps/vscode/src/test/examples/invalid.qmd @@ -0,0 +1,3 @@ +[missing close curly bracket]{ + +[missing close parenthesis](https://example.com diff --git a/apps/vscode/src/test/examples/roundtrip-failures.qmd b/apps/vscode/src/test/examples/roundtrip-changes.qmd similarity index 100% rename from apps/vscode/src/test/examples/roundtrip-failures.qmd rename to apps/vscode/src/test/examples/roundtrip-changes.qmd diff --git a/apps/vscode/src/test/examples/valid-basics.qmd b/apps/vscode/src/test/examples/valid-basics.qmd new file mode 100644 index 00000000..560e3256 --- /dev/null +++ b/apps/vscode/src/test/examples/valid-basics.qmd @@ -0,0 +1,42 @@ +- Item one +- Item two +- Item three + +This is `inline code` text + +``` +function hello() { + return "world" +} +``` + +This is *emphasized* text + +# Main Header + +Line one +Line two + +[a link](./hello "out"){#fig .class key=value} + +This is inline math $E = mc^2$ and more text + +This is display math + +$$\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}$$ + +More inline math $\alpha + \beta = \gamma$ here + +This is a simple paragraph + +'single quote' "double quote" + +a [span]{#with-id .class key=value} + +~~strikeout~~ + +This is **strong** text + +^superscript^ + +[underlined]{.underline} [underline]{.ul} diff --git a/apps/vscode/src/test/quartoDoc.test.ts b/apps/vscode/src/test/quartoDoc.test.ts index e6f9fddf..7782909b 100644 --- a/apps/vscode/src/test/quartoDoc.test.ts +++ b/apps/vscode/src/test/quartoDoc.test.ts @@ -1,10 +1,8 @@ import * as vscode from "vscode"; import * as assert from "assert"; -import { WORKSPACE_PATH, examplesOutUri, wait } from "./test-utils"; +import { WORKSPACE_PATH, readOrCreateSnapshot, examplesOutUri, wait, roundtrip, openAndShowTextDocument } from "./test-utils"; import { isQuartoDoc } from "../core/doc"; -import { extension } from "./extension"; -const APPROX_TIME_TO_OPEN_VISUAL_EDITOR = 1700; suite("Quarto basics", function () { // Before running tests, copy `./examples` to a new folder `./examples-out`. @@ -15,8 +13,7 @@ suite("Quarto basics", function () { }); test("Can open a Quarto document", async function () { - const doc = await vscode.workspace.openTextDocument(examplesOutUri("hello.qmd")); - const editor = await vscode.window.showTextDocument(doc); + const { editor } = await openAndShowTextDocument("hello.qmd"); assert.strictEqual(editor?.document.languageId, "quarto"); assert.strictEqual(isQuartoDoc(editor?.document), true); @@ -26,40 +23,38 @@ suite("Quarto basics", function () { // test. That's okay for this test, but could cause issues if you expect a qmd to look how it // does in `/examples`. test("Roundtrip doesn't change hello.qmd", async function () { - const doc = await vscode.workspace.openTextDocument(examplesOutUri("hello.qmd")); - const editor = await vscode.window.showTextDocument(doc); + const { doc } = await openAndShowTextDocument("hello.qmd"); const { before, after } = await roundtrip(doc); assert.equal(before, after); }); - test("Roundtrip does change roundtrip-failures.qmd", async function () { + test("Roundtrip changes roundtrip-changes.qmd", async function () { // We want this test to fail locally so that we can reference the // before/affter diff that Mocha logs, but we dont wan't CI to fail. if (process.env['CI']) this.skip(); - const doc = await vscode.workspace.openTextDocument(examplesOutUri("roundtrip-failures.qmd")); - const editor = await vscode.window.showTextDocument(doc); + const { doc } = await openAndShowTextDocument("roundtrip-changes.qmd"); const { before, after } = await roundtrip(doc); assert.equal(before, after); }); -}); -async function roundtrip(doc: vscode.TextDocument) { - const before = doc.getText(); + test("Roundtripped valid-basics.qmd matches snapshot", async function () { + const { doc } = await openAndShowTextDocument("valid-basics.qmd"); + + const { after } = await roundtrip(doc); + + assert.equal(after, await readOrCreateSnapshot("roundtripped-valid-basics.qmd", after)); + }); - // switch to visual editor and back - await vscode.commands.executeCommand("quarto.test_setkVisualModeConfirmedTrue"); - await wait(300); - await vscode.commands.executeCommand("quarto.editInVisualMode"); - await wait(APPROX_TIME_TO_OPEN_VISUAL_EDITOR); - await vscode.commands.executeCommand("quarto.editInSourceMode"); - await wait(300); + test("Roundtripped invalid.qmd matches snapshot", async function () { + const { doc } = await openAndShowTextDocument("invalid.qmd"); - const after = doc.getText(); + const { after } = await roundtrip(doc); - return { before, after }; -} + assert.equal(after, await readOrCreateSnapshot("roundtripped-invalid.qmd", after)); + }); +}); diff --git a/apps/vscode/src/test/test-utils.ts b/apps/vscode/src/test/test-utils.ts index 0f878c82..75c38efa 100644 --- a/apps/vscode/src/test/test-utils.ts +++ b/apps/vscode/src/test/test-utils.ts @@ -15,6 +15,9 @@ export const TEST_PATH = path.join(EXTENSION_ROOT_DIR, "src", "test"); export const WORKSPACE_PATH = path.join(TEST_PATH, "examples"); export const WORKSPACE_OUT_PATH = path.join(TEST_PATH, "examples-out"); +function examplesUri(fileName: string = ''): vscode.Uri { + return vscode.Uri.file(path.join(WORKSPACE_PATH, fileName)); +} export function examplesOutUri(fileName: string = ''): vscode.Uri { return vscode.Uri.file(path.join(WORKSPACE_OUT_PATH, fileName)); } @@ -22,3 +25,40 @@ export function examplesOutUri(fileName: string = ''): vscode.Uri { export function wait(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)); } + +export async function openAndShowTextDocument(fileName: string) { + const doc = await vscode.workspace.openTextDocument(examplesOutUri(fileName)); + const editor = await vscode.window.showTextDocument(doc); + return { doc, editor }; +} + +const APPROX_TIME_TO_OPEN_VISUAL_EDITOR = 1700; +export async function roundtrip(doc: vscode.TextDocument) { + const before = doc.getText(); + + // switch to visual editor and back + await vscode.commands.executeCommand("quarto.test_setkVisualModeConfirmedTrue"); + await wait(300); + await vscode.commands.executeCommand("quarto.editInVisualMode"); + await wait(APPROX_TIME_TO_OPEN_VISUAL_EDITOR); + await vscode.commands.executeCommand("quarto.editInSourceMode"); + await wait(300); + + const after = doc.getText(); + + return { before, after }; +} + +export async function readOrCreateSnapshot(fileName: string, content: string) { + const snapshotUri = examplesUri(path.join('generated_snapshots', fileName)); + try { + const doc = await vscode.workspace.openTextDocument(snapshotUri); + return doc.getText(); + } catch { + await vscode.workspace.fs.writeFile( + snapshotUri, + Buffer.from(content, 'utf8') + ); + return content; + } +}