Created
November 3, 2022 17:46
-
-
Save 4141done/f7805d8049bbe70bba778453e662eb70 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import testFramework from "./ujest.mjs"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* micro-Jest testing framework | |
* written by Minkyu lee (@niklauslee) | |
*/ | |
var tests = []; | |
var finished = []; | |
var timer = null; | |
function test(name, fn) { | |
tests.push({ | |
name: name, | |
fn: fn, | |
state: 0, // 0=idle, 1=runs, 2=pass, 3=fail | |
assertFail: 0, | |
}); | |
} | |
function error(msg) { | |
console.log(`\x1b[91m[Error] ${msg}\x1b[0m`); | |
} | |
function expect(v1) { | |
var matchers = { | |
toBe: function (v2) { | |
if (!Object.is(v1, v2)) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify(v2)} expected, but ${JSON.stringify(v1)} received` | |
); | |
} | |
}, | |
notToBe: function (v2) { | |
if (Object.is(v1, v2)) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify(v2)} not expected, but ${JSON.stringify( | |
v1 | |
)} received` | |
); | |
} | |
}, | |
toBeTruthy: function () { | |
if (!v1) { | |
tests[0].assertFail++; | |
error(`Truthy expected, but falsy (${JSON.stringify(v1)}) received`); | |
} | |
}, | |
toBeFalsy: function () { | |
if (v1) { | |
tests[0].assertFail++; | |
error(`Falsy expected, but truthy (${JSON.stringify(v1)}) received`); | |
} | |
}, | |
}; | |
if (Array.isArray(v1)) { | |
matchers = Object.assign(matchers, { | |
toContain: function (v2) { | |
if (v1.indexOf(v2) < 0) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify(v1)} expected to contain ${JSON.stringify( | |
v2 | |
)}, but not contained` | |
); | |
} | |
}, | |
notToContain: function (v2) { | |
if (v1.indexOf(v2) >= 0) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify(v1)} expected not to contain ${JSON.stringify( | |
v2 | |
)}, but contained` | |
); | |
} | |
}, | |
}); | |
} | |
if (typeof v1 === "number") { | |
matchers = Object.assign(matchers, { | |
toBeGreaterThan: function (v2) { | |
if (v1 <= v2) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify(v1)} expected to be greater than ${JSON.stringify( | |
v2 | |
)}, but not greater` | |
); | |
} | |
}, | |
toBeGreaterThanOrEqual: function (v2) { | |
if (v1 < v2) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify( | |
v1 | |
)} expected to be greater than or equal to ${JSON.stringify( | |
v2 | |
)}, but less` | |
); | |
} | |
}, | |
toBeLessThan: function (v2) { | |
if (v1 >= v2) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify(v1)} expected to be less than ${JSON.stringify( | |
v2 | |
)}, but not less` | |
); | |
} | |
}, | |
toBeLessThanOrEqual: function (v2) { | |
if (v1 > v2) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify( | |
v1 | |
)} expected to be less than or equal to ${JSON.stringify( | |
v2 | |
)}, but greater` | |
); | |
} | |
}, | |
}); | |
} | |
if (typeof v1 === "string") { | |
matchers = Object.assign(matchers, { | |
toMatch: function (v2) { | |
// v2 should be regex | |
if (!v1.match(v2)) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify( | |
v1 | |
)} expected to match ${v2.toString()}, but not matched` | |
); | |
} | |
}, | |
notToMatch: function (v2) { | |
// v2 should be regex | |
if (v1.match(v2)) { | |
tests[0].assertFail++; | |
error( | |
`${JSON.stringify( | |
v1 | |
)} not expected to match ${v2.toString()}, but matched` | |
); | |
} | |
}, | |
}); | |
} | |
if (typeof v1 === "function") { | |
matchers = Object.assign(matchers, { | |
toThrow: function (v2) { | |
try { | |
v1(); | |
tests[0].assertFail++; | |
error(`function expected to throw error, but not thrown`); | |
} catch (err) { | |
if (typeof v2 === "string") { | |
if (err.message !== v2) { | |
tests[0].assertFail++; | |
error( | |
`function expected to throw error with message "${v2}", but thrown with message "${err.message}"` | |
); | |
} | |
} | |
} | |
}, | |
notToThrow: function (v2) { | |
try { | |
v1(); | |
} catch (err) { | |
tests[0].assertFail++; | |
error(`function expected not to throw error, but thrown`); | |
} | |
}, | |
}); | |
} | |
return matchers; | |
} | |
/** | |
* Start all tests. If idx given, only the idx-th test to be performed | |
* @param {number} idx | |
*/ | |
function start(idx) { | |
if (typeof idx === "number") { | |
var _t = tests[idx]; | |
tests = [_t]; | |
} | |
timer = setInterval(() => { | |
if (tests.length > 0) { | |
var t = tests[0]; | |
if (t.state === 0) { | |
// idle | |
t.state = 1; | |
print(`\r\x1b[97;43m RUNS \x1b[0m ${t.name}`); | |
try { | |
t.fn((err) => { | |
if (err) { | |
t.state = 3; | |
error(err.toString()); | |
} else { | |
t.state = t.assertFail === 0 ? 2 : 3; | |
} | |
}); | |
} catch (e) { | |
t.state = 3; | |
console.log(e); | |
} | |
} else if (t.state === 2) { | |
// pass | |
print(`\x1b[2K\r\x1b[97;102m PASS \x1b[0m ${t.name}\r\n`); | |
finished.push(tests.shift()); | |
} else if (t.state === 3) { | |
// fail | |
print( | |
`\x1b[2K\r\x1b[97;101m FAIL \x1b[0m\x1b[91m ${t.name}\x1b[0m\r\n` | |
); | |
finished.push(tests.shift()); | |
} | |
} else { | |
clearInterval(timer); | |
console.log(""); | |
var l = finished.length; | |
var f = finished.filter((ts) => ts.state === 3).length; | |
var p = l - f; | |
console.log(`Tests: ${p} passed, ${f} failed (${l} total)`); | |
} | |
}, 10); | |
} | |
export default { test, expect, start }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment