mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-06 08:55:34 +00:00
127 lines
4.5 KiB
TypeScript
127 lines
4.5 KiB
TypeScript
import {parseWordListFromContents, parseWordListFromFilename, WordList} from '../dist/lexical-model-compiler/build-trie';
|
||
import {assert} from 'chai';
|
||
import 'mocha';
|
||
import { makePathToFixture, LogHoarder } from './helpers';
|
||
import { KeymanCompilerError } from '../dist/errors';
|
||
|
||
const BOM = '\ufeff';
|
||
const SENCOTEN_WORDLIST = {
|
||
'TŦE': 13644,
|
||
'E': 9134,
|
||
'SEN': 4816,
|
||
'Ȼ': 3479,
|
||
'SW̱': 2621,
|
||
'NIȽ': 2314,
|
||
'U¸': 2298,
|
||
'I¸': 1988,
|
||
'ȻSE': 1925,
|
||
'I': 1884
|
||
};
|
||
|
||
describe('parsing a word list', function () {
|
||
beforeEach(function () {
|
||
this.logHoarder = (new LogHoarder).install()
|
||
})
|
||
|
||
afterEach(function () {
|
||
this.logHoarder.uninstall();
|
||
delete this.logHoarder;
|
||
})
|
||
|
||
it('should remove the UTF-8 byte order mark from files', function () {
|
||
let word = 'hello';
|
||
let count = 1;
|
||
let expected: WordList = {};
|
||
expected[word] = count;
|
||
|
||
let file = `# this is a comment\n${word}\t${count}`;
|
||
let withoutBOM: WordList = {};
|
||
parseWordListFromContents(withoutBOM, file);
|
||
assert.deepEqual(withoutBOM, expected, "expected regular file to parse properly");
|
||
assert.isFalse(this.logHoarder.hasSeenWarnings());
|
||
|
||
let withBOM: WordList = {};
|
||
parseWordListFromContents(withBOM, `${BOM}${file}`)
|
||
assert.deepEqual(withBOM, expected, "expected BOM to be ignored");
|
||
assert.isFalse(this.logHoarder.hasSeenWarnings());
|
||
});
|
||
|
||
it('should read word lists in UTF-8', function () {
|
||
// N.B.: this is the format exported by Google Drive when selecting "TSV".
|
||
const filename = makePathToFixture('example.qaa.sencoten', 'wordlist.tsv');
|
||
let wordlist: WordList = {};
|
||
parseWordListFromFilename(wordlist, filename);
|
||
|
||
assert.deepEqual(wordlist, SENCOTEN_WORDLIST);
|
||
assert.isFalse(this.logHoarder.hasSeenWarnings());
|
||
});
|
||
|
||
it('should read word lists in UTF-16 little-endian (with BOM)', function () {
|
||
// N.B.: this is the format exported by MS Excel when selecting
|
||
// "UTF-16" text (tested on Excel for macOS).
|
||
const filename = makePathToFixture('example.qaa.utf16le', 'wordlist.txt');
|
||
let wordlist: WordList = {};
|
||
parseWordListFromFilename(wordlist, filename);
|
||
|
||
assert.deepEqual(wordlist, SENCOTEN_WORDLIST);
|
||
assert.isFalse(this.logHoarder.hasSeenWarnings());
|
||
});
|
||
|
||
it('should NOT read word lists in UTF-16 big-endian (with BOM)', function () {
|
||
// N.B.: Does anything output this format...?
|
||
const filename = makePathToFixture('example.qaa.utf16be', 'wordlist.txt');
|
||
let wordlist: WordList = {};
|
||
assert.throws(() => {
|
||
parseWordListFromFilename(wordlist, filename);
|
||
}, 'UTF-16BE is unsupported');
|
||
});
|
||
|
||
it('should merge duplicate entries in a wordlist', function () {
|
||
// Tests that we merge NFC+NFD entries and identical entries, trimming whitespace
|
||
// Note building the wordlist from an array to make clear that we have unnormalised inputs
|
||
const words = [
|
||
'hello', //1
|
||
'hello\u0301', //2, NFD helló
|
||
'hell\u00f3', //3, NFC helló
|
||
' hello ', //4, expect to trim whitespace
|
||
'hello']; //5
|
||
|
||
const expected: WordList = {
|
||
'hello': 10, /* 1+4+5 trimmed and identical */
|
||
'hell\u00f3': 5, /* 2+3 normalised to NFC */
|
||
};
|
||
|
||
// Build a wordlist from the array
|
||
let file = `# this is a comment\n`;
|
||
for(let i = 0; i < words.length; i++) {
|
||
file += `${words[i]}\t${i+1}\n`;
|
||
}
|
||
let repeatedWords: WordList = {};
|
||
parseWordListFromContents(repeatedWords, file);
|
||
|
||
assert.deepEqual(repeatedWords, expected);
|
||
|
||
assert.isTrue(this.logHoarder.hasSeenWarnings());
|
||
// hello has been seen multiple times:
|
||
assert.isTrue(this.logHoarder.hasSeenCode(KeymanCompilerError.CWARN_DuplicateWordInSameFile));
|
||
// helló and hello + U+0301 have both been seen:
|
||
assert.isTrue(this.logHoarder.hasSeenCode(KeymanCompilerError.CWARN_MixedNormalizationForms));
|
||
|
||
// Let's parse another file:
|
||
|
||
this.logHoarder.clear();
|
||
// Now, parse a DIFFERENT file, but with an NFD entry.
|
||
parseWordListFromContents(repeatedWords, "hello\u0301\t5\n");
|
||
assert.isTrue(this.logHoarder.hasSeenWarnings())
|
||
// hello + U+0301 (NFD) has been seen, but...
|
||
assert.isTrue(this.logHoarder.hasSeenCode(KeymanCompilerError.CWARN_MixedNormalizationForms));
|
||
// BUT! We have not seen a duplicate **within the same file**
|
||
assert.isFalse(this.logHoarder.hasSeenCode(KeymanCompilerError.CWARN_DuplicateWordInSameFile));
|
||
|
||
assert.deepEqual(repeatedWords, {
|
||
hello: expected['hello'],
|
||
// should have seen more of this entry:
|
||
"hell\u00f3": expected["hell\u00f3"] + 5,
|
||
});
|
||
});
|
||
});
|