Implemented beforeEach and afterEach.
Some checks failed
continuous-integration/appveyor/branch AppVeyor build failed

Also added onCall() support in sinon and chaining support.
Breaking: Renamed onCall with getCall.
This commit is contained in:
Jonatan Nilsson 2022-01-11 09:37:05 +00:00
parent 5e14f3f94c
commit 59ba39e406
6 changed files with 774 additions and 440 deletions

View file

@ -12,6 +12,8 @@ function Group(e, name) {
this.isExclusive = false
this.before = null
this.after = null
this.beforeEach = null
this.afterEach = null
}
Group.prototype.timeout = function(time) {
@ -74,6 +76,15 @@ Test.prototype.only = function() {
this.group.__hasonly(true)
}
Test.prototype.clone = function(prefix = '') {
var t = new Test(this.e, this.group, prefix + this.name, this.func)
let properties = ['skipTest', 'isExclusive', 'customTimeout', 'isBasic', 'error']
for (let key of properties) {
t[key] = this[key]
}
return t
}
function Eltro() {
this.__timeout = 2000
this.hasExclusive = false
@ -85,6 +96,7 @@ function Eltro() {
this.failedTests = []
this.hasTests = false
this.starting = false
this.logger = null
this.filename = ''
this.prefix = ''
this.temporary = {
@ -111,13 +123,15 @@ Eltro.prototype.begin = function() {
this.fileGroupMap.clear()
}
Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test') {
Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test', child = null) {
if (this.reporter === 'list') {
process.stdout.write(' \x1b[90m? ' + test.name + '\x1b[0m')
}
let markRealTest = child || test
if (!test.skipTest) {
await new Promise((resolve, reject) => {
let err = await new Promise((resolve, reject) => {
// Flag to check if we finished
let finished = false
let timeout = test.customTimeout || this.__timeout
@ -193,7 +207,8 @@ Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test') {
if (prefix === 'Test') {
stats.passed++
}
}, function(err) {
return null
}, (err) => {
let saveError = err
if (!saveError) {
saveError = new Error(prefix + ' promise rejected with empty message')
@ -205,32 +220,34 @@ Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test') {
}
saveError.originalError = err
}
test.error = saveError
stats.failed++
return saveError
}
)
if (err) {
markRealTest.error = err
this.failedTests.push(markRealTest.clone(child ? prefix : ''))
stats.failed++
}
} else {
stats.skipped++
}
if (test.error) {
this.failedTests.push(test)
}
if (this.reporter === 'list') {
process.stdout.clearLine();
process.stdout.cursorTo(0);
if (test.skipTest) {
process.stdout.write(' \x1b[94m- ' + test.name + '\x1b[0m\n')
} else if (!test.error) {
process.stdout.write(' \x1b[32m√\x1b[90m ' + test.name + '\x1b[0m\n')
if (markRealTest.skipTest) {
process.stdout.write(' \x1b[94m- ' + markRealTest.name + '\x1b[0m\n')
} else if (!markRealTest.error) {
process.stdout.write(' \x1b[32m√\x1b[90m ' + markRealTest.name + '\x1b[0m\n')
} else if (prefix === 'Test') {
process.stdout.write(' \x1b[31m' + this.failedTests.length + ') ' + test.name + '\x1b[0m\n')
process.stdout.write(' \x1b[31m' + this.failedTests.length + ') ' + markRealTest.name + '\x1b[0m\n')
}
} else if (this.reporter === 'dot') {
if (test.skipTest) {
if (markRealTest.skipTest) {
process.stdout.write('\x1b[94m.\x1b[0m')
} else if (!test.error) {
} else if (!markRealTest.error) {
process.stdout.write('\x1b[32m.\x1b[0m')
} else if (prefix === 'Test') {
process.stdout.write('\x1b[31m.\x1b[0m')
@ -250,12 +267,31 @@ Eltro.prototype.__runGroup = async function(g, stats) {
}
for (let x = 0; x < g.tests.length; x++) {
if (!g.tests[x].skipTest && g.tests[x].isExclusive === g.hasExclusive) {
await this.__runTest(stats, g.tests[x])
if (g.beforeEach) {
await this.__runTest(stats, g.beforeEach, 'Before each: ', g.tests[x])
if (!g.tests[x].error) {
await this.__runTest(stats, g.tests[x])
}
} else {
await this.__runTest(stats, g.tests[x])
}
if (g.afterEach) {
await this.__runTest(stats, g.afterEach, 'After each: ', g.tests[x])
}
}
}
for (let x = 0; x < g.groups.length; x++) {
if (!g.groups[x].skipTest && g.hasExclusive === (g.groups[x].hasExclusive || g.groups[x].isExclusive))
await this.__runGroup(g.groups[x], stats)
if (!g.groups[x].skipTest && g.hasExclusive === (g.groups[x].hasExclusive || g.groups[x].isExclusive)) {
if (g.beforeEach) {
await this.__runTest(stats, g.beforeEach, g.groups[x].name + ': ', g.beforeEach)
if (g.beforeEach.error) continue
}
await this.__runGroup(g.groups[x], stats)
if (g.afterEach) {
await this.__runTest(stats, g.afterEach, g.groups[x].name + ': ', g.afterEach)
}
}
}
if (g.after) {
await this.__runTest(stats, g.after, 'After')
@ -263,7 +299,7 @@ Eltro.prototype.__runGroup = async function(g, stats) {
}
Eltro.prototype.run = async function() {
if (this.reporter) {
if (this.reporter && this.reporter !== 'test') {
console.log('')
console.log('')
}
@ -283,7 +319,16 @@ Eltro.prototype.run = async function() {
let end = process.hrtime(start)
if (this.reporter) {
if (this.reporter === 'test') {
if (this.logger && this.logger.log) {
if (this.failedTests.length) {
for (let x = 0; x < this.failedTests.length; x++) {
let test = this.failedTests[x];
this.logger.log(test.name, test.error)
}
}
}
} else if (this.reporter) {
console.log('')
console.log('')
if (stats.passed) {
@ -321,37 +366,30 @@ Eltro.prototype.resetFilename = function() {
this.activeGroup = null
}
Eltro.prototype.before = function(func) {
if (!this.activeGroup) {
throw new Error('Tests outside groups are not allowed.')
let beforesandafters = [
['before', 'Before'],
['after', 'After'],
['beforeEach', 'Before each'],
['afterEach', 'After each'],
]
beforesandafters.forEach(function(item) {
Eltro.prototype[item[0]] = function(func) {
if (!this.activeGroup) {
throw new Error('Tests outside groups are not allowed.')
}
let test = new Test(this, this.activeGroup, item[1] + ': ' + this.activeGroup.name, func)
if (this.temporary.timeout || this.activeGroup.customTimeout) {
test.timeout(this.temporary.timeout || this.activeGroup.customTimeout)
this.temporary.timeout = 0
}
this.activeGroup[item[0]] = test
return test
}
let test = new Test(this, this.activeGroup, 'Before: ' + this.activeGroup.name, func)
if (this.temporary.timeout || this.activeGroup.customTimeout) {
test.timeout(this.temporary.timeout || this.activeGroup.customTimeout)
this.temporary.timeout = 0
}
this.activeGroup.before = test
return test
}
Eltro.prototype.after = function(func) {
if (!this.activeGroup) {
throw new Error('Tests outside groups are not allowed.')
}
let test = new Test(this, this.activeGroup, 'After: ' + this.activeGroup.name, func)
if (this.temporary.timeout || this.activeGroup.customTimeout) {
test.timeout(this.temporary.timeout || this.activeGroup.customTimeout)
this.temporary.timeout = 0
}
this.activeGroup.after = test
return test
}
})
Eltro.prototype.describe = function(name, func) {
let before = this.activeGroup

View file

@ -12,6 +12,8 @@ export function stub(returnFunc = null) {
if (returnFunc && typeof(returnFunc) !== 'function') {
throw new Error('stub() was called with non-function argument')
}
let manualReturners = new Map()
let nextManual = null
let returner = returnFunc ? returnFunc : null
let calls = []
let func = function(...args) {
@ -22,6 +24,9 @@ export function stub(returnFunc = null) {
func[indexMap[func.callCount]] = args
}
func.callCount++
if (manualReturners.has(func.callCount -1)) {
return manualReturners.get(func.callCount -1)(...args)
}
if (returner) {
return returner(...args)
}
@ -29,36 +34,63 @@ export function stub(returnFunc = null) {
func.lastCall = null
func.called = false
func.callCount = 0
func.onCall = function(i) {
func.getCall = function(i) {
return calls[i]
}
func.getCallN = function(i) {
return calls[i - 1]
}
func.onCall = function(i) {
if (i !== null && typeof(i) !== 'number') {
throw new Error('onCall must be called with either null or number')
}
nextManual = i
return func
}
func.onCallN = function(i) {
return func.onCall(i - 1)
}
func.reset = function() {
func.lastCall = null
func.called = false
func.callCount = 0
manualReturners.clear()
for (let i = 0; i < indexMap.length; i++) {
func[indexMap[i]] = null
}
returner = returnFunc ? returnFunc : null
calls.splice(0, calls.length)
return func
}
func.returns = function(data) {
returner = function() { return data }
func.returnWith(function() { return data })
return func
}
func.throws = function(data) {
func.returnWith(function() { throw data })
return func
}
func.resolves = function(data) {
func.returnWith(function() { return Promise.resolve(data) })
return func
}
func.rejects = function(data) {
func.returnWith(function() { return Promise.reject(data) })
return func
}
func.returnWith = function(returnFunc) {
if (typeof(returnFunc) !== 'function') {
throw new Error('stub() was called with non-function argument')
}
returner = returnFunc
}
func.throws = function(data) {
returner = function() { throw data }
}
func.resolves = function(data) {
returner = function() { return Promise.resolve(data) }
}
func.rejects = function(data) {
returner = function() { return Promise.reject(data) }
if (nextManual !== null) {
manualReturners.set(nextManual, returnFunc)
nextManual = null
} else {
returner = returnFunc
}
return func
}
for (let i = 0; i < indexMap.length; i++) {
func[indexMap[i]] = null

View file

@ -4,7 +4,7 @@
"description": "Eltro is a tiny no-dependancy test framework for node",
"main": "index.mjs",
"scripts": {
"test": "node cli.mjs test/**/*.test.mjs -r dot"
"test": "node cli.mjs test/**/*.test.mjs"
},
"repository": {
"type": "git",

583
test/eltro.flow.test.mjs Normal file
View file

@ -0,0 +1,583 @@
import e from '../lib/eltro.mjs'
import { stub } from '../lib/sinon.mjs'
import assert from '../lib/assert.mjs'
function CreateT() {
const t = new e.Eltro()
t.reporter = 'test'
t.logger = {
log: stub()
}
return t
}
e.describe('#before()', function() {
e.test('should support functions in describe group', async function() {
let assertRan = 0
let firstBefore = 0
let secondBefore = 0
let thirdBefore = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function() {
firstBefore = assertRan
})
t.describe('', function() {
t.before(function() {
secondBefore = assertRan
})
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.before(function() {
thirdBefore = assertRan
})
t.test('', function() { assertRan++ })
})
t.test('', function() { assertRan++ })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertRan, 5)
assert.strictEqual(stats.passed, 5)
assert.strictEqual(firstBefore, 0)
assert.strictEqual(secondBefore, 1)
assert.strictEqual(thirdBefore, 4)
})
})
e.describe('#beforeEach()', function() {
e.test('should support functions in describe group and run before each test and group', async function() {
const t = CreateT()
t.begin()
t.describe('', function() {
let outside = 0
t.beforeEach(function() {
outside++
})
t.describe('', function() {
t.before(function() {
assert.strictEqual(outside, 2)
})
let inside = 0
t.beforeEach(function() {
inside++
})
t.test('', function() { assert.strictEqual(inside, 1) })
t.test('', function() { assert.strictEqual(inside, 2) })
t.test('', function() { assert.strictEqual(inside, 3) })
})
t.describe('', function() {
t.before(function() {
assert.strictEqual(outside, 3)
})
let insideSecond = 0
t.beforeEach(function() {
assert.strictEqual(insideSecond, 0)
insideSecond++
})
t.test('', function() { assert.strictEqual(insideSecond, 1) })
})
t.test('', function() { assert.strictEqual(outside, 1) })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(stats.passed, 5)
assert.strictEqual(stats.failed, 0)
assert.strictEqual(stats.skipped, 0)
})
e.test('should be able to keep track of every error that occurs', async function() {
let counter = 0
const t = CreateT()
t.begin()
t.describe('BBBB', function() {
t.beforeEach(function() {
throw new Error(`Counter at ${++counter}`)
})
t.describe('CCCC', function() {
t.test('', function() { })
})
t.describe('DDDD', function() {
t.test('', function() { })
})
t.test('AAAA', function() { })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 3)
assert.strictEqual(t.logger.log.callCount, 3)
assert.match(t.logger.log.firstCall[1].message, /1/)
assert.match(t.logger.log.firstCall[0], /before each/i)
assert.match(t.logger.log.firstCall[0], /AAAA/)
assert.match(t.logger.log.firstCall[0], /BBBB/)
assert.match(t.logger.log.secondCall[1].message, /2/)
assert.match(t.logger.log.secondCall[0], /before each/i)
assert.match(t.logger.log.secondCall[0], /CCCC/)
assert.match(t.logger.log.secondCall[0], /BBBB/)
assert.match(t.logger.log.thirdCall[1].message, /3/)
assert.match(t.logger.log.thirdCall[0], /before each/i)
assert.match(t.logger.log.thirdCall[0], /DDDD/)
assert.match(t.logger.log.thirdCall[0], /BBBB/)
})
})
e.describe('#after()', function() {
e.test('should support functions in describe group', async function() {
let assertRan = 0
let firstAfter = 0
let secondAfter = 0
let thirdAfter = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function() {
firstAfter = assertRan
})
t.describe('', function() {
t.after(function() {
secondAfter = assertRan
})
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.after(function() {
thirdAfter = assertRan
})
t.test('', function() { assertRan++ })
})
t.test('', function() { assertRan++ })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(stats.passed, 5)
assert.strictEqual(assertRan, 5)
assert.strictEqual(firstAfter, 5)
assert.strictEqual(secondAfter, 4)
assert.strictEqual(thirdAfter, 5)
})
})
e.describe('#afterEach()', function() {
e.test('should support functions in describe group', async function() {
const t = CreateT()
t.begin()
t.describe('', function() {
let outside = 0
t.afterEach(function() {
outside++
})
t.describe('', function() {
t.before(function() { assert.strictEqual(outside, 1) })
let inside = 0
t.afterEach(function() {
inside++
})
t.test('', function() { assert.strictEqual(inside, 0) })
t.test('', function() { assert.strictEqual(inside, 1) })
t.test('', function() { assert.strictEqual(inside, 2) })
t.after(function() { assert.strictEqual(inside, 3) })
})
t.describe('', function() {
t.before(function() { assert.strictEqual(outside, 2) })
let inside = 0
t.afterEach(function() {
inside++
})
t.test('', function() { assert.strictEqual(inside, 0) })
t.after(function() { assert.strictEqual(inside, 1) })
})
t.test('', function() { assert.strictEqual(outside, 0) })
t.after(function() { assert.strictEqual(outside, 3) })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(stats.passed, 5)
assert.strictEqual(stats.failed, 0)
assert.strictEqual(stats.skipped, 0)
})
e.test('should be able to keep track of every error that occurs', async function() {
let counter = 0
const t = CreateT()
t.begin()
t.describe('YYYY', function() {
t.afterEach(function() {
throw new Error(`Counter at ${++counter}`)
})
t.describe('HHHH', function() {
t.test('', function() { })
})
t.describe('JJJJ', function() {
t.test('', function() { })
})
t.test('AAAA', function() { })
t.test('BBBB', function() { })
t.test('CCCC', function() { })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 5)
assert.strictEqual(t.logger.log.callCount, 5)
assert.match(t.logger.log.getCall(0)[1].message, /1/)
assert.match(t.logger.log.getCall(0)[0], /after each/i)
assert.match(t.logger.log.getCall(0)[0], /AAAA/)
assert.match(t.logger.log.getCall(0)[0], /YYYY/)
assert.match(t.logger.log.getCall(1)[1].message, /2/)
assert.match(t.logger.log.getCall(1)[0], /after each/i)
assert.match(t.logger.log.getCall(1)[0], /BBBB/)
assert.match(t.logger.log.getCall(1)[0], /YYYY/)
assert.match(t.logger.log.getCall(2)[1].message, /3/)
assert.match(t.logger.log.getCall(2)[0], /after each/i)
assert.match(t.logger.log.getCall(2)[0], /CCCC/)
assert.match(t.logger.log.getCall(2)[0], /YYYY/)
assert.match(t.logger.log.getCall(3)[1].message, /4/)
assert.match(t.logger.log.getCall(3)[0], /after each/i)
assert.match(t.logger.log.getCall(3)[0], /HHHH/)
assert.match(t.logger.log.getCall(3)[0], /YYYY/)
assert.match(t.logger.log.getCall(4)[1].message, /5/)
assert.match(t.logger.log.getCall(4)[0], /after each/i)
assert.match(t.logger.log.getCall(4)[0], /JJJJ/)
assert.match(t.logger.log.getCall(4)[0], /YYYY/)
})
})
let commonBeforeTests = ['before', 'beforeEach']
commonBeforeTests.forEach(function(before) {
e.describe(`#${before}()`, function() {
e.test('should not be possible outside of groups', async function() {
const t = CreateT()
t.begin()
assert.throws(function() {
t[before](function() {})
}, function(err) {
assert.match(err.message, /group/i)
return true
})
})
e.test('should support functions in describe timing out', async function() {
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function(cb) { }).timeout(50)
t.test('', function() { assertRan++ })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 0)
})
e.test('should support functions in describe late timing out', async function() {
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function(cb) {
setTimeout(cb, 100)
}).timeout(50)
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 2)
})
e.test('should support functions in describe timing out in front', async function() {
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.timeout(25)[before](function(cb) { setTimeout(cb, 50) })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /25ms/)
assert.strictEqual(assertRan, 2)
})
e.test('should support functions in describe being promised', async function() {
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function() {
return new Promise(function(res) {
assertIsTrue = true
res()
})
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('should support functions in describe with callback', async function() {
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function(cb) {
setTimeout(function() {
assertIsTrue = true
cb()
}, 25)
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('should support functions in describe with directly thrown errors', async function() {
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function() {
throw assertError
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('should support functions in describe with rejected promises', async function() {
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function() {
return new Promise(function(res, rej) {
rej(assertError)
})
})
t.test('', function() {})
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('should support functions in describe with callback rejected', async function() {
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t[before](function(cb) { cb(assertError) })
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
})
})
let commonAfterTests = ['after', 'afterEach']
commonAfterTests.forEach(function(after) {
e.describe(`#${after}()`, function() {
e.test('should not be possible outside of groups', async function() {
const t = CreateT()
t.begin()
assert.throws(function() {
t[after](function() {})
}, function(err) {
assert.match(err.message, /group/i)
return true
})
})
e.test('should support functions in describe, timing out', async function() {
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function(cb) { }).timeout(50)
t.test('', function() { assertRan++ })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 1)
})
e.test('should support functions in describe, late timing out', async function() {
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function(cb) {
setTimeout(cb, 100)
}).timeout(50)
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 3)
})
e.test('should support functions in describe, timing out in front', async function() {
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.timeout(25)[after](function(cb) { setTimeout(cb, 50) })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /25ms/)
assert.strictEqual(assertRan, 3)
})
e.test('should support functions in describe, being promised', async function() {
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function() {
return new Promise(function(res) {
assertIsTrue = true
res()
})
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('should support functions in describe, support callback', async function() {
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function(cb) {
setTimeout(function() {
assertIsTrue = true
cb()
}, 25)
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('should support functions in describe, support directly thrown errors', async function() {
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function() {
throw assertError
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('should support functions in describe, support rejected promises', async function() {
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function() {
return new Promise(function(res, rej) {
rej(assertError)
})
})
t.test('', function() {})
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('should support functions in describe, support callback rejected', async function() {
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t[after](function(cb) { cb(assertError) })
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
})
})

View file

@ -283,380 +283,6 @@ e.test('Eltro should support skipped tests in front of the test', async function
assert.strictEqual(assertIsTrue, true)
})
e.test('Eltro should support before() functions in describe group', async function() {
testsWereRun = true
let assertRan = 0
let firstBefore = 0
let secondBefore = 0
let thirdBefore = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function() {
firstBefore = assertRan
})
t.describe('', function() {
t.before(function() {
secondBefore = assertRan
})
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.before(function() {
thirdBefore = assertRan
})
t.test('', function() { assertRan++ })
})
t.test('', function() { assertRan++ })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertRan, 5)
assert.strictEqual(stats.passed, 5)
assert.strictEqual(firstBefore, 0)
assert.strictEqual(secondBefore, 1)
assert.strictEqual(thirdBefore, 4)
})
e.test('Eltro should support before() functions in describe, timing out', async function() {
testsWereRun = true
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function(cb) { }).timeout(50)
t.test('', function() { assertRan++ })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 0)
})
e.test('Eltro should support before() functions in describe, late timing out', async function() {
testsWereRun = true
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function(cb) {
setTimeout(cb, 100)
}).timeout(50)
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 2)
})
e.test('Eltro should support before() functions in describe, timing out in front', async function() {
testsWereRun = true
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.timeout(25).before(function(cb) { setTimeout(cb, 50) })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /25ms/)
assert.strictEqual(assertRan, 2)
})
e.test('Eltro should support before() functions in describe, being promised', async function() {
testsWereRun = true
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function() {
return new Promise(function(res) {
assertIsTrue = true
res()
})
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('Eltro should support before() functions in describe, support callback', async function() {
testsWereRun = true
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function(cb) {
setTimeout(function() {
assertIsTrue = true
cb()
}, 25)
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('Eltro should support before() functions in describe, support directly thrown errors', async function() {
testsWereRun = true
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function() {
throw assertError
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('Eltro should support before() functions in describe, support rejected promises', async function() {
testsWereRun = true
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function() {
return new Promise(function(res, rej) {
rej(assertError)
})
})
t.test('', function() {})
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('Eltro should support before() functions in describe, support callback rejected', async function() {
testsWereRun = true
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t.before(function(cb) { cb(assertError) })
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('Eltro should support after() functions in describe group', async function() {
testsWereRun = true
let assertRan = 0
let firstAfter = 0
let secondAfter = 0
let thirdAfter = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function() {
firstAfter = assertRan
})
t.describe('', function() {
t.after(function() {
secondAfter = assertRan
})
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.after(function() {
thirdAfter = assertRan
})
t.test('', function() { assertRan++ })
})
t.test('', function() { assertRan++ })
})
let stats = await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(stats.passed, 5)
assert.strictEqual(assertRan, 5)
assert.strictEqual(firstAfter, 5)
assert.strictEqual(secondAfter, 4)
assert.strictEqual(thirdAfter, 5)
})
e.test('Eltro should support after() functions in describe, timing out', async function() {
testsWereRun = true
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function(cb) { }).timeout(50)
t.test('', function() { assertRan++ })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 1)
})
e.test('Eltro should support after() functions in describe, late timing out', async function() {
testsWereRun = true
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function(cb) {
setTimeout(cb, 100)
}).timeout(50)
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /50ms/)
assert.strictEqual(assertRan, 3)
})
e.test('Eltro should support after() functions in describe, timing out in front', async function() {
testsWereRun = true
let assertRan = 0
const t = CreateT()
t.begin()
t.describe('', function() {
t.timeout(25).after(function(cb) { setTimeout(cb, 50) })
t.test('', function() { assertRan++ })
})
t.describe('', function() {
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
t.test('', function(cb) { assertRan++; setTimeout(cb, 25) })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.ok(t.failedTests[0].error)
assert.match(t.failedTests[0].error.message, /25ms/)
assert.strictEqual(assertRan, 3)
})
e.test('Eltro should support after() functions in describe, being promised', async function() {
testsWereRun = true
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function() {
return new Promise(function(res) {
assertIsTrue = true
res()
})
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('Eltro should support after() functions in describe, support callback', async function() {
testsWereRun = true
let assertIsTrue = false
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function(cb) {
setTimeout(function() {
assertIsTrue = true
cb()
}, 25)
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 0)
assert.strictEqual(assertIsTrue, true)
})
e.test('Eltro should support after() functions in describe, support directly thrown errors', async function() {
testsWereRun = true
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function() {
throw assertError
})
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('Eltro should support after() functions in describe, support rejected promises', async function() {
testsWereRun = true
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function() {
return new Promise(function(res, rej) {
rej(assertError)
})
})
t.test('', function() {})
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('Eltro should support after() functions in describe, support callback rejected', async function() {
testsWereRun = true
const assertError = new Error()
const t = CreateT()
t.begin()
t.describe('', function() {
t.after(function(cb) { cb(assertError) })
t.test('', function() { })
})
await t.run()
assert.strictEqual(t.failedTests.length, 1)
assert.strictEqual(t.failedTests[0].error, assertError)
})
e.test('Eltro should support only tests in front of the test', async function() {
testsWereRun = true
let assertIsTrue = false

View file

@ -86,10 +86,10 @@ import { spy, stub } from '../index.mjs'
assert.strictEqual(spyer.lastCall[1], assertThirdArgs[1])
assert.strictEqual(spyer.callCount, 3)
assert.strictEqual(spyer.onCall(0)[0], assertFirstArgs)
assert.strictEqual(spyer.onCall(1)[0], assertSecondArgs)
assert.strictEqual(spyer.onCall(2)[0], assertThirdArgs[0])
assert.strictEqual(spyer.onCall(2)[1], assertThirdArgs[1])
assert.strictEqual(spyer.getCall(0)[0], assertFirstArgs)
assert.strictEqual(spyer.getCall(1)[0], assertSecondArgs)
assert.strictEqual(spyer.getCall(2)[0], assertThirdArgs[0])
assert.strictEqual(spyer.getCall(2)[1], assertThirdArgs[1])
assert.strictEqual(spyer.firstCall[0], assertFirstArgs)
assert.strictEqual(spyer.secondCall[0], assertSecondArgs)
@ -295,4 +295,59 @@ t.describe('#stub()', function() {
s.reset()
assert.strictEqual(s(), 'success')
})
t.test('should support chaining', function() {
let s = stub()
s.reset()
.returnWith(function() {})
.resolves(null)
.rejects(null)
.throws(null)
.returns(null)
.reset()
})
t.test('onCall should throw if not a number', function() {
let s = stub()
assert.throws(function() { s.onCall(undefined) })
assert.throws(function() { s.onCall([]) })
assert.throws(function() { s.onCall({}) })
assert.throws(function() { s.onCall('') })
assert.throws(function() { s.onCall('asdf') })
})
t.test('should support arbitrary call returns', function() {
let s = stub()
s.onCall(0).returns(1)
.onCall(1).returns(2)
assert.strictEqual(s(), 1)
assert.strictEqual(s(), 2)
s.reset()
assert.strictEqual(s(), undefined)
assert.strictEqual(s(), undefined)
})
t.test('should send propert arguments in defined calls', function() {
const assertInput = { a : 1 }
const assertReturns = { b: 3 }
let ourCallCount = 0
let s = stub()
s.onCall(3).returnWith(function(input) {
ourCallCount++
assert.strictEqual(input, assertInput)
return assertReturns
})
assert.strictEqual(s(null), undefined)
assert.strictEqual(s(null), undefined)
assert.strictEqual(s(null), undefined)
assert.strictEqual(s(assertInput), assertReturns)
assert.ok(s.called)
assert.strictEqual(s.callCount, 4)
assert.strictEqual(ourCallCount, 1)
assert.strictEqual(s.getCall(3)[0], assertInput)
assert.strictEqual(s(null), undefined)
})
})