Skip to content

Commit

Permalink
✅ Better mock/spy cleaning (#4875)
Browse files Browse the repository at this point in the history
Whenever running tests playing with mocks or spies, we have to make sure
to properly clean everything. But over cleaning is as bad as no
cleaning, more precisely, from a CI point of view, over cleaning tend to
make tests slower.

This PR introduce a shared helper responsible to clean anything related
to spies. It has to be added on case by case basis to clean
describe-blocks using spies between every it and after the block, so
that other blocks don't get broken by a previously running
describe-block.
  • Loading branch information
dubzzz authored Apr 7, 2024
1 parent b32afae commit 8973a33
Show file tree
Hide file tree
Showing 47 changed files with 185 additions and 410 deletions.
8 changes: 8 additions & 0 deletions .yarn/versions/2faec736.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
releases:
fast-check: patch

declined:
- "@fast-check/ava"
- "@fast-check/jest"
- "@fast-check/vitest"
- "@fast-check/worker"
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import fc from 'fast-check';
import { afterAll, afterEach, beforeAll, vi } from 'vitest';

/**
* Connect hooks responsible to clean the spies,
* before any other test runs
*/
export function declareCleaningHooksForSpies(): void {
const currentGlobalConfiguration = fc.readConfigureGlobal();
function clean() {
vi.restoreAllMocks();
}
beforeAll(() => {
fc.configureGlobal({ ...currentGlobalConfiguration, afterEach: clean });
});
afterEach(clean);
afterAll(() => {
fc.configureGlobal(currentGlobalConfiguration);
});
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import fc from 'fast-check';
import prand from 'pure-rand';

Expand All @@ -16,15 +16,11 @@ import { fakeArbitrary } from '../__test-helpers__/ArbitraryHelpers';
import { fakeRandom } from '../__test-helpers__/RandomHelpers';
import { buildShrinkTree, walkTree } from '../__test-helpers__/ShrinkTree';
import * as DepthContextMock from '../../../../src/arbitrary/_internals/helpers/DepthContext';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from '../__test-helpers__/SpyCleaner';

describe('ArrayArbitrary', () => {
declareCleaningHooksForSpies();

describe('generate', () => {
it('should concat all the generated values together when no set constraints ', () => {
fc.assert(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { BigIntArbitrary } from '../../../../src/arbitrary/_internals/BigIntArbitrary';
import { Value } from '../../../../src/check/arbitrary/definition/Value';
Expand All @@ -15,21 +15,10 @@ import { Stream } from '../../../../src/stream/Stream';

import * as BiasNumericRangeMock from '../../../../src/arbitrary/_internals/helpers/BiasNumericRange';
import * as ShrinkBigIntMock from '../../../../src/arbitrary/_internals/helpers/ShrinkBigInt';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from '../__test-helpers__/SpyCleaner';

describe('BigIntArbitrary', () => {
if (typeof BigInt === 'undefined') {
it('no test', () => {
expect(true).toBe(true);
});
return;
}
declareCleaningHooksForSpies();

describe('generate', () => {
it('should never bias and generate the full range when biasFactor is not specified', () =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import type { MockInstance } from 'vitest';
import * as fc from 'fast-check';
import { IntegerArbitrary } from '../../../../src/arbitrary/_internals/IntegerArbitrary';
Expand All @@ -16,15 +16,11 @@ import { buildShrinkTree, renderTree, walkTree } from '../__test-helpers__/Shrin
import * as BiasNumericRangeMock from '../../../../src/arbitrary/_internals/helpers/BiasNumericRange';
import * as ShrinkIntegerMock from '../../../../src/arbitrary/_internals/helpers/ShrinkInteger';
import { Stream } from '../../../../src/stream/Stream';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from '../__test-helpers__/SpyCleaner';

describe('IntegerArbitrary', () => {
declareCleaningHooksForSpies();

describe('generate', () => {
it('should never bias and generate the full range when biasFactor is not specified', () =>
fc.assert(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import fc from 'fast-check';
import {
assertProduceValuesShrinkableWithoutContext,
Expand All @@ -14,21 +14,10 @@ import * as BigUintNMock from '../../../../src/arbitrary/bigUintN';
import { fakeArbitrary } from '../__test-helpers__/ArbitraryHelpers';
import { Value } from '../../../../src/check/arbitrary/definition/Value';
import { fakeRandom } from '../__test-helpers__/RandomHelpers';
import { declareCleaningHooksForSpies } from '../__test-helpers__/SpyCleaner';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);

describe('MixedCaseArbitrary (integration)', () => {
if (typeof BigInt === 'undefined') {
it('no test', () => {
expect(true).toBe(true);
});
return;
}
describe('MixedCaseArbitrary', () => {
declareCleaningHooksForSpies();

describe('generate', () => {
it('should not toggle any character if flags equal zero', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { StreamArbitrary } from '../../../../src/arbitrary/_internals/StreamArbitrary';
import { Value } from '../../../../src/check/arbitrary/definition/Value';
Expand All @@ -12,15 +12,11 @@ import { FakeIntegerArbitrary, fakeArbitrary } from '../__test-helpers__/Arbitra
import { fakeRandom } from '../__test-helpers__/RandomHelpers';

import * as StringifyMock from '../../../../src/utils/stringify';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from '../__test-helpers__/SpyCleaner';

describe('StreamArbitrary', () => {
declareCleaningHooksForSpies();

describe('generate', () => {
it('should produce a cloneable instance of Stream', () => {
// Arrange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect } from 'vitest';
import * as fc from 'fast-check';
import { SubarrayArbitrary } from '../../../../src/arbitrary/_internals/SubarrayArbitrary';

Expand All @@ -10,13 +10,6 @@ import {
assertShrinkProducesStrictlySmallerValue,
} from '../__test-helpers__/ArbitraryAssertions';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);

describe('SubarrayArbitrary', () => {
describe('constructor', () => {
it('should raise an error whenever minLength is below zero', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { typedIntArrayArbitraryArbitraryBuilder } from '../../../../../src/arbitrary/_internals/builders/TypedIntArrayArbitraryBuilder';

Expand All @@ -11,15 +11,11 @@ import {
assertProduceValuesShrinkableWithoutContext,
assertShrinkProducesSameValueWithoutInitialContext,
} from '../../__test-helpers__/ArbitraryAssertions';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from '../../__test-helpers__/SpyCleaner';

describe('typedIntArrayArbitraryArbitraryBuilder', () => {
declareCleaningHooksForSpies();

it('should default constraints for arbitraryBuilder to defaultMin/Max when not specified', () => {
fc.assert(
fc.property(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import fc from 'fast-check';
import type {
ScheduledTask,
Expand All @@ -8,13 +8,6 @@ import { SchedulerImplem } from '../../../../../src/arbitrary/_internals/impleme
import type { Scheduler } from '../../../../../src/arbitrary/_internals/interfaces/Scheduler';
import { cloneMethod, hasCloneMethod } from '../../../../../src/check/symbols';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);

const buildUnresolved = () => {
let resolved = false;
let resolve = () => {};
Expand Down
12 changes: 4 additions & 8 deletions packages/fast-check/test/unit/arbitrary/array.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { array } from '../../../src/arbitrary/array';

Expand All @@ -17,15 +17,11 @@ import { Value } from '../../../src/check/arbitrary/definition/Value';
import { buildShrinkTree, renderTree } from './__test-helpers__/ShrinkTree';
import { sizeRelatedGlobalConfigArb } from './__test-helpers__/SizeHelpers';
import { withConfiguredGlobal } from './__test-helpers__/GlobalSettingsHelpers';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from './__test-helpers__/SpyCleaner';

describe('array', () => {
declareCleaningHooksForSpies();

it('should instantiate ArrayArbitrary(arb, 0, ?, 0x7fffffff, n.a) for array(arb)', () => {
fc.assert(
fc.property(sizeRelatedGlobalConfigArb, (config) => {
Expand Down
12 changes: 4 additions & 8 deletions packages/fast-check/test/unit/arbitrary/ascii.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { ascii } from '../../../src/arbitrary/ascii';

import { fakeArbitrary } from './__test-helpers__/ArbitraryHelpers';
import { declareCleaningHooksForSpies } from './__test-helpers__/SpyCleaner';

import * as CharacterArbitraryBuilderMock from '../../../src/arbitrary/_internals/builders/CharacterArbitraryBuilder';
import {
Expand All @@ -13,14 +14,9 @@ import {
assertProduceSameValueGivenSameSeed,
} from './__test-helpers__/ArbitraryAssertions';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);

describe('ascii', () => {
declareCleaningHooksForSpies();

it('should be able to unmap any mapped value', () => {
// Arrange
const { min, max, mapToCode, unmapFromCode } = extractArgumentsForBuildCharacter(ascii);
Expand Down
12 changes: 4 additions & 8 deletions packages/fast-check/test/unit/arbitrary/base64.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { base64 } from '../../../src/arbitrary/base64';

Expand All @@ -12,15 +12,11 @@ import {
assertShrinkProducesStrictlySmallerValue,
assertProduceSameValueGivenSameSeed,
} from './__test-helpers__/ArbitraryAssertions';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);
import { declareCleaningHooksForSpies } from './__test-helpers__/SpyCleaner';

describe('base64', () => {
declareCleaningHooksForSpies();

it('should be able to unmap any mapped value', () => {
// Arrange
const { min, max, mapToCode, unmapFromCode } = extractArgumentsForBuildCharacter(base64);
Expand Down
12 changes: 4 additions & 8 deletions packages/fast-check/test/unit/arbitrary/base64String.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { base64String } from '../../../src/arbitrary/base64String';

Expand All @@ -7,21 +7,17 @@ import {
assertProduceCorrectValues,
assertProduceSameValueGivenSameSeed,
} from './__test-helpers__/ArbitraryAssertions';
import { declareCleaningHooksForSpies } from './__test-helpers__/SpyCleaner';

import * as ArrayMock from '../../../src/arbitrary/array';
import { fakeArbitrary } from './__test-helpers__/ArbitraryHelpers';
import { Value } from '../../../src/check/arbitrary/definition/Value';
import { buildShrinkTree, renderTree } from './__test-helpers__/ShrinkTree';
import { sizeForArbitraryArb } from './__test-helpers__/SizeHelpers';

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);

describe('base64String', () => {
declareCleaningHooksForSpies();

it('should accept any constraints accepting at least one length multiple of 4', () =>
fc.assert(
fc.property(
Expand Down
17 changes: 3 additions & 14 deletions packages/fast-check/test/unit/arbitrary/bigInt.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { beforeEach, describe, it, expect, vi } from 'vitest';
import { describe, it, expect, vi } from 'vitest';
import * as fc from 'fast-check';
import { bigInt } from '../../../src/arbitrary/bigInt';

import { fakeArbitrary } from './__test-helpers__/ArbitraryHelpers';
import { declareCleaningHooksForSpies } from './__test-helpers__/SpyCleaner';

import * as BigIntArbitraryMock from '../../../src/arbitrary/_internals/BigIntArbitrary';

Expand All @@ -11,20 +12,8 @@ function fakeBigIntArbitrary() {
return instance;
}

function beforeEachHook() {
vi.resetModules();
vi.restoreAllMocks();
fc.configureGlobal({ beforeEach: beforeEachHook });
}
beforeEach(beforeEachHook);

describe('bigInt', () => {
if (typeof BigInt === 'undefined') {
it('no test', () => {
expect(true).toBe(true);
});
return;
}
declareCleaningHooksForSpies();

it('should instantiate the same BigIntArbitrary as empty constraints for no arguments', () => {
// Arrange
Expand Down
Loading

0 comments on commit 8973a33

Please sign in to comment.