diff options
Diffstat (limited to 'vanilla/node_modules/@vitest/utils/dist/helpers.js')
| -rw-r--r-- | vanilla/node_modules/@vitest/utils/dist/helpers.js | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/vanilla/node_modules/@vitest/utils/dist/helpers.js b/vanilla/node_modules/@vitest/utils/dist/helpers.js new file mode 100644 index 0000000..b19970a --- /dev/null +++ b/vanilla/node_modules/@vitest/utils/dist/helpers.js @@ -0,0 +1,295 @@ +import { VALID_ID_PREFIX, NULL_BYTE_PLACEHOLDER } from './constants.js'; + +// port from nanoid +// https://github.com/ai/nanoid +const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; +function nanoid(size = 21) { + let id = ""; + let i = size; + while (i--) { + id += urlAlphabet[Math.random() * 64 | 0]; + } + return id; +} + +const RealDate = Date; +function random(seed) { + const x = Math.sin(seed++) * 1e4; + return x - Math.floor(x); +} +function shuffle(array, seed = RealDate.now()) { + let length = array.length; + while (length) { + const index = Math.floor(random(seed) * length--); + const previous = array[length]; + array[length] = array[index]; + array[index] = previous; + ++seed; + } + return array; +} + +/** +* Get original stacktrace without source map support the most performant way. +* - Create only 1 stack frame. +* - Rewrite prepareStackTrace to bypass "support-stack-trace" (usually takes ~250ms). +*/ +function createSimpleStackTrace(options) { + const { message = "$$stack trace error", stackTraceLimit = 1 } = options || {}; + const limit = Error.stackTraceLimit; + const prepareStackTrace = Error.prepareStackTrace; + Error.stackTraceLimit = stackTraceLimit; + Error.prepareStackTrace = (e) => e.stack; + const err = new Error(message); + const stackTrace = err.stack || ""; + Error.prepareStackTrace = prepareStackTrace; + Error.stackTraceLimit = limit; + return stackTrace; +} +function notNullish(v) { + return v != null; +} +function assertTypes(value, name, types) { + const receivedType = typeof value; + const pass = types.includes(receivedType); + if (!pass) { + throw new TypeError(`${name} value must be ${types.join(" or ")}, received "${receivedType}"`); + } +} +function isPrimitive(value) { + return value === null || typeof value !== "function" && typeof value !== "object"; +} +function slash(path) { + return path.replace(/\\/g, "/"); +} +const postfixRE = /[?#].*$/; +function cleanUrl(url) { + return url.replace(postfixRE, ""); +} +const externalRE = /^(?:[a-z]+:)?\/\//; +const isExternalUrl = (url) => externalRE.test(url); +/** +* Prepend `/@id/` and replace null byte so the id is URL-safe. +* This is prepended to resolved ids that are not valid browser +* import specifiers by the importAnalysis plugin. +*/ +function wrapId(id) { + return id.startsWith(VALID_ID_PREFIX) ? id : VALID_ID_PREFIX + id.replace("\0", NULL_BYTE_PLACEHOLDER); +} +/** +* Undo {@link wrapId}'s `/@id/` and null byte replacements. +*/ +function unwrapId(id) { + return id.startsWith(VALID_ID_PREFIX) ? id.slice(VALID_ID_PREFIX.length).replace(NULL_BYTE_PLACEHOLDER, "\0") : id; +} +function withTrailingSlash(path) { + if (path.at(-1) !== "/") { + return `${path}/`; + } + return path; +} +const bareImportRE = /^(?![a-z]:)[\w@](?!.*:\/\/)/i; +function isBareImport(id) { + return bareImportRE.test(id); +} +function toArray(array) { + if (array === null || array === undefined) { + array = []; + } + if (Array.isArray(array)) { + return array; + } + return [array]; +} +function isObject(item) { + return item != null && typeof item === "object" && !Array.isArray(item); +} +function isFinalObj(obj) { + return obj === Object.prototype || obj === Function.prototype || obj === RegExp.prototype; +} +function getType(value) { + return Object.prototype.toString.apply(value).slice(8, -1); +} +function collectOwnProperties(obj, collector) { + const collect = typeof collector === "function" ? collector : (key) => collector.add(key); + Object.getOwnPropertyNames(obj).forEach(collect); + Object.getOwnPropertySymbols(obj).forEach(collect); +} +function getOwnProperties(obj) { + const ownProps = new Set(); + if (isFinalObj(obj)) { + return []; + } + collectOwnProperties(obj, ownProps); + return Array.from(ownProps); +} +const defaultCloneOptions = { forceWritable: false }; +function deepClone(val, options = defaultCloneOptions) { + const seen = new WeakMap(); + return clone(val, seen, options); +} +function clone(val, seen, options = defaultCloneOptions) { + let k, out; + if (seen.has(val)) { + return seen.get(val); + } + if (Array.isArray(val)) { + out = Array.from({ length: k = val.length }); + seen.set(val, out); + while (k--) { + out[k] = clone(val[k], seen, options); + } + return out; + } + if (Object.prototype.toString.call(val) === "[object Object]") { + out = Object.create(Object.getPrototypeOf(val)); + seen.set(val, out); + // we don't need properties from prototype + const props = getOwnProperties(val); + for (const k of props) { + const descriptor = Object.getOwnPropertyDescriptor(val, k); + if (!descriptor) { + continue; + } + const cloned = clone(val[k], seen, options); + if (options.forceWritable) { + Object.defineProperty(out, k, { + enumerable: descriptor.enumerable, + configurable: true, + writable: true, + value: cloned + }); + } else if ("get" in descriptor) { + Object.defineProperty(out, k, { + ...descriptor, + get() { + return cloned; + } + }); + } else { + Object.defineProperty(out, k, { + ...descriptor, + value: cloned + }); + } + } + return out; + } + return val; +} +function noop() {} +function objectAttr(source, path, defaultValue = undefined) { + // a[3].b -> a.3.b + const paths = path.replace(/\[(\d+)\]/g, ".$1").split("."); + let result = source; + for (const p of paths) { + result = new Object(result)[p]; + if (result === undefined) { + return defaultValue; + } + } + return result; +} +function createDefer() { + let resolve = null; + let reject = null; + const p = new Promise((_resolve, _reject) => { + resolve = _resolve; + reject = _reject; + }); + p.resolve = resolve; + p.reject = reject; + return p; +} +/** +* If code starts with a function call, will return its last index, respecting arguments. +* This will return 25 - last ending character of toMatch ")" +* Also works with callbacks +* ``` +* toMatch({ test: '123' }); +* toBeAliased('123') +* ``` +*/ +function getCallLastIndex(code) { + let charIndex = -1; + let inString = null; + let startedBracers = 0; + let endedBracers = 0; + let beforeChar = null; + while (charIndex <= code.length) { + beforeChar = code[charIndex]; + charIndex++; + const char = code[charIndex]; + const isCharString = char === "\"" || char === "'" || char === "`"; + if (isCharString && beforeChar !== "\\") { + if (inString === char) { + inString = null; + } else if (!inString) { + inString = char; + } + } + if (!inString) { + if (char === "(") { + startedBracers++; + } + if (char === ")") { + endedBracers++; + } + } + if (startedBracers && endedBracers && startedBracers === endedBracers) { + return charIndex; + } + } + return null; +} +function isNegativeNaN(val) { + if (!Number.isNaN(val)) { + return false; + } + const f64 = new Float64Array(1); + f64[0] = val; + const u32 = new Uint32Array(f64.buffer); + const isNegative = u32[1] >>> 31 === 1; + return isNegative; +} +function toString(v) { + return Object.prototype.toString.call(v); +} +function isPlainObject(val) { + return toString(val) === "[object Object]" && (!val.constructor || val.constructor.name === "Object"); +} +function isMergeableObject(item) { + return isPlainObject(item) && !Array.isArray(item); +} +/** +* Deep merge :P +* +* Will merge objects only if they are plain +* +* Do not merge types - it is very expensive and usually it's better to case a type here +*/ +function deepMerge(target, ...sources) { + if (!sources.length) { + return target; + } + const source = sources.shift(); + if (source === undefined) { + return target; + } + if (isMergeableObject(target) && isMergeableObject(source)) { + Object.keys(source).forEach((key) => { + const _source = source; + if (isMergeableObject(_source[key])) { + if (!target[key]) { + target[key] = {}; + } + deepMerge(target[key], _source[key]); + } else { + target[key] = _source[key]; + } + }); + } + return deepMerge(target, ...sources); +} + +export { assertTypes, cleanUrl, clone, createDefer, createSimpleStackTrace, deepClone, deepMerge, getCallLastIndex, getOwnProperties, getType, isBareImport, isExternalUrl, isNegativeNaN, isObject, isPrimitive, nanoid, noop, notNullish, objectAttr, shuffle, slash, toArray, unwrapId, withTrailingSlash, wrapId }; |
