@moyal/js-test
Version:
A lightweight, dependency-free JavaScript testing utility. This project is framework-agnostic and usable in both browser and Node.js environments.
7 lines (6 loc) • 13.6 kB
JavaScript
/*!
* @moyal/js-test v2.1.7
* (c) 2000–present Ilan Moyal
* Released under the MIT License
*/
"use strict";let e,t,r;class s{static#e=null;static __setup(s,n,i){e=s,t=n,r=i}static getDefaultLogger(){if(null===this.#e)try{"undefined"!=typeof window&&void 0!==window.document||"function"==typeof importScripts&&"undefined"!=typeof self?this.#e=new t:"undefined"!=typeof process&&process.versions?.node?this.#e=new r:this.#e=new e}catch{this.#e=new e}return this.#e}static isLogger(e){return e instanceof s&&Object.getPrototypeOf(e.constructor)===s}#t=new Set(["black","red","green","yellow","blue","magenta","cyan","white","gray","lightred","lightgreen","lightyellow","lightblue","lightmagenta","lightcyan","lightgray"]);isSupportedColor(e){return this.#t.has(e)}normalizeColor(e){return"string"==typeof e?e.toLowerCase():""}log(e,t,...r){}info(e,t,...r){}warn(e,t,...r){}error(e,t,...r){}group(e,t){}groupCollapsed(e,t){}groupEnd(){}}class n{static#r;static{this.#r="undefined"!=typeof performance&&"function"==typeof performance.now?()=>performance.now():()=>Date.now()}static now(){return this.#r()}static isString(e){return"string"==typeof e||"[object String]"===Object.prototype.toString.call(e)}static isIterable(e){return n.isFunctionOrGeneratorFunction(e?.[Symbol.iterator])}static isFunction(e){let t=typeof e;return("object"===t||"function"===t)&&"[object Function]"===Object.prototype.toString.call(e)}static isFunctionOrGeneratorFunction(e){const t=typeof e;if("function"!==t&&"object"!==t)return!1;const r=Object.prototype.toString.call(e);return"[object Function]"===r||"[object GeneratorFunction]"===r}}class i{static*#s(e,t){for(;;)yield e.replace("{0}",t++)}#n=null;#i=null;#o=null;constructor(e,t){if(null!=t&&(!Number.isInteger(t)||t<1))throw new Error("startValue must be a positive integer");this.#n=e??"{0}",this.#i=t??1}reset(){this.#o=i.#s(this.#n,this.#i)}next(){return null==this.#o&&this.reset(),this.#o.next().value}close(){this.#o?.return&&this.#o.return(),this.#o=null}*[Symbol.iterator](){let e=i.#s(this.#n,this.#i);for(let t of e)yield t}}class o extends i{constructor(e=1,t="{0}. "){if(t??="{0}. ",!n.isString(t)||t.indexOf("{0}")<0)throw new Error("Automatic numbering format must include {0}");super(t,e??1)}next(e){return super.next()+(e??"")}}class l{#l="";#u=[];#i=1;constructor(e){this.#i=e??1,this.reset()}reset(){this.#l="",this.#u.length=0,this.#u.push(new o(this.#i,null))}get level(){return this.#u.length}next(e){return this.#l=this.#u[this.#u.length-1].next(),this.#l+(e??"")}nest(e){let t=this.#l.trim();return t+="{0}. ",this.#u.push(new o(e??1,t)),this}unnest(){return this.#u.length>1&&this.#u.pop(),this}}class u{_result=null;_additionalData=null;constructor(e,t){this._result=e,this._additionalData=t}}class a{#a=null;#c=!0;#h=null;#d=null;#g=null;#p=[];#_=0;static#f=null;static __setup(e){this.#f=e}constructor(e,t,r,s){if(!n.isString(e))throw new Error("testName must be string");if(null!=t&&!n.isString(t))throw new Error("successMessage must be string, null or undefined");if(null!=r&&!n.isString(r))throw new Error("failureMessage must be string, null or undefined");this.#a=e,this.#h=t??"success",this.#d=r??"failure",this.#g=s}get name(){return this.#a}get successMessage(){return this.#h}get failureMessage(){return this.#d}get elapsed(){return this.#_}set elapsed(e){this.#_=e}get succeeded(){return this.#c}set succeeded(e){this.#c=!0===e}get failed(){return!0!==this.succeeded}get errors(){return this.#p}get errorCount(){return this.errors.length}get additionalData(){return this.#g}set additionalData(e){this.#g=e}get logger(){return a.#f.logger}run(e,t){return this.runImpl(),(!0===e||!1!==e&&!this.succeeded)&&this.write(t),this.succeeded}runImpl(){throw new Error("Method 'runImpl()' must be implemented by subclass")}_push_error(e){this.#p.push(e)}write(e){null!=e&&e instanceof l||(e=null);const t=this.name?.trim()||"(unnamed test)";let r=`${e?.next()??""}${t}: ${this.succeeded?this.successMessage:this.failureMessage} (${this.elapsed} ms`,s=this.succeeded?"green":"red";if(0===this.errorCount)r+=")";else{let e=(this.succeeded?"":"un")+"expected "+(this.errorCount>1?"errors":"error");r+=`, ${this.errorCount} ${e})`}if(0!=this.errorCount||null!=this.additionalData){if(this.logger.groupCollapsed(r,s),this.errorCount>0){null!=this.additionalData&&this.logger.groupCollapsed("errors");for(let e of this.errors)this.succeeded?this.logger.error(e,"black"):this.logger.error(e);null!=this.additionalData&&this.logger.groupEnd()}null!=this.additionalData&&(this.errorCount>0&&this.logger.groupCollapsed("additional data"),this.logger.log(JSON.stringify(this.additionalData)),this.errorCount>0&&this.logger.groupEnd()),this.logger.groupEnd()}else this.logger.log(r,s)}}class c extends a{#f=null;#w=null;constructor(e,t,r,s,n,i){super(e,r,s,n),this.#f=t,this.#w=i??globalThis}runImpl(){if(!0===this.#f)this.succeeded=!0;else if(n.isFunction(this.#f)){let e;const t=n.now();try{let t=this.#f.call(this.#w);t instanceof u?(this.additionalData=t._additionalData,e=!0===t._result):e=t}catch(t){this._push_error(t),e=!1}const r=n.now();this.elapsed=r-t,this.succeeded=e}else this.succeeded=!1;return this.succeeded}}class h extends c{#x=null;#w=null;#m=!0;constructor(e,t,r,s,i){if(super(e,r,(t=!0===t)?"An error was thrown (as expected)!":"An error was NOT thrown (as expected).",t?"Expected an error, but none was thrown or it did not satisfy the predicate.":"An error was not thrown (unexpectedly).",i),!n.isFunction(r))throw new Error("fn parameter must be a function");if(t&&null!=s&&!n.isFunction(s))throw new Error("checkErrorFn parameter must be a function, null or undefined");this.#m=t,this.#w=i,this.#x=s}runImpl(){super.runImpl();super.succeeded||1!==this.errors.length?this.succeeded=!this.#m:this.succeeded=this.#m&&(null==this.#x||!0===this.#x.call(this.#w,this.errors[0]))}}class d extends c{constructor(e,t,r,s,i){let o,l=null;n.isFunction(t)||n.isFunction(r)||n.isFunction(s)?o=()=>{let e=n.isFunction(t)?t.call(i??globalThis):t,o=n.isFunction(r)?r.call(i??globalThis):r;return new u(n.isFunction(s)?s.call(i??globalThis,e,o):e===o,{expected:e,actual:o})}:(o=t===r,l={expected:t,actual:r}),super(e,o,"Expected and actual values matched","Expected and actual values did not match",l,i)}}class g extends c{constructor(e,t,r,s,i){let o,l=null;n.isFunction(t)||n.isFunction(r)||n.isFunction(s)?o=()=>{let e=n.isFunction(t)?t.call(i??globalThis):t,o=n.isFunction(r)?r.call(i??globalThis):r;return new u(n.isFunction(s)?!s.call(i??globalThis,e,o):e!==o,{not_expected:e,actual:o})}:(o=t!==r,l={not_expected:t,actual:r}),super(e,o,"Actual value did not match the disallowed value (as expected!)","Actual value matched the disallowed value (not as expected!)",l,i)}}class p extends g{constructor(e,t,r){super(e,void 0,t,null,r)}}class _ extends d{constructor(e,t,r){super(e,!1,t,null,r)}}class f extends g{constructor(e,t,r){super(e,null,t,null,r)}}class w extends d{constructor(e,t,r){super(e,null,t,null,r)}}class x extends d{constructor(e,t,r){super(e,!0,t,null,r)}}class m extends d{constructor(e,t,r){super(e,void 0,t,null,r)}}class C extends h{constructor(e,t,r){super(e,!1,t,null,r)}}class F extends a{#m=null;#C=null;#F=null;#E=!0;#w=null;constructor(e,t,r,s,i){super(e,"Actual sequence equals to the expected sequence","Actual sequence does not equal to the expected sequence)",null,i),this.additionalData={},this.#m=t,this.#C=r,this.#F=s,this.#w=i,n.isIterable(t)||(this.additionalData.expected="ERROR: 'expected' argument is not iterable!",this.#E=!1),n.isIterable(r)||(this.additionalData.actual="ERROR: 'actual' argument is not iterable!",this.#E=!1)}runImpl(){if(this.#E){const t=n.now();let r,s=this.additionalData.expected=Array.from(this.#m),i=this.additionalData.actual=Array.from(this.#C);if(s.length===i.length){let t=[];for(var e=0;e<s.length;e++){!0!==(null!=this.#F?this.#F.call(this.#w??void 0,s[e],i[e]):s[e]===i[e])&&t.push(e)}t.length>0&&(this.additionalData["Mismatch at indices"]="Different element indices are: {"+t.join(", ")+"}"),r=0===t.length}else this.additionalData["Mismatch at indices"]="expected.length !== actual.length",r=!1;const o=n.now();this.elapsed=o-t,this.succeeded=r}else this.succeeded=!1}}class E extends h{constructor(e,t,r,s){super(e,!0,t,r,s)}}class b extends a{#b=[];#y=0;#v=0;#D=0;#$=0;#A=null;#S=null;constructor(e,...t){super(e),this.add(...t)}clear(){this.#b.length=0,this.#y=0,this.#v=0,this.#D=0,this.#$=0}get errorCount(){return this.#D}run(e,t){return this.#S=e,super.run(e,t)}runImpl(){this.#y=0,this.#D=0,this.#$=0;const e=n.now();for(let e of this.#b)e.runImpl(),e instanceof b?(this.#v+=e.totalFailureCount,this.#$+=e.unexpectedErrorCount):(this.#y+=e.succeeded?0:1,this.#$+=e.succeeded?0:e.errorCount,this.#v+=e.succeeded?0:1),this.#D+=e.errorCount;const t=n.now();return this.elapsed=t-e,0===this.#y}write(e,t){null!=e&&e instanceof l||(e=null);const r=null==t?this.#S:t;let s,n=`${e?.next()??""}${this.name}: (${this.elapsed}ms, `;if(this.succeeded?(s="green",n+="all passed"):(s="red",n+=`${0==this.#y?"no":this.#y.toString()} direct failure${1===this.#y?"":"s"}, ${this.#v} total failure${1===this.#v?"":"s"}`),this.#$>0&&(n+=`, ${this.#$} unexpected error${this.#$>1?"s":""}`),n+=")",this.succeeded?this.logger.groupCollapsed(n,s):this.logger.group(n,s),this.#b?.length>0){e?.nest();for(let t of this.#b)(!0===r||null==r&&!t.succeeded)&&t.write(e,this.#S);e?.unnest()}this.logger.groupEnd()}get unexpectedErrorCount(){return this.#$}get directFailureCount(){return this.#y}get totalFailureCount(){return this.#v}get succeeded(){return 0===this.#v}add(...e){this.#b.push(...e);for(let t of e)t instanceof b&&(t.#A=this)}groupStart(e){let t=new b(e);return this.add(t),t}groupClose(){return this.#A??this}areEqual(e,t,r,s,n){return this.add(new d(e,t,r,s,n)),this}areNotEqual(e,t,r,s,n){return this.add(new g(e,t,r,s,n)),this}isTrue(e,t,r=null){return this.add(new x(e,t,r)),this}isFalse(e,t,r){return this.add(new _(e,t,r)),this}isNull(e,t,r){return this.add(new w(e,t,r)),this}isNotNull(e,t,r=null){return this.add(new f(e,t,r)),this}isDefined(e,t,r=null){return this.add(new p(e,t,r)),this}isUndefined(e,t,r=null){return this.add(new m(e,t,r)),this}throws(e,t,r,s=null){return this.add(new E(e,t,r,s)),this}noThrows(e,t,r=null){return this.add(new C(e,t,r)),this}sequencesAreEqual(e,t,r,s){return this.add(new F(e,t,r,s)),this}}class y extends s{#I=0;#L="";#N(){this.#I++,this.#L=" ".repeat(this.#I)}#T(){this.#I--,this.#I<0&&(this.#I=0),this.#L=" ".repeat(this.#I)}prefixMessage(e){return this.#L+e}colorfy(e,t,r){return e}log(e,t,...r){return e??="",console.log(this.colorfy(this.prefixMessage(e),t,"white"),...r),this}info(e,t,...r){return e??="",console.info(this.colorfy(this.prefixMessage(e),t,"cyan"),...r),this}warn(e,t,...r){return e??="",console.warn(this.colorfy(this.prefixMessage(e),t,"yellow"),...r),this}error(e,t,...r){return e??="",console.error(this.colorfy(this.prefixMessage(e),t,"red"),...r),this}#q(e,t){e??="",console.log(this.colorfy(this.prefixMessage(`▼ ${e}`),t,"gray")),this.#N()}group(e,t){return this.#q(e,t),this}groupCollapsed(e,t){return this.#q(e,t),this}groupEnd(){return this.#T(),this}}class v extends s{#M(e){return e=this.normalizeColor(e),this.isSupportedColor(e)?e:void 0}log(e,t,...r){return e??="",console.log(`%c${e}`,`color:${this.#M(t)??"inherit"}`,...r),this}info(e,t,...r){return e??="",console.info(`%c${e}`,`color:${this.#M(t)??"blue"}`,...r),this}warn(e,t,...r){return e??="",console.warn(`%c${e}`,`color:${this.#M(t)??"orange"}`,...r),this}error(e,t,...r){return e??="",console.error(`%c${e}`,`color:${this.#M(t)??"red"}`,...r),this}group(e,t){return console.group(`%c${e}`,`color:${this.#M(t)??"inherit"}`),this}groupCollapsed(e,t){return console.groupCollapsed(`%c${e}`,`color:${this.#M(t)??"inherit"}`),this}groupEnd(){return console.groupEnd(),this}}class D extends y{#z(e,t){return({black:"[30m",red:"[31m",green:"[32m",yellow:"[33m",blue:"[34m",magenta:"[35m",cyan:"[36m",white:"[37m",gray:"[90m",lightred:"[91m",lightgreen:"[92m",lightyellow:"[93m",lightblue:"[94m",lightmagenta:"[95m",lightcyan:"[96m",lightgray:"[97m"}[e=this.normalizeColor(e)]??"")+t+"[0m"}colorfy(e,t,r){return this.#z(t?.toLowerCase()??r,e)}}s.__setup(y,v,D);class ${static version="2.1.7"}class A{static#O=null;static get Version(){return $.version}static get logger(){return null==this.#O&&(this.#O=s.getDefaultLogger()),this.#O}static set logger(e){null==e?this.#O=s.getDefaultLogger():s.isLogger(e)&&(this.#O=e)}static areEqual(e,t,r,s,n){return new d(e,t,r,s).run(n)}static areNotEqual(e,t,r,s,n){return new g(e,t,r,s).run(n)}static isTrue(e,t,r){return new x(e,t).run(r)}static isFalse(e,t,r){return new _(e,t).run(r)}static isNull(e,t,r){return new w(e,t).run(r)}static isNotNull(e,t,r){return new f(e,t).run(r)}static isDefined(e,t,r){return new p(e,t).run(r)}static isUndefined(e,t,r){return new m(e,t).run(r)}static throws(e,t,r,s,n){return new E(e,t,r,s).run(n)}static noThrows(e,t,r,s){return new C(e,t,r).run(s)}static sequencesAreEqual(e,t,r,s,n){return new F(e,t,r,s).run(n)}}a.__setup(A),exports.AreEqual=d,exports.AreNotEqual=g,exports.Assert=c,exports.AutoNumbering=o,exports.BrowserLogger=v,exports.IsDefined=p,exports.IsFalse=_,exports.IsNotNull=f,exports.IsNull=w,exports.IsTrue=x,exports.IsUndefined=m,exports.LoggerBase=s,exports.MultiLevelAutoNumbering=l,exports.NoThrows=C,exports.NodeLogger=D,exports.SequencesAreEqual=F,exports.SequentialText=i,exports.SimpleLogger=y,exports.Test=A,exports.TestBase=a,exports.TestGroup=b,exports.Throws=E,exports.ThrowsBase=h;