Skip to content

Commit

Permalink
🐛 Better interrupt between multiple versions
Browse files Browse the repository at this point in the history
fast-check was badly behaving on cloning method, custom toString and assertions linked to pre when several versions of it were running at the same time.

One of the case for that issue is ES module and CommonJS being mixed in the same test and leading fast-check to be loaded once in ESM and once in CJS.

Another case is that user relies on two versions of fast-check due to a dependency forcing a version that is not the same as the one requested by the user or by another dependency (not the same meaning not compatible semver ranges).

Fixes #4845
  • Loading branch information
dubzzz committed May 14, 2024
1 parent 8f9103d commit 405e813
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
export class PreconditionFailure extends Error {
/** @internal */
private static readonly SharedFootPrint: symbol = Symbol('fast-check/PreconditionFailure');
private static readonly SharedFootPrint: symbol = Symbol.for('fast-check/PreconditionFailure');
/** @internal */
private readonly footprint: symbol;
constructor(readonly interruptExecution: boolean = false) {
Expand Down
2 changes: 1 addition & 1 deletion packages/fast-check/src/check/symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* @remarks Since 1.8.0
* @public
*/
export const cloneMethod = Symbol('fast-check/cloneMethod');
export const cloneMethod = Symbol.for('fast-check/cloneMethod');

/**
* Object instance that should be cloned from one generation/shrink to another
Expand Down
4 changes: 2 additions & 2 deletions packages/fast-check/src/utils/stringify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const safePositiveInfinity = Number.POSITIVE_INFINITY;
* @remarks Since 2.17.0
* @public
*/
export const toStringMethod = Symbol('fast-check/toStringMethod');
export const toStringMethod = Symbol.for('fast-check/toStringMethod');
/**
* Interface to implement for {@link toStringMethod}
*
Expand Down Expand Up @@ -62,7 +62,7 @@ export function hasToStringMethod<T>(instance: T): instance is T & WithToStringM
* @remarks Since 2.17.0
* @public
*/
export const asyncToStringMethod = Symbol('fast-check/asyncToStringMethod');
export const asyncToStringMethod = Symbol.for('fast-check/asyncToStringMethod');
/**
* Interface to implement for {@link asyncToStringMethod}
*
Expand Down
12 changes: 6 additions & 6 deletions packages/fast-check/test/unit/utils/stringify.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ describe('stringify', () => {
const instance3 = { [toStringMethod]: () => { throw new Error('hello3'); } };
const stringified3 = stringify(instance3);
expect(stringified3.replace(/[\s\n]+/g, ' ')).toEqual(
'{[Symbol("fast-check/toStringMethod")]:() => { throw new Error("hello3"); }}',
'{[Symbol.for("fast-check/toStringMethod")]:() => { throw new Error("hello3"); }}',
); // fallbacking to default

class InProto {
Expand All @@ -435,11 +435,11 @@ describe('stringify', () => {
expect(stringify(instance4)).toEqual('hello4');

const instance5 = { [toStringMethod]: 1 }; // not callable
expect(stringify(instance5)).toEqual('{[Symbol("fast-check/toStringMethod")]:1}');
expect(stringify(instance5)).toEqual('{[Symbol.for("fast-check/toStringMethod")]:1}');
});
it('Should not be able to rely on the output of [asyncToStringMethod] in sync mode', () => {
const instance1 = { [asyncToStringMethod]: () => 'hello1' }; // not even async there
expect(stringify(instance1)).toEqual('{[Symbol("fast-check/asyncToStringMethod")]:() => "hello1"}'); // fallbacking to default
expect(stringify(instance1)).toEqual('{[Symbol.for("fast-check/asyncToStringMethod")]:() => "hello1"}'); // fallbacking to default

const instance2 = { [asyncToStringMethod]: () => 'hello2', [toStringMethod]: () => 'world' };
expect(stringify(instance2)).toEqual('world'); // fallbacking to [toStringMethod]
Expand Down Expand Up @@ -560,7 +560,7 @@ describe('asyncStringify', () => {
const instance4 = { [asyncToStringMethod]: async () => { throw new Error('hello4'); } };
const stringified4 = await asyncStringify(instance4);
expect(stringified4.replace(/[\s\n]+/g, ' ')).toEqual(
'{[Symbol("fast-check/asyncToStringMethod")]:async () => { throw new Error("hello4"); }}',
'{[Symbol.for("fast-check/asyncToStringMethod")]:async () => { throw new Error("hello4"); }}',
); // fallbacking to default

// prettier-ignore
Expand All @@ -571,7 +571,7 @@ describe('asyncStringify', () => {
const instance6 = { [asyncToStringMethod]: () => { throw new Error('hello6'); } }; // throw is sync
const stringified6 = await asyncStringify(instance6);
expect(stringified6.replace(/[\s\n]+/g, ' ')).toEqual(
'{[Symbol("fast-check/asyncToStringMethod")]:() => { throw new Error("hello6"); }}',
'{[Symbol.for("fast-check/asyncToStringMethod")]:() => { throw new Error("hello6"); }}',
); // fallbacking to default

class InProto {
Expand All @@ -583,7 +583,7 @@ describe('asyncStringify', () => {
expect(await asyncStringify(instance7)).toEqual('hello7');

const instance8 = { [asyncToStringMethod]: 1 }; // not callable
expect(await asyncStringify(instance8)).toEqual('{[Symbol("fast-check/asyncToStringMethod")]:1}');
expect(await asyncStringify(instance8)).toEqual('{[Symbol.for("fast-check/asyncToStringMethod")]:1}');

const instance9 = {
[asyncToStringMethod]: async () => {
Expand Down

0 comments on commit 405e813

Please sign in to comment.