Best JavaScript code snippet using fast-check-monorepo
ArrayArbitrary.spec.ts
Source:ArrayArbitrary.spec.ts
1import fc from 'fast-check';2import prand from 'pure-rand';3import { ArrayArbitrary } from '../../../../src/arbitrary/_internals/ArrayArbitrary';4import { Value } from '../../../../src/check/arbitrary/definition/Value';5import { MaxLengthUpperBound } from '../../../../src/arbitrary/_internals/helpers/MaxLengthFromMinLength';6import { CustomSet } from '../../../../src/arbitrary/_internals/interfaces/CustomSet';7import { Stream } from '../../../../src/stream/Stream';8import { cloneMethod, hasCloneMethod } from '../../../../src/check/symbols';9import { Arbitrary } from '../../../../src/check/arbitrary/definition/Arbitrary';10import { Random } from '../../../../src/random/generator/Random';11import * as IntegerMock from '../../../../src/arbitrary/integer';12import { fakeArbitrary } from '../__test-helpers__/ArbitraryHelpers';13import { fakeRandom } from '../__test-helpers__/RandomHelpers';14import { buildShrinkTree, walkTree } from '../__test-helpers__/ShrinkTree';15import * as DepthContextMock from '../../../../src/arbitrary/_internals/helpers/DepthContext';16function beforeEachHook() {17 jest.resetModules();18 jest.restoreAllMocks();19 fc.configureGlobal({ beforeEach: beforeEachHook });20}21beforeEach(beforeEachHook);22describe('ArrayArbitrary', () => {23 describe('generate', () => {24 it('should concat all the generated values together when no set constraints ', () => {25 fc.assert(26 fc.property(27 fc.array(fc.tuple(fc.anything(), fc.anything())),28 fc.nat(),29 fc.nat(MaxLengthUpperBound),30 fc.nat(MaxLengthUpperBound),31 fc.anything(),32 (generatedValues, seed, aLength, bLength, integerContext) => {33 // Arrange34 const { acceptedValues, instance, generate } = prepareSetBuilderData(generatedValues, false);35 const { minLength, maxGeneratedLength, maxLength } = extractLengths(seed, aLength, bLength, acceptedValues);36 const { instance: integerInstance, generate: generateInteger } = fakeArbitrary();37 generateInteger.mockReturnValue(new Value(acceptedValues.size, integerContext));38 const integer = jest.spyOn(IntegerMock, 'integer');39 integer.mockReturnValue(integerInstance);40 const { instance: mrng } = fakeRandom();41 // Act42 const arb = new ArrayArbitrary(43 instance,44 minLength,45 maxGeneratedLength,46 maxLength,47 undefined,48 undefined,49 []50 );51 const g = arb.generate(mrng, undefined);52 // Assert53 expect(g.hasToBeCloned).toBe(false);54 expect(g.value).toEqual([...acceptedValues].map((v) => v.value));55 expect(integer).toHaveBeenCalledTimes(1);56 expect(integer).toHaveBeenCalledWith({ min: minLength, max: maxGeneratedLength });57 expect(generateInteger).toHaveBeenCalledTimes(1);58 expect(generateInteger).toHaveBeenCalledWith(mrng, undefined);59 expect(generate).toHaveBeenCalledTimes(acceptedValues.size);60 for (const call of generate.mock.calls) {61 expect(call).toEqual([mrng, undefined]);62 }63 }64 )65 );66 });67 it("should not concat all the values together in case they don't follow set contraints", () => {68 fc.assert(69 fc.property(70 fc.array(fc.tuple(fc.anything(), fc.anything(), fc.boolean())),71 fc.nat(),72 fc.nat(MaxLengthUpperBound),73 fc.nat(MaxLengthUpperBound),74 fc.anything(),75 (generatedValues, seed, aLength, bLength, integerContext) => {76 // Arrange77 const { acceptedValues, instance, generate, setBuilder } = prepareSetBuilderData(generatedValues, false);78 const { minLength, maxGeneratedLength, maxLength } = extractLengths(seed, aLength, bLength, acceptedValues);79 const { instance: integerInstance, generate: generateInteger } = fakeArbitrary();80 generateInteger.mockReturnValue(new Value(acceptedValues.size, integerContext));81 const integer = jest.spyOn(IntegerMock, 'integer');82 integer.mockReturnValue(integerInstance);83 const { instance: mrng } = fakeRandom();84 // Act85 const arb = new ArrayArbitrary(86 instance,87 minLength,88 maxGeneratedLength,89 maxLength,90 undefined,91 setBuilder,92 []93 );94 const g = arb.generate(mrng, undefined);95 // Assert96 expect(g.hasToBeCloned).toBe(false);97 // In the case of set the generated value might be smaller98 // The generator is allowed to stop whenever it considers at already tried to many times (maxGeneratedLength times)99 expect(g.value).toEqual([...acceptedValues].map((v) => v.value).slice(0, g.value.length));100 expect(integer).toHaveBeenCalledTimes(1);101 expect(integer).toHaveBeenCalledWith({ min: minLength, max: maxGeneratedLength });102 expect(generateInteger).toHaveBeenCalledTimes(1);103 expect(generateInteger).toHaveBeenCalledWith(mrng, undefined);104 expect(setBuilder).toHaveBeenCalledTimes(1);105 for (const call of generate.mock.calls) {106 expect(call).toEqual([mrng, undefined]);107 }108 }109 )110 );111 });112 it("should always pass bias to values' arbitrary when minLength equals maxGeneratedLength", () => {113 fc.assert(114 fc.property(115 fc.array(fc.tuple(fc.anything(), fc.anything(), fc.boolean())),116 fc.nat(),117 fc.nat(MaxLengthUpperBound),118 fc.anything(),119 fc.integer({ min: 2 }),120 fc.boolean(),121 (generatedValues, seed, aLength, integerContext, biasFactor, withSetBuilder) => {122 // Arrange123 const { acceptedValues, instance, setBuilder, generate } = prepareSetBuilderData(124 generatedValues,125 !withSetBuilder126 );127 const { minLength, maxLength } = extractLengths(seed, aLength, aLength, acceptedValues);128 const { instance: integerInstance, generate: generateInteger } = fakeArbitrary();129 generateInteger.mockReturnValue(new Value(minLength, integerContext));130 const integer = jest.spyOn(IntegerMock, 'integer');131 integer.mockReturnValue(integerInstance);132 const { instance: mrng } = fakeRandom();133 // Act134 const arb = new ArrayArbitrary(135 instance,136 minLength,137 minLength,138 maxLength,139 undefined,140 withSetBuilder ? setBuilder : undefined,141 []142 );143 const g = arb.generate(mrng, biasFactor);144 // Assert145 expect(g.hasToBeCloned).toBe(false);146 if (!withSetBuilder) {147 // In the case of set the generated value might be smaller148 // The generator is allowed to stop whenever it considers at already tried to many times (maxGeneratedLength times)149 expect(g.value).toEqual([...acceptedValues].map((v) => v.value).slice(0, minLength));150 } else {151 expect(g.value).toEqual(152 [...acceptedValues].map((v) => v.value).slice(0, Math.min(g.value.length, minLength))153 );154 }155 expect(integer).toHaveBeenCalledTimes(1);156 expect(integer).toHaveBeenCalledWith({ min: minLength, max: minLength });157 expect(generateInteger).toHaveBeenCalledTimes(1);158 expect(generateInteger).toHaveBeenCalledWith(mrng, undefined); // no need to bias it159 expect(setBuilder).toHaveBeenCalledTimes(withSetBuilder ? 1 : 0);160 expect(generate.mock.calls.length).toBeGreaterThanOrEqual(minLength);161 for (const call of generate.mock.calls) {162 expect(call).toEqual([mrng, biasFactor]); // but bias all sub-values163 }164 }165 )166 );167 });168 it('should bias depth the same way for any child and reset it at the end', () => {169 fc.assert(170 fc.property(171 fc.array(fc.tuple(fc.anything(), fc.anything(), fc.boolean())),172 fc.nat(),173 fc.nat(MaxLengthUpperBound),174 fc.nat(MaxLengthUpperBound),175 fc.anything(),176 fc.integer({ min: 2 }),177 fc.boolean(),178 (generatedValues, seed, aLength, bLength, integerContext, biasFactor, withSetBuilder) => {179 // Arrange180 const getDepthContextFor = jest.spyOn(DepthContextMock, 'getDepthContextFor');181 const depthContext = { depth: 0 };182 getDepthContextFor.mockReturnValue(depthContext);183 const seenDepths = new Set<number>();184 const { acceptedValues, instance, generate, setBuilder } = prepareSetBuilderData(185 generatedValues,186 !withSetBuilder,187 () => {188 seenDepths.add(depthContext.depth);189 }190 );191 const { minLength, maxGeneratedLength, maxLength } = extractLengths(seed, aLength, bLength, acceptedValues);192 const { instance: integerInstance, generate: generateInteger } = fakeArbitrary();193 generateInteger.mockReturnValue(new Value(minLength, integerContext));194 const integer = jest.spyOn(IntegerMock, 'integer');195 integer.mockReturnValue(integerInstance);196 const { instance: mrng } = fakeRandom();197 // Act198 const arb = new ArrayArbitrary(199 instance,200 minLength,201 maxGeneratedLength,202 maxLength,203 undefined,204 withSetBuilder ? setBuilder : undefined,205 []206 );207 arb.generate(mrng, biasFactor);208 // Assert209 expect(getDepthContextFor).toHaveBeenCalledTimes(1); // only array calls it in the test210 expect(depthContext.depth).toBe(0); // properly reset211 if (generate.mock.calls.length !== 0) {212 expect([...seenDepths]).toHaveLength(1); // always called with same depth213 } else {214 expect([...seenDepths]).toHaveLength(0); // never called on items215 }216 }217 )218 );219 });220 it('should produce a cloneable instance if provided one cloneable underlying', () => {221 // Arrange222 const { instance, generate } = fakeArbitrary<string[]>();223 generate224 .mockReturnValueOnce(new Value(['a'], undefined))225 .mockReturnValueOnce(new Value(Object.defineProperty(['b'], cloneMethod, { value: jest.fn() }), undefined))226 .mockReturnValueOnce(new Value(['c'], undefined))227 .mockReturnValueOnce(new Value(['d'], undefined));228 const { instance: integerInstance, generate: generateInteger } = fakeArbitrary();229 generateInteger.mockReturnValue(new Value(4, undefined));230 const integer = jest.spyOn(IntegerMock, 'integer');231 integer.mockReturnValue(integerInstance);232 const { instance: mrng } = fakeRandom();233 // Act234 const arb = new ArrayArbitrary(instance, 0, 10, 100, undefined, undefined, []);235 const g = arb.generate(mrng, undefined);236 // Assert237 expect(g.hasToBeCloned).toBe(true);238 expect(hasCloneMethod(g.value)).toBe(true);239 expect(g.value_).not.toEqual([['a'], ['b'], ['c'], ['d']]); // 2nd item is not just ['b']240 expect(g.value_.map((v) => [...v])).toEqual([['a'], ['b'], ['c'], ['d']]);241 });242 it('should not clone cloneable on generate', () => {243 // Arrange244 const cloneMethodImpl = jest.fn();245 const { instance, generate } = fakeArbitrary<string[]>();246 generate247 .mockReturnValueOnce(new Value(['a'], undefined))248 .mockReturnValueOnce(249 new Value(Object.defineProperty(['b'], cloneMethod, { value: cloneMethodImpl }), undefined)250 )251 .mockReturnValueOnce(new Value(['c'], undefined))252 .mockReturnValueOnce(new Value(['d'], undefined));253 const { instance: integerInstance, generate: generateInteger } = fakeArbitrary();254 generateInteger.mockReturnValue(new Value(4, undefined));255 const integer = jest.spyOn(IntegerMock, 'integer');256 integer.mockReturnValue(integerInstance);257 const { instance: mrng } = fakeRandom();258 // Act259 const arb = new ArrayArbitrary(instance, 0, 10, 100, undefined, undefined, []);260 const g = arb.generate(mrng, undefined);261 // Assert262 expect(cloneMethodImpl).not.toHaveBeenCalled();263 g.value; // not calling clone as this is the first access264 expect(cloneMethodImpl).not.toHaveBeenCalled();265 g.value; // calling clone as this is the second access266 expect(cloneMethodImpl).toHaveBeenCalledTimes(1);267 g.value; // calling clone (again) as this is the third access268 expect(cloneMethodImpl).toHaveBeenCalledTimes(2);269 g.value_; // not calling clone as we access value_ not value270 expect(cloneMethodImpl).toHaveBeenCalledTimes(2);271 });272 });273 describe('canShrinkWithoutContext', () => {274 it('should reject any array not matching the requirements on length', () => {275 fc.assert(276 fc.property(277 fc.array(fc.anything()),278 fc.boolean(),279 fc.nat(MaxLengthUpperBound),280 fc.nat(MaxLengthUpperBound),281 fc.nat(MaxLengthUpperBound),282 (value, withSetBuilder, aLength, bLength, cLength) => {283 // Arrange284 const [minLength, maxGeneratedLength, maxLength] = [aLength, bLength, cLength].sort((a, b) => a - b);285 fc.pre(value.length < minLength || value.length > maxLength);286 const { instance, canShrinkWithoutContext } = fakeArbitrary();287 const data: any[] = [];288 const customSet: CustomSet<Value<any>> = {289 size: () => data.length,290 getData: () => data,291 tryAdd: (vTest) => {292 data.push(vTest.value_);293 return true;294 },295 };296 const setBuilder = jest.fn();297 setBuilder.mockReturnValue(customSet);298 // Act299 const arb = new ArrayArbitrary(300 instance,301 minLength,302 maxGeneratedLength,303 maxLength,304 undefined,305 withSetBuilder ? setBuilder : undefined,306 []307 );308 const out = arb.canShrinkWithoutContext(value);309 // Assert310 expect(out).toBe(false);311 expect(canShrinkWithoutContext).not.toHaveBeenCalled();312 expect(setBuilder).not.toHaveBeenCalled();313 }314 )315 );316 });317 it('should reject any array with at least one entry rejected by the sub-arbitrary', () => {318 fc.assert(319 fc.property(320 fc.uniqueArray(fc.tuple(fc.anything(), fc.boolean()), {321 minLength: 1,322 selector: (v) => v[0],323 comparator: 'SameValue',324 }),325 fc.boolean(),326 fc.nat(MaxLengthUpperBound),327 fc.nat(MaxLengthUpperBound),328 fc.nat(MaxLengthUpperBound),329 (value, withSetBuilder, offsetMin, offsetMax, maxGeneratedLength) => {330 // Arrange331 fc.pre(value.some((v) => !v[1]));332 const minLength = Math.min(Math.max(0, value.length - offsetMin), maxGeneratedLength);333 const maxLength = Math.max(Math.min(MaxLengthUpperBound, value.length + offsetMax), maxGeneratedLength);334 const { instance, canShrinkWithoutContext } = fakeArbitrary();335 canShrinkWithoutContext.mockImplementation((vTest) => value.find((v) => Object.is(v[0], vTest))![1]);336 const data: any[] = [];337 const customSet: CustomSet<Value<any>> = {338 size: () => data.length,339 getData: () => data,340 tryAdd: (vTest) => {341 data.push(vTest.value_);342 return true;343 },344 };345 const setBuilder = jest.fn();346 setBuilder.mockReturnValue(customSet);347 // Act348 const arb = new ArrayArbitrary(349 instance,350 minLength,351 maxGeneratedLength,352 maxLength,353 undefined,354 withSetBuilder ? setBuilder : undefined,355 []356 );357 const out = arb.canShrinkWithoutContext(value.map((v) => v[0]));358 // Assert359 expect(out).toBe(false);360 expect(canShrinkWithoutContext).toHaveBeenCalled();361 }362 )363 );364 });365 it('should reject any array not matching requirements for set constraints', () => {366 fc.assert(367 fc.property(368 fc.uniqueArray(fc.tuple(fc.anything(), fc.boolean()), {369 minLength: 1,370 selector: (v) => v[0],371 comparator: 'SameValue',372 }),373 fc.nat(MaxLengthUpperBound),374 fc.nat(MaxLengthUpperBound),375 fc.nat(MaxLengthUpperBound),376 (value, offsetMin, offsetMax, maxGeneratedLength) => {377 // Arrange378 fc.pre(value.some((v) => !v[1]));379 const minLength = Math.min(Math.max(0, value.length - offsetMin), maxGeneratedLength);380 const maxLength = Math.max(Math.min(MaxLengthUpperBound, value.length + offsetMax), maxGeneratedLength);381 const { instance, canShrinkWithoutContext } = fakeArbitrary();382 canShrinkWithoutContext.mockReturnValue(true);383 const data: any[] = [];384 const customSet: CustomSet<Value<any>> = {385 size: () => data.length,386 getData: () => data,387 tryAdd: (vTest) => {388 if (value.find((v) => Object.is(v[0], vTest.value_))![1]) {389 data.push(vTest.value_);390 return true;391 }392 return false;393 },394 };395 const setBuilder = jest.fn();396 setBuilder.mockReturnValue(customSet);397 // Act398 const arb = new ArrayArbitrary(399 instance,400 minLength,401 maxGeneratedLength,402 maxLength,403 undefined,404 setBuilder,405 []406 );407 const out = arb.canShrinkWithoutContext(value.map((v) => v[0]));408 // Assert409 expect(out).toBe(false);410 expect(canShrinkWithoutContext).toHaveBeenCalled();411 expect(setBuilder).toHaveBeenCalled();412 }413 )414 );415 });416 it('should reject any sparse array', () => {417 fc.assert(418 fc.property(419 fc.sparseArray(fc.anything()),420 fc.boolean(),421 fc.nat(MaxLengthUpperBound),422 fc.nat(MaxLengthUpperBound),423 fc.nat(MaxLengthUpperBound),424 (value, withSetBuilder, offsetMin, offsetMax, maxGeneratedLength) => {425 // Arrange426 fc.pre(value.length !== Object.keys(value).length);427 const minLength = Math.min(Math.max(0, value.length - offsetMin), maxGeneratedLength);428 const maxLength = Math.max(Math.min(MaxLengthUpperBound, value.length + offsetMax), maxGeneratedLength);429 const { instance, canShrinkWithoutContext } = fakeArbitrary();430 canShrinkWithoutContext.mockReturnValue(true);431 const data: any[] = [];432 const customSet: CustomSet<Value<any>> = {433 size: () => data.length,434 getData: () => data,435 tryAdd: (vTest) => {436 data.push(vTest.value_);437 return true;438 },439 };440 const setBuilder = jest.fn();441 setBuilder.mockReturnValue(customSet);442 // Act443 const arb = new ArrayArbitrary(444 instance,445 minLength,446 maxGeneratedLength,447 maxLength,448 undefined,449 withSetBuilder ? setBuilder : undefined,450 []451 );452 const out = arb.canShrinkWithoutContext(value);453 // Assert454 expect(out).toBe(false);455 }456 )457 );458 });459 it('should accept all other arrays', () => {460 fc.assert(461 fc.property(462 fc.array(fc.anything()),463 fc.boolean(),464 fc.nat(MaxLengthUpperBound),465 fc.nat(MaxLengthUpperBound),466 fc.nat(MaxLengthUpperBound),467 (value, withSetBuilder, offsetMin, offsetMax, maxGeneratedLength) => {468 // Arrange469 const minLength = Math.min(Math.max(0, value.length - offsetMin), maxGeneratedLength);470 const maxLength = Math.max(Math.min(MaxLengthUpperBound, value.length + offsetMax), maxGeneratedLength);471 const { instance, canShrinkWithoutContext } = fakeArbitrary();472 canShrinkWithoutContext.mockReturnValue(true);473 const data: any[] = [];474 const customSet: CustomSet<Value<any>> = {475 size: () => data.length,476 getData: () => data,477 tryAdd: (vTest) => {478 data.push(vTest.value_);479 return true;480 },481 };482 const setBuilder = jest.fn();483 setBuilder.mockReturnValue(customSet);484 // Act485 const arb = new ArrayArbitrary(486 instance,487 minLength,488 maxGeneratedLength,489 maxLength,490 undefined,491 withSetBuilder ? setBuilder : undefined,492 []493 );494 const out = arb.canShrinkWithoutContext(value);495 // Assert496 expect(out).toBe(true);497 }498 )499 );500 });501 });502});503describe('ArrayArbitrary (integration)', () => {504 it('should not re-use twice the same instance of cloneable', () => {505 // Arrange506 const alreadySeenCloneable = new Set<unknown>();507 const mrng = new Random(prand.mersenne(0));508 const arb = new ArrayArbitrary(new CloneableArbitrary(), 0, 5, 100, undefined, undefined, []); // 0 to 5 generated items509 // Act510 let g = arb.generate(mrng, undefined);511 while (g.value.length !== 3) {512 // 3 allows to shrink something large enough but not too large513 // walking through the tree when >3 takes much longer514 g = arb.generate(mrng, undefined);515 }516 const treeA = buildShrinkTree(arb, g);517 const treeB = buildShrinkTree(arb, g);518 // Assert519 walkTree(treeA, (cloneable) => {520 expect(alreadySeenCloneable.has(cloneable)).toBe(false);521 alreadySeenCloneable.add(cloneable);522 for (const subCloneable of cloneable) {523 expect(alreadySeenCloneable.has(subCloneable)).toBe(false);524 alreadySeenCloneable.add(subCloneable);525 }526 });527 walkTree(treeB, (cloneable) => {528 expect(alreadySeenCloneable.has(cloneable)).toBe(false);529 alreadySeenCloneable.add(cloneable);530 for (const subCloneable of cloneable) {531 expect(alreadySeenCloneable.has(subCloneable)).toBe(false);532 alreadySeenCloneable.add(subCloneable);533 }534 });535 });536});537// Helpers538function prepareSetBuilderData(539 generatedValues: [value: any, context: any, rejected?: boolean][],540 acceptAll: boolean,541 onGenerateHook?: () => void542) {543 const acceptedValues = new Set<Value<any>>();544 const { instance, generate } = fakeArbitrary();545 for (const v of generatedValues) {546 const value = new Value(v[0], v[1]);547 const rejected = v[2];548 if (!rejected || acceptAll) {549 acceptedValues.add(value);550 }551 generate.mockImplementationOnce(() => {552 if (onGenerateHook !== undefined) {553 onGenerateHook();554 }555 return value;556 });557 }558 const data: any[] = [];559 const customSet: CustomSet<Value<any>> = {560 size: () => data.length,561 getData: () => data,562 tryAdd: (value) => {563 if (acceptedValues.has(value)) {564 data.push(value);565 return true;566 }567 return false;568 },569 };570 const setBuilder = jest.fn();571 setBuilder.mockReturnValue(customSet);572 return { acceptedValues, instance, generate, setBuilder };573}574function extractLengths(minLengthSeed: number, aLength: number, bLength: number, acceptedValues: Set<unknown>) {575 const minLength = minLengthSeed % (acceptedValues.size || 1);576 const [maxGeneratedLength, maxLength] = aLength < bLength ? [aLength, bLength] : [bLength, aLength];577 fc.pre(maxGeneratedLength >= acceptedValues.size);578 return { minLength, maxGeneratedLength, maxLength };579}580class CloneableArbitrary extends Arbitrary<number[]> {581 private instance() {582 return Object.defineProperty([], cloneMethod, { value: () => this.instance() });583 }584 generate(_mrng: Random): Value<number[]> {585 return new Value(this.instance(), { shrunkOnce: false });586 }587 canShrinkWithoutContext(_value: unknown): _value is number[] {588 throw new Error('No call expected in that scenario');589 }590 shrink(value: number[], context?: unknown): Stream<Value<number[]>> {591 if (typeof context !== 'object' || context === null || !('shrunkOnce' in context)) {592 throw new Error('Invalid context for CloneableArbitrary');593 }594 const safeContext = context as { shrunkOnce: boolean };595 if (safeContext.shrunkOnce) {596 return Stream.nil();597 }598 return Stream.of(new Value(this.instance(), { shrunkOnce: true }));599 }...
CloneArbitrary.spec.ts
Source:CloneArbitrary.spec.ts
1import fc from 'fast-check';2import { CloneArbitrary } from '../../../../src/arbitrary/_internals/CloneArbitrary';3import { Arbitrary } from '../../../../src/check/arbitrary/definition/Arbitrary';4import { Value } from '../../../../src/check/arbitrary/definition/Value';5import { cloneMethod, hasCloneMethod } from '../../../../src/check/symbols';6import { Random } from '../../../../src/random/generator/Random';7import { Stream } from '../../../../src/stream/Stream';8import {9 assertProduceValuesShrinkableWithoutContext,10 assertProduceCorrectValues,11 assertShrinkProducesSameValueWithoutInitialContext,12 assertShrinkProducesStrictlySmallerValue,13 assertProduceSameValueGivenSameSeed,14} from '../__test-helpers__/ArbitraryAssertions';15import { FakeIntegerArbitrary, fakeArbitrary } from '../__test-helpers__/ArbitraryHelpers';16import { fakeRandom } from '../__test-helpers__/RandomHelpers';17import { buildShrinkTree, renderTree, walkTree } from '../__test-helpers__/ShrinkTree';18describe('CloneArbitrary', () => {19 describe('generate', () => {20 it('should call generate numValues times on the passed arbitrary', () => {21 // Arrange22 const numValues = 3;23 const biasFactor = 48;24 const producedValue = Symbol();25 const { instance: mrng, clone } = fakeRandom();26 const { instance: mrngClone1 } = fakeRandom();27 const { instance: mrngClone2 } = fakeRandom();28 clone.mockReturnValueOnce(mrngClone1).mockReturnValueOnce(mrngClone2);29 const { instance: sourceArb, generate } = fakeArbitrary<symbol>();30 generate.mockReturnValue(new Value(producedValue, undefined));31 // Act32 const arb = new CloneArbitrary(sourceArb, numValues);33 const out = arb.generate(mrng, biasFactor);34 // Assert35 expect(out.value).toEqual([producedValue, producedValue, producedValue]);36 expect(generate).toHaveBeenCalledTimes(3);37 expect(generate).toHaveBeenCalledWith(mrngClone1, biasFactor);38 expect(generate).toHaveBeenCalledWith(mrngClone2, biasFactor);39 expect(generate).toHaveBeenLastCalledWith(mrng, biasFactor);40 });41 it.each`42 type | cloneable43 ${'non-cloneable'} | ${false}44 ${'cloneable'} | ${true}45 `('should produce a $type tuple when sub-value is $type', ({ cloneable }) => {46 // Arrange47 const numValues = 1;48 const { instance: mrng } = fakeRandom();49 const { instance: sourceArb, generate } = fakeArbitrary<unknown>();50 if (cloneable) generate.mockReturnValue(new Value({ [cloneMethod]: jest.fn() }, undefined));51 else generate.mockReturnValue(new Value({ m: jest.fn() }, undefined));52 // Act53 const arb = new CloneArbitrary(sourceArb, numValues);54 const out = arb.generate(mrng, numValues);55 // Assert56 expect(out.hasToBeCloned).toBe(cloneable);57 expect(hasCloneMethod(out.value)).toBe(cloneable);58 });59 });60 describe('canShrinkWithoutContext', () => {61 it('should return false if passed value does not have the right length', () =>62 fc.assert(63 fc.property(fc.nat({ max: 1000 }), fc.nat({ max: 1000 }), (numValues, numRequestedValues) => {64 // Arrange65 fc.pre(numValues !== numRequestedValues);66 const { instance: sourceArb, canShrinkWithoutContext } = fakeArbitrary();67 // Act68 const arb = new CloneArbitrary(sourceArb, numValues);69 const out = arb.canShrinkWithoutContext([...Array(numRequestedValues)]);70 // Assert71 expect(out).toBe(false);72 expect(canShrinkWithoutContext).not.toHaveBeenCalled();73 })74 ));75 it('should return false if values are not equal regarding Object.is', () => {76 // Arrange77 const { instance: sourceArb, canShrinkWithoutContext } = fakeArbitrary();78 // Act79 const arb = new CloneArbitrary(sourceArb, 2);80 const out = arb.canShrinkWithoutContext([{}, {}]);81 // Assert82 expect(out).toBe(false);83 expect(canShrinkWithoutContext).not.toHaveBeenCalled();84 });85 it.each`86 canShrinkWithoutContextValue87 ${true}88 ${false}89 `(90 'should ask sub-arbitrary whenever length is correct and children are equal regarding Object.is',91 ({ canShrinkWithoutContextValue }) => {92 // Arrange93 const value = {};94 const { instance: sourceArb, canShrinkWithoutContext } = fakeArbitrary();95 canShrinkWithoutContext.mockReturnValue(canShrinkWithoutContextValue);96 // Act97 const arb = new CloneArbitrary(sourceArb, 2);98 const out = arb.canShrinkWithoutContext([value, value]);99 // Assert100 expect(out).toBe(canShrinkWithoutContextValue);101 expect(canShrinkWithoutContext).toHaveBeenCalledTimes(1);102 expect(canShrinkWithoutContext).toHaveBeenCalledWith(value);103 }104 );105 });106 describe('shrink', () => {107 it('should shrink numValues times the value and zip the outputs together', () => {108 // Arrange109 const value = Symbol();110 const s1 = Symbol();111 const s2 = Symbol();112 const numValues = 3;113 const { instance: sourceArb, shrink } = fakeArbitrary<symbol>();114 shrink115 .mockReturnValueOnce(Stream.of<Value<symbol>>(new Value(s1, undefined), new Value(s2, undefined)))116 .mockReturnValueOnce(Stream.of<Value<symbol>>(new Value(s1, undefined), new Value(s2, undefined)))117 .mockReturnValueOnce(Stream.of<Value<symbol>>(new Value(s1, undefined), new Value(s2, undefined)));118 // Act119 const arb = new CloneArbitrary(sourceArb, numValues);120 const shrinks = [...arb.shrink([value, value, value])];121 // Assert122 expect(shrinks.map((v) => v.value)).toEqual([123 [s1, s1, s1],124 [s2, s2, s2],125 ]);126 expect(shrink).toHaveBeenCalledTimes(3);127 expect(shrink).toHaveBeenCalledWith(value, undefined);128 });129 });130});131describe('CloneArbitrary (integration)', () => {132 type Extra = number;133 const extraParameters: fc.Arbitrary<Extra> = fc.nat({ max: 100 });134 const isCorrect = (value: number[], extra: Extra) =>135 Array.isArray(value) && value.length === extra && new Set(value).size <= 1;136 // Should never be called for extra = 0137 const isStrictlySmaller = (t1: number[], t2: number[]) => t1[0] < t2[0];138 const cloneBuilder = (extra: Extra) => new CloneArbitrary(new FakeIntegerArbitrary(), extra);139 it('should produce the same values given the same seed', () => {140 assertProduceSameValueGivenSameSeed(cloneBuilder, { extraParameters });141 });142 it('should only produce correct values', () => {143 assertProduceCorrectValues(cloneBuilder, isCorrect, { extraParameters });144 });145 it('should produce values seen as shrinkable without any context', () => {146 // Only when equal regarding Object.is147 assertProduceValuesShrinkableWithoutContext(cloneBuilder, { extraParameters });148 });149 it('should be able to shrink to the same values without initial context (if underlyings do)', () => {150 assertShrinkProducesSameValueWithoutInitialContext(cloneBuilder, { extraParameters });151 });152 it('should preserve strictly smaller ordering in shrink (if underlyings do)', () => {153 assertShrinkProducesStrictlySmallerValue(cloneBuilder, isStrictlySmaller, { extraParameters });154 });155 it('should produce the right shrinking tree', () => {156 // Arrange157 const arb = new CloneArbitrary(new FirstArbitrary(), 5);158 const { instance: mrng } = fakeRandom();159 // Act160 const g = arb.generate(mrng, undefined);161 const renderedTree = renderTree(buildShrinkTree(arb, g)).join('\n');162 // Assert163 expect(renderedTree).toMatchInlineSnapshot(`164 "[4,4,4,4,4]165 â> [2,2,2,2,2]166 | â> [0,0,0,0,0]167 â> [3,3,3,3,3]168 â> [0,0,0,0,0]169 â> [1,1,1,1,1]"170 `);171 });172 it('should not re-use twice the same instance of cloneable', () => {173 // Arrange174 const alreadySeenCloneable = new Set<unknown>();175 const arb = new CloneArbitrary(new CloneableArbitrary(), 5);176 const { instance: mrng } = fakeRandom();177 // Act178 const g = arb.generate(mrng, undefined);179 const treeA = buildShrinkTree(arb, g);180 const treeB = buildShrinkTree(arb, g);181 // Assert182 walkTree(treeA, ([_first, cloneable, _second]) => {183 expect(alreadySeenCloneable.has(cloneable)).toBe(false);184 alreadySeenCloneable.add(cloneable);185 });186 walkTree(treeB, ([_first, cloneable, _second]) => {187 expect(alreadySeenCloneable.has(cloneable)).toBe(false);188 alreadySeenCloneable.add(cloneable);189 });190 });191});192// Helpers193const expectedFirst = 4;194class FirstArbitrary extends Arbitrary<number> {195 generate(_mrng: Random): Value<number> {196 return new Value(expectedFirst, { step: 2 });197 }198 canShrinkWithoutContext(_value: unknown): _value is number {199 throw new Error('No call expected in that scenario');200 }201 shrink(value: number, context?: unknown): Stream<Value<number>> {202 if (typeof context !== 'object' || context === null || !('step' in context)) {203 throw new Error('Invalid context for FirstArbitrary');204 }205 if (value <= 0) {206 return Stream.nil();207 }208 const currentStep = (context as { step: number }).step;209 const nextStep = currentStep + 1;210 return Stream.of(211 ...(value - currentStep >= 0 ? [new Value(value - currentStep, { step: nextStep })] : []),212 ...(value - currentStep + 1 >= 0 ? [new Value(value - currentStep + 1, { step: nextStep })] : [])213 );214 }215}216class CloneableArbitrary extends Arbitrary<number[]> {217 private instance() {218 return Object.defineProperty([], cloneMethod, { value: () => this.instance() });219 }220 generate(_mrng: Random): Value<number[]> {221 return new Value(this.instance(), { shrunkOnce: false });222 }223 canShrinkWithoutContext(_value: unknown): _value is number[] {224 throw new Error('No call expected in that scenario');225 }226 shrink(value: number[], context?: unknown): Stream<Value<number[]>> {227 if (typeof context !== 'object' || context === null || !('shrunkOnce' in context)) {228 throw new Error('Invalid context for CloneableArbitrary');229 }230 const safeContext = context as { shrunkOnce: boolean };231 if (safeContext.shrunkOnce) {232 return Stream.nil();233 }234 return Stream.of(new Value(this.instance(), { shrunkOnce: true }));235 }...
ConstantArbitrary.spec.ts
Source:ConstantArbitrary.spec.ts
1import fc from 'fast-check';2import { ConstantArbitrary } from '../../../../src/arbitrary/_internals/ConstantArbitrary';3import { fakeRandom } from '../__test-helpers__/RandomHelpers';4import { cloneMethod } from '../../../../src/check/symbols';5import {6 assertProduceValuesShrinkableWithoutContext,7 assertProduceCorrectValues,8 assertShrinkProducesStrictlySmallerValue,9 assertProduceSameValueGivenSameSeed,10} from '../__test-helpers__/ArbitraryAssertions';11import { buildShrinkTree, walkTree } from '../__test-helpers__/ShrinkTree';12describe('ConstantArbitrary', () => {13 describe('generate', () => {14 it('should never call Random when provided a single value', () => {15 // Arrange16 const expectedBiasFactor = 48;17 const value = Symbol();18 const { instance: mrng } = fakeRandom();19 // Act20 const arb = new ConstantArbitrary([value]);21 const g = arb.generate(mrng, expectedBiasFactor);22 // Assert23 expect(g.value).toEqual(value);24 expect(g.hasToBeCloned).toBe(false);25 });26 it('should call Random to generate any integer in [0, length-1] when provided multiple values', () =>27 fc.assert(28 fc.property(29 fc.array(fc.anything(), { minLength: 2 }),30 fc.option(fc.integer({ min: 2 }), { nil: undefined }),31 fc.nat(),32 (values, biasFactor, mod) => {33 // Arrange34 const { instance: mrng, nextInt } = fakeRandom();35 nextInt.mockImplementation((a, b) => a + (mod % (b - a + 1)));36 // Act37 const arb = new ConstantArbitrary(values);38 const g = arb.generate(mrng, biasFactor);39 // Assert40 expect(nextInt).toHaveBeenCalledTimes(1);41 expect(nextInt).toHaveBeenCalledWith(0, values.length - 1);42 expect(values).toContainEqual(g.value);43 }44 )45 ));46 it('should be able to generate any of the requested values', () =>47 fc.assert(48 fc.property(49 fc.array(fc.anything(), { minLength: 2 }),50 fc.option(fc.integer({ min: 2 }), { nil: undefined }),51 (values, biasFactor) => {52 // Arrange53 const { instance: mrng, nextInt } = fakeRandom();54 // Act / Assert55 const arb = new ConstantArbitrary(values);56 const notSeenValues = [...values];57 for (let idx = 0; idx !== values.length; ++idx) {58 nextInt.mockImplementationOnce((a, _b) => a + idx);59 const g = arb.generate(mrng, biasFactor);60 const index = notSeenValues.findIndex((v) => Object.is(g.value, v));61 expect(index).not.toBe(-1);62 notSeenValues.splice(index, 1);63 }64 expect(notSeenValues).toEqual([]);65 }66 )67 ));68 it('should produce a cloneable instance if provided value is cloneable', () => {69 // Arrange70 const expectedBiasFactor = 48;71 const cloneable = Object.defineProperty([], cloneMethod, { value: jest.fn() });72 const { instance: mrng } = fakeRandom();73 // Act74 const arb = new ConstantArbitrary([cloneable]);75 const g = arb.generate(mrng, expectedBiasFactor);76 // Assert77 expect(g.hasToBeCloned).toBe(true);78 });79 it('should clone cloneable instances for each access', () => {80 // Arrange81 const expectedBiasFactor = 48;82 const cloneMethodImpl = jest.fn();83 const cloneable = Object.defineProperty([], cloneMethod, { value: cloneMethodImpl });84 cloneMethodImpl.mockReturnValue(cloneable); // in reality it should be a clone of it, not itself85 const { instance: mrng } = fakeRandom();86 // Act87 const arb = new ConstantArbitrary([cloneable]);88 const g = arb.generate(mrng, expectedBiasFactor);89 expect(cloneMethodImpl).not.toHaveBeenCalled();90 // Assert91 g.value;92 expect(cloneMethodImpl).toHaveBeenCalledTimes(1);93 g.value;94 expect(cloneMethodImpl).toHaveBeenCalledTimes(2);95 });96 });97 describe('canShrinkWithoutContext', () => {98 it("should mark value as 'canShrinkWithoutContext' whenever one of the original values is equal regarding Object.is", () =>99 fc.assert(100 fc.property(fc.array(fc.anything(), { minLength: 1 }), fc.nat(), (values, mod) => {101 // Arrange102 const selectedValue = values[mod % values.length];103 // Act104 const arb = new ConstantArbitrary(values);105 const out = arb.canShrinkWithoutContext(selectedValue);106 // Assert107 expect(out).toBe(true);108 })109 ));110 it('should not detect values not equal regarding to Object.is', () => {111 // Arrange112 const values: unknown[] = [0, [], {}, ''];113 const selectedValue: unknown = [];114 // Act115 const arb = new ConstantArbitrary<unknown>(values);116 const out = arb.canShrinkWithoutContext(selectedValue);117 // Assert118 expect(out).toBe(false); // Object.is([], []) is falsy119 });120 });121 describe('shrink', () => {122 it('should shrink towards the first value if it was not already this one and to nil otherwise', () =>123 fc.assert(124 fc.property(fc.array(fc.anything(), { minLength: 1 }), fc.nat(), (values, mod) => {125 // Arrange126 const { instance: mrng, nextInt } = fakeRandom();127 nextInt.mockImplementation((a, b) => a + (mod % (b - a + 1)));128 // Act129 const arb = new ConstantArbitrary(values);130 const value = arb.generate(mrng, undefined);131 const shrinks = [...arb.shrink(value.value, value.context)];132 // Assert133 if (Object.is(value.value, values[0])) {134 expect(shrinks.map((v) => v.value)).toEqual([]);135 } else {136 expect(shrinks.map((v) => v.value)).toEqual([values[0]]);137 }138 })139 ));140 it('should shrink towards the first value if it was not already this one and to nil otherwise even without any context', () =>141 fc.assert(142 fc.property(fc.array(fc.anything(), { minLength: 1 }), fc.nat(), (values, mod) => {143 // Arrange144 const { instance: mrng, nextInt } = fakeRandom();145 nextInt.mockImplementation((a, b) => a + (mod % (b - a + 1)));146 // Act147 const arb = new ConstantArbitrary(values);148 const value = arb.generate(mrng, undefined);149 const shrinks = [...arb.shrink(value.value, undefined)];150 // Assert151 if (Object.is(value.value, values[0])) {152 expect(shrinks.map((v) => v.value)).toEqual([]);153 } else {154 expect(shrinks.map((v) => v.value)).toEqual([values[0]]);155 }156 })157 ));158 it('should not shrink towards the first value if generated value is equal to the first one regarding `Object.is`', () => {159 // Arrange160 const { instance: mrng, nextInt } = fakeRandom();161 // Act / Assert162 const arb = new ConstantArbitrary([Number.NaN, Number.NaN, Number.NaN]);163 for (let idx = 0; idx !== 3; ++idx) {164 nextInt.mockReturnValue(idx);165 const value = arb.generate(mrng, undefined);166 expect(value.value).toBe(Number.NaN);167 const shrinks = [...arb.shrink(value.value, value.context)];168 expect(shrinks).toHaveLength(0);169 }170 });171 });172});173describe('ConstantArbitrary (integration)', () => {174 type Extra = unknown[];175 const extraParameters: fc.Arbitrary<Extra> = fc.array(fc.anything(), { minLength: 1 });176 // In other words: extra.includes(value) --but with Object.is177 const isCorrect = (value: unknown, extra: Extra) => extra.findIndex((v) => Object.is(value, v)) !== -1;178 // In other words: extra.indexOf(v1) < extra.indexOf(v2) --but with Object.is179 // If the same value has been declared twice in the `extra` once for `extra[0]` and the other for `extra[n]` (with n > 0)180 // Shrinker should never shrink `extra[n]` into `extra[0]` if they are equal regarding `Object.is`181 const isStrictlySmaller = (v1: unknown, v2: unknown, extra: Extra) =>182 extra.findIndex((v) => Object.is(v1, v)) < extra.findIndex((v) => Object.is(v2, v));183 const constantBuilder = (extra: Extra) => new ConstantArbitrary(extra);184 it('should produce the same values given the same seed', () => {185 assertProduceSameValueGivenSameSeed(constantBuilder, { extraParameters });186 });187 it('should only produce correct values', () => {188 assertProduceCorrectValues(constantBuilder, isCorrect, { extraParameters });189 });190 it('should produce values seen as shrinkable without any context', () => {191 assertProduceValuesShrinkableWithoutContext(constantBuilder, { extraParameters });192 });193 it('should preserve strictly smaller ordering in shrink', () => {194 assertShrinkProducesStrictlySmallerValue(constantBuilder, isStrictlySmaller, { extraParameters });195 });196 it('should not re-use twice the same instance of cloneable', () => {197 // Arrange198 const alreadySeenCloneable = new Set<unknown>();199 const buildCloneable = (): unknown => {200 return Object.defineProperty([], cloneMethod, { value: buildCloneable });201 };202 const arb = new ConstantArbitrary([buildCloneable()]);203 const { instance: mrng } = fakeRandom();204 // Act205 const g = arb.generate(mrng, undefined);206 const treeA = buildShrinkTree(arb, g);207 const treeB = buildShrinkTree(arb, g);208 // Assert209 walkTree(treeA, (cloneable) => {210 expect(alreadySeenCloneable.has(cloneable)).toBe(false);211 alreadySeenCloneable.add(cloneable);212 });213 walkTree(treeB, (cloneable) => {214 expect(alreadySeenCloneable.has(cloneable)).toBe(false);215 alreadySeenCloneable.add(cloneable);216 });217 });...
Using AI Code Generation
1const { alreadySeenCloneable } = require('fast-check');2const seen = new Set();3const { alreadySeenCloneable } = require('fast-check-cloneable');4const seen = new Set();5const { alreadySeenCloneable } = require('fast-check-cloneable');6const seen = new Set();7const { alreadySeenCloneable } = require('fast-check-cloneable');8const seen = new Set();9const { alreadySeenCloneable } = require('fast-check-cloneable');10const seen = new Set();11const { alreadySeenCloneable } = require('fast-check-cloneable');12const seen = new Set();13const { alreadySeenCloneable } = require('fast-check-cloneable');14const seen = new Set();15const { alreadySeenCloneable } = require('fast-check-cloneable');16const seen = new Set();
Using AI Code Generation
1const { alreadySeenCloneable } = require('fast-check');2const { Arbitrary } = require('fast-check/lib/types/definition/Arbitrary');3const myArbitrary = new Arbitrary();4myArbitrary.canGenerate = (v) => {5 console.log('canGenerate called with', v);6 return true;7};8const myArbitrary2 = new Arbitrary();9myArbitrary2.canGenerate = (v) => {10 console.log('canGenerate called with', v);11 return true;12};13console.log(alreadySeenCloneable(myArbitrary, myArbitrary2));14const { alreadySeenCloneable } = require('fast-check');15const { Arbitrary } = require('fast-check/lib/types/definition/Arbitrary');16const myArbitrary = new Arbitrary();17myArbitrary.canGenerate = (v) => {18 console.log('canGenerate called with', v);19 return true;20};21const myArbitrary2 = new Arbitrary();22myArbitrary2.canGenerate = (v) => {23 console.log('canGenerate called with', v);24 return true;25};26const myArbitrary3 = new Arbitrary();27myArbitrary3.canGenerate = (v) => {28 console.log('canGenerate called with', v);29 return true;30};31console.log(alreadySeenCloneable(myArbitrary, myArbitrary3));
Using AI Code Generation
1const {alreadySeenCloneable} = require('fast-check');2const {string} = require('fast-check');3const {cloneable} = require('fast-check');4const {clone} = require('fast-check');5const {cloneMethod} = require('fast-check');6const {cloneMethodNoop} = require('fast-check');7const {cloneMethodThrow} = require('fast-check');8const c = cloneable({9});
Using AI Code Generation
1const { alreadySeenCloneable } = require('fast-check');2const seen = new Set();3const seenCloneable = new Set();4const cloneable = new Set();5const notCloneable = new Set();6const isCloneable = (value) => {7 try {8 JSON.stringify(value);9 return true;10 } catch (e) {11 return false;12 }13};14const seenCloneableFn = (value) => {15 if (!alreadySeenCloneable(value, seen)) {16 if (isCloneable(value)) {17 cloneable.add(value);18 } else {19 notCloneable.add(value);20 }21 }22 seen.add(value);23};24const seenCloneableFn2 = (value) => {25 if (!alreadySeenCloneable(value, seenCloneable)) {26 if (isCloneable(value)) {27 cloneable.add(value);28 } else {29 notCloneable.add(value);30 }31 }32 seenCloneable.add(value);33};34const seenCloneableFn3 = (value) => {35 if (!alreadySeenCloneable(value, seen)) {36 if (isCloneable(value)) {37 cloneable.add(value);38 } else {39 notCloneable.add(value);40 }41 }42 seenCloneable.add(value);43};44const seenCloneableFn4 = (value) => {45 if (!alreadySeenCloneable(value, seenCloneable)) {46 if (isCloneable(value)) {47 cloneable.add(value);48 } else {49 notCloneable.add(value);50 }51 }52 seen.add(value);53};54const seenCloneableFn5 = (value) => {55 if (!alreadySeenCloneable(value, seen)) {56 if (isCloneable(value)) {57 cloneable.add(value);58 } else {59 notCloneable.add(value);60 }61 }62 seenCloneable.add(value);63};64const seenCloneableFn6 = (value) => {65 if (!alreadySeenCloneable(value, seenCloneable)) {66 if (isCloneable(value)) {67 cloneable.add(value);68 } else {69 notCloneable.add(value);70 }71 }72 seenCloneable.add(value);73};74const seenCloneableFn7 = (value) => {75 if (!alreadySeenCloneable(value, seen)) {76 if (isCloneable(value)) {77 cloneable.add(value);78 } else {
Using AI Code Generation
1const fc = require('fast-check');2const { alreadySeenCloneable } = require('fast-check-monorepo');3const cloneable = fc.clone(fc.object());4const first = fc.sample(cloneable);5const second = fc.sample(cloneable);6console.log("first: " + first);7console.log("second: " + second);8console.log("first === second: " + (first === second));9console.log("first == second: " + (first == second));10console.log("first is cloneable: " + fc.isCloneable(first));11console.log("second is cloneable: " + fc.isCloneable(second));12console.log("first has already been seen: " + alreadySeenCloneable(first));13console.log("second has already been seen: " + alreadySeenCloneable(second));14console.log("marking first as already seen");15alreadySeenCloneable(first);16console.log("first has already been seen: " + alreadySeenCloneable(first));17console.log("second has already been seen: " + alreadySeenCloneable(second));18console.log("marking second as already seen");19alreadySeenCloneable(second);20console.log("first has already been seen: " + alreadySeenCloneable(first));21console.log("second has already been seen: " + alreadySeenCloneable(second));22console.log("marking first as not already seen");23alreadySeenCloneable(first, false);24console.log("first has already been seen: " + alreadySeenCloneable(first));25console.log("second has already been seen: " + alreadySeenCloneable(second));26console.log("marking second as not already seen");27alreadySeenCloneable(second, false);28console.log("first has already been seen: " + alreadySeenCloneable(first));29console.log("second has already been seen: " + alreadySeenCloneable(second));30first: { a: 0, b: 0, c: 0 }31second: { a: 0, b: 0, c: 0 }
Using AI Code Generation
1const fc = require("fast-check");2const { alreadySeenCloneable } = require("fast-check/lib/check/arbitrary/CloneArbitrary");3let obj = { a: 1, b: 2 };4let obj2 = { a: 1, b: 2 };5let obj3 = { a: 1, b: 3 };6let obj4 = { a: 1, b: 2 };7let obj5 = { a: 2, b: 2 };8let array = [obj, obj2, obj3, obj4, obj5];9console.log(alreadySeenCloneable(array, obj));10console.log(alreadySeenCloneable(array, obj2));11console.log(alreadySeenCloneable(array, obj3));12console.log(alreadySeenCloneable(array, obj4));13console.log(alreadySeenCloneable(array, obj5));
Using AI Code Generation
1const fc = require("fast-check");2const alreadySeenCloneable = require("fast-check-monorepo");3const cloneable = require("cloneable-readable");4const cloneableObj = cloneable();5const cloneableObj2 = cloneable();6const cloneableObj3 = cloneable();7const cloneableObj4 = cloneable();8const cloneableObj5 = cloneable();9const cloneableObj6 = cloneable();10const cloneableObj7 = cloneable();11const cloneableObj8 = cloneable();12const cloneableObj9 = cloneable();13const cloneableObj10 = cloneable();14const cloneableObj11 = cloneable();15const cloneableObj12 = cloneable();16const cloneableObj13 = cloneable();17const cloneableObj14 = cloneable();18const cloneableObj15 = cloneable();19const cloneableObj16 = cloneable();20const cloneableObj17 = cloneable();21const cloneableObj18 = cloneable();22const cloneableObj19 = cloneable();23const cloneableObj20 = cloneable();24const cloneableObj21 = cloneable();25const cloneableObj22 = cloneable();26const cloneableObj23 = cloneable();27const cloneableObj24 = cloneable();28const cloneableObj25 = cloneable();29const cloneableObj26 = cloneable();30const cloneableObj27 = cloneable();31const cloneableObj28 = cloneable();32const cloneableObj29 = cloneable();33const cloneableObj30 = cloneable();34const cloneableObj31 = cloneable();35const cloneableObj32 = cloneable();36const cloneableObj33 = cloneable();37const cloneableObj34 = cloneable();38const cloneableObj35 = cloneable();39const cloneableObj36 = cloneable();40const cloneableObj37 = cloneable();41const cloneableObj38 = cloneable();42const cloneableObj39 = cloneable();43const cloneableObj40 = cloneable();44const cloneableObj41 = cloneable();45const cloneableObj42 = cloneable();46const cloneableObj43 = cloneable();47const cloneableObj44 = cloneable();48const cloneableObj45 = cloneable();49const cloneableObj46 = cloneable();50const cloneableObj47 = cloneable();
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!!