#!/bin/bash set -euo pipefail source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" run_node_test <<'JS' const fs = require('fs') const vm = require('vm') const source = fs.readFileSync(path.join(root, 'shell/Commons/I18nZh.js'), 'utf8').replace('.pragma library', '') const context = {} vm.runInNewContext(source + '\nthis.table = table; this.templates = templates', context) const table = context.table const files = [] const walk = dir => { for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { const full = path.join(dir, entry.name) if (entry.isDirectory()) walk(full) else if (/\.(qml|js)$/.test(entry.name)) files.push(full) } } walk(path.join(root, 'shell')) const missing = [] let calls = 0 for (const file of files) { const text = fs.readFileSync(file, 'utf8') for (const list of text.matchAll(/I18n\.trMatch\([^\[]*\[([^\]]*)\]/g)) { for (const item of list[1].matchAll(/"((?:[^"\\]|\\.)*)"/g)) { const key = JSON.parse('"' + item[1] + '"') if (!(key in table)) missing.push(`${path.relative(root, file)}: ${key}`) } } for (const match of text.matchAll(/I18n\.tr\(\s*"((?:[^"\\]|\\.)*)"/g)) { calls++ const key = JSON.parse('"' + match[1] + '"') if (!(key in table)) missing.push(`${path.relative(root, file)}: ${key}`) } } assert(calls > 300, 'the shell routes its text through I18n.tr', `found ${calls} calls`) const missingTemplates = Array.from(context.templates).filter(t => !(t in table)) assert(missingTemplates.length === 0, 'every message template has a Chinese entry', missingTemplates.join('\n')) assert(missing.length === 0, 'every I18n.tr text has a Chinese entry', missing.join('\n')) const placeholders = s => (s.match(/%\d/g) || []).sort().join(',') const mismatched = Object.keys(table).filter(key => placeholders(key) !== placeholders(table[key])) assert(mismatched.length === 0, 'every Chinese entry keeps its English placeholders', mismatched.join('\n')) JS