-
-
Notifications
You must be signed in to change notification settings - Fork 175
/
stringify.ts
70 lines (68 loc) · 2.48 KB
/
stringify.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/** @hidden */
function stringifyNumber(numValue: number) {
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';
}
}
/** @hidden */
export function stringifyInternal<Ts>(value: Ts, previousValues: any[]): string {
const currentValues = previousValues.concat([value]);
if (typeof value === 'object') {
// early cycle detection for objects
if (previousValues.indexOf(value) !== -1) return '[cyclic]';
}
switch (Object.prototype.toString.call(value)) {
case '[object Array]':
return `[${(value as any).map((v: any) => 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 Map]':
return `new Map(${stringifyInternal(Array.from(value as any), 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 defaultRepr: string = value.toString();
if (defaultRepr !== '[object Object]') return defaultRepr;
return (
'{' +
Object.keys(value)
.map(k => `${JSON.stringify(k)}:${stringifyInternal((value as any)[k], currentValues)}`)
.join(',') +
'}'
);
} catch (err) {
return '[object Object]';
}
case '[object Set]':
return `new Set(${stringifyInternal(Array.from(value as any), currentValues)})`;
case '[object String]':
return typeof value === 'string' ? JSON.stringify(value) : `new String(${JSON.stringify(value)})`;
case '[object Undefined]':
return `undefined`;
default:
try {
return value.toString();
} catch {
return Object.prototype.toString.call(value);
}
}
}
/**
* Convert any value to its fast-check string representation
* @param value Value to be converted into a string
*/
export function stringify<Ts>(value: Ts): string {
return stringifyInternal(value, []);
}