feat(common/web): adds a few unit tests for KeyboardProperties

This commit is contained in:
Joshua A. Horton 2023-01-25 12:39:30 +07:00
parent 9741c3a6d2
commit 182ed34f1d
3 changed files with 161 additions and 9 deletions

View file

@ -6,8 +6,15 @@ export interface KeyboardFont {
'path': string;
}
// Filename properties are deliberately omitted here; we can add that at higher-levels where it matters
// via 'mix-in'.
//
// For example, the OSK module doesn't care about the filename of a loaded keyboard. It doesn't do
// keyboard loading on its own whatsoever.
// Corresponds to Keyman Engine for Web's internal "keyboard stub" format.
export type KeyboardInternalPropertySpec = {
KI: string,
'KFont': KeyboardFont,
'KOskFont': KeyboardFont,
displayName?: string,
@ -16,17 +23,37 @@ export type KeyboardInternalPropertySpec = {
'KLC'?: string
};
// Corresponds to the documented API for the Web engine's `addKeyboards` function
// when a single language object is specified - not an array.
export type LanguageAPIPropertySpec = {
id: string,
name: string,
font: KeyboardFont,
oskFont: KeyboardFont
}
/**
* Corresponds to the documented API for the Web engine's `addKeyboards` function
* when a single language object is specified - not an array.
*
* See https://help.keyman.com/DEVELOPER/ENGINE/WEB/15.0/reference/core/addKeyboards,
* "Using an `object`".
*/
export type KeyboardAPIPropertySpec = {
id: string,
name: string,
languages: {
id: string,
name: string,
font: KeyboardFont,
oskFont: KeyboardFont
}
languages: LanguageAPIPropertySpec;
}
/**
* Corresponds to the documented API for the Web engine's `addKeyboards` function
* when a language array is specified for the object.
*
* See https://help.keyman.com/DEVELOPER/ENGINE/WEB/15.0/reference/core/addKeyboards,
* "Using an `object`".
*/
export type KeyboardAPIPropertyMultilangSpec = {
id: string,
name: string,
languages: LanguageAPIPropertySpec[];
}
type MetadataObj = KeyboardInternalPropertySpec | KeyboardAPIPropertySpec;
@ -50,6 +77,7 @@ export default class KeyboardProperties {
} else {
let apiStub = arg1 as KeyboardAPIPropertySpec;
this.wrappedStub = {
KI: apiStub.id,
KN: apiStub.name,
KL: apiStub.languages.name,
KLC: apiStub.languages.id,
@ -60,6 +88,7 @@ export default class KeyboardProperties {
}
} else {
this.wrappedStub = {
KI: null,
displayName: arg1,
'KLC': arg2,
'KFont': arg3,
@ -68,6 +97,38 @@ export default class KeyboardProperties {
}
}
public static fromMultilanguageAPIStub(apiStub: KeyboardAPIPropertyMultilangSpec, spacebarTextMode?: SpacebarText): KeyboardProperties[] {
let stubs: KeyboardProperties[] = [];
for(let langSpec of apiStub.languages) {
let stub: KeyboardAPIPropertySpec = {
id: apiStub.id,
name: apiStub.name,
languages: langSpec
};
stubs.push(new KeyboardProperties(stub, spacebarTextMode));
}
return stubs;
}
public get id(): string {
return this.wrappedStub.KI;
}
public get name(): string {
return this.wrappedStub.KN;
}
public get langId(): string {
return this.wrappedStub.KLC;
}
public get langName(): string {
return this.wrappedStub.KL;
}
public get displayName(): string {
if(this.wrappedStub.displayName) {
return this.wrappedStub.displayName;

View file

@ -1,4 +1,5 @@
const enum SpacebarText {
// Compiles completely out if `const enum`, making it unavailable in JS-based unit tests.
enum SpacebarText {
KEYBOARD = 'keyboard',
LANGUAGE = 'language',
LANGUAGE_KEYBOARD = 'languageKeyboard',

View file

@ -0,0 +1,90 @@
import { assert } from 'chai';
import fs from 'fs';
import vm from 'vm';
import KeyboardProperties from '@keymanapp/keyboard-processor/build/obj/keyboards/keyboardProperties.js';
import SpacebarText from '@keymanapp/keyboard-processor/build/obj/keyboards/spacebarText.js';
describe('Keyboard Properties', function() {
let rootCommonStubPath = '../../test/resources/json/keyboards/';
it('initialization from KMW\'s addKeyboards() API spec', () => {
let files = fs.readdirSync(rootCommonStubPath);
for(let file of files) {
let stub = JSON.parse(fs.readFileSync(`${rootCommonStubPath}/${file}`));
let dataset = [];
if(stub.languages instanceof Array) {
dataset = KeyboardProperties.fromMultilanguageAPIStub(stub);
} else {
dataset = [new KeyboardProperties(stub)];
}
// do verification
for(let data of dataset) {
assert.isOk(data.id);
assert.isOk(data.name);
assert.isOk(data.langId);
assert.isOk(data.langName);
// Do not make assertions on font, oskFont - those may be undefined for some keyboards.
// Generated dynamically from the backing source data.
assert.isOk(data.displayName);
}
}
});
it('generates display-name text if not directly-specified', () => {
// Could convert to run on all stubs, but... this should be fine as-is.
let stub = JSON.parse(fs.readFileSync(`${rootCommonStubPath}/khmer_angkor.json`));
let propObject = new KeyboardProperties(stub);
// Without a configured SpacebarText value, will display the keyboard name.
assert.equal(propObject.displayName, propObject.name);
propObject.spacebarTextMode = SpacebarText.BLANK;
assert.equal(propObject.displayName, '');
propObject.spacebarTextMode = SpacebarText.KEYBOARD;
assert.equal(propObject.displayName, propObject.name);
propObject.spacebarTextMode = SpacebarText.LANGUAGE;
assert.equal(propObject.displayName, propObject.langName);
propObject.spacebarTextMode = SpacebarText.LANGUAGE_KEYBOARD;
assert.isTrue(propObject.displayName.includes(propObject.langName) && propObject.displayName.includes(propObject.name));
});
it('does not override directly-specified display-name text', () => {
// Could convert to run on all stubs, but... this should be fine as-is.
let stub = JSON.parse(fs.readFileSync(`${rootCommonStubPath}/khmer_angkor.json`));
const customDisplayName = "(custom)";
let propObject = new KeyboardProperties(stub);
propObject.displayName = customDisplayName;
// Without a configured SpacebarText value, will display the keyboard name.
assert.equal(propObject.displayName, customDisplayName);
propObject.spacebarTextMode = SpacebarText.BLANK;
assert.equal(propObject.displayName, customDisplayName);
propObject.spacebarTextMode = SpacebarText.KEYBOARD;
assert.equal(propObject.displayName, customDisplayName);
propObject.spacebarTextMode = SpacebarText.LANGUAGE;
assert.equal(propObject.displayName, customDisplayName);
propObject.spacebarTextMode = SpacebarText.LANGUAGE_KEYBOARD;
assert.equal(propObject.displayName, customDisplayName);
propObject.displayName = null; // clear the value
assert.notEqual(propObject.displayName, customDisplayName);
assert.isTrue(propObject.displayName.includes(propObject.langName) && propObject.displayName.includes(propObject.name));
propObject.displayName = customDisplayName;
assert.equal(propObject.displayName, customDisplayName);
});
});