From 4d9ea2db2d1a1768225a074ad58d91da77941ebc Mon Sep 17 00:00:00 2001 From: "Steven R. Loomis" Date: Fri, 28 Feb 2025 14:24:12 -0600 Subject: [PATCH] feat(developer): work around line number symbols - add KeymanXMLReader.removeSymbols() and call it from tests Fixes: #10622 --- developer/src/common/web/utils/src/xml-utils.ts | 11 ++++++++++- .../web/utils/test/kpj/kpj-file-writer.tests.ts | 5 +++-- .../web/utils/test/kps/kps-file-reader.tests.ts | 5 +++-- .../src/common/web/utils/test/kvks/kvks-file.tests.ts | 5 +++-- .../src/common/web/utils/test/xml-utils.tests.ts | 2 +- developer/src/kmc-ldml/test/helpers/compareXml.ts | 2 +- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/developer/src/common/web/utils/src/xml-utils.ts b/developer/src/common/web/utils/src/xml-utils.ts index 6365134db7..98af170790 100644 --- a/developer/src/common/web/utils/src/xml-utils.ts +++ b/developer/src/common/web/utils/src/xml-utils.ts @@ -156,13 +156,22 @@ export class KeymanXMLReader { * @param from source for symbols * @returns the onto object */ - private static copySymbols(onto: T, from: any): T { + public static copySymbols(onto: T, from: any): T { const o = onto as any; for (const sym of Object.getOwnPropertySymbols(from)) { o[sym] = from[sym]; } return onto; } + + /** use Object.entries to remove all symbols */ + public static removeSymbols(from: T): T { + if (Array.isArray(from)) { + return from.map(o => KeymanXMLReader.removeSymbols(o)) as T; + } + if (typeof from !== "object") return from; + return Object.fromEntries(Object.entries(from).map(([k, v]) => ([k, KeymanXMLReader.removeSymbols(v)]))) as T; + } /** move `{ $abc: 4 }` into `{ $: { abc: 4 } }` */ private static fixupDollarAttributes(data: any) : any { diff --git a/developer/src/common/web/utils/test/kpj/kpj-file-writer.tests.ts b/developer/src/common/web/utils/test/kpj/kpj-file-writer.tests.ts index 899527edbb..5fc223b240 100644 --- a/developer/src/common/web/utils/test/kpj/kpj-file-writer.tests.ts +++ b/developer/src/common/web/utils/test/kpj/kpj-file-writer.tests.ts @@ -6,6 +6,7 @@ import { KPJFileReader } from "../../src/types/kpj/kpj-file-reader.js"; import { TestCompilerCallbacks } from '@keymanapp/developer-test-helpers'; import { KPJFileWriter } from '../../src/types/kpj/kpj-file-writer.js'; import { KeymanDeveloperProjectOptions } from '../../src/types/kpj/keyman-developer-project.js'; +import { KeymanXMLReader } from '../../src/xml-utils.js'; const callbacks = new TestCompilerCallbacks(); @@ -21,7 +22,7 @@ describe('kpj-file-writer', function () { const writer = new KPJFileWriter(); const output = writer.write(project); - const outputKpj = reader.read(new TextEncoder().encode(output)); + const outputKpj = KeymanXMLReader.removeSymbols(reader.read(new TextEncoder().encode(output))); // The outputKpj may not contain all the fields from the inputKpj, only the // essential fields. Many of the fields in .kpj are deprecated, when they @@ -60,7 +61,7 @@ describe('kpj-file-writer', function () { const writer = new KPJFileWriter(); const output = writer.write(project); - const outputKpj = reader.read(new TextEncoder().encode(output)); + const outputKpj = KeymanXMLReader.removeSymbols(reader.read(new TextEncoder().encode(output))); // The outputKpj may not contain all the fields from the inputKpj, only the // essential fields. Many of the fields in .kpj are deprecated, when they diff --git a/developer/src/common/web/utils/test/kps/kps-file-reader.tests.ts b/developer/src/common/web/utils/test/kps/kps-file-reader.tests.ts index 1b809f39d0..94a1628bd9 100644 --- a/developer/src/common/web/utils/test/kps/kps-file-reader.tests.ts +++ b/developer/src/common/web/utils/test/kps/kps-file-reader.tests.ts @@ -15,6 +15,7 @@ import { makePathToFixture } from '../helpers/index.js'; import { KpsFileReader } from "../../src/types/kps/kps-file-reader.js"; import { KpsFileWriter } from '../../src/types/kps/kps-file-writer.js'; import { CommonTypesMessages } from '../../src/common-messages.js'; +import { KeymanXMLReader } from '../../src/xml-utils.js'; const callbacks = new TestCompilerCallbacks(); @@ -61,13 +62,13 @@ describe('kps-file-reader', function () { it('kps-file-reader should round-trip with kps-file-writer', function() { const input = fs.readFileSync(makePathToFixture('kps', 'khmer_angkor.kps')); const reader = new KpsFileReader(callbacks); - const kps = reader.read(input); + const kps = KeymanXMLReader.removeSymbols(reader.read(input)); const writer = new KpsFileWriter(); const output = writer.write(kps); // Round Trip - const kps2 = reader.read(new TextEncoder().encode(output)); + const kps2 = KeymanXMLReader.removeSymbols(reader.read(new TextEncoder().encode(output))); assert.deepEqual(kps2, kps); }); diff --git a/developer/src/common/web/utils/test/kvks/kvks-file.tests.ts b/developer/src/common/web/utils/test/kvks/kvks-file.tests.ts index 4c009e9d5c..96be2283b8 100644 --- a/developer/src/common/web/utils/test/kvks/kvks-file.tests.ts +++ b/developer/src/common/web/utils/test/kvks/kvks-file.tests.ts @@ -5,6 +5,7 @@ import KvksFileReader from "../../src/types/kvks/kvks-file-reader.js"; import KvksFileWriter from "../../src/types/kvks/kvks-file-writer.js"; import { verify_khmer_angkor, verify_balochi_inpage } from './kvk-utils.tests.js'; import { assert } from 'chai'; +import { KeymanXMLReader } from '../../src/xml-utils.js'; describe('kvks-file-reader', function() { it('should read a valid file', function() { @@ -48,7 +49,7 @@ describe('kvks-file-writer', function() { const input = fs.readFileSync(path); const reader = new KvksFileReader(); - const kvksExpected = reader.read(input); + const kvksExpected = KeymanXMLReader.removeSymbols(reader.read(input)); const invalidVkeys: string[] = []; const vk = reader.transform(kvksExpected, invalidVkeys); assert.isEmpty(invalidVkeys); @@ -59,6 +60,6 @@ describe('kvks-file-writer', function() { // We compare the (re)loaded data, because there may be // minor, irrelevant formatting differences in the emitted xml const kvks = reader.read(Buffer.from(output, 'utf8')); - assert.deepEqual(kvks, kvksExpected); + assert.deepEqual(KeymanXMLReader.removeSymbols(kvks), kvksExpected); }); }); diff --git a/developer/src/common/web/utils/test/xml-utils.tests.ts b/developer/src/common/web/utils/test/xml-utils.tests.ts index 44b4d95f21..9039760913 100644 --- a/developer/src/common/web/utils/test/xml-utils.tests.ts +++ b/developer/src/common/web/utils/test/xml-utils.tests.ts @@ -119,7 +119,7 @@ describe(`XML Reader Test ${GEN_XML_FIXTURES && '(update mode!)' || ''}`, () => writeJson(jsonPath, actual); } else { assert.ok(expect, `Could not read ${jsonPath} - run with env GEN_XML_FIXTURES=1 to update.`); - assert.deepEqual(actual, expect, `Mismatch of ${xmlPath} vs ${jsonPath}`); + assert.deepEqual(KeymanXMLReader.removeSymbols(actual), expect, `Mismatch of ${xmlPath} vs ${jsonPath}`); } }); } diff --git a/developer/src/kmc-ldml/test/helpers/compareXml.ts b/developer/src/kmc-ldml/test/helpers/compareXml.ts index f245da51a9..1503d4c606 100644 --- a/developer/src/kmc-ldml/test/helpers/compareXml.ts +++ b/developer/src/kmc-ldml/test/helpers/compareXml.ts @@ -21,5 +21,5 @@ export function compareXml(actual : string, expect: string, mutator?: (input: an const actualParsed = mutator(reader.parse(actualStr)); const expectParsed = mutator(reader.parse(expectStr)); - assert.deepEqual(actualParsed, expectParsed); + assert.deepEqual(KeymanXMLReader.removeSymbols(actualParsed), KeymanXMLReader.removeSymbols(expectParsed)); }