tests/i18n.test.cjs
raw · 2648 bytes
const assert = require('assert').strict;
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const assets = path.resolve(__dirname, '../app/src/main/assets/reader');
const config = JSON.parse(fs.readFileSync(path.join(assets, 'langpacks/config.json')));
const packs = Object.fromEntries(Object.keys(config.supportedLanguages).map(code =>
[code, JSON.parse(fs.readFileSync(path.join(assets, `langpacks/${code}.json`)))]));
const source = fs.readFileSync(path.join(assets, 'i18n.js'), 'utf8');
const content = fs.readFileSync(path.join(assets, 'content.js'), 'utf8');
const native = fs.readFileSync(path.join(assets, '../../java/net/astropenguin/naroureader/MainActivity.java'), 'utf8');
for (const pack of Object.values(packs)) {
assert.deepEqual(Object.keys(pack).sort(), Object.keys(packs.en).sort());
for (const match of content.matchAll(/'@([^']+)'/g)) assert.equal(typeof pack[match[1]], 'string', match[1]);
for (const match of native.matchAll(/tr\("([^"]+)"\)/g)) assert.equal(typeof pack[match[1]], 'string', match[1]);
}
async function load(saved, broken = false, partial = false) {
const requests = [];
const scope = {
console: {warn() {}},
browser: {runtime: {getURL: file => file}, storage: {local: {get: async () => ({narouTategaki: {language: saved}})}}},
fetch: async file => {
requests.push(file);
const code = path.basename(file, '.json');
if (broken && code === 'ja') throw new Error('missing pack');
return {ok: true, json: async () => code === 'config' ? config : partial && code === 'ja' ? {font: '文字'} : packs[code]};
}
};
vm.createContext(scope); vm.runInContext(source, scope);
return {api: await scope.NarouI18n.create(), requests};
}
(async () => {
let {api, requests} = await load('ja');
assert.equal(api.language, 'ja'); assert.equal(api.text('font'), '文字');
assert.equal(api.text('sensor.error', {detail: '<unsafe>'}), 'センサー接続エラー: <unsafe>');
await api.setLanguage('en'); assert.equal(api.text('font'), 'Font');
assert(requests.every(file => /^langpacks\/(config|en|ja)\.json$/.test(file)));
({api, requests} = await load('../../remote'));
assert.equal(api.language, 'en'); assert(!requests.some(file => file.includes('remote')));
({api} = await load('ja', true)); assert.equal(api.language, 'en');
({api} = await load('ja', false, true)); assert.equal(api.text('theme'), 'Theme');
console.log('PASS: pack parity, native/reader keys, saved selection, interpolation, safe paths, failed-pack and missing-key fallback');
})().catch(error => {console.error(error); process.exitCode = 1;});