🎉 initiate project *astro_rewrite*

This commit is contained in:
sindrekjelsrud 2023-07-19 21:31:30 +02:00
parent ffd4d5e86c
commit 2ba37bfbe3
8658 changed files with 2268794 additions and 2538 deletions

47
node_modules/uvu/assert/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,47 @@
type Types = 'string' | 'number' | 'boolean' | 'object' | 'undefined' | 'function';
export type Message = string | Error;
export function ok(actual: any, msg?: Message): asserts actual;
export function is(actual: any, expects: any, msg?: Message): void;
export function equal(actual: any, expects: any, msg?: Message): void;
export function type(actual: any, expects: Types, msg?: Message): void;
export function instance(actual: any, expects: any, msg?: Message): void;
export function snapshot(actual: string, expects: string, msg?: Message): void;
export function fixture(actual: string, expects: string, msg?: Message): void;
export function match(actual: string, expects: string | RegExp, msg?: Message): void;
export function throws(fn: Function, expects?: Message | RegExp | Function, msg?: Message): void;
export function not(actual: any, msg?: Message): void;
export function unreachable(msg?: Message): void;
export namespace is {
function not(actual: any, expects: any, msg?: Message): void;
}
export namespace not {
function ok(actual: any, msg?: Message): void;
function equal(actual: any, expects: any, msg?: Message): void;
function type(actual: any, expects: Types, msg?: Message): void;
function instance(actual: any, expects: any, msg?: Message): void;
function snapshot(actual: string, expects: string, msg?: Message): void;
function fixture(actual: string, expects: string, msg?: Message): void;
function match(actual: string, expects: string | RegExp, msg?: Message): void;
function throws(fn: Function, expects?: Message | RegExp | Function, msg?: Message): void;
}
export class Assertion extends Error {
name: 'Assertion';
code: 'ERR_ASSERTION';
details: false | string;
generated: boolean;
operator: string;
expects: any;
actual: any;
constructor(options?: {
message: string;
details?: string;
generated?: boolean;
operator: string;
expects: any;
actual: any;
});
}

173
node_modules/uvu/assert/index.js generated vendored Normal file
View file

@ -0,0 +1,173 @@
const { dequal } = require('dequal');
const { compare, lines } = require('uvu/diff');
function dedent(str) {
str = str.replace(/\r?\n/g, '\n');
let arr = str.match(/^[ \t]*(?=\S)/gm);
let i = 0, min = 1/0, len = (arr||[]).length;
for (; i < len; i++) min = Math.min(min, arr[i].length);
return len && min ? str.replace(new RegExp(`^[ \\t]{${min}}`, 'gm'), '') : str;
}
class Assertion extends Error {
constructor(opts={}) {
super(opts.message);
this.name = 'Assertion';
this.code = 'ERR_ASSERTION';
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
this.details = opts.details || false;
this.generated = !!opts.generated;
this.operator = opts.operator;
this.expects = opts.expects;
this.actual = opts.actual;
}
}
function assert(bool, actual, expects, operator, detailer, backup, msg) {
if (bool) return;
let message = msg || backup;
if (msg instanceof Error) throw msg;
let details = detailer && detailer(actual, expects);
throw new Assertion({ actual, expects, operator, message, details, generated: !msg });
}
function ok(val, msg) {
assert(!!val, false, true, 'ok', false, 'Expected value to be truthy', msg);
}
function is(val, exp, msg) {
assert(val === exp, val, exp, 'is', compare, 'Expected values to be strictly equal:', msg);
}
function equal(val, exp, msg) {
assert(dequal(val, exp), val, exp, 'equal', compare, 'Expected values to be deeply equal:', msg);
}
function unreachable(msg) {
assert(false, true, false, 'unreachable', false, 'Expected not to be reached!', msg);
}
function type(val, exp, msg) {
let tmp = typeof val;
assert(tmp === exp, tmp, exp, 'type', false, `Expected "${tmp}" to be "${exp}"`, msg);
}
function instance(val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(val instanceof exp, val, exp, 'instance', false, `Expected value to be an instance of ${name}`, msg);
}
function match(val, exp, msg) {
if (typeof exp === 'string') {
assert(val.includes(exp), val, exp, 'match', false, `Expected value to include "${exp}" substring`, msg);
} else {
assert(exp.test(val), val, exp, 'match', false, `Expected value to match \`${String(exp)}\` pattern`, msg);
}
}
function snapshot(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'snapshot', lines, 'Expected value to match snapshot:', msg);
}
const lineNums = (x, y) => lines(x, y, 1);
function fixture(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'fixture', lineNums, 'Expected value to match fixture:', msg);
}
function throws(blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
assert(false, false, true, 'throws', false, 'Expected function to throw', msg);
} catch (err) {
if (err instanceof Assertion) throw err;
if (typeof exp === 'function') {
assert(exp(err), false, true, 'throws', false, 'Expected function to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(exp.test(err.message), false, true, 'throws', false, `Expected function to throw exception matching \`${String(exp)}\` pattern`, msg);
}
}
}
// ---
function not(val, msg) {
assert(!val, true, false, 'not', false, 'Expected value to be falsey', msg);
}
not.ok = not;
is.not = function (val, exp, msg) {
assert(val !== exp, val, exp, 'is.not', false, 'Expected values not to be strictly equal', msg);
}
not.equal = function (val, exp, msg) {
assert(!dequal(val, exp), val, exp, 'not.equal', false, 'Expected values not to be deeply equal', msg);
}
not.type = function (val, exp, msg) {
let tmp = typeof val;
assert(tmp !== exp, tmp, exp, 'not.type', false, `Expected "${tmp}" not to be "${exp}"`, msg);
}
not.instance = function (val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(!(val instanceof exp), val, exp, 'not.instance', false, `Expected value not to be an instance of ${name}`, msg);
}
not.snapshot = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.snapshot', false, 'Expected value not to match snapshot', msg);
}
not.fixture = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.fixture', false, 'Expected value not to match fixture', msg);
}
not.match = function (val, exp, msg) {
if (typeof exp === 'string') {
assert(!val.includes(exp), val, exp, 'not.match', false, `Expected value not to include "${exp}" substring`, msg);
} else {
assert(!exp.test(val), val, exp, 'not.match', false, `Expected value not to match \`${String(exp)}\` pattern`, msg);
}
}
not.throws = function (blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
} catch (err) {
if (typeof exp === 'function') {
assert(!exp(err), true, false, 'not.throws', false, 'Expected function not to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(!exp.test(err.message), true, false, 'not.throws', false, `Expected function not to throw exception matching \`${String(exp)}\` pattern`, msg);
} else if (!exp) {
assert(false, true, false, 'not.throws', false, 'Expected function not to throw', msg);
}
}
}
exports.Assertion = Assertion;
exports.equal = equal;
exports.fixture = fixture;
exports.instance = instance;
exports.is = is;
exports.match = match;
exports.not = not;
exports.ok = ok;
exports.snapshot = snapshot;
exports.throws = throws;
exports.type = type;
exports.unreachable = unreachable;

160
node_modules/uvu/assert/index.mjs generated vendored Normal file
View file

@ -0,0 +1,160 @@
import { dequal } from 'dequal';
import { compare, lines } from 'uvu/diff';
function dedent(str) {
str = str.replace(/\r?\n/g, '\n');
let arr = str.match(/^[ \t]*(?=\S)/gm);
let i = 0, min = 1/0, len = (arr||[]).length;
for (; i < len; i++) min = Math.min(min, arr[i].length);
return len && min ? str.replace(new RegExp(`^[ \\t]{${min}}`, 'gm'), '') : str;
}
export class Assertion extends Error {
constructor(opts={}) {
super(opts.message);
this.name = 'Assertion';
this.code = 'ERR_ASSERTION';
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
this.details = opts.details || false;
this.generated = !!opts.generated;
this.operator = opts.operator;
this.expects = opts.expects;
this.actual = opts.actual;
}
}
function assert(bool, actual, expects, operator, detailer, backup, msg) {
if (bool) return;
let message = msg || backup;
if (msg instanceof Error) throw msg;
let details = detailer && detailer(actual, expects);
throw new Assertion({ actual, expects, operator, message, details, generated: !msg });
}
export function ok(val, msg) {
assert(!!val, false, true, 'ok', false, 'Expected value to be truthy', msg);
}
export function is(val, exp, msg) {
assert(val === exp, val, exp, 'is', compare, 'Expected values to be strictly equal:', msg);
}
export function equal(val, exp, msg) {
assert(dequal(val, exp), val, exp, 'equal', compare, 'Expected values to be deeply equal:', msg);
}
export function unreachable(msg) {
assert(false, true, false, 'unreachable', false, 'Expected not to be reached!', msg);
}
export function type(val, exp, msg) {
let tmp = typeof val;
assert(tmp === exp, tmp, exp, 'type', false, `Expected "${tmp}" to be "${exp}"`, msg);
}
export function instance(val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(val instanceof exp, val, exp, 'instance', false, `Expected value to be an instance of ${name}`, msg);
}
export function match(val, exp, msg) {
if (typeof exp === 'string') {
assert(val.includes(exp), val, exp, 'match', false, `Expected value to include "${exp}" substring`, msg);
} else {
assert(exp.test(val), val, exp, 'match', false, `Expected value to match \`${String(exp)}\` pattern`, msg);
}
}
export function snapshot(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'snapshot', lines, 'Expected value to match snapshot:', msg);
}
const lineNums = (x, y) => lines(x, y, 1);
export function fixture(val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val === exp, val, exp, 'fixture', lineNums, 'Expected value to match fixture:', msg);
}
export function throws(blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
assert(false, false, true, 'throws', false, 'Expected function to throw', msg);
} catch (err) {
if (err instanceof Assertion) throw err;
if (typeof exp === 'function') {
assert(exp(err), false, true, 'throws', false, 'Expected function to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(exp.test(err.message), false, true, 'throws', false, `Expected function to throw exception matching \`${String(exp)}\` pattern`, msg);
}
}
}
// ---
export function not(val, msg) {
assert(!val, true, false, 'not', false, 'Expected value to be falsey', msg);
}
not.ok = not;
is.not = function (val, exp, msg) {
assert(val !== exp, val, exp, 'is.not', false, 'Expected values not to be strictly equal', msg);
}
not.equal = function (val, exp, msg) {
assert(!dequal(val, exp), val, exp, 'not.equal', false, 'Expected values not to be deeply equal', msg);
}
not.type = function (val, exp, msg) {
let tmp = typeof val;
assert(tmp !== exp, tmp, exp, 'not.type', false, `Expected "${tmp}" not to be "${exp}"`, msg);
}
not.instance = function (val, exp, msg) {
let name = '`' + (exp.name || exp.constructor.name) + '`';
assert(!(val instanceof exp), val, exp, 'not.instance', false, `Expected value not to be an instance of ${name}`, msg);
}
not.snapshot = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.snapshot', false, 'Expected value not to match snapshot', msg);
}
not.fixture = function (val, exp, msg) {
val=dedent(val); exp=dedent(exp);
assert(val !== exp, val, exp, 'not.fixture', false, 'Expected value not to match fixture', msg);
}
not.match = function (val, exp, msg) {
if (typeof exp === 'string') {
assert(!val.includes(exp), val, exp, 'not.match', false, `Expected value not to include "${exp}" substring`, msg);
} else {
assert(!exp.test(val), val, exp, 'not.match', false, `Expected value not to match \`${String(exp)}\` pattern`, msg);
}
}
not.throws = function (blk, exp, msg) {
if (!msg && typeof exp === 'string') {
msg = exp; exp = null;
}
try {
blk();
} catch (err) {
if (typeof exp === 'function') {
assert(!exp(err), true, false, 'not.throws', false, 'Expected function not to throw matching exception', msg);
} else if (exp instanceof RegExp) {
assert(!exp.test(err.message), true, false, 'not.throws', false, `Expected function not to throw exception matching \`${String(exp)}\` pattern`, msg);
} else if (!exp) {
assert(false, true, false, 'not.throws', false, 'Expected function not to throw', msg);
}
}
}

35
node_modules/uvu/bin.js generated vendored Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env node
const sade = require('sade');
const pkg = require('./package');
const { parse } = require('./parse');
const dimport = x => new Function(`return import(${ JSON.stringify(x) })`).call(0);
const hasImport = (() => {
try { new Function('import').call(0) }
catch (err) { return !/unexpected/i.test(err.message) }
})();
sade('uvu [dir] [pattern]')
.version(pkg.version)
.option('-b, --bail', 'Exit on first failure')
.option('-i, --ignore', 'Any file patterns to ignore')
.option('-r, --require', 'Additional module(s) to preload')
.option('-C, --cwd', 'The current directory to resolve from', '.')
.option('-c, --color', 'Print colorized output', true)
.action(async (dir, pattern, opts) => {
try {
if (opts.color) process.env.FORCE_COLOR = '1';
let ctx = await parse(dir, pattern, opts);
if (!ctx.requires && hasImport) {
await dimport('uvu/run').then(m => m.run(ctx.suites, opts));
} else {
await require('uvu/run').run(ctx.suites, opts);
}
} catch (err) {
console.error(err.stack || err.message);
process.exit(1);
}
})
.parse(process.argv);

5
node_modules/uvu/diff/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,5 @@
export function chars(input: any, expects: any): string;
export function lines(input: any, expects: any, linenum?: number): string;
export function direct(input: any, expects: any, lenA?: number, lenB?: number): string;
export function compare(input: any, expects: any): string;
export function arrays(input: any, expects: any): string;

228
node_modules/uvu/diff/index.js generated vendored Normal file
View file

@ -0,0 +1,228 @@
const kleur = require('kleur');
const diff = require('diff');
const colors = {
'--': kleur.red,
'··': kleur.grey,
'++': kleur.green,
};
const TITLE = kleur.dim().italic;
const TAB=kleur.dim('→'), SPACE=kleur.dim('·'), NL=kleur.dim('↵');
const LOG = (sym, str) => colors[sym](sym + PRETTY(str)) + '\n';
const LINE = (num, x) => kleur.dim('L' + String(num).padStart(x, '0') + ' ');
const PRETTY = str => str.replace(/[ ]/g, SPACE).replace(/\t/g, TAB).replace(/(\r?\n)/g, NL);
function line(obj, prev, pad) {
let char = obj.removed ? '--' : obj.added ? '++' : '··';
let arr = obj.value.replace(/\r?\n$/, '').split('\n');
let i=0, tmp, out='';
if (obj.added) out += colors[char]().underline(TITLE('Expected:')) + '\n';
else if (obj.removed) out += colors[char]().underline(TITLE('Actual:')) + '\n';
for (; i < arr.length; i++) {
tmp = arr[i];
if (tmp != null) {
if (prev) out += LINE(prev + i, pad);
out += LOG(char, tmp || '\n');
}
}
return out;
}
// TODO: want better diffing
//~> complex items bail outright
function arrays(input, expect) {
let arr = diff.diffArrays(input, expect);
let i=0, j=0, k=0, tmp, val, char, isObj, str;
let out = LOG('··', '[');
for (; i < arr.length; i++) {
char = (tmp = arr[i]).removed ? '--' : tmp.added ? '++' : '··';
if (tmp.added) {
out += colors[char]().underline(TITLE('Expected:')) + '\n';
} else if (tmp.removed) {
out += colors[char]().underline(TITLE('Actual:')) + '\n';
}
for (j=0; j < tmp.value.length; j++) {
isObj = (tmp.value[j] && typeof tmp.value[j] === 'object');
val = stringify(tmp.value[j]).split(/\r?\n/g);
for (k=0; k < val.length;) {
str = ' ' + val[k++] + (isObj ? '' : ',');
if (isObj && k === val.length && (j + 1) < tmp.value.length) str += ',';
out += LOG(char, str);
}
}
}
return out + LOG('··', ']');
}
function lines(input, expect, linenum = 0) {
let i=0, tmp, output='';
let arr = diff.diffLines(input, expect);
let pad = String(expect.split(/\r?\n/g).length - linenum).length;
for (; i < arr.length; i++) {
output += line(tmp = arr[i], linenum, pad);
if (linenum && !tmp.removed) linenum += tmp.count;
}
return output;
}
function chars(input, expect) {
let arr = diff.diffChars(input, expect);
let i=0, output='', tmp;
let l1 = input.length;
let l2 = expect.length;
let p1 = PRETTY(input);
let p2 = PRETTY(expect);
tmp = arr[i];
if (l1 === l2) {
// no length offsets
} else if (tmp.removed && arr[i + 1]) {
let del = tmp.count - arr[i + 1].count;
if (del == 0) {
// wash~
} else if (del > 0) {
expect = ' '.repeat(del) + expect;
p2 = ' '.repeat(del) + p2;
l2 += del;
} else if (del < 0) {
input = ' '.repeat(-del) + input;
p1 = ' '.repeat(-del) + p1;
l1 += -del;
}
}
output += direct(p1, p2, l1, l2);
if (l1 === l2) {
for (tmp=' '; i < l1; i++) {
tmp += input[i] === expect[i] ? ' ' : '^';
}
} else {
for (tmp=' '; i < arr.length; i++) {
tmp += ((arr[i].added || arr[i].removed) ? '^' : ' ').repeat(Math.max(arr[i].count, 0));
if (i + 1 < arr.length && ((arr[i].added && arr[i+1].removed) || (arr[i].removed && arr[i+1].added))) {
arr[i + 1].count -= arr[i].count;
}
}
}
return output + kleur.red(tmp);
}
function direct(input, expect, lenA = String(input).length, lenB = String(expect).length) {
let gutter = 4;
let lenC = Math.max(lenA, lenB);
let typeA=typeof input, typeB=typeof expect;
if (typeA !== typeB) {
gutter = 2;
let delA = gutter + lenC - lenA;
let delB = gutter + lenC - lenB;
input += ' '.repeat(delA) + kleur.dim(`[${typeA}]`);
expect += ' '.repeat(delB) + kleur.dim(`[${typeB}]`);
lenA += delA + typeA.length + 2;
lenB += delB + typeB.length + 2;
lenC = Math.max(lenA, lenB);
}
let output = colors['++']('++' + expect + ' '.repeat(gutter + lenC - lenB) + TITLE('(Expected)')) + '\n';
return output + colors['--']('--' + input + ' '.repeat(gutter + lenC - lenA) + TITLE('(Actual)')) + '\n';
}
function sort(input, expect) {
var k, i=0, tmp, isArr = Array.isArray(input);
var keys=[], out=isArr ? Array(input.length) : {};
if (isArr) {
for (i=0; i < out.length; i++) {
tmp = input[i];
if (!tmp || typeof tmp !== 'object') out[i] = tmp;
else out[i] = sort(tmp, expect[i]); // might not be right
}
} else {
for (k in expect)
keys.push(k);
for (; i < keys.length; i++) {
if (Object.prototype.hasOwnProperty.call(input, k = keys[i])) {
if (!(tmp = input[k]) || typeof tmp !== 'object') out[k] = tmp;
else out[k] = sort(tmp, expect[k]);
}
}
for (k in input) {
if (!out.hasOwnProperty(k)) {
out[k] = input[k]; // expect didnt have
}
}
}
return out;
}
function circular() {
var cache = new Set;
return function print(key, val) {
if (val === void 0) return '[__VOID__]';
if (typeof val === 'number' && val !== val) return '[__NAN__]';
if (typeof val === 'bigint') return val.toString();
if (!val || typeof val !== 'object') return val;
if (cache.has(val)) return '[Circular]';
cache.add(val); return val;
}
}
function stringify(input) {
return JSON.stringify(input, circular(), 2).replace(/"\[__NAN__\]"/g, 'NaN').replace(/"\[__VOID__\]"/g, 'undefined');
}
function compare(input, expect) {
if (Array.isArray(expect) && Array.isArray(input)) return arrays(input, expect);
if (expect instanceof RegExp) return chars(''+input, ''+expect);
let isA = input && typeof input == 'object';
let isB = expect && typeof expect == 'object';
if (isA && isB) input = sort(input, expect);
if (isB) expect = stringify(expect);
if (isA) input = stringify(input);
if (expect && typeof expect == 'object') {
input = stringify(sort(input, expect));
expect = stringify(expect);
}
isA = typeof input == 'string';
isB = typeof expect == 'string';
if (isA && /\r?\n/.test(input)) return lines(input, ''+expect);
if (isB && /\r?\n/.test(expect)) return lines(''+input, expect);
if (isA && isB) return chars(input, expect);
return direct(input, expect);
}
exports.arrays = arrays;
exports.chars = chars;
exports.circular = circular;
exports.compare = compare;
exports.direct = direct;
exports.lines = lines;
exports.sort = sort;
exports.stringify = stringify;

219
node_modules/uvu/diff/index.mjs generated vendored Normal file
View file

@ -0,0 +1,219 @@
import kleur from 'kleur';
import * as diff from 'diff';
const colors = {
'--': kleur.red,
'··': kleur.grey,
'++': kleur.green,
};
const TITLE = kleur.dim().italic;
const TAB=kleur.dim('→'), SPACE=kleur.dim('·'), NL=kleur.dim('↵');
const LOG = (sym, str) => colors[sym](sym + PRETTY(str)) + '\n';
const LINE = (num, x) => kleur.dim('L' + String(num).padStart(x, '0') + ' ');
const PRETTY = str => str.replace(/[ ]/g, SPACE).replace(/\t/g, TAB).replace(/(\r?\n)/g, NL);
function line(obj, prev, pad) {
let char = obj.removed ? '--' : obj.added ? '++' : '··';
let arr = obj.value.replace(/\r?\n$/, '').split('\n');
let i=0, tmp, out='';
if (obj.added) out += colors[char]().underline(TITLE('Expected:')) + '\n';
else if (obj.removed) out += colors[char]().underline(TITLE('Actual:')) + '\n';
for (; i < arr.length; i++) {
tmp = arr[i];
if (tmp != null) {
if (prev) out += LINE(prev + i, pad);
out += LOG(char, tmp || '\n');
}
}
return out;
}
// TODO: want better diffing
//~> complex items bail outright
export function arrays(input, expect) {
let arr = diff.diffArrays(input, expect);
let i=0, j=0, k=0, tmp, val, char, isObj, str;
let out = LOG('··', '[');
for (; i < arr.length; i++) {
char = (tmp = arr[i]).removed ? '--' : tmp.added ? '++' : '··';
if (tmp.added) {
out += colors[char]().underline(TITLE('Expected:')) + '\n';
} else if (tmp.removed) {
out += colors[char]().underline(TITLE('Actual:')) + '\n';
}
for (j=0; j < tmp.value.length; j++) {
isObj = (tmp.value[j] && typeof tmp.value[j] === 'object');
val = stringify(tmp.value[j]).split(/\r?\n/g);
for (k=0; k < val.length;) {
str = ' ' + val[k++] + (isObj ? '' : ',');
if (isObj && k === val.length && (j + 1) < tmp.value.length) str += ',';
out += LOG(char, str);
}
}
}
return out + LOG('··', ']');
}
export function lines(input, expect, linenum = 0) {
let i=0, tmp, output='';
let arr = diff.diffLines(input, expect);
let pad = String(expect.split(/\r?\n/g).length - linenum).length;
for (; i < arr.length; i++) {
output += line(tmp = arr[i], linenum, pad);
if (linenum && !tmp.removed) linenum += tmp.count;
}
return output;
}
export function chars(input, expect) {
let arr = diff.diffChars(input, expect);
let i=0, output='', tmp;
let l1 = input.length;
let l2 = expect.length;
let p1 = PRETTY(input);
let p2 = PRETTY(expect);
tmp = arr[i];
if (l1 === l2) {
// no length offsets
} else if (tmp.removed && arr[i + 1]) {
let del = tmp.count - arr[i + 1].count;
if (del == 0) {
// wash~
} else if (del > 0) {
expect = ' '.repeat(del) + expect;
p2 = ' '.repeat(del) + p2;
l2 += del;
} else if (del < 0) {
input = ' '.repeat(-del) + input;
p1 = ' '.repeat(-del) + p1;
l1 += -del;
}
}
output += direct(p1, p2, l1, l2);
if (l1 === l2) {
for (tmp=' '; i < l1; i++) {
tmp += input[i] === expect[i] ? ' ' : '^';
}
} else {
for (tmp=' '; i < arr.length; i++) {
tmp += ((arr[i].added || arr[i].removed) ? '^' : ' ').repeat(Math.max(arr[i].count, 0));
if (i + 1 < arr.length && ((arr[i].added && arr[i+1].removed) || (arr[i].removed && arr[i+1].added))) {
arr[i + 1].count -= arr[i].count;
}
}
}
return output + kleur.red(tmp);
}
export function direct(input, expect, lenA = String(input).length, lenB = String(expect).length) {
let gutter = 4;
let lenC = Math.max(lenA, lenB);
let typeA=typeof input, typeB=typeof expect;
if (typeA !== typeB) {
gutter = 2;
let delA = gutter + lenC - lenA;
let delB = gutter + lenC - lenB;
input += ' '.repeat(delA) + kleur.dim(`[${typeA}]`);
expect += ' '.repeat(delB) + kleur.dim(`[${typeB}]`);
lenA += delA + typeA.length + 2;
lenB += delB + typeB.length + 2;
lenC = Math.max(lenA, lenB);
}
let output = colors['++']('++' + expect + ' '.repeat(gutter + lenC - lenB) + TITLE('(Expected)')) + '\n';
return output + colors['--']('--' + input + ' '.repeat(gutter + lenC - lenA) + TITLE('(Actual)')) + '\n';
}
export function sort(input, expect) {
var k, i=0, tmp, isArr = Array.isArray(input);
var keys=[], out=isArr ? Array(input.length) : {};
if (isArr) {
for (i=0; i < out.length; i++) {
tmp = input[i];
if (!tmp || typeof tmp !== 'object') out[i] = tmp;
else out[i] = sort(tmp, expect[i]); // might not be right
}
} else {
for (k in expect)
keys.push(k);
for (; i < keys.length; i++) {
if (Object.prototype.hasOwnProperty.call(input, k = keys[i])) {
if (!(tmp = input[k]) || typeof tmp !== 'object') out[k] = tmp;
else out[k] = sort(tmp, expect[k]);
}
}
for (k in input) {
if (!out.hasOwnProperty(k)) {
out[k] = input[k]; // expect didnt have
}
}
}
return out;
}
export function circular() {
var cache = new Set;
return function print(key, val) {
if (val === void 0) return '[__VOID__]';
if (typeof val === 'number' && val !== val) return '[__NAN__]';
if (typeof val === 'bigint') return val.toString();
if (!val || typeof val !== 'object') return val;
if (cache.has(val)) return '[Circular]';
cache.add(val); return val;
}
}
export function stringify(input) {
return JSON.stringify(input, circular(), 2).replace(/"\[__NAN__\]"/g, 'NaN').replace(/"\[__VOID__\]"/g, 'undefined');
}
export function compare(input, expect) {
if (Array.isArray(expect) && Array.isArray(input)) return arrays(input, expect);
if (expect instanceof RegExp) return chars(''+input, ''+expect);
let isA = input && typeof input == 'object';
let isB = expect && typeof expect == 'object';
if (isA && isB) input = sort(input, expect);
if (isB) expect = stringify(expect);
if (isA) input = stringify(input);
if (expect && typeof expect == 'object') {
input = stringify(sort(input, expect));
expect = stringify(expect);
}
isA = typeof input == 'string';
isB = typeof expect == 'string';
if (isA && /\r?\n/.test(input)) return lines(input, ''+expect);
if (isB && /\r?\n/.test(expect)) return lines(''+input, expect);
if (isA && isB) return chars(input, expect);
return direct(input, expect);
}

167
node_modules/uvu/dist/index.js generated vendored Normal file
View file

@ -0,0 +1,167 @@
const kleur = require('kleur');
const { compare } = require('uvu/diff');
let isCLI = false, isNode = false;
let hrtime = (now = Date.now()) => () => (Date.now() - now).toFixed(2) + 'ms';
let write = console.log;
const into = (ctx, key) => (name, handler) => ctx[key].push({ name, handler });
const context = (state) => ({ tests:[], before:[], after:[], bEach:[], aEach:[], only:[], skips:0, state });
const milli = arr => (arr[0]*1e3 + arr[1]/1e6).toFixed(2) + 'ms';
const hook = (ctx, key) => handler => ctx[key].push(handler);
if (isNode = typeof process < 'u' && typeof process.stdout < 'u') {
// globalThis polyfill; Node < 12
if (typeof globalThis !== 'object') {
Object.defineProperty(global, 'globalThis', {
get: function () { return this }
});
}
let rgx = /(\.bin[\\+\/]uvu$|uvu[\\+\/]bin\.js)/i;
isCLI = process.argv.some(x => rgx.test(x));
// attach node-specific utils
write = x => process.stdout.write(x);
hrtime = (now = process.hrtime()) => () => milli(process.hrtime(now));
} else if (typeof performance < 'u') {
hrtime = (now = performance.now()) => () => (performance.now() - now).toFixed(2) + 'ms';
}
globalThis.UVU_QUEUE = globalThis.UVU_QUEUE || [];
isCLI = isCLI || !!globalThis.UVU_DEFER;
isCLI || UVU_QUEUE.push([null]);
const QUOTE = kleur.dim('"'), GUTTER = '\n ';
const FAIL = kleur.red('✘ '), PASS = kleur.gray('• ');
const IGNORE = /^\s*at.*(?:\(|\s)(?:node|(internal\/[\w/]*))/;
const FAILURE = kleur.bold().bgRed(' FAIL ');
const FILE = kleur.bold().underline().white;
const SUITE = kleur.bgWhite().bold;
function stack(stack, idx) {
let i=0, line, out='';
let arr = stack.substring(idx).replace(/\\/g, '/').split('\n');
for (; i < arr.length; i++) {
line = arr[i].trim();
if (line.length && !IGNORE.test(line)) {
out += '\n ' + line;
}
}
return kleur.grey(out) + '\n';
}
function format(name, err, suite = '') {
let { details, operator='' } = err;
let idx = err.stack && err.stack.indexOf('\n');
if (err.name.startsWith('AssertionError') && !operator.includes('not')) details = compare(err.actual, err.expected); // TODO?
let str = ' ' + FAILURE + (suite ? kleur.red(SUITE(` ${suite} `)) : '') + ' ' + QUOTE + kleur.red().bold(name) + QUOTE;
str += '\n ' + err.message + (operator ? kleur.italic().dim(` (${operator})`) : '') + '\n';
if (details) str += GUTTER + details.split('\n').join(GUTTER);
if (!!~idx) str += stack(err.stack, idx);
return str + '\n';
}
async function runner(ctx, name) {
let { only, tests, before, after, bEach, aEach, state } = ctx;
let hook, test, arr = only.length ? only : tests;
let num=0, errors='', total=arr.length;
try {
if (name) write(SUITE(kleur.black(` ${name} `)) + ' ');
for (hook of before) await hook(state);
for (test of arr) {
state.__test__ = test.name;
try {
for (hook of bEach) await hook(state);
await test.handler(state);
for (hook of aEach) await hook(state);
write(PASS);
num++;
} catch (err) {
for (hook of aEach) await hook(state);
if (errors.length) errors += '\n';
errors += format(test.name, err, name);
write(FAIL);
}
}
} finally {
state.__test__ = '';
for (hook of after) await hook(state);
let msg = ` (${num} / ${total})\n`;
let skipped = (only.length ? tests.length : 0) + ctx.skips;
write(errors.length ? kleur.red(msg) : kleur.green(msg));
return [errors || true, num, skipped, total];
}
}
let timer;
function defer() {
clearTimeout(timer);
timer = setTimeout(exec);
}
function setup(ctx, name = '') {
ctx.state.__test__ = '';
ctx.state.__suite__ = name;
const test = into(ctx, 'tests');
test.before = hook(ctx, 'before');
test.before.each = hook(ctx, 'bEach');
test.after = hook(ctx, 'after');
test.after.each = hook(ctx, 'aEach');
test.only = into(ctx, 'only');
test.skip = () => { ctx.skips++ };
test.run = () => {
let copy = { ...ctx };
let run = runner.bind(0, copy, name);
Object.assign(ctx, context(copy.state));
UVU_QUEUE[globalThis.UVU_INDEX || 0].push(run);
isCLI || defer();
};
return test;
}
const suite = (name = '', state = {}) => setup(context(state), name);
const test = suite();
let isRunning = false;
async function exec(bail) {
let timer = hrtime();
let done=0, total=0, skips=0, code=0;
isRunning = true;
for (let group of UVU_QUEUE) {
if (total) write('\n');
let name = group.shift();
if (name != null) write(FILE(name) + '\n');
for (let test of group) {
let [errs, ran, skip, max] = await test();
total += max; done += ran; skips += skip;
if (errs.length) {
write('\n' + errs + '\n'); code=1;
if (bail) return isNode && process.exit(1);
}
}
}
isRunning = false;
write('\n Total: ' + total);
write((code ? kleur.red : kleur.green)('\n Passed: ' + done));
write('\n Skipped: ' + (skips ? kleur.yellow(skips) : skips));
write('\n Duration: ' + timer() + '\n\n');
if (isNode) process.exitCode = code;
}
if (isNode) process.on('exit', () => {
if (!isRunning) return; // okay to exit
process.exitCode = process.exitCode || 1;
console.error('Exiting early before testing is finished.');
});
exports.exec = exec;
exports.suite = suite;
exports.test = test;

163
node_modules/uvu/dist/index.mjs generated vendored Normal file
View file

@ -0,0 +1,163 @@
import kleur from 'kleur';
import { compare } from 'uvu/diff';
let isCLI = false, isNode = false;
let hrtime = (now = Date.now()) => () => (Date.now() - now).toFixed(2) + 'ms';
let write = console.log;
const into = (ctx, key) => (name, handler) => ctx[key].push({ name, handler });
const context = (state) => ({ tests:[], before:[], after:[], bEach:[], aEach:[], only:[], skips:0, state });
const milli = arr => (arr[0]*1e3 + arr[1]/1e6).toFixed(2) + 'ms';
const hook = (ctx, key) => handler => ctx[key].push(handler);
if (isNode = typeof process < 'u' && typeof process.stdout < 'u') {
// globalThis polyfill; Node < 12
if (typeof globalThis !== 'object') {
Object.defineProperty(global, 'globalThis', {
get: function () { return this }
});
}
let rgx = /(\.bin[\\+\/]uvu$|uvu[\\+\/]bin\.js)/i;
isCLI = process.argv.some(x => rgx.test(x));
// attach node-specific utils
write = x => process.stdout.write(x);
hrtime = (now = process.hrtime()) => () => milli(process.hrtime(now));
} else if (typeof performance < 'u') {
hrtime = (now = performance.now()) => () => (performance.now() - now).toFixed(2) + 'ms';
}
globalThis.UVU_QUEUE = globalThis.UVU_QUEUE || [];
isCLI = isCLI || !!globalThis.UVU_DEFER;
isCLI || UVU_QUEUE.push([null]);
const QUOTE = kleur.dim('"'), GUTTER = '\n ';
const FAIL = kleur.red('✘ '), PASS = kleur.gray('• ');
const IGNORE = /^\s*at.*(?:\(|\s)(?:node|(internal\/[\w/]*))/;
const FAILURE = kleur.bold().bgRed(' FAIL ');
const FILE = kleur.bold().underline().white;
const SUITE = kleur.bgWhite().bold;
function stack(stack, idx) {
let i=0, line, out='';
let arr = stack.substring(idx).replace(/\\/g, '/').split('\n');
for (; i < arr.length; i++) {
line = arr[i].trim();
if (line.length && !IGNORE.test(line)) {
out += '\n ' + line;
}
}
return kleur.grey(out) + '\n';
}
function format(name, err, suite = '') {
let { details, operator='' } = err;
let idx = err.stack && err.stack.indexOf('\n');
if (err.name.startsWith('AssertionError') && !operator.includes('not')) details = compare(err.actual, err.expected); // TODO?
let str = ' ' + FAILURE + (suite ? kleur.red(SUITE(` ${suite} `)) : '') + ' ' + QUOTE + kleur.red().bold(name) + QUOTE;
str += '\n ' + err.message + (operator ? kleur.italic().dim(` (${operator})`) : '') + '\n';
if (details) str += GUTTER + details.split('\n').join(GUTTER);
if (!!~idx) str += stack(err.stack, idx);
return str + '\n';
}
async function runner(ctx, name) {
let { only, tests, before, after, bEach, aEach, state } = ctx;
let hook, test, arr = only.length ? only : tests;
let num=0, errors='', total=arr.length;
try {
if (name) write(SUITE(kleur.black(` ${name} `)) + ' ');
for (hook of before) await hook(state);
for (test of arr) {
state.__test__ = test.name;
try {
for (hook of bEach) await hook(state);
await test.handler(state);
for (hook of aEach) await hook(state);
write(PASS);
num++;
} catch (err) {
for (hook of aEach) await hook(state);
if (errors.length) errors += '\n';
errors += format(test.name, err, name);
write(FAIL);
}
}
} finally {
state.__test__ = '';
for (hook of after) await hook(state);
let msg = ` (${num} / ${total})\n`;
let skipped = (only.length ? tests.length : 0) + ctx.skips;
write(errors.length ? kleur.red(msg) : kleur.green(msg));
return [errors || true, num, skipped, total];
}
}
let timer;
function defer() {
clearTimeout(timer);
timer = setTimeout(exec);
}
function setup(ctx, name = '') {
ctx.state.__test__ = '';
ctx.state.__suite__ = name;
const test = into(ctx, 'tests');
test.before = hook(ctx, 'before');
test.before.each = hook(ctx, 'bEach');
test.after = hook(ctx, 'after');
test.after.each = hook(ctx, 'aEach');
test.only = into(ctx, 'only');
test.skip = () => { ctx.skips++ };
test.run = () => {
let copy = { ...ctx };
let run = runner.bind(0, copy, name);
Object.assign(ctx, context(copy.state));
UVU_QUEUE[globalThis.UVU_INDEX || 0].push(run);
isCLI || defer();
};
return test;
}
export const suite = (name = '', state = {}) => setup(context(state), name);
export const test = suite();
let isRunning = false;
export async function exec(bail) {
let timer = hrtime();
let done=0, total=0, skips=0, code=0;
isRunning = true;
for (let group of UVU_QUEUE) {
if (total) write('\n');
let name = group.shift();
if (name != null) write(FILE(name) + '\n');
for (let test of group) {
let [errs, ran, skip, max] = await test();
total += max; done += ran; skips += skip;
if (errs.length) {
write('\n' + errs + '\n'); code=1;
if (bail) return isNode && process.exit(1);
}
}
}
isRunning = false;
write('\n Total: ' + total);
write((code ? kleur.red : kleur.green)('\n Passed: ' + done));
write('\n Skipped: ' + (skips ? kleur.yellow(skips) : skips));
write('\n Duration: ' + timer() + '\n\n');
if (isNode) process.exitCode = code;
}
if (isNode) process.on('exit', () => {
if (!isRunning) return; // okay to exit
process.exitCode = process.exitCode || 1;
console.error('Exiting early before testing is finished.');
});

27
node_modules/uvu/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,27 @@
declare namespace uvu {
type Crumbs = { __suite__: string; __test__: string };
type Callback<T> = (context: T & Crumbs) => Promise<void> | void;
interface Hook<T> {
(hook: Callback<T>): void;
each(hook: Callback<T>): void;
}
interface Test<T> {
(name: string, test: Callback<T>): void;
only(name: string, test: Callback<T>): void;
skip(name?: string, test?: Callback<T>): void;
before: Hook<T>;
after: Hook<T>
run(): void;
}
}
type Context = Record<string, any>;
export type Test<T=Context> = uvu.Test<T>;
export type Callback<T=Context> = uvu.Callback<T>;
export const test: uvu.Test<Context>;
export function suite<T=Context>(title?: string, context?: T): uvu.Test<T>;
export function exec(bail?: boolean): Promise<void>;

21
node_modules/uvu/license generated vendored Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

85
node_modules/uvu/package.json generated vendored Normal file
View file

@ -0,0 +1,85 @@
{
"name": "uvu",
"version": "0.5.6",
"repository": "lukeed/uvu",
"description": "uvu is an extremely fast and lightweight test runner for Node.js and the browser",
"module": "dist/index.mjs",
"main": "dist/index.js",
"types": "index.d.ts",
"license": "MIT",
"bin": {
"uvu": "bin.js"
},
"exports": {
".": {
"types": "./index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
},
"./assert": {
"types": "./assert/index.d.ts",
"require": "./assert/index.js",
"import": "./assert/index.mjs"
},
"./diff": {
"types": "./diff/index.d.ts",
"require": "./diff/index.js",
"import": "./diff/index.mjs"
},
"./parse": {
"types": "./parse/index.d.ts",
"require": "./parse/index.js",
"import": "./parse/index.mjs"
},
"./run": {
"types": "./run/index.d.ts",
"require": "./run/index.js",
"import": "./run/index.mjs"
}
},
"files": [
"*.js",
"*.d.ts",
"assert",
"parse",
"diff",
"dist",
"run"
],
"modes": {
"diff": "src/diff.js",
"assert": "src/assert.js",
"default": "src/index.js"
},
"scripts": {
"build": "bundt",
"test": "node test"
},
"engines": {
"node": ">=8"
},
"keywords": [
"assert",
"diffs",
"runner",
"snapshot",
"test"
],
"dependencies": {
"dequal": "^2.0.0",
"diff": "^5.0.0",
"kleur": "^4.0.3",
"sade": "^1.7.3"
},
"devDependencies": {
"bundt": "1.1.1",
"esm": "3.2.25",
"module-alias": "2.2.2",
"totalist": "2.0.0"
},
"_moduleAliases": {
"uvu": "src/index.js",
"uvu/diff": "src/diff.js",
"uvu/assert": "src/assert.js"
}
}

22
node_modules/uvu/parse/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,22 @@
type Arrayable<T> = T[] | T;
export interface Suite {
/** The relative file path */
name: string;
/** The absolute file path */
file: string;
}
export interface Options {
cwd: string;
require: Arrayable<string>;
ignore: Arrayable<string | RegExp>;
}
export interface Argv {
dir: string;
suites: Suite[];
requires: boolean;
}
export function parse(dir?: string, pattern?: string|RegExp, opts?: Partial<Options>): Promise<Argv>;

50
node_modules/uvu/parse/index.js generated vendored Normal file
View file

@ -0,0 +1,50 @@
// @ts-check
const { readdir, stat } = require('fs');
const { resolve, join } = require('path');
const { promisify } = require('util');
const ls = promisify(readdir);
const toStat = promisify(stat);
const toRegex = x => new RegExp(x, 'i');
async function parse(dir, pattern, opts = {}) {
if (pattern) pattern = toRegex(pattern);
else if (dir) pattern = /(((?:[^\/]*(?:\/|$))*)[\\\/])?\w+\.([mc]js|[jt]sx?)$/;
else pattern = /((\/|^)(tests?|__tests?__)\/.*|\.(tests?|spec)|^\/?tests?)\.([mc]js|[jt]sx?)$/i;
dir = resolve(opts.cwd || '.', dir || '.');
let suites = [];
let requires = [].concat(opts.require || []).filter(Boolean);
let ignores = ['^.git', 'node_modules'].concat(opts.ignore || []).map(toRegex);
requires.forEach(name => {
try { return require(name) }
catch (e) { throw new Error(`Cannot find module "${name}"`) }
});
// NOTE: Node 8.x support
// @modified lukeed/totalist
await (async function collect(d, p) {
await ls(d).then(files => {
return Promise.all(
files.map(async str => {
let name = join(p, str);
for (let i = ignores.length; i--;) {
if (ignores[i].test(name)) return;
}
let file = join(d, str);
let stats = await toStat(file);
if (stats.isDirectory()) return collect(file, name);
else if (pattern.test(name)) suites.push({ name, file });
})
);
});
})(dir, '');
suites.sort((a, b) => a.name.localeCompare(b.name));
return { dir, suites, requires: requires.length > 0 };
}
exports.parse = parse;

51
node_modules/uvu/parse/index.mjs generated vendored Normal file
View file

@ -0,0 +1,51 @@
import { readdir, stat } from 'fs';
import { createRequire } from 'module';
import { resolve, join } from 'path';
import { promisify } from 'util';
const ls = promisify(readdir);
const toStat = promisify(stat);
const toRegex = x => new RegExp(x, 'i');
export async function parse(dir, pattern, opts = {}) {
if (pattern) pattern = toRegex(pattern);
else if (dir) pattern = /(((?:[^\/]*(?:\/|$))*)[\\\/])?\w+\.([mc]js|[jt]sx?)$/;
else pattern = /((\/|^)(tests?|__tests?__)\/.*|\.(tests?|spec)|^\/?tests?)\.([mc]js|[jt]sx?)$/i;
dir = resolve(opts.cwd || '.', dir || '.');
let suites = [];
let requires = [].concat(opts.require || []).filter(Boolean);
let ignores = ['^.git', 'node_modules'].concat(opts.ignore || []).map(toRegex);
if (requires.length) {
let $require = createRequire(import.meta.url);
requires.forEach(name => {
try { return $require(name) }
catch (e) { throw new Error(`Cannot find module "${name}"`) }
});
}
// NOTE: Node 8.x support
// @modified lukeed/totalist
await (async function collect(d, p) {
await ls(d).then(files => {
return Promise.all(
files.map(async str => {
let name = join(p, str);
for (let i = ignores.length; i--;) {
if (ignores[i].test(name)) return;
}
let file = join(d, str);
let stats = await toStat(file);
if (stats.isDirectory()) return collect(file, name);
else if (pattern.test(name)) suites.push({ name, file });
})
);
});
})(dir, '');
suites.sort((a, b) => a.name.localeCompare(b.name));
return { dir, suites, requires: requires.length > 0 };
}

137
node_modules/uvu/readme.md generated vendored Normal file
View file

@ -0,0 +1,137 @@
<div align="center">
<img src="shots/uvu.jpg" alt="uvu" height="120" />
</div>
<div align="center">
<a href="https://npmjs.org/package/uvu">
<img src="https://badgen.now.sh/npm/v/uvu" alt="version" />
</a>
<a href="https://github.com/lukeed/uvu/actions">
<img src="https://github.com/lukeed/uvu/workflows/CI/badge.svg" alt="CI" />
</a>
<a href="https://npmjs.org/package/uvu">
<img src="https://badgen.now.sh/npm/dm/uvu" alt="downloads" />
</a>
<a href="https://packagephobia.now.sh/result?p=uvu">
<img src="https://packagephobia.now.sh/badge?p=uvu" alt="install size" />
</a>
</div>
<div align="center">
<b>uvu</b> is an extremely fast and lightweight test runner for Node.js and the browser<br>
<b>U</b>ltimate <b>V</b>elocity, <b>U</b>nleashed<br><br>
<img width="380" alt="example with suites" src="shots/suites.gif"/>
</div>
## Features
* Super [lightweight](https://npm.anvaka.com/#/view/2d/uvu)
* Extremely [performant](#benchmarks)
* Individually executable test files
* Supports `async`/`await` tests
* Supports native ES Modules
* Browser-Compatible
* Familiar API
## Install
```
$ npm install --save-dev uvu
```
## Usage
> Check out [`/examples`](/examples) for a list of working demos!
```js
// tests/demo.js
import { test } from 'uvu';
import * as assert from 'uvu/assert';
test('Math.sqrt()', () => {
assert.is(Math.sqrt(4), 2);
assert.is(Math.sqrt(144), 12);
assert.is(Math.sqrt(2), Math.SQRT2);
});
test('JSON', () => {
const input = {
foo: 'hello',
bar: 'world'
};
const output = JSON.stringify(input);
assert.snapshot(output, `{"foo":"hello","bar":"world"}`);
assert.equal(JSON.parse(output), input, 'matches original');
});
test.run();
```
Then execute this test file:
```sh
# via `uvu` cli, for all `/tests/**` files
$ uvu -r esm tests
# via `node` directly, for file isolation
$ node -r esm tests/demo.js
```
> **Note:** The `-r esm` is for legacy Node.js versions. [Learn More](/docs/esm.md)
> [View the `uvu` CLI documentation](/docs/cli.md)
## Assertions
The [`uvu/assert`](/docs/api.assert.md) module is _completely_ optional.
In fact, you may use any assertion library, including Node's native [`assert`](https://nodejs.org/api/assert.html) module! This works because `uvu` relies on thrown Errors to detect failures. Implicitly, this also means that any uncaught exceptions and/or unhandled `Promise` rejections will result in a failure, which is what you want!
## API
### Module: `uvu`
> [View `uvu` API documentation](/docs/api.uvu.md)
The main entry from which you will import the `test` or `suite` methods.
### Module: `uvu/assert`
> [View `uvu/assert` API documentation](/docs/api.assert.md)
A collection of assertion methods to use within your tests. Please note that:
* these are browser compatible
* these are _completely_ optional
## Benchmarks
> via the [`/bench`](/bench) directory with Node v10.21.0
Below you'll find each test runner with two timing values:
* the `took ___` value is the total process execution time from startup to termination
* the parenthesis value (`(___)`) is the self-reported execution time, if known
Each test runner's `stdout` is printed to the console to verify all assertions pass.<br>Said output is excluded below for brevity.
```
~> "ava" took 594ms ( ??? )
~> "jest" took 962ms (356 ms)
~> "mocha" took 209ms ( 4 ms)
~> "tape" took 122ms ( ??? )
~> "uvu" took 72ms ( 1.3ms)
```
## License
MIT © [Luke Edwards](https://lukeed.com)

2
node_modules/uvu/run/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,2 @@
import type { Suite } from 'uvu/parse';
export function run(suites: Suite[], options?: { bail: boolean }): Promise<void>;

12
node_modules/uvu/run/index.js generated vendored Normal file
View file

@ -0,0 +1,12 @@
exports.run = async function (suites, opts={}) {
globalThis.UVU_DEFER = 1;
const uvu = require('uvu');
suites.forEach((suite, idx) => {
globalThis.UVU_QUEUE.push([suite.name]);
globalThis.UVU_INDEX = idx;
require(suite.file);
});
await uvu.exec(opts.bail);
}

13
node_modules/uvu/run/index.mjs generated vendored Normal file
View file

@ -0,0 +1,13 @@
export async function run(suites, opts={}) {
globalThis.UVU_DEFER = 1;
const uvu = await import('uvu');
let suite, idx=0;
for (suite of suites) {
globalThis.UVU_INDEX = idx++;
globalThis.UVU_QUEUE.push([suite.name]);
await import('file:///' + suite.file);
}
await uvu.exec(opts.bail);
}