Added helpers into cb:
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
* wrap() that auto captures thrown exceptions and cb's them * finish() that auto captures thrown exception and cb's them, otherwise auto-finishes the cb for you
This commit is contained in:
parent
2c3fc01722
commit
9d2b71339c
7 changed files with 328 additions and 10 deletions
|
@ -42,7 +42,11 @@ on_success:
|
||||||
https://git.nfp.is/api/v1/repos/$APPVEYOR_REPO_NAME/releases \
|
https://git.nfp.is/api/v1/repos/$APPVEYOR_REPO_NAME/releases \
|
||||||
-d "{\"tag_name\":\"v${CURR_VER}\",\"name\":\"v${CURR_VER}\",\"body\":\"Automatic release from Appveyor from ${APPVEYOR_REPO_COMMIT} :\n\n${APPVEYOR_REPO_COMMIT_MESSAGE}\"}")
|
-d "{\"tag_name\":\"v${CURR_VER}\",\"name\":\"v${CURR_VER}\",\"body\":\"Automatic release from Appveyor from ${APPVEYOR_REPO_COMMIT} :\n\n${APPVEYOR_REPO_COMMIT_MESSAGE}\"}")
|
||||||
RELEASE_ID=$(echo $RELEASE_RESULT | jq -r .id)
|
RELEASE_ID=$(echo $RELEASE_RESULT | jq -r .id)
|
||||||
echo "Created release ${RELEASE_ID}"
|
if [ "$RELEASE_ID" == "null" ]; then
|
||||||
|
echo $RELEASE_RESULT
|
||||||
|
else
|
||||||
|
echo "Created release ${RELEASE_ID}"
|
||||||
|
fi
|
||||||
echo '//registry.npmjs.org/:_authToken=${npmtoken}' > ~/.npmrc
|
echo '//registry.npmjs.org/:_authToken=${npmtoken}' > ~/.npmrc
|
||||||
echo "Publishing new version to npm"
|
echo "Publishing new version to npm"
|
||||||
npm publish
|
npm publish
|
||||||
|
|
33
lib/callback.mjs
Normal file
33
lib/callback.mjs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
export function runWithCallbackSafe(test) {
|
||||||
|
return new Promise(function(res, rej) {
|
||||||
|
try {
|
||||||
|
let cb = function(err) {
|
||||||
|
if (err) {
|
||||||
|
return rej(err)
|
||||||
|
}
|
||||||
|
res()
|
||||||
|
}
|
||||||
|
let safeWrap = function(finish) {
|
||||||
|
// return a safe wrap support
|
||||||
|
return function(fun) {
|
||||||
|
return function(a, b, c) {
|
||||||
|
try {
|
||||||
|
fun(a, b, c)
|
||||||
|
if (finish) {
|
||||||
|
res()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (err) {
|
||||||
|
return rej(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb.wrap = safeWrap(false)
|
||||||
|
cb.finish = safeWrap(true)
|
||||||
|
test.func(cb)
|
||||||
|
} catch (err) {
|
||||||
|
rej(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import * as readline from 'readline'
|
import * as readline from 'readline'
|
||||||
|
import { runWithCallbackSafe } from './callback.mjs'
|
||||||
import { printError } from './cli.mjs'
|
import { printError } from './cli.mjs'
|
||||||
|
|
||||||
function Group(e, name) {
|
function Group(e, name) {
|
||||||
|
@ -155,14 +156,7 @@ Eltro.prototype.__runTest = async function(stats, test, prefix = 'Test', child =
|
||||||
// If the test requires callback, wrap it in a promise where callback
|
// If the test requires callback, wrap it in a promise where callback
|
||||||
// either resolves or rejects that promise
|
// either resolves or rejects that promise
|
||||||
if (checkIsCallback) {
|
if (checkIsCallback) {
|
||||||
promise = new Promise(function(res, rej) {
|
promise = runWithCallbackSafe(test)
|
||||||
test.func(function(err) {
|
|
||||||
if (err) {
|
|
||||||
return rej(err)
|
|
||||||
}
|
|
||||||
res()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
// Function doesn't require a callback, run it directly
|
// Function doesn't require a callback, run it directly
|
||||||
promise = test.func()
|
promise = test.func()
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "eltro",
|
"name": "eltro",
|
||||||
"version": "1.3.1",
|
"version": "1.3.2",
|
||||||
"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": {
|
||||||
|
|
217
test/callback.test.mjs
Normal file
217
test/callback.test.mjs
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
import { runWithCallbackSafe } from '../lib/callback.mjs'
|
||||||
|
import assert from '../lib/assert.mjs'
|
||||||
|
|
||||||
|
import t from '../lib/eltro.mjs'
|
||||||
|
|
||||||
|
t.describe('runCb()', function() {
|
||||||
|
t.test('cb() should work normally', async function() {
|
||||||
|
let called = false
|
||||||
|
let test = { func: function(cb) { called = true; cb() } }
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
|
||||||
|
assert.strictEqual(called, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb() should work with timeout', async function() {
|
||||||
|
let called = false
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
setImmediate(function() {
|
||||||
|
called = true;
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
|
||||||
|
assert.strictEqual(called, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb() should capture throws outside', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) { throw assertError } }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb() should support callback error', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) { cb(assertError) } }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb() should support callback error in immediate', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
setImmediate(function() {
|
||||||
|
cb(assertError)
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.wrap() should return function and work with timeout', async function() {
|
||||||
|
let calledFirst = false
|
||||||
|
let calledSecond = false
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
let fun = cb.wrap(function() {
|
||||||
|
calledSecond = true
|
||||||
|
cb()
|
||||||
|
})
|
||||||
|
|
||||||
|
setImmediate(function() {
|
||||||
|
calledFirst = true;
|
||||||
|
fun()
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
|
||||||
|
assert.strictEqual(calledFirst, true)
|
||||||
|
assert.strictEqual(calledSecond, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.wrap() should pass arguments correctly', async function() {
|
||||||
|
let a = 0
|
||||||
|
let b = 0
|
||||||
|
let c = 0
|
||||||
|
let called = false
|
||||||
|
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
let fun = cb.wrap(function(ina, inb, inc) {
|
||||||
|
a = ina
|
||||||
|
b = inb
|
||||||
|
c = inc
|
||||||
|
cb()
|
||||||
|
})
|
||||||
|
|
||||||
|
setImmediate(function() {
|
||||||
|
called = true
|
||||||
|
fun(1, 2, 3)
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
|
||||||
|
assert.strictEqual(called, true)
|
||||||
|
assert.strictEqual(a, 1)
|
||||||
|
assert.strictEqual(b, 2)
|
||||||
|
assert.strictEqual(c, 3)
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.wrap() should throw', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
setImmediate(cb.wrap(function() {
|
||||||
|
throw assertError
|
||||||
|
}))
|
||||||
|
} }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.wrap() should support nested calls', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
setImmediate(function() {
|
||||||
|
setImmediate(cb.wrap(function() {
|
||||||
|
throw assertError
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
t.test('cb.finish() should return function and work with timeout and finish', async function() {
|
||||||
|
let calledFirst = false
|
||||||
|
let calledSecond = false
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
let fun = cb.finish(function() {
|
||||||
|
calledSecond = true
|
||||||
|
})
|
||||||
|
|
||||||
|
setImmediate(function() {
|
||||||
|
calledFirst = true;
|
||||||
|
fun()
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
|
||||||
|
assert.strictEqual(calledFirst, true)
|
||||||
|
assert.strictEqual(calledSecond, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.finish() should pass arguments correctly', async function() {
|
||||||
|
let a = 0
|
||||||
|
let b = 0
|
||||||
|
let c = 0
|
||||||
|
let called = false
|
||||||
|
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
let fun = cb.finish(function(ina, inb, inc) {
|
||||||
|
a = ina
|
||||||
|
b = inb
|
||||||
|
c = inc
|
||||||
|
})
|
||||||
|
|
||||||
|
setImmediate(function() {
|
||||||
|
called = true
|
||||||
|
fun(1, 2, 3)
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
|
||||||
|
assert.strictEqual(called, true)
|
||||||
|
assert.strictEqual(a, 1)
|
||||||
|
assert.strictEqual(b, 2)
|
||||||
|
assert.strictEqual(c, 3)
|
||||||
|
|
||||||
|
await runWithCallbackSafe(test)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.finish() should support throw', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
setImmediate(cb.finish(function() {
|
||||||
|
throw assertError
|
||||||
|
}))
|
||||||
|
} }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('cb.finish() should support nested throw calls', async function() {
|
||||||
|
const assertError = new Error('a')
|
||||||
|
let test = { func: function(cb) {
|
||||||
|
setImmediate(function() {
|
||||||
|
setImmediate(cb.finish(function() {
|
||||||
|
throw assertError
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
} }
|
||||||
|
|
||||||
|
let err = await assert.isRejected(runWithCallbackSafe(test))
|
||||||
|
|
||||||
|
assert.strictEqual(err, assertError)
|
||||||
|
})
|
||||||
|
})
|
|
@ -147,6 +147,38 @@ e.test('Eltro should support callback', async function() {
|
||||||
assert.strictEqual(assertIsTrue, true)
|
assert.strictEqual(assertIsTrue, true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
e.test('Eltro should support custom cb with finish wrap', async function() {
|
||||||
|
let actualRan = 0
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.describe('', function() {
|
||||||
|
t.test('a', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.finish(() => { actualRan++; }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('b', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.finish(() => { actualRan++; }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.test('c', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.finish(() => { actualRan++; }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.test('d', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.finish(() => { actualRan++; }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 0)
|
||||||
|
assert.strictEqual(actualRan, 4)
|
||||||
|
})
|
||||||
|
|
||||||
e.test('Eltro should support directly thrown errors', async function() {
|
e.test('Eltro should support directly thrown errors', async function() {
|
||||||
testsWereRun = true
|
testsWereRun = true
|
||||||
const assertError = new Error()
|
const assertError = new Error()
|
||||||
|
|
|
@ -49,3 +49,41 @@ e.test('Eltro should support any value in throws', async function() {
|
||||||
assert.ok(t.failedTests[x].error.stack)
|
assert.ok(t.failedTests[x].error.stack)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
e.test('Eltro should support custom cb with safe wrap', async function() {
|
||||||
|
let actualRan = 0
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.describe('', function() {
|
||||||
|
t.test('a', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.wrap(() => { actualRan++; throw null }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.test('b', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.wrap(() => { actualRan++; throw {} }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.test('c', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.wrap(() => { actualRan++; throw { message: 'test' } }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.test('d', function(cb) {
|
||||||
|
setImmediate(() => {
|
||||||
|
setImmediate(cb.wrap(() => { actualRan++; throw 1234 }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 4)
|
||||||
|
|
||||||
|
for (let x = 0; x < t.failedTests.length; x++) {
|
||||||
|
assert.strictEqual(typeof(t.failedTests[x].error), 'object')
|
||||||
|
assert.ok(t.failedTests[x].error.message)
|
||||||
|
assert.ok(t.failedTests[x].error.stack)
|
||||||
|
}
|
||||||
|
assert.strictEqual(actualRan, t.failedTests.length)
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in a new issue