mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-24 08:37:42 +00:00
Merge pull request #7203 from keymanapp/chore/developer/add-test-for-messages-and-improve-reporting-on-e2e
chore(developer): add test for compiler messages and cleanup e2e test 🙀
This commit is contained in:
commit
89331b62c4
2 changed files with 95 additions and 14 deletions
|
|
@ -7,25 +7,32 @@ import Compiler from '../src/keyman/compiler/compiler';
|
|||
import KMXBuilder from '../src/keyman/kmx/kmx-builder';
|
||||
import {CompilerCallbacks, makePathToFixture} from './helpers/index';
|
||||
|
||||
function checkMessages(callbacks: CompilerCallbacks) {
|
||||
if(callbacks.messages.length > 0) {
|
||||
console.log(callbacks.messages);
|
||||
}
|
||||
assert.isEmpty(callbacks.messages);
|
||||
}
|
||||
|
||||
function compileKeyboard(inputFilename: string): Uint8Array {
|
||||
const callbacks = new CompilerCallbacks();
|
||||
const k = new Compiler(callbacks);
|
||||
let source = k.load(inputFilename);
|
||||
if(!source) {
|
||||
return null;
|
||||
}
|
||||
if(!k.validate(source)) {
|
||||
return null;
|
||||
}
|
||||
let kmx = k.compile(source);
|
||||
if(!kmx) {
|
||||
return null;
|
||||
}
|
||||
const source = k.load(inputFilename);
|
||||
checkMessages(callbacks);
|
||||
assert.isNotNull(source, 'k.load should not have returned null');
|
||||
|
||||
const valid = k.validate(source);
|
||||
checkMessages(callbacks);
|
||||
assert.isTrue(valid, 'k.validate should not have failed');
|
||||
|
||||
const kmx = k.compile(source);
|
||||
checkMessages(callbacks);
|
||||
assert.isNotNull(kmx, 'k.compile should not have returned null');
|
||||
|
||||
// Use the builder to generate the binary output file
|
||||
let builder = new KMXBuilder(kmx, true);
|
||||
let result = builder.compile();
|
||||
assert(callbacks.messages.length == 0);
|
||||
const builder = new KMXBuilder(kmx, true);
|
||||
const result = builder.compile();
|
||||
checkMessages(callbacks);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
74
developer/src/kmldmlc/test/test-messages.ts
Normal file
74
developer/src/kmldmlc/test/test-messages.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import 'mocha';
|
||||
import {assert, expect} from 'chai';
|
||||
import { CompilerErrorSeverity, CompilerMessages } from '../src/keyman/compiler/messages';
|
||||
|
||||
const toTitleCase = (s: string) => s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
|
||||
|
||||
//
|
||||
// The purpose of these tests is to ensure that our slightly WET constant
|
||||
// definitions for compiler errors are consistent in their usage:
|
||||
//
|
||||
// * that names are consistent between the message functions and constants
|
||||
// * that constants have unique codes
|
||||
// * that constants have the right error mask for their type
|
||||
//
|
||||
// This means we don't have to worry about DRYing out the constants, which would
|
||||
// probably require us to have a preprocessing step, which has its own negatives.
|
||||
//
|
||||
|
||||
describe('compiler messages', function () {
|
||||
it('each compiler message function has a corresponding constant', function() {
|
||||
let keys = Object.keys(CompilerMessages);
|
||||
|
||||
const m = CompilerMessages as Record<string,any>;
|
||||
|
||||
for(let key of keys) {
|
||||
if(key == 'severityName') {
|
||||
// any helper functions we skip here
|
||||
continue;
|
||||
}
|
||||
|
||||
if(typeof m[key] == 'function') {
|
||||
const o = /^(Info|Hint|Warning|Error|Fatal)_([A-Za-z0-9_]+)$/.exec(key);
|
||||
expect(o).to.be.instanceOf(Array);
|
||||
|
||||
const c = o[1].toUpperCase() + '_' + o[2];
|
||||
expect(m[c]).to.be.a('number', `Expected constant name ${c} to exist`);
|
||||
|
||||
let v = m[key]('','','','','','','','','','','','' /* ignore arguments*/);
|
||||
expect(v.code).to.equal(m[c], `Function ${key} returns the wrong code`);
|
||||
}
|
||||
else if(typeof m[key] == 'number') {
|
||||
const o = /^(INFO|HINT|WARNING|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key);
|
||||
expect(o).to.be.instanceOf(Array);
|
||||
|
||||
const f = toTitleCase(o[1]) + '_' + o[2];
|
||||
expect(m[f]).to.be.a('function', `Expected function name ${f} to exist`);
|
||||
} else {
|
||||
assert.fail(`Unexepected compiler message member ${key}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('each compiler message constant to be have the right mask and be unique', function() {
|
||||
let keys = Object.keys(CompilerMessages);
|
||||
|
||||
const m = CompilerMessages as Record<string,any>;
|
||||
|
||||
let codes: number[] = [];
|
||||
|
||||
for(let key of keys) {
|
||||
if(typeof m[key] == 'number') {
|
||||
const o = /^(INFO|HINT|WARNING|ERROR|FATAL)_([A-Za-z0-9_]+)$/.exec(key);
|
||||
expect(o).to.be.instanceOf(Array);
|
||||
|
||||
const mask = CompilerMessages.severityName(m[key]);
|
||||
expect(o[1]).to.equal(mask, `Mask value for ${key} does not match`);
|
||||
|
||||
const code = m[key] & CompilerErrorSeverity.Error_Mask;
|
||||
expect(codes).to.not.contain(code, `Constant value ${key} is not unique`);
|
||||
codes.push(code);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue