feat(core): improve kmxplus validation tests

- update basic.txt to include the kvk section #12402
- use run() instead of compile()
- move compile()+serialize to a separate subtest
This commit is contained in:
Steven R. Loomis 2025-03-21 17:11:03 -05:00
parent 4e3379c698
commit 692ea6ee9e
3 changed files with 19 additions and 26 deletions

View file

@ -75,6 +75,11 @@ function do_build_fixtures() {
# Generate a binary file from basic.txt for comparison purposes
node ../../../common/tools/hextobin/build/hextobin.js ./test/fixtures/basic.txt ./build/test/fixtures/basic-txt.kmx
if ! cmp ./build/test/fixtures/basic-xml.kmx ./build/test/fixtures/basic-txt.kmx; then
printf "${COLOR_RED}basic-xml.kmx and basic-txt.kmx are different!${COLOR_RESET}\n"
else
printf "${COLOR_GREY}basic-xml.kmx and basic-txt.kmx are identical${COLOR_RESET}\n"
fi
}
builder_run_action clean do_clean

View file

@ -1,8 +1,7 @@
import 'mocha';
import {assert} from 'chai';
import hextobin from '@keymanapp/hextobin';
import { KMXBuilder } from '@keymanapp/developer-utils';
import {checkMessages, compileKeyboard, compilerTestCallbacks, compilerTestOptions, makePathToFixture} from './helpers/index.js';
import {compileKeyboard, compilerTestCallbacks, compilerTestOptions, makePathToFixture} from './helpers/index.js';
import { compareXml } from './helpers/compareXml.js';
import { LdmlKeyboardCompiler } from '../src/compiler/compiler.js';
import { kmxToXml } from '../src/util/serialize.js';
@ -24,45 +23,29 @@ describe('compiler-tests', function() {
const inputFilename = makePathToFixture('basic.xml');
const binaryFilename = makePathToFixture('basic.txt');
// Compile the keyboard
const kmx = await compileKeyboard(inputFilename, {...compilerTestOptions, saveDebug: true, shouldAddCompilerVersion: false});
assert.isNotNull(kmx);
// Use the builder to generate the binary output file
const builder = new KMXBuilder(kmx, true);
const code = builder.compile();
checkMessages();
assert.isNotNull(code);
// Compare output
let expected = await hextobin(binaryFilename, undefined, {silent:true});
assert.deepEqual<Uint8Array>(code, expected);
// now output it again as XML
const outputFilename = makePathToFixture('basic-serialized.xml');
const asXml = kmxToXml(kmx);
writeFileSync(outputFilename, asXml, 'utf-8');
// now compare it to use with run()
// Let's build basic.xml
// It should match basic.kmx (built from basic.txt)
const k = new LdmlKeyboardCompiler();
await k.init(compilerTestCallbacks, { ...compilerTestOptions, saveDebug: true, shouldAddCompilerVersion: false });
const { artifacts } = await k.run(inputFilename, "basic.kmx");
const { artifacts } = await k.run(inputFilename, "basic-xml.kmx"); // need the exact name passed to build-fixtures
assert.isNotNull(artifacts);
const { kmx, kvk } = artifacts;
assert.isNotNull(kmx);
assert.deepEqual<Uint8Array>(kmx?.data, expected);
assert.ok(artifacts?.kmx?.data);
// TODO: Can't compare the data here, it contains an embedded .kvk file that's present above!
// assert.deepEqual<Uint8Array>(artifacts?.kmx?.data, expected, "output of run() did not match");
// TODO-LDML: compare the .kvk file to something else?
assert.isNotNull(kvk?.data);
});
it('should-serialize-kmx', async function() {
this.timeout(4000);
// Let's build basic.xml
// It should match basic.kmx (built from basic.txt)
const inputFilename = makePathToFixture('basic.xml');
// Compile the keyboard
@ -77,7 +60,6 @@ describe('compiler-tests', function() {
compareXml(outputFilename, inputFilename);
});
it('should handle non existent files', async () => {
const filename = 'DOES_NOT_EXIST.xml';
const k = new LdmlKeyboardCompiler();

View file

@ -72,6 +72,10 @@ block(stores) # struct COMP_STORE {
offset(store_targets_string) # KMX_DWORD dpString;
# };
18 00 00 00 # TSS_VISUALKEYBOARD
00 00 00 00 # KMX_DWORD dpName;
offset(store_vk_path_string) # KMX_DWORD dpString;
block(store_name_name)
26 00 4e 00 41 00 4d 00 45 00 00 00 # '&NAME'
block(store_name_string)
@ -88,6 +92,8 @@ block(store_targets_name)
26 00 54 00 41 00 52 00 47 00 45 00 54 00 53 00 00 00 # '&TARGETS'
block(store_targets_string)
64 00 65 00 73 00 6b 00 74 00 6f 00 70 00 00 00 # 'desktop'
block(store_vk_path_string)
62 00 61 00 73 00 69 00 63 00 2d 00 78 00 6d 00 6c 00 2e 00 6b 00 76 00 6b 00 00 00 # 'basic-xml.kvk'
block(sect) # struct COMP_KMXPLUS_SECT {
73 65 63 74 # KMX_DWORD header.ident; // 0000 Section name