Best JavaScript code snippet using fast-check-monorepo
stringify.spec.ts
Source:stringify.spec.ts  
1import * as fc from 'fast-check';2// Importing 'buffer' imports the real implementation from node3// Instead we want 'buffer' from our node_modules - the most used polyfill for Buffer on browser-side4import { Buffer as NotNodeBuffer } from '../../../../../node_modules/buffer';5import {6  asyncStringify,7  asyncToStringMethod,8  possiblyAsyncStringify,9  stringify,10  toStringMethod,11} from '../../../src/utils/stringify';12declare function BigInt(n: number | bigint | string): bigint;13const checkEqual = (a: any, b: any): boolean => {14  try {15    expect(a).toEqual(b);16    return true;17  } catch (err) {18    return false;19  }20};21class ThrowingToString {22  toString() {23    throw new Error('No toString');24  }25}26class CustomTagThrowingToString {27  [Symbol.toStringTag] = 'CustomTagThrowingToString';28  toString() {29    throw new Error('No toString');30  }31}32const anythingEnableAll = {33  withBoxedValues: true,34  withMap: true,35  withSet: true,36  withObjectString: true,37  withNullPrototype: true,38  withDate: true,39  withTypedArray: true,40  withSparseArray: true,41  ...(typeof BigInt !== 'undefined' ? { withBigInt: true } : {}),42};43describe('stringify', () => {44  it('Should be able to stringify fc.anything()', () =>45    fc.assert(fc.property(fc.anything(anythingEnableAll), (a) => typeof stringify(a) === 'string')));46  it('Should be able to stringify fc.char16bits() (ie. possibly invalid strings)', () =>47    fc.assert(fc.property(fc.char16bits(), (a) => typeof stringify(a) === 'string')));48  if (typeof BigInt !== 'undefined') {49    it('Should be able to stringify bigint in object correctly', () =>50      fc.assert(fc.property(fc.bigInt(), (b) => stringify({ b }) === '{"b":' + b + 'n}')));51  }52  it('Should be equivalent to JSON.stringify for JSON compliant objects', () =>53    fc.assert(54      fc.property(55        // Remark: While fc.unicodeJsonObject() could have been a good alternative to fc.anything()56        //         it unfortunately cannot be used as JSON.stringify poorly handles negative zeros.57        // JSON.parse('{"a": -0}') -> preserves -058        // JSON.stringify({a: -0}) -> changes -0 into 0, it produces {"a":0}59        fc.anything({60          key: fc.string().filter((k) => k !== '__proto__'),61          values: [62            fc.boolean(),63            fc.integer(),64            fc.double({ noDefaultInfinity: true, noNaN: true }).filter((d) => !Object.is(d, -0)),65            fc.fullUnicodeString(),66            fc.constant(null),67          ],68        }),69        (obj) => {70          expect(stringify(obj)).toEqual(JSON.stringify(obj));71        }72      )73    ));74  it('Should be readable from eval', () =>75    fc.assert(76      fc.property(fc.anything(anythingEnableAll), (obj) => {77        expect(eval(`(function() { return ${stringify(obj)}; })()`)).toStrictEqual(obj as any);78      })79    ));80  it('Should stringify differently distinct objects', () =>81    fc.assert(82      fc.property(fc.anything(), fc.anything(), (a, b) => {83        fc.pre(!checkEqual(a, b));84        expect(stringify(a)).not.toEqual(stringify(b));85      })86    ));87  it('Should be able to stringify cyclic object', () => {88    const cyclic: any = { a: 1, b: 2, c: 3 };89    cyclic.b = cyclic;90    const repr = stringify(cyclic);91    expect(repr).toContain('"a"');92    expect(repr).toContain('"b"');93    expect(repr).toContain('"c"');94    expect(repr).toContain('[cyclic]');95    expect(repr).toEqual('{"a":1,"b":[cyclic],"c":3}');96  });97  it('Should be able to stringify cyclic arrays', () => {98    const cyclic: any[] = [1, 2, 3];99    cyclic.push(cyclic);100    cyclic.push(4);101    const repr = stringify(cyclic);102    expect(repr).toEqual('[1,2,3,[cyclic],4]');103  });104  it('Should be able to stringify small sparse arrays', () => {105    // eslint-disable-next-line no-sparse-arrays106    expect(stringify([,])).toEqual('[,]'); // empty with one hole107    // eslint-disable-next-line no-sparse-arrays108    expect(stringify([, ,])).toEqual('[,,]'); // empty with two holes109    // eslint-disable-next-line no-sparse-arrays110    expect(stringify([, , , ,])).toEqual('[,,,,]'); // empty with four holes111    // eslint-disable-next-line no-sparse-arrays112    expect(stringify([1, , ,])).toEqual('[1,,,]'); // one value then two holes113    // eslint-disable-next-line no-sparse-arrays114    expect(stringify([, , 1, , 2])).toEqual('[,,1,,2]'); // two holes non-trailing holes115    // eslint-disable-next-line no-sparse-arrays116    expect(stringify([1, , 2])).toEqual('[1,,2]'); // one hole non-trailing hole117    // eslint-disable-next-line no-sparse-arrays118    expect(stringify([1, 2, ,])).toEqual('[1,2,,]'); // two values then one hole119    // eslint-disable-next-line no-sparse-arrays120    expect(stringify([1, 2, , ,])).toEqual('[1,2,,,]'); // two values then two holes121  });122  it('Should be able to stringify large sparse arrays', () => {123    // eslint-disable-next-line no-sparse-arrays124    expect(stringify(Array(10000))).toEqual('Array(10000)');125    // eslint-disable-next-line no-sparse-arrays126    expect(stringify(Array(4294967295))).toEqual('Array(4294967295)');127    // eslint-disable-next-line no-sparse-arrays128    const sparseNonEmpty: any[] = Array(10000);129    sparseNonEmpty[150] = 5;130    sparseNonEmpty[21] = 1;131    sparseNonEmpty[200] = 10;132    expect(stringify(sparseNonEmpty)).toEqual('Object.assign(Array(10000),{21:1,150:5,200:10})');133    // Here are some possibilities for sparse versions:134    // > (s=Array(10000),s[21]=1,s[150]=5,s[200]=10,s)135    // > (()=>{const s=Array(10000);s[21]=1;s[150]=5;s[200]=10;return s;})()136    // > Object.assign(Array(10000), {21:1,150:5,200:10})137    // > [<20 empty slots>, 1,...] [cannot be copy-pasted]138    const sparseNonEmptyB: any[] = Array(4294967295);139    sparseNonEmptyB[1234567890] = 5;140    expect(stringify(sparseNonEmptyB)).toEqual('Object.assign(Array(4294967295),{1234567890:5})');141    const sparseNonEmptyC: any[] = Array(123456);142    sparseNonEmptyC[0] = 0;143    sparseNonEmptyC[1] = 1;144    expect(stringify(sparseNonEmptyC)).toEqual('Object.assign(Array(123456),{0:0,1:1})');145  });146  it('Should be able to stringify cyclic sets', () => {147    const cyclic: Set<any> = new Set([1, 2, 3]);148    cyclic.add(cyclic);149    cyclic.add(4);150    const repr = stringify(cyclic);151    expect(repr).toEqual('new Set([1,2,3,[cyclic],4])');152  });153  it('Should be able to stringify cyclic maps', () => {154    const cyclic: Map<any, any> = new Map();155    cyclic.set(1, 2);156    cyclic.set(3, cyclic);157    cyclic.set(cyclic, 4);158    cyclic.set(5, 6);159    const repr = stringify(cyclic);160    expect(repr).toEqual('new Map([[1,2],[3,[cyclic]],[[cyclic],4],[5,6]])');161  });162  it('Should be able to stringify values', () => {163    expect(stringify(null)).toEqual('null');164    expect(stringify(undefined)).toEqual('undefined');165    expect(stringify(false)).toEqual('false');166    expect(stringify(42)).toEqual('42');167    expect(stringify(-0)).toEqual('-0');168    expect(stringify(Number.POSITIVE_INFINITY)).toEqual('Number.POSITIVE_INFINITY');169    expect(stringify(Number.NEGATIVE_INFINITY)).toEqual('Number.NEGATIVE_INFINITY');170    expect(stringify(Number.NaN)).toEqual('Number.NaN');171    expect(stringify('Hello')).toEqual('"Hello"');172    if (typeof BigInt !== 'undefined') {173      expect(stringify(BigInt(42))).toEqual('42n');174    }175  });176  it('Should be able to stringify boxed values', () => {177    expect(stringify(new Boolean(false))).toEqual('new Boolean(false)');178    expect(stringify(new Number(42))).toEqual('new Number(42)');179    expect(stringify(new Number(-0))).toEqual('new Number(-0)');180    expect(stringify(new Number(Number.POSITIVE_INFINITY))).toEqual('new Number(Number.POSITIVE_INFINITY)');181    expect(stringify(new Number(Number.NEGATIVE_INFINITY))).toEqual('new Number(Number.NEGATIVE_INFINITY)');182    expect(stringify(new Number(Number.NaN))).toEqual('new Number(Number.NaN)');183    expect(stringify(new String('Hello'))).toEqual('new String("Hello")');184  });185  it('Should be able to stringify Date', () => {186    expect(stringify(new Date(NaN))).toEqual('new Date(NaN)');187    expect(stringify(new Date('2014-25-23'))).toEqual('new Date(NaN)');188    expect(stringify(new Date('2019-05-23T22:19:06.049Z'))).toEqual('new Date("2019-05-23T22:19:06.049Z")');189  });190  it('Should be able to stringify Regex', () => {191    expect(stringify(/\w+/)).toEqual('/\\w+/');192    expect(stringify(/^Hello(\d+)(\w*)$/gi)).toEqual('/^Hello(\\d+)(\\w*)$/gi');193    expect(stringify(new RegExp('\\w+'))).toEqual('/\\w+/');194  });195  it('Should be able to stringify Set', () => {196    expect(stringify(new Set([1, 2]))).toEqual('new Set([1,2])');197  });198  it('Should be able to stringify Map', () => {199    expect(stringify(new Map([[1, 2]]))).toEqual('new Map([[1,2]])');200  });201  it('Should be able to stringify Symbol', () => {202    expect(stringify(Symbol())).toEqual('Symbol()');203    expect(stringify(Symbol('fc'))).toEqual('Symbol("fc")');204    expect(stringify(Symbol.for('fc'))).toEqual('Symbol.for("fc")');205  });206  it('Should be able to stringify well-known Symbols', () => {207    expect(stringify(Symbol.iterator)).toEqual('Symbol.iterator');208    expect(stringify(Symbol('Symbol.iterator'))).toEqual('Symbol("Symbol.iterator")');209    // Same as above but with all the known symbols210    let foundOne = false;211    for (const symbolName of Object.getOwnPropertyNames(Symbol)) {212      const s = (Symbol as any)[symbolName];213      if (typeof s === 'symbol') {214        foundOne = true;215        expect(stringify(s)).toEqual(`Symbol.${symbolName}`);216        expect(stringify(Symbol(`Symbol.${symbolName}`))).toEqual(`Symbol("Symbol.${symbolName}")`);217        expect(eval(`(function() { return typeof ${stringify(s)}; })()`)).toBe('symbol');218      }219    }220    expect(foundOne).toBe(true);221  });222  it('Should be able to stringify Object', () => {223    expect(stringify({ a: 1 })).toEqual('{"a":1}');224    expect(stringify({ a: 1, b: 2 })).toEqual('{"a":1,"b":2}');225    expect(stringify({ [Symbol.for('a')]: 1 })).toEqual('{[Symbol.for("a")]:1}');226    expect(stringify({ a: 1, [Symbol.for('a')]: 1 })).toEqual('{"a":1,[Symbol.for("a")]:1}');227    expect(stringify({ [Symbol.for('a')]: 1, a: 1 })).toEqual('{"a":1,[Symbol.for("a")]:1}');228  });229  it('Should be able to stringify Object but skip non enumerable properties', () => {230    // At least for the moment we don't handle non enumerable properties231    const obj: any = {};232    Object.defineProperties(obj, {233      a: { value: 1, enumerable: false },234      b: { value: 1, enumerable: true },235      [Symbol.for('a')]: { value: 1, enumerable: false },236      [Symbol.for('b')]: { value: 1, enumerable: true },237    });238    expect(stringify(obj)).toEqual('{"b":1,[Symbol.for("b")]:1}');239  });240  it('Should be able to stringify instances of classes', () => {241    class A {242      public a: number;243      constructor() {244        this.a = 1;245        (this as any)[Symbol.for('a')] = 2;246      }247      public ma() {248        // no-op249      }250    }251    expect(stringify(new A())).toEqual('{"a":1,[Symbol.for("a")]:2}');252    class AA {253      public a = 0;254    }255    expect(stringify(new AA())).toEqual('{"a":0}');256  });257  it('Should be able to stringify instances of classes inheriting from others', () => {258    class A {259      public a: number;260      constructor() {261        this.a = 1;262        (this as any)[Symbol.for('a')] = 2;263      }264      public ma() {265        // no-op266      }267    }268    class B extends A {269      public b;270      constructor() {271        super();272        this.b = 3;273        (this as any)[Symbol.for('b')] = 4;274      }275      public mb() {276        // no-op277      }278    }279    expect(stringify(new B())).toEqual('{"a":1,"b":3,[Symbol.for("a")]:2,[Symbol.for("b")]:4}');280  });281  it('Should be able to stringify Object without prototype', () => {282    expect(stringify(Object.create(null))).toEqual('Object.create(null)');283    expect(stringify(Object.assign(Object.create(null), { a: 1 }))).toEqual(284      'Object.assign(Object.create(null),{"a":1})'285    );286    expect(stringify(Object.assign(Object.create(null), { [Symbol.for('a')]: 1 }))).toEqual(287      'Object.assign(Object.create(null),{[Symbol.for("a")]:1})'288    );289  });290  it('Should be able to stringify Object with custom __proto__ value', () => {291    expect(stringify({ ['__proto__']: 1 })).toEqual('{["__proto__"]:1}');292    // NOTE: {__proto__: 1} and {'__proto__': 1} are not the same as {['__proto__']: 1}293  });294  it('Should be able to stringify Object with custom __proto__ value and no prototype', () => {295    const instance = Object.assign(Object.create(null), { ['__proto__']: 1 });296    expect(stringify(instance)).toEqual('Object.assign(Object.create(null),{["__proto__"]:1})');297    // NOTE: {['__proto__']: 1} is not the same as Object.assign(Object.create(null),{["__proto__"]:1})298    // The first one has a prototype equal to Object, the second one has no prototype.299  });300  it('Should be able to stringify Promise but not show its value or status in sync mode', () => {301    const p1 = Promise.resolve(1); // resolved302    const p2 = Promise.reject(1); // rejected303    const p3 = new Promise(() => {}); // unresolved (ie pending)304    expect(stringify(p1)).toEqual('new Promise(() => {/*unknown*/})');305    expect(stringify(p2)).toEqual('new Promise(() => {/*unknown*/})');306    expect(stringify(p3)).toEqual('new Promise(() => {/*unknown*/})');307    expect(stringify({ p1 })).toEqual('{"p1":new Promise(() => {/*unknown*/})}');308    [p1, p2, p3].map((p) => p.catch(() => {})); // no unhandled rejections309  });310  it('Should be able to stringify Buffer', () => {311    expect(stringify(Buffer.from([1, 2, 3, 4]))).toEqual('Buffer.from([1,2,3,4])');312    expect(stringify(Buffer.alloc(3))).toEqual('Buffer.from([0,0,0])');313    expect(stringify(Buffer.alloc(4, 'a'))).toEqual('Buffer.from([97,97,97,97])');314    fc.assert(315      fc.property(fc.array(fc.nat(255)), (data) => {316        const buffer = Buffer.from(data);317        const stringifiedBuffer = stringify(buffer);318        const bufferFromStringified = eval(stringifiedBuffer);319        return Buffer.isBuffer(bufferFromStringified) && buffer.equals(bufferFromStringified);320      })321    );322  });323  it('Should be able to stringify a polyfill-ed Buffer', () => {324    const buffer = NotNodeBuffer.from([1, 2, 3, 4]);325    expect(NotNodeBuffer).not.toBe(Buffer);326    expect(buffer instanceof NotNodeBuffer).toBe(true);327    expect(buffer instanceof Buffer).toBe(false);328    expect(stringify(buffer)).toEqual('Buffer.from([1,2,3,4])');329  });330  it('Should be able to stringify Int8Array', () => {331    expect(stringify(Int8Array.from([-128, 5, 127]))).toEqual('Int8Array.from([-128,5,127])');332    assertStringifyTypedArraysProperly(fc.integer({ min: -128, max: 127 }), Int8Array.from.bind(Int8Array));333  });334  it('Should be able to stringify Uint8Array', () => {335    expect(stringify(Uint8Array.from([255, 0, 5, 127]))).toEqual('Uint8Array.from([255,0,5,127])');336    assertStringifyTypedArraysProperly(fc.integer({ min: 0, max: 255 }), Uint8Array.from.bind(Uint8Array));337  });338  it('Should be able to stringify Int16Array', () => {339    expect(stringify(Int16Array.from([-32768, 5, 32767]))).toEqual('Int16Array.from([-32768,5,32767])');340    assertStringifyTypedArraysProperly(fc.integer({ min: -32768, max: 32767 }), Int16Array.from.bind(Int16Array));341  });342  it('Should be able to stringify Uint16Array', () => {343    expect(stringify(Uint16Array.from([65535, 0, 5, 32767]))).toEqual('Uint16Array.from([65535,0,5,32767])');344    assertStringifyTypedArraysProperly(fc.integer({ min: 0, max: 65535 }), Uint16Array.from.bind(Uint16Array));345  });346  it('Should be able to stringify Int32Array', () => {347    expect(stringify(Int32Array.from([-2147483648, 5, 2147483647]))).toEqual(348      'Int32Array.from([-2147483648,5,2147483647])'349    );350    assertStringifyTypedArraysProperly(351      fc.integer({ min: -2147483648, max: 2147483647 }),352      Int32Array.from.bind(Int32Array)353    );354  });355  it('Should be able to stringify Uint32Array', () => {356    expect(stringify(Uint32Array.from([4294967295, 0, 5, 2147483647]))).toEqual(357      'Uint32Array.from([4294967295,0,5,2147483647])'358    );359    assertStringifyTypedArraysProperly(fc.integer({ min: 0, max: 4294967295 }), Uint32Array.from.bind(Uint32Array));360  });361  it('Should be able to stringify Float32Array', () => {362    expect(stringify(Float32Array.from([0, 0.5, 30, -1]))).toEqual('Float32Array.from([0,0.5,30,-1])');363    assertStringifyTypedArraysProperly(fc.float(), Float32Array.from.bind(Float32Array));364  });365  it('Should be able to stringify Float64Array', () => {366    expect(stringify(Float64Array.from([0, 0.5, 30, -1]))).toEqual('Float64Array.from([0,0.5,30,-1])');367    assertStringifyTypedArraysProperly(fc.double(), Float64Array.from.bind(Float64Array));368  });369  if (typeof BigInt !== 'undefined') {370    it('Should be able to stringify BigInt64Array', () => {371      expect(stringify(BigInt64Array.from([BigInt(-2147483648), BigInt(5), BigInt(2147483647)]))).toEqual(372        'BigInt64Array.from([-2147483648n,5n,2147483647n])'373      );374      assertStringifyTypedArraysProperly<bigint>(fc.bigIntN(64), BigInt64Array.from.bind(BigInt64Array));375    });376    it('Should be able to stringify BigUint64Array', () => {377      expect(stringify(BigUint64Array.from([BigInt(0), BigInt(5), BigInt(2147483647)]))).toEqual(378        'BigUint64Array.from([0n,5n,2147483647n])'379      );380      assertStringifyTypedArraysProperly<bigint>(fc.bigUintN(64), BigUint64Array.from.bind(BigUint64Array));381    });382  }383  it('Should be only produce toStringTag for failing toString', () => {384    expect(stringify(new ThrowingToString())).toEqual('[object Object]');385    expect(stringify(new CustomTagThrowingToString())).toEqual('[object CustomTagThrowingToString]');386    // TODO Move to getter-based implementation instead - es5 required387    const instance = Object.create(null);388    Object.defineProperty(instance, 'toString', {389      get: () => {390        throw new Error('No such accessor');391      },392    });393    expect(stringify(instance)).toEqual('[object Object]');394  });395  it('Should use [toStringMethod] if any on the instance or its prototype', () => {396    const instance1 = { [toStringMethod]: () => 'hello1' };397    expect(stringify(instance1)).toEqual('hello1');398    const instance2 = Object.create(null);399    Object.defineProperty(instance2, toStringMethod, {400      value: () => 'hello2',401      configurable: false,402      enumerable: false,403      writable: false,404    });405    expect(stringify(instance2)).toEqual('hello2');406    // prettier-ignore407    const instance3 = { [toStringMethod]: () => { throw new Error('hello3'); } };408    expect(stringify(instance3)).toEqual(409      '{[Symbol("fast-check/toStringMethod")]:() => { throw new Error(\'hello3\'); }}'410    ); // fallbacking to default411    class InProto {412      [toStringMethod]() {413        return 'hello4';414      }415    }416    const instance4 = new InProto();417    expect(stringify(instance4)).toEqual('hello4');418    const instance5 = { [toStringMethod]: 1 }; // not callable419    expect(stringify(instance5)).toEqual('{[Symbol("fast-check/toStringMethod")]:1}');420  });421  it('Should not be able to rely on the output of [asyncToStringMethod] in sync mode', () => {422    const instance1 = { [asyncToStringMethod]: () => 'hello1' }; // not even async there423    expect(stringify(instance1)).toEqual('{[Symbol("fast-check/asyncToStringMethod")]:() => \'hello1\'}'); // fallbacking to default424    const instance2 = { [asyncToStringMethod]: () => 'hello2', [toStringMethod]: () => 'world' };425    expect(stringify(instance2)).toEqual('world'); // fallbacking to [toStringMethod]426    const instance3ProbeFn = jest.fn();427    const instance3 = { [asyncToStringMethod]: instance3ProbeFn };428    stringify(instance3);429    expect(instance3ProbeFn).not.toHaveBeenCalled(); // never calling [asyncToStringMethod] in sync mode430  });431});432describe('possiblyAsyncStringify', () => {433  it('Should behave as "stringify" for synchronous values produced by fc.anything()', () =>434    fc.assert(435      fc.property(fc.anything(anythingEnableAll), (value) => {436        const expectedStringifiedValue = stringify(value);437        const stringifiedValue = possiblyAsyncStringify(value);438        expect(typeof stringifiedValue).toBe('string');439        expect(stringifiedValue as string).toBe(expectedStringifiedValue);440      })441    ));442  it('Should return the same string as "stringify" wrapped into Promise.resolve for Promises on values produced by fc.anything()', () =>443    fc.assert(444      fc.asyncProperty(fc.anything(anythingEnableAll), async (value) => {445        const expectedStringifiedValue = stringify(value);446        const stringifiedValue = possiblyAsyncStringify(Promise.resolve(value));447        expect(typeof stringifiedValue).not.toBe('string');448        expect(await stringifiedValue).toBe(`Promise.resolve(${expectedStringifiedValue})`);449      })450    ));451});452describe('asyncStringify', () => {453  it('Should return the same string as "stringify" for synchronous values produced by fc.anything()', () =>454    fc.assert(455      fc.asyncProperty(fc.anything(anythingEnableAll), async (value) => {456        const expectedStringifiedValue = stringify(value);457        const stringifiedValue = asyncStringify(value);458        expect(typeof stringifiedValue).not.toBe('string');459        expect(await stringifiedValue).toBe(expectedStringifiedValue);460      })461    ));462  it('Should return the same string as "stringify" wrapped into Promise.resolve for Promises on values produced by fc.anything()', () =>463    fc.assert(464      fc.asyncProperty(fc.anything(anythingEnableAll), async (value) => {465        const expectedStringifiedValue = stringify(value);466        const stringifiedValue = asyncStringify(Promise.resolve(value));467        expect(typeof stringifiedValue).not.toBe('string');468        expect(await stringifiedValue).toBe(`Promise.resolve(${expectedStringifiedValue})`);469      })470    ));471  it('Should be able to stringify resolved Promise', async () => {472    const p = Promise.resolve(1);473    expect(await asyncStringify(p)).toEqual('Promise.resolve(1)');474  });475  it('Should be able to stringify rejected Promise', async () => {476    const p = Promise.reject(1);477    expect(await asyncStringify(p)).toEqual('Promise.reject(1)');478    p.catch(() => {}); // no unhandled rejections479  });480  it('Should be able to stringify rejected Promise with Error', async () => {481    const p = Promise.reject(new Error('message'));482    expect(await asyncStringify(p)).toEqual('Promise.reject(new Error("message"))');483    p.catch(() => {}); // no unhandled rejections484  });485  it('Should be able to stringify pending Promise', async () => {486    const p = new Promise(() => {});487    expect(await asyncStringify(p)).toEqual('new Promise(() => {/*pending*/})');488  });489  it('Should be able to stringify Promise in other instances', async () => {490    const p1 = Promise.resolve(1);491    expect(await asyncStringify([p1])).toEqual('[Promise.resolve(1)]');492    expect(await asyncStringify(new Set([p1]))).toEqual('new Set([Promise.resolve(1)])');493    expect(await asyncStringify({ p1 })).toEqual('{"p1":Promise.resolve(1)}');494  });495  it('Should be able to stringify nested Promise', async () => {496    const nestedPromises = Promise.resolve({497      lvl1: Promise.resolve({498        lvl2: Promise.resolve(2),499      }),500    });501    expect(await asyncStringify(nestedPromises)).toEqual(502      'Promise.resolve({"lvl1":Promise.resolve({"lvl2":Promise.resolve(2)})})'503    );504  });505  it('Should be able to stringify self nested Promise', async () => {506    const resolvedValueChildLvl1 = {507      a1: Promise.resolve<unknown>(null),508    };509    const resolvedValue = {510      a: Promise.resolve(resolvedValueChildLvl1),511      b: { b1: Promise.resolve(resolvedValueChildLvl1) },512    };513    const nestedPromises = Promise.resolve(resolvedValue);514    resolvedValueChildLvl1.a1 = nestedPromises;515    expect(await asyncStringify(nestedPromises)).toEqual(516      'Promise.resolve({"a":Promise.resolve({"a1":[cyclic]}),"b":{"b1":Promise.resolve({"a1":[cyclic]})}})'517    );518  });519  it('Should use [asyncToStringMethod] if any on the instance or its prototype', async () => {520    const instance1 = { [asyncToStringMethod]: async () => 'hello1' };521    expect(await asyncStringify(instance1)).toEqual('hello1');522    const instance2 = Object.create(null);523    Object.defineProperty(instance2, asyncToStringMethod, {524      value: () => 'hello2',525      configurable: false,526      enumerable: false,527      writable: false,528    });529    expect(await asyncStringify(instance2)).toEqual('hello2');530    const instance3 = { [asyncToStringMethod]: async () => 'hello3', [toStringMethod]: () => 'world' };531    expect(await asyncStringify(instance3)).toEqual('hello3'); // even when [toStringMethod] has been defined532    // prettier-ignore533    const instance4 = { [asyncToStringMethod]: async () => { throw new Error('hello4'); } };534    expect(await asyncStringify(instance4)).toEqual(535      '{[Symbol("fast-check/asyncToStringMethod")]:async () => { throw new Error(\'hello4\'); }}'536    ); // fallbacking to default537    // prettier-ignore538    const instance5 = { [asyncToStringMethod]: async () => { throw new Error('hello5'); }, [toStringMethod]: () => "world" };539    expect(await asyncStringify(instance5)).toEqual('world'); // fallbacking to [toStringMethod]540    // prettier-ignore541    const instance6 = { [asyncToStringMethod]: () => { throw new Error('hello6'); } }; // throw is sync542    expect(await asyncStringify(instance6)).toEqual(543      '{[Symbol("fast-check/asyncToStringMethod")]:() => { throw new Error(\'hello6\'); }}'544    ); // fallbacking to default545    class InProto {546      async [asyncToStringMethod]() {547        return 'hello7';548      }549    }550    const instance7 = new InProto();551    expect(await asyncStringify(instance7)).toEqual('hello7');552    const instance8 = { [asyncToStringMethod]: 1 }; // not callable553    expect(await asyncStringify(instance8)).toEqual('{[Symbol("fast-check/asyncToStringMethod")]:1}');554    const instance9 = {555      [asyncToStringMethod]: async () => {556        const s1 = await asyncStringify(Promise.resolve('hello9'));557        const s2 = await asyncStringify(Promise.resolve('world9'));558        return `${s1} ${s2}`;559      },560    };561    expect(await asyncStringify(instance9)).toEqual('Promise.resolve("hello9") Promise.resolve("world9")');562    const p10 = Promise.resolve('hello10');563    const instance10 = { [asyncToStringMethod]: () => p10.then((v) => `got: ${v}`) };564    expect(await asyncStringify(instance10)).toEqual('got: hello10');565  });566});567// Helpers568function assertStringifyTypedArraysProperly<TNumber>(569  arb: fc.Arbitrary<TNumber>,570  typedArrayProducer: (data: TNumber[]) => { values: () => IterableIterator<TNumber>; [Symbol.toStringTag]: string }571): void {572  fc.assert(573    fc.property(fc.array(arb), (data) => {574      const typedArray = typedArrayProducer(data);575      const stringifiedTypedArray = stringify(typedArray);576      const typedArrayFromStringified: typeof typedArray = eval(stringifiedTypedArray);577      expect(typedArrayFromStringified[Symbol.toStringTag]).toEqual(typedArray[Symbol.toStringTag]);578      expect([...typedArrayFromStringified.values()]).toEqual([...typedArray.values()]);579    })580  );...Using AI Code Generation
1const { instance3ProbeFn } = require('fast-check-monorepo');2instance3ProbeFn();3const { instance4ProbeFn } = require('fast-check-monorepo');4instance4ProbeFn();5const { instance5ProbeFn } = require('fast-check-monorepo');6instance5ProbeFn();7const { instance6ProbeFn } = require('fast-check-monorepo');8instance6ProbeFn();9const { instance7ProbeFn } = require('fast-check-monorepo');10instance7ProbeFn();11const { instance8ProbeFn } = require('fast-check-monorepo');12instance8ProbeFn();13const { instance9ProbeFn } = require('fast-check-monorepo');14instance9ProbeFn();15const { instance10ProbeFn } = require('fast-check-monorepo');16instance10ProbeFn();17const { instance11ProbeFn } = require('fast-check-monorepo');18instance11ProbeFn();19const { instance12ProbeFn } = require('fast-check-monorepo');20instance12ProbeFn();21const { instance13ProbeFn } = require('fast-check-monorepo');22instance13ProbeFn();23const { instance14ProbeFn } = require('fast-check-monorepo');24instance14ProbeFn();Using AI Code Generation
1const { instance3ProbeFn } = require('fast-check-monorepo')2const isEven = (n) => n % 2 === 03const isOdd = (n) => n % 2 !== 04const isEvenOrOdd = (n) => isEven(n) || isOdd(n)5test('isEvenOrOdd', () => {6  fc.assert(7    fc.property(fc.integer(), (n) => {8      expect(isEvenOrOdd(n)).toBe(true)9    })10})11const { instance3ProbeFn } = require('fast-check-monorepo')12const isEven = (n) => n % 2 === 013const isOdd = (n) => n % 2 !== 014const isEvenOrOdd = (n) => isEven(n) || isOdd(n)15test('isEvenOrOdd', () => {16  fc.assert(17    fc.property(fc.integer(), (n) => {18      expect(isEvenOrOdd(n)).toBe(true)19    })20})21const { instance3ProbeFn } = require('fast-check-monorepo')22const isEven = (n) => n % 2 === 023const isOdd = (n) => n % 2 !== 024const isEvenOrOdd = (n) => isEven(n) || isOdd(n)25test('isEvenOrOdd', () => {26  fc.assert(27    fc.property(fc.integer(), (n) => {28      expect(isEvenOrOdd(n)).toBe(true)29    })30})31const { instance3ProbeFn } = require('fast-check-monorepo')32const isEven = (n) => n % 2 === 033const isOdd = (n) => n % 2 !== 034const isEvenOrOdd = (n) => isEven(n) || isOdd(n)35test('isEvenOrOdd', () => {36  fc.assert(37    fc.property(fc.integer(), (n) => {38      expect(isEvenOrOdd(n)).toBe(true)39    })40})Using AI Code Generation
1const instance3ProbeFn = require('fast-check-monorepo').instance3ProbeFn;2const instance4ProbeFn = require('fast-check-monorepo').instance4ProbeFn;3const instance5ProbeFn = require('fast-check-monorepo').instance5ProbeFn;4const instance6ProbeFn = require('fast-check-monorepo').instance6ProbeFn;5const instance7ProbeFn = require('fast-check-monorepo').instance7ProbeFn;6const instance8ProbeFn = require('fast-check-monorepo').instance8ProbeFn;7const instance9ProbeFn = require('fast-check-monorepo').instance9ProbeFn;8const instance10ProbeFn = require('fast-check-monorepo').instance10ProbeFn;9const instance11ProbeFn = require('fast-check-monorepo').instance11ProbeFn;Using AI Code Generation
1import { instance3ProbeFn } from 'fast-check';2import { NextArbitrary } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';3import { NextValue } from 'fast-check/lib/check/arbitrary/definition/NextValue';4import { NextArbitrary as NextArbitrary1 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';5import { NextValue as NextValue1 } from 'fast-check/lib/check/arbitrary/definition/NextValue';6import { NextArbitrary as NextArbitrary2 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';7import { NextValue as NextValue2 } from 'fast-check/lib/check/arbitrary/definition/NextValue';8import { NextArbitrary as NextArbitrary3 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';9import { NextValue as NextValue3 } from 'fast-check/lib/check/arbitrary/definition/NextValue';10import { NextArbitrary as NextArbitrary4 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';11import { NextValue as NextValue4 } from 'fast-check/lib/check/arbitrary/definition/NextValue';12import { NextArbitrary as NextArbitrary5 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';13import { NextValue as NextValue5 } from 'fast-check/lib/check/arbitrary/definition/NextValue';14import { NextArbitrary as NextArbitrary6 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';15import { NextValue as NextValue6 } from 'fast-check/lib/check/arbitrary/definition/NextValue';16import { NextArbitrary as NextArbitrary7 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';17import { NextValue as NextValue7 } from 'fast-check/lib/check/arbitrary/definition/NextValue';18import { NextArbitrary as NextArbitrary8 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';19import { NextValue as NextValue8 } from 'fast-check/lib/check/arbitrary/definition/NextValue';20import { NextArbitrary as NextArbitrary9 } from 'fast-check/lib/check/arbitrary/definition/NextArbitrary';21import { NextValue as NextValue9 } from 'fast-check/lib/check/arUsing AI Code Generation
1import { instance3ProbeFn } from 'fast-check-monorepo'2const myProbe = instance3ProbeFn()3console.log(myProbe())4{5  "scripts": {6  },7  "dependencies": {8  }9}10import { instance3ProbeFn } from 'fast-check-monorepo'11const myProbe = instance3ProbeFn()12console.log(myProbe())13import { instance3ProbeFn } from 'fast-check-monorepo'14const myProbe = instance3ProbeFn()15for (let i = 0; i < 10; i++) {16  console.log(myProbe())17}Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
