51 lines
2.8 KiB
JavaScript
51 lines
2.8 KiB
JavaScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdtemp, writeFile, readFile, rm, access } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { createConverter, runProcess } from './native-office.mjs';
|
|
import { patchOffice, target } from './install-office-preview.mjs';
|
|
|
|
test('patch is exact, version gated and refuses repeat application', () => {
|
|
const patched = patchOffice(target, '0.2.0-rc.2', '0.2.0-rc.2');
|
|
assert.match(patched, /dsh-native-office/);
|
|
for (const source of ['', target + target, patched]) assert.throws(() => patchOffice(source, '0.2.0-rc.2', '0.2.0-rc.2'));
|
|
assert.throws(() => patchOffice(target, 'next', '0.2.0-rc.2'));
|
|
assert.throws(() => patchOffice(target, '0.2.0-rc.2', 'next'));
|
|
});
|
|
|
|
test('process cancellation, missing binary and failure are classified', async () => {
|
|
const signal = new AbortController().signal;
|
|
await assert.rejects(runProcess('/not-an-office-binary', [], signal), { code: 'unavailable' });
|
|
await assert.rejects(runProcess(process.execPath, ['-e', 'process.exit(2)'], signal), { code: 'invalid-document' });
|
|
const controller = new AbortController();
|
|
const reason = new Error('cancel test');
|
|
const pending = runProcess(process.execPath, ['-e', 'setInterval(() => {}, 1000)'], controller.signal);
|
|
controller.abort(reason);
|
|
await assert.rejects(pending, error => error === reason);
|
|
});
|
|
|
|
test('input bounds, corruption, exclusive output, abort and disposal', async () => {
|
|
const directory = await mkdtemp(join(tmpdir(), 'office-test-'));
|
|
const inputPath = join(directory, 'source.docx');
|
|
const outputPath = join(directory, 'output.pdf');
|
|
const converter = await createConverter();
|
|
try {
|
|
await writeFile(inputPath, 'invalid');
|
|
await assert.rejects(converter.render({ inputPath, outputPath }), { code: 'invalid-document' });
|
|
await assert.rejects(access(outputPath));
|
|
const small = await createConverter({ maxInputBytes: 1 });
|
|
await assert.rejects(small.render({ inputPath, outputPath }), { code: 'input-too-large' });
|
|
await small.dispose();
|
|
await writeFile(outputPath, 'preserve');
|
|
await assert.rejects(converter.render({ inputPath, outputPath }), { code: 'EEXIST' });
|
|
assert.equal(await readFile(outputPath, 'utf8'), 'preserve');
|
|
const controller = new AbortController();
|
|
controller.abort(new Error('cancelled'));
|
|
await assert.rejects(converter.render({ inputPath, outputPath }, controller.signal), /cancelled/);
|
|
await converter.dispose();
|
|
await assert.rejects(converter.render({ inputPath, outputPath }), { code: 'unavailable' });
|
|
await assert.rejects(createConverter({ fontDirectories: [] }), { code: 'unavailable' });
|
|
} finally { await converter.dispose(); await rm(directory, { recursive: true, force: true }); }
|
|
});
|