under-the-sun
Version:
A nothing-new-under-the-sun testing framework.
22 lines (19 loc) • 6.91 kB
JavaScript
;var W=Object.create;var y=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,H=Object.prototype.hasOwnProperty;var K=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of J(t))!H.call(e,r)&&r!==o&&y(e,r,{get:()=>t[r],enumerable:!(n=z(t,r))||n.enumerable});return e};var c=(e,t,o)=>(o=e!=null?W(Q(e)):{},K(t||!e||!e.__esModule?y(o,"default",{value:e,enumerable:!0}):o,e));function T(e){try{return V(e)}catch(t){throw console.error(b),t}}function V(e){let t={dir:".",mode:"dynamic",importBase:".",ignoreRegex:/(^|\/)(node_modules($|\/)|\.)/,testFilePathRegex1:/\.(spec|test)\.[mc]?[jt]sx?$/,testFilePathRegex2:/.*/,testDescriptionRegex:/.*/,magicGlobals:!1,modulesToLoad:[],serial:!1},o=e.slice(2),n=0,r=()=>{let i=o.shift();switch(i){case"-h":case"--help":console.log(b),process.exit(2);return;case"-i":case"--ignore":{let s=o.shift();if(!s)throw new Error("-i/--ignore requires an argument");t.ignoreRegex=new RegExp(s);return}case"--print-imports":t.mode="imports";return;case"--import-base":{let s=o.shift();if(!s)throw new Error("--import-base requires an argument");t.importBase=s;return}case"-m":case"--magic":t.magicGlobals=!0;return;case"-p":case"--pattern":{let s=o.shift();if(!s)throw new Error("-p/--pattern requires an argument");t.testFilePathRegex1=new RegExp(s);return}case"-r":case"--require":{let s=o.shift();if(!s)throw new Error("-r requires an argument");t.modulesToLoad.push(s);return}case"-s":case"--serial":t.serial=!0;return}if(i.startsWith("-"))throw i.includes("=")?new Error(`Unrecognized option ${i}. (This tool does not support \`--some-arg=some-value\`-style options. Use \`--some-arg some-value\` instead.)`):new Error(`Unrecognized option ${i}`);switch(n++,n){case 1:t.dir=i;return;case 2:t.testFilePathRegex2=new RegExp(i);return;case 3:t.testDescriptionRegex=new RegExp(i);return}throw new Error(`Too many arguments, starting with ${i}`)};for(;o.length>0;)r();return t}var b=`
Usage:
under-the-sun [-r <module>] [-m] [-s] [-p <file pattern>]
[<dir> [<file filter> [<description filter>]]]
Parameters:
<dir> Directory in which to find tests
<file filter> Regex pattern for matching test file names,
applied *in addition to* -p/--pattern
<description filter> Regex pattern for matching test descriptions
Options:
--import-base Change base of import paths with --print-imports [string]
--magic, -m Make "test" available as a global [boolean]
--pattern, -p Regex pattern for matching test files [string]
--print-imports Print imports to test files instead of running [boolean]
--require, -r Preload the specified module at startup [string]
--serial, -s Run tests sequentially, not in parallel [boolean]
`;var S=c(require("node:fs/promises")),P=c(require("node:path"));async function g({dir:e,ignorePattern:t},o){let n=await S.default.readdir(e,{withFileTypes:!0});await Promise.allSettled(n.sort((r,i)=>r.name.localeCompare(i.name)).map(r=>{let i=P.default.posix.join(e,r.name);if(!t.test(i))return r.isDirectory()?g({dir:i,ignorePattern:t},o):o(i)}))}async function p(e,t){function o(n){return e.testFilePathRegex1.test(n)&&e.testFilePathRegex2.test(n)}await g({dir:e.dir,ignorePattern:e.ignoreRegex},async n=>{o(n)&&await t(n)})}async function k(e){function t(r,i){return i?`${e.importBase}/${r}`:r}function o(r,i=!0){return`import "${t(r,i)}"`}let n=[];for(let r of e.modulesToLoad)console.log(o(r,/^\.{1,2}\//.test(r)));e.magicGlobals&&(console.log('import "under-the-sun/configure/magic-globals"'),console.log('import "under-the-sun"')),e.serial&&console.log('import "under-the-sun/configure/serial-scheduler"'),await p(e,r=>{n.push(r)}),console.log(n.sort((r,i)=>r.localeCompare(i)).map(r=>o(r)).join(`
`))}function E(e){e().then(()=>{},t=>{console.error(t),process.exit(1)})}var R=require("node:perf_hooks");var d=require("perf_hooks");function G(){let e=d.performance.now(),t=0,o=0;return{reportResult(n,r){if(!r.error){t++;return}o++,F("FAIL: "+n),console.error(r.error.stack??r.error.message),console.error()},reportFinish(){let n=t+o,r=d.performance.now()-e,i=`${t}/${n} tests passed (${Math.ceil(r)}ms)`;(o>0?F:X)(i)}}}function F(e){console.error("\x1B[31m%s\x1B[0m",e)}function X(e){console.info("\x1B[32m%s\x1B[0m",e)}var v=global??window??{},A=Symbol.for("__UTS_G__"),u=v[A]=v[A]??{};var l=u.options=u.options??{};function D(){return{schedule(e){return e.run()}}}function m(){let e=Promise.resolve({runtimeMs:0,error:null});return{schedule(t){return e=e.then(async()=>t.run()),e}}}function C(e){l.customTestScheduler=e}function L(){return l.serial?m():D()}function Y(){return{testsRunning:[],reporter:l.customTestReporter??G(),finalReportScheduled:!1,scheduler:l.customTestScheduler??L(),filterByDescription:/.*/}}var h;function a(){return h||(h=u.state=Y()),h}function Z(){return new Promise(e=>{setTimeout(e,1)})}async function ee(){await Z();let e=a(),t=[];for(;t.length<e.testsRunning.length;)t=await Promise.allSettled(e.testsRunning);return t}async function te(){return!(await ee()).some(t=>t.status==="rejected"||t.value?.error)}async function re(){let e=a();e.finalReportScheduled=!0;try{return await te()}finally{e.reporter.reportFinish?.()}}function I(){a().finalReportScheduled||re().then(t=>{process.exit(t?0:1)},t=>{console.error(t)})}function M(e){let t=a();t.testsRunning!==null&&t.filterByDescription.test(e.description)&&t.testsRunning.push(t.scheduler.schedule(e)),I()}function w(e){return e instanceof Error?e:new Error(JSON.stringify(e))}async function $(e){try{return await e(),null}catch(t){return w(t)}}function x(e,t){M({description:e,run:async()=>{let n=R.performance.now(),r=await $(t),s={runtimeMs:R.performance.now()-n,error:r};return await a().reporter.reportResult(e,s),s}})}function q(e){return(t,o)=>x(e+t,o)}function _(){let e=global;e.test=x,e.defineTestGroup=q}var U=c(require("node:path"));var O=c(require("node:path")),B=O.default.relative(__dirname,process.cwd()).replace(/\\/g,"/");async function f(e,t=!0){return ie(oe(e,t))}function oe(e,t){return t?U.default.posix.join(B,e):e}async function ie(e){try{require(e)}catch(t){if(t instanceof Error&&t.code==="ERR_REQUIRE_ESM")await ne(e);else throw t}}var ne=e=>new Function(`return import(${JSON.stringify(e)})`).call(0);async function j(e){for(let t of e)await f(t,/^\.{1,2}\//.test(t))}function se(e){a().filterByDescription=e.testDescriptionRegex,e.serial&&C(m()),e.magicGlobals&&_()}async function N(e){await j(e.modulesToLoad),se(e),await p(e,async t=>{try{let o=f(t,!0).then(()=>null);a().testsRunning.push(o),await o}catch(o){await a().reporter.reportResult(t,{runtimeMs:0,error:w(o)})}})}E(async()=>{let e=T(process.argv);if(e.mode==="imports"){await k(e);return}await N(e)});