mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
85 lines
3.4 KiB
JavaScript
85 lines
3.4 KiB
JavaScript
|
|
// Test that single-byte encodings mappings are correct and match spec
|
||
|
|
// Works without Intl
|
||
|
|
|
||
|
|
// From: https://github.com/ExodusOSS/bytes/blob/master/tests/single-byte.test.js
|
||
|
|
// Copyright Exodus Movement. Licensed under MIT License.
|
||
|
|
|
||
|
|
import '../common/index.mjs';
|
||
|
|
import { readFileSync } from 'node:fs';
|
||
|
|
import { join } from 'node:path';
|
||
|
|
import { test, describe } from 'node:test';
|
||
|
|
import raw from '../fixtures/encoding/encodings.json' with { type: 'json' };
|
||
|
|
|
||
|
|
const groups = new Map(raw.map((x) => [x.heading, x.encodings.map((x) => x.name.toLowerCase())]));
|
||
|
|
const encodings = groups.get('Legacy single-byte encodings');
|
||
|
|
|
||
|
|
describe('single-byte encodings are supersets of ascii', () => {
|
||
|
|
for (const encoding of encodings) {
|
||
|
|
test(encoding, (t) => {
|
||
|
|
const loose = new TextDecoder(encoding);
|
||
|
|
const fatal = new TextDecoder(encoding, { fatal: true });
|
||
|
|
for (let i = 0; i < 128; i++) {
|
||
|
|
const str = String.fromCodePoint(i);
|
||
|
|
t.assert.strictEqual(loose.decode(Uint8Array.of(i)), str, i);
|
||
|
|
t.assert.strictEqual(fatal.decode(Uint8Array.of(i)), str, i);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('single-byte encodings index', () => {
|
||
|
|
for (const encoding of encodings) {
|
||
|
|
test(encoding, (t) => {
|
||
|
|
const loose = new TextDecoder(encoding);
|
||
|
|
const fatal = new TextDecoder(encoding, { fatal: true });
|
||
|
|
const file = encoding === 'iso-8859-8-i' ? `index-iso-8859-8.txt` : `index-${encoding}.txt`;
|
||
|
|
const text = readFileSync(join(import.meta.dirname, '../fixtures/encoding/single-byte', file), 'utf8');
|
||
|
|
const rows = text
|
||
|
|
.split('\n')
|
||
|
|
.map((x) => x.trim())
|
||
|
|
.filter((x) => x && x[0] !== '#')
|
||
|
|
.map((x) => x.split('\t'))
|
||
|
|
.map(([istr, codeHex, description]) => {
|
||
|
|
const i = Number(istr);
|
||
|
|
t.assert.ok(i < 128);
|
||
|
|
const code = parseInt(codeHex.slice(2), 16);
|
||
|
|
t.assert.strictEqual(`${i}`, istr);
|
||
|
|
t.assert.strictEqual('0x' + code.toString(16).padStart(4, '0').toUpperCase(), codeHex);
|
||
|
|
t.assert.ok(code && code !== 0xff_fd && code <= 0xff_ff); // Can't be a replacement char, has to be <= 16-bit
|
||
|
|
t.assert.ok(code < 0xd8_00 || code >= 0xe0_00); // not a surrogate
|
||
|
|
return [i, { i, code, description }];
|
||
|
|
});
|
||
|
|
|
||
|
|
t.assert.ok(rows.length <= 128);
|
||
|
|
const known = new Map(rows);
|
||
|
|
t.assert.strictEqual(rows.length, known.size); // all unique
|
||
|
|
|
||
|
|
for (let i = 0; i < 128; i++) {
|
||
|
|
const row = known.get(i);
|
||
|
|
const byte = i + 128;
|
||
|
|
if (row) {
|
||
|
|
t.assert.strictEqual(i, row.i);
|
||
|
|
const str = String.fromCodePoint(row.code);
|
||
|
|
t.assert.strictEqual(fatal.decode(Uint8Array.of(byte)), str, row.description);
|
||
|
|
t.assert.strictEqual(loose.decode(Uint8Array.of(byte)), str, row.description);
|
||
|
|
} else {
|
||
|
|
t.assert.throws(() => fatal.decode(Uint8Array.of(byte)), TypeError);
|
||
|
|
t.assert.strictEqual(loose.decode(Uint8Array.of(byte)), '\uFFFD');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// https://encoding.spec.whatwg.org/#x-user-defined-decoder
|
||
|
|
test('x-user-defined', (t) => {
|
||
|
|
const encoding = 'x-user-defined';
|
||
|
|
const loose = new TextDecoder(encoding);
|
||
|
|
const fatal = new TextDecoder(encoding, { fatal: true });
|
||
|
|
for (let byte = 0; byte < 256; byte++) {
|
||
|
|
const str = String.fromCodePoint(byte >= 0x80 ? 0xF780 + byte - 0x80 : byte);
|
||
|
|
t.assert.strictEqual(fatal.decode(Uint8Array.of(byte)), str, byte);
|
||
|
|
t.assert.strictEqual(loose.decode(Uint8Array.of(byte)), str, byte);
|
||
|
|
}
|
||
|
|
});
|