import { expect, it } from "vitest"; import { HTML_INLINE_SCRIPT_LOCATION_LIMIT, htmlArtifactReferences, } from "./htmlArtifactReferences.js"; it.each([ ['', []], ['', []], [``, []], ["", ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ["", ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ['', []], ['', ["actual.js"]], ['', []], ['', []], ['', []], [``, []], [ '', [], ], ['', []], [ '', ["actual.js"], ], ['', ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ['', ["actual.js"]], ])("extracts document references from %s", (text, expected) => { expect( htmlArtifactReferences(text).scripts.map(({ scriptPath }) => scriptPath), ).toEqual(expected); }); it("retains exact opening-tag coordinates rather than the script body", () => { const opening = ''; const prefix = "\n\n"; const text = `${prefix}${opening}ignored body`; expect(htmlArtifactReferences(text)).toEqual({ baseHref: null, inlineScripts: [], inlineScriptCount: 0, scripts: [ { scriptPath: "actual.js", scriptType: "classic", location: { start: { line: 3, column: 0 }, end: { line: 4, column: ' title=">" src=actual.js>'.length }, }, }, ], }); }); it.each([ ['', "actual/"], ['', "actual/"], ['', ""], ['', "actual/"], ['', "actual/"], ])("selects the first real base href from %s", (text, expected) => { expect(htmlArtifactReferences(text).baseHref).toBe(expected); }); it("traverses deep valid document content without recursive stack growth", () => { const depth = 12_000; const text = `${"
".repeat(depth)}${"
".repeat(depth)}`; expect( htmlArtifactReferences(text).scripts.map(({ scriptPath }) => scriptPath), ).toEqual(["actual.js"]); }); it.each([ ["", ["classic"]], ['', ["classic"]], ['', ["classic"]], ['', ["classic"]], ['', ["classic"]], ['', ["classic"]], ['', ["module"]], // Only the JavaScript MIME check strips whitespace; `module` must match. ['', []], ['', []], ["", ["classic"]], // A src attribute, even an empty one, means the browser ignores the body. ['', []], ['', []], ["", []], ['', []], ['', []], ['', []], ['', []], ['', []], ['', []], ["", []], ["", []], ["", []], ])("classifies inline JavaScript in %s", (text, expected) => { expect( htmlArtifactReferences(text).inlineScripts.map( ({ scriptType }) => scriptType, ), ).toEqual(expected); }); it("retains exact inline script body coordinates, including unclosed scripts", () => { const prefix = "\n

after

`; expect(htmlArtifactReferences(closed).inlineScripts).toEqual([ { scriptType: "classic", location: { start: { line: 2, column: 8 }, end: { line: 4, column: 0 } }, }, ]); const unclosed = `${prefix}${body}`; expect(htmlArtifactReferences(unclosed).inlineScripts).toEqual([ { scriptType: "classic", location: { start: { line: 2, column: 8 }, end: { line: 4, column: 0 } }, }, ]); }); it("counts every inline body but retains bounded locations", () => { const count = 150_000; const text = "".repeat(count); const { inlineScripts, inlineScriptCount } = htmlArtifactReferences(text); expect(inlineScriptCount).toBe(count); expect(inlineScripts).toHaveLength(HTML_INLINE_SCRIPT_LOCATION_LIMIT); const column = 18 * (HTML_INLINE_SCRIPT_LOCATION_LIMIT - 1) + 8; expect(inlineScripts.at(-1)).toEqual({ scriptType: "classic", location: { start: { line: 1, column }, end: { line: 1, column: column + 1 }, }, }); }); it.each([ ['type=" Text/JavaScript "', "classic"], ['type="MODULE"', "module"], ['type="application/json"', null], ['type="importmap"', null], ['type="speculationrules"', null], ['language="vbscript"', null], ['type=" module "', null], ])( "retains external src with parsed JavaScript type for %s", (attributes, scriptType) => { expect( htmlArtifactReferences(``) .scripts, ).toMatchObject([{ scriptPath: "source.js", scriptType }]); }, );