summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/japanese-util.test.js39
-rw-r--r--test/jsdom.test.js9
-rw-r--r--test/json-schema.test.js71
-rw-r--r--test/options-util.test.js49
-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
7 files changed, 347 insertions, 193 deletions
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/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/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/profile-conditions-util.test.js b/test/profile-conditions-util.test.js
index ca8b00ef..30052b34 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-ignore - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: true, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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-ignore - Ignore type for string flag for testing purposes
+ {expected: false, context: {depth: 0, url: '', flags: ['clipboard', 'test2']}},
+ // @ts-ignore - 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);