diff --git a/.changeset/rare-lemons-prove.md b/.changeset/rare-lemons-prove.md new file mode 100644 index 00000000..94fc7112 --- /dev/null +++ b/.changeset/rare-lemons-prove.md @@ -0,0 +1,5 @@ +--- +"fast-check": major +--- + +💥 Drop global capture of methods [Batch 1] diff --git a/packages/fast-check/src/arbitrary/_internals/ArrayArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/ArrayArbitrary.ts index 23a24c89..183dd66d 100644 --- a/packages/fast-check/src/arbitrary/_internals/ArrayArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/ArrayArbitrary.ts @@ -9,7 +9,6 @@ import type { CustomSetBuilder } from './interfaces/CustomSet.js'; import type { DepthContext, DepthIdentifier } from './helpers/DepthContext.js'; import { getDepthContextFor } from './helpers/DepthContext.js'; import { buildSlicedGenerator } from './helpers/BuildSlicedGenerator.js'; -import { safeMap, safePush, safeSlice } from '../../utils/globals.js'; /** @internal */ type ArrayArbitraryContext = { @@ -65,7 +64,7 @@ export class ArrayArbitrary extends Arbitrary { (vs as any)[cloneMethod] = () => { const cloned: T[] = []; for (let idx = 0; idx !== shrinkables.length; ++idx) { - safePush(cloned, shrinkables[idx].value); // push potentially cloned values + cloned.push(shrinkables[idx].value); // push potentially cloned values } this.makeItCloneable(cloned, shrinkables); return cloned; @@ -122,7 +121,7 @@ export class ArrayArbitrary extends Arbitrary { slicedGenerator.attemptExact(N); for (let index = 0; index !== N; ++index) { const current = slicedGenerator.next(); - safePush(items, current); + items.push(current); } return items; } @@ -155,8 +154,8 @@ export class ArrayArbitrary extends Arbitrary { for (let idx = 0; idx !== items.length; ++idx) { const s = items[idx]; cloneable = cloneable || s.hasToBeCloned; - safePush(vs, s.value); - safePush(itemsContexts, s.context); + vs.push(s.value); + itemsContexts.push(s.context); } if (cloneable) { ArrayArbitrary.makeItCloneable(vs, items); @@ -227,7 +226,7 @@ export class ArrayArbitrary extends Arbitrary { } // `preFilter` only drops items, it does not reorder them or add some more // if calling it with `value` results into a smaller array it means that the value was not generated by this instance - const filtered = this.preFilter(safeMap(value, (item) => new Value(item, undefined))); + const filtered = this.preFilter(value.map((item) => new Value(item, undefined))); return filtered.length === value.length; } @@ -238,18 +237,15 @@ export class ArrayArbitrary extends Arbitrary { ): IterableIterator<[Value[], unknown, number]> { const shrinks: IterableIterator<[Value[], unknown, number]>[] = []; for (let index = safeContext.startIndex; index < endIndex; ++index) { - safePush( - shrinks, + shrinks.push( makeLazy(() => this.arb.shrink(value[index], safeContext.itemsContexts[index]).map((v): [Value[], unknown, number] => { - const beforeCurrent = safeMap( - safeSlice(value, 0, index), - (v, i) => new Value(cloneIfNeeded(v), safeContext.itemsContexts[i]), - ); - const afterCurrent = safeMap( - safeSlice(value, index + 1), - (v, i) => new Value(cloneIfNeeded(v), safeContext.itemsContexts[i + index + 1]), - ); + const beforeCurrent = value + .slice(0, index) + .map((v, i) => new Value(cloneIfNeeded(v), safeContext.itemsContexts[i])); + const afterCurrent = value + .slice(index + 1) + .map((v, i) => new Value(cloneIfNeeded(v), safeContext.itemsContexts[i + index + 1])); return [ [...beforeCurrent, v, ...afterCurrent], undefined, // no length context @@ -290,10 +286,9 @@ export class ArrayArbitrary extends Arbitrary { .map((lengthValue): [Value[], unknown, number] => { const sliceStart = value.length - lengthValue.value; return [ - safeMap( - safeSlice(value, sliceStart), - (v, index) => new Value(cloneIfNeeded(v), safeContext.itemsContexts[index + sliceStart]), - ), // array of length lengthValue.value + value + .slice(sliceStart) + .map((v, index) => new Value(cloneIfNeeded(v), safeContext.itemsContexts[index + sliceStart])), // array of length lengthValue.value lengthValue.context, // integer context for value lengthValue.value (the length) 0, ]; @@ -316,10 +311,10 @@ export class ArrayArbitrary extends Arbitrary { const subContext: ArrayArbitraryContext = { shrunkOnce: false, lengthContext: undefined, - itemsContexts: safeSlice(safeContext.itemsContexts, 1), + itemsContexts: safeContext.itemsContexts.slice(1), startIndex: 0, }; - return this.shrinkImpl(safeSlice(value, 1), subContext) + return this.shrinkImpl(value.slice(1), subContext) .filter((v) => this.minLength <= v[0].length + 1) .map((v): [Value[], unknown, number] => { return [[new Value(cloneIfNeeded(value[0]), safeContext.itemsContexts[0]), ...v[0]], undefined, 0]; diff --git a/packages/fast-check/src/arbitrary/_internals/CloneArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/CloneArbitrary.ts index 9cd1ffca..d533e75a 100644 --- a/packages/fast-check/src/arbitrary/_internals/CloneArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/CloneArbitrary.ts @@ -3,7 +3,6 @@ import { Value } from '../../check/arbitrary/definition/Value.js'; import { cloneMethod } from '../../check/symbols.js'; import type { Random } from '../../random/generator/Random.js'; import { Stream } from '../../stream/Stream.js'; -import { safeMap, safePush } from '../../utils/globals.js'; /** @internal */ export class CloneArbitrary extends Arbitrary { @@ -21,9 +20,9 @@ export class CloneArbitrary extends Arbitrary { } // We call generate multiple times to have fully independent values for (let idx = 0; idx !== this.numValues - 1; ++idx) { - safePush(items, this.arb.generate(mrng.clone(), biasFactor)); + items.push(this.arb.generate(mrng.clone(), biasFactor)); } - safePush(items, this.arb.generate(mrng, biasFactor)); + items.push(this.arb.generate(mrng, biasFactor)); return this.wrapper(items); } @@ -55,11 +54,11 @@ export class CloneArbitrary extends Arbitrary { } private *shrinkImpl(value: T[], contexts: unknown[]): IterableIterator[]> { - const its = safeMap(value, (v, idx) => this.arb.shrink(v, contexts[idx])[Symbol.iterator]()); - let cur = safeMap(its, (it) => it.next()); + const its = value.map((v, idx) => this.arb.shrink(v, contexts[idx])[Symbol.iterator]()); + let cur = its.map((it) => it.next()); while (!cur[0].done) { - yield safeMap(cur, (c) => c.value); - cur = safeMap(its, (it) => it.next()); + yield cur.map((c) => c.value); + cur = its.map((it) => it.next()); } } @@ -67,7 +66,7 @@ export class CloneArbitrary extends Arbitrary { (vs as any)[cloneMethod] = () => { const cloned: T[] = []; for (let idx = 0; idx !== shrinkables.length; ++idx) { - safePush(cloned, shrinkables[idx].value); // push potentially cloned values + cloned.push(shrinkables[idx].value); // push potentially cloned values } this.makeItCloneable(cloned, shrinkables); return cloned; @@ -82,8 +81,8 @@ export class CloneArbitrary extends Arbitrary { for (let idx = 0; idx !== items.length; ++idx) { const s = items[idx]; cloneable = cloneable || s.hasToBeCloned; - safePush(vs, s.value); - safePush(contexts, s.context); + vs.push(s.value); + contexts.push(s.context); } if (cloneable) { CloneArbitrary.makeItCloneable(vs, items); diff --git a/packages/fast-check/src/arbitrary/_internals/ConstantArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/ConstantArbitrary.ts index 9cb933e9..2e93a7d0 100644 --- a/packages/fast-check/src/arbitrary/_internals/ConstantArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/ConstantArbitrary.ts @@ -3,7 +3,6 @@ import { Stream } from '../../stream/Stream.js'; import { Arbitrary } from '../../check/arbitrary/definition/Arbitrary.js'; import { Value } from '../../check/arbitrary/definition/Value.js'; import { cloneMethod, hasCloneMethod } from '../../check/symbols.js'; -import { Set, safeHas } from '../../utils/globals.js'; /** @internal */ class FastConstantValuesLookup { @@ -16,7 +15,7 @@ class FastConstantValuesLookup { let hasMinusZero = false; let hasPlusZero = false; - if (safeHas(this.fastValues, 0)) { + if (this.fastValues.has(0)) { for (let idx = 0; idx !== this.values.length; ++idx) { const value = this.values[idx]; hasMinusZero = hasMinusZero || Object.is(value, -0); @@ -34,7 +33,7 @@ class FastConstantValuesLookup { } return this.hasMinusZero; } - return safeHas(this.fastValues, value); + return this.fastValues.has(value); } } diff --git a/packages/fast-check/src/arbitrary/_internals/FrequencyArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/FrequencyArbitrary.ts index 7659a8f8..47157198 100644 --- a/packages/fast-check/src/arbitrary/_internals/FrequencyArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/FrequencyArbitrary.ts @@ -6,7 +6,6 @@ import type { DepthContext, DepthIdentifier } from './helpers/DepthContext.js'; import { getDepthContextFor } from './helpers/DepthContext.js'; import type { DepthSize } from './helpers/MaxLengthFromMinLength.js'; import { depthBiasFromSizeForArbitrary } from './helpers/MaxLengthFromMinLength.js'; -import { safePush } from '../../utils/globals.js'; /** @internal */ export class FrequencyArbitrary extends Arbitrary { @@ -49,7 +48,7 @@ export class FrequencyArbitrary extends Arbitrary { this.cumulatedWeights = []; for (let idx = 0; idx !== warbs.length; ++idx) { currentWeight += warbs[idx].weight; - safePush(this.cumulatedWeights, currentWeight); + this.cumulatedWeights.push(currentWeight); } this.totalWeight = currentWeight; } diff --git a/packages/fast-check/src/arbitrary/_internals/GeneratorArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/GeneratorArbitrary.ts index 6b4a1333..471153b3 100644 --- a/packages/fast-check/src/arbitrary/_internals/GeneratorArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/GeneratorArbitrary.ts @@ -2,7 +2,6 @@ import { Arbitrary } from '../../check/arbitrary/definition/Arbitrary.js'; import type { Value } from '../../check/arbitrary/definition/Value.js'; import type { Random } from '../../random/generator/Random.js'; import { Stream } from '../../stream/Stream.js'; -import { safeMap } from '../../utils/globals.js'; import type { GeneratorContext, GeneratorValue, PreBuiltValue } from './builders/GeneratorValueBuilder.js'; import { buildGeneratorValue } from './builders/GeneratorValueBuilder.js'; import { buildStableArbitraryGeneratorCache, naiveIsEqual } from './builders/StableArbitraryGeneratorCache.js'; @@ -42,7 +41,7 @@ export class GeneratorArbitrary extends Arbitrary { function computePreBuiltValues(): PreBuiltValue[] { const subValues = shrink.value; // trigger an explicit access to the value in case it needs to be cloned const subContexts = shrink.context; - return safeMap(history, (entry, index) => ({ + return history.map((entry, index) => ({ arb: entry.arb, value: subValues[index], context: subContexts[index], diff --git a/packages/fast-check/src/arbitrary/_internals/InitialPoolForEntityGraphArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/InitialPoolForEntityGraphArbitrary.ts index a4e33e3e..dfbff5e3 100644 --- a/packages/fast-check/src/arbitrary/_internals/InitialPoolForEntityGraphArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/InitialPoolForEntityGraphArbitrary.ts @@ -2,7 +2,6 @@ import { array, type ArrayConstraints } from '../array.js'; import type { Arbitrary } from '../../check/arbitrary/definition/Arbitrary.js'; import { tuple } from '../tuple.js'; import { constant } from '../constant.js'; -import { safeFlat, Error as SError } from '../../utils/globals.js'; type InitialPoolForEntityGraphConstraints = { [EntityName in TEntityNames]?: ArrayConstraints; @@ -31,7 +30,7 @@ export function initialPoolForEntityGraph( } if (!canHaveAtLeastOneItem(keys, constraints)) { - throw new SError('Contraints on pool must accept at least one entity, maxLength cannot sum to 0'); + throw new Error('Contraints on pool must accept at least one entity, maxLength cannot sum to 0'); } const arbitraries: Arbitrary[] = keys.map((key) => array(constant(key), constraints[key])); @@ -39,7 +38,7 @@ export function initialPoolForEntityGraph( tuple(...arbitraries) // While algorithmic-wise it could be great to reverse this mapping, from a usage point-of-view we don't care. // This arbitrary will stay internal and be only used to fuel a .chain and thus reversing it will not be useful. - .map((values) => safeFlat(values)) + .map((values) => values.flat()) // For now, we restrict our checks on the length being >0. // We consider that breaching the length by having more than 4294967295 names is something that should be handled by the user. .filter((names) => names.length > 0) diff --git a/packages/fast-check/src/arbitrary/_internals/MixedCaseArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/MixedCaseArbitrary.ts index 40d04af0..90fbc76e 100644 --- a/packages/fast-check/src/arbitrary/_internals/MixedCaseArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/MixedCaseArbitrary.ts @@ -10,8 +10,6 @@ import { computeNextFlags, computeTogglePositions, } from './helpers/ToggleFlags.js'; -import { safeJoin, safeSlice } from '../../utils/globals.js'; -import { BigInt } from '../../utils/globals.js'; /** @internal */ type MixedCaseArbitraryContext = { @@ -55,7 +53,7 @@ export class MixedCaseArbitrary extends Arbitrary { const flagsValue = flagsArb.generate(mrng, undefined); // true => toggle the char, false => keep it as-is applyFlagsOnChars(chars, flagsValue.value, togglePositions, this.toggleCase); - return new Value(safeJoin(chars, ''), this.buildContextFor(rawStringValue, flagsValue)); + return new Value(chars.join(''), this.buildContextFor(rawStringValue, flagsValue)); } canShrinkWithoutContext(value: unknown): value is string { @@ -108,7 +106,7 @@ export class MixedCaseArbitrary extends Arbitrary { applyFlagsOnChars(nChars, nFlags, nTogglePositions, this.toggleCase); // Remark: Value nFlags can be attached to a context equal to undefined // as `canShrinkWithoutContext(nFlags) === true` for the bigint arbitrary - return new Value(safeJoin(nChars, ''), this.buildContextFor(nRawStringValue, new Value(nFlags, undefined))); + return new Value(nChars.join(''), this.buildContextFor(nRawStringValue, new Value(nFlags, undefined))); }) .join( makeLazy(() => { @@ -117,10 +115,10 @@ export class MixedCaseArbitrary extends Arbitrary { return bigInt(0n, (1n << BigInt(togglePositions.length)) - 1n) .shrink(flags, contextSafe.flagsContext) .map((nFlagsValue) => { - const nChars = safeSlice(chars); // cloning chars + const nChars = chars.slice(); // cloning chars applyFlagsOnChars(nChars, nFlagsValue.value, togglePositions, this.toggleCase); return new Value( - safeJoin(nChars, ''), + nChars.join(''), this.buildContextFor(new Value(rawString, contextSafe.rawStringContext), nFlagsValue), ); }); diff --git a/packages/fast-check/src/arbitrary/_internals/StreamArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/StreamArbitrary.ts index 027c6720..2675c902 100644 --- a/packages/fast-check/src/arbitrary/_internals/StreamArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/StreamArbitrary.ts @@ -3,12 +3,11 @@ import { Value } from '../../check/arbitrary/definition/Value.js'; import { cloneMethod } from '../../check/symbols.js'; import type { Random } from '../../random/generator/Random.js'; import { Stream } from '../../stream/Stream.js'; -import { safeJoin, safePush } from '../../utils/globals.js'; import { asyncStringify, asyncToStringMethod, stringify, toStringMethod } from '../../utils/stringify.js'; /** @internal */ function prettyPrint(numSeen: number, seenValuesStrings?: string[]): string { - const seenSegment = seenValuesStrings !== undefined ? `${safeJoin(seenValuesStrings, ',')}…` : `${numSeen} emitted`; + const seenSegment = seenValuesStrings !== undefined ? `${seenValuesStrings.join(',')}…` : `${numSeen} emitted`; return `Stream(${seenSegment})`; } @@ -31,7 +30,7 @@ export class StreamArbitrary extends Arbitrary> { const value = arb.generate(clonedMrng, appliedBiasFactor).value; numSeenValues++; if (seenValues !== null) { - safePush(seenValues, value); + seenValues.push(value); } yield value; } diff --git a/packages/fast-check/src/arbitrary/_internals/StringUnitArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/StringUnitArbitrary.ts index 5ed60e78..09fb0a06 100644 --- a/packages/fast-check/src/arbitrary/_internals/StringUnitArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/StringUnitArbitrary.ts @@ -1,5 +1,4 @@ import type { Arbitrary } from '../../check/arbitrary/definition/Arbitrary.js'; -import { safeNormalize, safePush } from '../../utils/globals.js'; import { mapToConstant } from '../mapToConstant.js'; import type { GraphemeRange } from './data/GraphemeRanges.js'; import { @@ -45,15 +44,15 @@ function getOrCreateStringUnitInstance(type: StringUnitType, alphabet: StringUni const ranges = type === 'binary' ? alphabetRanges : intersectGraphemeRanges(alphabetRanges, autonomousGraphemeRanges); const entries: GraphemeRangeEntry[] = []; for (const range of ranges) { - safePush(entries, convertGraphemeRangeToMapToConstantEntry(range)); + entries.push(convertGraphemeRangeToMapToConstantEntry(range)); } if (type === 'grapheme') { const decomposedRanges = intersectGraphemeRanges(alphabetRanges, autonomousDecomposableGraphemeRanges); for (const range of decomposedRanges) { const rawEntry = convertGraphemeRangeToMapToConstantEntry(range); - safePush(entries, { + entries.push({ num: rawEntry.num, - build: (idInGroup) => safeNormalize(rawEntry.build(idInGroup), 'NFD'), + build: (idInGroup) => rawEntry.build(idInGroup).normalize('NFD'), }); } } diff --git a/packages/fast-check/src/arbitrary/_internals/TupleArbitrary.ts b/packages/fast-check/src/arbitrary/_internals/TupleArbitrary.ts index e804498c..ee28257e 100644 --- a/packages/fast-check/src/arbitrary/_internals/TupleArbitrary.ts +++ b/packages/fast-check/src/arbitrary/_internals/TupleArbitrary.ts @@ -4,7 +4,6 @@ import type { WithCloneMethod } from '../../check/symbols.js'; import { cloneIfNeeded, cloneMethod } from '../../check/symbols.js'; import { Arbitrary } from '../../check/arbitrary/definition/Arbitrary.js'; import { Value } from '../../check/arbitrary/definition/Value.js'; -import { safePush } from '../../utils/globals.js'; import { makeLazy } from '../../stream/LazyIterableIterator.js'; /** @internal */ @@ -26,7 +25,7 @@ function tupleMakeItCloneable( if (current === undefined) { current = new Value(vs[idx], ctxs[idx]); // backfill missing indices in values. Each missing idx is simply a dummy Value instance } - safePush(cloned, current.value); // push potentially cloned values + cloned.push(current.value); // push potentially cloned values } tupleMakeItCloneable(cloned, ctxs, values); return cloned; @@ -45,8 +44,7 @@ export function tupleShrink( const shrinks: IterableIterator>[] = []; const safeContext: TupleContext = Array.isArray(context) ? context : []; for (let idx = 0; idx !== arbs.length; ++idx) { - safePush( - shrinks, + shrinks.push( makeLazy(() => arbs[idx].shrink(value[idx], safeContext[idx]).map((v) => { let cloneable = false; @@ -59,8 +57,8 @@ export function tupleShrink( cloneable = true; mapped[nestedIdx] = nestedV; } - safePush(vs, nestedV.value); - safePush(ctxs, nestedV.context); + vs.push(nestedV.value); + ctxs.push(nestedV.context); } if (cloneable) { tupleMakeItCloneable(vs, ctxs, mapped); @@ -94,8 +92,8 @@ export class TupleArbitrary extends Arbitrary { cloneable = true; mapped[idx] = v; } - safePush(vs, v.value); - safePush(ctxs, v.context); + vs.push(v.value); + ctxs.push(v.context); } if (cloneable) { tupleMakeItCloneable(vs, ctxs, mapped); diff --git a/packages/fast-check/src/arbitrary/_internals/builders/CompareFunctionArbitraryBuilder.ts b/packages/fast-check/src/arbitrary/_internals/builders/CompareFunctionArbitraryBuilder.ts index b0064a97..e6f54edd 100644 --- a/packages/fast-check/src/arbitrary/_internals/builders/CompareFunctionArbitraryBuilder.ts +++ b/packages/fast-check/src/arbitrary/_internals/builders/CompareFunctionArbitraryBuilder.ts @@ -6,7 +6,6 @@ import { stringify } from '../../../utils/stringify.js'; import { integer } from '../../integer.js'; import { noShrink } from '../../noShrink.js'; import { tuple } from '../../tuple.js'; -import { safeJoin } from '../../../utils/globals.js'; /** @internal */ export function buildCompareFunctionArbitrary( @@ -31,9 +30,7 @@ export function buildCompareFunctionArbitrary( .map((k) => `${k} => ${stringify(recorded[k])}`) .map((line) => `/* ${escapeForMultilineComments(line)} */`); return `function(a, b) { - // With hash and stringify coming from fast-check${ - seenValues.length !== 0 ? `\n ${safeJoin(seenValues, '\n ')}` : '' - } + // With hash and stringify coming from fast-check${seenValues.length !== 0 ? `\n ${seenValues.join('\n ')}` : ''} const cmp = ${cmp}; const hA = hash('${seed}' + stringify(a)) % ${hashEnvSize}; const hB = hash('${seed}' + stringify(b)) % ${hashEnvSize}; diff --git a/packages/fast-check/src/arbitrary/_internals/builders/GeneratorValueBuilder.ts b/packages/fast-check/src/arbitrary/_internals/builders/GeneratorValueBuilder.ts index 83f06f18..72415923 100644 --- a/packages/fast-check/src/arbitrary/_internals/builders/GeneratorValueBuilder.ts +++ b/packages/fast-check/src/arbitrary/_internals/builders/GeneratorValueBuilder.ts @@ -2,7 +2,6 @@ import type { Arbitrary } from '../../../check/arbitrary/definition/Arbitrary.js import { Value } from '../../../check/arbitrary/definition/Value.js'; import { cloneMethod } from '../../../check/symbols.js'; import type { Random } from '../../../random/generator/Random.js'; -import { safeMap, safePush } from '../../../utils/globals.js'; import { stringify, toStringMethod } from '../../../utils/stringify.js'; import type { ArbitraryGeneratorCache } from './StableArbitraryGeneratorCache.js'; @@ -90,7 +89,7 @@ export function buildGeneratorValue( if (preBuiltValue !== undefined && preBuiltValue.arb === arb) { // Until it matches we just re-use the originally produced value const value = preBuiltValue.value; - safePush(context.history, { arb, value, context: preBuiltValue.context, mrng: preBuiltValue.mrng }); + context.history.push({ arb, value, context: preBuiltValue.context, mrng: preBuiltValue.mrng }); localMrng = preBuiltValue.mrng.clone(); return value as T; } @@ -100,7 +99,7 @@ export function buildGeneratorValue( // In other words: `preBuiltValue !== undefined && context.history.length === 0` is a legit case! // If we start to mismatch we run a new random value computation const g = arb.generate(localMrng, biasFactor); - safePush(context.history, { arb, value: g.value_, context: g.context, mrng: localMrng.clone() }); + context.history.push({ arb, value: g.value_, context: g.context, mrng: localMrng.clone() }); return g.value; }; @@ -113,13 +112,13 @@ export function buildGeneratorValue( const valueMethods = { values(): unknown[] { - return safeMap(context.history, (c) => c.value); + return context.history.map((c) => c.value); }, [cloneMethod](): GeneratorValue { return buildGeneratorValue(mrng, biasFactor, computePreBuiltValues, arbitraryCache).value; }, [toStringMethod](): string { - return stringify(safeMap(context.history, (c) => c.value)); + return stringify(context.history.map((c) => c.value)); }, }; diff --git a/packages/fast-check/src/arbitrary/base64String.ts b/packages/fast-check/src/arbitrary/base64String.ts index a3c37440..1616e2c9 100644 --- a/packages/fast-check/src/arbitrary/base64String.ts +++ b/packages/fast-check/src/arbitrary/base64String.ts @@ -7,7 +7,6 @@ import { codePointsToStringMapper, codePointsToStringUnmapper } from './_interna import { stringToBase64Mapper, stringToBase64Unmapper } from './_internals/mappers/StringToBase64.js'; import { createSlicesForStringLegacy } from './_internals/helpers/SlicesForStringBuilder.js'; import { integer } from './integer.js'; -import { Error, safeCharCodeAt } from '../utils/globals.js'; export type { StringSharedConstraints } from './_shared/StringSharedConstraints.js'; /** @internal */ @@ -23,7 +22,7 @@ function base64Unmapper(s: unknown) { if (typeof s !== 'string' || s.length !== 1) { throw new Error('Invalid entry'); } - const v = safeCharCodeAt(s, 0); + const v = s.charCodeAt(0); if (v >= 65 && v <= 90) return v - 65; // A-Z if (v >= 97 && v <= 122) return v - 97 + 26; // a-z if (v >= 48 && v <= 57) return v - 48 + 52; // 0-9 diff --git a/packages/fast-check/src/arbitrary/date.ts b/packages/fast-check/src/arbitrary/date.ts index 074c5719..455c7763 100644 --- a/packages/fast-check/src/arbitrary/date.ts +++ b/packages/fast-check/src/arbitrary/date.ts @@ -1,5 +1,4 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { safeGetTime } from '../utils/globals.js'; import { integer } from './integer.js'; import { timeToDateMapper, @@ -44,8 +43,8 @@ export interface DateConstraints { */ export function date(constraints: DateConstraints = {}): Arbitrary { // Date min and max in ECMAScript specification : https://stackoverflow.com/a/11526569/3707828 - const intMin = constraints.min !== undefined ? safeGetTime(constraints.min) : -8640000000000000; - const intMax = constraints.max !== undefined ? safeGetTime(constraints.max) : 8640000000000000; + const intMin = constraints.min !== undefined ? constraints.min.getTime() : -8640000000000000; + const intMax = constraints.max !== undefined ? constraints.max.getTime() : 8640000000000000; const noInvalidDate = constraints.noInvalidDate; if (Number.isNaN(intMin)) throw new Error('fc.date min must be valid instance of Date'); if (Number.isNaN(intMax)) throw new Error('fc.date max must be valid instance of Date'); diff --git a/packages/fast-check/src/arbitrary/domain.ts b/packages/fast-check/src/arbitrary/domain.ts index 7761bd70..24a7393b 100644 --- a/packages/fast-check/src/arbitrary/domain.ts +++ b/packages/fast-check/src/arbitrary/domain.ts @@ -12,7 +12,6 @@ import type { Size, SizeForArbitrary } from './_internals/helpers/MaxLengthFromM import { resolveSize, relativeSizeToSize } from './_internals/helpers/MaxLengthFromMinLength.js'; import type { AdapterOutput } from './_internals/AdapterArbitrary.js'; import { adapter } from './_internals/AdapterArbitrary.js'; -import { safeJoin, safeSlice, safeSplit, safeSubstring } from '../utils/globals.js'; /** @internal */ function toSubdomainLabelMapper([f, d]: [string, [string, string] | null]): string { @@ -26,7 +25,7 @@ function toSubdomainLabelUnmapper(value: unknown): [string, [string, string] | n if (value.length === 1) { return [value[0], null]; } - return [value[0], [safeSubstring(value, 1, value.length - 1), value[value.length - 1]]]; + return [value[0], [value.substring(1, value.length - 1), value[value.length - 1]]]; } /** @internal */ @@ -56,7 +55,7 @@ function subdomainLabel(size: Size) { /** @internal */ function labelsMapper(elements: [string[], string]): string { - return `${safeJoin(elements[0], '.')}.${elements[1]}`; + return `${elements[0].join('.')}.${elements[1]}`; } /** @internal */ function labelsUnmapper(value: unknown): [string[], string] { @@ -64,7 +63,7 @@ function labelsUnmapper(value: unknown): [string[], string] { throw new Error('Unsupported type'); } const lastDotIndex = value.lastIndexOf('.'); - return [safeSplit(safeSubstring(value, 0, lastDotIndex), '.'), safeSubstring(value, lastDotIndex + 1)]; + return [value.substring(0, lastDotIndex).split('.'), value.substring(lastDotIndex + 1)]; } /** @internal */ @@ -79,7 +78,7 @@ function labelsAdapter(labels: [string[], string]): AdapterOutput<[string[], str // a domain name (i.e., the sum of all label octets and label lengths) is limited to 255. // It seems that this restriction has been relaxed in modern web browsers. if (lengthNotIncludingIndex > 255) { - return { adapted: true, value: [safeSlice(subDomains, 0, index), suffix] }; + return { adapted: true, value: [subDomains.slice(0, index), suffix] }; } } return { adapted: false, value: labels }; diff --git a/packages/fast-check/src/arbitrary/emailAddress.ts b/packages/fast-check/src/arbitrary/emailAddress.ts index 04790627..88f2524d 100644 --- a/packages/fast-check/src/arbitrary/emailAddress.ts +++ b/packages/fast-check/src/arbitrary/emailAddress.ts @@ -7,7 +7,6 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; import type { SizeForArbitrary } from './_internals/helpers/MaxLengthFromMinLength.js'; import type { AdapterOutput } from './_internals/AdapterArbitrary.js'; import { adapter } from './_internals/AdapterArbitrary.js'; -import { safeJoin, safeSlice, safeSplit } from '../utils/globals.js'; /** @internal */ function dotAdapter(a: string[]): AdapterOutput { @@ -17,21 +16,21 @@ function dotAdapter(a: string[]): AdapterOutput { for (let index = 1; index !== a.length; ++index) { currentLength += 1 + a[index].length; if (currentLength > 64) { - return { adapted: true, value: safeSlice(a, 0, index) }; + return { adapted: true, value: a.slice(0, index) }; } } return { adapted: false, value: a }; } /** @internal */ function dotMapper(a: string[]): string { - return safeJoin(a, '.'); + return a.join('.'); } /** @internal */ function dotUnmapper(value: unknown): string[] { if (typeof value !== 'string') { throw new Error('Unsupported'); } - return safeSplit(value, '.'); + return value.split('.'); } /** @internal */ function atMapper(data: [string, string]): string { @@ -42,7 +41,7 @@ function atUnmapper(value: unknown): [string, string] { if (typeof value !== 'string') { throw new Error('Unsupported'); } - return safeSplit(value, '@', 2) as [string, string]; + return value.split('@', 2) as [string, string]; } /** diff --git a/packages/fast-check/src/arbitrary/float32Array.ts b/packages/fast-check/src/arbitrary/float32Array.ts index 329942f6..9f0bb07c 100644 --- a/packages/fast-check/src/arbitrary/float32Array.ts +++ b/packages/fast-check/src/arbitrary/float32Array.ts @@ -3,7 +3,6 @@ import type { FloatConstraints } from './float.js'; import { float } from './float.js'; import { array } from './array.js'; import type { SizeForArbitrary } from './_internals/helpers/MaxLengthFromMinLength.js'; -import { Float32Array as SFloat32Array } from '../utils/globals.js'; /** * Constraints to be applied on {@link float32Array} @@ -32,12 +31,12 @@ export type Float32ArrayConstraints = { /** @internal */ function toTypedMapper(data: number[]): Float32Array { - return SFloat32Array.from(data); + return Float32Array.from(data); } /** @internal */ function fromTypedUnmapper(value: unknown): number[] { - if (!(value instanceof SFloat32Array)) throw new Error('Unexpected type'); + if (!(value instanceof Float32Array)) throw new Error('Unexpected type'); return [...value]; } diff --git a/packages/fast-check/src/arbitrary/float64Array.ts b/packages/fast-check/src/arbitrary/float64Array.ts index 026a6655..13199466 100644 --- a/packages/fast-check/src/arbitrary/float64Array.ts +++ b/packages/fast-check/src/arbitrary/float64Array.ts @@ -3,7 +3,6 @@ import type { DoubleConstraints } from './double.js'; import { double } from './double.js'; import { array } from './array.js'; import type { SizeForArbitrary } from './_internals/helpers/MaxLengthFromMinLength.js'; -import { Float64Array as SFloat64Array } from '../utils/globals.js'; /** * Constraints to be applied on {@link float64Array} @@ -32,12 +31,12 @@ export type Float64ArrayConstraints = { /** @internal */ function toTypedMapper(data: number[]): Float64Array { - return SFloat64Array.from(data); + return Float64Array.from(data); } /** @internal */ function fromTypedUnmapper(value: unknown): number[] { - if (!(value instanceof SFloat64Array)) throw new Error('Unexpected type'); + if (!(value instanceof Float64Array)) throw new Error('Unexpected type'); return [...value]; } diff --git a/packages/fast-check/src/arbitrary/func.ts b/packages/fast-check/src/arbitrary/func.ts index 7f5cd1c1..fd968626 100644 --- a/packages/fast-check/src/arbitrary/func.ts +++ b/packages/fast-check/src/arbitrary/func.ts @@ -7,7 +7,6 @@ import { integer } from './integer.js'; import { noShrink } from './noShrink.js'; import { tuple } from './tuple.js'; import { escapeForMultilineComments } from './_internals/helpers/TextEscaper.js'; -import { safeMap, safeSort } from '../utils/globals.js'; /** * For pure functions @@ -28,10 +27,10 @@ export function func(arb: Arbitrary): Arbitrary return hasCloneMethod(val) ? val[cloneMethod]() : val; }; function prettyPrint(stringifiedOuts: string): string { - const seenValues = safeMap( - safeMap(safeSort(Object.keys(recorded)), (k) => `${k} => ${stringify(recorded[k])}`), - (line) => `/* ${escapeForMultilineComments(line)} */`, - ); + const seenValues = Object.keys(recorded) + .sort() + .map((k) => `${k} => ${stringify(recorded[k])}`) + .map((line) => `/* ${escapeForMultilineComments(line)} */`); return `function(...args) { // With hash and stringify coming from fast-check${seenValues.length !== 0 ? `\n ${seenValues.join('\n ')}` : ''} const outs = ${stringifiedOuts}; diff --git a/packages/fast-check/src/arbitrary/int16Array.ts b/packages/fast-check/src/arbitrary/int16Array.ts index 57204866..bd6a1f8b 100644 --- a/packages/fast-check/src/arbitrary/int16Array.ts +++ b/packages/fast-check/src/arbitrary/int16Array.ts @@ -1,5 +1,4 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { Int16Array as SInt16Array } from '../utils/globals.js'; import { integer } from './integer.js'; import type { IntArrayConstraints } from './_internals/builders/TypedIntArrayArbitraryBuilder.js'; import { typedIntArrayArbitraryArbitraryBuilder } from './_internals/builders/TypedIntArrayArbitraryBuilder.js'; @@ -14,7 +13,7 @@ export function int16Array(constraints: IntArrayConstraints = {}): Arbitrary tryParseStringifiedNat(v, 10)); + return value.split('.').map((v) => tryParseStringifiedNat(v, 10)); } /** diff --git a/packages/fast-check/src/arbitrary/ipV4Extended.ts b/packages/fast-check/src/arbitrary/ipV4Extended.ts index 54100f93..897e0ab7 100644 --- a/packages/fast-check/src/arbitrary/ipV4Extended.ts +++ b/packages/fast-check/src/arbitrary/ipV4Extended.ts @@ -1,12 +1,11 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { safeJoin, safeSplit } from '../utils/globals.js'; import { oneof } from './oneof.js'; import { tuple } from './tuple.js'; import { buildStringifiedNatArbitrary } from './_internals/builders/StringifiedNatArbitraryBuilder.js'; /** @internal */ function dotJoinerMapper(data: string[]): string { - return safeJoin(data, '.'); + return data.join('.'); } /** @internal */ @@ -14,7 +13,7 @@ function dotJoinerUnmapper(value: unknown): string[] { if (typeof value !== 'string') { throw new Error('Invalid type'); } - return safeSplit(value, '.'); + return value.split('.'); } /** diff --git a/packages/fast-check/src/arbitrary/ipV6.ts b/packages/fast-check/src/arbitrary/ipV6.ts index e8ed51a0..a6a2c43c 100644 --- a/packages/fast-check/src/arbitrary/ipV6.ts +++ b/packages/fast-check/src/arbitrary/ipV6.ts @@ -19,7 +19,6 @@ import { noTrailingUnmapper, } from './_internals/mappers/EntitiesToIPv6.js'; import { integer } from './integer.js'; -import { safeCharCodeAt, Error } from '../utils/globals.js'; /** @internal */ function h16sTol32Mapper([a, b]: [string, string]): string { @@ -47,7 +46,7 @@ function hexa(): Arbitrary { if (c.length !== 1) { throw new Error('Invalid length'); } - const code = safeCharCodeAt(c, 0); // 0=48,..,9=57,a=97,..,f=102 + const code = c.charCodeAt(0); // 0=48,..,9=57,a=97,..,f=102 if (code <= 57) { return code - 48; // any char before '0' will lead to <0 (rejected by integer) } diff --git a/packages/fast-check/src/arbitrary/json.ts b/packages/fast-check/src/arbitrary/json.ts index aca0ec9e..95722b03 100644 --- a/packages/fast-check/src/arbitrary/json.ts +++ b/packages/fast-check/src/arbitrary/json.ts @@ -1,7 +1,6 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; import { jsonValue } from './jsonValue.js'; import type { JsonSharedConstraints, JsonValue } from './_internals/helpers/JsonConstraintsBuilder.js'; -import { Error } from '../utils/globals.js'; export type { JsonSharedConstraints }; diff --git a/packages/fast-check/src/arbitrary/letrec.ts b/packages/fast-check/src/arbitrary/letrec.ts index 9dc2d9d2..77c8d597 100644 --- a/packages/fast-check/src/arbitrary/letrec.ts +++ b/packages/fast-check/src/arbitrary/letrec.ts @@ -1,6 +1,5 @@ import { LazyArbitrary } from './_internals/LazyArbitrary.js'; import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { Map as SMap, safeMapSet, safeMapGet } from '../utils/globals.js'; /** * Type of the value produced by {@link letrec} @@ -50,14 +49,14 @@ export type LetrecLooselyTypedBuilder = (tie: LetrecLooselyTypedTie) => Letre /** @internal */ function createLazyArbsPool() { - const lazyArbsPool = new SMap>(); + const lazyArbsPool = new Map>(); const getLazyFromPool = (key: keyof T): LazyArbitrary => { - let lazyArb = safeMapGet(lazyArbsPool, key); + let lazyArb = lazyArbsPool.get(key); if (lazyArb !== undefined) { return lazyArb; } lazyArb = new LazyArbitrary(String(key)); - safeMapSet(lazyArbsPool, key, lazyArb); + lazyArbsPool.set(key, lazyArb); return lazyArb; }; return getLazyFromPool; diff --git a/packages/fast-check/src/arbitrary/mapToConstant.ts b/packages/fast-check/src/arbitrary/mapToConstant.ts index ec9e55f8..db44e0e1 100644 --- a/packages/fast-check/src/arbitrary/mapToConstant.ts +++ b/packages/fast-check/src/arbitrary/mapToConstant.ts @@ -4,7 +4,6 @@ import { indexToMappedConstantMapperFor, indexToMappedConstantUnmapperFor, } from './_internals/mappers/IndexToMappedConstant.js'; -import { Error } from '../utils/globals.js'; /** @internal */ function computeNumChoices(options: { num: number; build: (idInGroup: number) => T }[]): number { diff --git a/packages/fast-check/src/arbitrary/mixedCase.ts b/packages/fast-check/src/arbitrary/mixedCase.ts index d996758d..894f2b4c 100644 --- a/packages/fast-check/src/arbitrary/mixedCase.ts +++ b/packages/fast-check/src/arbitrary/mixedCase.ts @@ -1,5 +1,4 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { safeToUpperCase, safeToLowerCase } from '../utils/globals.js'; import { MixedCaseArbitrary } from './_internals/MixedCaseArbitrary.js'; /** @@ -24,9 +23,9 @@ export interface MixedCaseConstraints { /** @internal */ function defaultToggleCase(rawChar: string) { - const upper = safeToUpperCase(rawChar); + const upper = rawChar.toUpperCase(); if (upper !== rawChar) return upper; - return safeToLowerCase(rawChar); + return rawChar.toLowerCase(); } /** diff --git a/packages/fast-check/src/arbitrary/oneof.ts b/packages/fast-check/src/arbitrary/oneof.ts index 2e138007..da190e69 100644 --- a/packages/fast-check/src/arbitrary/oneof.ts +++ b/packages/fast-check/src/arbitrary/oneof.ts @@ -1,6 +1,5 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; import { isArbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { safeMap, safeSlice } from '../utils/globals.js'; import { FrequencyArbitrary } from './_internals/FrequencyArbitrary.js'; import type { DepthIdentifier } from './_internals/helpers/DepthContext.js'; import type { DepthSize } from './_internals/helpers/MaxLengthFromMinLength.js'; @@ -146,10 +145,10 @@ function oneof[]>( // TODO With TypeScript 4.0 it will be possible to properly define typings for `oneof(...arbs, constraints)` const constraints = args[0]; if (isOneOfContraints(constraints)) { - const weightedArbs = safeMap(safeSlice(args, 1) as MaybeWeightedArbitrary>[], toWeightedArbitrary); + const weightedArbs = (args.slice(1) as MaybeWeightedArbitrary>[]).map(toWeightedArbitrary); return FrequencyArbitrary.from(weightedArbs, constraints, 'fc.oneof'); } - const weightedArbs = safeMap(args as MaybeWeightedArbitrary>[], toWeightedArbitrary); + const weightedArbs = (args as MaybeWeightedArbitrary>[]).map(toWeightedArbitrary); return FrequencyArbitrary.from(weightedArbs, {}, 'fc.oneof'); } export { oneof }; diff --git a/packages/fast-check/src/arbitrary/sparseArray.ts b/packages/fast-check/src/arbitrary/sparseArray.ts index c3e130db..b0caedde 100644 --- a/packages/fast-check/src/arbitrary/sparseArray.ts +++ b/packages/fast-check/src/arbitrary/sparseArray.ts @@ -1,5 +1,4 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { Array, safeMap, safeSlice } from '../utils/globals.js'; import { tuple } from './tuple.js'; import { uniqueArray } from './uniqueArray.js'; import { restrictedIntegerArbitraryBuilder } from './_internals/builders/RestrictedIntegerArbitraryBuilder.js'; @@ -145,7 +144,7 @@ export function sparseArray(arb: Arbitrary, constraints: SparseArrayConstr if (noTrailingHole && value.length !== 0 && !(value.length - 1 in value)) { throw new Error('No trailing hole'); } - return safeMap(Object.entries(value as T[]), (entry): [number, T] => [Number(entry[0]), entry[1]]); + return Object.entries(value as T[]).map((entry): [number, T] => [Number(entry[0]), entry[1]]); }, ); @@ -163,7 +162,7 @@ export function sparseArray(arb: Arbitrary, constraints: SparseArrayConstr if (sparse.length >= targetLength) { return sparse; } - const longerSparse = safeSlice(sparse); + const longerSparse = sparse.slice(); longerSparse.length = targetLength; return longerSparse; }, diff --git a/packages/fast-check/src/arbitrary/uint16Array.ts b/packages/fast-check/src/arbitrary/uint16Array.ts index 0e640f80..9d5a1fb0 100644 --- a/packages/fast-check/src/arbitrary/uint16Array.ts +++ b/packages/fast-check/src/arbitrary/uint16Array.ts @@ -1,5 +1,4 @@ import type { Arbitrary } from '../check/arbitrary/definition/Arbitrary.js'; -import { Uint16Array as SUint16Array } from '../utils/globals.js'; import { integer } from './integer.js'; import type { IntArrayConstraints } from './_internals/builders/TypedIntArrayArbitraryBuilder.js'; import { typedIntArrayArbitraryArbitraryBuilder } from './_internals/builders/TypedIntArrayArbitraryBuilder.js'; @@ -14,7 +13,7 @@ export function uint16Array(constraints: IntArrayConstraints = {}): Arbitrary