diff --git a/scripts/i18n-icu-contract.test.ts b/scripts/i18n-icu-contract.test.ts index 17f5d4d97..b6baba69d 100644 --- a/scripts/i18n-icu-contract.test.ts +++ b/scripts/i18n-icu-contract.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict' import { test } from 'node:test' -import { contractFromMessage, contractsEqual } from './i18n-icu-contract' +import { contractFromMessage, contractsEqual, sourceContractChanged } from './i18n-icu-contract' test('same plain text contract is equal', () => { assert.equal( @@ -56,3 +56,26 @@ test('select branch changes contract', () => { false, ) }) + +test('invalid previous source message is treated as changed', () => { + assert.equal( + sourceContractChanged( + 'Get support at {support-link}', + 'Get support at ', + 'previous', + 'current', + ), + true, + ) +}) + +test('invalid current source message is rejected', () => { + assert.throws(() => + sourceContractChanged( + 'Get support at ', + 'Get support at {support-link}', + 'previous', + 'current', + ), + ) +}) diff --git a/scripts/i18n-icu-contract.ts b/scripts/i18n-icu-contract.ts index fa961df98..5f6002615 100644 --- a/scripts/i18n-icu-contract.ts +++ b/scripts/i18n-icu-contract.ts @@ -99,6 +99,22 @@ export function contractsEqual(a: Contract, b: Contract) { return JSON.stringify(a) === JSON.stringify(b) } +export function sourceContractChanged( + previousText: string, + currentText: string, + previousLabel: string, + currentLabel: string, +) { + const after = contractFromMessage(currentText, currentLabel) + + try { + const before = contractFromMessage(previousText, previousLabel) + return !contractsEqual(before, after) + } catch { + return true + } +} + async function readJson(file: string): Promise { return JSON.parse(await readFile(file, 'utf8')) as MessageFile } @@ -250,10 +266,14 @@ async function changedSourceIds(baseRef: string, scope?: string) { const currentText = textOf(currentEntry) if (previousText === undefined || currentText === undefined) continue - const before = contractFromMessage(previousText, `${baseRef}:${sourceFile}:${key}`) - const after = contractFromMessage(currentText, `${sourceFile}:${key}`) - - if (!contractsEqual(before, after)) { + if ( + sourceContractChanged( + previousText, + currentText, + `${baseRef}:${sourceFile}:${key}`, + `${sourceFile}:${key}`, + ) + ) { const ids = changed.get(destPath) ?? new Set() ids.add(key) changed.set(destPath, ids)