UNPKG

intern

Version:

Intern. A next-generation code testing stack for JavaScript.

725 lines 28.4 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "@dojo/core/lang", "./path"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var lang_1 = require("@dojo/core/lang"); var path_1 = require("./path"); function evalProperty(key) { var addToExisting = key[key.length - 1] === '+'; var name = (addToExisting ? key.slice(0, key.length - 1) : key); return { name: name, addToExisting: addToExisting }; } exports.evalProperty = evalProperty; function getBasePath(configFile, basePath, isAbsolute, pathSep) { pathSep = pathSep || path_1.getPathSep(configFile, basePath); var configPathParts = configFile.replace(/\\/g, '/').split('/'); var initialBasePath; if (configFile[0] === '/' && configPathParts.length === 2) { initialBasePath = '/'; } else { initialBasePath = configPathParts.slice(0, -1).join('/'); } var finalBasePath; if (basePath) { basePath = path_1.normalize(basePath); if (isAbsolute(basePath)) { finalBasePath = basePath; } else { finalBasePath = path_1.join(initialBasePath, basePath); } } else { finalBasePath = initialBasePath; } return finalBasePath.split('/').join(pathSep); } exports.getBasePath = getBasePath; function getConfigDescription(config, prefix) { if (prefix === void 0) { prefix = ''; } var description = ''; if (config.description) { description += "" + prefix + config.description + "\n\n"; } if (config.configs) { description += prefix + "Configs:\n"; var width_1 = Object.keys(config.configs).reduce(function (width, name) { return Math.max(width, name.length); }, 0); var lines = Object.keys(config.configs).map(function (name) { var child = config.configs[name]; while (name.length < width_1) { name += ' '; } var line = " " + name; if (child.description) { line += " (" + child.description + ")"; } return "" + prefix + line; }); description += lines.join('\n'); } return description; } exports.getConfigDescription = getConfigDescription; function isTask(value) { if (!value || typeof value !== 'object') { return false; } for (var _i = 0, _a = ['then', 'catch', 'finally', 'cancel']; _i < _a.length; _i++) { var name_1 = _a[_i]; if (!(name_1 in value) || typeof value[name_1] !== 'function') { return false; } } return true; } exports.isTask = isTask; function loadConfig(configPath, loadText, args, childConfig) { return _loadConfig(configPath, loadText, args, childConfig).then(function (config) { delete config.config; delete config.extends; if (!(args && (args.showConfigs || args.help))) { delete config.configs; } return config; }); } exports.loadConfig = loadConfig; function parseArgs(rawArgs) { var parsedArgs = {}; for (var _i = 0, rawArgs_1 = rawArgs; _i < rawArgs_1.length; _i++) { var arg = rawArgs_1[_i]; var name_2 = arg; var value = void 0; var args = parsedArgs; var eq = arg.indexOf('='); if (eq !== -1) { name_2 = arg.slice(0, eq); value = arg.slice(eq + 1); } if (name_2.indexOf('.') !== -1) { var parts = name_2.split('.'); var head = parts.slice(0, parts.length - 1); name_2 = parts[parts.length - 1]; for (var _a = 0, head_1 = head; _a < head_1.length; _a++) { var part = head_1[_a]; if (!args[part]) { args[part] = {}; } args = args[part]; } } if (typeof value === 'undefined') { args[name_2] = true; } else { if (!(name_2 in args)) { args[name_2] = value; } else if (!Array.isArray(args[name_2])) { args[name_2] = [args[name_2], value]; } else { args[name_2].push(value); } } } return parsedArgs; } exports.parseArgs = parseArgs; function parseJson(json) { return JSON.parse(removeComments(json)); } exports.parseJson = parseJson; function parseValue(name, value, parser, requiredProperty) { switch (parser) { case 'boolean': if (typeof value === 'boolean') { return value; } if (value === 'true') { return true; } if (value === 'false') { return false; } throw new Error("Non-boolean value \"" + value + "\" for " + name); case 'number': var numValue = Number(value); if (!isNaN(numValue)) { return numValue; } throw new Error("Non-numeric value \"" + value + "\" for " + name); case 'regexp': if (typeof value === 'string') { return new RegExp(value); } if (value instanceof RegExp) { return value; } throw new Error("Non-regexp value \"" + value + "\" for " + name); case 'object': if (typeof value === 'string') { try { value = value ? JSON.parse(value) : {}; } catch (error) { if (!requiredProperty) { throw new Error("Non-object value \"" + value + "\" for " + name); } value = (_a = {}, _a[requiredProperty] = value, _a); } } if (Object.prototype.toString.call(value) === '[object Object]') { if (requiredProperty && !value[requiredProperty]) { throw new Error("Invalid value \"" + JSON.stringify(value) + "\" for " + name + ": missing '" + requiredProperty + "' property"); } return value; } throw new Error("Non-object value \"" + value + "\" for " + name); case 'object[]': if (!value) { value = []; } if (!Array.isArray(value)) { value = [value]; } return value.map(function (item) { return parseValue(name, item, 'object', requiredProperty); }); case 'string': if (typeof value === 'string') { return value; } throw new Error("Non-string value \"" + value + "\" for " + name); case 'string[]': if (!value) { value = []; } if (typeof value === 'string') { value = [value]; } if (Array.isArray(value) && value.every(function (v) { return typeof v === 'string'; })) { return value; } throw new Error("Non-string[] value \"" + value + "\" for " + name); default: if (typeof parser === 'function') { return parser(value); } else { throw new Error('Parser must be a valid type name'); } } var _a; } exports.parseValue = parseValue; function prefix(message, prefix) { return message .split('\n') .map(function (line) { return prefix + line; }) .join('\n'); } exports.prefix = prefix; function processOption(key, value, config, executor) { var _a = evalProperty(key), name = _a.name, addToExisting = _a.addToExisting; var emit = executor ? function (eventName, data) { executor.emit(eventName, data); } : function () { var _args = []; for (var _i = 0; _i < arguments.length; _i++) { _args[_i] = arguments[_i]; } }; if (name === 'loader') { setOption(config, name, parseValue(name, value, 'object', 'script')); } else if (name === 'bail' || name === 'baseline' || name === 'benchmark' || name === 'debug' || name === 'filterErrorStack' || name === 'showConfig') { setOption(config, name, parseValue(name, value, 'boolean')); } else if (name === 'basePath' || name === 'coverageVariable' || name === 'description' || name === 'internPath' || name === 'name' || name === 'sessionId') { setOption(config, name, parseValue(name, value, 'string')); } else if (name === 'defaultTimeout') { setOption(config, name, parseValue(name, value, 'number')); } else if (name === 'grep') { setOption(config, name, parseValue(name, value, 'regexp')); } else if (name === 'reporters') { setOption(config, name, parseValue(name, value, 'object[]', 'name'), addToExisting); } else if (name === 'plugins' || name === 'requires' || name === 'require' || name === 'scripts') { var useLoader = false; var _name = name; if (name === 'scripts') { emit('deprecated', { original: 'scripts', replacement: 'plugins' }); _name = 'plugins'; } else if (name === 'require') { emit('deprecated', { original: 'require', replacement: 'plugins' }); _name = 'plugins'; } else if (name === 'requires') { emit('deprecated', { original: 'require', replacement: 'plugins', message: 'Set `useLoader: true`' }); _name = 'plugins'; useLoader = true; } var parsed = parseValue(_name, value, 'object[]', 'script'); if (useLoader) { parsed.forEach(function (entry) { entry.useLoader = true; }); } setOption(config, _name, parsed, addToExisting); } else if (name === 'suites') { setOption(config, name, parseValue(name, value, 'string[]'), addToExisting); } else if (name === 'node' || name === 'browser') { var envConfig_1 = config[name] || {}; if (!config[name]) { config[name] = envConfig_1; } var envName_1 = name; var _value_1 = parseValue(name, value, 'object'); if (_value_1) { Object.keys(_value_1).forEach(function (valueKey) { var key = valueKey; var resource = _value_1[key]; var _a = evalProperty(key), name = _a.name, addToExisting = _a.addToExisting; switch (name) { case 'loader': resource = parseValue(name, resource, 'object', 'script'); setOption(envConfig_1, name, resource, false); break; case 'reporters': resource = parseValue('reporters', resource, 'object[]', 'name'); setOption(envConfig_1, name, resource, addToExisting); break; case 'plugins': case 'require': case 'requires': case 'scripts': var useLoader = false; if (name === 'scripts') { emit('deprecated', { original: 'scripts', replacement: 'plugins' }); name = 'plugins'; } else if (name === 'require') { emit('deprecated', { original: 'require', replacement: 'plugins' }); name = 'plugins'; } else if (name === 'requires') { emit('deprecated', { original: 'requires', replacement: 'plugins', message: 'Set `useLoader: true`' }); name = 'plugins'; useLoader = true; } resource = parseValue(name, resource, 'object[]', 'script'); if (useLoader) { resource.forEach(function (entry) { entry.useLoader = true; }); } setOption(envConfig_1, name, resource, addToExisting); break; case 'suites': resource = parseValue(name, resource, 'string[]'); setOption(envConfig_1, name, resource, addToExisting); break; default: throw new Error("Invalid property " + key + " in " + envName_1 + " config"); } }); } } else if (name === 'functionalBaseUrl' || name === 'serverUrl') { setOption(config, name, parseValue(name, value, 'string')); } else if (name === 'proxy') { if (value == null) { setOption(config, name, undefined); } else { setOption(config, name, parseValue(name, value, 'string')); } } else if (name === 'capabilities' || name === 'instrumenterOptions' || name === 'tunnelOptions') { setOption(config, name, parseValue(name, value, 'object'), addToExisting); } else if (name === 'environments') { var _value = value; if (!_value) { _value = []; } else if (!Array.isArray(_value)) { _value = [_value]; } _value = _value.map(function (val) { if (typeof val === 'object' && val.browserName == null) { val.browserName = val.browser; } return val; }); setOption(config, name, parseValue(name, _value, 'object[]', 'browserName'), addToExisting); } else if (name === 'excludeInstrumentation') { emit('deprecated', { original: 'excludeInstrumentation', replacement: 'coverage' }); } else if (name === 'tunnel') { setOption(config, name, parseValue(name, value, 'string')); } else if (name === 'functionalCoverage' || name === 'leaveRemoteOpen' || name === 'serveOnly' || name === 'runInSync') { setOption(config, name, parseValue(name, value, 'boolean')); } else if (name === 'coverage') { var parsed = void 0; try { parsed = parseValue(name, value, 'boolean'); } catch (error) { parsed = parseValue(name, value, 'string[]'); } if (typeof parsed === 'boolean' && parsed !== false) { throw new Error("Non-false boolean for 'coverage'"); } setOption(config, name, parsed); } else if (name === 'functionalSuites') { setOption(config, name, parseValue(name, value, 'string[]'), addToExisting); } else if (name === 'functionalTimeouts') { if (!config.functionalTimeouts) { config.functionalTimeouts = {}; } var parsedTimeout_1 = parseValue(name, value, 'object'); if (parsedTimeout_1) { Object.keys(parsedTimeout_1).forEach(function (timeoutKey) { var key = timeoutKey; if (key === 'connectTimeout') { emit('deprecated', { original: 'functionalTimeouts.connectTimeout', replacement: 'connectTimeout' }); setOption(config, key, parseValue(key, parsedTimeout_1[key], 'number')); } else { config.functionalTimeouts[key] = parseValue("functionalTimeouts." + key, parsedTimeout_1[key], 'number'); } }); } else { setOption(config, name, {}); } } else if (name === 'connectTimeout' || name === 'heartbeatInterval' || name === 'maxConcurrency' || name === 'serverPort' || name === 'socketPort') { setOption(config, name, parseValue(name, value, 'number')); } else { emit('log', "Config has unknown option \"" + name + "\""); setOption(config, name, value); } } exports.processOption = processOption; function pullFromArray(haystack, needle) { var removed = []; var i = 0; while ((i = haystack.indexOf(needle, i)) > -1) { removed.push(haystack.splice(i, 1)[0]); } return removed; } exports.pullFromArray = pullFromArray; function removeComments(text) { var state = 'default'; var i = 0; var chars = text.split(''); while (i < chars.length) { switch (state) { case 'block-comment': if (chars[i] === '*' && chars[i + 1] === '/') { chars[i] = ' '; chars[i + 1] = ' '; state = 'default'; i += 2; } else if (chars[i] !== '\n') { chars[i] = ' '; i += 1; } else { i += 1; } break; case 'line-comment': if (chars[i] === '\n') { state = 'default'; } else { chars[i] = ' '; } i += 1; break; case 'string': if (chars[i] === '"') { state = 'default'; i += 1; } else if (chars[i] === '\\' && chars[i + 1] === '\\') { i += 2; } else if (chars[i] === '\\' && chars[i + 1] === '"') { i += 2; } else { i += 1; } break; default: if (chars[i] === '"') { state = 'string'; i += 1; } else if (chars[i] === '/' && chars[i + 1] === '*') { chars[i] = ' '; chars[i + 1] = ' '; state = 'block-comment'; i += 2; } else if (chars[i] === '/' && chars[i + 1] === '/') { chars[i] = ' '; chars[i + 1] = ' '; state = 'line-comment'; i += 2; } else { i += 1; } } } return chars.join(''); } function setOption(config, name, value, addToExisting) { if (addToExisting === void 0) { addToExisting = false; } if (addToExisting) { var currentValue = config[name]; if (currentValue == null) { config[name] = value; } else if (Array.isArray(currentValue)) { currentValue.push.apply(currentValue, value); } else if (typeof config[name] === 'object') { config[name] = lang_1.deepMixin({}, config[name], value); } else { throw new Error('Only array or object options may be added'); } } else { config[name] = value; } } exports.setOption = setOption; function splitConfigPath(path, separator) { if (separator === void 0) { separator = '/'; } var lastSep = path.lastIndexOf(configPathSeparator); if (lastSep === 0) { return { configFile: '', childConfig: path.slice(1) }; } if (lastSep === -1 || path[lastSep - 1] === separator) { return { configFile: path }; } return { configFile: path.slice(0, lastSep), childConfig: path.slice(lastSep + 1) }; } exports.splitConfigPath = splitConfigPath; function stringify(object, indent) { return JSON.stringify(object, serializeReplacer, indent); } exports.stringify = stringify; function _loadConfig(configPath, loadText, args, childConfig) { return loadText(configPath) .then(function (text) { var preConfig; try { preConfig = parseJson(text); } catch (error) { throw new Error("Invalid JSON in " + configPath); } if (preConfig.extends) { var parts = configPath.split('/'); var _a = splitConfigPath(preConfig.extends), configFile = _a.configFile, childConfig_1 = _a.childConfig; var extensionPath = parts .slice(0, parts.length - 1) .concat(configFile) .join('/'); return _loadConfig(extensionPath, loadText, undefined, childConfig_1).then(function (extension) { Object.keys(preConfig) .filter(function (key) { return key !== 'configs'; }) .forEach(function (key) { processOption(key, preConfig[key], extension); }); if (preConfig.configs) { if (extension.configs == null) { extension.configs = {}; } Object.keys(preConfig.configs).forEach(function (key) { extension.configs[key] = preConfig.configs[key]; }); } return extension; }); } else { var config_1 = {}; Object.keys(preConfig).forEach(function (key) { processOption(key, preConfig[key], config_1); }); return config_1; } }) .then(function (config) { if (args && (args.showConfigs || args.help)) { return config; } if (childConfig) { var mixinConfig_1 = function (childConfig) { var configs = Array.isArray(childConfig) ? childConfig : [childConfig]; configs.forEach(function (childConfig) { var child = config.configs[childConfig]; if (!child) { throw new Error("Unknown child config \"" + childConfig + "\""); } if (child.extends) { mixinConfig_1(child.extends); } Object.keys(child) .filter(function (key) { return key !== 'node' && key !== 'browser'; }) .forEach(function (key) { processOption(key, child[key], config); }); ['node', 'browser'].forEach(function (key) { if (child[key]) { if (config[key]) { var envConfig = {}; processOption(key, child[key], envConfig); lang_1.mixin(config[key], envConfig[key]); } else { processOption(key, child[key], config); } } }); }); }; mixinConfig_1(childConfig); } return config; }) .then(function (config) { if (args) { var resources = [ 'plugins', 'reporters', 'suites' ]; resources .filter(function (resource) { return resource in args; }) .forEach(function (resource) { var environments = [ 'node', 'browser' ]; environments .filter(function (environment) { return config[environment]; }) .forEach(function (environment) { delete config[environment][resource]; }); }); Object.keys(args).forEach(function (key) { processOption(key, args[key], config); }); } return config; }); } var configPathSeparator = '@'; function serializeReplacer(_key, value) { if (!value) { return value; } if (value instanceof RegExp) { return value.source; } if (typeof value === 'function') { return value.toString(); } return value; } }); //# sourceMappingURL=util.js.map