diff options
| -rw-r--r-- | test/test-options-util.js | 585 | 
1 files changed, 585 insertions, 0 deletions
| diff --git a/test/test-options-util.js b/test/test-options-util.js new file mode 100644 index 00000000..67dc57b7 --- /dev/null +++ b/test/test-options-util.js @@ -0,0 +1,585 @@ +/* + * Copyright (C) 2020  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 {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([ +        'mixed/js/core.js', +        'mixed/js/cache-map.js', +        'bg/js/json-schema.js', +        'bg/js/options.js' +    ]); + +    return vm; +} + + +function clone(value) { +    return JSON.parse(JSON.stringify(value)); +} + + +function createProfileOptionsTestData1() { +    return { +        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'], +            volume: 100, +            autoPlay: false, +            customSourceUrl: '', +            textToSpeechVoice: '' +        }, +        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: {}, +        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, +            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, +            usePopupWindow: false +        }, +        audio: { +            enabled: true, +            sources: ['jpod101'], +            volume: 100, +            autoPlay: false, +            customSourceUrl: '', +            textToSpeechVoice: '' +        }, +        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, +            inputs: [ +                { +                    include: 'shift', +                    exclude: '', +                    types: { +                        mouse: true, +                        touch: false, +                        pen: false +                    }, +                    options: { +                        showAdvanced: false, +                        scanOnPenHover: true, +                        scanOnPenPress: true, +                        scanOnPenRelease: false, +                        searchTerms: true, +                        searchKanji: true +                    } +                }, +                { +                    include: 'mouse2', +                    exclude: '', +                    types: { +                        mouse: true, +                        touch: false, +                        pen: false +                    }, +                    options: { +                        showAdvanced: false, +                        scanOnPenHover: true, +                        scanOnPenPress: true, +                        scanOnPenRelease: false, +                        searchTerms: true, +                        searchKanji: true +                    } +                }, +                { +                    include: '', +                    exclude: '', +                    types: { +                        mouse: false, +                        touch: true, +                        pen: true +                    }, +                    options: { +                        showAdvanced: false, +                        scanOnPenHover: true, +                        scanOnPenPress: true, +                        scanOnPenRelease: false, +                        searchTerms: true, +                        searchKanji: true +                    } +                } +            ] +        }, +        translation: { +            convertHalfWidthCharacters: 'false', +            convertNumericCharacters: 'false', +            convertAlphabeticCharacters: 'false', +            convertHiraganaToKatakana: 'false', +            convertKatakanaToHiragana: 'variant', +            collapseEmphaticSequences: 'false' +        }, +        dictionaries: {}, +        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 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: 4, +        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 testFieldTemplatesUpdate(extDir) { +    const vm = createVM(extDir); +    const [OptionsUtil] = vm.get(['OptionsUtil']); +    const optionsUtil = new OptionsUtil(); +    await optionsUtil.prepare(); + +    const loadDataFile = (fileName) => fs.readFileSync(path.join(extDir, fileName), {encoding: 'utf8'}); +    const update2 = loadDataFile('bg/data/anki-field-templates-upgrade-v2.handlebars'); +    const update4 = loadDataFile('bg/data/anki-field-templates-upgrade-v4.handlebars'); + +    const data = [ +        // Standard format +        { +            old: ` +{{#*inline "character"}} +    {{~definition.character~}} +{{/inline}} + +{{~> (lookup . "marker") ~}}`.trimStart(), + +            expected: ` +{{#*inline "character"}} +    {{~definition.character~}} +{{/inline}} + +${update2} +${update4} +{{~> (lookup . "marker") ~}}`.trimStart() +        }, +        // Non-standard marker format +        { +            old: ` +{{#*inline "character"}} +    {{~definition.character~}} +{{/inline}} + +{{~> (lookup . "marker2") ~}}`.trimStart(), + +            expected: ` +{{#*inline "character"}} +    {{~definition.character~}} +{{/inline}} + +{{~> (lookup . "marker2") ~}} +${update2} +${update4}`.trimStart() +        }, +        // Empty test +        { +            old: ` +{{~> (lookup . "marker") ~}}`.trimStart(), + +            expected: ` +${update2} +${update4} +{{~> (lookup . "marker") ~}}`.trimStart() +        } +    ]; + +    for (const {old, expected} of data) { +        const options = createOptionsTestData1(); +        options.profiles[0].options.anki.fieldTemplates = old; +        const optionsUpdated = clone(await optionsUtil.update(options)); +        const fieldTemplatesActual = optionsUpdated.profiles[0].options.anki.fieldTemplates; +        assert.deepStrictEqual(fieldTemplatesActual, expected); +    } +} + + +async function main() { +    const extDir = path.join(__dirname, '..', 'ext'); +    await testUpdate(extDir); +    await testFieldTemplatesUpdate(extDir); +} + + +if (require.main === module) { main(); } |