aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDarius Jahandarie <djahandarie@gmail.com>2023-12-06 03:53:16 +0000
committerGitHub <noreply@github.com>2023-12-06 03:53:16 +0000
commitbd5bc1a5db29903bc098995cd9262c4576bf76af (patch)
treec9214189e0214480fcf6539ad1c6327aef6cbd1c /test
parentfd6bba8a2a869eaf2b2c1fa49001f933fce3c618 (diff)
parent23e6fb76319c9ed7c9bcdc3efba39bc5dd38f288 (diff)
Merge pull request #339 from toasted-nutbread/type-annotations
Type annotations
Diffstat (limited to 'test')
-rw-r--r--test/anki-note-builder.test.js48
-rw-r--r--test/cache-map.test.js12
-rw-r--r--test/core.test.js5
-rw-r--r--test/css-json.test.js1
-rw-r--r--test/data/anki-note-builder-test-results.json48
-rw-r--r--test/data/html/test-document2-script.js40
-rw-r--r--test/data/translator-test-results-note-data1.json280
-rw-r--r--test/data/translator-test-results.json236
-rw-r--r--test/database.test.js113
-rw-r--r--test/deinflector.test.js17
-rw-r--r--test/dictionary.test.js6
-rw-r--r--test/document-util.test.js118
-rw-r--r--test/dom-text-scanner.test.js47
-rw-r--r--test/hotkey-util.test.js7
-rw-r--r--test/japanese-util.test.js39
-rw-r--r--test/jsconfig.json40
-rw-r--r--test/jsdom.test.js9
-rw-r--r--test/json-schema.test.js71
-rw-r--r--test/object-property-accessor.test.js40
-rw-r--r--test/options-util.test.js49
-rw-r--r--test/playwright/integration.spec.js13
-rw-r--r--test/playwright/playwright-util.js11
-rw-r--r--test/playwright/visual.spec.js12
-rw-r--r--test/profile-conditions-util.test.js357
-rw-r--r--test/text-source-map.test.js10
-rw-r--r--test/translator.test.js5
26 files changed, 1085 insertions, 549 deletions
diff --git a/test/anki-note-builder.test.js b/test/anki-note-builder.test.js
index e21aa993..96dacab6 100644
--- a/test/anki-note-builder.test.js
+++ b/test/anki-note-builder.test.js
@@ -26,8 +26,14 @@ import {TranslatorVM} from '../dev/translator-vm.js';
import {AnkiNoteBuilder} from '../ext/js/data/anki-note-builder.js';
import {JapaneseUtil} from '../ext/js/language/sandbox/japanese-util.js';
-vi.stubGlobal('fetch', async (url2) => {
- const extDir = path.join(__dirname, '..', 'ext');
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+
+/**
+ * @param {string} url2
+ * @returns {Promise<import('dev/vm').PseudoFetchResponse>}
+ */
+async function fetch(url2) {
+ const extDir = path.join(dirname, '..', 'ext');
let filePath;
try {
filePath = url.fileURLToPath(url2);
@@ -43,11 +49,13 @@ vi.stubGlobal('fetch', async (url2) => {
text: async () => Promise.resolve(content.toString('utf8')),
json: async () => Promise.resolve(JSON.parse(content.toString('utf8')))
};
-});
+}
+vi.stubGlobal('fetch', fetch);
vi.mock('../ext/js/templates/template-renderer-proxy.js');
-const dirname = path.dirname(fileURLToPath(import.meta.url));
-
+/**
+ * @returns {Promise<TranslatorVM>}
+ */
async function createVM() {
const dictionaryDirectory = path.join(dirname, 'data', 'dictionaries', 'valid-dictionary1');
const vm = new TranslatorVM();
@@ -57,6 +65,10 @@ async function createVM() {
return vm;
}
+/**
+ * @param {'terms'|'kanji'} type
+ * @returns {string[]}
+ */
function getFieldMarkers(type) {
switch (type) {
case 'terms':
@@ -117,8 +129,17 @@ function getFieldMarkers(type) {
}
}
+/**
+ * @param {import('dictionary').DictionaryEntry[]} dictionaryEntries
+ * @param {'terms'|'kanji'} type
+ * @param {import('settings').ResultOutputMode} mode
+ * @param {string} template
+ * @param {import('@vitest/expect').ExpectStatic} expect
+ * @returns {Promise<import('anki').NoteFields[]>}
+ */
async function getRenderResults(dictionaryEntries, type, mode, template, expect) {
const markers = getFieldMarkers(type);
+ /** @type {import('anki-note-builder').Field[]} */
const fields = [];
for (const marker of markers) {
fields.push([marker, `{${marker}}`]);
@@ -151,9 +172,10 @@ async function getRenderResults(dictionaryEntries, type, mode, template, expect)
query: 'query',
fullQuery: 'fullQuery'
};
- const {note: {fields: noteFields}, errors} = await ankiNoteBuilder.createNote({
+ /** @type {import('anki-note-builder').CreateNoteDetails} */
+ const details = {
dictionaryEntry,
- mode: null,
+ mode: 'test',
context,
template,
deckName: 'deckName',
@@ -165,8 +187,11 @@ async function getRenderResults(dictionaryEntries, type, mode, template, expect)
duplicateScopeCheckAllModels: false,
resultOutputMode: mode,
glossaryLayoutMode: 'default',
- compactTags: false
- });
+ compactTags: false,
+ requirements: [],
+ mediaOptions: null
+ };
+ const {note: {fields: noteFields}, errors} = await ankiNoteBuilder.createNote(details);
for (const error of errors) {
console.error(error);
}
@@ -178,6 +203,7 @@ async function getRenderResults(dictionaryEntries, type, mode, template, expect)
}
+/** */
async function main() {
const vm = await createVM();
@@ -199,6 +225,7 @@ async function main() {
case 'findTerms':
{
const {name, mode, text} = t;
+ /** @type {import('translation').FindTermsOptions} */
const options = vm.buildOptions(optionsPresets, t.options);
const {dictionaryEntries} = structuredClone(await vm.translator.findTerms(mode, text, options));
const results = mode !== 'simple' ? structuredClone(await getRenderResults(dictionaryEntries, 'terms', mode, template, expect)) : null;
@@ -209,9 +236,10 @@ async function main() {
case 'findKanji':
{
const {name, text} = t;
+ /** @type {import('translation').FindKanjiOptions} */
const options = vm.buildOptions(optionsPresets, t.options);
const dictionaryEntries = structuredClone(await vm.translator.findKanji(text, options));
- const results = structuredClone(await getRenderResults(dictionaryEntries, 'kanji', null, template, expect));
+ const results = structuredClone(await getRenderResults(dictionaryEntries, 'kanji', 'split', template, expect));
actualResults1.push({name, results});
expect(results).toStrictEqual(expected1.results);
}
diff --git a/test/cache-map.test.js b/test/cache-map.test.js
index 9d10a719..df891188 100644
--- a/test/cache-map.test.js
+++ b/test/cache-map.test.js
@@ -19,6 +19,7 @@
import {expect, test} from 'vitest';
import {CacheMap} from '../ext/js/general/cache-map.js';
+/** */
function testConstructor() {
test('constructor', () => {
const data = [
@@ -29,6 +30,7 @@ function testConstructor() {
[true, () => new CacheMap(1.5)],
[true, () => new CacheMap(Number.NaN)],
[true, () => new CacheMap(Number.POSITIVE_INFINITY)],
+ // @ts-expect-error - Ignore because it should throw an error
[true, () => new CacheMap('a')]
];
@@ -42,6 +44,7 @@ function testConstructor() {
});
}
+/** */
function testApi() {
test('api', () => {
const data = [
@@ -103,10 +106,10 @@ function testApi() {
const {func, args} = call;
let returnValue;
switch (func) {
- case 'get': returnValue = cache.get(...args); break;
- case 'set': returnValue = cache.set(...args); break;
- case 'has': returnValue = cache.has(...args); break;
- case 'clear': returnValue = cache.clear(...args); break;
+ case 'get': returnValue = cache.get(args[0]); break;
+ case 'set': returnValue = cache.set(args[0], args[1]); break;
+ case 'has': returnValue = cache.has(args[0]); break;
+ case 'clear': returnValue = cache.clear(); break;
}
if (Object.prototype.hasOwnProperty.call(call, 'returnValue')) {
const {returnValue: expectedReturnValue} = call;
@@ -119,6 +122,7 @@ function testApi() {
}
+/** */
function main() {
testConstructor();
testApi();
diff --git a/test/core.test.js b/test/core.test.js
index 203460f4..685bf9dc 100644
--- a/test/core.test.js
+++ b/test/core.test.js
@@ -19,14 +19,17 @@
import {describe, expect, test} from 'vitest';
import {DynamicProperty, deepEqual} from '../ext/js/core.js';
+/** */
function testDynamicProperty() {
test('DynamicProperty', () => {
const data = [
{
initialValue: 0,
+ /** @type {{operation: ?string, expectedDefaultValue: number, expectedValue: number, expectedOverrideCount: number, expeectedEventOccurred: boolean, args: [value: number, priority?: number]}[]} */
operations: [
{
operation: null,
+ args: [0],
expectedDefaultValue: 0,
expectedValue: 0,
expectedOverrideCount: 0,
@@ -147,6 +150,7 @@ function testDynamicProperty() {
});
}
+/** */
function testDeepEqual() {
describe('deepEqual', () => {
const data = [
@@ -280,6 +284,7 @@ function testDeepEqual() {
}
+/** */
function main() {
testDynamicProperty();
testDeepEqual();
diff --git a/test/css-json.test.js b/test/css-json.test.js
index 0aaf7d10..66ecfeba 100644
--- a/test/css-json.test.js
+++ b/test/css-json.test.js
@@ -20,6 +20,7 @@ import fs from 'fs';
import {expect, test} from 'vitest';
import {formatRulesJson, generateRules, getTargets} from '../dev/generate-css-json';
+/** */
function main() {
test('css-json', () => {
for (const {cssFile, overridesCssFile, outputPath} of getTargets()) {
diff --git a/test/data/anki-note-builder-test-results.json b/test/data/anki-note-builder-test-results.json
index b752e878..49542e39 100644
--- a/test/data/anki-note-builder-test-results.json
+++ b/test/data/anki-note-builder-test-results.json
@@ -194,7 +194,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -224,7 +224,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
@@ -379,7 +379,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 24</li><li>Test Dictionary 2: 30</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: eighteen</li><li>Test Dictionary 2: twenty-four (24)</li><li>Test Dictionary 2: 30</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[う]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>uchikomu definition 3</li><li>uchikomu definition 4</li></ul></div>",
@@ -409,7 +409,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 25</li><li>Test Dictionary 2: 31</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: nineteen</li><li>Test Dictionary 2: twenty-five (25)</li><li>Test Dictionary 2: thirty-one</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[ぶ]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>buchikomu definition 3</li><li>buchikomu definition 4</li></ul></div>",
@@ -499,7 +499,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -529,7 +529,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
@@ -759,7 +759,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -824,7 +824,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
@@ -889,7 +889,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 24</li><li>Test Dictionary 2: 30</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: eighteen</li><li>Test Dictionary 2: twenty-four (24)</li><li>Test Dictionary 2: 30</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[う]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>uchikomu definition 3</li><li>uchikomu definition 4</li></ul></div>",
@@ -949,7 +949,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -1014,7 +1014,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 25</li><li>Test Dictionary 2: 31</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: nineteen</li><li>Test Dictionary 2: twenty-five (25)</li><li>Test Dictionary 2: thirty-one</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[ぶ]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>buchikomu definition 3</li><li>buchikomu definition 4</li></ul></div>",
@@ -1074,7 +1074,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
@@ -1526,7 +1526,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 24</li><li>Test Dictionary 2: 30</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: eighteen</li><li>Test Dictionary 2: twenty-four (24)</li><li>Test Dictionary 2: 30</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[う]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>uchikomu definition 3</li><li>uchikomu definition 4</li></ul></div>",
@@ -1556,7 +1556,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 25</li><li>Test Dictionary 2: 31</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: nineteen</li><li>Test Dictionary 2: twenty-five (25)</li><li>Test Dictionary 2: thirty-one</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[ぶ]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>buchikomu definition 3</li><li>buchikomu definition 4</li></ul></div>",
@@ -1646,7 +1646,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -1676,7 +1676,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
@@ -1831,7 +1831,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 24</li><li>Test Dictionary 2: 30</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: eighteen</li><li>Test Dictionary 2: twenty-four (24)</li><li>Test Dictionary 2: 30</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[う]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>uchikomu definition 3</li><li>uchikomu definition 4</li></ul></div>",
@@ -1861,7 +1861,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 25</li><li>Test Dictionary 2: 31</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: nineteen</li><li>Test Dictionary 2: twenty-five (25)</li><li>Test Dictionary 2: thirty-one</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[ぶ]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>buchikomu definition 3</li><li>buchikomu definition 4</li></ul></div>",
@@ -1951,7 +1951,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -1981,7 +1981,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
@@ -2136,7 +2136,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 24</li><li>Test Dictionary 2: 30</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 12</li><li>Test Dictionary 2: eighteen</li><li>Test Dictionary 2: twenty-four (24)</li><li>Test Dictionary 2: 30</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[う]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>uchikomu definition 3</li><li>uchikomu definition 4</li></ul></div>",
@@ -2166,7 +2166,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打ち込む",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: 7</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 25</li><li>Test Dictionary 2: 31</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 3</li><li>Test Dictionary 2: seven</li><li>Test Dictionary 2: 13</li><li>Test Dictionary 2: nineteen</li><li>Test Dictionary 2: twenty-five (25)</li><li>Test Dictionary 2: thirty-one</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>ち<ruby>込<rt>こ</rt></ruby>む",
"furigana-plain": "打[ぶ]ち 込[こ]む",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>buchikomu definition 3</li><li>buchikomu definition 4</li></ul></div>",
@@ -2256,7 +2256,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 22</li><li>Test Dictionary 2: 28</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 10</li><li>Test Dictionary 2: sixteen</li><li>Test Dictionary 2: twenty-two (22)</li><li>Test Dictionary 2: 28</li></ul>",
"furigana": "<ruby>打<rt>う</rt></ruby>つ",
"furigana-plain": "打[う]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>utsu definition 3</li><li>utsu definition 4</li></ul></div>",
@@ -2286,7 +2286,7 @@
"dictionary": "Test Dictionary 2",
"document-title": "title",
"expression": "打つ",
- "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: 0</li><li>Test Dictionary 2: 23</li><li>Test Dictionary 2: 29</li></ul>",
+ "frequencies": "<ul style=\"text-align: left;\"><li>Test Dictionary 2: 2</li><li>Test Dictionary 2: 6</li><li>Test Dictionary 2: 11</li><li>Test Dictionary 2: seventeen</li><li>Test Dictionary 2: twenty-three (23)</li><li>Test Dictionary 2: twenty-nine</li></ul>",
"furigana": "<ruby>打<rt>ぶ</rt></ruby>つ",
"furigana-plain": "打[ぶ]つ",
"glossary": "<div style=\"text-align: left;\"><i>(vt, Test Dictionary 2)</i> <ul><li>butsu definition 3</li><li>butsu definition 4</li></ul></div>",
diff --git a/test/data/html/test-document2-script.js b/test/data/html/test-document2-script.js
index 8a183019..f6082802 100644
--- a/test/data/html/test-document2-script.js
+++ b/test/data/html/test-document2-script.js
@@ -16,40 +16,65 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
+/**
+ * @param {Element} element
+ */
function requestFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
+ // @ts-expect-error - Browser compatibility
} else if (element.mozRequestFullScreen) {
+ // @ts-expect-error - Browser compatibility
element.mozRequestFullScreen();
+ // @ts-expect-error - Browser compatibility
} else if (element.webkitRequestFullscreen) {
+ // @ts-expect-error - Browser compatibility
element.webkitRequestFullscreen();
+ // @ts-expect-error - Browser compatibility
} else if (element.msRequestFullscreen) {
+ // @ts-expect-error - Browser compatibility
element.msRequestFullscreen();
}
}
+/** */
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
+ // @ts-expect-error - Browser compatibility
} else if (document.mozCancelFullScreen) {
+ // @ts-expect-error - Browser compatibility
document.mozCancelFullScreen();
+ // @ts-expect-error - Browser compatibility
} else if (document.webkitExitFullscreen) {
+ // @ts-expect-error - Browser compatibility
document.webkitExitFullscreen();
+ // @ts-expect-error - Browser compatibility
} else if (document.msExitFullscreen) {
+ // @ts-expect-error - Browser compatibility
document.msExitFullscreen();
}
}
+/**
+ * @returns {?Element}
+ */
function getFullscreenElement() {
return (
document.fullscreenElement ||
+ // @ts-expect-error - Browser compatibility
document.msFullscreenElement ||
+ // @ts-expect-error - Browser compatibility
document.mozFullScreenElement ||
+ // @ts-expect-error - Browser compatibility
document.webkitFullscreenElement ||
null
);
}
+/**
+ * @param {Element} element
+ */
function toggleFullscreen(element) {
if (getFullscreenElement()) {
exitFullscreen();
@@ -58,6 +83,10 @@ function toggleFullscreen(element) {
}
}
+/**
+ * @param {HTMLElement|DocumentFragment} container
+ * @param {?Element} [fullscreenElement]
+ */
function setup(container, fullscreenElement=null) {
const fullscreenLink = container.querySelector('.fullscreen-link');
if (fullscreenLink !== null) {
@@ -65,6 +94,7 @@ function setup(container, fullscreenElement=null) {
fullscreenElement = container.querySelector('.fullscreen-element');
}
fullscreenLink.addEventListener('click', (e) => {
+ if (fullscreenElement === null) { return; }
toggleFullscreen(fullscreenElement);
e.preventDefault();
return false;
@@ -74,11 +104,15 @@ function setup(container, fullscreenElement=null) {
const template = container.querySelector('template');
const templateContentContainer = container.querySelector('.template-content-container');
if (template !== null && templateContentContainer !== null) {
- const mode = container.dataset.shadowMode;
- const shadow = templateContentContainer.attachShadow({mode});
+ const mode = (container instanceof HTMLElement ? container.dataset.shadowMode : void 0);
+ const shadow = templateContentContainer.attachShadow({
+ mode: (mode === 'open' || mode === 'closed' ? mode : 'open')
+ });
const containerStyles = document.querySelector('#container-styles');
- shadow.appendChild(containerStyles.cloneNode(true));
+ if (containerStyles !== null) {
+ shadow.appendChild(containerStyles.cloneNode(true));
+ }
const content = document.importNode(template.content, true);
setup(content);
diff --git a/test/data/translator-test-results-note-data1.json b/test/data/translator-test-results-note-data1.json
index d686563c..34f7c21a 100644
--- a/test/data/translator-test-results-note-data1.json
+++ b/test/data/translator-test-results-note-data1.json
@@ -1659,7 +1659,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -1672,7 +1672,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -1791,7 +1791,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -1804,7 +1804,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -1963,7 +1963,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -1976,7 +1976,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -1989,7 +1989,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -2095,7 +2095,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -2108,7 +2108,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -2121,7 +2121,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -3651,7 +3651,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -3677,7 +3677,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -3690,7 +3690,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -3813,7 +3813,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -3839,7 +3839,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -3852,7 +3852,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -4045,7 +4045,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -4071,7 +4071,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -4084,7 +4084,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -4097,7 +4097,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -4207,7 +4207,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -4233,7 +4233,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -4246,7 +4246,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -4259,7 +4259,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -5079,7 +5079,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -5092,7 +5092,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -5211,7 +5211,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -5224,7 +5224,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -5385,7 +5385,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -5398,7 +5398,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -5411,7 +5411,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -5517,7 +5517,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -5530,7 +5530,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -5543,7 +5543,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -7394,7 +7394,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -7407,7 +7407,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -7526,7 +7526,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -7539,7 +7539,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -8007,7 +8007,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -8020,7 +8020,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -8033,7 +8033,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -8139,7 +8139,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -8152,7 +8152,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -8165,7 +8165,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -8684,7 +8684,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -8710,7 +8710,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -8723,7 +8723,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -8846,7 +8846,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -8872,7 +8872,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -8885,7 +8885,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -9412,7 +9412,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -9425,7 +9425,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -9544,7 +9544,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -9557,7 +9557,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -10089,7 +10089,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -10115,7 +10115,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -10128,7 +10128,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -10141,7 +10141,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -10251,7 +10251,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -10277,7 +10277,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -10290,7 +10290,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -10303,7 +10303,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -10817,7 +10817,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -10830,7 +10830,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -10843,7 +10843,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -10949,7 +10949,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -10962,7 +10962,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -10975,7 +10975,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -16097,7 +16097,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -16123,7 +16123,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -16136,7 +16136,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -16259,7 +16259,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -16285,7 +16285,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -16298,7 +16298,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -16495,7 +16495,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -16521,7 +16521,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -16534,7 +16534,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -16547,7 +16547,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -16657,7 +16657,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -16683,7 +16683,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -16696,7 +16696,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -16709,7 +16709,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -17529,7 +17529,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -17542,7 +17542,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -17661,7 +17661,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -17674,7 +17674,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -17835,7 +17835,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -17848,7 +17848,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -17861,7 +17861,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -17967,7 +17967,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -17980,7 +17980,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -17993,7 +17993,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -19523,7 +19523,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -19549,7 +19549,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -19562,7 +19562,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -19685,7 +19685,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -19711,7 +19711,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -19724,7 +19724,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -19917,7 +19917,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -19943,7 +19943,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -19956,7 +19956,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -19969,7 +19969,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -20079,7 +20079,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -20105,7 +20105,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -20118,7 +20118,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -20131,7 +20131,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -20951,7 +20951,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -20964,7 +20964,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -21083,7 +21083,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -21096,7 +21096,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -21257,7 +21257,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -21270,7 +21270,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -21283,7 +21283,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -21389,7 +21389,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -21402,7 +21402,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -21415,7 +21415,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -22945,7 +22945,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -22971,7 +22971,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -22984,7 +22984,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -23107,7 +23107,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -23133,7 +23133,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "eighteen"
},
{
"index": 4,
@@ -23146,7 +23146,7 @@
"expression": "打ち込む",
"reading": "うちこむ",
"hasReading": true,
- "frequency": 24
+ "frequency": "twenty-four (24)"
},
{
"index": 5,
@@ -23339,7 +23339,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -23365,7 +23365,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -23378,7 +23378,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -23391,7 +23391,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -23501,7 +23501,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": false,
- "frequency": 7
+ "frequency": "seven"
},
{
"index": 2,
@@ -23527,7 +23527,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 0
+ "frequency": "nineteen"
},
{
"index": 4,
@@ -23540,7 +23540,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 25
+ "frequency": "twenty-five (25)"
},
{
"index": 5,
@@ -23553,7 +23553,7 @@
"expression": "打ち込む",
"reading": "ぶちこむ",
"hasReading": true,
- "frequency": 31
+ "frequency": "thirty-one"
}
],
"pitches": [
@@ -24373,7 +24373,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -24386,7 +24386,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -24505,7 +24505,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "sixteen"
},
{
"index": 4,
@@ -24518,7 +24518,7 @@
"expression": "打つ",
"reading": "うつ",
"hasReading": true,
- "frequency": 22
+ "frequency": "twenty-two (22)"
},
{
"index": 5,
@@ -24679,7 +24679,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -24692,7 +24692,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -24705,7 +24705,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
@@ -24811,7 +24811,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 0
+ "frequency": "seventeen"
},
{
"index": 4,
@@ -24824,7 +24824,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 23
+ "frequency": "twenty-three (23)"
},
{
"index": 5,
@@ -24837,7 +24837,7 @@
"expression": "打つ",
"reading": "ぶつ",
"hasReading": true,
- "frequency": 29
+ "frequency": "twenty-nine"
}
],
"pitches": [],
diff --git a/test/data/translator-test-results.json b/test/data/translator-test-results.json
index 98db0ef4..0a7155b8 100644
--- a/test/data/translator-test-results.json
+++ b/test/data/translator-test-results.json
@@ -1101,8 +1101,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -1112,8 +1112,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -1266,8 +1266,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -1277,8 +1277,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -1288,7 +1288,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
@@ -2150,7 +2150,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -2172,8 +2172,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "eighteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -2183,8 +2183,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 24,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-four (24)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -2337,7 +2337,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -2359,8 +2359,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "nineteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -2370,8 +2370,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 25,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-five (25)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -2381,7 +2381,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 31,
- "displayValue": null,
+ "displayValue": "thirty-one",
"displayValueParsed": false
}
]
@@ -2860,8 +2860,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -2871,8 +2871,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -3027,8 +3027,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -3038,8 +3038,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -3049,7 +3049,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
@@ -4166,8 +4166,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -4177,8 +4177,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -4502,8 +4502,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -4513,8 +4513,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -4524,7 +4524,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
@@ -4860,7 +4860,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -4882,8 +4882,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "eighteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -4893,8 +4893,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 24,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-four (24)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -5216,8 +5216,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -5227,8 +5227,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -5574,7 +5574,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -5596,8 +5596,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "nineteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -5607,8 +5607,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 25,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-five (25)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -5618,7 +5618,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 31,
- "displayValue": null,
+ "displayValue": "thirty-one",
"displayValueParsed": false
}
]
@@ -5930,8 +5930,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -5941,8 +5941,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -5952,7 +5952,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
@@ -9645,7 +9645,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -9667,8 +9667,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "eighteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -9678,8 +9678,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 24,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-four (24)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -9836,7 +9836,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -9858,8 +9858,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "nineteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -9869,8 +9869,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 25,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-five (25)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -9880,7 +9880,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 31,
- "displayValue": null,
+ "displayValue": "thirty-one",
"displayValueParsed": false
}
]
@@ -10359,8 +10359,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -10370,8 +10370,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -10526,8 +10526,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -10537,8 +10537,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -10548,7 +10548,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
@@ -11410,7 +11410,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -11432,8 +11432,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "eighteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -11443,8 +11443,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 24,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-four (24)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -11597,7 +11597,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -11619,8 +11619,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "nineteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -11630,8 +11630,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 25,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-five (25)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -11641,7 +11641,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 31,
- "displayValue": null,
+ "displayValue": "thirty-one",
"displayValueParsed": false
}
]
@@ -12120,8 +12120,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -12131,8 +12131,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -12287,8 +12287,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -12298,8 +12298,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -12309,7 +12309,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
@@ -13171,7 +13171,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -13193,8 +13193,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "eighteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -13204,8 +13204,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 24,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-four (24)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -13358,7 +13358,7 @@
"dictionaryPriority": 0,
"hasReading": false,
"frequency": 7,
- "displayValue": null,
+ "displayValue": "seven",
"displayValueParsed": false
},
{
@@ -13380,8 +13380,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "nineteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -13391,8 +13391,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 25,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-five (25)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -13402,7 +13402,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 31,
- "displayValue": null,
+ "displayValue": "thirty-one",
"displayValueParsed": false
}
]
@@ -13881,8 +13881,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "sixteen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -13892,8 +13892,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 22,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-two (22)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -14048,8 +14048,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 0,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "seventeen",
+ "displayValueParsed": true
},
{
"index": 4,
@@ -14059,8 +14059,8 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 23,
- "displayValue": null,
- "displayValueParsed": false
+ "displayValue": "twenty-three (23)",
+ "displayValueParsed": true
},
{
"index": 5,
@@ -14070,7 +14070,7 @@
"dictionaryPriority": 0,
"hasReading": true,
"frequency": 29,
- "displayValue": null,
+ "displayValue": "twenty-nine",
"displayValueParsed": false
}
]
diff --git a/test/database.test.js b/test/database.test.js
index b53d0e65..80871f95 100644
--- a/test/database.test.js
+++ b/test/database.test.js
@@ -17,6 +17,7 @@
*/
import {IDBFactory, IDBKeyRange} from 'fake-indexeddb';
+import {fileURLToPath} from 'node:url';
import path from 'path';
import {beforeEach, describe, expect, test, vi} from 'vitest';
import {createDictionaryArchive} from '../dev/util.js';
@@ -24,16 +25,27 @@ import {DictionaryDatabase} from '../ext/js/language/dictionary-database.js';
import {DictionaryImporterMediaLoader} from '../ext/js/language/dictionary-importer-media-loader.js';
import {DictionaryImporter} from '../ext/js/language/dictionary-importer.js';
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+
vi.stubGlobal('IDBKeyRange', IDBKeyRange);
vi.mock('../ext/js/language/dictionary-importer-media-loader.js');
+/**
+ * @param {string} dictionary
+ * @param {string} [dictionaryName]
+ * @returns {import('jszip')}
+ */
function createTestDictionaryArchive(dictionary, dictionaryName) {
- const dictionaryDirectory = path.join(__dirname, 'data', 'dictionaries', dictionary);
+ const dictionaryDirectory = path.join(dirname, 'data', 'dictionaries', dictionary);
return createDictionaryArchive(dictionaryDirectory, dictionaryName);
}
+/**
+ * @param {import('dictionary-importer').OnProgressCallback} [onProgress]
+ * @returns {DictionaryImporter}
+ */
function createDictionaryImporter(onProgress) {
const dictionaryImporterMediaLoader = new DictionaryImporterMediaLoader();
return new DictionaryImporter(dictionaryImporterMediaLoader, (...args) => {
@@ -47,24 +59,53 @@ function createDictionaryImporter(onProgress) {
}
+/**
+ * @param {import('dictionary-database').TermEntry[]} dictionaryDatabaseEntries
+ * @param {string} term
+ * @returns {number}
+ */
function countDictionaryDatabaseEntriesWithTerm(dictionaryDatabaseEntries, term) {
return dictionaryDatabaseEntries.reduce((i, v) => (i + (v.term === term ? 1 : 0)), 0);
}
+/**
+ * @param {import('dictionary-database').TermEntry[]} dictionaryDatabaseEntries
+ * @param {string} reading
+ * @returns {number}
+ */
function countDictionaryDatabaseEntriesWithReading(dictionaryDatabaseEntries, reading) {
return dictionaryDatabaseEntries.reduce((i, v) => (i + (v.reading === reading ? 1 : 0)), 0);
}
+/**
+ * @param {import('dictionary-database').TermMeta[]|import('dictionary-database').KanjiMeta[]} metas
+ * @param {import('dictionary-database').TermMetaType|import('dictionary-database').KanjiMetaType} mode
+ * @returns {number}
+ */
function countMetasWithMode(metas, mode) {
- return metas.reduce((i, v) => (i + (v.mode === mode ? 1 : 0)), 0);
+ let i = 0;
+ for (const item of metas) {
+ if (item.mode === mode) { ++i; }
+ }
+ return i;
}
+/**
+ * @param {import('dictionary-database').KanjiEntry[]} kanji
+ * @param {string} character
+ * @returns {number}
+ */
function countKanjiWithCharacter(kanji, character) {
- return kanji.reduce((i, v) => (i + (v.character === character ? 1 : 0)), 0);
+ let i = 0;
+ for (const item of kanji) {
+ if (item.character === character) { ++i; }
+ }
+ return i;
}
+/** */
async function testDatabase1() {
test('Database1', async () => { // Load dictionary data
const testDictionary = createTestDictionaryArchive('valid-dictionary1');
@@ -172,6 +213,9 @@ async function testDatabase1() {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ */
async function testDatabaseEmpty1(database) {
test('DatabaseEmpty1', async () => {
const info = await database.getDictionaryInfo();
@@ -185,17 +229,22 @@ async function testDatabaseEmpty1(database) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {import('dictionary-database').DictionarySet} titles
+ */
async function testFindTermsBulkTest1(database, titles) {
test('FindTermsBulkTest1', async () => {
+ /** @type {{inputs: {matchType: import('dictionary-database').MatchType, termList: string[]}[], expectedResults: {total: number, terms: [key: string, count: number][], readings: [key: string, count: number][]}}[]} */
const data = [
{
inputs: [
{
- matchType: null,
+ matchType: 'exact',
termList: ['打', '打つ', '打ち込む']
},
{
- matchType: null,
+ matchType: 'exact',
termList: ['だ', 'ダース', 'うつ', 'ぶつ', 'うちこむ', 'ぶちこむ']
},
{
@@ -223,7 +272,7 @@ async function testFindTermsBulkTest1(database, titles) {
{
inputs: [
{
- matchType: null,
+ matchType: 'exact',
termList: ['込む']
}
],
@@ -254,7 +303,7 @@ async function testFindTermsBulkTest1(database, titles) {
{
inputs: [
{
- matchType: null,
+ matchType: 'exact',
termList: []
}
],
@@ -281,8 +330,13 @@ async function testFindTermsBulkTest1(database, titles) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {import('dictionary-database').DictionarySet} titles
+ */
async function testTindTermsExactBulk1(database, titles) {
test('TindTermsExactBulk1', async () => {
+ /** @type {{inputs: {termList: {term: string, reading: string}[]}[], expectedResults: {total: number, terms: [key: string, count: number][], readings: [key: string, count: number][]}}[]} */
const data = [
{
inputs: [
@@ -387,8 +441,13 @@ async function testTindTermsExactBulk1(database, titles) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {string} mainDictionary
+ */
async function testFindTermsBySequenceBulk1(database, mainDictionary) {
test('FindTermsBySequenceBulk1', async () => {
+ /** @type {{inputs: {sequenceList: number[]}[], expectedResults: {total: number, terms: [key: string, count: number][], readings: [key: string, count: number][]}}[]} */
const data = [
{
inputs: [
@@ -538,8 +597,13 @@ async function testFindTermsBySequenceBulk1(database, mainDictionary) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {import('dictionary-database').DictionarySet} titles
+ */
async function testFindTermMetaBulk1(database, titles) {
test('FindTermMetaBulk1', async () => {
+ /** @type {{inputs: {termList: string[]}[], expectedResults: {total: number, modes: [key: import('dictionary-database').TermMetaType, count: number][]}}[]} */
const data = [
{
inputs: [
@@ -606,8 +670,13 @@ async function testFindTermMetaBulk1(database, titles) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {import('dictionary-database').DictionarySet} titles
+ */
async function testFindKanjiBulk1(database, titles) {
test('FindKanjiBulk1', async () => {
+ /** @type {{inputs: {kanjiList: string[]}[], expectedResults: {total: number, kanji: [key: string, count: number][]}}[]} */
const data = [
{
inputs: [
@@ -660,8 +729,13 @@ async function testFindKanjiBulk1(database, titles) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {import('dictionary-database').DictionarySet} titles
+ */
async function testFindKanjiMetaBulk1(database, titles) {
test('FindKanjiMetaBulk1', async () => {
+ /** @type {{inputs: {kanjiList: string[]}[], expectedResults: {total: number, modes: [key: import('dictionary-database').KanjiMetaType, count: number][]}}[]} */
const data = [
{
inputs: [
@@ -714,6 +788,10 @@ async function testFindKanjiMetaBulk1(database, titles) {
});
}
+/**
+ * @param {DictionaryDatabase} database
+ * @param {string} title
+ */
async function testFindTagForTitle1(database, title) {
test('FindTagForTitle1', async () => {
const data = [
@@ -769,6 +847,7 @@ async function testFindTagForTitle1(database, title) {
}
+/** */
async function testDatabase2() {
test('Database2', async () => { // Load dictionary data
const testDictionary = createTestDictionaryArchive('valid-dictionary1');
@@ -782,10 +861,12 @@ async function testDatabase2() {
// Setup database
const dictionaryDatabase = new DictionaryDatabase();
+ /** @type {import('dictionary-importer').ImportDetails} */
+ const detaultImportDetails = {prefixWildcardsSupported: false};
// Database not open
- await expect(dictionaryDatabase.deleteDictionary(title, 1000)).rejects.toThrow('Database not open');
- await expect(dictionaryDatabase.findTermsBulk(['?'], titles, null)).rejects.toThrow('Database not open');
+ await expect(dictionaryDatabase.deleteDictionary(title, 1000, () => {})).rejects.toThrow('Database not open');
+ await expect(dictionaryDatabase.findTermsBulk(['?'], titles, 'exact')).rejects.toThrow('Database not open');
await expect(dictionaryDatabase.findTermsExactBulk([{term: '?', reading: '?'}], titles)).rejects.toThrow('Database not open');
await expect(dictionaryDatabase.findTermsBySequenceBulk([{query: 1, dictionary: title}])).rejects.toThrow('Database not open');
await expect(dictionaryDatabase.findTermMetaBulk(['?'], titles)).rejects.toThrow('Database not open');
@@ -794,24 +875,25 @@ async function testDatabase2() {
await expect(dictionaryDatabase.findKanjiMetaBulk(['?'], titles)).rejects.toThrow('Database not open');
await expect(dictionaryDatabase.findTagForTitle('tag', title)).rejects.toThrow('Database not open');
await expect(dictionaryDatabase.getDictionaryInfo()).rejects.toThrow('Database not open');
- await expect(dictionaryDatabase.getDictionaryCounts(titles, true)).rejects.toThrow('Database not open');
- await expect(createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, {})).rejects.toThrow('Database is not ready');
+ await expect(dictionaryDatabase.getDictionaryCounts([...titles.keys()], true)).rejects.toThrow('Database not open');
+ await expect(createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, detaultImportDetails)).rejects.toThrow('Database is not ready');
await dictionaryDatabase.prepare();
// already prepared
await expect(dictionaryDatabase.prepare()).rejects.toThrow('Database already open');
- await createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, {});
+ await createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, detaultImportDetails);
// dictionary already imported
- await expect(createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, {})).rejects.toThrow('Dictionary is already imported');
+ await expect(createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, detaultImportDetails)).rejects.toThrow('Dictionary is already imported');
await dictionaryDatabase.close();
});
}
+/** */
async function testDatabase3() {
const invalidDictionaries = [
'invalid-dictionary1',
@@ -828,12 +910,14 @@ async function testDatabase3() {
test(`${invalidDictionary}`, async () => {
// Setup database
const dictionaryDatabase = new DictionaryDatabase();
+ /** @type {import('dictionary-importer').ImportDetails} */
+ const detaultImportDetails = {prefixWildcardsSupported: false};
await dictionaryDatabase.prepare();
const testDictionary = createTestDictionaryArchive(invalidDictionary);
const testDictionarySource = await testDictionary.generateAsync({type: 'arraybuffer'});
- await expect(createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, {})).rejects.toThrow('Dictionary has invalid data');
+ await expect(createDictionaryImporter().importDictionary(dictionaryDatabase, testDictionarySource, detaultImportDetails)).rejects.toThrow('Dictionary has invalid data');
await dictionaryDatabase.close();
});
}
@@ -841,6 +925,7 @@ async function testDatabase3() {
}
+/** */
async function main() {
beforeEach(async () => {
globalThis.indexedDB = new IDBFactory();
diff --git a/test/deinflector.test.js b/test/deinflector.test.js
index edb85833..bd538428 100644
--- a/test/deinflector.test.js
+++ b/test/deinflector.test.js
@@ -17,12 +17,23 @@
*/
import fs from 'fs';
+import {fileURLToPath} from 'node:url';
import path from 'path';
import {describe, expect, test} from 'vitest';
import {Deinflector} from '../ext/js/language/deinflector.js';
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+
+/**
+ * @param {Deinflector} deinflector
+ * @param {string} source
+ * @param {string} expectedTerm
+ * @param {string} expectedRule
+ * @param {string[]|undefined} expectedReasons
+ * @returns {{has: false, reasons: null, rules: null}|{has: true, reasons: string[], rules: number}}
+ */
function hasTermReasons(deinflector, source, expectedTerm, expectedRule, expectedReasons) {
- for (const {term, reasons, rules} of deinflector.deinflect(source, source)) {
+ for (const {term, reasons, rules} of deinflector.deinflect(source)) {
if (term !== expectedTerm) { continue; }
if (typeof expectedRule !== 'undefined') {
const expectedFlags = Deinflector.rulesToRuleFlags([expectedRule]);
@@ -46,6 +57,7 @@ function hasTermReasons(deinflector, source, expectedTerm, expectedRule, expecte
}
+/** */
function testDeinflections() {
const data = [
{
@@ -915,7 +927,7 @@ function testDeinflections() {
}
];
- const deinflectionReasons = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'ext', 'data/deinflect.json')));
+ const deinflectionReasons = JSON.parse(fs.readFileSync(path.join(dirname, '..', 'ext', 'data/deinflect.json'), {encoding: 'utf8'}));
const deinflector = new Deinflector(deinflectionReasons);
describe('deinflections', () => {
@@ -939,6 +951,7 @@ function testDeinflections() {
}
+/** */
function main() {
testDeinflections();
}
diff --git a/test/dictionary.test.js b/test/dictionary.test.js
index 8f160bc1..e516bd8e 100644
--- a/test/dictionary.test.js
+++ b/test/dictionary.test.js
@@ -24,12 +24,18 @@ import {createDictionaryArchive} from '../dev/util.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
+/**
+ * @param {string} dictionary
+ * @param {string} [dictionaryName]
+ * @returns {import('jszip')}
+ */
function createTestDictionaryArchive(dictionary, dictionaryName) {
const dictionaryDirectory = path.join(dirname, 'data', 'dictionaries', dictionary);
return createDictionaryArchive(dictionaryDirectory, dictionaryName);
}
+/** */
async function main() {
const dictionaries = [
{name: 'valid-dictionary1', valid: true},
diff --git a/test/document-util.test.js b/test/document-util.test.js
index f2552f78..8c6ab69b 100644
--- a/test/document-util.test.js
+++ b/test/document-util.test.js
@@ -30,24 +30,48 @@ const dirname = path.dirname(fileURLToPath(import.meta.url));
// DOMRect class definition
class DOMRect {
+ /**
+ * @param {number} x
+ * @param {number} y
+ * @param {number} width
+ * @param {number} height
+ */
constructor(x, y, width, height) {
+ /** @type {number} */
this._x = x;
+ /** @type {number} */
this._y = y;
+ /** @type {number} */
this._width = width;
+ /** @type {number} */
this._height = height;
}
+ /** @type {number} */
get x() { return this._x; }
+ /** @type {number} */
get y() { return this._y; }
+ /** @type {number} */
get width() { return this._width; }
+ /** @type {number} */
get height() { return this._height; }
+ /** @type {number} */
get left() { return this._x + Math.min(0, this._width); }
+ /** @type {number} */
get right() { return this._x + Math.max(0, this._width); }
+ /** @type {number} */
get top() { return this._y + Math.min(0, this._height); }
+ /** @type {number} */
get bottom() { return this._y + Math.max(0, this._height); }
+ /** @returns {string} */
+ toJSON() { return '<not implemented>'; }
}
+/**
+ * @param {string} fileName
+ * @returns {JSDOM}
+ */
function createJSDOM(fileName) {
const domSource = fs.readFileSync(fileName, {encoding: 'utf8'});
const dom = new JSDOM(domSource);
@@ -65,10 +89,20 @@ function createJSDOM(fileName) {
return dom;
}
+/**
+ * @param {Element} element
+ * @param {string|undefined} selector
+ * @returns {?Element}
+ */
function querySelectorChildOrSelf(element, selector) {
return selector ? element.querySelector(selector) : element;
}
+/**
+ * @param {JSDOM} dom
+ * @param {?Node} node
+ * @returns {?Text|Node}
+ */
function getChildTextNodeOrSelf(dom, node) {
if (node === null) { return null; }
const Node = dom.window.Node;
@@ -76,6 +110,10 @@ function getChildTextNodeOrSelf(dom, node) {
return (childNode !== null && childNode.nodeType === Node.TEXT_NODE ? childNode : node);
}
+/**
+ * @param {unknown} value
+ * @returns {unknown}
+ */
function getPrototypeOfOrNull(value) {
try {
return Object.getPrototypeOf(value);
@@ -84,12 +122,17 @@ function getPrototypeOfOrNull(value) {
}
}
+/**
+ * @param {Document} document
+ * @returns {?Element}
+ */
function findImposterElement(document) {
// Finds the imposter element based on it's z-index style
return document.querySelector('div[style*="2147483646"]>*');
}
+/** */
async function testDocument1() {
const dom = createJSDOM(path.join(dirname, 'data', 'html', 'test-document1.html'));
const window = dom.window;
@@ -102,13 +145,16 @@ async function testDocument1() {
}
}
+/**
+ * @param {JSDOM} dom
+ */
async function testDocumentTextScanningFunctions(dom) {
const document = dom.window.document;
test('DocumentTextScanningFunctions', () => {
- for (const testElement of document.querySelectorAll('.test[data-test-type=scan]')) {
- // Get test parameters
- let {
+ for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('.test[data-test-type=scan]'))) {
+ // Get test parameters
+ const {
elementFromPointSelector,
caretRangeFromPointSelector,
startNodeSelector,
@@ -127,10 +173,10 @@ async function testDocumentTextScanningFunctions(dom) {
const startNode = getChildTextNodeOrSelf(dom, querySelectorChildOrSelf(testElement, startNodeSelector));
const endNode = getChildTextNodeOrSelf(dom, querySelectorChildOrSelf(testElement, endNodeSelector));
- startOffset = parseInt(startOffset, 10);
- endOffset = parseInt(endOffset, 10);
- sentenceScanExtent = parseInt(sentenceScanExtent, 10);
- terminateAtNewlines = (terminateAtNewlines !== 'false');
+ const startOffset2 = parseInt(/** @type {string} */ (startOffset), 10);
+ const endOffset2 = parseInt(/** @type {string} */ (endOffset), 10);
+ const sentenceScanExtent2 = parseInt(/** @type {string} */ (sentenceScanExtent), 10);
+ const terminateAtNewlines2 = (terminateAtNewlines !== 'false');
expect(elementFromPointValue).not.toStrictEqual(null);
expect(caretRangeFromPointValue).not.toStrictEqual(null);
@@ -145,11 +191,25 @@ async function testDocumentTextScanningFunctions(dom) {
expect(!!imposter).toStrictEqual(hasImposter === 'true');
const range = document.createRange();
- range.setStart(imposter ? imposter : startNode, startOffset);
- range.setEnd(imposter ? imposter : startNode, endOffset);
+ range.setStart(/** @type {Node} */ (imposter ? imposter : startNode), startOffset2);
+ range.setEnd(/** @type {Node} */ (imposter ? imposter : startNode), endOffset2);
// Override getClientRects to return a rect guaranteed to contain (x, y)
- range.getClientRects = () => [new DOMRect(x - 1, y - 1, 2, 2)];
+ range.getClientRects = () => {
+ /** @type {import('test/document-types').PseudoDOMRectList} */
+ const domRectList = Object.assign(
+ [new DOMRect(x - 1, y - 1, 2, 2)],
+ {
+ /**
+ * @this {DOMRect[]}
+ * @param {number} index
+ * @returns {DOMRect}
+ */
+ item: function item(index) { return this[index]; }
+ }
+ );
+ return domRectList;
+ };
return range;
};
@@ -192,8 +252,8 @@ async function testDocumentTextScanningFunctions(dom) {
const sentenceActual = DocumentUtil.extractSentence(
source,
false,
- sentenceScanExtent,
- terminateAtNewlines,
+ sentenceScanExtent2,
+ terminateAtNewlines2,
terminatorMap,
forwardQuoteMap,
backwardQuoteMap
@@ -206,13 +266,16 @@ async function testDocumentTextScanningFunctions(dom) {
});
}
+/**
+ * @param {JSDOM} dom
+ */
async function testTextSourceRangeSeekFunctions(dom) {
const document = dom.window.document;
test('TextSourceRangeSeekFunctions', async () => {
- for (const testElement of document.querySelectorAll('.test[data-test-type=text-source-range-seek]')) {
- // Get test parameters
- let {
+ for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('.test[data-test-type=text-source-range-seek]'))) {
+ // Get test parameters
+ const {
seekNodeSelector,
seekNodeIsText,
seekOffset,
@@ -224,34 +287,37 @@ async function testTextSourceRangeSeekFunctions(dom) {
expectedResultContent
} = testElement.dataset;
- seekOffset = parseInt(seekOffset, 10);
- seekLength = parseInt(seekLength, 10);
- expectedResultOffset = parseInt(expectedResultOffset, 10);
+ const seekOffset2 = parseInt(/** @type {string} */ (seekOffset), 10);
+ const seekLength2 = parseInt(/** @type {string} */ (seekLength), 10);
+ const expectedResultOffset2 = parseInt(/** @type {string} */ (expectedResultOffset), 10);
- let seekNode = testElement.querySelector(seekNodeSelector);
- if (seekNodeIsText === 'true') {
+ /** @type {?Node} */
+ let seekNode = testElement.querySelector(/** @type {string} */ (seekNodeSelector));
+ if (seekNodeIsText === 'true' && seekNode !== null) {
seekNode = seekNode.firstChild;
}
- let expectedResultNode = testElement.querySelector(expectedResultNodeSelector);
- if (expectedResultNodeIsText === 'true') {
+ /** @type {?Node} */
+ let expectedResultNode = testElement.querySelector(/** @type {string} */ (expectedResultNodeSelector));
+ if (expectedResultNodeIsText === 'true' && expectedResultNode !== null) {
expectedResultNode = expectedResultNode.firstChild;
}
const {node, offset, content} = (
- seekDirection === 'forward' ?
- new DOMTextScanner(seekNode, seekOffset, true, false).seek(seekLength) :
- new DOMTextScanner(seekNode, seekOffset, true, false).seek(-seekLength)
+ seekDirection === 'forward' ?
+ new DOMTextScanner(/** @type {Node} */ (seekNode), seekOffset2, true, false).seek(seekLength2) :
+ new DOMTextScanner(/** @type {Node} */ (seekNode), seekOffset2, true, false).seek(-seekLength2)
);
expect(node).toStrictEqual(expectedResultNode);
- expect(offset).toStrictEqual(expectedResultOffset);
+ expect(offset).toStrictEqual(expectedResultOffset2);
expect(content).toStrictEqual(expectedResultContent);
}
});
}
+/** */
async function main() {
await testDocument1();
}
diff --git a/test/dom-text-scanner.test.js b/test/dom-text-scanner.test.js
index d1b31276..f6a7410a 100644
--- a/test/dom-text-scanner.test.js
+++ b/test/dom-text-scanner.test.js
@@ -18,15 +18,27 @@
import fs from 'fs';
import {JSDOM} from 'jsdom';
+import {fileURLToPath} from 'node:url';
import path from 'path';
import {expect, test} from 'vitest';
import {DOMTextScanner} from '../ext/js/dom/dom-text-scanner.js';
+const dirname = path.dirname(fileURLToPath(import.meta.url));
+
+/**
+ * @param {string} fileName
+ * @returns {JSDOM}
+ */
function createJSDOM(fileName) {
const domSource = fs.readFileSync(fileName, {encoding: 'utf8'});
return new JSDOM(domSource);
}
+/**
+ * @param {Element} element
+ * @param {string} selector
+ * @returns {?Node}
+ */
function querySelectorTextNode(element, selector) {
let textIndex = -1;
const match = /::text$|::nth-text\((\d+)\)$/.exec(selector);
@@ -35,13 +47,16 @@ function querySelectorTextNode(element, selector) {
selector = selector.substring(0, selector.length - match[0].length);
}
const result = element.querySelector(selector);
+ if (result === null) {
+ return null;
+ }
if (textIndex < 0) {
return result;
}
for (let n = result.firstChild; n !== null; n = n.nextSibling) {
- if (n.nodeType === n.constructor.TEXT_NODE) {
+ if (n.nodeType === /** @type {typeof Node} */ (n.constructor).TEXT_NODE) {
if (textIndex === 0) {
- return n;
+ return /** @type {Text} */ (n);
}
--textIndex;
}
@@ -50,10 +65,16 @@ function querySelectorTextNode(element, selector) {
}
+/**
+ * @param {import('jsdom').DOMWindow} window
+ * @param {(element: Element) => CSSStyleDeclaration} getComputedStyle
+ * @param {?Node} element
+ * @returns {number}
+ */
function getComputedFontSizeInPixels(window, getComputedStyle, element) {
for (; element !== null; element = element.parentNode) {
if (element.nodeType === window.Node.ELEMENT_NODE) {
- const fontSize = getComputedStyle(element).fontSize;
+ const fontSize = getComputedStyle(/** @type {Element} */ (element)).fontSize;
if (fontSize.endsWith('px')) {
const value = parseFloat(fontSize.substring(0, fontSize.length - 2));
return value;
@@ -64,14 +85,19 @@ function getComputedFontSizeInPixels(window, getComputedStyle, element) {
return defaultFontSize;
}
+/**
+ * @param {import('jsdom').DOMWindow} window
+ * @returns {(element: Element, pseudoElement?: ?string) => CSSStyleDeclaration}
+ */
function createAbsoluteGetComputedStyle(window) {
// Wrapper to convert em units to px units
const getComputedStyleOld = window.getComputedStyle.bind(window);
+ /** @type {(element: Element, pseudoElement?: ?string) => CSSStyleDeclaration} */
return (element, ...args) => {
const style = getComputedStyleOld(element, ...args);
return new Proxy(style, {
get: (target, property) => {
- let result = target[property];
+ let result = /** @type {import('core').SafeAny} */ (target)[property];
if (typeof result === 'string') {
result = result.replace(/([-+]?\d(?:\.\d)?(?:[eE][-+]?\d+)?)em/g, (g0, g1) => {
const fontSize = getComputedFontSizeInPixels(window, getComputedStyleOld, element);
@@ -85,12 +111,15 @@ function createAbsoluteGetComputedStyle(window) {
}
+/**
+ * @param {JSDOM} dom
+ */
async function testDomTextScanner(dom) {
const document = dom.window.document;
test('DomTextScanner', () => {
- for (const testElement of document.querySelectorAll('y-test')) {
- let testData = JSON.parse(testElement.dataset.testData);
+ for (const testElement of /** @type {NodeListOf<HTMLElement>} */ (document.querySelectorAll('y-test'))) {
+ let testData = JSON.parse(/** @type {string} */ (testElement.dataset.testData));
if (!Array.isArray(testData)) {
testData = [testData];
}
@@ -159,19 +188,21 @@ async function testDomTextScanner(dom) {
}
+/** */
async function testDocument1() {
- const dom = createJSDOM(path.join(__dirname, 'data', 'html', 'test-dom-text-scanner.html'));
+ const dom = createJSDOM(path.join(dirname, 'data', 'html', 'test-dom-text-scanner.html'));
const window = dom.window;
try {
window.getComputedStyle = createAbsoluteGetComputedStyle(window);
- await testDomTextScanner(dom, {DOMTextScanner});
+ await testDomTextScanner(dom);
} finally {
window.close();
}
}
+/** */
async function main() {
await testDocument1();
}
diff --git a/test/hotkey-util.test.js b/test/hotkey-util.test.js
index 8666b98b..02622c40 100644
--- a/test/hotkey-util.test.js
+++ b/test/hotkey-util.test.js
@@ -19,8 +19,10 @@
import {expect, test} from 'vitest';
import {HotkeyUtil} from '../ext/js/input/hotkey-util.js';
+/** */
function testCommandConversions() {
test('CommandConversions', () => {
+ /** @type {{os: import('environment').OperatingSystem, command: string, expectedCommand: string, expectedInput: {key: string, modifiers: import('input').Modifier[]}}[]} */
const data = [
{os: 'win', command: 'Alt+F', expectedCommand: 'Alt+F', expectedInput: {key: 'KeyF', modifiers: ['alt']}},
{os: 'win', command: 'F1', expectedCommand: 'F1', expectedInput: {key: 'F1', modifiers: []}},
@@ -49,8 +51,10 @@ function testCommandConversions() {
});
}
+/** */
function testDisplayNames() {
test('DisplayNames', () => {
+ /** @type {{os: import('environment').OperatingSystem, key: ?string, modifiers: import('input').Modifier[], expected: string}[]} */
const data = [
{os: 'win', key: null, modifiers: [], expected: ''},
{os: 'win', key: 'KeyF', modifiers: [], expected: 'F'},
@@ -138,8 +142,10 @@ function testDisplayNames() {
});
}
+/** */
function testSortModifiers() {
test('SortModifiers', () => {
+ /** @type {{modifiers: import('input').Modifier[], expected: import('input').Modifier[]}[]} */
const data = [
{modifiers: [], expected: []},
{modifiers: ['shift', 'alt', 'ctrl', 'mouse4', 'meta', 'mouse1', 'mouse0'], expected: ['meta', 'ctrl', 'alt', 'shift', 'mouse0', 'mouse1', 'mouse4']}
@@ -155,6 +161,7 @@ function testSortModifiers() {
}
+/** */
function main() {
testCommandConversions();
testDisplayNames();
diff --git a/test/japanese-util.test.js b/test/japanese-util.test.js
index 47da4ccb..a0078da0 100644
--- a/test/japanese-util.test.js
+++ b/test/japanese-util.test.js
@@ -23,8 +23,10 @@ import * as wanakana from '../ext/lib/wanakana.js';
const jp = new JapaneseUtil(wanakana);
+/** */
function testIsCodePointKanji() {
test('isCodePointKanji', () => {
+ /** @type {[characters: string, expected: boolean][]} */
const data = [
['力方', true],
['\u53f1\u{20b9f}', true],
@@ -34,7 +36,7 @@ function testIsCodePointKanji() {
for (const [characters, expected] of data) {
for (const character of characters) {
- const codePoint = character.codePointAt(0);
+ const codePoint = /** @type {number} */ (character.codePointAt(0));
const actual = jp.isCodePointKanji(codePoint);
expect(actual).toStrictEqual(expected); // `isCodePointKanji failed for ${character} (\\u{${codePoint.toString(16)}})`
}
@@ -42,8 +44,10 @@ function testIsCodePointKanji() {
});
}
+/** */
function testIsCodePointKana() {
test('isCodePointKana', () => {
+ /** @type {[characters: string, expected: boolean][]} */
const data = [
['かたカタ', true],
['力方々kata、。?,.?', false],
@@ -52,7 +56,7 @@ function testIsCodePointKana() {
for (const [characters, expected] of data) {
for (const character of characters) {
- const codePoint = character.codePointAt(0);
+ const codePoint = /** @type {number} */ (character.codePointAt(0));
const actual = jp.isCodePointKana(codePoint);
expect(actual).toStrictEqual(expected); // `isCodePointKana failed for ${character} (\\u{${codePoint.toString(16)}})`
}
@@ -60,8 +64,10 @@ function testIsCodePointKana() {
});
}
+/** */
function testIsCodePointJapanese() {
test('isCodePointJapanese', () => {
+ /** @type {[characters: string, expected: boolean][]} */
const data = [
['かたカタ力方々、。?', true],
['\u53f1\u{20b9f}', true],
@@ -71,7 +77,7 @@ function testIsCodePointJapanese() {
for (const [characters, expected] of data) {
for (const character of characters) {
- const codePoint = character.codePointAt(0);
+ const codePoint = /** @type {number} */ (character.codePointAt(0));
const actual = jp.isCodePointJapanese(codePoint);
expect(actual).toStrictEqual(expected); // `isCodePointJapanese failed for ${character} (\\u{${codePoint.toString(16)}})`
}
@@ -79,8 +85,10 @@ function testIsCodePointJapanese() {
});
}
+/** */
function testIsStringEntirelyKana() {
test('isStringEntirelyKana', () => {
+ /** @type {[string: string, expected: boolean][]} */
const data = [
['かたかな', true],
['カタカナ', true],
@@ -101,8 +109,10 @@ function testIsStringEntirelyKana() {
});
}
+/** */
function testIsStringPartiallyJapanese() {
test('isStringPartiallyJapanese', () => {
+ /** @type {[string: string, expected: boolean][]} */
const data = [
['かたかな', true],
['カタカナ', true],
@@ -124,8 +134,10 @@ function testIsStringPartiallyJapanese() {
});
}
+/** */
function testConvertKatakanaToHiragana() {
test('convertKatakanaToHiragana', () => {
+ /** @type {[string: string, expected: string, keepProlongedSoundMarks?: boolean][]} */
const data = [
['かたかな', 'かたかな'],
['ひらがな', 'ひらがな'],
@@ -146,8 +158,10 @@ function testConvertKatakanaToHiragana() {
});
}
+/** */
function testConvertHiraganaToKatakana() {
test('ConvertHiraganaToKatakana', () => {
+ /** @type {[string: string, expected: string][]} */
const data = [
['かたかな', 'カタカナ'],
['ひらがな', 'ヒラガナ'],
@@ -166,8 +180,10 @@ function testConvertHiraganaToKatakana() {
});
}
+/** */
function testConvertToRomaji() {
test('ConvertToRomaji', () => {
+ /** @type {[string: string, expected: string][]} */
const data = [
['かたかな', 'katakana'],
['ひらがな', 'hiragana'],
@@ -186,8 +202,10 @@ function testConvertToRomaji() {
});
}
+/** */
function testConvertNumericToFullWidth() {
test('ConvertNumericToFullWidth', () => {
+ /** @type {[string: string, expected: string][]} */
const data = [
['0123456789', '0123456789'],
['abcdefghij', 'abcdefghij'],
@@ -201,8 +219,10 @@ function testConvertNumericToFullWidth() {
});
}
+/** */
function testConvertHalfWidthKanaToFullWidth() {
test('ConvertHalfWidthKanaToFullWidth', () => {
+ /** @type {[string: string, expected: string, expectedSourceMapping?: number[]][]} */
const data = [
['0123456789', '0123456789'],
['abcdefghij', 'abcdefghij'],
@@ -227,8 +247,10 @@ function testConvertHalfWidthKanaToFullWidth() {
});
}
+/** */
function testConvertAlphabeticToKana() {
test('ConvertAlphabeticToKana', () => {
+ /** @type {[string: string, expected: string, expectedSourceMapping?: number[]][]} */
const data = [
['0123456789', '0123456789'],
['abcdefghij', 'あbcでfgひj', [1, 1, 1, 2, 1, 1, 2, 1]],
@@ -252,8 +274,10 @@ function testConvertAlphabeticToKana() {
});
}
+/** */
function testDistributeFurigana() {
test('DistributeFurigana', () => {
+ /** @type {[input: [term: string, reading: string], expected: {text: string, reading: string}[]][]} */
const data = [
[
['有り難う', 'ありがとう'],
@@ -719,8 +743,10 @@ function testDistributeFurigana() {
});
}
+/** */
function testDistributeFuriganaInflected() {
test('DistributeFuriganaInflected', () => {
+ /** @type {[input: [term: string, reading: string, source: string], expected: {text: string, reading: string}[]][]} */
const data = [
[
['美味しい', 'おいしい', '美味しかた'],
@@ -770,8 +796,10 @@ function testDistributeFuriganaInflected() {
});
}
+/** */
function testCollapseEmphaticSequences() {
test('CollapseEmphaticSequences', () => {
+ /** @type {[input: [text: string, fullCollapse: boolean], output: [expected: string, expectedSourceMapping: number[]]][]} */
const data = [
[['かこい', false], ['かこい', [1, 1, 1]]],
[['かこい', true], ['かこい', [1, 1, 1]]],
@@ -825,8 +853,10 @@ function testCollapseEmphaticSequences() {
});
}
+/** */
function testIsMoraPitchHigh() {
test('IsMoraPitchHigh', () => {
+ /** @type {[input: [moraIndex: number, pitchAccentDownstepPosition: number], expected: boolean][]} */
const data = [
[[0, 0], false],
[[1, 0], true],
@@ -861,8 +891,10 @@ function testIsMoraPitchHigh() {
});
}
+/** */
function testGetKanaMorae() {
test('GetKanaMorae', () => {
+ /** @type {[text: string, expected: string[]][]} */
const data = [
['かこ', ['か', 'こ']],
['かっこ', ['か', 'っ', 'こ']],
@@ -883,6 +915,7 @@ function testGetKanaMorae() {
}
+/** */
function main() {
testIsCodePointKanji();
testIsCodePointKana();
diff --git a/test/jsconfig.json b/test/jsconfig.json
new file mode 100644
index 00000000..c587abe6
--- /dev/null
+++ b/test/jsconfig.json
@@ -0,0 +1,40 @@
+{
+ "compilerOptions": {
+ "module": "ES2022",
+ "target": "ES2022",
+ "checkJs": true,
+ "moduleResolution": "node",
+ "strict": true,
+ "strictNullChecks": true,
+ "noImplicitAny": true,
+ "strictPropertyInitialization": true,
+ "suppressImplicitAnyIndexErrors": false,
+ "skipLibCheck": false,
+ "baseUrl": ".",
+ "paths": {
+ "*": ["../types/ext/*"],
+ "dev/*": ["../types/dev/*"],
+ "test/*": ["../types/test/*"],
+ "rollup/parseAst": ["../types/other/rollup-parse-ast"]
+ },
+ "types": [
+ "chrome",
+ "firefox-webext-browser",
+ "handlebars",
+ "jszip",
+ "parse5",
+ "wanakana"
+ ]
+ },
+ "include": [
+ "**/*.js",
+ "../ext/**/*.js",
+ "../types/ext/**/*.ts",
+ "../types/dev/**/*.ts",
+ "../types/other/globals.d.ts"
+ ],
+ "exclude": [
+ "../node_modules",
+ "../dev/lib"
+ ]
+} \ No newline at end of file
diff --git a/test/jsdom.test.js b/test/jsdom.test.js
index c53f374e..6c2e00ee 100644
--- a/test/jsdom.test.js
+++ b/test/jsdom.test.js
@@ -26,20 +26,25 @@ import {expect, test} from 'vitest';
*/
function testJSDOMSelectorBug() {
test('JSDOMSelectorBug', () => {
- // nwsapi is used by JSDOM
+ // nwsapi is used by JSDOM
const dom = new JSDOM();
const {document} = dom.window;
const div = document.createElement('div');
div.innerHTML = '<div class="b"><div class="c"></div></div>';
const c = div.querySelector('.c');
- expect(() => c.matches('.a:nth-last-of-type(1) .b .c')).not.toThrow();
+ expect(() => {
+ if (c === null) { throw new Error('Element not found'); }
+ c.matches('.a:nth-last-of-type(1) .b .c');
+ }).not.toThrow();
});
}
+/** */
export function testJSDOM() {
testJSDOMSelectorBug();
}
+/** */
function main() {
testJSDOM();
}
diff --git a/test/json-schema.test.js b/test/json-schema.test.js
index 5370e8da..e534f538 100644
--- a/test/json-schema.test.js
+++ b/test/json-schema.test.js
@@ -19,25 +19,47 @@
import {expect, test} from 'vitest';
import {JsonSchema} from '../ext/js/data/json-schema.js';
+/**
+ * @param {import('json-schema').Schema} schema
+ * @param {unknown} value
+ * @returns {boolean}
+ */
function schemaValidate(schema, value) {
return new JsonSchema(schema).isValid(value);
}
+/**
+ * @param {import('json-schema').Schema} schema
+ * @param {unknown} value
+ * @returns {import('json-schema').Value}
+ */
function getValidValueOrDefault(schema, value) {
return new JsonSchema(schema).getValidValueOrDefault(value);
}
+/**
+ * @param {import('json-schema').Schema} schema
+ * @param {import('json-schema').Value} value
+ * @returns {import('json-schema').Value}
+ */
function createProxy(schema, value) {
return new JsonSchema(schema).createProxy(value);
}
+/**
+ * @template T
+ * @param {T} value
+ * @returns {T}
+ */
function clone(value) {
return JSON.parse(JSON.stringify(value));
}
+/** */
function testValidate1() {
test('Validate1', () => {
+ /** @type {import('json-schema').Schema} */
const schema = {
allOf: [
{
@@ -56,28 +78,34 @@ function testValidate1() {
]
},
{
- not: [
- {multipleOf: 20}
- ]
+ not: {
+ anyOf: [
+ {multipleOf: 20}
+ ]
+ }
}
]
};
+ /**
+ * @param {number} value
+ * @returns {boolean}
+ */
const jsValidate = (value) => {
return (
typeof value === 'number' &&
- (
- (value >= 10 && value <= 100) ||
- (value >= -100 && value <= -10)
- ) &&
- (
(
- (value % 3) === 0 ||
- (value % 5) === 0
+ (value >= 10 && value <= 100) ||
+ (value >= -100 && value <= -10)
+ ) &&
+ (
+ (
+ (value % 3) === 0 ||
+ (value % 5) === 0
+ ) &&
+ (value % 15) !== 0
) &&
- (value % 15) !== 0
- ) &&
- (value % 20) !== 0
+ (value % 20) !== 0
);
};
@@ -89,10 +117,12 @@ function testValidate1() {
});
}
+/** */
function testValidate2() {
test('Validate2', () => {
+ /** @type {{schema: import('json-schema').Schema, inputs: {expected: boolean, value: unknown}[]}[]} */
const data = [
- // String tests
+ // String tests
{
schema: {
type: 'string'
@@ -494,10 +524,12 @@ function testValidate2() {
}
+/** */
function testGetValidValueOrDefault1() {
test('GetValidValueOrDefault1', () => {
+ /** @type {{schema: import('json-schema').Schema, inputs: [value: unknown, expected: unknown][]}[]} */
const data = [
- // Test value defaulting on objects with additionalProperties=false
+ // Test value defaulting on objects with additionalProperties=false
{
schema: {
type: 'object',
@@ -667,10 +699,10 @@ function testGetValidValueOrDefault1() {
type: 'object',
required: ['toString'],
properties: {
- toString: {
+ toString: /** @type {import('json-schema').SchemaObject} */ ({
type: 'string',
default: 'default'
- }
+ })
}
},
inputs: [
@@ -850,10 +882,12 @@ function testGetValidValueOrDefault1() {
}
+/** */
function testProxy1() {
test('Proxy1', () => {
+ /** @type {{schema: import('json-schema').Schema, tests: {error: boolean, value?: import('json-schema').Value, action: (value: import('core').SafeAny) => void}[]}[]} */
const data = [
- // Object tests
+ // Object tests
{
schema: {
type: 'object',
@@ -998,6 +1032,7 @@ function testProxy1() {
}
+/** */
function main() {
testValidate1();
testValidate2();
diff --git a/test/object-property-accessor.test.js b/test/object-property-accessor.test.js
index a8730093..4d50b1e9 100644
--- a/test/object-property-accessor.test.js
+++ b/test/object-property-accessor.test.js
@@ -19,6 +19,9 @@
import {expect, test} from 'vitest';
import {ObjectPropertyAccessor} from '../ext/js/general/object-property-accessor.js';
+/**
+ * @returns {import('core').UnknownObject}
+ */
function createTestObject() {
return {
0: null,
@@ -36,8 +39,10 @@ function createTestObject() {
}
+/** */
function testGet1() {
test('Get1', () => {
+ /** @type {[pathArray: (string|number)[], getExpected: (object: import('core').SafeAny) => unknown][]} */
const data = [
[[], (object) => object],
[['0'], (object) => object['0']],
@@ -61,11 +66,13 @@ function testGet1() {
});
}
+/** */
function testGet2() {
test('Get2', () => {
const object = createTestObject();
const accessor = new ObjectPropertyAccessor(object);
+ /** @type {[pathArray: (string|number)[], message: string][]} */
const data = [
[[0], 'Invalid path: [0]'],
[['0', 'invalid'], 'Invalid path: ["0"].invalid'],
@@ -95,9 +102,11 @@ function testGet2() {
}
+/** */
function testSet1() {
test('Set1', () => {
const testValue = {};
+ /** @type {(string|number)[][]} */
const data = [
['0'],
['value1', 'value2'],
@@ -120,12 +129,14 @@ function testSet1() {
});
}
+/** */
function testSet2() {
test('Set2', () => {
const object = createTestObject();
const accessor = new ObjectPropertyAccessor(object);
const testValue = {};
+ /** @type {[pathArray: (string|number)[], message: string][]} */
const data = [
[[], 'Invalid path'],
[[0], 'Invalid path: [0]'],
@@ -148,10 +159,17 @@ function testSet2() {
}
+/** */
function testDelete1() {
test('Delete1', () => {
+ /**
+ * @param {unknown} object
+ * @param {string} property
+ * @returns {boolean}
+ */
const hasOwn = (object, property) => Object.prototype.hasOwnProperty.call(object, property);
+ /** @type {[pathArray: (string|number)[], validate: (object: import('core').SafeAny) => boolean][]} */
const data = [
[['0'], (object) => !hasOwn(object, '0')],
[['value1', 'value2'], (object) => !hasOwn(object.value1, 'value2')],
@@ -171,8 +189,10 @@ function testDelete1() {
});
}
+/** */
function testDelete2() {
test('Delete2', () => {
+ /** @type {[pathArray: (string|number)[], message: string][]} */
const data = [
[[], 'Invalid path'],
[[0], 'Invalid path: [0]'],
@@ -201,8 +221,10 @@ function testDelete2() {
}
+/** */
function testSwap1() {
test('Swap1', () => {
+ /** @type {[pathArray: (string|number)[], compareValues: boolean][]} */
const data = [
[['0'], true],
[['value1', 'value2'], true],
@@ -237,8 +259,10 @@ function testSwap1() {
});
}
+/** */
function testSwap2() {
test('Swap2', () => {
+ /** @type {[pathArray1: (string|number)[], pathArray2: (string|number)[], checkRevert: boolean, message: string][]} */
const data = [
[[], [], false, 'Invalid path 1'],
[['0'], [], false, 'Invalid path 2'],
@@ -276,8 +300,10 @@ function testSwap2() {
}
+/** */
function testGetPathString1() {
test('GetPathString1', () => {
+ /** @type {[pathArray: (string|number)[], expected: string][]} */
const data = [
[[], ''],
[[0], '[0]'],
@@ -298,22 +324,27 @@ function testGetPathString1() {
});
}
+/** */
function testGetPathString2() {
test('GetPathString2', () => {
+ /** @type {[pathArray: unknown[], message: string][]} */
const data = [
[[1.5], 'Invalid index'],
[[null], 'Invalid type: object']
];
for (const [pathArray, message] of data) {
+ // @ts-expect-error - Throwing is expected
expect(() => ObjectPropertyAccessor.getPathString(pathArray)).toThrow(message);
}
});
}
+/** */
function testGetPathArray1() {
test('GetPathArray1', () => {
+ /** @type {[pathString: string, pathArray: (string|number)[]][]} */
const data = [
['', []],
['[0]', [0]],
@@ -338,8 +369,10 @@ function testGetPathArray1() {
});
}
+/** */
function testGetPathArray2() {
test('GetPathArray2', () => {
+ /** @type {[pathString: string, message: string][]} */
const data = [
['?', 'Unexpected character: ?'],
['.', 'Unexpected character: .'],
@@ -372,8 +405,10 @@ function testGetPathArray2() {
}
+/** */
function testHasProperty() {
test('HasProperty', () => {
+ /** @type {[object: unknown, property: unknown, expected: boolean][]} */
const data = [
[{}, 'invalid', false],
[{}, 0, false],
@@ -389,13 +424,16 @@ function testHasProperty() {
];
for (const [object, property, expected] of data) {
+ // @ts-expect-error - Ignore potentially property types
expect(ObjectPropertyAccessor.hasProperty(object, property)).toStrictEqual(expected);
}
});
}
+/** */
function testIsValidPropertyType() {
test('IsValidPropertyType', () => {
+ /** @type {[object: unknown, property: unknown, expected: boolean][]} */
const data = [
[{}, 'invalid', true],
[{}, 0, false],
@@ -411,12 +449,14 @@ function testIsValidPropertyType() {
];
for (const [object, property, expected] of data) {
+ // @ts-expect-error - Ignore potentially property types
expect(ObjectPropertyAccessor.isValidPropertyType(object, property)).toStrictEqual(expected);
}
});
}
+/** */
function main() {
testGet1();
testGet2();
diff --git a/test/options-util.test.js b/test/options-util.test.js
index ff5b6713..7845d759 100644
--- a/test/options-util.test.js
+++ b/test/options-util.test.js
@@ -24,7 +24,12 @@ import {OptionsUtil} from '../ext/js/data/options-util.js';
import {TemplatePatcher} from '../ext/js/templates/template-patcher.js';
const dirname = path.dirname(fileURLToPath(import.meta.url));
-vi.stubGlobal('fetch', async function fetch(url2) {
+
+/**
+ * @param {string} url2
+ * @returns {Promise<import('dev/vm').PseudoFetchResponse>}
+ */
+async function fetch(url2) {
const filePath = url.fileURLToPath(url2);
await Promise.resolve();
const content = fs.readFileSync(filePath, {encoding: null});
@@ -35,15 +40,22 @@ vi.stubGlobal('fetch', async function fetch(url2) {
text: async () => Promise.resolve(content.toString('utf8')),
json: async () => Promise.resolve(JSON.parse(content.toString('utf8')))
};
-});
-vi.stubGlobal('chrome', {
+}
+/** @type {import('dev/vm').PseudoChrome} */
+const chrome = {
runtime: {
- getURL: (path2) => {
+ getURL(path2) {
return url.pathToFileURL(path.join(dirname, '..', 'ext', path2.replace(/^\//, ''))).href;
}
}
-});
+};
+
+vi.stubGlobal('fetch', fetch);
+vi.stubGlobal('chrome', chrome);
+/**
+ * @returns {unknown}
+ */
function createProfileOptionsTestData1() {
return {
version: 14,
@@ -144,6 +156,9 @@ function createProfileOptionsTestData1() {
};
}
+/**
+ * @returns {unknown}
+ */
function createOptionsTestData1() {
return {
profiles: [
@@ -243,6 +258,9 @@ function createOptionsTestData1() {
}
+/**
+ * @returns {unknown}
+ */
function createProfileOptionsUpdatedTestData1() {
return {
general: {
@@ -519,6 +537,9 @@ function createProfileOptionsUpdatedTestData1() {
};
}
+/**
+ * @returns {unknown}
+ */
function createOptionsUpdatedTestData1() {
return {
profiles: [
@@ -612,6 +633,7 @@ function createOptionsUpdatedTestData1() {
}
+/** */
async function testUpdate() {
test('Update', async () => {
const optionsUtil = new OptionsUtil();
@@ -624,8 +646,10 @@ async function testUpdate() {
});
}
+/** */
async function testDefault() {
test('Default', async () => {
+ /** @type {((options: import('options-util').IntermediateOptions) => void)[]} */
const data = [
(options) => options,
(options) => {
@@ -651,12 +675,17 @@ async function testDefault() {
});
}
+/** */
async function testFieldTemplatesUpdate() {
test('FieldTemplatesUpdate', async () => {
const optionsUtil = new OptionsUtil();
await optionsUtil.prepare();
const templatePatcher = new TemplatePatcher();
+ /**
+ * @param {string} fileName
+ * @returns {string}
+ */
const loadDataFile = (fileName) => {
const content = fs.readFileSync(path.join(dirname, '..', 'ext', fileName), {encoding: 'utf8'});
return templatePatcher.parsePatch(content).addition;
@@ -671,6 +700,11 @@ async function testFieldTemplatesUpdate() {
{version: 13, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v13.handlebars')},
{version: 21, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v21.handlebars')}
];
+ /**
+ * @param {number} startVersion
+ * @param {number} targetVersion
+ * @returns {string}
+ */
const getUpdateAdditions = (startVersion, targetVersion) => {
let value = '';
for (const {version, changes} of updates) {
@@ -682,7 +716,7 @@ async function testFieldTemplatesUpdate() {
};
const data = [
- // Standard format
+ // Standard format
{
oldVersion: 0,
newVersion: 12,
@@ -1564,7 +1598,7 @@ async function testFieldTemplatesUpdate() {
const updatesPattern = /<<<UPDATE-ADDITIONS>>>/g;
for (const {old, expected, oldVersion, newVersion} of data) {
- const options = createOptionsTestData1();
+ const options = /** @type {import('core').SafeAny} */ (createOptionsTestData1());
options.profiles[0].options.anki.fieldTemplates = old;
options.version = oldVersion;
@@ -1578,6 +1612,7 @@ async function testFieldTemplatesUpdate() {
}
+/** */
async function main() {
await testUpdate();
await testDefault();
diff --git a/test/playwright/integration.spec.js b/test/playwright/integration.spec.js
index b9a86d84..c8cf2f6d 100644
--- a/test/playwright/integration.spec.js
+++ b/test/playwright/integration.spec.js
@@ -45,7 +45,8 @@ test('search clipboard', async ({page, extensionId}) => {
test('anki add', async ({context, page, extensionId}) => {
// mock anki routes
- let resolve;
+ /** @type {?(value: unknown) => void} */
+ let resolve = null;
const addNotePromise = new Promise((res) => {
resolve = res;
});
@@ -53,7 +54,7 @@ test('anki add', async ({context, page, extensionId}) => {
mockAnkiRouteHandler(route);
const req = route.request();
if (req.url().includes('127.0.0.1:8765') && req.postDataJSON().action === 'addNote') {
- resolve(req.postDataJSON());
+ /** @type {(value: unknown) => void} */ (resolve)(req.postDataJSON());
}
});
@@ -63,7 +64,11 @@ test('anki add', async ({context, page, extensionId}) => {
// load in test dictionary
const dictionary = createDictionaryArchive(path.join(root, 'test/data/dictionaries/valid-dictionary1'), 'valid-dictionary1');
const testDictionarySource = await dictionary.generateAsync({type: 'arraybuffer'});
- await page.locator('input[id="dictionary-import-file-input"]').setInputFiles({name: 'valid-dictionary1.zip', buffer: Buffer.from(testDictionarySource)});
+ await page.locator('input[id="dictionary-import-file-input"]').setInputFiles({
+ name: 'valid-dictionary1.zip',
+ mimeType: 'application/x-zip',
+ buffer: Buffer.from(testDictionarySource)
+ });
await expect(page.locator('id=dictionaries')).toHaveText('Dictionaries (1 installed, 1 enabled)', {timeout: 5 * 60 * 1000});
// connect to anki
@@ -75,7 +80,7 @@ test('anki add', async ({context, page, extensionId}) => {
await page.locator('select.anki-card-deck').selectOption('Mock Deck');
await page.locator('select.anki-card-model').selectOption('Mock Model');
for (const modelField of mockModelFieldNames) {
- await page.locator(`[data-setting="anki.terms.fields.${modelField}"]`).fill(mockModelFieldsToAnkiValues[modelField]);
+ await page.locator(`[data-setting="anki.terms.fields.${modelField}"]`).fill(/** @type {string} */ (mockModelFieldsToAnkiValues[modelField]));
}
await page.locator('#anki-cards-modal > div > div.modal-footer > button:nth-child(2)').click();
await writeToClipboardFromPage(page, '読むの例文');
diff --git a/test/playwright/playwright-util.js b/test/playwright/playwright-util.js
index 5ceb92fd..ac68db4d 100644
--- a/test/playwright/playwright-util.js
+++ b/test/playwright/playwright-util.js
@@ -55,6 +55,7 @@ export const mockModelFieldNames = [
'Sentence'
];
+/** @type {{[key: string]: string|undefined}} */
export const mockModelFieldsToAnkiValues = {
'Word': '{expression}',
'Reading': '{furigana-plain}',
@@ -62,6 +63,10 @@ export const mockModelFieldsToAnkiValues = {
'Audio': '{audio}'
};
+/**
+ * @param {import('playwright').Route} route
+ * @returns {Promise<void>|undefined}
+ */
export const mockAnkiRouteHandler = (route) => {
const reqBody = route.request().postDataJSON();
const respBody = ankiRouteResponses[reqBody.action];
@@ -71,6 +76,11 @@ export const mockAnkiRouteHandler = (route) => {
route.fulfill(respBody);
};
+/**
+ * @param {import('playwright').Page} page
+ * @param {string} text
+ * @returns {Promise<void>}
+ */
export const writeToClipboardFromPage = async (page, text) => {
await page.evaluate(`navigator.clipboard.writeText('${text}')`);
};
@@ -100,6 +110,7 @@ const baseAnkiResp = {
contentType: 'text/json'
};
+/** @type {{[key: string]: import('core').SerializableObject}} */
const ankiRouteResponses = {
'version': Object.assign({body: JSON.stringify(6)}, baseAnkiResp),
'deckNames': Object.assign({body: JSON.stringify(['Mock Deck'])}, baseAnkiResp),
diff --git a/test/playwright/visual.spec.js b/test/playwright/visual.spec.js
index 2f46990f..8b48b7c0 100644
--- a/test/playwright/visual.spec.js
+++ b/test/playwright/visual.spec.js
@@ -48,10 +48,16 @@ test('visual', async ({page, extensionId}) => {
// take a screenshot of the settings page with jmdict loaded
await expect.soft(page).toHaveScreenshot('settings-jmdict-loaded.png', {mask: [storage_locator]});
+ /**
+ * @param {number} doc_number
+ * @param {number} test_number
+ * @param {import('@playwright/test').ElementHandle<Node>} el
+ * @param {{x: number, y: number}} offset
+ */
const screenshot = async (doc_number, test_number, el, offset) => {
const test_name = 'doc' + doc_number + '-test' + test_number;
- const box = await el.boundingBox();
+ const box = (await el.boundingBox()) || {x: 0, y: 0, width: 0, height: 0};
// find the popup frame if it exists
let popup_frame = page.frames().find((f) => f.url().includes('popup.html'));
@@ -66,7 +72,7 @@ test('visual', async ({page, extensionId}) => {
popup_frame = await frame_attached; // wait for popup to be attached
}
try {
- await (await popup_frame.frameElement()).waitForElementState('visible', {timeout: 500}); // some tests don't have a popup, so don't fail if it's not there; TODO: check if the popup is expected to be there
+ await (await /** @type {import('@playwright/test').Frame} */ (popup_frame).frameElement()).waitForElementState('visible', {timeout: 500}); // some tests don't have a popup, so don't fail if it's not there; TODO: check if the popup is expected to be there
} catch (error) {
console.log(test_name + ' has no popup');
}
@@ -75,7 +81,7 @@ test('visual', async ({page, extensionId}) => {
await expect.soft(page).toHaveScreenshot(test_name + '.png');
await page.mouse.click(0, 0); // click away so popup disappears
- await (await popup_frame.frameElement()).waitForElementState('hidden'); // wait for popup to disappear
+ await (await /** @type {import('@playwright/test').Frame} */ (popup_frame).frameElement()).waitForElementState('hidden'); // wait for popup to disappear
};
// Load test-document1.html
diff --git a/test/profile-conditions-util.test.js b/test/profile-conditions-util.test.js
index ca8b00ef..62b21555 100644
--- a/test/profile-conditions-util.test.js
+++ b/test/profile-conditions-util.test.js
@@ -19,31 +19,33 @@
import {expect, test} from 'vitest';
import {ProfileConditionsUtil} from '../ext/js/background/profile-conditions-util.js';
+/** */
function testNormalizeContext() {
test('NormalizeContext', () => {
+ /** @type {{context: import('settings').OptionsContext, expected: import('profile-conditions-util').NormalizedOptionsContext}[]} */
const data = [
- // Empty
+ // Empty
{
- context: {},
- expected: {flags: []}
+ context: {index: 0},
+ expected: {index: 0, flags: []}
},
// Domain normalization
{
- context: {url: ''},
- expected: {url: '', flags: []}
+ context: {depth: 0, url: ''},
+ expected: {depth: 0, url: '', flags: []}
},
{
- context: {url: 'http://example.com/'},
- expected: {url: 'http://example.com/', domain: 'example.com', flags: []}
+ context: {depth: 0, url: 'http://example.com/'},
+ expected: {depth: 0, url: 'http://example.com/', domain: 'example.com', flags: []}
},
{
- context: {url: 'http://example.com:1234/'},
- expected: {url: 'http://example.com:1234/', domain: 'example.com', flags: []}
+ context: {depth: 0, url: 'http://example.com:1234/'},
+ expected: {depth: 0, url: 'http://example.com:1234/', domain: 'example.com', flags: []}
},
{
- context: {url: 'http://user@example.com:1234/'},
- expected: {url: 'http://user@example.com:1234/', domain: 'example.com', flags: []}
+ context: {depth: 0, url: 'http://user@example.com:1234/'},
+ expected: {depth: 0, url: 'http://user@example.com:1234/', domain: 'example.com', flags: []}
}
];
@@ -55,15 +57,17 @@ function testNormalizeContext() {
});
}
+/** */
function testSchemas() {
test('Schemas', () => {
+ /** @type {{conditionGroups: import('settings').ProfileConditionGroup[], expectedSchema?: import('json-schema').Schema, inputs?: {expected: boolean, context: import('settings').OptionsContext}[]}[]} */
const data = [
- // Empty
+ // Empty
{
conditionGroups: [],
expectedSchema: {},
inputs: [
- {expected: true, context: {url: 'http://example.com/'}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/'}}
]
},
{
@@ -72,7 +76,7 @@ function testSchemas() {
],
expectedSchema: {},
inputs: [
- {expected: true, context: {url: 'http://example.com/'}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/'}}
]
},
{
@@ -82,7 +86,7 @@ function testSchemas() {
],
expectedSchema: {},
inputs: [
- {expected: true, context: {url: 'http://example.com/'}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/'}}
]
},
@@ -124,14 +128,16 @@ function testSchemas() {
}
],
expectedSchema: {
- not: [
- {
- properties: {
- depth: {const: 0}
- },
- required: ['depth']
- }
- ]
+ not: {
+ anyOf: [
+ {
+ properties: {
+ depth: {const: 0}
+ },
+ required: ['depth']
+ }
+ ]
+ }
},
inputs: [
{expected: false, context: {depth: 0, url: 'http://example.com/'}},
@@ -371,9 +377,9 @@ function testSchemas() {
},
inputs: [
{expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -383,7 +389,7 @@ function testSchemas() {
{
type: 'modifierKeys',
operator: 'are',
- value: 'Alt, Shift'
+ value: 'alt, shift'
}
]
}
@@ -395,8 +401,8 @@ function testSchemas() {
maxItems: 2,
minItems: 2,
allOf: [
- {contains: {const: 'Alt'}},
- {contains: {const: 'Shift'}}
+ {contains: {const: 'alt'}},
+ {contains: {const: 'shift'}}
]
}
},
@@ -404,9 +410,9 @@ function testSchemas() {
},
inputs: [
{expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -422,24 +428,26 @@ function testSchemas() {
}
],
expectedSchema: {
- not: [
- {
- properties: {
- modifierKeys: {
- type: 'array',
- maxItems: 0,
- minItems: 0
- }
- },
- required: ['modifierKeys']
- }
- ]
+ not: {
+ anyOf: [
+ {
+ properties: {
+ modifierKeys: {
+ type: 'array',
+ maxItems: 0,
+ minItems: 0
+ }
+ },
+ required: ['modifierKeys']
+ }
+ ]
+ }
},
inputs: [
{expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -449,34 +457,36 @@ function testSchemas() {
{
type: 'modifierKeys',
operator: 'areNot',
- value: 'Alt, Shift'
+ value: 'alt, shift'
}
]
}
],
expectedSchema: {
- not: [
- {
- properties: {
- modifierKeys: {
- type: 'array',
- maxItems: 2,
- minItems: 2,
- allOf: [
- {contains: {const: 'Alt'}},
- {contains: {const: 'Shift'}}
- ]
- }
- },
- required: ['modifierKeys']
- }
- ]
+ not: {
+ anyOf: [
+ {
+ properties: {
+ modifierKeys: {
+ type: 'array',
+ maxItems: 2,
+ minItems: 2,
+ allOf: [
+ {contains: {const: 'alt'}},
+ {contains: {const: 'shift'}}
+ ]
+ }
+ },
+ required: ['modifierKeys']
+ }
+ ]
+ }
},
inputs: [
{expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -502,9 +512,9 @@ function testSchemas() {
},
inputs: [
{expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -514,7 +524,7 @@ function testSchemas() {
{
type: 'modifierKeys',
operator: 'include',
- value: 'Alt, Shift'
+ value: 'alt, shift'
}
]
}
@@ -525,8 +535,8 @@ function testSchemas() {
type: 'array',
minItems: 2,
allOf: [
- {contains: {const: 'Alt'}},
- {contains: {const: 'Shift'}}
+ {contains: {const: 'alt'}},
+ {contains: {const: 'shift'}}
]
}
},
@@ -534,9 +544,9 @@ function testSchemas() {
},
inputs: [
{expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -561,9 +571,9 @@ function testSchemas() {
},
inputs: [
{expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
{
@@ -573,7 +583,7 @@ function testSchemas() {
{
type: 'modifierKeys',
operator: 'notInclude',
- value: 'Alt, Shift'
+ value: 'alt, shift'
}
]
}
@@ -582,19 +592,21 @@ function testSchemas() {
properties: {
modifierKeys: {
type: 'array',
- not: [
- {contains: {const: 'Alt'}},
- {contains: {const: 'Shift'}}
- ]
+ not: {
+ anyOf: [
+ {contains: {const: 'alt'}},
+ {contains: {const: 'shift'}}
+ ]
+ }
}
},
required: ['modifierKeys']
},
inputs: [
{expected: true, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}},
- {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}}
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt']}},
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift']}},
+ {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['alt', 'shift', 'ctrl']}}
]
},
@@ -622,11 +634,13 @@ function testSchemas() {
}
},
inputs: [
- {expected: true, context: {}},
- {expected: true, context: {flags: []}},
- {expected: false, context: {flags: ['test1']}},
- {expected: false, context: {flags: ['test1', 'test2']}},
- {expected: false, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: true, context: {depth: 0, url: ''}},
+ {expected: true, context: {depth: 0, url: '', flags: []}},
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -636,7 +650,7 @@ function testSchemas() {
{
type: 'flags',
operator: 'are',
- value: 'test1, test2'
+ value: 'clipboard, test2'
}
]
}
@@ -649,18 +663,20 @@ function testSchemas() {
maxItems: 2,
minItems: 2,
allOf: [
- {contains: {const: 'test1'}},
+ {contains: {const: 'clipboard'}},
{contains: {const: 'test2'}}
]
}
}
},
inputs: [
- {expected: false, context: {}},
- {expected: false, context: {flags: []}},
- {expected: false, context: {flags: ['test1']}},
- {expected: true, context: {flags: ['test1', 'test2']}},
- {expected: false, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: false, context: {depth: 0, url: ''}},
+ {expected: false, context: {depth: 0, url: '', flags: []}},
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -676,25 +692,29 @@ function testSchemas() {
}
],
expectedSchema: {
- not: [
- {
- required: ['flags'],
- properties: {
- flags: {
- type: 'array',
- maxItems: 0,
- minItems: 0
+ not: {
+ anyOf: [
+ {
+ required: ['flags'],
+ properties: {
+ flags: {
+ type: 'array',
+ maxItems: 0,
+ minItems: 0
+ }
}
}
- }
- ]
+ ]
+ }
},
inputs: [
- {expected: false, context: {}},
- {expected: false, context: {flags: []}},
- {expected: true, context: {flags: ['test1']}},
- {expected: true, context: {flags: ['test1', 'test2']}},
- {expected: true, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: false, context: {depth: 0, url: ''}},
+ {expected: false, context: {depth: 0, url: '', flags: []}},
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -704,35 +724,39 @@ function testSchemas() {
{
type: 'flags',
operator: 'areNot',
- value: 'test1, test2'
+ value: 'clipboard, test2'
}
]
}
],
expectedSchema: {
- not: [
- {
- required: ['flags'],
- properties: {
- flags: {
- type: 'array',
- maxItems: 2,
- minItems: 2,
- allOf: [
- {contains: {const: 'test1'}},
- {contains: {const: 'test2'}}
- ]
+ not: {
+ anyOf: [
+ {
+ required: ['flags'],
+ properties: {
+ flags: {
+ type: 'array',
+ maxItems: 2,
+ minItems: 2,
+ allOf: [
+ {contains: {const: 'clipboard'}},
+ {contains: {const: 'test2'}}
+ ]
+ }
}
}
- }
- ]
+ ]
+ }
},
inputs: [
- {expected: true, context: {}},
- {expected: true, context: {flags: []}},
- {expected: true, context: {flags: ['test1']}},
- {expected: false, context: {flags: ['test1', 'test2']}},
- {expected: true, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: true, context: {depth: 0, url: ''}},
+ {expected: true, context: {depth: 0, url: '', flags: []}},
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -757,11 +781,13 @@ function testSchemas() {
}
},
inputs: [
- {expected: true, context: {}},
- {expected: true, context: {flags: []}},
- {expected: true, context: {flags: ['test1']}},
- {expected: true, context: {flags: ['test1', 'test2']}},
- {expected: true, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: true, context: {depth: 0, url: ''}},
+ {expected: true, context: {depth: 0, url: '', flags: []}},
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -771,7 +797,7 @@ function testSchemas() {
{
type: 'flags',
operator: 'include',
- value: 'test1, test2'
+ value: 'clipboard, test2'
}
]
}
@@ -783,18 +809,20 @@ function testSchemas() {
type: 'array',
minItems: 2,
allOf: [
- {contains: {const: 'test1'}},
+ {contains: {const: 'clipboard'}},
{contains: {const: 'test2'}}
]
}
}
},
inputs: [
- {expected: false, context: {}},
- {expected: false, context: {flags: []}},
- {expected: false, context: {flags: ['test1']}},
- {expected: true, context: {flags: ['test1', 'test2']}},
- {expected: true, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: false, context: {depth: 0, url: ''}},
+ {expected: false, context: {depth: 0, url: '', flags: []}},
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -818,11 +846,13 @@ function testSchemas() {
}
},
inputs: [
- {expected: true, context: {}},
- {expected: true, context: {flags: []}},
- {expected: true, context: {flags: ['test1']}},
- {expected: true, context: {flags: ['test1', 'test2']}},
- {expected: true, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: true, context: {depth: 0, url: ''}},
+ {expected: true, context: {depth: 0, url: '', flags: []}},
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
{
@@ -832,7 +862,7 @@ function testSchemas() {
{
type: 'flags',
operator: 'notInclude',
- value: 'test1, test2'
+ value: 'clipboard, test2'
}
]
}
@@ -842,19 +872,23 @@ function testSchemas() {
properties: {
flags: {
type: 'array',
- not: [
- {contains: {const: 'test1'}},
- {contains: {const: 'test2'}}
- ]
+ not: {
+ anyOf: [
+ {contains: {const: 'clipboard'}},
+ {contains: {const: 'test2'}}
+ ]
+ }
}
}
},
inputs: [
- {expected: true, context: {}},
- {expected: true, context: {flags: []}},
- {expected: false, context: {flags: ['test1']}},
- {expected: false, context: {flags: ['test1', 'test2']}},
- {expected: false, context: {flags: ['test1', 'test2', 'test3']}}
+ {expected: true, context: {depth: 0, url: ''}},
+ {expected: true, context: {depth: 0, url: '', flags: []}},
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-expect-error - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2', 'test3']}}
]
},
@@ -1082,6 +1116,7 @@ function testSchemas() {
}
+/** */
function main() {
testNormalizeContext();
testSchemas();
diff --git a/test/text-source-map.test.js b/test/text-source-map.test.js
index aeaba000..54b39319 100644
--- a/test/text-source-map.test.js
+++ b/test/text-source-map.test.js
@@ -19,6 +19,7 @@
import {expect, test} from 'vitest';
import {TextSourceMap} from '../ext/js/general/text-source-map.js';
+/** */
function testSource() {
test('Source', () => {
const data = [
@@ -34,8 +35,10 @@ function testSource() {
});
}
+/** */
function testEquals() {
test('Equals', () => {
+ /** @type {[args1: [source1: string, mapping1: ?(number[])], args2: [source2: string, mapping2: ?(number[])], expectedEquals: boolean][]} */
const data = [
[['source1', null], ['source1', null], true],
[['source2', null], ['source2', null], true],
@@ -76,8 +79,10 @@ function testEquals() {
});
}
+/** */
function testGetSourceLength() {
test('GetSourceLength', () => {
+ /** @type {[args: [source: string, mapping: number[]], finalLength: number, expectedValue: number][]} */
const data = [
[['source', [1, 1, 1, 1, 1, 1]], 1, 1],
[['source', [1, 1, 1, 1, 1, 1]], 2, 2],
@@ -103,10 +108,12 @@ function testGetSourceLength() {
});
}
+/** */
function testCombineInsert() {
test('CombineInsert', () => {
+ /** @type {[args: [source: string, mapping: ?(number[])], expectedArgs: [expectedSource: string, expectedMapping: ?(number[])], operations: [operation: string, arg1: number, arg2: number][]][]} */
const data = [
- // No operations
+ // No operations
[
['source', null],
['source', [1, 1, 1, 1, 1, 1]],
@@ -226,6 +233,7 @@ function testCombineInsert() {
}
+/** */
function main() {
testSource();
testEquals();
diff --git a/test/translator.test.js b/test/translator.test.js
index 7a827d39..3db560a7 100644
--- a/test/translator.test.js
+++ b/test/translator.test.js
@@ -28,6 +28,7 @@ vi.stubGlobal('IDBKeyRange', IDBKeyRange);
const dirname = path.dirname(fileURLToPath(import.meta.url));
+/** */
async function main() {
const translatorVM = new TranslatorVM();
const dictionaryDirectory = path.join(dirname, 'data', 'dictionaries', 'valid-dictionary1');
@@ -53,6 +54,7 @@ async function main() {
case 'findTerms':
{
const {name, mode, text} = t;
+ /** @type {import('translation').FindTermsOptions} */
const options = translatorVM.buildOptions(optionsPresets, t.options);
const {dictionaryEntries, originalTextLength} = structuredClone(await translatorVM.translator.findTerms(mode, text, options));
const noteDataList = mode !== 'simple' ? structuredClone(dictionaryEntries.map((dictionaryEntry) => translatorVM.createTestAnkiNoteData(structuredClone(dictionaryEntry), mode))) : null;
@@ -66,9 +68,10 @@ async function main() {
case 'findKanji':
{
const {name, text} = t;
+ /** @type {import('translation').FindKanjiOptions} */
const options = translatorVM.buildOptions(optionsPresets, t.options);
const dictionaryEntries = structuredClone(await translatorVM.translator.findKanji(text, options));
- const noteDataList = structuredClone(dictionaryEntries.map((dictionaryEntry) => translatorVM.createTestAnkiNoteData(structuredClone(dictionaryEntry), null)));
+ const noteDataList = structuredClone(dictionaryEntries.map((dictionaryEntry) => translatorVM.createTestAnkiNoteData(structuredClone(dictionaryEntry), 'split')));
actualResults1.push({name, dictionaryEntries});
actualResults2.push({name, noteDataList});
expect(dictionaryEntries).toStrictEqual(expected1.dictionaryEntries);