UNPKG

browser-ui-test

Version:

Small JS framework to provide headless browser-based tests

133 lines (124 loc) 3.88 kB
// Commands related to setting script functions. const { RESERVED_VARIABLE_NAME, hasError, plural } = require('../utils.js'); const { validator } = require('../validator.js'); // Possible inputs: // // * ("function name", [ident arguments], block {}) function parseDefineFunction(parser) { const ret = validator(parser, { kind: 'tuple', elements: [ { kind: 'string', allowEmpty: false, }, { kind: 'array', valueTypes: { 'ident': { notAllowed: [RESERVED_VARIABLE_NAME, 'null'], }, }, }, { kind: 'block', }, ], }, ); if (hasError(ret)) { return ret; } const tuple = ret.value.entries; const func_name = tuple[0].value.value; let warnings = undefined; if (parser.definedFunctions.has(func_name)) { warnings = [`overwriting existing \`${func_name}\` function`]; } parser.definedFunctions.set(func_name, { 'arguments': tuple[1].value.entries.map(e => e.value), 'commands': tuple[2].value.value, 'start_line': tuple[2].value.blockLine, 'filePath': parser.getCurrentFile(), }); return { 'instructions': [], 'wait': false, 'warnings': warnings, }; } // This function is only to get parsing errors, function name and arguments. // // Possible inputs: // // * ("function name", [arguments value] | {"argument": value}) function parseCallFunction(parser) { const ret = validator(parser, { kind: 'tuple', elements: [ { kind: 'string', allowEmpty: false, }, { kind: 'json', keyTypes: { 'string': [], }, allowAllValues: true, allowRecursiveValues: true, valueTypes: {}, }, ], }, ); if (hasError(ret)) { return ret; } const tuple = ret.value.entries; const func_name = tuple[0].value.value; if (!parser.definedFunctions.has(func_name)) { return { 'error': `no function called \`${func_name}\`. To define a function, use \ the \`define-function\` command`, }; } const args = tuple[1].value.getRaw(); const expected_args = parser.definedFunctions.get(func_name)['arguments'].length; if (args.length !== expected_args) { return { 'error': `function \`${func_name}\` expected ${expected_args} \ ${plural('argument', expected_args)}, found ${args.length}`, }; } const funcArgs = new Map(); const func = parser.definedFunctions.get(func_name); for (const arg_name of func['arguments']) { const index = args.findIndex(arg => arg.key.value === arg_name); if (index === -1) { return { 'error': `Missing argument "${arg_name}"`, 'line': parser.get_current_command_line(), 'fatal_error': true, }; } funcArgs.set(arg_name, args[index].value); } const context = parser.get_current_context(); parser.pushNewContext({ 'ast': context.ast, 'commands': func.commands, 'currentCommand': 0, 'functionArgs': new Map([...context.functionArgs, ...funcArgs]), 'filePath': func.filePath, }); return { 'skipInstructions': true, }; } module.exports = { 'parseDefineFunction': parseDefineFunction, 'parseCallFunction': parseCallFunction, };