feat(developer): work around line number symbols

- add KeymanXMLReader.removeSymbols() and call it from tests

Fixes: #10622
This commit is contained in:
Steven R. Loomis 2025-02-28 14:24:12 -06:00
parent 819d9bf562
commit 4d9ea2db2d
6 changed files with 21 additions and 9 deletions

View file

@ -156,13 +156,22 @@ export class KeymanXMLReader {
* @param from source for symbols
* @returns the onto object
*/
private static copySymbols<T>(onto: T, from: any): T {
public static copySymbols<T>(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<T>(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 {

View file

@ -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

View file

@ -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);
});

View file

@ -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);
});
});

View file

@ -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}`);
}
});
}

View file

@ -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));
}