fix(runtime): support PDF preview on Chrome 143
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { runInNewContext } from 'node:vm';
|
||||
import { compat, patchPdf, workerTarget, marker } from './install-pdf-compat.mjs';
|
||||
|
||||
function run(code) {
|
||||
return runInNewContext('delete Math.sumPrecise; delete Map.prototype.getOrInsert; delete Map.prototype.getOrInsertComputed;\n' + compat + '\n' + code);
|
||||
}
|
||||
test('precise summation handles cancellation, rounding, overflow, subnormals and special values', () => {
|
||||
assert.equal(run('Math.sumPrecise([1e20, 1, -1e20])'), 1);
|
||||
assert.equal(run('Math.sumPrecise([Number.MAX_VALUE, Number.MAX_VALUE, -Number.MAX_VALUE])'), Number.MAX_VALUE);
|
||||
assert.equal(run('Math.sumPrecise([Number.MAX_VALUE, Number.MAX_VALUE])'), Infinity);
|
||||
assert.equal(run('Math.sumPrecise([Number.MIN_VALUE, Number.MIN_VALUE])'), 2 * Number.MIN_VALUE);
|
||||
assert.equal(run('Math.sumPrecise([1, 2 ** -53])'), 1);
|
||||
assert.equal(run('Math.sumPrecise([1, 2 ** -53, 2 ** -54])'), 1 + Number.EPSILON);
|
||||
assert.ok(Object.is(run('Math.sumPrecise([])'), -0));
|
||||
assert.ok(Object.is(run('Math.sumPrecise([-0])'), -0));
|
||||
assert.ok(Object.is(run('Math.sumPrecise([-1, 1])'), 0));
|
||||
assert.ok(Number.isNaN(run('Math.sumPrecise([Infinity, -Infinity])')));
|
||||
assert.throws(() => run('Math.sumPrecise([Infinity, "1"])'), /numbers/);
|
||||
});
|
||||
test('computed insertion caches undefined and promises without recomputation', () => {
|
||||
assert.equal(run('const m = new Map(); let n = 0; m.getOrInsertComputed("x", () => { n++; }); m.getOrInsertComputed("x", () => { n++; }); n'), 1);
|
||||
assert.equal(run('const m = new Map(); const p = Promise.resolve(1); m.getOrInsertComputed("x", () => p) === m.getOrInsertComputed("x", () => 2)'), true);
|
||||
});
|
||||
test('callback validation, errors, receiver, key normalization and reentrancy', () => {
|
||||
assert.throws(() => run('new Map([[1, 2]]).getOrInsertComputed(1, null)'), /callable/);
|
||||
assert.throws(() => run('Map.prototype.getOrInsertComputed.call({}, 1, () => 2)'), /incompatible receiver/);
|
||||
assert.equal(run('new Map().getOrInsertComputed(-0, k => Object.is(k, 0))'), true);
|
||||
assert.equal(run('const m = new Map(); m.getOrInsertComputed(1, k => { m.set(k, 2); return 3; }); m.get(1)'), 3);
|
||||
assert.equal(run('const m = new Map(); try { m.getOrInsertComputed(1, () => { throw Error(); }); } catch {} m.size'), 0);
|
||||
assert.equal(run('new Map([[NaN, 4]]).getOrInsertComputed(NaN, () => 5)'), 4);
|
||||
});
|
||||
test('plain insertion and non-enumerable, repeat-safe methods', () => {
|
||||
assert.equal(run('const m = new Map([[1, undefined]]); m.getOrInsert(1, 2) === undefined && m.getOrInsert(2, 3) === 3'), true);
|
||||
assert.equal(run('Object.getOwnPropertyDescriptor(Map.prototype, "getOrInsertComputed").enumerable'), false);
|
||||
assert.equal(runInNewContext('Map.prototype.getOrInsertComputed = () => 42;\n' + compat + '\nnew Map().getOrInsertComputed()'), 42);
|
||||
});
|
||||
test('patch guards and worker injection', () => {
|
||||
const source = 'this.#methodPromises.getOrInsertComputed(name, f); ' + workerTarget + ' tail]);';
|
||||
const patched = patchPdf(source, '0.2.1-rc.2', '0.2.1-rc.2');
|
||||
assert.ok(patched.startsWith(marker + '\n' + compat));
|
||||
assert.ok(patched.includes('new Blob([' + JSON.stringify(compat) + ', _dsh_pdf_worker_default,'));
|
||||
assert.throws(() => patchPdf(patched, '0.2.1-rc.2', '0.2.1-rc.2'), /already/);
|
||||
assert.throws(() => patchPdf(source, 'other', '0.2.1-rc.2'), /version/);
|
||||
for (const bad of ['', source + workerTarget]) assert.throws(() => patchPdf(bad, '0.2.1-rc.2', '0.2.1-rc.2'), /unexpected/);
|
||||
});
|
||||
Reference in New Issue
Block a user