UNPKG

fast-check

Version:

Property based testing framework for JavaScript (like QuickCheck)

89 lines (88 loc) 3.62 kB
const findSymbolNameRegex = /^Symbol\((.*)\)$/; function getSymbolDescription(s) { if (s.description !== undefined) return s.description; const m = findSymbolNameRegex.exec(String(s)); return m && m[1].length ? m[1] : null; } function stringifyNumber(numValue) { switch (numValue) { case 0: return 1 / numValue === Number.NEGATIVE_INFINITY ? '-0' : '0'; case Number.NEGATIVE_INFINITY: return 'Number.NEGATIVE_INFINITY'; case Number.POSITIVE_INFINITY: return 'Number.POSITIVE_INFINITY'; default: return numValue === numValue ? String(numValue) : 'Number.NaN'; } } export function stringifyInternal(value, previousValues) { const currentValues = previousValues.concat([value]); if (typeof value === 'object') { if (previousValues.indexOf(value) !== -1) return '[cyclic]'; } switch (Object.prototype.toString.call(value)) { case '[object Array]': return `[${value.map((v) => stringifyInternal(v, currentValues)).join(',')}]`; case '[object BigInt]': return `${value}n`; case '[object Boolean]': return typeof value === 'boolean' ? JSON.stringify(value) : `new Boolean(${JSON.stringify(value)})`; case '[object Date]': { const d = value; return Number.isNaN(d.getTime()) ? `new Date(NaN)` : `new Date(${JSON.stringify(d.toISOString())})`; } case '[object Map]': return `new Map(${stringifyInternal(Array.from(value), currentValues)})`; case '[object Null]': return `null`; case '[object Number]': return typeof value === 'number' ? stringifyNumber(value) : `new Number(${stringifyNumber(Number(value))})`; case '[object Object]': { try { const toStringAccessor = value.toString; if (typeof toStringAccessor === 'function' && toStringAccessor !== Object.prototype.toString) { return value.toString(); } } catch (err) { return '[object Object]'; } const rawRepr = '{' + Object.keys(value) .map((k) => `${k === '__proto__' ? '["__proto__"]' : JSON.stringify(k)}:${stringifyInternal(value[k], currentValues)}`) .join(',') + '}'; if (Object.getPrototypeOf(value) === null) { return rawRepr === '{}' ? 'Object.create(null)' : `Object.assign(Object.create(null),${rawRepr})`; } return rawRepr; } case '[object Set]': return `new Set(${stringifyInternal(Array.from(value), currentValues)})`; case '[object String]': return typeof value === 'string' ? JSON.stringify(value) : `new String(${JSON.stringify(value)})`; case '[object Symbol]': { const s = value; if (Symbol.keyFor(s) !== undefined) { return `Symbol.for(${JSON.stringify(Symbol.keyFor(s))})`; } const desc = getSymbolDescription(s); return desc !== null ? `Symbol(${JSON.stringify(desc)})` : `Symbol()`; } case '[object Undefined]': return `undefined`; default: try { return value.toString(); } catch (_a) { return Object.prototype.toString.call(value); } } } export function stringify(value) { return stringifyInternal(value, []); }