52 lines
3.5 KiB
TypeScript
52 lines
3.5 KiB
TypeScript
// `storebound shots copy translate | check | reviewed`: fills copy.json per language with a marker file, caption limits.
|
|
import { describe, expect, test } from 'bun:test';
|
|
import { readFileSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import type { ShipConfig } from '../cli/lib/config';
|
|
import { validateCopy } from '../cli/shots/lib';
|
|
import { applyFields, marksNotes, overLimit, parseMarks, sceneFields } from '../cli/lib/shots-copy-translate';
|
|
import { run } from '../cli/shots/copy';
|
|
import { BASE, capture, project } from './helpers/store-mock';
|
|
|
|
const CFG: ShipConfig = {
|
|
...BASE,
|
|
languages: [{ id: 'en', apple: 'en-US', play: 'en-US' }, { id: 'de', apple: 'de-DE', play: 'de-DE' }],
|
|
shots: { copy: 'store/shots/copy.json', scenes: [{ id: 'home', palette: 'gold', frames: [] }] } as never,
|
|
};
|
|
const COPY = JSON.stringify({ en: { home: { eyebrow: 'Hello', title: ['Everything', 'in order'], sub: 'Lists and notes.' } } });
|
|
const go = async (p: ReturnType<typeof project>, argv: string[]) => { const r = await capture(() => run(p.ctx(argv))); return r; };
|
|
|
|
describe('shots copy translate', () => {
|
|
test('without a hook the source is copied in as status=translate; the missing-locale problem names the command', async () => {
|
|
const p = project(CFG, { 'store/shots/copy.json': COPY });
|
|
expect(validateCopy(JSON.parse(COPY), CFG.shots!, ['en', 'de'])[0]).toContain('storebound shots copy translate --to de');
|
|
await go(p, ['translate', '--to', 'de']);
|
|
const copy = JSON.parse(readFileSync(join(p.root, 'store/shots/copy.json'), 'utf8'));
|
|
expect(copy.de.home.title).toEqual(['Everything', 'in order']);
|
|
const marks = parseMarks(readFileSync(join(p.root, 'store/shots/copy.translations.json'), 'utf8'));
|
|
expect(marks.de).toEqual({ from: 'en', status: 'translate' });
|
|
expect(marksNotes(marks, 'copy')[0]).toContain('not translated yet');
|
|
expect(validateCopy(copy, CFG.shots!, ['en', 'de'])).toEqual([]);
|
|
});
|
|
test('with a hook: draft; an over-limit field keeps the source and the language stays translate; reviewed refuses translate', async () => {
|
|
const p = project(CFG, { 'store/shots/copy.json': COPY });
|
|
await go(p, ['translate', '--to', 'de', '--translate', 'tr a-z A-Z']);
|
|
let copy = JSON.parse(readFileSync(join(p.root, 'store/shots/copy.json'), 'utf8'));
|
|
expect(copy.de.home.eyebrow).toBe('HELLO');
|
|
expect(parseMarks(readFileSync(join(p.root, 'store/shots/copy.translations.json'), 'utf8')).de!.status).toBe('draft');
|
|
const r = await go(p, ['reviewed', '--lang', 'de']);
|
|
expect(r.exit).toBeFalsy();
|
|
expect(readFileSync(join(p.root, 'store/shots/copy.translations.json'), 'utf8').trim()).toBe('{}');
|
|
const q = project(CFG, { 'store/shots/copy.json': COPY });
|
|
await go(q, ['translate', '--to', 'de', '--translate', 'echo xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx']);
|
|
copy = JSON.parse(readFileSync(join(q.root, 'store/shots/copy.json'), 'utf8'));
|
|
expect(copy.de.home.title[0]).toBe('Everything');
|
|
expect(parseMarks(readFileSync(join(q.root, 'store/shots/copy.translations.json'), 'utf8')).de!.status).toBe('translate');
|
|
});
|
|
test('helpers: fields, limits', () => {
|
|
const sc = JSON.parse(COPY).en.home;
|
|
expect(sceneFields(sc).map(f => f.key)).toEqual(['eyebrow', 'title.0', 'title.1', 'sub']);
|
|
expect(applyFields(sc, { sub: 'x' }).sub).toBe('x');
|
|
expect(overLimit({ home: { title: ['a'.repeat(40), 'b'] } })[0]).toMatchObject({ field: 'title.0', limit: 28 });
|
|
});
|
|
});
|