Prepare first release
This commit is contained in:
parent
cc34409439
commit
653e54c846
15 changed files with 1215 additions and 2 deletions
64
cli.mjs
Normal file
64
cli.mjs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Get arguments
|
||||||
|
const [,, ...args] = process.argv
|
||||||
|
|
||||||
|
import c from './lib/casette.mjs'
|
||||||
|
import { CLI, printError } from './lib/cli.mjs'
|
||||||
|
|
||||||
|
c.begin()
|
||||||
|
|
||||||
|
const cli = new CLI(c)
|
||||||
|
cli.parseOptions(args)
|
||||||
|
|
||||||
|
if (cli.errored) {
|
||||||
|
PrintHelp()
|
||||||
|
}
|
||||||
|
|
||||||
|
function PrintHelp() {
|
||||||
|
console.log('')
|
||||||
|
console.log('Usage: casette <options> <files>')
|
||||||
|
console.log('')
|
||||||
|
console.log('where <files> can either be a single file or a simple glob pattern.')
|
||||||
|
console.log('where <options> can be any of the following:')
|
||||||
|
console.log(' -r, --reporter - Specify the reporter to use.')
|
||||||
|
console.log(' Supported reporters: list, dot')
|
||||||
|
console.log('')
|
||||||
|
console.log('casette test/mytest.mjs')
|
||||||
|
console.log('casette dot test/*.mjs')
|
||||||
|
console.log('casette -r dot test/**/*.test.mjs')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
cli.processTargets().then(function() {
|
||||||
|
if (!cli.files.length) {
|
||||||
|
console.log('')
|
||||||
|
console.log('No files were found with pattern', cli.targets.join(','))
|
||||||
|
PrintHelp()
|
||||||
|
}
|
||||||
|
return cli.loadFiles()
|
||||||
|
.then(function() {
|
||||||
|
c.reporter = cli.reporter
|
||||||
|
|
||||||
|
return c.run()
|
||||||
|
.catch(function(err) {
|
||||||
|
console.log('')
|
||||||
|
console.error('\x1b[31mUnknown error occured while running the tests\x1b[0m')
|
||||||
|
printError(err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
}, function(err) {
|
||||||
|
console.log('')
|
||||||
|
console.error('\x1b[31mUnknown error while opening files\x1b[0m')
|
||||||
|
printError(err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
}, function(err) {
|
||||||
|
console.log('')
|
||||||
|
console.error('\x1b[31mUnknown error while processing arguments\x1b[0m')
|
||||||
|
printError(err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
process.exit(0)
|
||||||
|
})
|
7
index.mjs
Normal file
7
index.mjs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Casette from './lib/casette.mjs'
|
||||||
|
import assert from './lib/assert.mjs'
|
||||||
|
|
||||||
|
export {
|
||||||
|
Casette,
|
||||||
|
assert,
|
||||||
|
}
|
83
lib/assert.mjs
Normal file
83
lib/assert.mjs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
import assert from 'assert'
|
||||||
|
import util from 'util'
|
||||||
|
|
||||||
|
const fail = assert.fail;
|
||||||
|
|
||||||
|
function truncate(s, n) {
|
||||||
|
return s.length < n ? s : s.slice(0, n) + '...';
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringifyObject(data) {
|
||||||
|
if (typeof(data) !== 'string') {
|
||||||
|
data = util.inspect(
|
||||||
|
data,
|
||||||
|
{ depth: 1 }
|
||||||
|
)
|
||||||
|
.replace(/\n /g, '');
|
||||||
|
}
|
||||||
|
return truncate(data, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.notOk = (value, message) => {
|
||||||
|
if (Boolean(value)) {
|
||||||
|
assert.equal(value, false, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.match = (value, test, message) => {
|
||||||
|
let result = value.match(test);
|
||||||
|
if (result) return;
|
||||||
|
|
||||||
|
let m = message
|
||||||
|
if (!m) {
|
||||||
|
m = `${value} did not match ${test}`
|
||||||
|
}
|
||||||
|
|
||||||
|
fail(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.notMatch = (value, test, message) => {
|
||||||
|
let result = value.match(test);
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
let m = message
|
||||||
|
if (!m) {
|
||||||
|
m = `${value} matched ${test}`
|
||||||
|
}
|
||||||
|
|
||||||
|
fail(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.isFulfilled = (promise, message) => {
|
||||||
|
return Promise.resolve(true)
|
||||||
|
.then(() => promise)
|
||||||
|
.catch((err) => {
|
||||||
|
let m = message
|
||||||
|
if (!m) {
|
||||||
|
m = `promise failed with ${err.message || stringifyObject(err)}`;
|
||||||
|
}
|
||||||
|
fail(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.isRejected = (promise, message) => {
|
||||||
|
let hasFailed = false;
|
||||||
|
|
||||||
|
return Promise.resolve(true)
|
||||||
|
.then(() => promise)
|
||||||
|
.catch((data) => {
|
||||||
|
hasFailed = true;
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
if (hasFailed) return data;
|
||||||
|
let m = message
|
||||||
|
if (!m) {
|
||||||
|
m = `promise was fulfilled with ${stringifyObject(data)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default assert
|
263
lib/casette.mjs
Normal file
263
lib/casette.mjs
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
import { printError } from './cli.mjs'
|
||||||
|
|
||||||
|
function Group(name) {
|
||||||
|
this.name = name
|
||||||
|
this.tests = []
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test(name, func) {
|
||||||
|
this.skipTest = false
|
||||||
|
this.customTimeout = null
|
||||||
|
this.name = name
|
||||||
|
this.func = func
|
||||||
|
this.group = null
|
||||||
|
this.error = null
|
||||||
|
}
|
||||||
|
|
||||||
|
Test.prototype.timeout = function(time) {
|
||||||
|
this.customTimeout = time
|
||||||
|
}
|
||||||
|
|
||||||
|
Test.prototype.skip = function() {
|
||||||
|
this.skipTest = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function Casette() {
|
||||||
|
this.__timeout = 2000
|
||||||
|
this.reporter = 'list'
|
||||||
|
this.Casette = Casette
|
||||||
|
this.groups = new Map()
|
||||||
|
this.groupsFlat = []
|
||||||
|
this.tests = []
|
||||||
|
this.failedTests = []
|
||||||
|
this.hasTests = false
|
||||||
|
this.starting = false
|
||||||
|
this.filename = ''
|
||||||
|
this.prefix = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.begin = function() {
|
||||||
|
if (this.starting) {
|
||||||
|
console.warn('WARNING: Multiple calls to Casette.begin were done.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.hasTests = false
|
||||||
|
this.starting = true
|
||||||
|
this.filename = ''
|
||||||
|
this.prefix = ''
|
||||||
|
this.groups.clear()
|
||||||
|
this.tests.splice(0, this.tests.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.__runTest = async function(stats, test) {
|
||||||
|
if (this.reporter === 'list') {
|
||||||
|
process.stdout.write(' \x1b[90m? ' + test.name + '\x1b[0m')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test.skipTest) {
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
// Flag to check if we finished
|
||||||
|
let finished = false
|
||||||
|
let timeout = test.customTimeout || this.__timeout
|
||||||
|
|
||||||
|
// Timeout timer in case test times out
|
||||||
|
let timer = setTimeout(function() {
|
||||||
|
if (finished === true) return
|
||||||
|
reject(new Error('timeout of ' + timeout + 'ms exceeded. Ensure the done() callback is being called in this test.'))
|
||||||
|
}, timeout)
|
||||||
|
|
||||||
|
// start the test runner
|
||||||
|
try {
|
||||||
|
// Does it accept a callback
|
||||||
|
let checkIsCallback = (test.func.toString()).match(/^(function)? *\([^\)]+\)/)
|
||||||
|
let promise
|
||||||
|
|
||||||
|
// If the test requires callback, wrap it in a promise where callback
|
||||||
|
// either resolves or rejects that promise
|
||||||
|
if (checkIsCallback) {
|
||||||
|
promise = new Promise(function(res, rej) {
|
||||||
|
test.func(function(err) {
|
||||||
|
if (err) {
|
||||||
|
return rej(err)
|
||||||
|
}
|
||||||
|
res()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Function doesn't require a callback, run it directly
|
||||||
|
promise = test.func()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the function we ran returned a promise
|
||||||
|
if (promise && promise.then && typeof(promise.then === 'function')) {
|
||||||
|
// If the promise from the function succeeded, resolve our promise.
|
||||||
|
// Otherwise reject it
|
||||||
|
promise.then(function() {
|
||||||
|
// check if our test had already finished and if so, do nothing
|
||||||
|
if (finished === true) return
|
||||||
|
|
||||||
|
finished = true
|
||||||
|
clearTimeout(timer)
|
||||||
|
resolve()
|
||||||
|
}, function(err) {
|
||||||
|
// check if our test had already finished and if so, do nothing
|
||||||
|
if (finished === true) return
|
||||||
|
|
||||||
|
finished = true
|
||||||
|
clearTimeout(timer)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// check if our test had already finished and if so, do nothing
|
||||||
|
if (finished === true) return
|
||||||
|
|
||||||
|
// Possible this was a synchronous test, pass immediately
|
||||||
|
finished = true
|
||||||
|
clearTimeout(timer)
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// check if our test had already finished and if so, do nothing
|
||||||
|
if (finished === true) return
|
||||||
|
|
||||||
|
// An error occured while running function. Possible exception
|
||||||
|
// during a synchronous test or something else.
|
||||||
|
finished = true
|
||||||
|
clearTimeout(timer)
|
||||||
|
reject(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
stats.passed++
|
||||||
|
}, function(err) {
|
||||||
|
test.error = err
|
||||||
|
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')
|
||||||
|
} else {
|
||||||
|
process.stdout.write(' \x1b[31m' + this.failedTests.length + ') ' + test.name + '\x1b[0m\n')
|
||||||
|
}
|
||||||
|
} else if (this.reporter === 'dot') {
|
||||||
|
if (test.skipTest) {
|
||||||
|
process.stdout.write('\x1b[94m.\x1b[0m')
|
||||||
|
} else if (!test.error) {
|
||||||
|
process.stdout.write('\x1b[32m.\x1b[0m')
|
||||||
|
} else {
|
||||||
|
process.stdout.write('\x1b[31m.\x1b[0m')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.run = async function() {
|
||||||
|
if (this.reporter) {
|
||||||
|
console.log('')
|
||||||
|
console.log('')
|
||||||
|
}
|
||||||
|
|
||||||
|
let stats = {
|
||||||
|
passed: 0,
|
||||||
|
failed: 0,
|
||||||
|
skipped: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
let start = process.hrtime()
|
||||||
|
for (let i = 0; i < this.groupsFlat.length; i++) {
|
||||||
|
let g = this.groupsFlat[i];
|
||||||
|
|
||||||
|
if (this.reporter === 'list') {
|
||||||
|
console.log(' ' + g.name)
|
||||||
|
}
|
||||||
|
for (let x = 0; x < g.tests.length; x++) {
|
||||||
|
await this.__runTest(stats, g.tests[x])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let x = 0; x < this.tests.length; x++) {
|
||||||
|
await this.__runTest(stats, this.tests[x])
|
||||||
|
}
|
||||||
|
let end = process.hrtime(start)
|
||||||
|
|
||||||
|
if (this.reporter) {
|
||||||
|
console.log('')
|
||||||
|
console.log('')
|
||||||
|
if (stats.passed) {
|
||||||
|
console.log(' \x1b[32m' + stats.passed + ' passing \x1b[90m(' + (end[0] * 1000 + Math.round(end[1] / 1000000)) + 'ms)\x1b[0m')
|
||||||
|
}
|
||||||
|
if (stats.failed) {
|
||||||
|
console.log(' \x1b[31m' + stats.failed + ' failing\x1b[0m')
|
||||||
|
}
|
||||||
|
if (stats.skipped) {
|
||||||
|
console.log(' \x1b[94m' + stats.skipped + ' pending\x1b[0m')
|
||||||
|
}
|
||||||
|
console.log('')
|
||||||
|
|
||||||
|
if (this.failedTests.length) {
|
||||||
|
for (let x = 0; x < this.failedTests.length; x++) {
|
||||||
|
let test = this.failedTests[x];
|
||||||
|
console.log(' ' + (x + 1) + ') '
|
||||||
|
+ (test.group ? test.group.name + ': ' : '' )
|
||||||
|
+ test.name + ':'
|
||||||
|
)
|
||||||
|
printError(test.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.setFilename = function(filename) {
|
||||||
|
this.filename = filename
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.resetFilename = function() {
|
||||||
|
this.filename = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.describe = function(name, func) {
|
||||||
|
let before = this.prefix
|
||||||
|
if (before) {
|
||||||
|
this.prefix = before + ' ' + name
|
||||||
|
} else {
|
||||||
|
this.prefix = name
|
||||||
|
}
|
||||||
|
func()
|
||||||
|
this.prefix = before
|
||||||
|
}
|
||||||
|
|
||||||
|
Casette.prototype.test = function(name, func) {
|
||||||
|
let targetName = name
|
||||||
|
if (this.prefix) {
|
||||||
|
targetName = this.prefix + ' ' + name
|
||||||
|
}
|
||||||
|
this.hasTests = true
|
||||||
|
|
||||||
|
let group = this
|
||||||
|
if (this.filename) {
|
||||||
|
if (!this.groups.has(this.filename)) {
|
||||||
|
let g = new Group(this.filename)
|
||||||
|
this.groupsFlat.push(g)
|
||||||
|
this.groups.set(this.filename, g)
|
||||||
|
}
|
||||||
|
group = this.groups.get(this.filename)
|
||||||
|
}
|
||||||
|
let test = new Test(targetName, func)
|
||||||
|
test.group = group
|
||||||
|
group.tests.push(test)
|
||||||
|
return test
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Casette()
|
169
lib/cli.mjs
Normal file
169
lib/cli.mjs
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
import path from 'path'
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
|
export function CLI(c) {
|
||||||
|
this.c = c
|
||||||
|
this.reporter = 'list'
|
||||||
|
this.targets = ['test/**']
|
||||||
|
this.files = []
|
||||||
|
this.errored = false
|
||||||
|
}
|
||||||
|
|
||||||
|
CLI.prototype.parseOptions = function(args) {
|
||||||
|
if (!args || !args.length) {
|
||||||
|
this.targets.push('test/**')
|
||||||
|
this.errored = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.errored = false
|
||||||
|
this.targets.splice(0, this.targets.length)
|
||||||
|
|
||||||
|
|
||||||
|
for (let i = 0; i < args.length; i++) {
|
||||||
|
if (args[i] === '-r' || args[i] === '--reporter') {
|
||||||
|
if (!args[i + 1] || (args[i + 1] !== 'list' && args[i + 1] !== 'dot')) {
|
||||||
|
this.errored = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.reporter = args[i + 1]
|
||||||
|
i++
|
||||||
|
} else {
|
||||||
|
this.targets.push(args[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.targets.length) {
|
||||||
|
this.targets.push('test/**')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CLI.prototype.processTargets = function() {
|
||||||
|
this.files.splice(0, this.files.length)
|
||||||
|
|
||||||
|
if (!this.targets.length) {
|
||||||
|
return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(this.targets.map((target) => {
|
||||||
|
return getFiles(this.files, target)
|
||||||
|
})).then(() => {
|
||||||
|
if (!this.files.length) {
|
||||||
|
this.errored = 'empty'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
CLI.prototype.loadFiles = async function() {
|
||||||
|
let cwd = process.cwd()
|
||||||
|
|
||||||
|
for (let i = 0; i < this.files.length; i++) {
|
||||||
|
if (this.files[i].endsWith('.mjs') || this.files[i].endsWith('.js')) {
|
||||||
|
this.c.setFilename(this.files[i])
|
||||||
|
await import('file:///' + path.join(cwd, this.files[i]))
|
||||||
|
this.c.resetFilename()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function traverseFolder(files, curr, match, insidePath, grabAll, insideStar, includeFiles) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
return fs.readdir(curr, function(err, data) {
|
||||||
|
if (err) return reject(new Error('unable to read directory ' + curr + ': ' + err.message))
|
||||||
|
|
||||||
|
resolve(Promise.all(data.map(function(file) {
|
||||||
|
return new Promise(function(res, rej) {
|
||||||
|
fs.lstat(path.join(curr, file), function(err, stat) {
|
||||||
|
if (err) return rej(new Error('unable to read file or directory ' + path.join(curr, file) + ': ' + err.message))
|
||||||
|
|
||||||
|
if ((includeFiles || grabAll) && stat.isFile()) {
|
||||||
|
if (!match || fileMatches(file, match)) {
|
||||||
|
files.push(path.join(insidePath, file).replace(/\\/g, '/'))
|
||||||
|
return res(files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stat.isDirectory() && grabAll) {
|
||||||
|
return res(traverseFolder(files, path.join(curr, file), match, path.join(insidePath, file), grabAll, insideStar, includeFiles))
|
||||||
|
} else if (stat.isDirectory() && match) {
|
||||||
|
return res(getFiles(files, match, path.join(insidePath, file), grabAll, insideStar))
|
||||||
|
}
|
||||||
|
res(null)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})).then(function() { return files }))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fileMatches(filename, match) {
|
||||||
|
return Boolean(filename.match(new RegExp(match.replace(/\./, '\\.').replace(/\*/, '.*'))))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFiles(files, match, insidePath, grabAll, insideStar) {
|
||||||
|
let isGrabbingAll = grabAll || false
|
||||||
|
let isStarred = insideStar || false
|
||||||
|
let cwd = process.cwd()
|
||||||
|
let currPath = insidePath || ''
|
||||||
|
let curr = path.join(cwd, currPath || '')
|
||||||
|
|
||||||
|
return new Promise(function(res, rej) {
|
||||||
|
let start = 0
|
||||||
|
let splitted = match.split('/')
|
||||||
|
if (splitted[start] === '.') {
|
||||||
|
start++
|
||||||
|
}
|
||||||
|
if (splitted[splitted.length - 1] === '') {
|
||||||
|
splitted[splitted.length - 1] === '*'
|
||||||
|
}
|
||||||
|
|
||||||
|
let first = splitted[start]
|
||||||
|
|
||||||
|
if (splitted.length > start + 1) {
|
||||||
|
if (first === '**') {
|
||||||
|
isGrabbingAll = isStarred = true
|
||||||
|
return traverseFolder(files, curr, splitted.slice(start + 1).join('/'), currPath, isGrabbingAll, isStarred, false)
|
||||||
|
.then(res, rej)
|
||||||
|
} else if (first === '*') {
|
||||||
|
isStarred = true
|
||||||
|
return traverseFolder(files, curr, splitted.slice(start + 1).join('/'), currPath, isGrabbingAll, isStarred, false)
|
||||||
|
.then(res, rej)
|
||||||
|
}
|
||||||
|
return getFiles(files, splitted.slice(start + 1).join('/'), path.join(currPath, first), grabAll, isStarred)
|
||||||
|
.then(res, rej)
|
||||||
|
} else if (first.indexOf('*') >= 0) {
|
||||||
|
if (first === '**') {
|
||||||
|
isGrabbingAll = isStarred = true
|
||||||
|
}
|
||||||
|
return traverseFolder(files, curr, first === '*' || first === '**'? '' : first, currPath, isGrabbingAll, isStarred, true)
|
||||||
|
.then(res, rej)
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.lstat(path.join(curr, first), function(err, stat) {
|
||||||
|
if (err) {
|
||||||
|
// If we're inside a star, we ignore files we cannot find
|
||||||
|
if (isStarred) {
|
||||||
|
return res(files)
|
||||||
|
}
|
||||||
|
return rej(new Error('file ' + path.join(insidePath, first) + ' could not be found: ' + err.message))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
return traverseFolder(files, path.join(curr, first), '', path.join(currPath, first), true, true, true)
|
||||||
|
.then(res, rej)
|
||||||
|
}
|
||||||
|
|
||||||
|
files.push(path.join(currPath, match).replace(/\\/g, '/'))
|
||||||
|
return res(files)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function printError(err, msg) {
|
||||||
|
let before = msg || ''
|
||||||
|
console.error('')
|
||||||
|
console.error('\x1b[31m '
|
||||||
|
+ before + err.toString()
|
||||||
|
+ '\x1b[0m\n \x1b[90m'
|
||||||
|
+ err.stack.replace(err.toString(), ''))
|
||||||
|
console.error('\x1b[0m')
|
||||||
|
}
|
10
package.json
10
package.json
|
@ -2,7 +2,7 @@
|
||||||
"name": "casette",
|
"name": "casette",
|
||||||
"version": "0.9.0",
|
"version": "0.9.0",
|
||||||
"description": "No-dependancy test framework for node",
|
"description": "No-dependancy test framework for node",
|
||||||
"main": "index.js",
|
"main": "index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node cli.mjs test/**/*.test.mjs"
|
"test": "node cli.mjs test/**/*.test.mjs"
|
||||||
},
|
},
|
||||||
|
@ -25,5 +25,11 @@
|
||||||
"homepage": "https://github.com/TheThing/node-casette#readme",
|
"homepage": "https://github.com/TheThing/node-casette#readme",
|
||||||
"bin": {
|
"bin": {
|
||||||
"casette": "./cli.mjs"
|
"casette": "./cli.mjs"
|
||||||
}
|
},
|
||||||
|
"files": [
|
||||||
|
"index.mjs",
|
||||||
|
"cli.mjs",
|
||||||
|
"README.md",
|
||||||
|
"lib"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
154
test/assert.test.mjs
Normal file
154
test/assert.test.mjs
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
import util from 'util'
|
||||||
|
import assert from 'assert'
|
||||||
|
import assertExtended from '../lib/assert.mjs'
|
||||||
|
|
||||||
|
import c from '../lib/casette.mjs'
|
||||||
|
|
||||||
|
const testLongObject = {
|
||||||
|
a: 1, b:2, c:3, d:4,
|
||||||
|
e: {herp: 51, derp: 23},
|
||||||
|
f: 'asdfgagwegawegawegawegawe',
|
||||||
|
g: '32ghaiwugb23 238023'
|
||||||
|
}
|
||||||
|
|
||||||
|
c.describe('#notOk()', function() {
|
||||||
|
c.test('should exist', function() {
|
||||||
|
assertExtended.ok(assertExtended.notOk)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should throw for true values', function() {
|
||||||
|
assertExtended.throws(function() {
|
||||||
|
assertExtended.notOk(true)
|
||||||
|
}, assertExtended.AssertionError)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should pass for false values', function() {
|
||||||
|
assertExtended.notOk(false)
|
||||||
|
assertExtended.notOk(null)
|
||||||
|
assertExtended.notOk(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.describe('#isFulfilled()', function() {
|
||||||
|
c.test('should exist', function() {
|
||||||
|
assertExtended.ok(assertExtended.isFulfilled)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should throw for rejected promises', function() {
|
||||||
|
return assertExtended.isFulfilled(Promise.reject({}))
|
||||||
|
.catch((err) => {
|
||||||
|
assertExtended.ok(err.message.match(/promise fail/))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should properly parse rejected object response', function() {
|
||||||
|
let assertMessage = util.inspect(testLongObject, {depth: 1}).replace(/\n /g, '')
|
||||||
|
assertMessage = assertMessage.slice(0, 64) + '...'
|
||||||
|
|
||||||
|
return assertExtended.isFulfilled(Promise.reject(testLongObject))
|
||||||
|
.catch((err) =>
|
||||||
|
assertExtended.notStrictEqual(err.message.indexOf(assertMessage), -1)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should include error message if error', function() {
|
||||||
|
const assertMessage = 'something something dark side'
|
||||||
|
return assertExtended.isFulfilled(Promise.reject(new Error(assertMessage)))
|
||||||
|
.catch((err) => {
|
||||||
|
assertExtended.ok(err.message.match(new RegExp('with ' + assertMessage)))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should pass for resolved promises', function() {
|
||||||
|
return assertExtended.isFulfilled(Promise.resolve())
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support custom message', function() {
|
||||||
|
const assertMessage = 'something something dark side'
|
||||||
|
return assertExtended.isFulfilled(Promise.reject({}), assertMessage)
|
||||||
|
.catch((err) => {
|
||||||
|
assertExtended.ok(err.message.match(assertMessage))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should return result for the resolved promise', function() {
|
||||||
|
const assertResult = {a: 1}
|
||||||
|
|
||||||
|
return assertExtended.isFulfilled(Promise.resolve(assertResult))
|
||||||
|
.then((data) => assertExtended.strictEqual(data, assertResult))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.describe('#isRejected()', function() {
|
||||||
|
c.test('should exist', function() {
|
||||||
|
assertExtended.ok(assertExtended.isRejected)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should throw for resolved promises', function() {
|
||||||
|
let hasFailed = false
|
||||||
|
|
||||||
|
return assertExtended.isRejected(Promise.resolve({}))
|
||||||
|
.catch((err) => {
|
||||||
|
hasFailed = true
|
||||||
|
assertExtended.ok(err.message.match(/fulfilled with/))
|
||||||
|
})
|
||||||
|
.then(function() {
|
||||||
|
assertExtended.strictEqual(hasFailed, true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should properly stringify objects', function() {
|
||||||
|
let assertMessage = util.inspect(testLongObject, {depth: 1}).replace(/\n /g, '')
|
||||||
|
assertMessage = assertMessage.slice(0, 64) + '...'
|
||||||
|
|
||||||
|
return assertExtended.isRejected(Promise.resolve(testLongObject))
|
||||||
|
.catch((err) =>
|
||||||
|
assertExtended.notStrictEqual(err.message.indexOf(assertMessage), -1)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support custom message', function() {
|
||||||
|
const assertMessage = 'something something dark side'
|
||||||
|
return assertExtended.isRejected(Promise.resolve({}), assertMessage)
|
||||||
|
.catch((err) => assertExtended.ok(err.message.match(assertMessage)))
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should return result for the unresolved promise', function() {
|
||||||
|
const assertResult = {a: 1}
|
||||||
|
|
||||||
|
return assertExtended.isRejected(Promise.reject(assertResult))
|
||||||
|
.then((data) => assertExtended.strictEqual(data, assertResult))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.describe('#match()', function() {
|
||||||
|
c.test('should exist', function() {
|
||||||
|
assertExtended.ok(assertExtended.match);
|
||||||
|
});
|
||||||
|
|
||||||
|
c.test('should throw if no match', function() {
|
||||||
|
assertExtended.throws(function() {
|
||||||
|
assertExtended.match('a', /b/);
|
||||||
|
}, assertExtended.AssertionError);
|
||||||
|
});
|
||||||
|
|
||||||
|
c.test('should pass if matches', function() {
|
||||||
|
assertExtended.match('a', /a/);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
c.describe('#notMatch()', function() {
|
||||||
|
c.test('should exist', function() {
|
||||||
|
assertExtended.ok(assertExtended.notMatch);
|
||||||
|
});
|
||||||
|
|
||||||
|
c.test('should throw if match', function() {
|
||||||
|
assertExtended.throws(function() {
|
||||||
|
assertExtended.notMatch('a', /a/);
|
||||||
|
}, assertExtended.AssertionError);
|
||||||
|
});
|
||||||
|
|
||||||
|
c.test('should pass if not matches', function() {
|
||||||
|
assertExtended.notMatch('a', /b/);
|
||||||
|
});
|
||||||
|
})
|
192
test/casette.test.mjs
Normal file
192
test/casette.test.mjs
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
import c from '../lib/casette.mjs'
|
||||||
|
import assert from '../lib/assert.mjs'
|
||||||
|
import { printError } from '../lib/cli.mjs'
|
||||||
|
|
||||||
|
let testsWereRun = false
|
||||||
|
|
||||||
|
function CreateT() {
|
||||||
|
const t = new c.Casette()
|
||||||
|
t.reporter = ''
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
c.test('Casette describe should add prefix to the group tests', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const assertPrefix = 'something'
|
||||||
|
const assertName = 'blabla'
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.setFilename('test')
|
||||||
|
t.describe(assertPrefix, function() {
|
||||||
|
t.test(assertName, function() {})
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.strictEqual(t.groupsFlat.length, 1)
|
||||||
|
assert.strictEqual(t.groupsFlat[0].tests.length, 1)
|
||||||
|
assert.strictEqual(t.groupsFlat[0].tests[0].name, assertPrefix + ' ' + assertName)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette describe should add prefix to individual tests', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const assertPrefix = 'something'
|
||||||
|
const assertName = 'blabla'
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.describe(assertPrefix, function() {
|
||||||
|
t.test(assertName, function() {})
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.strictEqual(t.tests.length, 1)
|
||||||
|
assert.strictEqual(t.tests[0].name, assertPrefix + ' ' + assertName)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette describe should support multiple describe', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const assertPrefix = 'something'
|
||||||
|
const assertPrefix2 = 'else'
|
||||||
|
const assertName = 'blabla'
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.describe(assertPrefix, function() {
|
||||||
|
t.describe(assertPrefix2, function() {
|
||||||
|
t.test(assertName, function() {})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.strictEqual(t.tests.length, 1)
|
||||||
|
assert.strictEqual(t.tests[0].name, assertPrefix + ' ' + assertPrefix2 + ' ' + assertName)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should run test', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
let assertIsTrue = false
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function() {
|
||||||
|
assertIsTrue = true
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 0)
|
||||||
|
assert.strictEqual(assertIsTrue, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should run promised test', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
let assertIsTrue = false
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function() {
|
||||||
|
return new Promise(function(res) {
|
||||||
|
assertIsTrue = true
|
||||||
|
res()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 0)
|
||||||
|
assert.strictEqual(assertIsTrue, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support callback', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
let assertIsTrue = false
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function(cb) {
|
||||||
|
setTimeout(function() {
|
||||||
|
assertIsTrue = true
|
||||||
|
cb()
|
||||||
|
}, 50)
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 0)
|
||||||
|
assert.strictEqual(assertIsTrue, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support directly thrown errors', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const assertError = new Error()
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function() {
|
||||||
|
throw assertError
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 1)
|
||||||
|
assert.strictEqual(t.failedTests[0].error, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support promise rejected errors', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const assertError = new Error()
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function() {
|
||||||
|
return new Promise(function(res, rej) {
|
||||||
|
rej(assertError)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 1)
|
||||||
|
assert.strictEqual(t.failedTests[0].error, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support callback rejected errors', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const assertError = new Error()
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function(cb) {
|
||||||
|
cb(assertError)
|
||||||
|
})
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 1)
|
||||||
|
assert.strictEqual(t.failedTests[0].error, assertError)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support timing out tests', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function(cb) { }).timeout(50)
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 1)
|
||||||
|
assert.ok(t.failedTests[0].error)
|
||||||
|
assert.match(t.failedTests[0].error.message, /50ms/)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support timed out tests on late tests', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function(cb) {
|
||||||
|
setTimeout(function() {
|
||||||
|
cb()
|
||||||
|
}, 100)
|
||||||
|
}).timeout(50)
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 1)
|
||||||
|
assert.ok(t.failedTests[0].error)
|
||||||
|
assert.match(t.failedTests[0].error.message, /50ms/)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('Casette should support skipped tests', async function() {
|
||||||
|
testsWereRun = true
|
||||||
|
const t = CreateT()
|
||||||
|
t.begin()
|
||||||
|
t.test('', function() {
|
||||||
|
throw new Error('Should not be called')
|
||||||
|
}).skip()
|
||||||
|
await t.run()
|
||||||
|
assert.strictEqual(t.failedTests.length, 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Extra testing to make sure tests were run at all
|
||||||
|
process.on('exit', function(e) {
|
||||||
|
try {
|
||||||
|
assert.strictEqual(testsWereRun, true)
|
||||||
|
} catch(err) {
|
||||||
|
printError(err)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
process.exit(e)
|
||||||
|
})
|
265
test/cli.test.mjs
Normal file
265
test/cli.test.mjs
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
import c from '../lib/casette.mjs'
|
||||||
|
import assert from '../lib/assert.mjs'
|
||||||
|
import { CLI, getFiles, fileMatches } from '../lib/cli.mjs'
|
||||||
|
|
||||||
|
c.describe('CLI', function() {
|
||||||
|
let cli = new CLI()
|
||||||
|
|
||||||
|
c.test('#constructor() give default options', function() {
|
||||||
|
assert.strictEqual(cli.reporter, 'list')
|
||||||
|
assert.deepEqual(cli.targets, ['test/**'])
|
||||||
|
assert.deepEqual(cli.files, [])
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* #parseOptions()
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
c.describe('#parseOptions()', function() {
|
||||||
|
c.test('should not do anything if no options', function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
|
cli.parseOptions([])
|
||||||
|
assert.strictEqual(cli.reporter, 'list')
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support overriding reporter with shorthand option', function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
|
cli.parseOptions(['-r', 'dot'])
|
||||||
|
assert.strictEqual(cli.reporter, 'dot')
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support overriding reporter with long option', function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
|
cli.parseOptions(['--reporter', 'dot'])
|
||||||
|
assert.strictEqual(cli.reporter, 'dot')
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support reporter list', function() {
|
||||||
|
cli.reporter = 'list'
|
||||||
|
cli.parseOptions(['-r', 'list'])
|
||||||
|
assert.strictEqual(cli.reporter, 'list')
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should mark errored if missing reporter', function() {
|
||||||
|
cli.parseOptions(['--reporter'])
|
||||||
|
assert.ok(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should mark errored if invalid reporter', function() {
|
||||||
|
cli.parseOptions(['--reporter', 'test'])
|
||||||
|
assert.ok(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should add file to targets', function() {
|
||||||
|
cli.parseOptions(['test'])
|
||||||
|
assert.deepEqual(cli.targets, ['test'])
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should add file to targets no matter where it is', function() {
|
||||||
|
cli.parseOptions(['test', '-r', 'list', 'test2'])
|
||||||
|
assert.deepEqual(cli.targets, ['test', 'test2'])
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should default add test to target if no target', function() {
|
||||||
|
cli.parseOptions(['-r', 'list'])
|
||||||
|
assert.deepEqual(cli.targets, ['test/**'])
|
||||||
|
assert.notOk(cli.errored)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* #processTargets()
|
||||||
|
*****************************************/
|
||||||
|
|
||||||
|
c.describe('#processTargets()', function() {
|
||||||
|
c.test('should mark errored if empty', async function() {
|
||||||
|
cli.targets = ['test/folder1/*.txt']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.strictEqual(cli.files.length, 0)
|
||||||
|
assert.ok(cli.errored)
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support direct file path if exists', async function() {
|
||||||
|
cli.targets = ['test/folder1/sampletest1.temp.mjs']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.strictEqual(cli.files.length, 1)
|
||||||
|
assert.strictEqual(cli.files[0], 'test/folder1/sampletest1.temp.mjs')
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should return all files in a directory', async function() {
|
||||||
|
cli.targets = ['test/folder1/']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.strictEqual(cli.files.length, 2)
|
||||||
|
assert.strictEqual(cli.files[0], 'test/folder1/sampletest1.temp.mjs')
|
||||||
|
assert.strictEqual(cli.files[1], 'test/folder1/sampletest2.temp.mjs')
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support start as folder substitute', async function() {
|
||||||
|
cli.targets = ['*/folder1/']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.strictEqual(cli.files.length, 2)
|
||||||
|
assert.strictEqual(cli.files[0], 'test/folder1/sampletest1.temp.mjs')
|
||||||
|
assert.strictEqual(cli.files[1], 'test/folder1/sampletest2.temp.mjs')
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support grabbing only files in folder', async function() {
|
||||||
|
cli.targets = ['test/*']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.ok(cli.files.length)
|
||||||
|
for (let i = 0; i < cli.files.length; i++) {
|
||||||
|
assert.notOk(cli.files[i].match(/\/folder1\//))
|
||||||
|
assert.notOk(cli.files[i].match(/\/folder2\//))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support grabbing only pattern files in folder', async function() {
|
||||||
|
cli.targets = ['test/*.test.mjs']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.ok(cli.files.length)
|
||||||
|
for (let i = 0; i < cli.files.length; i++) {
|
||||||
|
assert.notOk(cli.files[i].match(/\/folder1\//))
|
||||||
|
assert.notOk(cli.files[i].match(/\/folder2\//))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support multiple star pattern', async function() {
|
||||||
|
cli.targets = ['test/*/*.mjs']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.strictEqual(cli.files.length, 4)
|
||||||
|
cli.files.sort()
|
||||||
|
assert.deepEqual(cli.files, [
|
||||||
|
'test/folder1/sampletest1.temp.mjs',
|
||||||
|
'test/folder1/sampletest2.temp.mjs',
|
||||||
|
'test/folder2/sampletest3.temp.mjs',
|
||||||
|
'test/folder2/sampletest4.temp.mjs',
|
||||||
|
])
|
||||||
|
|
||||||
|
cli.targets = ['test/*/sampletest*.mjs']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.strictEqual(cli.files.length, 4)
|
||||||
|
cli.files.sort()
|
||||||
|
assert.deepEqual(cli.files, [
|
||||||
|
'test/folder1/sampletest1.temp.mjs',
|
||||||
|
'test/folder1/sampletest2.temp.mjs',
|
||||||
|
'test/folder2/sampletest3.temp.mjs',
|
||||||
|
'test/folder2/sampletest4.temp.mjs',
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support double star pattern', async function() {
|
||||||
|
cli.targets = ['test/**/*.mjs']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.ok(cli.files.length)
|
||||||
|
|
||||||
|
let found = {
|
||||||
|
sampletest1: false,
|
||||||
|
sampletest2: false,
|
||||||
|
sampletest3: false,
|
||||||
|
sampletest4: false,
|
||||||
|
sampletest5: false,
|
||||||
|
cli: false
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < cli.files.length; i++) {
|
||||||
|
if (cli.files[i] === 'test/folder1/sampletest1.temp.mjs') {
|
||||||
|
found.sampletest1 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder1/sampletest2.temp.mjs') {
|
||||||
|
found.sampletest2 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder2/sampletest3.temp.mjs') {
|
||||||
|
found.sampletest3 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder2/sampletest4.temp.mjs') {
|
||||||
|
found.sampletest4 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder2/sampletest5.temp.txt') {
|
||||||
|
found.sampletest5 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/cli.test.mjs') {
|
||||||
|
found.cli = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepEqual(found, {
|
||||||
|
sampletest1: true,
|
||||||
|
sampletest2: true,
|
||||||
|
sampletest3: true,
|
||||||
|
sampletest4: true,
|
||||||
|
sampletest5: false,
|
||||||
|
cli: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('should support double star pattern end', async function() {
|
||||||
|
cli.targets = ['test/**']
|
||||||
|
await cli.processTargets()
|
||||||
|
|
||||||
|
assert.ok(cli.files.length)
|
||||||
|
|
||||||
|
let found = {
|
||||||
|
sampletest1: false,
|
||||||
|
sampletest2: false,
|
||||||
|
sampletest3: false,
|
||||||
|
sampletest4: false,
|
||||||
|
sampletest5: false,
|
||||||
|
cli: false
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < cli.files.length; i++) {
|
||||||
|
if (cli.files[i] === 'test/folder1/sampletest1.temp.mjs') {
|
||||||
|
found.sampletest1 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder1/sampletest2.temp.mjs') {
|
||||||
|
found.sampletest2 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder2/sampletest3.temp.mjs') {
|
||||||
|
found.sampletest3 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder2/sampletest4.temp.mjs') {
|
||||||
|
found.sampletest4 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/folder2/sampletest5.temp.txt') {
|
||||||
|
found.sampletest5 = true
|
||||||
|
}
|
||||||
|
if (cli.files[i] === 'test/cli.test.mjs') {
|
||||||
|
found.cli = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepEqual(found, {
|
||||||
|
sampletest1: true,
|
||||||
|
sampletest2: true,
|
||||||
|
sampletest3: true,
|
||||||
|
sampletest4: true,
|
||||||
|
sampletest5: true,
|
||||||
|
cli: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
c.test('#fileMatches() should support filename matching with glob pattern', async function() {
|
||||||
|
assert.ok(fileMatches('bla.test.mjs', '*.mjs'))
|
||||||
|
assert.ok(fileMatches('bla.test.mjs', '*test.mjs'))
|
||||||
|
assert.ok(fileMatches('bla.test.mjs', 'bla*.mjs'))
|
||||||
|
assert.notOk(fileMatches('bla.test.mjs', 'bla*.js'))
|
||||||
|
assert.notOk(fileMatches('bla.test.mjs', '*.js'))
|
||||||
|
assert.notOk(fileMatches('bla.test.mjs', 'blas*.js'))
|
||||||
|
})
|
0
test/folder1/sampletest1.temp.mjs
Normal file
0
test/folder1/sampletest1.temp.mjs
Normal file
0
test/folder1/sampletest2.temp.mjs
Normal file
0
test/folder1/sampletest2.temp.mjs
Normal file
0
test/folder2/sampletest3.temp.mjs
Normal file
0
test/folder2/sampletest3.temp.mjs
Normal file
0
test/folder2/sampletest4.temp.mjs
Normal file
0
test/folder2/sampletest4.temp.mjs
Normal file
1
test/folder2/sampletest5.temp.txt
Normal file
1
test/folder2/sampletest5.temp.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
keep
|
9
test/test.mjs
Normal file
9
test/test.mjs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { Casette as c, assert} from '../index.mjs'
|
||||||
|
|
||||||
|
c.describe('Array', function() {
|
||||||
|
c.describe('#indexOf()', function() {
|
||||||
|
c.test('should return -1 when value is not present', function() {
|
||||||
|
assert.equal([1,2,3].indexOf(4), -1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in a new issue