From c7da0a952ca5b2bee7a6a53ee461e4cf77066cc2 Mon Sep 17 00:00:00 2001 From: Sabine Date: Tue, 17 Mar 2026 18:27:02 +0100 Subject: [PATCH] =?UTF-8?q?feat(developer):=20remove=20Error-Msg=20in=20ke?= =?UTF-8?q?ylayout-to-kmn-converter.ts=E2=80=8E=20and=20adapt=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../keylayout-to-kmn-converter.ts | 55 +++++++++---------- .../test/keylayout-to-kmn-converter.tests.ts | 49 +++++++---------- .../kmc-convert/test/kmn-file-writer.tests.ts | 55 ------------------- 3 files changed, 48 insertions(+), 111 deletions(-) diff --git a/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts b/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts index 8e518b2288..9d995d0108 100644 --- a/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts +++ b/developer/src/kmc-convert/src/keylayout-to-kmn/keylayout-to-kmn-converter.ts @@ -183,31 +183,29 @@ export class KeylayoutToKmnConverter { }; if ((jsonObj === null) || (!jsonObj.hasOwnProperty("keyboard"))) { - this.callbacks.reportMessage(ConverterMessages.Error_UnableToRead({ inputFilename: inputfilename })); - return dataObject; - } else { - - // create an array of modifier combinations and store in dataObject - for (let j = 0; j < jsonObj.keyboard.modifierMap.keyMapSelect.length; j++) { - const singleModifierSet: string[] = []; - for (let k = 0; k < jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier.length; k++) { - singleModifierSet.push(jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier[k]['@__keys']); - } - modifierBehavior.push(singleModifierSet); - } - - // fill dataObject with filenames, behaviors and (initialized) rules - dataObject.keylayoutFilename = inputfilename; - dataObject.kmnFilename = inputfilename.replace(/\.keylayout$/, '.kmn'); - dataObject.modifiers = modifierBehavior; // ukelele uses behaviors e.g. 18 modifiersCombinations in 8 KeyMapSelect(behaviors) - dataObject.rules = rules; - - // fix the amount of processable keys to the maximun nr of keys of a keyMap to avoid processing more keys than defined - KeylayoutToKmnConverter.USE_KEY_COUNT = findUsedKeysCount(jsonObj); - - // fill rules into 'rules' of dataObject - return this.createRuleData(dataObject, jsonObj); + return null; } + // create an array of modifier combinations and store in dataObject + for (let j = 0; j < jsonObj.keyboard.modifierMap.keyMapSelect.length; j++) { + const singleModifierSet: string[] = []; + for (let k = 0; k < jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier.length; k++) { + singleModifierSet.push(jsonObj.keyboard.modifierMap.keyMapSelect[j].modifier[k]['@__keys']); + } + modifierBehavior.push(singleModifierSet); + } + + // fill dataObject with filenames, behaviors and (initialized) rules + dataObject.keylayoutFilename = inputfilename; + dataObject.kmnFilename = inputfilename.replace(/\.keylayout$/, '.kmn'); + dataObject.modifiers = modifierBehavior; // ukelele uses behaviors e.g. 18 modifiersCombinations in 8 KeyMapSelect(behaviors) + dataObject.rules = rules; + + // fix the amount of processable keys to the maximun nr of keys of a keyMap to avoid processing more keys than defined + KeylayoutToKmnConverter.USE_KEY_COUNT = findUsedKeysCount(jsonObj); + + // fill rules into 'rules' of dataObject + return this.createRuleData(dataObject, jsonObj); + } /** @@ -224,7 +222,7 @@ export class KeylayoutToKmnConverter { let actionId: string; // check if we use CAPS in a modifier throughout the .keylayout file. In this case we need to add NCAPS - const isCapsused = (this.checkIfCapsIsUsed(dataUkelele.modifiers) !== undefined); + const isCapsused = (this.checkIfCapsIsUsed(dataUkelele.modifiers)); // if there are different amounts of keyMapSelect vs keyMap if (jsonObj.keyboard.modifierMap?.keyMapSelect.length !== jsonObj.keyboard.keyMapSet[0].keyMap.length) { @@ -707,10 +705,11 @@ export class KeylayoutToKmnConverter { * @param keylayoutModifier the modifier string used in the .keylayout-file * @return "caps" or undefined if "caps" is not found */ - public checkIfCapsIsUsed(keylayoutModifier: string[][]): string { + public checkIfCapsIsUsed(keylayoutModifier: string[][]): boolean { if (!keylayoutModifier) - return undefined; - return keylayoutModifier.flat().find(e => e.toUpperCase() === 'CAPS'); + return false; + // make sure we always have a whitespace before and after each modifier( to distinguish from caps? ) + return (" " + keylayoutModifier.flat().join(" ").toUpperCase() + " ").indexOf(" CAPS ") >= 0;; } /** diff --git a/developer/src/kmc-convert/test/keylayout-to-kmn-converter.tests.ts b/developer/src/kmc-convert/test/keylayout-to-kmn-converter.tests.ts index 302e8f48a3..a1b7f7c750 100644 --- a/developer/src/kmc-convert/test/keylayout-to-kmn-converter.tests.ts +++ b/developer/src/kmc-convert/test/keylayout-to-kmn-converter.tests.ts @@ -183,15 +183,11 @@ describe('KeylayoutToKmnConverter', function () { }); it('should return empty on empty input', async function () { - assert.isTrue((convertedEmpty.keylayoutFilename === '' - && convertedEmpty.modifiers.length === 0 - && convertedEmpty.rules.length === 0)); + assert.isNull(convertedEmpty) }); - it('should return empty on only name as input', async function () { - assert.isTrue((convertedUnavailable.keylayoutFilename === '' - && convertedUnavailable.modifiers.length === 0 - && convertedUnavailable.rules.length === 0)); + it('should return empty on empty name as input', async function () { + assert.isNull(convertedUnavailable) }); it('should return empty on only modifiers as input', async function () { @@ -200,9 +196,7 @@ describe('KeylayoutToKmnConverter', function () { modifiers: [['caps'], ['Shift'], ['command']], rules: [] }, ''); - assert.isTrue((convertedMod.keylayoutFilename === '' - && convertedMod.modifiers.length === 0 - && convertedMod.rules.length === 0)); + assert.isNull(convertedMod) }); it('should return empty on only rules as input', async function () { @@ -211,14 +205,13 @@ describe('KeylayoutToKmnConverter', function () { modifiers: [], rules: [['C0', '', '', 0, 0, '', '', 0, 0, 'CAPS', 'K_A', 'A']] }, ''); - assert.isTrue((convertedRule.keylayoutFilename === '' - && convertedRule.modifiers.length === 0 - && convertedRule.rules.length === 0)); + assert.isNull(convertedRule) }); it('should return empty array of rules on null input', async function () { const convertedRule = sut.convertBound.convert(null, 'ABC.kmn'); - assert.isTrue(convertedRule.rules.length === 0); + assert.isNull(convertedRule) + }); }); @@ -320,20 +313,20 @@ describe('KeylayoutToKmnConverter', function () { describe('checkIfCapsIsUsed ', function () { const sut = new KeylayoutToKmnConverter(compilerTestCallbacks, compilerTestOptions); [ - [[['caps', 'xxx'], ['yyy']], 'caps'], - [[['Caps', 'xxx'], ['yyy']], 'Caps'], - [[['CaPs', 'xxx'], ['yyy']], 'CaPs'], - [[['Caps?', 'xxx'], ['yyy']], undefined], - [[['caps?', 'xxx'], ['yyy']], undefined], - [[['zzz', 'xxx'], ['yyy']], undefined], - [[['shift', 'xxx'], ['caps']], 'caps'], - [[['shift', 'caps'], ['yyy']], 'caps'], - [[['caps', 'xxx'], ['caps']], 'caps'], - [[['', 'someWordWithCaps'], ['']], undefined], - [null, undefined], - [[], undefined], - [[['', ''], ['']], undefined], - [[[' ', ' '], [' ']], undefined], + [[['caps', 'xxx'], ['yyy']], true], + [[['Caps', 'xxx'], ['yyy']], true], + [[['CaPs', 'xxx'], ['yyy']], true], + [[['Caps?', 'xxx'], ['yyy']], false], + [[['caps?', 'xxx'], ['yyy']], false], + [[['zzz', 'xxx'], ['yyy']], false], + [[['shift', 'xxx'], ['caps']], true], + [[['shift', 'caps'], ['yyy']], true], + [[['caps', 'xxx'], ['caps']], true], + [[['', 'someWordWithCaps'], ['']], false], + [null, false], + [[], false], + [[['', ''], ['']], false], + [[[' ', ' '], [' ']], false], ].forEach(function (values) { it(("checkIfCapsIsUsed(" + values[0] + ")").padEnd(40, " ") + "should return " + "'" + values[1] + "'", async function () { const result = sut.checkIfCapsIsUsed(values[0] as string[][]); diff --git a/developer/src/kmc-convert/test/kmn-file-writer.tests.ts b/developer/src/kmc-convert/test/kmn-file-writer.tests.ts index 1dddb50888..4991ab9da1 100644 --- a/developer/src/kmc-convert/test/kmn-file-writer.tests.ts +++ b/developer/src/kmc-convert/test/kmn-file-writer.tests.ts @@ -30,31 +30,6 @@ describe('KmnFileWriter', function () { const read = sutR.read(inputFilename); const converted = sut.convertBound.convert(read, inputFilename.replace(/\.keylayout$/, '.kmn')); - const outExpected: string = - "c ..................................................................................................................\n" - + "c ..................................................................................................................\n" - + "c Keyman keyboard generated by kmn-convert version: " + KEYMAN_VERSION.VERSION + "\n" - + "c from Ukelele file: " - + "\n" - + "c ..................................................................................................................\n" - + "c ..................................................................................................................\n" - + "\n" - + "store(&TARGETS) 'desktop'\n" - + "\n" - + "begin Unicode > use(main)\n\n" - + "group(main) using keys\n\n" - + "\n"; - - - // empty ProcessedData from unavailable file name - const inputFilenameUnavailable = makePathToFixture('../data/X.keylayout'); - const readUnavailable = sutR.read(inputFilenameUnavailable); - const convertedUnavailable = sut.convertBound.convert(readUnavailable, inputFilenameUnavailable.replace(/\.keylayout$/, '.kmn')); - it('write() should return header in case of missing inputfile', async function () { - const result = sutW.write(convertedUnavailable); - assert.equal(new TextDecoder().decode(result), ("\n" + outExpected)); - }); - it('write() should return result', async function () { const result = sutW.write(converted); assert.isNotNull(result); @@ -69,21 +44,11 @@ describe('KmnFileWriter', function () { const read = sutR.read(inputFilename); const converted = sut.convertBound.convert(read, inputFilename.replace(/\.keylayout$/, '.kmn')); - // empty ProcessedData from unavailable file name - const inputFilenameUnavailable = makePathToFixture('../data/X.keylayout'); - const readUnavailable = sutR.read(inputFilenameUnavailable); - const convertedUnavailable = sut.convertBound.convert(readUnavailable, inputFilenameUnavailable.replace(/\.keylayout$/, '.kmn')); - it('writeDataRules() should return true (no error) if written', async function () { const result = sutW.writeDataRules(converted); assert.isTrue(result.length > 0); }); - it('writeDataRules() should return false if no inputfile', async function () { - const result = sutW.writeDataRules(convertedUnavailable); - assert.isFalse(result.length > 0); - }); - }); describe("writeKmnFileHeader() ", function () { @@ -94,16 +59,6 @@ describe('KmnFileWriter', function () { const read = sutR.read(inputFilename); const converted = sut.convertBound.convert(read, inputFilename.replace(/\.keylayout$/, '.kmn')); - // empty ProcessedData from unavailable file name - const inputFilenameUnavailable = makePathToFixture('../data/X.keylayout'); - const readUnavailable = sutR.read(inputFilenameUnavailable); - const convertedUnavailable = sut.convertBound.convert(readUnavailable, inputFilenameUnavailable.replace(/\.keylayout$/, '.kmn')); - - // empty ProcessedData from empty filename - const inputFilenameEmpty = makePathToFixture(''); - const readEmpty = sutR.read(inputFilenameEmpty); - const convertedEmpty = sut.convertBound.convert(readEmpty, inputFilenameEmpty); - const outExpectedFirst: string = "c ..................................................................................................................\n" + "c ..................................................................................................................\n" @@ -125,16 +80,6 @@ describe('KmnFileWriter', function () { const writtenCorrectName = sutW.writeKmnFileHeader(converted); assert.equal(writtenCorrectName, (outExpectedFirst + converted.keylayoutFilename + outExpectedLast)); }); - - it(('writeKmnFileHeader should return store text without filename ').padEnd(62, " ") + 'on empty input', async function () { - const writtenEmptyName = sutW.writeKmnFileHeader(convertedEmpty); - assert.equal(writtenEmptyName, (outExpectedFirst + outExpectedLast)); - }); - - it(('writeKmnFileHeader should return store text without filename ').padEnd(62, " ") + 'on only filename as input', async function () { - const writtenOnlyName = sutW.writeKmnFileHeader(convertedUnavailable); - assert.equal(writtenOnlyName, (outExpectedFirst + convertedUnavailable.keylayoutFilename + outExpectedLast)); - }); }); describe('convertToUnicodeCodePoint ', function () {