diff options
author | Darius Jahandarie <djahandarie@gmail.com> | 2023-11-08 03:11:35 +0900 |
---|---|---|
committer | Darius Jahandarie <djahandarie@gmail.com> | 2023-11-08 03:23:17 +0900 |
commit | 0f4d36938fd0d844f548aa5a7f7e7842df8dfb41 (patch) | |
tree | 5b6be3620a557d0b9177047003f6d742d9d2a32d /test/test-options-util.js | |
parent | ef79eab44bfd000792c610b968b5ceefd41e76a0 (diff) |
Switch to vitest for ESM support; other fixes
Diffstat (limited to 'test/test-options-util.js')
-rw-r--r-- | test/test-options-util.js | 1609 |
1 files changed, 0 insertions, 1609 deletions
diff --git a/test/test-options-util.js b/test/test-options-util.js deleted file mode 100644 index d94028c0..00000000 --- a/test/test-options-util.js +++ /dev/null @@ -1,1609 +0,0 @@ -/* - * Copyright (C) 2023 Yomitan Authors - * Copyright (C) 2020-2022 Yomichan Authors - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -const fs = require('fs'); -const url = require('url'); -const path = require('path'); -const assert = require('assert'); -const {testMain} = require('../dev/util'); -const {VM} = require('../dev/vm'); - - -function createVM(extDir) { - const chrome = { - runtime: { - getURL(path2) { - return url.pathToFileURL(path.join(extDir, path2.replace(/^\//, ''))).href; - } - } - }; - - async function fetch(url2) { - const filePath = url.fileURLToPath(url2); - await Promise.resolve(); - const content = fs.readFileSync(filePath, {encoding: null}); - return { - ok: true, - status: 200, - statusText: 'OK', - text: async () => Promise.resolve(content.toString('utf8')), - json: async () => Promise.resolve(JSON.parse(content.toString('utf8'))) - }; - } - - const vm = new VM({chrome, fetch}); - vm.execute([ - 'js/core.js', - 'js/general/cache-map.js', - 'js/data/json-schema.js', - 'js/templates/template-patcher.js', - 'js/data/options-util.js' - ]); - - return vm; -} - - -function clone(value) { - return JSON.parse(JSON.stringify(value)); -} - - -function createProfileOptionsTestData1() { - return { - version: 14, - general: { - enable: true, - enableClipboardPopups: false, - resultOutputMode: 'group', - debugInfo: false, - maxResults: 32, - showAdvanced: false, - popupDisplayMode: 'default', - popupWidth: 400, - popupHeight: 250, - popupHorizontalOffset: 0, - popupVerticalOffset: 10, - popupHorizontalOffset2: 10, - popupVerticalOffset2: 0, - popupHorizontalTextPosition: 'below', - popupVerticalTextPosition: 'before', - popupScalingFactor: 1, - popupScaleRelativeToPageZoom: false, - popupScaleRelativeToVisualViewport: true, - showGuide: true, - compactTags: false, - compactGlossaries: false, - mainDictionary: '', - popupTheme: 'default', - popupOuterTheme: 'default', - customPopupCss: '', - customPopupOuterCss: '', - enableWanakana: true, - enableClipboardMonitor: false, - showPitchAccentDownstepNotation: true, - showPitchAccentPositionNotation: true, - showPitchAccentGraph: false, - showIframePopupsInRootFrame: false, - useSecurePopupFrameUrl: true, - usePopupShadowDom: true - }, - audio: { - enabled: true, - sources: ['jpod101', 'text-to-speech', 'custom'], - volume: 100, - autoPlay: false, - customSourceUrl: 'http://localhost/audio.mp3?term={expression}&reading={reading}', - textToSpeechVoice: 'example-voice' - }, - scanning: { - middleMouse: true, - touchInputEnabled: true, - selectText: true, - alphanumeric: true, - autoHideResults: false, - delay: 20, - length: 10, - modifier: 'shift', - deepDomScan: false, - popupNestingMaxDepth: 0, - enablePopupSearch: false, - enableOnPopupExpressions: false, - enableOnSearchPage: true, - enableSearchTags: false, - layoutAwareScan: false - }, - translation: { - convertHalfWidthCharacters: 'false', - convertNumericCharacters: 'false', - convertAlphabeticCharacters: 'false', - convertHiraganaToKatakana: 'false', - convertKatakanaToHiragana: 'variant', - collapseEmphaticSequences: 'false' - }, - dictionaries: { - 'Test Dictionary': { - priority: 0, - enabled: true, - allowSecondarySearches: false - } - }, - parsing: { - enableScanningParser: true, - enableMecabParser: false, - selectedParser: null, - termSpacing: true, - readingMode: 'hiragana' - }, - anki: { - enable: false, - server: 'http://127.0.0.1:8765', - tags: ['yomichan'], - sentenceExt: 200, - screenshot: {format: 'png', quality: 92}, - terms: {deck: '', model: '', fields: {}}, - kanji: {deck: '', model: '', fields: {}}, - duplicateScope: 'collection', - fieldTemplates: null - } - }; -} - -function createOptionsTestData1() { - return { - profiles: [ - { - name: 'Default', - options: createProfileOptionsTestData1(), - conditionGroups: [ - { - conditions: [ - { - type: 'popupLevel', - operator: 'equal', - value: 1 - }, - { - type: 'popupLevel', - operator: 'notEqual', - value: 0 - }, - { - type: 'popupLevel', - operator: 'lessThan', - value: 3 - }, - { - type: 'popupLevel', - operator: 'greaterThan', - value: 0 - }, - { - type: 'popupLevel', - operator: 'lessThanOrEqual', - value: 2 - }, - { - type: 'popupLevel', - operator: 'greaterThanOrEqual', - value: 1 - } - ] - }, - { - conditions: [ - { - type: 'url', - operator: 'matchDomain', - value: 'example.com' - }, - { - type: 'url', - operator: 'matchRegExp', - value: 'example\\.com' - } - ] - }, - { - conditions: [ - { - type: 'modifierKeys', - operator: 'are', - value: [ - 'ctrl', - 'shift' - ] - }, - { - type: 'modifierKeys', - operator: 'areNot', - value: [ - 'alt', - 'shift' - ] - }, - { - type: 'modifierKeys', - operator: 'include', - value: 'alt' - }, - { - type: 'modifierKeys', - operator: 'notInclude', - value: 'ctrl' - } - ] - } - ] - } - ], - profileCurrent: 0, - version: 2, - global: { - database: { - prefixWildcardsSupported: false - } - } - }; -} - - -function createProfileOptionsUpdatedTestData1() { - return { - general: { - enable: true, - resultOutputMode: 'group', - debugInfo: false, - maxResults: 32, - showAdvanced: false, - popupDisplayMode: 'default', - popupWidth: 400, - popupHeight: 250, - popupHorizontalOffset: 0, - popupVerticalOffset: 10, - popupHorizontalOffset2: 10, - popupVerticalOffset2: 0, - popupHorizontalTextPosition: 'below', - popupVerticalTextPosition: 'before', - popupScalingFactor: 1, - popupScaleRelativeToPageZoom: false, - popupScaleRelativeToVisualViewport: true, - showGuide: true, - compactTags: false, - glossaryLayoutMode: 'default', - mainDictionary: '', - popupTheme: 'light', - popupOuterTheme: 'light', - customPopupCss: '', - customPopupOuterCss: '', - enableWanakana: true, - showPitchAccentDownstepNotation: true, - showPitchAccentPositionNotation: true, - showPitchAccentGraph: false, - showIframePopupsInRootFrame: false, - useSecurePopupFrameUrl: true, - usePopupShadowDom: true, - usePopupWindow: false, - popupCurrentIndicatorMode: 'triangle', - popupActionBarVisibility: 'auto', - popupActionBarLocation: 'top', - frequencyDisplayMode: 'split-tags-grouped', - termDisplayMode: 'ruby', - sortFrequencyDictionary: null, - sortFrequencyDictionaryOrder: 'descending' - }, - audio: { - enabled: true, - sources: [ - { - type: 'jpod101', - url: '', - voice: '' - }, - { - type: 'text-to-speech', - url: '', - voice: 'example-voice' - }, - { - type: 'custom', - url: 'http://localhost/audio.mp3?term={term}&reading={reading}', - voice: '' - } - ], - volume: 100, - autoPlay: false - }, - scanning: { - touchInputEnabled: true, - selectText: true, - alphanumeric: true, - autoHideResults: false, - delay: 20, - length: 10, - deepDomScan: false, - popupNestingMaxDepth: 0, - enablePopupSearch: false, - enableOnPopupExpressions: false, - enableOnSearchPage: true, - enableSearchTags: false, - layoutAwareScan: false, - hideDelay: 0, - pointerEventsEnabled: false, - matchTypePrefix: false, - hidePopupOnCursorExit: false, - hidePopupOnCursorExitDelay: 0, - normalizeCssZoom: true, - preventMiddleMouse: { - onWebPages: false, - onPopupPages: false, - onSearchPages: false, - onSearchQuery: false - }, - inputs: [ - { - include: 'shift', - exclude: 'mouse0', - types: { - mouse: true, - touch: false, - pen: false - }, - options: { - showAdvanced: false, - searchTerms: true, - searchKanji: true, - scanOnTouchMove: true, - scanOnTouchPress: true, - scanOnTouchRelease: false, - scanOnPenMove: true, - scanOnPenHover: true, - scanOnPenReleaseHover: false, - scanOnPenPress: true, - scanOnPenRelease: false, - preventTouchScrolling: true, - preventPenScrolling: true - } - }, - { - include: 'mouse2', - exclude: '', - types: { - mouse: true, - touch: false, - pen: false - }, - options: { - showAdvanced: false, - searchTerms: true, - searchKanji: true, - scanOnTouchMove: true, - scanOnTouchPress: true, - scanOnTouchRelease: false, - scanOnPenMove: true, - scanOnPenHover: true, - scanOnPenReleaseHover: false, - scanOnPenPress: true, - scanOnPenRelease: false, - preventTouchScrolling: true, - preventPenScrolling: true - } - }, - { - include: '', - exclude: '', - types: { - mouse: false, - touch: true, - pen: true - }, - options: { - showAdvanced: false, - searchTerms: true, - searchKanji: true, - scanOnTouchMove: true, - scanOnTouchPress: true, - scanOnTouchRelease: false, - scanOnPenMove: true, - scanOnPenHover: true, - scanOnPenReleaseHover: false, - scanOnPenPress: true, - scanOnPenRelease: false, - preventTouchScrolling: true, - preventPenScrolling: true - } - } - ] - }, - translation: { - convertHalfWidthCharacters: 'false', - convertNumericCharacters: 'false', - convertAlphabeticCharacters: 'false', - convertHiraganaToKatakana: 'false', - convertKatakanaToHiragana: 'variant', - collapseEmphaticSequences: 'false', - textReplacements: { - searchOriginal: true, - groups: [] - } - }, - dictionaries: [ - { - name: 'Test Dictionary', - priority: 0, - enabled: true, - allowSecondarySearches: false, - definitionsCollapsible: 'not-collapsible' - } - ], - parsing: { - enableScanningParser: true, - enableMecabParser: false, - selectedParser: null, - termSpacing: true, - readingMode: 'hiragana' - }, - anki: { - enable: false, - server: 'http://127.0.0.1:8765', - tags: ['yomichan'], - screenshot: {format: 'png', quality: 92}, - terms: {deck: '', model: '', fields: {}}, - kanji: {deck: '', model: '', fields: {}}, - duplicateScope: 'collection', - duplicateScopeCheckAllModels: false, - displayTags: 'never', - checkForDuplicates: true, - fieldTemplates: null, - suspendNewCards: false, - noteGuiMode: 'browse', - apiKey: '', - downloadTimeout: 0 - }, - sentenceParsing: { - scanExtent: 200, - terminationCharacterMode: 'custom', - terminationCharacters: [ - {enabled: true, character1: '「', character2: '」', includeCharacterAtStart: false, includeCharacterAtEnd: false}, - {enabled: true, character1: '『', character2: '』', includeCharacterAtStart: false, includeCharacterAtEnd: false}, - {enabled: true, character1: '"', character2: '"', includeCharacterAtStart: false, includeCharacterAtEnd: false}, - {enabled: true, character1: '\'', character2: '\'', includeCharacterAtStart: false, includeCharacterAtEnd: false}, - {enabled: true, character1: '.', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '!', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '?', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '.', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '。', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '!', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '?', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '…', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '︒', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '︕', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '︖', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true}, - {enabled: true, character1: '︙', character2: null, includeCharacterAtStart: false, includeCharacterAtEnd: true} - ] - }, - inputs: { - hotkeys: [ - {action: 'close', argument: '', key: 'Escape', modifiers: [], scopes: ['popup'], enabled: true}, - {action: 'focusSearchBox', argument: '', key: 'Escape', modifiers: [], scopes: ['search'], enabled: true}, - {action: 'previousEntry', argument: '3', key: 'PageUp', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'nextEntry', argument: '3', key: 'PageDown', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'lastEntry', argument: '', key: 'End', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'firstEntry', argument: '', key: 'Home', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'previousEntry', argument: '1', key: 'ArrowUp', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'nextEntry', argument: '1', key: 'ArrowDown', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'historyBackward', argument: '', key: 'KeyB', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'historyForward', argument: '', key: 'KeyF', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'addNoteKanji', argument: '', key: 'KeyK', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'addNoteTermKanji', argument: '', key: 'KeyE', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'addNoteTermKana', argument: '', key: 'KeyR', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'playAudio', argument: '', key: 'KeyP', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'viewNote', argument: '', key: 'KeyV', modifiers: ['alt'], scopes: ['popup', 'search'], enabled: true}, - {action: 'copyHostSelection', argument: '', key: 'KeyC', modifiers: ['ctrl'], scopes: ['popup'], enabled: true} - ] - }, - popupWindow: { - width: 400, - height: 250, - left: 0, - top: 0, - useLeft: false, - useTop: false, - windowType: 'popup', - windowState: 'normal' - }, - clipboard: { - enableBackgroundMonitor: false, - enableSearchPageMonitor: false, - autoSearchContent: true, - maximumSearchLength: 1000 - }, - accessibility: { - forceGoogleDocsHtmlRendering: false - } - }; -} - -function createOptionsUpdatedTestData1() { - return { - profiles: [ - { - name: 'Default', - options: createProfileOptionsUpdatedTestData1(), - conditionGroups: [ - { - conditions: [ - { - type: 'popupLevel', - operator: 'equal', - value: '1' - }, - { - type: 'popupLevel', - operator: 'notEqual', - value: '0' - }, - { - type: 'popupLevel', - operator: 'lessThan', - value: '3' - }, - { - type: 'popupLevel', - operator: 'greaterThan', - value: '0' - }, - { - type: 'popupLevel', - operator: 'lessThanOrEqual', - value: '2' - }, - { - type: 'popupLevel', - operator: 'greaterThanOrEqual', - value: '1' - } - ] - }, - { - conditions: [ - { - type: 'url', - operator: 'matchDomain', - value: 'example.com' - }, - { - type: 'url', - operator: 'matchRegExp', - value: 'example\\.com' - } - ] - }, - { - conditions: [ - { - type: 'modifierKeys', - operator: 'are', - value: 'ctrl, shift' - }, - { - type: 'modifierKeys', - operator: 'areNot', - value: 'alt, shift' - }, - { - type: 'modifierKeys', - operator: 'include', - value: 'alt' - }, - { - type: 'modifierKeys', - operator: 'notInclude', - value: 'ctrl' - } - ] - } - ] - } - ], - profileCurrent: 0, - version: 21, - global: { - database: { - prefixWildcardsSupported: false - } - } - }; -} - - -async function testUpdate(extDir) { - const vm = createVM(extDir); - const [OptionsUtil] = vm.get(['OptionsUtil']); - const optionsUtil = new OptionsUtil(); - await optionsUtil.prepare(); - - const options = createOptionsTestData1(); - const optionsUpdated = clone(await optionsUtil.update(options)); - const optionsExpected = createOptionsUpdatedTestData1(); - assert.deepStrictEqual(optionsUpdated, optionsExpected); -} - -async function testDefault(extDir) { - const data = [ - (options) => options, - (options) => { - delete options.profiles[0].options.audio.autoPlay; - }, - (options) => { - options.profiles[0].options.audio.autoPlay = void 0; - } - ]; - - const vm = createVM(extDir); - const [OptionsUtil] = vm.get(['OptionsUtil']); - const optionsUtil = new OptionsUtil(); - await optionsUtil.prepare(); - - for (const modify of data) { - const options = optionsUtil.getDefault(); - - const optionsModified = clone(options); - modify(optionsModified); - - const optionsUpdated = await optionsUtil.update(clone(optionsModified)); - assert.deepStrictEqual(clone(optionsUpdated), clone(options)); - } -} - -async function testFieldTemplatesUpdate(extDir) { - const vm = createVM(extDir); - const [OptionsUtil, TemplatePatcher] = vm.get(['OptionsUtil', 'TemplatePatcher']); - const optionsUtil = new OptionsUtil(); - await optionsUtil.prepare(); - - const templatePatcher = new TemplatePatcher(); - const loadDataFile = (fileName) => { - const content = fs.readFileSync(path.join(extDir, fileName), {encoding: 'utf8'}); - return templatePatcher.parsePatch(content).addition; - }; - const updates = [ - {version: 2, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v2.handlebars')}, - {version: 4, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v4.handlebars')}, - {version: 6, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v6.handlebars')}, - {version: 8, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v8.handlebars')}, - {version: 10, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v10.handlebars')}, - {version: 12, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v12.handlebars')}, - {version: 13, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v13.handlebars')}, - {version: 21, changes: loadDataFile('data/templates/anki-field-templates-upgrade-v21.handlebars')} - ]; - const getUpdateAdditions = (startVersion, targetVersion) => { - let value = ''; - for (const {version, changes} of updates) { - if (version <= startVersion || version > targetVersion || changes.length === 0) { continue; } - if (value.length > 0) { value += '\n'; } - value += changes; - } - return value; - }; - - const data = [ - // Standard format - { - oldVersion: 0, - newVersion: 12, - old: ` -{{#*inline "character"}} - {{~definition.character~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "character"}} - {{~definition.character~}} -{{/inline}} - -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // Non-standard marker format - { - oldVersion: 0, - newVersion: 12, - old: ` -{{#*inline "character"}} - {{~definition.character~}} -{{/inline}} - -{{~> (lookup . "marker2") ~}}`.trimStart(), - - expected: ` -{{#*inline "character"}} - {{~definition.character~}} -{{/inline}} - -{{~> (lookup . "marker2") ~}} -<<<UPDATE-ADDITIONS>>>`.trimStart() - }, - // Empty test - { - oldVersion: 0, - newVersion: 12, - old: ` -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // Definition tags update - { - oldVersion: 0, - newVersion: 12, - old: ` -{{#*inline "glossary-single"}} - {{~#unless brief~}} - {{~#if definitionTags~}}<i>({{#each definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each}})</i> {{/if~}} - {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} -{{/inline}} - -{{#*inline "glossary-single2"}} - {{~#unless brief~}} - {{~#if definitionTags~}}<i>({{#each definitionTags}}{{name}}{{#unless @last}}, {{/unless}}{{/each}})</i> {{/if~}} - {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} -{{/inline}} - -{{#*inline "glossary"}} - {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries~}} - {{~> glossary-single definition brief=brief compactGlossaries=../compactGlossaries~}} -{{/inline}} - -{{~> (lookup . "marker") ~}} -`.trimStart(), - - expected: ` -{{#*inline "glossary-single"}} - {{~#unless brief~}} - {{~#scope~}} - {{~#set "any" false}}{{/set~}} - {{~#if definitionTags~}}{{#each definitionTags~}} - {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{name}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/each~}} - {{~#if (get "any")}})</i> {{/if~}} - {{~/if~}} - {{~/scope~}} - {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} -{{/inline}} - -{{#*inline "glossary-single2"}} - {{~#unless brief~}} - {{~#scope~}} - {{~#set "any" false}}{{/set~}} - {{~#if definitionTags~}}{{#each definitionTags~}} - {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{name}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/each~}} - {{~#if (get "any")}})</i> {{/if~}} - {{~/if~}} - {{~/scope~}} - {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} -{{/inline}} - -{{#*inline "glossary"}} - {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries data=.~}} - {{~> glossary-single definition brief=brief compactGlossaries=../compactGlossaries data=../.~}} -{{/inline}} - -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}} -`.trimStart() - }, - // glossary and glossary-brief update - { - oldVersion: 7, - newVersion: 12, - old: ` -{{#*inline "glossary-single"}} - {{~#unless brief~}} - {{~#scope~}} - {{~#set "any" false}}{{/set~}} - {{~#if definitionTags~}}{{#each definitionTags~}} - {{~#if (op "||" (op "!" ../data.compactTags) (op "!" redundant))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{name}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/each~}} - {{~#if (get "any")}})</i> {{/if~}} - {{~/if~}} - {{~/scope~}} - {{~#if only~}}({{#each only}}{{{.}}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} - {{~#if glossary.[1]~}} - {{~#if compactGlossaries~}} - {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}} - {{~else~}} - <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul> - {{~/if~}} - {{~else~}} - {{~#multiLine}}{{glossary.[0]}}{{/multiLine~}} - {{~/if~}} -{{/inline}} - -{{#*inline "character"}} - {{~definition.character~}} -{{/inline}} - -{{#*inline "glossary"}} - <div style="text-align: left;"> - {{~#if modeKanji~}} - {{~#if definition.glossary.[1]~}} - <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol> - {{~else~}} - {{definition.glossary.[0]}} - {{~/if~}} - {{~else~}} - {{~#if group~}} - {{~#if definition.definitions.[1]~}} - <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol> - {{~else~}} - {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}} - {{~/if~}} - {{~else if merge~}} - {{~#if definition.definitions.[1]~}} - <ol>{{#each definition.definitions}}<li>{{> glossary-single brief=../brief compactGlossaries=../compactGlossaries data=../.}}</li>{{/each}}</ol> - {{~else~}} - {{~> glossary-single definition.definitions.[0] brief=brief compactGlossaries=compactGlossaries data=.~}} - {{~/if~}} - {{~else~}} - {{~> glossary-single definition brief=brief compactGlossaries=compactGlossaries data=.~}} - {{~/if~}} - {{~/if~}} - </div> -{{/inline}} - -{{#*inline "glossary-brief"}} - {{~> glossary brief=true ~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "glossary-single"}} - {{~#unless brief~}} - {{~#scope~}} - {{~#set "any" false}}{{/set~}} - {{~#each definitionTags~}} - {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{name}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/each~}} - {{~#unless noDictionaryTag~}} - {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{dictionary}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/unless~}} - {{~#if (get "any")}})</i> {{/if~}} - {{~/scope~}} - {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} - {{~#if (op "<=" glossary.length 1)~}} - {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}} - {{~else if @root.compactGlossaries~}} - {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}} - {{~else~}} - <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul> - {{~/if~}} - {{~#set "previousDictionary" dictionary~}}{{~/set~}} -{{/inline}} - -{{#*inline "character"}} - {{~definition.character~}} -{{/inline}} - -{{~#*inline "glossary"~}} - <div style="text-align: left;"> - {{~#scope~}} - {{~#if (op "===" definition.type "term")~}} - {{~> glossary-single definition brief=brief noDictionaryTag=noDictionaryTag ~}} - {{~else if (op "||" (op "===" definition.type "termGrouped") (op "===" definition.type "termMerged"))~}} - {{~#if (op ">" definition.definitions.length 1)~}} - <ol>{{~#each definition.definitions~}}<li>{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}</li>{{~/each~}}</ol> - {{~else~}} - {{~#each definition.definitions~}}{{~> glossary-single . brief=../brief noDictionaryTag=../noDictionaryTag ~}}{{~/each~}} - {{~/if~}} - {{~else if (op "===" definition.type "kanji")~}} - {{~#if (op ">" definition.glossary.length 1)~}} - <ol>{{#each definition.glossary}}<li>{{.}}</li>{{/each}}</ol> - {{~else~}} - {{~#each definition.glossary~}}{{.}}{{~/each~}} - {{~/if~}} - {{~/if~}} - {{~/scope~}} - </div> -{{~/inline~}} - -{{#*inline "glossary-no-dictionary"}} - {{~> glossary noDictionaryTag=true ~}} -{{/inline}} - -{{#*inline "glossary-brief"}} - {{~> glossary brief=true ~}} -{{/inline}} - -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // formatGlossary update - { - oldVersion: 12, - newVersion: 13, - old: ` -{{#*inline "example"}} - {{~#if (op "<=" glossary.length 1)~}} - {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{/each}} - {{~else if @root.compactGlossaries~}} - {{#each glossary}}{{#multiLine}}{{.}}{{/multiLine}}{{#unless @last}} | {{/unless}}{{/each}} - {{~else~}} - <ul>{{#each glossary}}<li>{{#multiLine}}{{.}}{{/multiLine}}</li>{{/each}}</ul> - {{~/if~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "example"}} - {{~#if (op "<=" glossary.length 1)~}} - {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{/each}} - {{~else if @root.compactGlossaries~}} - {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{#unless @last}} | {{/unless}}{{/each}} - {{~else~}} - <ul>{{#each glossary}}<li>{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}</li>{{/each}}</ul> - {{~/if~}} -{{/inline}} - -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // hasMedia/getMedia update - { - oldVersion: 12, - newVersion: 13, - old: ` -{{#*inline "audio"}} - {{~#if definition.audioFileName~}} - [sound:{{definition.audioFileName}}] - {{~/if~}} -{{/inline}} - -{{#*inline "screenshot"}} - <img src="{{definition.screenshotFileName}}" /> -{{/inline}} - -{{#*inline "clipboard-image"}} - {{~#if definition.clipboardImageFileName~}} - <img src="{{definition.clipboardImageFileName}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-text"}} - {{~#if definition.clipboardText~}}{{definition.clipboardText}}{{~/if~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "audio"}} - {{~#if (hasMedia "audio")~}} - [sound:{{#getMedia "audio"}}{{/getMedia}}] - {{~/if~}} -{{/inline}} - -{{#*inline "screenshot"}} - {{~#if (hasMedia "screenshot")~}} - <img src="{{#getMedia "screenshot"}}{{/getMedia}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-image"}} - {{~#if (hasMedia "clipboardImage")~}} - <img src="{{#getMedia "clipboardImage"}}{{/getMedia}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-text"}} - {{~#if (hasMedia "clipboardText")}}{{#getMedia "clipboardText"}}{{/getMedia}}{{/if~}} -{{/inline}} - -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // hasMedia/getMedia update - { - oldVersion: 12, - newVersion: 13, - old: ` -{{! Pitch Accents }} -{{#*inline "pitch-accent-item-downstep-notation"}} - {{~#scope~}} - <span> - {{~#set "style1a"~}}display:inline-block;position:relative;{{~/set~}} - {{~#set "style1b"~}}padding-right:0.1em;margin-right:0.1em;{{~/set~}} - {{~#set "style2a"~}}display:block;user-select:none;pointer-events:none;position:absolute;top:0.1em;left:0;right:0;height:0;border-top:0.1em solid;{{~/set~}} - {{~#set "style2b"~}}right:-0.1em;height:0.4em;border-right:0.1em solid;{{~/set~}} - {{~#each (getKanaMorae reading)~}} - {{~#set "style1"}}{{#get "style1a"}}{{/get}}{{/set~}} - {{~#set "style2"}}{{/set~}} - {{~#if (isMoraPitchHigh @index ../position)}} - {{~#set "style2"}}{{#get "style2a"}}{{/get}}{{/set~}} - {{~#if (op "!" (isMoraPitchHigh (op "+" @index 1) ../position))~}} - {{~#set "style1" (op "+" (get "style1") (get "style1b"))}}{{/set~}} - {{~#set "style2" (op "+" (get "style2") (get "style2b"))}}{{/set~}} - {{~/if~}} - {{~/if~}} - <span style="{{#get "style1"}}{{/get}}">{{{.}}}<span style="{{#get "style2"}}{{/get}}"></span></span> - {{~/each~}} - </span> - {{~/scope~}} -{{/inline}} - -{{#*inline "pitch-accent-item-graph-position-x"}}{{#op "+" 25 (op "*" index 50)}}{{/op}}{{/inline}} -{{#*inline "pitch-accent-item-graph-position-y"}}{{#op "+" 25 (op "?:" (isMoraPitchHigh index position) 0 50)}}{{/op}}{{/inline}} -{{#*inline "pitch-accent-item-graph-position"}}{{> pitch-accent-item-graph-position-x index=index position=position}} {{> pitch-accent-item-graph-position-y index=index position=position}}{{/inline}} -{{#*inline "pitch-accent-item-graph"}} - {{~#scope~}} - {{~#set "morae" (getKanaMorae reading)}}{{/set~}} - {{~#set "morae-count" (property (get "morae") "length")}}{{/set~}} -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {{#op "+" 50 (op "*" 50 (get "morae-count"))}}{{/op}} 100" style="display:inline-block;height:2em;"> - <defs> - <g id="term-pitch-accent-graph-dot"><circle cx="0" cy="0" r="15" style="fill:#000;stroke:#000;stroke-width:5;" /></g> - <g id="term-pitch-accent-graph-dot-downstep"><circle cx="0" cy="0" r="15" style="fill:none;stroke:#000;stroke-width:5;" /><circle cx="0" cy="0" r="5" style="fill:none;stroke:#000;stroke-width:5;" /></g> - <g id="term-pitch-accent-graph-triangle"><path d="M0 13 L15 -13 L-15 -13 Z" style="fill:none;stroke:#000;stroke-width:5;" /></g> - </defs> - <path style="fill:none;stroke:#000;stroke-width:5;" d=" - {{~#set "cmd" "M"}}{{/set~}} - {{~#each (get "morae")~}} - {{~#get "cmd"}}{{/get~}} - {{~> pitch-accent-item-graph-position index=@index position=../position~}} - {{~#set "cmd" "L"}}{{/set~}} - {{~/each~}} - "></path> - <path style="fill:none;stroke:#000;stroke-width:5;stroke-dasharray:5 5;" d="M{{> pitch-accent-item-graph-position index=(op "-" (get "morae-count") 1) position=position}} L{{> pitch-accent-item-graph-position index=(get "morae-count") position=position}}"></path> - {{#each (get "morae")}} - <use href="{{#if (op "&&" (isMoraPitchHigh @index ../position) (op "!" (isMoraPitchHigh (op "+" @index 1) ../position)))}}#term-pitch-accent-graph-dot-downstep{{else}}#term-pitch-accent-graph-dot{{/if}}" x="{{> pitch-accent-item-graph-position-x index=@index position=../position}}" y="{{> pitch-accent-item-graph-position-y index=@index position=../position}}"></use> - {{/each}} - <use href="#term-pitch-accent-graph-triangle" x="{{> pitch-accent-item-graph-position-x index=(get "morae-count") position=position}}" y="{{> pitch-accent-item-graph-position-y index=(get "morae-count") position=position}}"></use> -</svg> - {{~/scope~}} -{{/inline}} - -{{#*inline "pitch-accent-item-position"~}} - <span>[{{position}}]</span> -{{~/inline}} - -{{#*inline "pitch-accent-item"}} - {{~#if (op "==" format "downstep-notation")~}} - {{~> pitch-accent-item-downstep-notation~}} - {{~else if (op "==" format "graph")~}} - {{~> pitch-accent-item-graph~}} - {{~else if (op "==" format "position")~}} - {{~> pitch-accent-item-position~}} - {{~/if~}} -{{/inline}} - -{{#*inline "pitch-accent-item-disambiguation"}} - {{~#scope~}} - {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}} - {{~#if (op ">" (property (get "exclusive") "length") 0)~}} - {{~#set "separator" ""~}}{{/set~}} - <em>({{#each (get "exclusive")~}} - {{~#get "separator"}}{{/get~}}{{{.}}} - {{~/each}} only) </em> - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{#*inline "pitch-accent-list"}} - {{~#if (op ">" pitchCount 0)~}} - {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}} - {{~#each pitches~}} - {{~#each pitches~}} - {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}} - {{~> pitch-accent-item-disambiguation~}} - {{~> pitch-accent-item format=../../format~}} - {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}} - {{~/each~}} - {{~/each~}} - {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}} - {{~else~}} - No pitch accent data - {{~/if~}} -{{/inline}} - -{{#*inline "pitch-accents"}} - {{~> pitch-accent-list format='downstep-notation'~}} -{{/inline}} - -{{#*inline "pitch-accent-graphs"}} - {{~> pitch-accent-list format='graph'~}} -{{/inline}} - -{{#*inline "pitch-accent-positions"}} - {{~> pitch-accent-list format='position'~}} -{{/inline}} -{{! End Pitch Accents }} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{! Pitch Accents }} -{{#*inline "pitch-accent-item"}} - {{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}} -{{/inline}} - -{{#*inline "pitch-accent-item-disambiguation"}} - {{~#scope~}} - {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}} - {{~#if (op ">" (property (get "exclusive") "length") 0)~}} - {{~#set "separator" ""~}}{{/set~}} - <em>({{#each (get "exclusive")~}} - {{~#get "separator"}}{{/get~}}{{{.}}} - {{~/each}} only) </em> - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{#*inline "pitch-accent-list"}} - {{~#if (op ">" pitchCount 0)~}} - {{~#if (op ">" pitchCount 1)~}}<ol>{{~/if~}} - {{~#each pitches~}} - {{~#each pitches~}} - {{~#if (op ">" ../../pitchCount 1)~}}<li>{{~/if~}} - {{~> pitch-accent-item-disambiguation~}} - {{~> pitch-accent-item format=../../format~}} - {{~#if (op ">" ../../pitchCount 1)~}}</li>{{~/if~}} - {{~/each~}} - {{~/each~}} - {{~#if (op ">" pitchCount 1)~}}</ol>{{~/if~}} - {{~else~}} - No pitch accent data - {{~/if~}} -{{/inline}} - -{{#*inline "pitch-accents"}} - {{~> pitch-accent-list format='text'~}} -{{/inline}} - -{{#*inline "pitch-accent-graphs"}} - {{~> pitch-accent-list format='graph'~}} -{{/inline}} - -{{#*inline "pitch-accent-positions"}} - {{~> pitch-accent-list format='position'~}} -{{/inline}} -{{! End Pitch Accents }} - -<<<UPDATE-ADDITIONS>>> -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // block helper update: furigana and furiganaPlain - { - oldVersion: 20, - newVersion: 21, - old: ` -{{#*inline "furigana"}} - {{~#if merge~}} - {{~#each definition.expressions~}} - <span class="expression-{{termFrequency}}">{{~#furigana}}{{{.}}}{{/furigana~}}</span> - {{~#unless @last}}、{{/unless~}} - {{~/each~}} - {{~else~}} - {{#furigana}}{{{definition}}}{{/furigana}} - {{~/if~}} -{{/inline}} - -{{#*inline "furigana-plain"}} - {{~#if merge~}} - {{~#each definition.expressions~}} - <span class="expression-{{termFrequency}}">{{~#furiganaPlain}}{{{.}}}{{/furiganaPlain~}}</span> - {{~#unless @last}}、{{/unless~}} - {{~/each~}} - {{~else~}} - {{#furiganaPlain}}{{{definition}}}{{/furiganaPlain}} - {{~/if~}} -{{/inline}} - -{{#*inline "frequencies"}} - {{~#if (op ">" definition.frequencies.length 0)~}} - <ul style="text-align: left;"> - {{~#each definition.frequencies~}} - <li> - {{~#if (op "!==" ../definition.type "kanji")~}} - {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}( - {{~#furigana expression reading~}}{{~/furigana~}} - ) {{/if~}} - {{~/if~}} - {{~dictionary}}: {{frequency~}} - </li> - {{~/each~}} - </ul> - {{~/if~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "furigana"}} - {{~#if merge~}} - {{~#each definition.expressions~}} - <span class="expression-{{termFrequency}}">{{~furigana .~}}</span> - {{~#unless @last}}、{{/unless~}} - {{~/each~}} - {{~else~}} - {{furigana definition}} - {{~/if~}} -{{/inline}} - -{{#*inline "furigana-plain"}} - {{~#if merge~}} - {{~#each definition.expressions~}} - <span class="expression-{{termFrequency}}">{{~furiganaPlain .~}}</span> - {{~#unless @last}}、{{/unless~}} - {{~/each~}} - {{~else~}} - {{furiganaPlain definition}} - {{~/if~}} -{{/inline}} - -{{#*inline "frequencies"}} - {{~#if (op ">" definition.frequencies.length 0)~}} - <ul style="text-align: left;"> - {{~#each definition.frequencies~}} - <li> - {{~#if (op "!==" ../definition.type "kanji")~}} - {{~#if (op "||" (op ">" ../uniqueExpressions.length 1) (op ">" ../uniqueReadings.length 1))~}}( - {{~furigana expression reading~}} - ) {{/if~}} - {{~/if~}} - {{~dictionary}}: {{frequency~}} - </li> - {{~/each~}} - </ul> - {{~/if~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // block helper update: formatGlossary - { - oldVersion: 20, - newVersion: 21, - old: ` -{{#*inline "glossary-single"}} - {{~#unless brief~}} - {{~#scope~}} - {{~#set "any" false}}{{/set~}} - {{~#each definitionTags~}} - {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{name}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/each~}} - {{~#unless noDictionaryTag~}} - {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{dictionary}} - {{~#set "any" true}}{{/set~}} - {{~/if~}} - {{~/unless~}} - {{~#if (get "any")}})</i> {{/if~}} - {{~/scope~}} - {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} - {{~#if (op "<=" glossary.length 1)~}} - {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{/each}} - {{~else if @root.compactGlossaries~}} - {{#each glossary}}{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}{{#unless @last}} | {{/unless}}{{/each}} - {{~else~}} - <ul>{{#each glossary}}<li>{{#formatGlossary ../dictionary}}{{{.}}}{{/formatGlossary}}</li>{{/each}}</ul> - {{~/if~}} - {{~#set "previousDictionary" dictionary~}}{{~/set~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "glossary-single"}} - {{~#unless brief~}} - {{~#scope~}} - {{~set "any" false~}} - {{~#each definitionTags~}} - {{~#if (op "||" (op "!" @root.compactTags) (op "!" redundant))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{name}} - {{~set "any" true~}} - {{~/if~}} - {{~/each~}} - {{~#unless noDictionaryTag~}} - {{~#if (op "||" (op "!" @root.compactTags) (op "!==" dictionary (get "previousDictionary")))~}} - {{~#if (get "any")}}, {{else}}<i>({{/if~}} - {{dictionary}} - {{~set "any" true~}} - {{~/if~}} - {{~/unless~}} - {{~#if (get "any")}})</i> {{/if~}} - {{~/scope~}} - {{~#if only~}}({{#each only}}{{.}}{{#unless @last}}, {{/unless}}{{/each}} only) {{/if~}} - {{~/unless~}} - {{~#if (op "<=" glossary.length 1)~}} - {{#each glossary}}{{formatGlossary ../dictionary .}}{{/each}} - {{~else if @root.compactGlossaries~}} - {{#each glossary}}{{formatGlossary ../dictionary .}}{{#unless @last}} | {{/unless}}{{/each}} - {{~else~}} - <ul>{{#each glossary}}<li>{{formatGlossary ../dictionary .}}</li>{{/each}}</ul> - {{~/if~}} - {{~set "previousDictionary" dictionary~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // block helper update: set and get - { - oldVersion: 20, - newVersion: 21, - old: ` -{{#*inline "pitch-accent-item-disambiguation"}} - {{~#scope~}} - {{~#set "exclusive" (spread exclusiveExpressions exclusiveReadings)}}{{/set~}} - {{~#if (op ">" (property (get "exclusive") "length") 0)~}} - {{~#set "separator" ""~}}{{/set~}} - <em>({{#each (get "exclusive")~}} - {{~#get "separator"}}{{/get~}}{{{.}}} - {{~/each}} only) </em> - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{#*inline "stroke-count"}} - {{~#scope~}} - {{~#set "found" false}}{{/set~}} - {{~#each definition.stats.misc~}} - {{~#if (op "===" name "strokes")~}} - {{~#set "found" true}}{{/set~}} - Stroke count: {{value}} - {{~/if~}} - {{~/each~}} - {{~#if (op "!" (get "found"))~}} - Stroke count: Unknown - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{#*inline "part-of-speech"}} - {{~#scope~}} - {{~#if (op "!==" definition.type "kanji")~}} - {{~#set "first" true}}{{/set~}} - {{~#each definition.expressions~}} - {{~#each wordClasses~}} - {{~#unless (get (concat "used_" .))~}} - {{~> part-of-speech-pretty . ~}} - {{~#unless (get "first")}}, {{/unless~}} - {{~#set (concat "used_" .) true~}}{{~/set~}} - {{~#set "first" false~}}{{~/set~}} - {{~/unless~}} - {{~/each~}} - {{~/each~}} - {{~#if (get "first")~}}Unknown{{~/if~}} - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "pitch-accent-item-disambiguation"}} - {{~#scope~}} - {{~set "exclusive" (spread exclusiveExpressions exclusiveReadings)~}} - {{~#if (op ">" (property (get "exclusive") "length") 0)~}} - {{~set "separator" ""~}} - <em>({{#each (get "exclusive")~}} - {{~get "separator"~}}{{{.}}} - {{~/each}} only) </em> - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{#*inline "stroke-count"}} - {{~#scope~}} - {{~set "found" false~}} - {{~#each definition.stats.misc~}} - {{~#if (op "===" name "strokes")~}} - {{~set "found" true~}} - Stroke count: {{value}} - {{~/if~}} - {{~/each~}} - {{~#if (op "!" (get "found"))~}} - Stroke count: Unknown - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{#*inline "part-of-speech"}} - {{~#scope~}} - {{~#if (op "!==" definition.type "kanji")~}} - {{~set "first" true~}} - {{~#each definition.expressions~}} - {{~#each wordClasses~}} - {{~#unless (get (concat "used_" .))~}} - {{~> part-of-speech-pretty . ~}} - {{~#unless (get "first")}}, {{/unless~}} - {{~set (concat "used_" .) true~}} - {{~set "first" false~}} - {{~/unless~}} - {{~/each~}} - {{~/each~}} - {{~#if (get "first")~}}Unknown{{~/if~}} - {{~/if~}} - {{~/scope~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // block helper update: hasMedia and getMedia - { - oldVersion: 20, - newVersion: 21, - old: ` -{{#*inline "audio"}} - {{~#if (hasMedia "audio")~}} - [sound:{{#getMedia "audio"}}{{/getMedia}}] - {{~/if~}} -{{/inline}} - -{{#*inline "screenshot"}} - {{~#if (hasMedia "screenshot")~}} - <img src="{{#getMedia "screenshot"}}{{/getMedia}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-image"}} - {{~#if (hasMedia "clipboardImage")~}} - <img src="{{#getMedia "clipboardImage"}}{{/getMedia}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-text"}} - {{~#if (hasMedia "clipboardText")}}{{#getMedia "clipboardText"}}{{/getMedia}}{{/if~}} -{{/inline}} - -{{#*inline "selection-text"}} - {{~#if (hasMedia "selectionText")}}{{#getMedia "selectionText"}}{{/getMedia}}{{/if~}} -{{/inline}} - -{{#*inline "sentence-furigana"}} - {{~#if definition.cloze~}} - {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}} - {{#getMedia "textFurigana" definition.cloze.sentence escape=false}}{{/getMedia}} - {{~else~}} - {{definition.cloze.sentence}} - {{~/if~}} - {{~/if~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "audio"}} - {{~#if (hasMedia "audio")~}} - [sound:{{getMedia "audio"}}] - {{~/if~}} -{{/inline}} - -{{#*inline "screenshot"}} - {{~#if (hasMedia "screenshot")~}} - <img src="{{getMedia "screenshot"}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-image"}} - {{~#if (hasMedia "clipboardImage")~}} - <img src="{{getMedia "clipboardImage"}}" /> - {{~/if~}} -{{/inline}} - -{{#*inline "clipboard-text"}} - {{~#if (hasMedia "clipboardText")}}{{getMedia "clipboardText"}}{{/if~}} -{{/inline}} - -{{#*inline "selection-text"}} - {{~#if (hasMedia "selectionText")}}{{getMedia "selectionText"}}{{/if~}} -{{/inline}} - -{{#*inline "sentence-furigana"}} - {{~#if definition.cloze~}} - {{~#if (hasMedia "textFurigana" definition.cloze.sentence)~}} - {{getMedia "textFurigana" definition.cloze.sentence escape=false}} - {{~else~}} - {{definition.cloze.sentence}} - {{~/if~}} - {{~/if~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart() - }, - // block helper update: pronunciation - { - oldVersion: 20, - newVersion: 21, - old: ` -{{#*inline "pitch-accent-item"}} - {{~#pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}{{~/pronunciation~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart(), - - expected: ` -{{#*inline "pitch-accent-item"}} - {{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}} -{{/inline}} - -{{~> (lookup . "marker") ~}}`.trimStart() - } - ]; - - const updatesPattern = /<<<UPDATE-ADDITIONS>>>/g; - for (const {old, expected, oldVersion, newVersion} of data) { - const options = createOptionsTestData1(); - options.profiles[0].options.anki.fieldTemplates = old; - options.version = oldVersion; - - const expected2 = expected.replace(updatesPattern, getUpdateAdditions(oldVersion, newVersion)); - - const optionsUpdated = clone(await optionsUtil.update(options, newVersion)); - const fieldTemplatesActual = optionsUpdated.profiles[0].options.anki.fieldTemplates; - assert.deepStrictEqual(fieldTemplatesActual, expected2); - } -} - - -async function main() { - const extDir = path.join(__dirname, '..', 'ext'); - await testUpdate(extDir); - await testDefault(extDir); - await testFieldTemplatesUpdate(extDir); -} - - -if (require.main === module) { testMain(main); } |