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: ''}), 'センサー接続エラー: '); 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;});