diff --git a/src/command/render/freeze.ts b/src/command/render/freeze.ts index 2db57afedda..1586e0299ab 100644 --- a/src/command/render/freeze.ts +++ b/src/command/render/freeze.ts @@ -53,8 +53,10 @@ export function freezeExecuteResult( result: ExecuteResult, ) { // resolve includes within executeResult + // nb: Beware to not modify the original result object const innerResult = { ...result, + includes: result.includes ? { ...result.includes } : undefined, } as ExecuteResult; const resolveIncludes = ( name: "include-in-header" | "include-before-body" | "include-after-body", diff --git a/tests/.gitignore b/tests/.gitignore index 57bd231639e..b50374b5ecc 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,8 +1,8 @@ # Python Environments .env .venv -env/ -venv/ +/env/ +/venv/ ENV/ env.bak/ venv.bak/ diff --git a/tests/docs/smoke-all/2024/06/19/9208.qmd b/tests/docs/smoke-all/2024/06/19/9208.qmd index 4853d7596d6..13b10503aab 100644 --- a/tests/docs/smoke-all/2024/06/19/9208.qmd +++ b/tests/docs/smoke-all/2024/06/19/9208.qmd @@ -8,8 +8,8 @@ _quarto: html: noErrors: true printsMessage: - - WARN - - 'code-link.*ignored' + level: WARN + regex: 'code-link.*ignored' ensureHtmlElements: - [] - ['pre.downlit'] diff --git a/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd b/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd index fe651943a8c..ebfc5449780 100644 --- a/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd +++ b/tests/docs/smoke-all/2024/08/30/10291/latex-hyphen-lang-es-no-install.qmd @@ -7,8 +7,8 @@ _quarto: pdf: noErrors: true printsMessage: - - WARN - - 'missing hyphenation.*hyphen-spanish' + level: WARN + regex: 'missing hyphenation.*hyphen-spanish' --- ```{r} diff --git a/tests/docs/smoke-all/2024/09/30/10931-2.qmd b/tests/docs/smoke-all/2024/09/30/10931-2.qmd index bc787c75e5f..9ffcc852c43 100644 --- a/tests/docs/smoke-all/2024/09/30/10931-2.qmd +++ b/tests/docs/smoke-all/2024/09/30/10931-2.qmd @@ -5,8 +5,8 @@ _quarto: tests: pptx: printsMessage: - - INFO - - 'WARNING.*FloatRefTargets require' + level: INFO + regex: 'WARNING.*FloatRefTargets require' ensurePptxXpath: - - 2 diff --git a/tests/docs/smoke-all/2025/03/05/12204/.gitignore b/tests/docs/smoke-all/2025/03/05/12204/.gitignore new file mode 100644 index 00000000000..075b2542afb --- /dev/null +++ b/tests/docs/smoke-all/2025/03/05/12204/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/tests/docs/smoke-all/2025/03/05/12204/_quarto.yml b/tests/docs/smoke-all/2025/03/05/12204/_quarto.yml new file mode 100644 index 00000000000..b8bae5830fa --- /dev/null +++ b/tests/docs/smoke-all/2025/03/05/12204/_quarto.yml @@ -0,0 +1,2 @@ +project: + type: default diff --git a/tests/docs/smoke-all/2025/03/05/12204/index.qmd b/tests/docs/smoke-all/2025/03/05/12204/index.qmd new file mode 100644 index 00000000000..510f6dbdb53 --- /dev/null +++ b/tests/docs/smoke-all/2025/03/05/12204/index.qmd @@ -0,0 +1,15 @@ +--- +format: html +engine: julia +_quarto: + tests: + html: + printsMessage: + level: INFO + regex: 'FATAL[\s\S]*Error resolving header-includes' + negate: true +--- + +```{julia} +?for +``` \ No newline at end of file diff --git a/tests/docs/smoke-all/crossrefs/float/latex/latex-raw-table-env-no-tbl-label.qmd b/tests/docs/smoke-all/crossrefs/float/latex/latex-raw-table-env-no-tbl-label.qmd index 6e24b9adbea..a545ae82701 100644 --- a/tests/docs/smoke-all/crossrefs/float/latex/latex-raw-table-env-no-tbl-label.qmd +++ b/tests/docs/smoke-all/crossrefs/float/latex/latex-raw-table-env-no-tbl-label.qmd @@ -9,8 +9,8 @@ _quarto: - ['[\s\S]+\\begin\{table\}\[htbp\][\s\S]+', '[\s\S]+\\caption\{\\label\{mod\}'] - [] printsMessage: - - INFO - - 'WARNING(.*)Raw LaTeX table found with non-tbl label:' + level: INFO + regex: 'WARNING(.*)Raw LaTeX table found with non-tbl label:' --- This document has a raw LaTeX table with no intent to use quarto crossref. It uses a label with `tbl-` id. diff --git a/tests/smoke/env/check.test.ts b/tests/smoke/env/check.test.ts index 692ca392749..9125b71d9c9 100644 --- a/tests/smoke/env/check.test.ts +++ b/tests/smoke/env/check.test.ts @@ -12,6 +12,6 @@ testQuartoCmd( [], [ noErrorsOrWarnings, - printsMessage("INFO", /Version: 99\.9\.9/), + printsMessage({level: "INFO", regex: /Version: 99\.9\.9/}), ], ); diff --git a/tests/smoke/env/install.test.ts b/tests/smoke/env/install.test.ts index 2bf8b2ef3fc..1a1c044c6f8 100644 --- a/tests/smoke/env/install.test.ts +++ b/tests/smoke/env/install.test.ts @@ -12,8 +12,8 @@ testQuartoCmd( ["list"], [ noErrorsOrWarnings, - printsMessage("INFO", /tinytex\s+/), - // printsMessage("INFO", /chromium\s+/), + printsMessage({level: "INFO", regex: /tinytex\s+/}), + // printsMessage({level: "INFO", regex: /chromium\s+/}), // temporarily disabled until we get puppeteer back ], ); diff --git a/tests/smoke/jupyter/cache.test.ts b/tests/smoke/jupyter/cache.test.ts index e0537da5ac3..6a687778aab 100644 --- a/tests/smoke/jupyter/cache.test.ts +++ b/tests/smoke/jupyter/cache.test.ts @@ -41,7 +41,7 @@ test({ verify: [ folderExists(cacheFolder), // this will check only for the second render that should be read from cache - printsMessage("INFO", /Notebook read from cache/) + printsMessage({ level: "INFO", regex: /Notebook read from cache/}) ], type: "smoke", }); @@ -82,7 +82,7 @@ test({ verify: [ folderExists(cacheFolder2), // this will check only for the second render that should be read from cache - printsMessage("INFO", /Notebook read from cache/) + printsMessage({level: "INFO", regex: /Notebook read from cache/}) ], type: "smoke", }); \ No newline at end of file diff --git a/tests/smoke/project/project-prepost.test.ts b/tests/smoke/project/project-prepost.test.ts index 85845e046bf..3caf6d72419 100644 --- a/tests/smoke/project/project-prepost.test.ts +++ b/tests/smoke/project/project-prepost.test.ts @@ -36,7 +36,7 @@ testQuartoCmd( -// Tests that if the pre-renderf script mutates the output directory +// Tests that if the pre-render script mutates the output directory // we throw an error that complains about this. const mutateRenderDir = docs("project/prepost/invalid-mutate"); const mutateRenderDirAbs = join(Deno.cwd(), mutateRenderDir); @@ -45,7 +45,7 @@ const mutateRenderOutDir = join(mutateRenderDirAbs, "_site"); testQuartoCmd( "render", [mutateRenderDir], - [printsMessage("ERROR", /output-dir may not be mutated/gm)], + [printsMessage({level: "ERROR", regex: /output-dir may not be mutated/gm})], { teardown: async () => { const mdClean = join(mutateRenderDirAbs, "_metadata.yml"); diff --git a/tests/smoke/smoke-all.test.ts b/tests/smoke/smoke-all.test.ts index ee00a8cb1e8..9fe502a272a 100644 --- a/tests/smoke/smoke-all.test.ts +++ b/tests/smoke/smoke-all.test.ts @@ -160,7 +160,7 @@ function resolveTestSpecs( verifyFns.push(verifyMap[key](outputFile.outputPath, ...value)); } } else if (key === "printsMessage") { - verifyFns.push(verifyMap[key](...value)); + verifyFns.push(verifyMap[key](value)); } else if (verifyMap[key]) { // FIXME: We should find another way that having this requirement of keep-* in the metadata if (key === "ensureTypstFileRegexMatches") { @@ -325,7 +325,7 @@ Promise.all(testFilesPromises).then(() => { for (const project of testedProjects) { // Clean project output directory const projectOutDir = join(project, findProjectOutputDir(project)); - if (safeExistsSync(projectOutDir)) { + if (projectOutDir !== project && safeExistsSync(projectOutDir)) { safeRemoveSync(projectOutDir, { recursive: true }); } // Clean hidden .quarto directory diff --git a/tests/smoke/use/template.test.ts b/tests/smoke/use/template.test.ts index e8947548ab9..b1c17a47da8 100644 --- a/tests/smoke/use/template.test.ts +++ b/tests/smoke/use/template.test.ts @@ -39,7 +39,7 @@ ensureDirSync(nonEmptyWorkingDir); testQuartoCmd( "use", ["template", "quarto-journals/jasa", "--no-prompt"], - [printsMessage("ERROR", /directory isn't empty/), directoryContainsOnlyAllowedPaths(nonEmptyWorkingDir, [nonEmptyFileName])], + [printsMessage({level: "ERROR", regex: /directory isn't empty/}), directoryContainsOnlyAllowedPaths(nonEmptyWorkingDir, [nonEmptyFileName])], { setup: () => { Deno.writeTextFileSync(join(nonEmptyWorkingDir, nonEmptyFileName), "Just making a non-empty file!"); diff --git a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts index c2dcea97dc3..4468391ba19 100644 --- a/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts +++ b/tests/smoke/yaml-intelligence/yaml-intelligence-code-cell-options.test.ts @@ -8,7 +8,7 @@ const testYamlValidationFails = (file: string) => { testQuartoCmd( "render", [yamlDocs(file, "html").input, "--to", "html", "--quiet"], - [printsMessage("ERROR", /Validation of YAML cell metadata failed/)], + [printsMessage({level: "ERROR", regex: /Validation of YAML cell metadata failed/})], ); }; diff --git a/tests/smoke/yaml/config-yaml-validation.test.ts b/tests/smoke/yaml/config-yaml-validation.test.ts index 6ed1bd6a13d..0548907858f 100644 --- a/tests/smoke/yaml/config-yaml-validation.test.ts +++ b/tests/smoke/yaml/config-yaml-validation.test.ts @@ -14,5 +14,5 @@ const input = docs("yaml/bad-config-yaml/subfolder/bad-config-yaml.qmd"); testQuartoCmd( "render", [input], - [printsMessage("ERROR", /bad-config-yaml[\/\\]+_quarto[.]yml validation failed/)] + [printsMessage({level: "ERROR", regex: /bad-config-yaml[\/\\]+_quarto[.]yml validation failed/})] ); diff --git a/tests/verify.ts b/tests/verify.ts index 3e56eb0d4a9..f3a6cf0106a 100644 --- a/tests/verify.ts +++ b/tests/verify.ts @@ -133,20 +133,26 @@ export const noErrorsOrWarnings: Verify = { }, }; -export const printsMessage = ( - level: "DEBUG" | "INFO" | "WARN" | "ERROR", - regex: RegExp | string, -): Verify => { +export const printsMessage = (options: { + level: "DEBUG" | "INFO" | "WARN" | "ERROR"; + regex: string | RegExp; + negate?: boolean; +}): Verify => { + const { level, regex: regexPattern, negate = false } = options; // Set default here return { - name: `${level} matches ${String(regex)}`, + name: `${level} matches ${String(regexPattern)}`, verify: (outputs: ExecuteOutput[]) => { - if (typeof regex === "string") { - regex = new RegExp(regex); - } + const regex = typeof regexPattern === "string" + ? new RegExp(regexPattern) + : regexPattern; + const printedMessage = outputs.some((output) => { return output.levelName === level && output.msg.match(regex); }); - assert(printedMessage, `Missing ${level} ${String(regex)}`); + assert( + negate ? !printedMessage : printedMessage, + `${negate ? "Found" : "Missing"} ${level} ${String(regex)}` + ); return Promise.resolve(); }, };