Compare commits
No commits in common. "master" and "v1.4.0" have entirely different histories.
17 changed files with 65 additions and 372 deletions
|
@ -111,11 +111,9 @@ $ eltro --watch my_watch_name --npm build
|
||||||
|
|
||||||
Not only does eltro allow you to use any assertion library of your own choosing, it also comes with it's own assertion library based on node's default [assert](https://nodejs.org/api/assert.html) with a few extra methods:
|
Not only does eltro allow you to use any assertion library of your own choosing, it also comes with it's own assertion library based on node's default [assert](https://nodejs.org/api/assert.html) with a few extra methods:
|
||||||
|
|
||||||
* `assert.equalWithMargin(value, test, margin, [message])`: Check if number value is equal to test with error margin.
|
|
||||||
* `assert.notOk(value, [message])`: Assert value is not ok.
|
* `assert.notOk(value, [message])`: Assert value is not ok.
|
||||||
* `assert.match(value, test, [message])`: Check if value matches RegExp test.
|
* `assert.match(value, test, [message])`: Check if value matches RegExp test.
|
||||||
* `assert.notMatch(value, [message])`: Check if value does not match RegExp test.
|
* `assert.notMatch(value, [message])`: Check if value does not match RegExp test.
|
||||||
* `assert.throwsAndCatch(fn, [message])`: Checks if function fn throws and returns the thrown error.
|
|
||||||
* `assert.isFulfilled(promise, [message])`: Assert the promise resolves.
|
* `assert.isFulfilled(promise, [message])`: Assert the promise resolves.
|
||||||
* `assert.isRejected(promise, [message])`: Assert the promise gets rejects.
|
* `assert.isRejected(promise, [message])`: Assert the promise gets rejects.
|
||||||
|
|
||||||
|
|
11
cli.mjs
11
cli.mjs
|
@ -27,20 +27,15 @@ function PrintHelp() {
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
function showErrorAndExit(message = '', err = null, code = 1, clean = false) {
|
function showErrorAndExit(message = '', err = null, code = 1) {
|
||||||
if (!clean) {
|
|
||||||
console.log('')
|
console.log('')
|
||||||
}
|
|
||||||
|
|
||||||
if (message) {
|
if (message) {
|
||||||
console.error(`\x1b[31m${message}\x1b[0m`)
|
console.error(`\x1b[31m${message}\x1b[0m`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
printError(err, '', clean)
|
printError(err)
|
||||||
if (err.inner) {
|
|
||||||
return showErrorAndExit(null, err.inner, code, true)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
PrintHelp()
|
PrintHelp()
|
||||||
}
|
}
|
||||||
|
@ -59,7 +54,7 @@ cli.parseOptions(args)
|
||||||
})
|
})
|
||||||
.catch(function(err) { showErrorAndExit('Unknown error while processing arguments', err) })
|
.catch(function(err) { showErrorAndExit('Unknown error while processing arguments', err) })
|
||||||
.then(function() {
|
.then(function() {
|
||||||
if (!cli.files.length && cli.run === 'test') {
|
if (!cli.files.length) {
|
||||||
showErrorAndExit('No files were found with pattern', cli.targets.join(','))
|
showErrorAndExit('No files were found with pattern', cli.targets.join(','))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,14 +57,6 @@ assert.throwsAndCatch = (fn, message) => {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.equalWithMargin = (value, test, margin = 0.005, message) => {
|
|
||||||
assert.strictEqual(typeof value, 'number', 'Value should be number')
|
|
||||||
assert.strictEqual(typeof test, 'number', 'Test should be number')
|
|
||||||
|
|
||||||
let difference = Math.abs(value - test)
|
|
||||||
assert.ok(difference <= margin, message || `${value} ± ${margin} != ${test} (difference of ${difference} > ${margin})`)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.isFulfilled = (promise, message) => {
|
assert.isFulfilled = (promise, message) => {
|
||||||
return Promise.resolve(true)
|
return Promise.resolve(true)
|
||||||
.then(() => promise)
|
.then(() => promise)
|
||||||
|
|
13
lib/cli.mjs
13
lib/cli.mjs
|
@ -3,7 +3,6 @@ import fs from 'fs'
|
||||||
import fsPromise from 'fs/promises'
|
import fsPromise from 'fs/promises'
|
||||||
import cluster from 'cluster'
|
import cluster from 'cluster'
|
||||||
import child_process from 'child_process'
|
import child_process from 'child_process'
|
||||||
import kill from './kill.mjs'
|
|
||||||
import Watcher, { EVENT_REMOVE, EVENT_UPDATE } from './watch/index.mjs'
|
import Watcher, { EVENT_REMOVE, EVENT_UPDATE } from './watch/index.mjs'
|
||||||
|
|
||||||
export const MESSAGE_FILES_REQUEST = 'message_files_request'
|
export const MESSAGE_FILES_REQUEST = 'message_files_request'
|
||||||
|
@ -42,12 +41,8 @@ export function CLI(e, overrides = {}) {
|
||||||
this.logger = overrides.logger || console
|
this.logger = overrides.logger || console
|
||||||
this.child_process = overrides.child_process || child_process
|
this.child_process = overrides.child_process || child_process
|
||||||
this.process = overrides.process || process
|
this.process = overrides.process || process
|
||||||
this.kill = overrides.kill || kill
|
|
||||||
this.importer = overrides.importer
|
this.importer = overrides.importer
|
||||||
this.loadDefaults()
|
|
||||||
}
|
|
||||||
|
|
||||||
CLI.prototype.loadDefaults = function() {
|
|
||||||
// Eltro specific options
|
// Eltro specific options
|
||||||
this.reporter = 'list'
|
this.reporter = 'list'
|
||||||
this.ignoreOnly = false
|
this.ignoreOnly = false
|
||||||
|
@ -115,7 +110,7 @@ CLI.prototype.parseOptions = function(args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.targets.length && this.run === 'test') {
|
if (!this.targets.length) {
|
||||||
this.targets.push('test/**')
|
this.targets.push('test/**')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +284,7 @@ CLI.prototype.runProgram = function() {
|
||||||
if (runningTest) {
|
if (runningTest) {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
this.kill(this.worker.pid)
|
this.worker.kill()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,9 +435,9 @@ export function getFilesFromTarget(files, match, insidePath, grabAll, insideStar
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function printError(err, msg, clean = false) {
|
export function printError(err, msg) {
|
||||||
let before = msg || ''
|
let before = msg || ''
|
||||||
if (!clean) console.error('')
|
console.error('')
|
||||||
console.error('\x1b[31m '
|
console.error('\x1b[31m '
|
||||||
+ before + err.toString()
|
+ before + err.toString()
|
||||||
+ '\x1b[0m\n \x1b[90m'
|
+ '\x1b[0m\n \x1b[90m'
|
||||||
|
|
|
@ -117,7 +117,6 @@ process.on('uncaughtException', function(err) {
|
||||||
})
|
})
|
||||||
|
|
||||||
function Eltro() {
|
function Eltro() {
|
||||||
this.process = process
|
|
||||||
this.__timeout = 2000
|
this.__timeout = 2000
|
||||||
this.hasExclusive = false
|
this.hasExclusive = false
|
||||||
this.reporter = 'list'
|
this.reporter = 'list'
|
||||||
|
@ -160,8 +159,8 @@ Eltro.prototype.begin = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test', child = null) {
|
Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test', child = null) {
|
||||||
if (this.reporter === 'list' && prefix === 'Test') {
|
if (this.reporter === 'list') {
|
||||||
this.process.stdout.write(' \x1b[90m? ' + test.name + '\x1b[0m')
|
process.stdout.write(' \x1b[90m? ' + test.name + '\x1b[0m')
|
||||||
}
|
}
|
||||||
|
|
||||||
let markRealTest = child || test
|
let markRealTest = child || test
|
||||||
|
@ -280,24 +279,24 @@ Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test', child =
|
||||||
this.captureOutsideExceptions = null
|
this.captureOutsideExceptions = null
|
||||||
|
|
||||||
if (this.reporter === 'list') {
|
if (this.reporter === 'list') {
|
||||||
readline.clearLine(this.process.stdout, 0)
|
readline.clearLine(process.stdout, 0)
|
||||||
readline.cursorTo(this.process.stdout, 0, null)
|
readline.cursorTo(process.stdout, 0, null)
|
||||||
if (markRealTest.skipTest) {
|
if (markRealTest.skipTest) {
|
||||||
this.process.stdout.write(' \x1b[94m- ' + markRealTest.name + '\x1b[0m\n')
|
process.stdout.write(' \x1b[94m- ' + markRealTest.name + '\x1b[0m\n')
|
||||||
} else if (!markRealTest.error) {
|
} else if (!markRealTest.error) {
|
||||||
if (!test.name.startsWith('~')) {
|
if (!test.name.startsWith('~')) {
|
||||||
this.process.stdout.write(' \x1b[32m√\x1b[90m ' + markRealTest.name + ' (' + markRealTest.totalTime + 'ms)\x1b[0m\n')
|
process.stdout.write(' \x1b[32m√\x1b[90m ' + markRealTest.name + ' (' + markRealTest.totalTime + 'ms)\x1b[0m\n')
|
||||||
}
|
}
|
||||||
} else if (prefix === 'Test') {
|
} else if (prefix === 'Test') {
|
||||||
this.process.stdout.write(' \x1b[31m' + this.failedTests.length + ') ' + markRealTest.name + ' (' + markRealTest.totalTime + 'ms)\x1b[0m\n')
|
process.stdout.write(' \x1b[31m' + this.failedTests.length + ') ' + markRealTest.name + ' (' + markRealTest.totalTime + 'ms)\x1b[0m\n')
|
||||||
}
|
}
|
||||||
} else if (this.reporter === 'dot') {
|
} else if (this.reporter === 'dot') {
|
||||||
if (markRealTest.skipTest) {
|
if (markRealTest.skipTest) {
|
||||||
this.process.stdout.write('\x1b[94m.\x1b[0m')
|
process.stdout.write('\x1b[94m.\x1b[0m')
|
||||||
} else if (markRealTest.error) {
|
} else if (!markRealTest.error) {
|
||||||
this.process.stdout.write('\x1b[31m.\x1b[0m')
|
process.stdout.write('\x1b[32m.\x1b[0m')
|
||||||
} else if (prefix === 'Test') {
|
} else if (prefix === 'Test') {
|
||||||
this.process.stdout.write('\x1b[32m.\x1b[0m')
|
process.stdout.write('\x1b[31m.\x1b[0m')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +304,7 @@ Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test', child =
|
||||||
Eltro.prototype.__runGroup = async function(g, stats) {
|
Eltro.prototype.__runGroup = async function(g, stats) {
|
||||||
if (g.tests.length) {
|
if (g.tests.length) {
|
||||||
if (this.reporter === 'list') {
|
if (this.reporter === 'list') {
|
||||||
this.process.stdout.write(' ' + g.name + '\n')
|
console.log(' ' + g.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g.before) {
|
if (g.before) {
|
||||||
|
@ -352,8 +351,8 @@ Eltro.prototype.__runGroup = async function(g, stats) {
|
||||||
|
|
||||||
Eltro.prototype.run = async function() {
|
Eltro.prototype.run = async function() {
|
||||||
if (this.reporter && this.reporter !== 'test') {
|
if (this.reporter && this.reporter !== 'test') {
|
||||||
this.process.stdout.write('' + '\n')
|
console.log('')
|
||||||
this.process.stdout.write('' + '\n')
|
console.log('')
|
||||||
}
|
}
|
||||||
|
|
||||||
captureUnknownErrors(this)
|
captureUnknownErrors(this)
|
||||||
|
@ -382,23 +381,23 @@ Eltro.prototype.run = async function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (this.reporter) {
|
} else if (this.reporter) {
|
||||||
this.process.stdout.write('' + '\n')
|
console.log('')
|
||||||
this.process.stdout.write('' + '\n')
|
console.log('')
|
||||||
if (stats.passed) {
|
if (stats.passed) {
|
||||||
this.process.stdout.write(' \x1b[32m' + stats.passed + ' passing \x1b[90m(' + (end[0] * 1000 + Math.round(end[1] / 1000000)) + 'ms)\x1b[0m' + '\n')
|
console.log(' \x1b[32m' + stats.passed + ' passing \x1b[90m(' + (end[0] * 1000 + Math.round(end[1] / 1000000)) + 'ms)\x1b[0m')
|
||||||
}
|
}
|
||||||
if (stats.failed) {
|
if (stats.failed) {
|
||||||
this.process.stdout.write(' \x1b[31m' + stats.failed + ' failing\x1b[0m' + '\n')
|
console.log(' \x1b[31m' + stats.failed + ' failing\x1b[0m')
|
||||||
}
|
}
|
||||||
if (stats.skipped) {
|
if (stats.skipped) {
|
||||||
this.process.stdout.write(' \x1b[94m' + stats.skipped + ' pending\x1b[0m' + '\n')
|
console.log(' \x1b[94m' + stats.skipped + ' pending\x1b[0m')
|
||||||
}
|
}
|
||||||
this.process.stdout.write('' + '\n')
|
console.log('')
|
||||||
|
|
||||||
if (this.failedTests.length) {
|
if (this.failedTests.length) {
|
||||||
for (let x = 0; x < this.failedTests.length; x++) {
|
for (let x = 0; x < this.failedTests.length; x++) {
|
||||||
let test = this.failedTests[x];
|
let test = this.failedTests[x];
|
||||||
this.process.stdout.write(' ' + (x + 1) + ') ' + test.name + ':' + '\n')
|
console.log(' ' + (x + 1) + ') ' + test.name + ':')
|
||||||
printError(test.error)
|
printError(test.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
85
lib/kill.mjs
85
lib/kill.mjs
|
@ -1,85 +0,0 @@
|
||||||
import { promisify } from 'util'
|
|
||||||
import { spawn, exec } from 'child_process'
|
|
||||||
|
|
||||||
const execPromise = promisify(exec)
|
|
||||||
|
|
||||||
export default function kill(pid, signal) {
|
|
||||||
let pids = new Set([pid])
|
|
||||||
let getSpawn = null
|
|
||||||
let getPids = null
|
|
||||||
|
|
||||||
switch (process.platform) {
|
|
||||||
case 'win32':
|
|
||||||
return execPromise('taskkill /pid ' + pid + ' /T /F').then(() => pids)
|
|
||||||
case 'darwin':
|
|
||||||
getSpawn = function(parentPid) {
|
|
||||||
return spawn('pgrep', ['-P', parentPid])
|
|
||||||
}
|
|
||||||
getPids = function(data) {
|
|
||||||
return data.match(/\d+/g).map(Number)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
getSpawn = function (parentPid) {
|
|
||||||
return exec('ps -opid="" -oppid="" | grep ' + parentPid)
|
|
||||||
}
|
|
||||||
getPids = function(data, parentPid) {
|
|
||||||
let output = data.trim().split('\n')
|
|
||||||
return output.map(line => {
|
|
||||||
let [child, parent] = line.trim().split(/ +/)
|
|
||||||
|
|
||||||
if (Number(parent) === parentPid) {
|
|
||||||
return Number(child)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}).filter(x => x)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildTree(pids, getSpawn, getPids, pid)
|
|
||||||
.then(function() {
|
|
||||||
for (let pid of pids) {
|
|
||||||
try {
|
|
||||||
process.kill(pid, signal)
|
|
||||||
} catch (err) {
|
|
||||||
if (err.code !== 'ESRCH') throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return pids
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildTree(allPids, spawnGetChildren, spawnGetPids, parentPid) {
|
|
||||||
allPids.add(parentPid)
|
|
||||||
|
|
||||||
let ps = spawnGetChildren(parentPid)
|
|
||||||
let data = ''
|
|
||||||
let err = ''
|
|
||||||
ps.stdout.on('data', function(buf) {
|
|
||||||
data += buf.toString('ascii')
|
|
||||||
})
|
|
||||||
ps.stderr.on('data', function(buf) {
|
|
||||||
err += buf.toString('ascii')
|
|
||||||
})
|
|
||||||
|
|
||||||
return new Promise(function(res, rej) {
|
|
||||||
ps.on('close', function(code) {
|
|
||||||
// Check if ps errored out
|
|
||||||
if (code !== 0 && err.trim()) {
|
|
||||||
return rej(new Error('Error running ps to kill processes:\n\t' + err))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if we otherwise got an error code (usually means empty results)
|
|
||||||
if (code !== 0 || !data.trim()) return res()
|
|
||||||
|
|
||||||
let pids = spawnGetPids(data, parentPid)
|
|
||||||
|
|
||||||
res(Promise.all(
|
|
||||||
pids.filter(pid => pid && !allPids.has(pid))
|
|
||||||
.map(buildTree.bind(this, allPids, spawnGetChildren, spawnGetPids))
|
|
||||||
))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -34,7 +34,6 @@ export function stub(returnFunc = null) {
|
||||||
func.lastCall = null
|
func.lastCall = null
|
||||||
func.called = false
|
func.called = false
|
||||||
func.callCount = 0
|
func.callCount = 0
|
||||||
func.calls = calls
|
|
||||||
|
|
||||||
func.findCall = function(fn) {
|
func.findCall = function(fn) {
|
||||||
for (let call of calls) {
|
for (let call of calls) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "eltro",
|
"name": "eltro",
|
||||||
"version": "1.5.0",
|
"version": "1.4.0",
|
||||||
"description": "Eltro is a tiny no-dependancy test framework for node",
|
"description": "Eltro is a tiny no-dependancy test framework for node",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -29,41 +29,6 @@ t.describe('#notOk()', function() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
t.describe('#equalWithMargin()', function() {
|
|
||||||
t.test('should support default margin for floating point math', function() {
|
|
||||||
let check = 0.1 + 0.2
|
|
||||||
|
|
||||||
assertExtended.throws(function() {
|
|
||||||
assertExtended.strictEqual(check, 0.3)
|
|
||||||
}, assertExtended.AssertionError)
|
|
||||||
|
|
||||||
assertExtended.equalWithMargin(check, 0.3)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should support custom margin', function() {
|
|
||||||
assertExtended.equalWithMargin(1, 2, 1)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should fail if margin is too small', function() {
|
|
||||||
assertExtended.throws(function() {
|
|
||||||
assertExtended.equalWithMargin(1, 2, 0.9)
|
|
||||||
}, assertExtended.AssertionError)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should support custom message', function () {
|
|
||||||
const assertMessage = 'Hello world'
|
|
||||||
let error = null
|
|
||||||
|
|
||||||
try {
|
|
||||||
assertExtended.equalWithMargin(1, 2, 0, assertMessage)
|
|
||||||
} catch (err) {
|
|
||||||
error = err
|
|
||||||
}
|
|
||||||
assert.ok(error)
|
|
||||||
assert.match(error.message, new RegExp(assertMessage))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.describe('#throwAndCatch()', function() {
|
t.describe('#throwAndCatch()', function() {
|
||||||
t.test('should work and return the original error', function() {
|
t.test('should work and return the original error', function() {
|
||||||
const assertError = new Error('Speed')
|
const assertError = new Error('Speed')
|
||||||
|
|
|
@ -26,9 +26,8 @@ t.describe('CLI', function() {
|
||||||
const cluster = { c: 3 }
|
const cluster = { c: 3 }
|
||||||
const process = { d: 4 }
|
const process = { d: 4 }
|
||||||
const importer = { e: 5 }
|
const importer = { e: 5 }
|
||||||
const kill = { f: 6 }
|
|
||||||
|
|
||||||
let cliTest = createSafeCli(eltro, { logger, cluster, process, importer, kill })
|
let cliTest = createSafeCli(eltro, { logger, cluster, process, importer })
|
||||||
assert.strictEqual(cliTest.reporter, 'list')
|
assert.strictEqual(cliTest.reporter, 'list')
|
||||||
assert.strictEqual(cliTest.ignoreOnly, false)
|
assert.strictEqual(cliTest.ignoreOnly, false)
|
||||||
assert.strictEqual(cliTest.timeout, 2000)
|
assert.strictEqual(cliTest.timeout, 2000)
|
||||||
|
@ -44,7 +43,6 @@ t.describe('CLI', function() {
|
||||||
assert.strictEqual(cliTest.cluster, cluster)
|
assert.strictEqual(cliTest.cluster, cluster)
|
||||||
assert.strictEqual(cliTest.process, process)
|
assert.strictEqual(cliTest.process, process)
|
||||||
assert.strictEqual(cliTest.importer, importer)
|
assert.strictEqual(cliTest.importer, importer)
|
||||||
assert.strictEqual(cliTest.kill, kill)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should detect isSlave from cluster', function() {
|
t.test('should detect isSlave from cluster', function() {
|
||||||
|
@ -61,31 +59,32 @@ t.describe('CLI', function() {
|
||||||
*****************************************/
|
*****************************************/
|
||||||
|
|
||||||
t.describe('#parseOptions()', function() {
|
t.describe('#parseOptions()', function() {
|
||||||
t.beforeEach(function() {
|
|
||||||
cli.loadDefaults()
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should not do anything if no options', async function() {
|
t.test('should not do anything if no options', async function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
await cli.parseOptions([])
|
await cli.parseOptions([])
|
||||||
assert.strictEqual(cli.reporter, 'list')
|
assert.strictEqual(cli.reporter, 'list')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding reporter with shorthand option', async function() {
|
t.test('should support overriding reporter with shorthand option', async function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
await cli.parseOptions(['-r', 'dot'])
|
await cli.parseOptions(['-r', 'dot'])
|
||||||
assert.strictEqual(cli.reporter, 'dot')
|
assert.strictEqual(cli.reporter, 'dot')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding reporter with long option', async function() {
|
t.test('should support overriding reporter with long option', async function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
await cli.parseOptions(['--reporter', 'dot'])
|
await cli.parseOptions(['--reporter', 'dot'])
|
||||||
assert.strictEqual(cli.reporter, 'dot')
|
assert.strictEqual(cli.reporter, 'dot')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support enabling ignore-only long option', async function() {
|
t.test('should support enabling ignore-only long option', async function() {
|
||||||
|
cli.ignoreOnly = false
|
||||||
await cli.parseOptions(['--ignore-only', '-r', 'dot'])
|
await cli.parseOptions(['--ignore-only', '-r', 'dot'])
|
||||||
assert.strictEqual(cli.ignoreOnly, true)
|
assert.strictEqual(cli.ignoreOnly, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support reporter list', async function() {
|
t.test('should support reporter list', async function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
await cli.parseOptions(['-r', 'list'])
|
await cli.parseOptions(['-r', 'list'])
|
||||||
assert.strictEqual(cli.reporter, 'list')
|
assert.strictEqual(cli.reporter, 'list')
|
||||||
})
|
})
|
||||||
|
@ -101,11 +100,13 @@ t.describe('CLI', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding timeout with shorthand option', async function() {
|
t.test('should support overriding timeout with shorthand option', async function() {
|
||||||
|
cli.timeout = 2000
|
||||||
await cli.parseOptions(['-t', '1000'])
|
await cli.parseOptions(['-t', '1000'])
|
||||||
assert.strictEqual(cli.timeout, 1000)
|
assert.strictEqual(cli.timeout, 1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding timeout with long option', async function() {
|
t.test('should support overriding timeout with long option', async function() {
|
||||||
|
cli.timeout = 2000
|
||||||
await cli.parseOptions(['--timeout', '250'])
|
await cli.parseOptions(['--timeout', '250'])
|
||||||
assert.strictEqual(cli.timeout, 250)
|
assert.strictEqual(cli.timeout, 250)
|
||||||
})
|
})
|
||||||
|
@ -121,54 +122,57 @@ t.describe('CLI', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding watch', async function() {
|
t.test('should support overriding watch', async function() {
|
||||||
|
cli.watch = null
|
||||||
await cli.parseOptions(['-w', 'unittest_test1'])
|
await cli.parseOptions(['-w', 'unittest_test1'])
|
||||||
assert.strictEqual(cli.watch, 'unittest_test1')
|
assert.strictEqual(cli.watch, 'unittest_test1')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding watch with long option', async function() {
|
t.test('should support overriding watch with long option', async function() {
|
||||||
|
cli.watch = null
|
||||||
await cli.parseOptions(['--watch', 'unittest_test1'])
|
await cli.parseOptions(['--watch', 'unittest_test1'])
|
||||||
assert.strictEqual(cli.watch, 'unittest_test1')
|
assert.strictEqual(cli.watch, 'unittest_test1')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should fail setting watch if value is missing', async function() {
|
t.test('should fail overriding if next parameter is missing', async function() {
|
||||||
|
cli.watch = null
|
||||||
let err = await assert.isRejected(cli.parseOptions(['--watch']))
|
let err = await assert.isRejected(cli.parseOptions(['--watch']))
|
||||||
assert.strictEqual(cli.watch, null)
|
assert.strictEqual(cli.watch, null)
|
||||||
assert.match(err.message, /watch/i)
|
assert.match(err.message, /watch/i)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should fail setting watch if value is parameter', async function() {
|
t.test('should fail overriding if next parameter is a parameter', async function() {
|
||||||
|
cli.watch = null
|
||||||
let err = await assert.isRejected(cli.parseOptions(['-w', '--reporter', 'list']))
|
let err = await assert.isRejected(cli.parseOptions(['-w', '--reporter', 'list']))
|
||||||
assert.strictEqual(cli.watch, null)
|
assert.strictEqual(cli.watch, null)
|
||||||
assert.match(err.message, /watch/i)
|
assert.match(err.message, /watch/i)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding run', async function() {
|
t.test('should support overriding run', async function() {
|
||||||
|
cli.run = null
|
||||||
await cli.parseOptions(['-n', 'unittest_run1'])
|
await cli.parseOptions(['-n', 'unittest_run1'])
|
||||||
assert.strictEqual(cli.run, 'unittest_run1')
|
assert.strictEqual(cli.run, 'unittest_run1')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should support overriding run with long option', async function() {
|
t.test('should support overriding run with long option', async function() {
|
||||||
|
cli.run = null
|
||||||
await cli.parseOptions(['--npm', 'unittest_run1'])
|
await cli.parseOptions(['--npm', 'unittest_run1'])
|
||||||
assert.strictEqual(cli.run, 'unittest_run1')
|
assert.strictEqual(cli.run, 'unittest_run1')
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should fail setting npm if value is missing', async function() {
|
t.test('should fail overriding if next parameter is missing', async function() {
|
||||||
|
cli.run = null
|
||||||
let err = await assert.isRejected(cli.parseOptions(['--npm']))
|
let err = await assert.isRejected(cli.parseOptions(['--npm']))
|
||||||
assert.strictEqual(cli.run, 'test')
|
assert.strictEqual(cli.run, null)
|
||||||
assert.match(err.message, /npm/i)
|
assert.match(err.message, /npm/i)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('should fail setting npm if value is parameter', async function() {
|
t.test('should fail overriding if next parameter is a parameter', async function() {
|
||||||
|
cli.run = null
|
||||||
let err = await assert.isRejected(cli.parseOptions(['-n', '--reporter', 'list']))
|
let err = await assert.isRejected(cli.parseOptions(['-n', '--reporter', 'list']))
|
||||||
assert.strictEqual(cli.run, 'test')
|
assert.strictEqual(cli.run, null)
|
||||||
assert.match(err.message, /npm/i)
|
assert.match(err.message, /npm/i)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('when using run and no target, leave target empty', async function() {
|
|
||||||
await cli.parseOptions(['--npm', 'unittest_run1'])
|
|
||||||
assert.strictEqual(cli.targets.length, 0)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should add file to targets', async function() {
|
t.test('should add file to targets', async function() {
|
||||||
await cli.parseOptions(['test'])
|
await cli.parseOptions(['test'])
|
||||||
assert.deepEqual(cli.targets, ['test'])
|
assert.deepEqual(cli.targets, ['test'])
|
||||||
|
@ -752,10 +756,10 @@ t.describe('CLI', function() {
|
||||||
|
|
||||||
assert.ok(eltro.starting)
|
assert.ok(eltro.starting)
|
||||||
assert.strictEqual(loaded.length, 2)
|
assert.strictEqual(loaded.length, 2)
|
||||||
assert.match(loaded[0], new RegExp(path.join('root', testFiles[1]).replace(/\\/g, '\\\\')))
|
assert.match(loaded[0], path.join('root', testFiles[1]))
|
||||||
assert.match(loaded[1], new RegExp(path.join('root', testFiles[2]).replace(/\\/g, '\\\\')))
|
assert.match(loaded[1], path.join('root', testFiles[2]))
|
||||||
assert.match(filenames[0], new RegExp(testFiles[1].replace(/\\/g, '\\\\')))
|
assert.match(filenames[0], testFiles[1])
|
||||||
assert.match(filenames[1], new RegExp(testFiles[2].replace(/\\/g, '\\\\')))
|
assert.match(filenames[1], testFiles[2])
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('on error should throw and wrap in inner error', async function() {
|
t.test('on error should throw and wrap in inner error', async function() {
|
||||||
|
@ -915,16 +919,14 @@ t.describe('CLI', function() {
|
||||||
let testCluster
|
let testCluster
|
||||||
let testChildProcess
|
let testChildProcess
|
||||||
let testWorker
|
let testWorker
|
||||||
let testKill
|
|
||||||
let cli
|
let cli
|
||||||
|
|
||||||
t.beforeEach(function() {
|
t.beforeEach(function() {
|
||||||
testKill = stub()
|
|
||||||
testProcess = { stdout: { write: stub() }, stderr: { write: stub() } }
|
testProcess = { stdout: { write: stub() }, stderr: { write: stub() } }
|
||||||
testWorker = { on: stub(), once: stub(), send: stub(), stderr: { on: stub() }, stdout: { on: stub() } }
|
testWorker = { on: stub(), once: stub(), kill: stub(), send: stub(), stderr: { on: stub() }, stdout: { on: stub() } }
|
||||||
testCluster = { fork: stub().returns(testWorker) }
|
testCluster = { fork: stub().returns(testWorker) }
|
||||||
testChildProcess = { spawn: stub().returns(testWorker) }
|
testChildProcess = { spawn: stub().returns(testWorker) }
|
||||||
cli = createSafeCli(null, { cluster: testCluster, child_process: testChildProcess, process: testProcess, kill: testKill })
|
cli = createSafeCli(null, { cluster: testCluster, child_process: testChildProcess, process: testProcess })
|
||||||
})
|
})
|
||||||
|
|
||||||
t.describe('in test mode', function() {
|
t.describe('in test mode', function() {
|
||||||
|
@ -988,14 +990,14 @@ t.describe('CLI', function() {
|
||||||
t.test('multiple calls should cancel', function() {
|
t.test('multiple calls should cancel', function() {
|
||||||
cli.runProgram()
|
cli.runProgram()
|
||||||
|
|
||||||
assert.notOk(testKill.called)
|
assert.notOk(testWorker.kill.called)
|
||||||
assert.ok(testCluster.fork.called)
|
assert.ok(testCluster.fork.called)
|
||||||
testCluster.fork.reset()
|
testCluster.fork.reset()
|
||||||
|
|
||||||
cli.runProgram()
|
cli.runProgram()
|
||||||
|
|
||||||
assert.notOk(testCluster.fork.called)
|
assert.notOk(testCluster.fork.called)
|
||||||
assert.notOk(testKill.called)
|
assert.notOk(testWorker.kill.called)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1067,19 +1069,16 @@ t.describe('CLI', function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.test('multiple calls should kill', function() {
|
t.test('multiple calls should kill', function() {
|
||||||
const assertPid = 12345235
|
|
||||||
testWorker.pid = assertPid
|
|
||||||
cli.runProgram()
|
cli.runProgram()
|
||||||
|
|
||||||
assert.notOk(testKill.called)
|
assert.notOk(testWorker.kill.called)
|
||||||
assert.ok(testChildProcess.spawn.called)
|
assert.ok(testChildProcess.spawn.called)
|
||||||
testChildProcess.spawn.reset().returns(testWorker)
|
testChildProcess.spawn.reset().returns(testWorker)
|
||||||
|
|
||||||
cli.runProgram()
|
cli.runProgram()
|
||||||
|
|
||||||
assert.ok(testChildProcess.spawn.called)
|
assert.ok(testChildProcess.spawn.called)
|
||||||
assert.ok(testKill.called)
|
assert.ok(testWorker.kill.called)
|
||||||
assert.strictEqual(testKill.firstCall[0], assertPid)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,9 +8,6 @@ function CreateT() {
|
||||||
t.logger = {
|
t.logger = {
|
||||||
log: stub()
|
log: stub()
|
||||||
}
|
}
|
||||||
t.process = {
|
|
||||||
stdout: { write: stub() }
|
|
||||||
}
|
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,60 +284,6 @@ e.describe('#beforeEach()', function() {
|
||||||
assert.match(t.logger.log.getCallN(4)[0], /DDDD/)
|
assert.match(t.logger.log.getCallN(4)[0], /DDDD/)
|
||||||
assert.match(t.logger.log.getCallN(4)[0], /BBBB/)
|
assert.match(t.logger.log.getCallN(4)[0], /BBBB/)
|
||||||
})
|
})
|
||||||
|
|
||||||
e.describe('reporter', function() {
|
|
||||||
e.test('should not log before each with reporter list', async function() {
|
|
||||||
const t = CreateT()
|
|
||||||
t.reporter = 'list'
|
|
||||||
t.begin()
|
|
||||||
t.describe('BBBB', function() {
|
|
||||||
t.beforeEach(function() {})
|
|
||||||
|
|
||||||
t.describe('CCCC', function() {
|
|
||||||
t.test('c1', function() { })
|
|
||||||
t.test('c2', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.describe('DDDD', function() {
|
|
||||||
t.test('d1', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('AAAA', function() { })
|
|
||||||
})
|
|
||||||
await t.run()
|
|
||||||
for (let row of t.process.stdout.write.calls) {
|
|
||||||
assert.notMatch(row.filter(x => x).join(' '), /before each/i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
e.test('should not log success before each with reporter dot', async function() {
|
|
||||||
const t = CreateT()
|
|
||||||
t.reporter = 'dot'
|
|
||||||
t.begin()
|
|
||||||
t.describe('BBBB', function() {
|
|
||||||
t.beforeEach(function() {})
|
|
||||||
|
|
||||||
t.describe('CCCC', function() {
|
|
||||||
t.test('c1', function() { })
|
|
||||||
t.test('c2', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.describe('DDDD', function() {
|
|
||||||
t.test('d1', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('AAAA', function() { })
|
|
||||||
})
|
|
||||||
await t.run()
|
|
||||||
let total = 0
|
|
||||||
for (let row of t.process.stdout.write.calls) {
|
|
||||||
if (row.filter(x => x).join(' ').match(/\[32m\./)) {
|
|
||||||
total++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert.strictEqual(total, 4)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
e.describe('#after()', function() {
|
e.describe('#after()', function() {
|
||||||
|
@ -736,60 +679,6 @@ e.describe('#afterEach()', function() {
|
||||||
assert.match(t.logger.log.getCallN(5)[0], /JJJJ/)
|
assert.match(t.logger.log.getCallN(5)[0], /JJJJ/)
|
||||||
assert.match(t.logger.log.getCallN(5)[0], /YYYY/)
|
assert.match(t.logger.log.getCallN(5)[0], /YYYY/)
|
||||||
})
|
})
|
||||||
|
|
||||||
e.describe('reporter', function() {
|
|
||||||
e.test('should not log before each with reporter list', async function() {
|
|
||||||
const t = CreateT()
|
|
||||||
t.reporter = 'list'
|
|
||||||
t.begin()
|
|
||||||
t.describe('BBBB', function() {
|
|
||||||
t.afterEach(function() {})
|
|
||||||
|
|
||||||
t.describe('CCCC', function() {
|
|
||||||
t.test('c1', function() { })
|
|
||||||
t.test('c2', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.describe('DDDD', function() {
|
|
||||||
t.test('d1', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('AAAA', function() { })
|
|
||||||
})
|
|
||||||
await t.run()
|
|
||||||
for (let row of t.process.stdout.write.calls) {
|
|
||||||
assert.notMatch(row.filter(x => x).join(' '), /after each/i)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
e.test('should not log success before each with reporter dot', async function() {
|
|
||||||
const t = CreateT()
|
|
||||||
t.reporter = 'dot'
|
|
||||||
t.begin()
|
|
||||||
t.describe('BBBB', function() {
|
|
||||||
t.afterEach(function() {})
|
|
||||||
|
|
||||||
t.describe('CCCC', function() {
|
|
||||||
t.test('c1', function() { })
|
|
||||||
t.test('c2', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.describe('DDDD', function() {
|
|
||||||
t.test('d1', function() { })
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('AAAA', function() { })
|
|
||||||
})
|
|
||||||
await t.run()
|
|
||||||
let total = 0
|
|
||||||
for (let row of t.process.stdout.write.calls) {
|
|
||||||
if (row.filter(x => x).join(' ').match(/\[32m\./)) {
|
|
||||||
total++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assert.strictEqual(total, 4)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
let commonBeforeTests = ['before', 'beforeEach']
|
let commonBeforeTests = ['before', 'beforeEach']
|
||||||
|
|
|
@ -234,6 +234,7 @@ e.test('Eltro should support capturing unknown errors outside scope', async func
|
||||||
t.describe('', function() {
|
t.describe('', function() {
|
||||||
t.test('', function(cb) {
|
t.test('', function(cb) {
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
|
console.log('throw')
|
||||||
throw assertError
|
throw assertError
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import { spawn } from 'child_process'
|
|
||||||
import t from '../../lib/eltro.mjs'
|
|
||||||
import assert from '../../lib/assert.mjs'
|
|
||||||
import kill from '../../lib/kill.mjs'
|
|
||||||
|
|
||||||
t.describe('kill', function() {
|
|
||||||
let worker
|
|
||||||
|
|
||||||
t.afterEach(function() {
|
|
||||||
if (worker?.pid && !worker.killed) {
|
|
||||||
worker.kill()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should kill process correctly', function(done) {
|
|
||||||
worker = spawn('node', ['./test/kill/runner.mjs'])
|
|
||||||
assert.ok(worker.pid)
|
|
||||||
|
|
||||||
worker.on('exit', done.finish(function(code, signal) {
|
|
||||||
assert.ok(code || signal)
|
|
||||||
}))
|
|
||||||
|
|
||||||
kill(worker.pid)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.test('should succeed in killing tree', async function() {
|
|
||||||
worker = spawn('node', ['./test/kill/runner.mjs'])
|
|
||||||
assert.ok(worker.pid)
|
|
||||||
|
|
||||||
// Give it some time to start
|
|
||||||
await new Promise(res => {
|
|
||||||
worker.stdout.on('data', function(data) {
|
|
||||||
if (data.toString().indexOf('secondary') >= 0) res()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
return kill(worker.pid).then(function(pids) {
|
|
||||||
assert.strictEqual(pids.size, 2)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { spawn } from 'child_process'
|
|
||||||
|
|
||||||
console.log('primary', process.pid)
|
|
||||||
|
|
||||||
let secondary = spawn('node', ['./test/kill/second_runner.mjs'])
|
|
||||||
|
|
||||||
secondary.stdout.on('data', function(data) {
|
|
||||||
process.stdout.write(data)
|
|
||||||
})
|
|
||||||
|
|
||||||
setInterval(function() { console.log('primary', process.pid) }, 100)
|
|
|
@ -1,2 +0,0 @@
|
||||||
console.log('secondary', process.pid)
|
|
||||||
setInterval(function() { console.log('secondary', process.pid) }, 100)
|
|
|
@ -28,7 +28,7 @@ t.afterEach(function(done) {
|
||||||
|
|
||||||
t.after(function() {
|
t.after(function() {
|
||||||
if (builder) {
|
if (builder) {
|
||||||
return builder.cleanup()
|
builder.cleanup()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,7 @@ Builder.prototype.newRandomFiles = function(fpath, count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder.prototype.cleanup = function() {
|
Builder.prototype.cleanup = function() {
|
||||||
return fs.rm(this.root, { recursive: true, force: true })
|
return fs.rmdir(this.root)
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder.prototype.getAllDirectories = function() {
|
Builder.prototype.getAllDirectories = function() {
|
||||||
|
|
Loading…
Reference in a new issue