UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

282 lines (207 loc) 9 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ !function () { var fs = require('fs') var path = require('path') Class('Siesta.Launcher.DiscoverTool', { does : [ Siesta.Launcher.CommandLineTool.BaseTool, Siesta.Launcher.CommandLineTool.NodeJSTool, Siesta.Util.Role.CanGetType, Siesta.Util.Role.CanEscapeRegExp ], has : { helpIntro : function () { return [ 'Usage: discover [OPTIONS] desc_file.json dir1 dir2 ... dirN', 'All options are optional.', '', 'This tool will scan the provided dirs and create a corresponding', 'set of test descriptors in the `desc_file.json`. This file is', 'suitable for usage with the project `startFromUrl` method.', 'Existing content of `desc_file.json` will be preservered', 'as much as possible', '' ] }, knownOptionGroups : { init : { '00-system' : { name : 'Base options' } } }, knownOptions : { init : [ { name : 'help', desc : 'Prints this help message and exit', group : '00-system' }, { name : 'version', desc : 'Prints versions of Siesta and automation component and exit', group : '00-system' }, { name : 'overwrite', desc : 'Overwrite any existing content of the `desc.json` file, w/o trying to preserve it', group : '00-system' }, { name : 'ext', desc : 'Test file extension, default value is "t.js"', group : '00-system' }, { name : 'base-dir', desc : [ 'Test base directory (directory with your project html file), all other file paths', 'will be resolved relative to that dir.' ], group : '00-system' } ] }, descriptorsFile : null, descriptors : null }, override : { prepareOptions : function (callback) { var me = this this.SUPER(function (e) { if (e) { callback(e); return } if (me.argv.length < 2) { me.printError("Should have at least 2 positional arguments - first one is the JSON file with test descriptors, second - directory to scan for test files.") me.printHelp() callback(true) return } me.descriptorsFile = me.argv.shift() var fileName = me.descriptorsFile if (me.fileExists(fileName) && !me.options.overwrite) { var json try { json = me.readFile(fileName) } catch (e) { me.printError([ me.formatString("Can't read the content of the JSON file: {fileName}", { fileName : fileName }) ]) callback(true) return } try { json = JSON.parse(json) if (me.typeOf(json) != 'Array') throw "not an array" me.descriptors = json } catch (e) { if (!me.options.overwrite) { me.printError([ me.formatString("JSON file does not contain valid JSON array: {fileName}", { fileName : fileName }) ]) callback(true) return } } } callback() }) } }, methods : { start : function (callback) { var me = this this.prepareOptions(function (e) { if (e) { callback(null, 1); return } me.launch(callback) }) }, createIndex : function (descriptors, parentDesc, index) { var me = this index = index || { groups : {}, tests : {} } Joose.A.each(descriptors, function (desc) { if (desc) if (desc.group) { desc.id = parentDesc ? parentDesc.id + '/' + desc.group : desc.group var hasSpecialConfig = false for (var i in desc) if (i != 'group' && i != 'items' && i != 'id') { hasSpecialConfig = true; break; } if (hasSpecialConfig) index.groups[ desc.id ] = desc me.createIndex(desc.items, desc, index) } else if (typeof desc != 'string' && desc.url) index.tests[ desc.url ] = desc }) return index }, launch : function (callback) { var me = this var groups = [] var index if (me.descriptors) index = this.createIndex(me.descriptors) Joose.A.each(this.argv, function (dir) { groups.push(me.scanDir(dir, index)) }) this.saveFile(this.descriptorsFile, require('js-beautify').js_beautify(JSON.stringify(groups), { // wrap the line at the first chance wrap_line_length : 1, brace_style : "expand" })) callback() }, scanDir : function (dir, index, recurseCall) { dir = path.resolve(this.normalizePath(dir)) var me = this var items = [] var group = { group : path.basename(dir) + '' } var baseDir = path.resolve(this.options[ 'base-dir' ] || '') var regexp = new RegExp(this.escapeRegExp((this.options.ext || '.t.js')) + '$') Joose.A.each(fs.readdirSync(dir), function (file) { file = path.resolve(dir, file) var stat = fs.statSync(file) if (stat.isDirectory()) { var id = path.basename(dir) + '/' + path.relative(dir, file) var subGroup = me.scanDir(file, index, true) if (index && index.groups[ id ]) { me.mergePropsFromExistingDesc(subGroup, index.groups[ id ], true) // re-assign to "items" property go last var prev = subGroup.items delete subGroup.items subGroup.items = prev } if (subGroup.items.length || index && index.groups[ id ]) items.push(subGroup) } else if (regexp.test(file)) { var relativePath = path.relative(baseDir, file).replace(/\\/g, '/') if (index && index.tests[ relativePath ]) items.push(me.mergePropsFromExistingDesc({ url : relativePath }, index.tests[ relativePath ], false)) else items.push(relativePath) } }) if (!recurseCall) { var topDirId = path.basename(dir) if (index && index.groups[ topDirId ]) me.mergePropsFromExistingDesc(group, index.groups[ topDirId ], true) } // asign last so that in stringified form it goes also last group.items = items return group }, mergePropsFromExistingDesc : function (newDesc, oldDesc, isGroup) { for (var i in oldDesc) { if (isGroup && i != 'group' && i != 'items' && i != 'id' || !isGroup && i != 'url') newDesc[ i ] = oldDesc [ i ] } return newDesc }, printVersion : function () { var siestaAll = this.readFile(this.binDir + '../siesta-all.js') var match = /^\/\*[\s\S]*?Siesta (\d.+)\n/.exec(siestaAll) if (match) this.print("Siesta : " + match[ 1 ]) } } }) }()