diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/test-profile-conditions.js | 847 | ||||
| -rw-r--r-- | test/yomichan-vm.js | 21 | 
2 files changed, 868 insertions, 0 deletions
| diff --git a/test/test-profile-conditions.js b/test/test-profile-conditions.js new file mode 100644 index 00000000..ce26cbb4 --- /dev/null +++ b/test/test-profile-conditions.js @@ -0,0 +1,847 @@ +/* + * 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 assert = require('assert'); +const {VM} = require('./yomichan-vm'); + + +const vm = new VM({}); +vm.execute([ +    'mixed/js/core.js', +    'mixed/js/cache-map.js', +    'bg/js/json-schema.js', +    'bg/js/profile-conditions2.js' +]); +const [JsonSchema, ProfileConditions] = vm.get(['JsonSchema', 'ProfileConditions']); + + +function schemaValidate(value, schema) { +    try { +        JsonSchema.validate(value, schema); +        return true; +    } catch (e) { +        return false; +    } +} + + +function testNormalizeContext() { +    const data = [ +        // Empty +        { +            context: {}, +            expected: {} +        }, + +        // Domain normalization +        { +            context: {url: ''}, +            expected: {url: ''} +        }, +        { +            context: {url: 'http://example.com/'}, +            expected: {url: 'http://example.com/', domain: 'example.com'} +        }, +        { +            context: {url: 'http://example.com:1234/'}, +            expected: {url: 'http://example.com:1234/', domain: 'example.com'} +        }, +        { +            context: {url: 'http://user@example.com:1234/'}, +            expected: {url: 'http://user@example.com:1234/', domain: 'example.com'} +        } +    ]; + +    for (const {context, expected} of data) { +        const profileConditions = new ProfileConditions(); +        const actual = profileConditions.normalizeContext(context); +        vm.assert.deepStrictEqual(actual, expected); +    } +} + +function testSchemas() { +    const data = [ +        // Empty +        { +            conditionGroups: [], +            expectedSchema: {}, +            inputs: [ +                {expected: true, context: {url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                {conditions: []} +            ], +            expectedSchema: {}, +            inputs: [ +                {expected: true, context: {url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                {conditions: []}, +                {conditions: []} +            ], +            expectedSchema: {}, +            inputs: [ +                {expected: true, context: {url: 'http://example.com/'}} +            ] +        }, + +        // popupLevel tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'equal', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: {const: 0} +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'notEqual', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                not: [ +                    { +                        properties: { +                            depth: {const: 0} +                        }, +                        required: ['depth'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        exclusiveMaximum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        exclusiveMinimum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'lessThanOrEqual', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        maximum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThanOrEqual', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        minimum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, + +        // url tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'url', +                            operator: 'matchDomain', +                            value: 'example.com' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    domain: { +                        oneOf: [ +                            {const: 'example.com'} +                        ] +                    } +                }, +                required: ['domain'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example1.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example2.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com:1234/'}}, +                {expected: true,  context: {depth: 0, url: 'http://user@example.com:1234/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'url', +                            operator: 'matchDomain', +                            value: 'example.com, example1.com, example2.com' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    domain: { +                        oneOf: [ +                            {const: 'example.com'}, +                            {const: 'example1.com'}, +                            {const: 'example2.com'} +                        ] +                    } +                }, +                required: ['domain'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example1.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example2.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example3.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com:1234/'}}, +                {expected: true,  context: {depth: 0, url: 'http://user@example.com:1234/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'url', +                            operator: 'matchRegExp', +                            value: '^http://example\\d?\\.com/[\\w\\W]*$' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    url: { +                        type: 'string', +                        pattern: '^http://example\\d?\\.com/[\\w\\W]*$', +                        patternFlags: 'i' +                    } +                }, +                required: ['url'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example1.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example2.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example3.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/example'}}, +                {expected: false, context: {depth: 0, url: 'http://example.com:1234/'}}, +                {expected: false, context: {depth: 0, url: 'http://user@example.com:1234/'}}, +                {expected: false, context: {depth: 0, url: 'http://example-1.com/'}} +            ] +        }, + +        // modifierKeys tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'are', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        maxItems: 0, +                        minItems: 0 +                    } +                }, +                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']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'are', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        maxItems: 2, +                        minItems: 2, +                        allOf: [ +                            {contains: {const: 'Alt'}}, +                            {contains: {const: 'Shift'}} +                        ] +                    } +                }, +                required: ['modifierKeys'] +            }, +            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']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'areNot', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                not: [ +                    { +                        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']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'areNot', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                not: [ +                    { +                        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']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'include', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        minItems: 0 +                    } +                }, +                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: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'include', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        minItems: 2, +                        allOf: [ +                            {contains: {const: 'Alt'}}, +                            {contains: {const: 'Shift'}} +                        ] +                    } +                }, +                required: ['modifierKeys'] +            }, +            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']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'notInclude', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array' +                    } +                }, +                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: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'notInclude', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        not: [ +                            {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']}} +            ] +        }, + +        // Multiple conditions tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '3' +                        } +                    ] +                } +            ], +            expectedSchema: { +                allOf: [ +                    { +                        properties: { +                            depth: { +                                type: 'number', +                                exclusiveMinimum: 0 +                            } +                        }, +                        required: ['depth'] +                    }, +                    { +                        properties: { +                            depth: { +                                type: 'number', +                                exclusiveMaximum: 3 +                            } +                        }, +                        required: ['depth'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: -2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 3, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '3' +                        } +                    ] +                }, +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'equal', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                anyOf: [ +                    { +                        allOf: [ +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMinimum: 0 +                                    } +                                }, +                                required: ['depth'] +                            }, +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMaximum: 3 +                                    } +                                }, +                                required: ['depth'] +                            } +                        ] +                    }, +                    { +                        properties: { +                            depth: {const: 0} +                        }, +                        required: ['depth'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: -2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 3, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '3' +                        } +                    ] +                }, +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'lessThanOrEqual', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'greaterThanOrEqual', +                            value: '-1' +                        } +                    ] +                } +            ], +            expectedSchema: { +                anyOf: [ +                    { +                        allOf: [ +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMinimum: 0 +                                    } +                                }, +                                required: ['depth'] +                            }, +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMaximum: 3 +                                    } +                                }, +                                required: ['depth'] +                            } +                        ] +                    }, +                    { +                        allOf: [ +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        maximum: 0 +                                    } +                                }, +                                required: ['depth'] +                            }, +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        minimum: -1 +                                    } +                                }, +                                required: ['depth'] +                            } +                        ] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: -2, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 3, url: 'http://example.com/'}} +            ] +        } +    ]; + +    for (const {conditionGroups, expectedSchema, inputs} of data) { +        const profileConditions = new ProfileConditions(); +        const schema = profileConditions.createSchema(conditionGroups); +        if (typeof expectedSchema !== 'undefined') { +            vm.assert.deepStrictEqual(schema, expectedSchema); +        } +        if (Array.isArray(inputs)) { +            for (const {expected, context} of inputs) { +                const normalizedContext = profileConditions.normalizeContext(context); +                const actual = schemaValidate(normalizedContext, schema); +                assert.strictEqual(actual, expected); +            } +        } +    } +} + + +function main() { +    testNormalizeContext(); +    testSchemas(); +} + + +if (require.main === module) { main(); } diff --git a/test/yomichan-vm.js b/test/yomichan-vm.js index 97faa03e..79e92772 100644 --- a/test/yomichan-vm.js +++ b/test/yomichan-vm.js @@ -115,8 +115,29 @@ function deepStrictEqual(actual, expected) {  } +function createURLClass() { +    const BaseURL = URL; +    return function URL(url) { +        const u = new BaseURL(url); +        this.hash = u.hash; +        this.host = u.host; +        this.hostname = u.hostname; +        this.href = u.href; +        this.origin = u.origin; +        this.password = u.password; +        this.pathname = u.pathname; +        this.port = u.port; +        this.protocol = u.protocol; +        this.search = u.search; +        this.searchParams = u.searchParams; +        this.username = u.username; +    }; +} + +  class VM {      constructor(context={}) { +        context.URL = createURLClass();          this._context = vm.createContext(context);          this._assert = {              deepStrictEqual |