spiegel-keyman/developer/src/kmldmlc/src/kmldmlc.ts
Marc Durdin 995d731ccb feat(developer): add unit tests for meta compiler
First, a little bit of refactoring to make it cleaner to do unit test
for each section.

Then add some global error values.

Throw in a helper function or two.

Dust off the edges of the CompilerCallbacks object.

Duct tape together validation of the normalization attribute.

And ... eventually we get a nice clean-like unit test for the meta
compiler, with three pretty little fixtures and as-neat-as-you-like-it
assertions.
2022-08-30 13:52:36 +10:00

79 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
/**
* kmldmlc - Keyman LDML Keyboard Compiler
*/
import * as fs from 'fs';
import * as path from 'path';
import * as program from 'commander';
import Compiler from './keyman/compiler/compiler';
import KMXBuilder from './keyman/kmx/kmx-builder';
import { getErrorSeverityName } from './keyman/compiler/errors';
let inputFilename: string;
const KEYMAN_VERSION = require("@keymanapp/keyman-version").KEYMAN_VERSION;
/* Arguments */
program
.description('Compiles Keyman LDML keyboards')
.version(KEYMAN_VERSION.VERSION_WITH_TAG)
.arguments('<infile>')
.action((infile:any) => inputFilename = infile)
.option('-o, --outFile <filename>', 'where to save the resulting .kmx file');
program.parse(process.argv);
// Deal with input arguments:
if (!inputFilename) {
exitDueToUsageError('Must provide a LDML keyboard .xml source file.');
}
function exitDueToUsageError(message: string): never {
console.error(`${program._name}: ${message}`);
console.error();
program.outputHelp();
return process.exit(64); // TODO: SysExits.EX_USAGE
}
class CompilerCallbacks {
loadFile(baseFilename: string, filename:string): Buffer {
// TODO: translate filename based on the baseFilename
return fs.readFileSync(filename);
}
reportMessage(code: number, message: string): void {
console.log(getErrorSeverityName(code) + ' ' + code.toString(16) + ': ' + message);
}
}
function compileKeyboard(inputFilename: string): Uint8Array {
const c = new CompilerCallbacks();
const k = new Compiler(c);
let source = k.load(inputFilename);
if(!source) {
return null;
}
if(!k.validate(source)) {
return null;
}
let kmx = k.compile(source);
if(!kmx) {
return null;
}
// Use the builder to generate the binary output file
let builder = new KMXBuilder(kmx, true);
return builder.compile();
}
// Compile:
let code = compileKeyboard(inputFilename);
// Output:
if(code) {
const outFile = program.outFile ?? path.join(path.dirname(inputFilename), path.basename(inputFilename, '.xml') + '.kmx');
console.log(`Writing compiled keyboard to ${outFile}`);
fs.writeFileSync(outFile, code);
}