Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 2x 2x 2x 2x 2x 2x 8x 8x 8x 8x 8x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 1x 1x | const { suite } = require('uvu')
const assert = require('uvu/assert')
/**
* Generate function to process the test data from array and execute tests.
*
* The generated function accepts an array, verifies the shape and content as well
* as either executes an uvu is assert using the extracted components or fails the
* test upon execution with exposure of the problematic test vector.
*
* The options object with method and trace members if present sets the assertion method and tracing mode.
*
* Defaults are `assert.is` as assertion method and production (non-tracing) mode.
*
* Any valid test vector has
* 1. content
* 2. is a javascript array
* 3. has 3 or more items
* 4. has a function under test or its string representation as first item
* 5. has the expectation (result) as last item
* 6. all items but the first and last are positional input parameters to the function under test
*
* @param options is an optional object with method and trace members
* @returns {(function(*=): void)|*}
*/
const process = (options) => {
return vector => {
const trace = options && options.trace
if (trace) console.log(vector, options)
const default_method = assert.is
const method = options && options.method
? (typeof(options.method) === 'string'
? eval(options.method)
: options.method)
: default_method
if (vector && Array.isArray(vector) && vector.length > 2 && typeof (vector[0]) === 'function') {
const [function_under_test, parameters, expectation] = [
typeof(vector[0]) === 'string' ? eval(vector[0]) : vector[0], vector.slice(1, -1), vector[vector.length - 1] ]
if (trace) {
console.log("Parsed:")
console.log(" method: ", method)
console.log(" fut: ", function_under_test)
console.log(" parameters: ", parameters)
console.log(" expectation: ", expectation)
}
if (!Array.isArray(expectation)) {
method(function_under_test(...parameters), expectation)
} else {
const zipper = '_'
method(function_under_test(...parameters).join(zipper), expectation.join(zipper))
}
} else {
assert.is(false, true, `test vector data problem: ${JSON.stringify(vector)}`)
}
}
}
/**
* Test builder within suites relying on convention to use system under test object as anchor for functions under test.
*
* The test cases must be an array of arrays with only strings as elements.
* The fixture file absolute path must be present as first or only element.
* Optionally a test name can be present as second element in addition - if not the name will be derived from fixture.
*
* @param sut is the object with all incoming functions under test as members
* @param executor is the test suite object
* @param test_cases an array of pairs with the first element the fixture path and the optional second naming the test
* @param options an optional object to pass through for assert and trace modes
*/
const build_tests = (sut, executor, test_cases, options) => {
test_cases.forEach(tc => {
const fixture = tc[0]
const name = tc.length === 2
? tc[1]
: fixture // Derive test name from fixture file name
.split('/') // Mostly works as universal path separator
.pop() // use the last element only (assuming it is the file name
.replace('.json', '') // remove extension from fixture file name, keep the specific part (base)
.replaceAll('_', ' ').split(' ') // prepare title case transform - array of words
.map(s => s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase())
.join(' ') // back to single string
executor(name, () => {
let vectors = require(fixture)
vectors.forEach(e => e[0] = eval(e[0]))
vectors.forEach(process(options))
})
})
return executor
}
module.exports = { process, build_tests }
|