added modifier chain (fuzzing) support...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2025-12-26 03:19:15 +03:00
parent 832af19dfa
commit 5624805518
3 changed files with 61 additions and 35 deletions

6
package-lock.json generated
View File

@ -1,15 +1,15 @@
{ {
"name": "ig-test", "name": "ig-test",
"version": "1.4.8", "version": "1.5.9",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ig-test", "name": "ig-test",
"version": "1.4.8", "version": "1.5.9",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"dependencies": { "dependencies": {
"colors": "^1.4.0", "colors": "1.4.0",
"glob": "^7.1.6", "glob": "^7.1.6",
"ig-argv": "^2.16.3", "ig-argv": "^2.16.3",
"ig-object": "^5.4.16" "ig-object": "^5.4.16"

View File

@ -1,6 +1,6 @@
{ {
"name": "ig-test", "name": "ig-test",
"version": "1.5.9", "version": "1.6.0",
"description": "experimental test runner....", "description": "experimental test runner....",
"main": "test.js", "main": "test.js",
"bin": { "bin": {

88
test.js
View File

@ -603,7 +603,7 @@ module.merge =
// ...if not then need to cleanup run(..) to use TestSet / BASE_TEST_SET... // ...if not then need to cleanup run(..) to use TestSet / BASE_TEST_SET...
var runner = var runner =
module.runner = module.runner =
async function(spec, chain, stats){ async function(spec, chain, stats, mod_chain_length=1){
// parse chain... // parse chain...
chain = (chain == '*' || chain == null) ? chain = (chain == '*' || chain == null) ?
[] []
@ -639,31 +639,48 @@ async function(spec, chain, stats){
var started = Date.now() var started = Date.now()
// tests... // tests...
var test_queue =
object.deepKeys(tests)
.filter(function(t, i, l){
return typeof(tests[t]) == 'function'
// skip blank tests if we have other tests unless
// explicitly specified...
&& ((t == '-'
&& test != t
&& l.length > 1) ?
false
: (test == '*'
|| test == t) ) })
if(mod_chain_length <= 0){
var mod_queue = []
} else {
var mod_queue = object.deepKeys(modifiers)
.filter(function(m){
return typeof(modifiers[m]) == 'function'
&& (mod == '*' || mod == m) })
.map(function(m){
return [m] })
// modifier chains...
for(var i=1; i < mod_chain_length; i++){
mod_queue = [
...mod_queue,
...mod_queue
.map(function(m){
return mod_queue
.map(function(mm){
return [...m, ...mm] }) })
.flat()] } }
var setup_queue = object.deepKeys(setups)
.filter(function(s){
return typeof(setups[s]) == 'function'
&& (setup == '*' || setup == s) })
var queue = var queue =
chain_length != 1 ? chain_length != 1 ?
object.deepKeys(tests) test_queue
.filter(function(t, i, l){
return typeof(tests[t]) == 'function'
// skip blank tests if we have other tests unless
// explicitly specified...
&& ((t == '-'
&& test != t
&& l.length > 1) ?
false
: (test == '*'
|| test == t) ) })
.map(function(t){ .map(function(t){
// modifiers... return mod_queue
return object.deepKeys(modifiers)
.filter(function(m){
return typeof(modifiers[m]) == 'function'
&& (mod == '*' || mod == m) })
.map(function(m){ .map(function(m){
// setups... return setup_queue
return object.deepKeys(setups)
.filter(function(s){
return typeof(setups[s]) == 'function'
&& (setup == '*' || setup == s) })
.map(function(s){ .map(function(s){
return [s, m, t] }) }) }) return [s, m, t] }) }) })
.flat(2) .flat(2)
@ -675,16 +692,15 @@ async function(spec, chain, stats){
// run the test... // run the test...
stats.tests += 1 stats.tests += 1
var _assert = assert.push( var _assert = assert.push(
[s, m, t] [s, ...m, t]
// do not print blank pass-through ('-') // do not print blank pass-through ('-')
// components... // components...
.filter(function(e){ .filter(function(e){
return e != '-' }) ) return e != '-' }) )
await tests[t]( var d = await setups[s](_assert)
_assert, for(var mod of m){
await modifiers[m]( d = await modifiers[mod](_assert, d) }
_assert, await tests[t](_assert, d) }
await setups[s](_assert))) }
// cases... // cases...
var queue = var queue =
@ -854,6 +870,16 @@ argv.Parser({
process.exit() }}, process.exit() }},
mod_chain_length: 1,
'-m': '-max-modifier-chain',
'-max-modifier-chain': {
doc: 'Maximum number of modifiers to use in chain',
arg: 'NUMBER | mod_chain_length',
default: function(){
return this.mod_chain_length },
},
// queue files/patterns... // queue files/patterns...
// XXX should this energetically load modules (current) or queue // XXX should this energetically load modules (current) or queue
// them for later loading (on .then(..))... // them for later loading (on .then(..))...
@ -911,7 +937,6 @@ argv.Parser({
//that.loadModule(path) }) }) }}, //that.loadModule(path) }) }) }},
that.queueModule(path) }) }) }}, that.queueModule(path) }) }) }},
// ignore paths... // ignore paths...
ignore_files: undefined, ignore_files: undefined,
@ -1003,16 +1028,17 @@ function(default_files, tests){
default_files: default_files, default_files: default_files,
}) })
return p return p
// XXX should this be generic??? // XXX should this be generic???
.then(async function(chains){ .then(async function(chains){
// run the tests... // run the tests...
if(chains.length > 0){ if(chains.length > 0){
for(var chain of chains){ for(var chain of chains){
await runner(tests, chain, stats) } await runner(tests, chain, stats, this.mod_chain_length) }
//await module.BASE_TEST_SET(tests, chain, stats) } //await module.BASE_TEST_SET(tests, chain, stats) }
} else { } else {
await runner(tests, '*', stats) } await runner(tests, '*', stats, this.mod_chain_length) }
//await module.BASE_TEST_SET(tests, '*', stats) } //await module.BASE_TEST_SET(tests, '*', stats) }
// XXX BUG for some reason we can get here BEFORE all the // XXX BUG for some reason we can get here BEFORE all the