|
function testRandomFunction(props) { |
|
const { randFn, runsPerCycle = 1e5, logProgress = true } = (props || {}); |
|
if (typeof randFn !== "function") { |
|
throw new TypeError("Random Function `randFn` must be a function in order to test"); |
|
} |
|
|
|
const results = {}, startTime = Date.now(), strEllapsed = '', ret = {}; |
|
let stopped = false; |
|
function clog(...args) { |
|
if (logProgress) { |
|
console.log(...args); |
|
} |
|
} |
|
|
|
function getElapsedTime(currTime) { |
|
const hms = [ |
|
[1000,"″","″"],[60,"′","′"],[60,"h","h"] |
|
].reduce((a,c,i,w) => [ |
|
...a, |
|
[w.slice(0,i+1).reduce((_a,_c)=>_a*_c[0],1), ...c.slice(1)] |
|
], []).reverse() |
|
; |
|
return hms |
|
.reduce((a,d) => [ |
|
[...a[0], a[1] / d[0] | 0], a[1] % d[0], [...a[2], [d[1],d[2]] ] |
|
], [[], currTime - startTime, []]) |
|
.map((_,i,x) => [x[0][i], x[2][i][0], x[2][i][1] ] ) |
|
.reduce( |
|
(a,[n,s,p],i,w) => a + ( |
|
(i === w.length - 1) ? " " : (i === 0 ? "" : " ") |
|
) + n + "" + (n === 1 ? s : p) |
|
, "" |
|
) |
|
; |
|
} |
|
|
|
results.count = {}; |
|
results.percent = {}; |
|
results.total = 0; |
|
|
|
ret.results = new Promise((resolve, reject) => { |
|
for (let l1 = 0; l1 <= 99; l1++) { |
|
clog([ |
|
String(l1).padStart(3), "% [", ( |
|
"▓".repeat(l1 / 3 | 0) + |
|
("_░▒".split(""))[ l1 % 3 ] |
|
).padEnd(34, "_"), |
|
"] ", |
|
getElapsedTime(Date.now()) |
|
].join("")); |
|
|
|
if (stopped) { |
|
clog("RandFn Test was stopped"); |
|
return reject(results); |
|
} |
|
|
|
for (let l2=0; l2 <= runsPerCycle; l2++) { |
|
try { |
|
let out = randFn(); |
|
if (results.count[out] == null) { |
|
results.count[out] = 0; |
|
} |
|
results.count[out] += 1; |
|
results.total += 1; |
|
} catch (e) { |
|
clog("randFn failed during test, aborting"); |
|
console.trace(e); |
|
return reject(results); |
|
} |
|
|
|
if (stopped) { |
|
clog("RandFn Test was stopped"); |
|
return reject(results); |
|
} |
|
} |
|
|
|
// end for 1 |
|
} |
|
|
|
clog("RandFn test completed! Results of the test:", results); |
|
resolve(results); |
|
}); |
|
|
|
ret.stopTest = () => { |
|
clog("Requested immediate end of RandFn Test"); |
|
stopped = true; |
|
}; |
|
|
|
Object.entries(results.count).forEach(([key, value]) => { |
|
results.percent[key] = Math.round(value / results.total * 1e5) / 1e3; |
|
}) |
|
|
|
clog(`100% [${'▓'.repeat(34)}] ${strEllapsed}`); |
|
return ret; |
|
} |