diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/japanese-util.test.js | 39 | ||||
-rw-r--r-- | test/jsdom.test.js | 9 | ||||
-rw-r--r-- | test/json-schema.test.js | 71 | ||||
-rw-r--r-- | test/options-util.test.js | 49 | ||||
-rw-r--r-- | test/profile-conditions-util.test.js | 357 | ||||
-rw-r--r-- | test/text-source-map.test.js | 10 | ||||
-rw-r--r-- | test/translator.test.js | 5 |
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); |