feat(developer): remove Error-Msg in keylayout-to-kmn-converter.ts‎ and adapt tests
Some checks are pending
Keyman Build Summary / Summarize build status checks (push) Waiting to run

This commit is contained in:
Sabine 2026-03-17 18:27:02 +01:00
parent 8633cb50f2
commit c7da0a952c
3 changed files with 48 additions and 111 deletions

View file

@ -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;;
}
/**

View file

@ -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[][]);

View file

@ -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 () {