feedback5 WAD: language packs are the first type of content packs — a language is a file in a language folder (public/i18n/<code>.json, optional data/i18n/<code>.json) or a pack folder (packs/<id>/pack.json); the server lists them live at /packs/index.json (server/packs.js), the menu shows every pack, strings fall back pack → base → declared fallback (English) → Chinese, broken placeholders are skipped, plurals follow Intl.PluralRules (English unchanged), English carries a _meta manifest like any pack; tools: i18n.mjs template / check <code>, packs.mjs list / index, build-i18n --lang ja|ko|zh-TW (the official JP / KR / TW clients); the release zip ships packs/ and a generated packs/index.json; golden unchanged
This commit is contained in:
1 parent
f1df0d359d
commit
25b2a87b26
22 files changed
+2222
-241
No files matched your search
@@ -261,6 +261,43 @@ test('a --no-install build of the temporary checkout zips exactly the plan in on
|
||||
}
|
||||
});
|
||||
|
||||
test('content packs ship: every committed pack of both layouts, never one only on this machine; the stage gets packs/index.json listing exactly them', { skip: !hasZipTool && 'no zip / tar' }, () => {
|
||||
const { dir, put } = fakeCheckout();
|
||||
const out = fs.mkdtempSync(path.join(os.tmpdir(), 'sp-package-out-'));
|
||||
const git = (...args) => spawnSync('git', ['-C', dir, ...args], { encoding: 'utf8' });
|
||||
try {
|
||||
const PACK_FILES = ['public/i18n/en.json', 'public/i18n/qaa.json', 'data/i18n/qaa.json', 'packs/README.md', 'packs/qab/pack.json', 'packs/qab/ui.json'];
|
||||
put('public/i18n/en.json', JSON.stringify({ _meta: { name: 'English', complete: true }, 开始: 'Start' }));
|
||||
put('public/i18n/qaa.json', JSON.stringify({ _meta: { name: 'Qaa', fallback: ['en'] }, 开始: 'Los' }));
|
||||
put('data/i18n/qaa.json', JSON.stringify({ version: 1, lang: 'qaa', names: {}, files: {} }));
|
||||
put('packs/README.md', '# packs\n');
|
||||
put('packs/qab/pack.json', JSON.stringify({ type: 'lang', lang: 'qab', name: 'Qab', files: { ui: 'ui.json' } }));
|
||||
put('packs/qab/ui.json', JSON.stringify({ 开始: 'Q' }));
|
||||
assert.equal(git('add', ...PACK_FILES).status, 0);
|
||||
// installed here, never committed: stays out; a stale index on disk is never shipped as it is
|
||||
put('packs/local/pack.json', JSON.stringify({ type: 'lang', lang: 'qac', files: { ui: 'ui.json' } }));
|
||||
put('packs/local/ui.json', JSON.stringify({ 开始: 'L' }));
|
||||
put('packs/index.json', '{ "stale": true }\n');
|
||||
const dry = runTool(['--root', dir, '--dry-run', '--list', '--lite', '--allow-dirty']);
|
||||
assert.equal(dry.status, 0, dry.stdout + dry.stderr);
|
||||
assert.deepEqual(listed(dry.stdout).sort(), [...SHIPPED_TRACKED, ...PACK_FILES, 'packs/index.json'].sort());
|
||||
assert.match(dry.stdout, /^generated: packs\/index\.json \(the pack index of the shipped packs, for a static host\)$/m);
|
||||
const r = runTool(['--root', dir, '--out', out, '--no-install', '--allow-dirty', '--lite', '--keep-stage']);
|
||||
assert.equal(r.status, 0, r.stdout + r.stderr);
|
||||
const stage = path.join(out, `${FOLDER}-v9.9.9-lite`, FOLDER);
|
||||
const index = JSON.parse(fs.readFileSync(path.join(stage, 'packs/index.json'), 'utf8'));
|
||||
assert.deepEqual(index.packs.map((x) => [x.id, x.type, x.files]), [
|
||||
['en', 'lang', { ui: '/i18n/en.json' }],
|
||||
['qaa', 'lang', { ui: '/i18n/qaa.json', data: '/data/i18n/qaa.json' }],
|
||||
['qab', 'lang', { ui: '/packs/qab/ui.json' }],
|
||||
]);
|
||||
assert.ok(!fs.existsSync(path.join(stage, 'packs/local')), 'a pack only on this machine is not in the zip');
|
||||
} finally {
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
fs.rmSync(out, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('the personal scan reads bytes, never reports the matched text, and skips files it cannot read', () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'sp-package-scan-'));
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user