mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-26 06:34:20 +08:00
- Enforce oxlint and oxfmt for owned JavaScript and TypeScript with independent CI checks. - Preserve compiler import boundaries and protected fixtures while cleaning up lint findings. - Standardize source formatting and validate import, fixture, and embedded-source protections.
87 lines
3.2 KiB
TypeScript
87 lines
3.2 KiB
TypeScript
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { expect, test } from "vitest";
|
|
import { analyze } from "../src/index.js";
|
|
|
|
test.each([
|
|
[
|
|
"constructor reads this",
|
|
"function Make() { console.log(this); return { value: 1 }; } new Make();",
|
|
],
|
|
[
|
|
"constructor arrow captures this",
|
|
"function Make() { return { read: () => this }; } new Make();",
|
|
],
|
|
[
|
|
"constructor default reads this",
|
|
"function Make({value = this} = {}) { return { value }; } new Make();",
|
|
],
|
|
[
|
|
"constructor reads new.target",
|
|
"function Make() { console.log(new.target); return { value: 1 }; } new Make();",
|
|
],
|
|
[
|
|
"constructor returns a primitive on one branch",
|
|
"function Make(flag) { if (flag) return 1; return { value: 1 }; } new Make(true);",
|
|
],
|
|
[
|
|
"constructor binding reassigned",
|
|
"function Make() { return { value: 1 }; } Make = function () { return { value: 2 }; }; console.log(new Make().value);",
|
|
],
|
|
] as const)("object-returning constructor retains the fence when %s", (_name, source) => {
|
|
const dir = mkdtempSync("/tmp/scriptc-constructor-boundary-");
|
|
try {
|
|
const entry = join(dir, "main.mjs");
|
|
writeFileSync(entry, source);
|
|
const { coverage } = analyze(entry);
|
|
expect([...coverage.diagnostics, ...(coverage.runtimeFences ?? [])].length).toBeGreaterThan(0);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
test.each([
|
|
[
|
|
"detached method",
|
|
"class C { static value = 1; static read(): number { return this.value; } } const read = C.read; console.log(read());",
|
|
],
|
|
[
|
|
"polymorphic receiver",
|
|
"class C { static read(): string { return this.name; } } class D extends C {} function run(value: typeof C): string { return value.read(); } console.log(run(D));",
|
|
],
|
|
[
|
|
"inherited private field",
|
|
"class C { static #value = 1; static read(): number { return this.#value; } } class D extends C {} console.log(D.read());",
|
|
],
|
|
[
|
|
"shadowed private field",
|
|
"class C { static #value = 1; static read(): number { return this.#value; } } class D extends C { static #value = 2; } console.log(D.read());",
|
|
],
|
|
[
|
|
"inherited private method",
|
|
"class C { static #value(): number { return 1; } static read(): number { return this.#value(); } } class D extends C {} console.log(D.read());",
|
|
],
|
|
[
|
|
"shadowed private method",
|
|
"class C { static #value(): number { return 1; } static read(): number { return this.#value(); } } class D extends C { static #value(): number { return 2; } } console.log(D.read());",
|
|
],
|
|
[
|
|
"inherited static write",
|
|
"class C { static value = 1; static write(): void { this.value = 2; } } class D extends C {} D.write();",
|
|
],
|
|
] as const)("receiver specialization preserves the %s boundary", (_name, source) => {
|
|
const dir = mkdtempSync("/tmp/scriptc-static-boundary-");
|
|
try {
|
|
const entry = join(dir, "main.ts");
|
|
writeFileSync(entry, source);
|
|
const { coverage } = analyze(entry);
|
|
expect(coverage.preflightFailed).toBe(false);
|
|
expect(
|
|
coverage.diagnostics.some((d) => d.code === "SC1090"),
|
|
JSON.stringify(coverage.diagnostics),
|
|
).toBe(true);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|