diff --git a/developer/src/kmc-convert/src/converter-messages.ts b/developer/src/kmc-convert/src/converter-messages.ts index 3d5a614f15..10c559ccbf 100644 --- a/developer/src/kmc-convert/src/converter-messages.ts +++ b/developer/src/kmc-convert/src/converter-messages.ts @@ -58,6 +58,12 @@ export class ConverterMessages { `INFO: Input file ${def(o.inputFilename)} contains unsupported character '${def(o.output)}' at keyMap index ${def(o.keymapIndex)} on Keycode ${def(o.key)} (${def(o.KeyName)})` ); + static ERROR_UndefinedActionDetected = SevError | 0x0009; + static Error_UndefinedActionDetected = (o: { inputFilename: string, action: string, KeyName: string, keymapIndex: string; }) => m( + this.ERROR_UndefinedActionDetected, + `${def(o.inputFilename)}: Action id ${def(o.action)} of key ${def(o.KeyName)} in keymapIndex ${def(o.keymapIndex)} is not defined` + ); + static ERROR_InvalidFile = SevError | 0x0008; static Error_InvalidFile = (o: { errorText: string; }) => m( this.ERROR_InvalidFile, 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 9d995d0108..b52f81fb7f 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 @@ -337,6 +337,15 @@ export class KeylayoutToKmnConverter { // ............................................................................................................................... const b1ActionIndex: number = this.getActionIndexFromActionId(jsonObj, actionId); + if (b1ActionIndex < 0) { + this.callbacks.reportMessage(ConverterMessages.Error_UndefinedActionDetected({ + inputFilename: jsonObj.keyboard['@__name'] + ".keylayout", + action: actionId, + KeyName: this.mapUkeleleKeycodeToVK(jsonObj.keyboard.keyMapSet[0].keyMap[i].key[j]['@__code']), + keymapIndex: jsonObj.keyboard.keyMapSet[0].keyMap[i]['@__index'] + })); + return null; + } // with actionId from above loop all 'action' and search for a state(none)-next-pair ............................................................................................................ // e.g. in Block 5: find for action id a18 ...................................................................................................................... @@ -807,7 +816,7 @@ export class KeylayoutToKmnConverter { return i; } } - return 0; + return -1; } /** 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 a1b7f7c750..c87be4708a 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 @@ -89,6 +89,19 @@ describe('KeylayoutToKmnConverter', function () { }); }); + describe('RunSpecialTestFiles - undefined action', function () { + const sut = new KeylayoutToKmnConverter(compilerTestCallbacks, compilerTestOptions); + [ + [makePathToFixture('../data/Test_undefinedAction.keylayout')], + ].forEach(function (files) { + it(files + " should give Error: undefined action detected", async function () { + sut.run(files[0]); + assert.isTrue(compilerTestCallbacks.messages.length === 1); + assert.equal(compilerTestCallbacks.messages[0].code, 5292041); + }); + }); + }); + describe('run() ', function () { const sut = new KeylayoutToKmnConverter(compilerTestCallbacks, compilerTestOptions); @@ -183,11 +196,11 @@ describe('KeylayoutToKmnConverter', function () { }); it('should return empty on empty input', async function () { - assert.isNull(convertedEmpty) + assert.isNull(convertedEmpty); }); it('should return empty on empty name as input', async function () { - assert.isNull(convertedUnavailable) + assert.isNull(convertedUnavailable); }); it('should return empty on only modifiers as input', async function () { @@ -196,7 +209,7 @@ describe('KeylayoutToKmnConverter', function () { modifiers: [['caps'], ['Shift'], ['command']], rules: [] }, ''); - assert.isNull(convertedMod) + assert.isNull(convertedMod); }); it('should return empty on only rules as input', async function () { @@ -205,12 +218,12 @@ describe('KeylayoutToKmnConverter', function () { modifiers: [], rules: [['C0', '', '', 0, 0, '', '', 0, 0, 'CAPS', 'K_A', 'A']] }, ''); - assert.isNull(convertedRule) + assert.isNull(convertedRule); }); it('should return empty array of rules on null input', async function () { const convertedRule = sut.convertBound.convert(null, 'ABC.kmn'); - assert.isNull(convertedRule) + assert.isNull(convertedRule); }); }); @@ -419,16 +432,16 @@ describe('KeylayoutToKmnConverter', function () { const read = sutR.read(inputFilename); [ - ['none', 0], + ['none', -1], ['A_16', 8], ['A_18', 10], ['A_19', 11], - ['0', 0], - ['', 0], - [' ', 0], - [null, 0], - [undefined, 0], - ['unknown', 0], + ['0', -1], + ['', -1], + [' ', -1], + [null, -1], + [undefined, -1], + ['unknown', -1], ].forEach(function (values) { it(("getActionIndexFromActionId('" + values[0] + "')").padEnd(50, " ") + ' should return ' + values[1], async function () { const result = sut.getActionIndexFromActionId(read, String(values[0]));