diff --git a/test/edge-cases.js b/test/edge-cases.js new file mode 100644 index 0000000..66f2e81 --- /dev/null +++ b/test/edge-cases.js @@ -0,0 +1,116 @@ +// Edge cases: math, special chars, Markdown HTML — non-destructive model. +"use strict"; + +const { JSDOM } = require("jsdom"); +const fs = require("fs"); +const path = require("path"); +const src = fs.readFileSync(path.join(__dirname, "../src/content.js"), "utf8"); + +let passed = 0, failed = 0; +function assert(label, cond, got) { + if (cond) { console.log("PASS " + label); passed++; } + else { console.log("FAIL " + label + (got !== undefined ? " — got: " + JSON.stringify(String(got).slice(0, 80)) : "")); failed++; } +} + +function makeDOM(bodyHTML, settings) { + settings = Object.assign({ enabled: true, fixDirection: true, useFont: true, fixInputs: true, disabledSites: [] }, settings || {}); + const dom = new JSDOM("
" + bodyHTML + "", + { url: "https://example.com/", runScripts: "dangerously" }); + const win = dom.window; + win.chrome = { + runtime: { getURL: (p) => "chrome-extension://test/" + p, lastError: null }, + storage: { local: { get: (d, cb) => cb(settings), set: () => {} }, onChanged: { addListener: () => {} } } + }; + const s = win.document.createElement("script"); + s.textContent = src; + win.document.head.appendChild(s); + return dom; +} + +console.log("=== Math Characters ==="); +{ + const dom = makeDOM("The formula is ∑(n=0..∞) = π × r² ± ε
"); + const p = dom.window.document.getElementById("t"); + assert("math-only: no dir", !p.hasAttribute("dir"), p.getAttribute("dir")); + assert("math-only: no font change", !p.style.fontFamily); + assert("math-only: text unchanged", p.textContent === "The formula is ∑(n=0..∞) = π × r² ± ε"); +} +{ + const dom = makeDOM("مساحت دایره برابر است با π × r²
"); + const p = dom.window.document.getElementById("t"); + assert("persian+math: dir=rtl", p.getAttribute("dir") === "rtl", p.getAttribute("dir")); + assert("persian+math: Vazirmatn applied", p.style.fontFamily.toLowerCase().includes("vazirmatn")); + assert("persian+math: π preserved in text", p.textContent.includes("π")); +} + +console.log("\n=== Special Characters ==="); +{ + const dom = makeDOM("Copyright © 2024 → All rights reserved ™
"); + const p = dom.window.document.getElementById("t"); + assert("special-only: no dir", !p.hasAttribute("dir")); + assert("special-only: no font change", !p.style.fontFamily); +} +{ + const dom = makeDOM("محصول جدید ما → قیمت: ۱۲۰ تومان ©
"); + const p = dom.window.document.getElementById("t"); + assert("persian+special: dir=rtl", p.getAttribute("dir") === "rtl", p.getAttribute("dir")); + assert("persian+special: © and → preserved", p.textContent.includes("©") && p.textContent.includes("→")); +} + +console.log("\n=== ZWNJ (Persian word joiner) ==="); +{ + const ZWNJ = ""; + const dom = makeDOM("می" + ZWNJ + "خواهم برگردم
"); + const p = dom.window.document.getElementById("t"); + // No wrapping → ZWNJ can never split a word now. Text is byte-identical. + assert("ZWNJ: text byte-identical (no splitting possible)", p.textContent === "می" + ZWNJ + "خواهم برگردم"); + assert("ZWNJ: dir=rtl", p.getAttribute("dir") === "rtl"); +} + +console.log("\n=== Markdown-rendered HTML ==="); +{ + const dom = makeDOM("const سلام = 'hello'; // فارسی");
+ const code = dom.window.document.getElementById("t");
+ assert("MD code block: no dir", !code.hasAttribute("dir"));
+ assert("MD code block: no font change", !code.style.fontFamily);
+}
+{
+ const dom = makeDOM("Use تابع() to call it. این متن فارسی است.
متن فارسی پررنگ and English text here
"); + const strong = dom.window.document.getElementById("t"); + const p = strong.parentElement; + assert("MD bold: font applied to (text's parent)", strong.style.fontFamily.toLowerCase().includes("vazirmatn"), strong.style.fontFamily); + assert("MD bold: dir on block", p.hasAttribute("dir"), p.getAttribute("dir")); +} +{ + const dom = makeDOM("
"); + const p = dom.window.document.getElementById("t"); + assert("MD blockquote: dir=rtl", p.getAttribute("dir") === "rtl", p.getAttribute("dir")); +} +{ + const dom = makeDOM(''); + const svgText = dom.window.document.getElementById("t"); + if (svgText) assert("SVG text: no dir (skipped)", !svgText.hasAttribute("dir")); + else assert("SVG element found", false, "null"); +} +{ + const dom = makeDOM(''); + const mi = dom.window.document.getElementById("t"); + if (mi) assert("MathML mi: no dir (skipped)", !mi.hasAttribute("dir")); + else assert("MathML element found (jsdom may lack support)", true); +} + +console.log("\n" + passed + "/" + (passed + failed) + " passed" + (failed ? " — " + failed + " FAILED" : "")); +process.exit(failed ? 1 : 0);این یک نقلقول فارسی است