feat: 集成漫画源并支持在线阅读
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const zip = require('../zip');
|
||||
|
||||
test('writeZip/readZip: 基本往返,文本与二进制内容不失真', () => {
|
||||
const entries = [
|
||||
{ name: 'mimetype', data: Buffer.from('application/epub+zip') },
|
||||
{ name: 'a/b.txt', data: Buffer.from('hello 你好', 'utf8') },
|
||||
{ name: 'c.bin', data: Buffer.from([0, 1, 2, 255, 254, 128]) }
|
||||
];
|
||||
const buf = zip.writeZip(entries);
|
||||
const parsed = zip.readZip(buf);
|
||||
assert.deepStrictEqual([...parsed.keys()], ['mimetype', 'a/b.txt', 'c.bin']);
|
||||
assert.strictEqual(parsed.get('a/b.txt').toString('utf8'), 'hello 你好');
|
||||
assert.deepStrictEqual([...parsed.get('c.bin')], [0, 1, 2, 255, 254, 128]);
|
||||
});
|
||||
|
||||
test('writeZip/readZip: 大文件(跨多个 chunk)内容比特级一致', () => {
|
||||
const big = Buffer.alloc(500000);
|
||||
for (let i = 0; i < big.length; i++) big[i] = i % 256;
|
||||
const buf = zip.writeZip([{ name: 'big.bin', data: big }]);
|
||||
const parsed = zip.readZip(buf);
|
||||
assert.strictEqual(Buffer.compare(parsed.get('big.bin'), big), 0);
|
||||
});
|
||||
|
||||
test('readZip: 能解析第三方(JSZip)产出的 DEFLATE 压缩包', async () => {
|
||||
const JSZip = require('../ui/vendor/jszip.min.js');
|
||||
const jz = new JSZip();
|
||||
jz.file('x.txt', 'DEFLATE 测试内容');
|
||||
const buf = await jz.generateAsync({ type: 'nodebuffer', compression: 'DEFLATE' });
|
||||
const parsed = zip.readZip(buf);
|
||||
assert.strictEqual(parsed.get('x.txt').toString('utf8'), 'DEFLATE 测试内容');
|
||||
});
|
||||
|
||||
test('writeZip: 产出的包能被第三方(JSZip)正确打开', async () => {
|
||||
const JSZip = require('../ui/vendor/jszip.min.js');
|
||||
const buf = zip.writeZip([
|
||||
{ name: 'mimetype', data: Buffer.from('application/epub+zip') },
|
||||
{ name: 'nested/dir/file.txt', data: Buffer.from('nested content') }
|
||||
]);
|
||||
const jz = await JSZip.loadAsync(buf);
|
||||
assert.ok(jz.file('mimetype'));
|
||||
const text = await jz.file('nested/dir/file.txt').async('string');
|
||||
assert.strictEqual(text, 'nested content');
|
||||
});
|
||||
|
||||
test('readZip: 空 ZIP(EOCD 但无条目)不抛错,返回空 Map', () => {
|
||||
const buf = zip.writeZip([]);
|
||||
const parsed = zip.readZip(buf);
|
||||
assert.strictEqual(parsed.size, 0);
|
||||
});
|
||||
|
||||
test('readZip: 非 ZIP 数据抛出可读错误而不是崩溃', () => {
|
||||
assert.throws(() => zip.readZip(Buffer.from('not a zip file')), /不是有效的 ZIP 文件/);
|
||||
});
|
||||
|
||||
test('readZip: 不把未知压缩方式误当作 STORE 内容', () => {
|
||||
const buf = zip.writeZip([{ name: 'x.bin', data: Buffer.from([1, 2, 3]) }]);
|
||||
const central = buf.indexOf(Buffer.from([0x50, 0x4b, 0x01, 0x02]));
|
||||
buf.writeUInt16LE(99, central + 10);
|
||||
assert.throws(() => zip.readZip(buf), /压缩方式不受支持/);
|
||||
});
|
||||
|
||||
test('readZip: 条目内容损坏时通过 CRC 拒绝继续读取', () => {
|
||||
const buf = zip.writeZip([{ name: 'x.bin', data: Buffer.from([1, 2, 3]) }]);
|
||||
const dataStart = 30 + Buffer.byteLength('x.bin');
|
||||
buf[dataStart] ^= 0xff;
|
||||
assert.throws(() => zip.readZip(buf), /条目校验失败/);
|
||||
});
|
||||
Reference in New Issue
Block a user