saintest
Version:
Lightweight testing framework
7 lines (6 loc) • 7.16 kB
JavaScript
/*!
* saintest v0.2.0 | MIT License
* Copyright (c) 2025-present NOuSantx
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).saintest={})}(this,(function(e){"use strict";const t="[0m",o=e=>`[38;5;${e}m`,r=35,n=203,i=245;function s(e,i){return`\n ${o(r)}+ Expected: ${JSON.stringify(i)}${t}\n ${o(n)}- Received: ${JSON.stringify(e)}${t}`}function a(e){return{toBe(t){if(e!==t)throw new Error(`Expected ${JSON.stringify(e)} to be ${JSON.stringify(t)}${s(e,t)}`)},toEqual(t){if(JSON.stringify(e)!==JSON.stringify(t))throw new Error(`Expected deep equality${s(e,t)}`)},toThrow(t){let o=!1,r=null;try{e()}catch(e){o=!0,r=e}if(!o)throw new Error("Expected function to throw an error");if(t&&r.message!==t)throw new Error(`Expected error message "${t}" but got "${r.message}"`)},toBeGreaterThan(t){if(!(e>t))throw new Error(`Expected ${e} to be greater than ${t}`)},toBeLessThan(t){if(!(e<t))throw new Error(`Expected ${e} to be less than ${t}`)},toContain(t){if(!e.includes(t))throw new Error(`Expected ${JSON.stringify(e)} to contain ${JSON.stringify(t)}`)},toHaveLength(t){if(e.length!==t)throw new Error(`Expected length of ${e.length} to be ${t}`)},toBeInstanceOf(t){if(!(e instanceof t))throw new Error(`Expected ${e} to be instance of ${t.name}`)},toBeTruthy(){if(!e)throw new Error(`Expected ${e} to be truthy`)},toBeFalsy(){if(e)throw new Error(`Expected ${e} to be falsy`)},toBeNull(){if(null!==e)throw new Error(`Expected ${e} to be null`)},toBeUndefined(){if(void 0!==e)throw new Error(`Expected ${e} to be undefined`)},toBeDefined(){if(void 0===e)throw new Error("Expected value to be defined")},toBeNaN(){if(!Number.isNaN(e))throw new Error(`Expected ${e} to be NaN`)},toMatch(t){if(!t.test(e))throw new Error(`Expected ${e} to match ${t}`)},not:{toBe(t){if(e===t)throw new Error(`Expected ${JSON.stringify(e)} not to be ${JSON.stringify(t)}`)},toEqual(t){if(JSON.stringify(e)===JSON.stringify(t))throw new Error(`Expected values not to be deeply equal${s(e,t)}`)},toBeInstanceOf(t){if(e instanceof t)throw new Error(`Expected ${e} not to be instance of ${t.name}`)},toMatch(t){if(t.test(e))throw new Error(`Expected ${e} not to match ${t}`)},toContain(t){if(e.includes(t))throw new Error(`Expected ${JSON.stringify(e)} not to contain ${JSON.stringify(t)}`)},toBeTruthy(){if(e)throw new Error(`Expected ${e} not to be truthy`)},toBeFalsy(){if(!e)throw new Error(`Expected ${e} not to be falsy`)},toBeNull(){if(null===e)throw new Error("Expected value not to be null")},toBeUndefined(){if(void 0===e)throw new Error("Expected value not to be undefined")},toBeDefined(){if(void 0!==e)throw new Error("Expected value to be undefined")},toBeNaN(){if(Number.isNaN(e))throw new Error("Expected value not to be NaN")},toHaveLength(t){if(e.length===t)throw new Error(`Expected length not to be ${t}`)},toBeGreaterThan(t){if(e>t)throw new Error(`Expected ${e} not to be greater than ${t}`)},toBeLessThan(t){if(e<t)throw new Error(`Expected ${e} not to be less than ${t}`)},toHaveProperty(t,o){const r=t.split(".");let n=e;try{for(const e of r)n=n[e];if(void 0===o)throw new Error(`Expected object not to have property "${t}"`);if(n===o)throw new Error(`Expected property "${t}" not to have value ${JSON.stringify(o)}`)}catch(e){return}},toThrow(t){try{e()}catch(e){if(!t)throw new Error("Expected function not to throw an error");if(e.message===t)throw new Error(`Expected function not to throw error "${t}"`)}},toBeCloseTo(t,o=2){const r=Math.pow(10,o);if(Math.round(e*r)===Math.round(t*r))throw new Error(`Expected ${e} not to be close to ${t} with precision of ${o} decimal points`)}},toHaveProperty(t,o){const r=t.split(".");let n=e;for(const e of r){if(!(e in n))throw new Error(`Expected object to have property "${t}"`);n=n[e]}if(void 0!==o&&n!==o)throw new Error(`Expected property "${t}" to have value ${JSON.stringify(o)}, got ${JSON.stringify(n)}`)},toBeCloseTo(t,o=2){const r=Math.pow(10,o);if(Math.round(e*r)!==Math.round(t*r))throw new Error(`Expected ${e} to be close to ${t} with precision of ${o} decimal points`)}}}const c=[],l={name:"Standalone Tests",tests:[],beforeEach:null,afterEach:null,beforeAll:null,afterAll:null};e.currentSuite=null;let f=0,u=0,$=0,h=0;function d(t,o){const r={name:t,tests:[],beforeEach:null,afterEach:null,beforeAll:null,afterAll:null};c.push(r);const n=e.currentSuite;e.currentSuite=r,o(),e.currentSuite=n}function w(t){e.currentSuite?e.currentSuite.beforeEach=t:l.beforeEach=t}function E(t){e.currentSuite?e.currentSuite.afterEach=t:l.afterEach=t}function p(t){e.currentSuite?e.currentSuite.beforeAll=t:l.beforeAll=t}function g(t){e.currentSuite?e.currentSuite.afterAll=t:l.afterAll=t}function b(t,o){const r={name:t,fn:o,skip:!1,only:!1,timeout:100};return e.currentSuite?e.currentSuite.tests.push(r):l.tests.push(r),{skip:()=>{r.skip=!0,$++},only:()=>{r.only=!0},timeout:e=>{r.timeout=e}}}function y(e,t){return b(e,t)}async function x(e,s){if(e.skip)return console.log(` ${o(214)}○${t} ${o(i)}${e.name} [3m(skipped)${t}`),{status:"skipped"};try{s.beforeEach&&await s.beforeEach();const n=Promise.race([Promise.resolve(e.fn()),new Promise(((t,o)=>setTimeout((()=>o(new Error(`Test timed out after ${e.timeout}ms`))),e.timeout)))]);return await n,s.afterEach&&await s.afterEach(),console.log(` ${o(r)}✓${t} ${o(7)}${e.name}${t}`),{status:"passed"}}catch(r){return console.log(` ${o(n)}✗${t} ${o(i)}${e.name}${t}`),console.log(`${o(i)} ${r.message}${t}`),{status:"failed"}}}async function m(e){if(0===e.tests.length)return;let s=0,a=0,c=0;console.log(`\n${o(r)}${e.name}${o(i)} [${e.tests.length} tests]${t}\n`);try{e.beforeAll&&await e.beforeAll();const l=e.tests.filter((e=>e.only)),$=l.length>0?l:e.tests;for(const t of $)switch((await x(t,e)).status){case"passed":s++,f++;break;case"failed":a++,u++;break;case"skipped":c++}e.afterAll&&await e.afterAll();const h=s+a+c,d=(s/(h-c)*100).toFixed(2);console.log("\n Suite Summary:"),console.log(` ${o(r)}${d}%${t} ${o(i)}passing${t}`),console.log(` ${o(r)}${s} passed${t} · ${o(n)}${a} failed${t} · ${o(214)}${c} skipped${t} · ${o(i)}${h} total${t}`)}catch(e){console.error(`${o(n)}Suite Error: ${e.message}${t}`)}}async function S(){h=performance.now(),l.tests.length>0&&await m(l);for(const e of c)await m(e);const e=((performance.now()-h)/1e3).toFixed(3),s=f+u+$,a=(f/(s-$)*100).toFixed(2);(c.length>0||l.tests.length>0)&&(console.log("\nFinal Test Results:"),console.log(`${o(r)}${a}%${t} ${o(i)}of all tests passing${t}`),console.log(`${o(r)}${f} passed${t} · ${o(n)}${u} failed${t} · ${o(214)}${$} skipped${t} · ${o(i)}${s} total${t}`),console.log(`${o(i)}Total Time: ${e}s${t}\n`))}var N={expect:a,it:b,test:y,describe:d,beforeEach:w,afterEach:E,beforeAll:p,afterAll:g,run:S,testSuites:c,defaultSuite:l,currentSuite:e.currentSuite};e.afterAll=g,e.afterEach=E,e.beforeAll=p,e.beforeEach=w,e.default=N,e.defaultSuite=l,e.describe=d,e.expect=a,e.it=b,e.run=S,e.test=y,e.testSuites=c,Object.defineProperty(e,"__esModule",{value:!0})}));
//# sourceMappingURL=index.umd.min.js.map