First implementation of the metaltest
parent
16f2281e77
commit
f953f607bb
|
@ -0,0 +1 @@
|
|||
node_modules
|
|
@ -0,0 +1,59 @@
|
|||
import chalk from 'chalk'
|
||||
const log = (...args) => process.stdout.write(...args)
|
||||
|
||||
const consolereporter = () => {
|
||||
|
||||
const report = {
|
||||
start: (title) => {
|
||||
log(chalk.cyanBright(title) + ' ')
|
||||
},
|
||||
success: (test) => {
|
||||
log(chalk.greenBright('✓ '))
|
||||
},
|
||||
fail: (test, e) => {
|
||||
log(chalk.redBright('✗ '))
|
||||
},
|
||||
end: (stats) => {
|
||||
const { success, fail, total, testFail } = stats
|
||||
|
||||
log(' ' + chalk.redBright(fail))
|
||||
log(' ' + chalk.greenBright(success))
|
||||
log(' ' + chalk.gray('total:', total) + '\n')
|
||||
|
||||
for (const test of testFail) {
|
||||
log('\n' + chalk.redBright(test.name) + '\n')
|
||||
prettyError(test.error)
|
||||
log('\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return report
|
||||
}
|
||||
|
||||
const prettyError = (error) => {
|
||||
if (typeof error == 'string') {
|
||||
log(chalk.yellowBright(error))
|
||||
log('\n')
|
||||
return
|
||||
}
|
||||
|
||||
const msg = error.stack
|
||||
const i = msg.indexOf('\n')
|
||||
|
||||
const title = msg.slice(0, i)
|
||||
log(chalk.yellowBright(title) + '\n')
|
||||
|
||||
const at = msg.indexOf(' at ')
|
||||
const diff = msg.slice(i + 1, at - 1)
|
||||
if (diff != '\n ')
|
||||
log(chalk.white(diff))
|
||||
|
||||
const atEnd = msg.slice(at).indexOf('\n')
|
||||
const where = msg.slice(at + 3, at + atEnd)
|
||||
|
||||
if (where != '')
|
||||
log(chalk.gray(where) + '\n')
|
||||
}
|
||||
|
||||
export { consolereporter }
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
import { consolereporter } from './consolereporter.js'
|
||||
import { totalreporter } from './totalreporter.js'
|
||||
import { runifmain } from './runifmain.js'
|
||||
|
||||
const noreporter = {
|
||||
start: (title) => { },
|
||||
before: () => { },
|
||||
success: (test) => { },
|
||||
fail: (test, e) => { },
|
||||
after: () => { },
|
||||
end: (stats) => { },
|
||||
}
|
||||
|
||||
const metaltest = (title) => {
|
||||
const suite = []
|
||||
const only = []
|
||||
const before = []
|
||||
const after = []
|
||||
|
||||
let success = 0
|
||||
let fail = 0
|
||||
const testSuccess = []
|
||||
const testFail = []
|
||||
|
||||
const runner = (name, fn) => {
|
||||
suite.push({ name, fn })
|
||||
}
|
||||
|
||||
runner.only = (fn) => { only.push(fn) }
|
||||
runner.before = (fn) => { before.push(fn) }
|
||||
runner.after = (fn) => { after.push(fn) }
|
||||
|
||||
runner.run = async (...reporters) => {
|
||||
const rs = reporters.map(r => Object.assign({}, noreporter, r))
|
||||
|
||||
rs.forEach(r => r.start(title))
|
||||
rs.forEach(r => r.before())
|
||||
|
||||
const tests = only.length ? only : suite
|
||||
for (const test of tests) {
|
||||
try {
|
||||
for (const fn of before) await fn()
|
||||
await test.fn()
|
||||
success++
|
||||
rs.forEach(r => r.success(test))
|
||||
}
|
||||
catch (e) {
|
||||
fail++
|
||||
testFail.push(Object.assign({}, test, { error: e }))
|
||||
rs.forEach(r => r.fail(test, e))
|
||||
}
|
||||
}
|
||||
|
||||
for (const fn of after) await fn()
|
||||
|
||||
rs.forEach(r => r.after())
|
||||
|
||||
const stats = { title, success, fail, total: success + fail, testSuccess, testFail }
|
||||
|
||||
rs.forEach(r => r.end(stats))
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
return runner
|
||||
}
|
||||
|
||||
export { metaltest, consolereporter, totalreporter, runifmain }
|
||||
export default metaltest
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"name": "metaltest",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "metaltest",
|
||||
"version": "1.0.0",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"chalk": "^5.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz",
|
||||
"integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ==",
|
||||
"engines": {
|
||||
"node": "^12.17.0 || ^14.13 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.1.2.tgz",
|
||||
"integrity": "sha512-E5CkT4jWURs1Vy5qGJye+XwCkNj7Od3Af7CP6SujMetSMkLs8Do2RWJK5yx1wamHV/op8Rz+9rltjaTQWDnEFQ=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "metaltest",
|
||||
"version": "1.0.0",
|
||||
"description": "Clone of baretest with reporting",
|
||||
"type": "module",
|
||||
"exports": "./index.js",
|
||||
"scripts": {
|
||||
"test": "node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.tranche.ca/fmatte/metaltest"
|
||||
},
|
||||
"author": "Frédéric Matte <fmatte@gmail.com>",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"chalk": "^5.1.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const isMain = (meta) => {
|
||||
const path = fileURLToPath(meta.url)
|
||||
|
||||
return path.includes(process.argv[1])
|
||||
}
|
||||
|
||||
const runifmain = async (meta, fn) => {
|
||||
if (isMain(meta)) {
|
||||
await fn()
|
||||
}
|
||||
}
|
||||
|
||||
export { runifmain }
|
|
@ -0,0 +1,26 @@
|
|||
import assert from 'node:assert/strict'
|
||||
import { metaltest, consolereporter } from './index.js'
|
||||
|
||||
const test = metaltest('Metaltest')
|
||||
|
||||
let count = 0
|
||||
test.before(() => count++)
|
||||
|
||||
test('success', () => new Promise((s, f) => setTimeout(s, 500)))
|
||||
test('not equal', () => assert.notEqual({ a: 1 }, { a: 2 }))
|
||||
test('fail with the message', () => new Promise((s, f) => setTimeout(s, 500)))
|
||||
test('throw', () => {
|
||||
return assert.rejects(async () => {
|
||||
throw new Error('message')
|
||||
}, { name: 'Error', message: 'message' })
|
||||
})
|
||||
|
||||
export { test }
|
||||
|
||||
import { runifmain } from './runifmain.js'
|
||||
await runifmain(import.meta, async () => {
|
||||
const stats = await test.run(consolereporter())
|
||||
assert.equal(count, 4)
|
||||
assert.equal(stats.success, 4)
|
||||
assert.equal(stats.fail, 0)
|
||||
})
|
|
@ -0,0 +1,17 @@
|
|||
import chalk from 'chalk'
|
||||
|
||||
const totalreporter = () => {
|
||||
let totalSuccess = 0, totalFail = 0
|
||||
|
||||
return {
|
||||
success: (test) => { totalSuccess++ },
|
||||
fail: (test, e) => { totalFail++ },
|
||||
msg: () => `
|
||||
${chalk.redBright(`Total fail: ${totalFail}`)}
|
||||
${chalk.greenBright(`Total sucess: ${totalSuccess}`)}
|
||||
${chalk.yellowBright(`Ratio ${(totalSuccess / (totalSuccess + totalFail)) * 100}%`)}
|
||||
`
|
||||
}
|
||||
}
|
||||
|
||||
export { totalreporter }
|
Loading…
Reference in New Issue