Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔧 Toggle on isolatedDeclarations flag on the project #5136

Merged
merged 33 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
35c6772
🔧 Toggle on `isolatedDeclarations` flag on the project
dubzzz Jul 16, 2024
fcd9d5b
fix poisoning
dubzzz Jul 16, 2024
146beab
fix some in fc
dubzzz Jul 16, 2024
0ddbdb1
Merge branch 'main' into iso-dec
dubzzz Jul 23, 2024
7560f21
Merge branch 'main' into iso-dec
dubzzz Aug 6, 2024
4dc1f78
fix stream
dubzzz Aug 6, 2024
9a3c464
fix wrapper
dubzzz Aug 6, 2024
1c74c13
lint wrapper
dubzzz Aug 6, 2024
c41a10d
trick to pass isolatedDeclarations on unpublished
dubzzz Aug 7, 2024
3c71345
fix vitest and jest?
dubzzz Aug 10, 2024
4212214
Revert breaking parts
dubzzz Aug 10, 2024
26861e4
Dropping isolatedDeclarations for fc
dubzzz Aug 10, 2024
e3e3cb2
Merge remote-tracking branch 'origin/main' into iso-dec
dubzzz Aug 10, 2024
37f4da0
Merge branch 'main' into iso-dec
dubzzz Sep 19, 2024
220fe48
Merge remote-tracking branch 'origin/main' into iso-dec
dubzzz Oct 29, 2024
5fe3f36
Merge remote-tracking branch 'origin/main' into iso-dec
dubzzz Nov 28, 2024
98851bc
drop useless, targeting next major rather than minor
dubzzz Nov 28, 2024
2d1d7e1
oups useless
dubzzz Nov 28, 2024
b60d02f
Merge branch 'main' into iso-dec
dubzzz Jan 9, 2025
7d79f9e
Merge branch 'main' into iso-dec
dubzzz Feb 6, 2025
c18bd70
fix
dubzzz Feb 6, 2025
d96ce5c
fix
dubzzz Feb 6, 2025
d06446d
Create blue-glasses-love.md
dubzzz Feb 6, 2025
e6751f0
doc
dubzzz Feb 6, 2025
d91b3fc
Merge branch 'iso-dec' of https://github.com/dubzzz/fast-check into i…
dubzzz Feb 6, 2025
c2a2f43
fix typecheck
dubzzz Feb 6, 2025
3bb1ae9
fix
dubzzz Feb 6, 2025
e74aea1
Apply suggestions from code review
dubzzz Feb 6, 2025
6484fc6
add missing dep
dubzzz Feb 6, 2025
ceabecf
attempt
dubzzz Feb 6, 2025
2567715
type import
dubzzz Feb 6, 2025
bd5ecc8
fix?
dubzzz Feb 6, 2025
7863a61
Merge remote-tracking branch 'origin/main' into iso-dec
dubzzz Feb 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/blue-glasses-love.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"fast-check": major
---

🔧 Toggle on `isolatedDeclarations` flag on the project
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ const safeNegativeInfinity = Number.NEGATIVE_INFINITY;
const safePositiveInfinity = Number.POSITIVE_INFINITY;

/** @internal */
export const MIN_VALUE_32 = 2 ** -126 * 2 ** -23;
export const MIN_VALUE_32: number = 2 ** -126 * 2 ** -23;
/** @internal */
export const MAX_VALUE_32 = 2 ** 127 * (1 + (2 ** 23 - 1) / 2 ** 23);
export const MAX_VALUE_32: number = 2 ** 127 * (1 + (2 ** 23 - 1) / 2 ** 23);
/** @internal */
export const EPSILON_32 = 2 ** -23;
export const EPSILON_32: number = 2 ** -23;

/** @internal */
const INDEX_POSITIVE_INFINITY = 2139095040; // floatToIndex(MAX_VALUE_32) + 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Value } from '../../../check/arbitrary/definition/Value';

/** @internal */
export const UndefinedContextPlaceholder = Symbol('UndefinedContextPlaceholder');
export const UndefinedContextPlaceholder: unique symbol = Symbol('UndefinedContextPlaceholder');

/** @internal */
export function noUndefinedAsContext<Ts>(value: Value<Ts>): Value<Ts> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { escapeForTemplateString } from '../helpers/TextEscaper';
import { cloneMethod } from '../../../check/symbols';
import type { WithCloneMethod } from '../../../check/symbols';
import { stringify } from '../../../utils/stringify';
import type { Scheduler, SchedulerAct, SchedulerReportItem, SchedulerSequenceItem } from '../interfaces/Scheduler';

Expand Down Expand Up @@ -49,6 +50,11 @@ export class SchedulerImplem<TMetaData> implements Scheduler<TMetaData> {
this.scheduledTasks = [];
this.triggeredTasks = [];
this.scheduledWatchers = [];
(this as unknown as WithCloneMethod<unknown>)[cloneMethod] = function (
this: SchedulerImplem<TMetaData>,
): Scheduler<TMetaData> {
return new SchedulerImplem(this.act, this.sourceTaskSelector);
};
}

private static buildLog<TMetaData>(reportItem: SchedulerReportItem<TMetaData>) {
Expand Down Expand Up @@ -323,8 +329,4 @@ export class SchedulerImplem<TMetaData> implements Scheduler<TMetaData> {
'`'
);
}

[cloneMethod](): Scheduler<TMetaData> {
return new SchedulerImplem(this.act, this.sourceTaskSelector);
}
}
13 changes: 6 additions & 7 deletions packages/fast-check/src/check/model/commands/CommandWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
hasToStringMethod,
toStringMethod,
} from '../../../utils/stringify';
import type { WithToStringMethod, WithAsyncToStringMethod } from '../../../utils/stringify';
import { cloneMethod, hasCloneMethod } from '../../symbols';
import type { ICommand } from '../command/ICommand';

Expand All @@ -14,22 +15,20 @@ import type { ICommand } from '../command/ICommand';
export class CommandWrapper<Model extends object, Real, RunResult, CheckAsync extends boolean>
implements ICommand<Model, Real, RunResult, CheckAsync>
{
[toStringMethod]?: () => string;
[asyncToStringMethod]?: () => Promise<string>;

hasRan = false;
constructor(readonly cmd: ICommand<Model, Real, RunResult, CheckAsync>) {
if (hasToStringMethod(cmd)) {
const method = cmd[toStringMethod];
this[toStringMethod] = function toStringMethod(): string {
(this as unknown as WithToStringMethod)[toStringMethod] = function toStringMethod(): string {
return method.call(cmd);
};
}
if (hasAsyncToStringMethod(cmd)) {
const method = cmd[asyncToStringMethod];
this[asyncToStringMethod] = function asyncToStringMethod(): Promise<string> {
return method.call(cmd);
};
(this as unknown as WithAsyncToStringMethod)[asyncToStringMethod] =
function asyncToStringMethod(): Promise<string> {
return method.call(cmd);
};
}
}
check(m: Readonly<Model>): CheckAsync extends false ? boolean : Promise<boolean> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { cloneMethod } from '../../symbols';
import type { WithCloneMethod } from '../../symbols';
import type { CommandWrapper } from './CommandWrapper';

/**
Expand All @@ -10,16 +11,19 @@ export class CommandsIterable<Model extends object, Real, RunResult, CheckAsync
constructor(
readonly commands: CommandWrapper<Model, Real, RunResult, CheckAsync>[],
readonly metadataForReplay: () => string,
) {}
) {
(this as unknown as WithCloneMethod<unknown>)[cloneMethod] = function (
this: CommandsIterable<Model, Real, RunResult, CheckAsync>,
): CommandsIterable<Model, Real, RunResult, CheckAsync> {
return new CommandsIterable(
this.commands.map((c) => c.clone()),
this.metadataForReplay,
);
};
}
[Symbol.iterator](): Iterator<CommandWrapper<Model, Real, RunResult, CheckAsync>> {
return this.commands[Symbol.iterator]();
}
[cloneMethod](): CommandsIterable<Model, Real, RunResult, CheckAsync> {
return new CommandsIterable(
this.commands.map((c) => c.clone()),
this.metadataForReplay,
);
}
toString(): string {
const serializedCommands = this.commands
.filter((c) => c.hasRan)
Expand Down
4 changes: 2 additions & 2 deletions packages/fast-check/src/utils/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ const SUint32Array: typeof Uint32Array = Uint32Array;
export { SUint32Array as Uint32Array };
const SencodeURIComponent: typeof encodeURIComponent = encodeURIComponent;
export { SencodeURIComponent as encodeURIComponent };
const SMap = Map;
const SMap: MapConstructor = Map;
export { SMap as Map };
const SSymbol = Symbol;
const SSymbol: SymbolConstructor = Symbol;
export { SSymbol as Symbol };

// Various remarks concerning this part of the file:
Expand Down
2 changes: 1 addition & 1 deletion packages/fast-check/test/e2e/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ const globalSeed = globalConfig.seed;
if (process.env.CI && globalSeed === undefined) {
throw new Error('seed must be defined globally in CI');
}
export const seed = globalSeed !== undefined ? globalSeed : Date.now();
export const seed: number = globalSeed !== undefined ? globalSeed : Date.now();
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ export function float64raw(): fc.Arbitrary<number> {
.map(([na32, nb32]) => new Float64Array(new Int32Array([na32, nb32]).buffer)[0]);
}

export const defaultFloatRecordConstraints = {
export const defaultFloatRecordConstraints: {
min: fc.Arbitrary<number>;
max: fc.Arbitrary<number>;
noDefaultInfinity: fc.Arbitrary<boolean>;
noNaN: fc.Arbitrary<boolean>;
noInteger: fc.Arbitrary<boolean>;
minExcluded: fc.Arbitrary<boolean>;
maxExcluded: fc.Arbitrary<boolean>;
} = {
min: float32raw(),
max: float32raw(),
noDefaultInfinity: fc.boolean(),
Expand All @@ -27,7 +35,15 @@ export const defaultFloatRecordConstraints = {
maxExcluded: fc.boolean(),
};

export const defaultDoubleRecordConstraints = {
export const defaultDoubleRecordConstraints: {
min: fc.Arbitrary<number>;
max: fc.Arbitrary<number>;
noDefaultInfinity: fc.Arbitrary<boolean>;
noNaN: fc.Arbitrary<boolean>;
noInteger: fc.Arbitrary<boolean>;
minExcluded: fc.Arbitrary<boolean>;
maxExcluded: fc.Arbitrary<boolean>;
} = {
min: float64raw(),
max: float64raw(),
noDefaultInfinity: fc.boolean(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,21 @@ import type {
} from '../../../../src/arbitrary/_internals/helpers/MaxLengthFromMinLength';

const allSizeOrdered = ['xsmall', 'small', 'medium', 'large', 'xlarge'] as const;
export const sizeArb = fc.constantFrom<Size>(...allSizeOrdered);
export const sizeArb: fc.Arbitrary<Size> = fc.constantFrom<Size>(...allSizeOrdered);
export const isSmallerSize = (sa: Size, sb: Size): boolean => allSizeOrdered.indexOf(sa) < allSizeOrdered.indexOf(sb);

const allRelativeSize = ['-4', '-3', '-2', '-1', '=', '+1', '+2', '+3', '+4'] as const;
export const relativeSizeArb = fc.constantFrom<RelativeSize>(...allRelativeSize);
export const relativeSizeArb: fc.Arbitrary<RelativeSize> = fc.constantFrom<RelativeSize>(...allRelativeSize);

const allSizeForArbitrary = [...allSizeOrdered, ...allRelativeSize, 'max'] as const; // WARNING: it does not include undefined
export const sizeForArbitraryArb = fc.constantFrom<SizeForArbitrary>(...allSizeForArbitrary);

export const sizeRelatedGlobalConfigArb = fc.record(
{ baseSize: sizeArb, defaultSizeToMaxWhenMaxSpecified: fc.boolean() },
{ requiredKeys: [] },
export const sizeForArbitraryArb: fc.Arbitrary<SizeForArbitrary> = fc.constantFrom<SizeForArbitrary>(
...allSizeForArbitrary,
);

export const sizeRelatedGlobalConfigArb: fc.Arbitrary<
Partial<{ baseSize: Size; defaultSizeToMaxWhenMaxSpecified: boolean }>
> = fc.record({ baseSize: sizeArb, defaultSizeToMaxWhenMaxSpecified: fc.boolean() }, { requiredKeys: [] });

// Type check that helpers are covering all the possibilities

const failIfMissingSize: Size extends (typeof allSizeOrdered)[number] ? true : never = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as fc from 'fast-check';
import { CommandWrapper } from '../../../../../src/check/model/commands/CommandWrapper';
import { CommandsIterable } from '../../../../../src/check/model/commands/CommandsIterable';
import type { Command } from '../../../../../src/check/model/command/Command';
import { cloneMethod } from '../../../../../src/check/symbols';
import { cloneMethod, hasCloneMethod } from '../../../../../src/check/symbols';

type Model = Record<string, unknown>;
type Real = unknown;
Expand Down Expand Up @@ -38,6 +38,9 @@ describe('CommandsIterable', () => {
fc.assert(
fc.property(fc.array(fc.boolean()), (runFlags) => {
const originalIterable = new CommandsIterable(buildAlreadyRanCommands(runFlags), () => '');
if (!hasCloneMethod(originalIterable)) {
throw new Error(`Not cloaneable`);
}
originalIterable[cloneMethod]();
const commands = [...originalIterable];
for (let idx = 0; idx !== runFlags.length; ++idx) {
Expand All @@ -48,7 +51,11 @@ describe('CommandsIterable', () => {
it('Should reset hasRun flag for the clone on clone', () =>
fc.assert(
fc.property(fc.array(fc.boolean()), (runFlags) => {
const commands = [...new CommandsIterable(buildAlreadyRanCommands(runFlags), () => '')[cloneMethod]()];
const commandsIterable = new CommandsIterable(buildAlreadyRanCommands(runFlags), () => '');
if (!hasCloneMethod(commandsIterable)) {
throw new Error(`Not cloaneable`);
}
const commands = [...commandsIterable[cloneMethod]()];
for (let idx = 0; idx !== runFlags.length; ++idx) {
expect(commands[idx].hasRan).toBe(false);
}
Expand Down
1 change: 1 addition & 0 deletions packages/jest/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"jest": "^29.7.0",
"jest-jasmine2": "^29.7.0",
"typescript": "~5.7.3",
"vite": "^6.1.0",
"vitest": "^2.1.9"
},
"keywords": [
Expand Down
5 changes: 4 additions & 1 deletion packages/jest/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { UserConfig } from 'vite';
import { defineConfig } from 'vitest/config';

const major = Number(process.versions.node.split('.')[0]);

export default defineConfig({
// @ts-expect-error - We will fix that one by bumping Vitest to v3
const config: UserConfig = defineConfig({
test: {
testTimeout: 60000, // 60s
include: ['**/test/*.{test,spec}.?(c|m)[jt]s?(x)'],
retry: major === 23 ? 5 : undefined,
},
});
export default config;
1 change: 1 addition & 0 deletions packages/packaged/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@types/npm-packlist": "^7.0.3",
"@types/npmcli__arborist": "^6.3.0",
"typescript": "~5.7.3",
"vite": "^6.1.0",
"vitest": "^2.1.9"
},
"keywords": [],
Expand Down
5 changes: 4 additions & 1 deletion packages/packaged/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type { UserConfig } from 'vite';
import { defineConfig } from 'vitest/config';

export default defineConfig({
// @ts-expect-error - We will fix that one by bumping Vitest to v3
const config: UserConfig = defineConfig({
test: {
include: ['**/test/*.{test,spec}.?(c|m)[jt]s?(x)'],
},
});
export default config;
5 changes: 4 additions & 1 deletion packages/vitest/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { UserConfig } from 'vite';
import { defineConfig } from 'vitest/config';

const major = Number(process.versions.node.split('.')[0]);

export default defineConfig({
// @ts-expect-error - We will fix that one by bumping Vitest to v3
const config: UserConfig = defineConfig({
test: {
testTimeout: 60000, // 60s
include: ['**/test/*.{test,spec}.?(c|m)[jt]s?(x)'],
retry: major === 23 ? 5 : undefined,
},
});
export default config;
3 changes: 2 additions & 1 deletion tsconfig.common.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"compilerOptions": {
"noEmit": true,
"declaration": false,
"declaration": true,
"isolatedDeclarations": true,
"incremental": false,
"sourceMap": true,
"target": "es2017",
Expand Down
1 change: 1 addition & 0 deletions tsconfig.publish.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"compilerOptions": {
"noEmit": false,
"declaration": false,
"isolatedDeclarations": false,
"removeComments": true,
"sourceMap": false
}
Expand Down
1 change: 1 addition & 0 deletions tsconfig.publish.types.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"noEmit": false,
"declaration": true,
"emitDeclarationOnly": true,
"isolatedDeclarations": true,
"removeComments": false,
"sourceMap": false,
"stripInternal": true
Expand Down
37 changes: 37 additions & 0 deletions website/docs/migration/from-3.x-to-4.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,40 @@ stringify(Object.assign(Object.create(null), { a: 1 })); // '{__proto__:null,"a"
This change is unlikely to impact most users. However, we are highlighting it for advanced users who might rely on custom reporting capabilities or stringifier behavior to meet specific needs.

Related pull requests: [#5603](https://github.com/dubzzz/fast-check/pull/5603)

### Remove certain Symbol-based typings for commands

In previous versions, the typings for `CommandWrapper` included methods on the symbols `toStringMethod` and `asyncToStringMethod`. While these methods will still exist in JavaScript in v4, they will no longer be exposed in the TypeScript typings. As a result, the declared type will change as follows:

```diff
export declare class CommandWrapper<Model extends object, Real, RunResult, CheckAsync extends boolean>
implements ICommand<Model, Real, RunResult, CheckAsync>
{
readonly cmd: ICommand<Model, Real, RunResult, CheckAsync>;
- [toStringMethod]?: () => string;
- [asyncToStringMethod]?: () => Promise<string>;
hasRan: boolean;
constructor(cmd: ICommand<Model, Real, RunResult, CheckAsync>);
check(m: Readonly<Model>): CheckAsync extends false ? boolean : Promise<boolean>;
run(m: Model, r: Real): RunResult;
clone(): CommandWrapper<Model, Real, RunResult, CheckAsync>;
toString(): string;
}
```

A similar change affects `CommandsIterable`, where the `cloneMethod` symbol will no longer be included in the typings:

```diff
export declare class CommandsIterable<Model extends object, Real, RunResult, CheckAsync extends boolean = false>
implements Iterable<CommandWrapper<Model, Real, RunResult, CheckAsync>>
{
readonly commands: CommandWrapper<Model, Real, RunResult, CheckAsync>[];
readonly metadataForReplay: () => string;
constructor(commands: CommandWrapper<Model, Real, RunResult, CheckAsync>[], metadataForReplay: () => string);
[Symbol.iterator](): Iterator<CommandWrapper<Model, Real, RunResult, CheckAsync>>;
- [cloneMethod](): CommandsIterable<Model, Real, RunResult, CheckAsync>;
toString(): string;
}
```

Related pull requests: [#5136](https://github.com/dubzzz/fast-check/pull/5136)
2 changes: 2 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3670,6 +3670,7 @@ __metadata:
jest: "npm:^29.7.0"
jest-jasmine2: "npm:^29.7.0"
typescript: "npm:~5.7.3"
vite: "npm:^6.1.0"
vitest: "npm:^2.1.9"
peerDependencies:
"@fast-check/worker": ">=0.0.7 <0.5.0"
Expand Down Expand Up @@ -3712,6 +3713,7 @@ __metadata:
"@types/npmcli__arborist": "npm:^6.3.0"
npm-packlist: "npm:^10.0.0"
typescript: "npm:~5.7.3"
vite: "npm:^6.1.0"
vitest: "npm:^2.1.9"
bin:
packaged: ./bin/packaged.js
Expand Down
Loading