Files
arsam 11e152cc4b Import tests: test/edge-cases
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
2026-09-18 23:07:31 +03:30

117 lines
5.6 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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("<!DOCTYPE html><html><body>" + bodyHTML + "</body></html>",
{ 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("<p id='t'>The formula is ∑(n=0..∞) = π × r² ± ε</p>");
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("<p id='t'>مساحت دایره برابر است با π × r²</p>");
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("<p id='t'>Copyright © 2024 → All rights reserved ™</p>");
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("<p id='t'>محصول جدید ما → قیمت: ۱۲۰ تومان ©</p>");
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("<p id='t'>می" + ZWNJ + "خواهم برگردم</p>");
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("<pre><code id='t'>const سلام = 'hello'; // فارسی</code></pre>");
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("<p id='t'>Use <code id='c'>تابع()</code> to call it. این متن فارسی است.</p>");
const p = dom.window.document.getElementById("t");
const code = dom.window.document.getElementById("c");
assert("inline code: code element no font change", !code.style.fontFamily);
assert("inline code: English-leading mixed block dir=auto", p.getAttribute("dir") === "auto", p.getAttribute("dir"));
}
{
const dom = makeDOM("<p><strong id='t'>متن فارسی پررنگ</strong> and English text here</p>");
const strong = dom.window.document.getElementById("t");
const p = strong.parentElement;
assert("MD bold: font applied to <strong> (text's parent)", strong.style.fontFamily.toLowerCase().includes("vazirmatn"), strong.style.fontFamily);
assert("MD bold: dir on block <p>", p.hasAttribute("dir"), p.getAttribute("dir"));
}
{
const dom = makeDOM("<h1 id='t'>راهنمای استفاده</h1>");
const h1 = dom.window.document.getElementById("t");
assert("MD heading: dir=rtl", h1.getAttribute("dir") === "rtl", h1.getAttribute("dir"));
assert("MD heading: Vazirmatn applied", h1.style.fontFamily.toLowerCase().includes("vazirmatn"));
}
{
const dom = makeDOM("<blockquote><p id='t'>این یک نقل‌قول فارسی است</p></blockquote>");
const p = dom.window.document.getElementById("t");
assert("MD blockquote: dir=rtl", p.getAttribute("dir") === "rtl", p.getAttribute("dir"));
}
{
const dom = makeDOM('<svg xmlns="http://www.w3.org/2000/svg"><text id="t">متن فارسی</text></svg>');
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('<math xmlns="http://www.w3.org/1998/Math/MathML"><mi id="t">متغیر</mi></math>');
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);