Aktueller Stand

This commit is contained in:
2026-01-23 01:33:35 +01:00
parent 082dc5e110
commit 2766dd12c5
10109 changed files with 1578841 additions and 77685 deletions

View File

@@ -0,0 +1,213 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Arbitrary = void 0;
exports.isArbitrary = isArbitrary;
exports.assertIsArbitrary = assertIsArbitrary;
const Stream_1 = require("../../../stream/Stream");
const symbols_1 = require("../../symbols");
const Value_1 = require("./Value");
const safeObjectAssign = Object.assign;
class Arbitrary {
filter(refinement) {
return new FilterArbitrary(this, refinement);
}
map(mapper, unmapper) {
return new MapArbitrary(this, mapper, unmapper);
}
chain(chainer) {
return new ChainArbitrary(this, chainer);
}
noShrink() {
return new NoShrinkArbitrary(this);
}
noBias() {
return new NoBiasArbitrary(this);
}
}
exports.Arbitrary = Arbitrary;
class ChainArbitrary extends Arbitrary {
constructor(arb, chainer) {
super();
this.arb = arb;
this.chainer = chainer;
}
generate(mrng, biasFactor) {
const clonedMrng = mrng.clone();
const src = this.arb.generate(mrng, biasFactor);
return this.valueChainer(src, mrng, clonedMrng, biasFactor);
}
canShrinkWithoutContext(value) {
return false;
}
shrink(value, context) {
if (this.isSafeContext(context)) {
return (!context.stoppedForOriginal
? this.arb
.shrink(context.originalValue, context.originalContext)
.map((v) => this.valueChainer(v, context.clonedMrng.clone(), context.clonedMrng, context.originalBias))
: Stream_1.Stream.nil()).join(context.chainedArbitrary.shrink(value, context.chainedContext).map((dst) => {
const newContext = safeObjectAssign(safeObjectAssign({}, context), {
chainedContext: dst.context,
stoppedForOriginal: true,
});
return new Value_1.Value(dst.value_, newContext);
}));
}
return Stream_1.Stream.nil();
}
valueChainer(v, generateMrng, clonedMrng, biasFactor) {
const chainedArbitrary = this.chainer(v.value_);
const dst = chainedArbitrary.generate(generateMrng, biasFactor);
const context = {
originalBias: biasFactor,
originalValue: v.value_,
originalContext: v.context,
stoppedForOriginal: false,
chainedArbitrary,
chainedContext: dst.context,
clonedMrng,
};
return new Value_1.Value(dst.value_, context);
}
isSafeContext(context) {
return (context != null &&
typeof context === 'object' &&
'originalBias' in context &&
'originalValue' in context &&
'originalContext' in context &&
'stoppedForOriginal' in context &&
'chainedArbitrary' in context &&
'chainedContext' in context &&
'clonedMrng' in context);
}
}
class MapArbitrary extends Arbitrary {
constructor(arb, mapper, unmapper) {
super();
this.arb = arb;
this.mapper = mapper;
this.unmapper = unmapper;
this.bindValueMapper = (v) => this.valueMapper(v);
}
generate(mrng, biasFactor) {
const g = this.arb.generate(mrng, biasFactor);
return this.valueMapper(g);
}
canShrinkWithoutContext(value) {
if (this.unmapper !== undefined) {
try {
const unmapped = this.unmapper(value);
return this.arb.canShrinkWithoutContext(unmapped);
}
catch (_err) {
return false;
}
}
return false;
}
shrink(value, context) {
if (this.isSafeContext(context)) {
return this.arb.shrink(context.originalValue, context.originalContext).map(this.bindValueMapper);
}
if (this.unmapper !== undefined) {
const unmapped = this.unmapper(value);
return this.arb.shrink(unmapped, undefined).map(this.bindValueMapper);
}
return Stream_1.Stream.nil();
}
mapperWithCloneIfNeeded(v) {
const sourceValue = v.value;
const mappedValue = this.mapper(sourceValue);
if (v.hasToBeCloned &&
((typeof mappedValue === 'object' && mappedValue !== null) || typeof mappedValue === 'function') &&
Object.isExtensible(mappedValue) &&
!(0, symbols_1.hasCloneMethod)(mappedValue)) {
Object.defineProperty(mappedValue, symbols_1.cloneMethod, { get: () => () => this.mapperWithCloneIfNeeded(v)[0] });
}
return [mappedValue, sourceValue];
}
valueMapper(v) {
const [mappedValue, sourceValue] = this.mapperWithCloneIfNeeded(v);
const context = { originalValue: sourceValue, originalContext: v.context };
return new Value_1.Value(mappedValue, context);
}
isSafeContext(context) {
return (context != null &&
typeof context === 'object' &&
'originalValue' in context &&
'originalContext' in context);
}
}
class FilterArbitrary extends Arbitrary {
constructor(arb, refinement) {
super();
this.arb = arb;
this.refinement = refinement;
this.bindRefinementOnValue = (v) => this.refinementOnValue(v);
}
generate(mrng, biasFactor) {
while (true) {
const g = this.arb.generate(mrng, biasFactor);
if (this.refinementOnValue(g)) {
return g;
}
}
}
canShrinkWithoutContext(value) {
return this.arb.canShrinkWithoutContext(value) && this.refinement(value);
}
shrink(value, context) {
return this.arb.shrink(value, context).filter(this.bindRefinementOnValue);
}
refinementOnValue(v) {
return this.refinement(v.value);
}
}
class NoShrinkArbitrary extends Arbitrary {
constructor(arb) {
super();
this.arb = arb;
}
generate(mrng, biasFactor) {
return this.arb.generate(mrng, biasFactor);
}
canShrinkWithoutContext(value) {
return this.arb.canShrinkWithoutContext(value);
}
shrink(_value, _context) {
return Stream_1.Stream.nil();
}
noShrink() {
return this;
}
}
class NoBiasArbitrary extends Arbitrary {
constructor(arb) {
super();
this.arb = arb;
}
generate(mrng, _biasFactor) {
return this.arb.generate(mrng, undefined);
}
canShrinkWithoutContext(value) {
return this.arb.canShrinkWithoutContext(value);
}
shrink(value, context) {
return this.arb.shrink(value, context);
}
noBias() {
return this;
}
}
function isArbitrary(instance) {
return (typeof instance === 'object' &&
instance !== null &&
'generate' in instance &&
'shrink' in instance &&
'canShrinkWithoutContext' in instance);
}
function assertIsArbitrary(instance) {
if (!isArbitrary(instance)) {
throw new Error('Unexpected value received: not an instance of Arbitrary');
}
}

View File

@@ -0,0 +1,30 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Value = void 0;
const symbols_1 = require("../../symbols");
const safeObjectDefineProperty = Object.defineProperty;
class Value {
constructor(value_, context, customGetValue = undefined) {
this.value_ = value_;
this.context = context;
this.hasToBeCloned = customGetValue !== undefined || (0, symbols_1.hasCloneMethod)(value_);
this.readOnce = false;
if (this.hasToBeCloned) {
safeObjectDefineProperty(this, 'value', { get: customGetValue !== undefined ? customGetValue : this.getValue });
}
else {
this.value = value_;
}
}
getValue() {
if (this.hasToBeCloned) {
if (!this.readOnce) {
this.readOnce = true;
return this.value_;
}
return this.value_[symbols_1.cloneMethod]();
}
return this.value_;
}
}
exports.Value = Value;

View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.modelRun = modelRun;
exports.asyncModelRun = asyncModelRun;
exports.scheduledModelRun = scheduledModelRun;
const ScheduledCommand_1 = require("./commands/ScheduledCommand");
const genericModelRun = (s, cmds, initialValue, runCmd, then) => {
return s.then((o) => {
const { model, real } = o;
let state = initialValue;
for (const c of cmds) {
state = then(state, () => {
return runCmd(c, model, real);
});
}
return state;
});
};
const internalModelRun = (s, cmds) => {
const then = (_p, c) => c();
const setupProducer = {
then: (fun) => {
fun(s());
return undefined;
},
};
const runSync = (cmd, m, r) => {
if (cmd.check(m))
cmd.run(m, r);
return undefined;
};
return genericModelRun(setupProducer, cmds, undefined, runSync, then);
};
const isAsyncSetup = (s) => {
return typeof s.then === 'function';
};
const internalAsyncModelRun = async (s, cmds, defaultPromise = Promise.resolve()) => {
const then = (p, c) => p.then(c);
const setupProducer = {
then: (fun) => {
const out = s();
if (isAsyncSetup(out))
return out.then(fun);
else
return fun(out);
},
};
const runAsync = async (cmd, m, r) => {
if (await cmd.check(m))
await cmd.run(m, r);
};
return await genericModelRun(setupProducer, cmds, defaultPromise, runAsync, then);
};
function modelRun(s, cmds) {
internalModelRun(s, cmds);
}
async function asyncModelRun(s, cmds) {
await internalAsyncModelRun(s, cmds);
}
async function scheduledModelRun(scheduler, s, cmds) {
const scheduledCommands = (0, ScheduledCommand_1.scheduleCommands)(scheduler, cmds);
const out = internalAsyncModelRun(s, scheduledCommands, scheduler.schedule(Promise.resolve(), 'startModel'));
await scheduler.waitFor(out);
await scheduler.waitAll();
}

View File

@@ -0,0 +1,82 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReplayPath = void 0;
class ReplayPath {
static parse(replayPathStr) {
const [serializedCount, serializedChanges] = replayPathStr.split(':');
const counts = this.parseCounts(serializedCount);
const changes = this.parseChanges(serializedChanges);
return this.parseOccurences(counts, changes);
}
static stringify(replayPath) {
const occurences = this.countOccurences(replayPath);
const serializedCount = this.stringifyCounts(occurences);
const serializedChanges = this.stringifyChanges(occurences);
return `${serializedCount}:${serializedChanges}`;
}
static intToB64(n) {
if (n < 26)
return String.fromCharCode(n + 65);
if (n < 52)
return String.fromCharCode(n + 97 - 26);
if (n < 62)
return String.fromCharCode(n + 48 - 52);
return String.fromCharCode(n === 62 ? 43 : 47);
}
static b64ToInt(c) {
if (c >= 'a')
return c.charCodeAt(0) - 97 + 26;
if (c >= 'A')
return c.charCodeAt(0) - 65;
if (c >= '0')
return c.charCodeAt(0) - 48 + 52;
return c === '+' ? 62 : 63;
}
static countOccurences(replayPath) {
return replayPath.reduce((counts, cur) => {
if (counts.length === 0 || counts[counts.length - 1].count === 64 || counts[counts.length - 1].value !== cur)
counts.push({ value: cur, count: 1 });
else
counts[counts.length - 1].count += 1;
return counts;
}, []);
}
static parseOccurences(counts, changes) {
const replayPath = [];
for (let idx = 0; idx !== counts.length; ++idx) {
const count = counts[idx];
const value = changes[idx];
for (let num = 0; num !== count; ++num)
replayPath.push(value);
}
return replayPath;
}
static stringifyChanges(occurences) {
let serializedChanges = '';
for (let idx = 0; idx < occurences.length; idx += 6) {
const changesInt = occurences
.slice(idx, idx + 6)
.reduceRight((prev, cur) => prev * 2 + (cur.value ? 1 : 0), 0);
serializedChanges += this.intToB64(changesInt);
}
return serializedChanges;
}
static parseChanges(serializedChanges) {
const changesInt = serializedChanges.split('').map((c) => this.b64ToInt(c));
const changes = [];
for (let idx = 0; idx !== changesInt.length; ++idx) {
let current = changesInt[idx];
for (let n = 0; n !== 6; ++n, current >>= 1) {
changes.push(current % 2 === 1);
}
}
return changes;
}
static stringifyCounts(occurences) {
return occurences.map(({ count }) => this.intToB64(count - 1)).join('');
}
static parseCounts(serializedCount) {
return serializedCount.split('').map((c) => this.b64ToInt(c) + 1);
}
}
exports.ReplayPath = ReplayPath;

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommandWrapper = void 0;
const stringify_1 = require("../../../utils/stringify");
const symbols_1 = require("../../symbols");
class CommandWrapper {
constructor(cmd) {
this.cmd = cmd;
this.hasRan = false;
if ((0, stringify_1.hasToStringMethod)(cmd)) {
const method = cmd[stringify_1.toStringMethod];
this[stringify_1.toStringMethod] = function toStringMethod() {
return method.call(cmd);
};
}
if ((0, stringify_1.hasAsyncToStringMethod)(cmd)) {
const method = cmd[stringify_1.asyncToStringMethod];
this[stringify_1.asyncToStringMethod] = function asyncToStringMethod() {
return method.call(cmd);
};
}
}
check(m) {
return this.cmd.check(m);
}
run(m, r) {
this.hasRan = true;
return this.cmd.run(m, r);
}
clone() {
if ((0, symbols_1.hasCloneMethod)(this.cmd))
return new CommandWrapper(this.cmd[symbols_1.cloneMethod]());
return new CommandWrapper(this.cmd);
}
toString() {
return this.cmd.toString();
}
}
exports.CommandWrapper = CommandWrapper;

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommandsIterable = void 0;
const symbols_1 = require("../../symbols");
class CommandsIterable {
constructor(commands, metadataForReplay) {
this.commands = commands;
this.metadataForReplay = metadataForReplay;
}
[Symbol.iterator]() {
return this.commands[Symbol.iterator]();
}
[symbols_1.cloneMethod]() {
return new CommandsIterable(this.commands.map((c) => c.clone()), this.metadataForReplay);
}
toString() {
const serializedCommands = this.commands
.filter((c) => c.hasRan)
.map((c) => c.toString())
.join(',');
const metadata = this.metadataForReplay();
return metadata.length !== 0 ? `${serializedCommands} /*${metadata}*/` : serializedCommands;
}
}
exports.CommandsIterable = CommandsIterable;

View File

@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.scheduleCommands = exports.ScheduledCommand = void 0;
class ScheduledCommand {
constructor(s, cmd) {
this.s = s;
this.cmd = cmd;
}
async check(m) {
let error = null;
let checkPassed = false;
const status = await this.s.scheduleSequence([
{
label: `check@${this.cmd.toString()}`,
builder: async () => {
try {
checkPassed = await Promise.resolve(this.cmd.check(m));
}
catch (err) {
error = err;
throw err;
}
},
},
]).task;
if (status.faulty) {
throw error;
}
return checkPassed;
}
async run(m, r) {
let error = null;
const status = await this.s.scheduleSequence([
{
label: `run@${this.cmd.toString()}`,
builder: async () => {
try {
await this.cmd.run(m, r);
}
catch (err) {
error = err;
throw err;
}
},
},
]).task;
if (status.faulty) {
throw error;
}
}
}
exports.ScheduledCommand = ScheduledCommand;
const scheduleCommands = function* (s, cmds) {
for (const cmd of cmds) {
yield new ScheduledCommand(s, cmd);
}
};
exports.scheduleCommands = scheduleCommands;

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pre = pre;
const PreconditionFailure_1 = require("./PreconditionFailure");
function pre(expectTruthy) {
if (!expectTruthy) {
throw new PreconditionFailure_1.PreconditionFailure();
}
}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PreconditionFailure = void 0;
class PreconditionFailure extends Error {
constructor(interruptExecution = false) {
super();
this.interruptExecution = interruptExecution;
this.footprint = PreconditionFailure.SharedFootPrint;
}
static isFailure(err) {
return err != null && err.footprint === PreconditionFailure.SharedFootPrint;
}
}
exports.PreconditionFailure = PreconditionFailure;
PreconditionFailure.SharedFootPrint = Symbol.for('fast-check/PreconditionFailure');

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncProperty = void 0;
const PreconditionFailure_1 = require("../precondition/PreconditionFailure");
const IRawProperty_1 = require("./IRawProperty");
const GlobalParameters_1 = require("../runner/configuration/GlobalParameters");
const Stream_1 = require("../../stream/Stream");
const NoUndefinedAsContext_1 = require("../../arbitrary/_internals/helpers/NoUndefinedAsContext");
const globals_1 = require("../../utils/globals");
class AsyncProperty {
constructor(arb, predicate) {
this.arb = arb;
this.predicate = predicate;
const { asyncBeforeEach, asyncAfterEach, beforeEach, afterEach } = (0, GlobalParameters_1.readConfigureGlobal)() || {};
if (asyncBeforeEach !== undefined && beforeEach !== undefined) {
throw (0, globals_1.Error)('Global "asyncBeforeEach" and "beforeEach" parameters can\'t be set at the same time when running async properties');
}
if (asyncAfterEach !== undefined && afterEach !== undefined) {
throw (0, globals_1.Error)('Global "asyncAfterEach" and "afterEach" parameters can\'t be set at the same time when running async properties');
}
this.beforeEachHook = asyncBeforeEach || beforeEach || AsyncProperty.dummyHook;
this.afterEachHook = asyncAfterEach || afterEach || AsyncProperty.dummyHook;
}
isAsync() {
return true;
}
generate(mrng, runId) {
const value = this.arb.generate(mrng, runId != null ? (0, IRawProperty_1.runIdToFrequency)(runId) : undefined);
return (0, NoUndefinedAsContext_1.noUndefinedAsContext)(value);
}
shrink(value) {
if (value.context === undefined && !this.arb.canShrinkWithoutContext(value.value_)) {
return Stream_1.Stream.nil();
}
const safeContext = value.context !== NoUndefinedAsContext_1.UndefinedContextPlaceholder ? value.context : undefined;
return this.arb.shrink(value.value_, safeContext).map(NoUndefinedAsContext_1.noUndefinedAsContext);
}
async runBeforeEach() {
await this.beforeEachHook();
}
async runAfterEach() {
await this.afterEachHook();
}
async run(v, dontRunHook) {
if (!dontRunHook) {
await this.beforeEachHook();
}
try {
const output = await this.predicate(v);
return output == null || output === true
? null
: {
error: new globals_1.Error('Property failed by returning false'),
errorMessage: 'Error: Property failed by returning false',
};
}
catch (err) {
if (PreconditionFailure_1.PreconditionFailure.isFailure(err))
return err;
if (err instanceof globals_1.Error && err.stack) {
return { error: err, errorMessage: err.stack };
}
return { error: err, errorMessage: (0, globals_1.String)(err) };
}
finally {
if (!dontRunHook) {
await this.afterEachHook();
}
}
}
beforeEach(hookFunction) {
const previousBeforeEachHook = this.beforeEachHook;
this.beforeEachHook = () => hookFunction(previousBeforeEachHook);
return this;
}
afterEach(hookFunction) {
const previousAfterEachHook = this.afterEachHook;
this.afterEachHook = () => hookFunction(previousAfterEachHook);
return this;
}
}
exports.AsyncProperty = AsyncProperty;
AsyncProperty.dummyHook = () => { };

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.asyncProperty = asyncProperty;
const Arbitrary_1 = require("../arbitrary/definition/Arbitrary");
const tuple_1 = require("../../arbitrary/tuple");
const AsyncProperty_generic_1 = require("./AsyncProperty.generic");
const AlwaysShrinkableArbitrary_1 = require("../../arbitrary/_internals/AlwaysShrinkableArbitrary");
const globals_1 = require("../../utils/globals");
function asyncProperty(...args) {
if (args.length < 2) {
throw new Error('asyncProperty expects at least two parameters');
}
const arbs = (0, globals_1.safeSlice)(args, 0, args.length - 1);
const p = args[args.length - 1];
(0, globals_1.safeForEach)(arbs, Arbitrary_1.assertIsArbitrary);
const mappedArbs = (0, globals_1.safeMap)(arbs, (arb) => new AlwaysShrinkableArbitrary_1.AlwaysShrinkableArbitrary(arb));
return new AsyncProperty_generic_1.AsyncProperty((0, tuple_1.tuple)(...mappedArbs), (t) => p(...t));
}

View File

@@ -0,0 +1,7 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runIdToFrequency = runIdToFrequency;
const safeMathLog = Math.log;
function runIdToFrequency(runId) {
return 2 + ~~(safeMathLog(runId + 1) * 0.4342944819032518);
}

View File

@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.IgnoreEqualValuesProperty = void 0;
const stringify_1 = require("../../utils/stringify");
const PreconditionFailure_1 = require("../precondition/PreconditionFailure");
function fromSyncCached(cachedValue) {
return cachedValue === null ? new PreconditionFailure_1.PreconditionFailure() : cachedValue;
}
function fromCached(...data) {
if (data[1])
return data[0].then(fromSyncCached);
return fromSyncCached(data[0]);
}
function fromCachedUnsafe(cachedValue, isAsync) {
return fromCached(cachedValue, isAsync);
}
class IgnoreEqualValuesProperty {
constructor(property, skipRuns) {
this.property = property;
this.skipRuns = skipRuns;
this.coveredCases = new Map();
if (this.property.runBeforeEach !== undefined && this.property.runAfterEach !== undefined) {
this.runBeforeEach = () => this.property.runBeforeEach();
this.runAfterEach = () => this.property.runAfterEach();
}
}
isAsync() {
return this.property.isAsync();
}
generate(mrng, runId) {
return this.property.generate(mrng, runId);
}
shrink(value) {
return this.property.shrink(value);
}
run(v, dontRunHook) {
const stringifiedValue = (0, stringify_1.stringify)(v);
if (this.coveredCases.has(stringifiedValue)) {
const lastOutput = this.coveredCases.get(stringifiedValue);
if (!this.skipRuns) {
return lastOutput;
}
return fromCachedUnsafe(lastOutput, this.property.isAsync());
}
const out = this.property.run(v, dontRunHook);
this.coveredCases.set(stringifiedValue, out);
return out;
}
}
exports.IgnoreEqualValuesProperty = IgnoreEqualValuesProperty;

View File

@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Property = void 0;
const PreconditionFailure_1 = require("../precondition/PreconditionFailure");
const IRawProperty_1 = require("./IRawProperty");
const GlobalParameters_1 = require("../runner/configuration/GlobalParameters");
const Stream_1 = require("../../stream/Stream");
const NoUndefinedAsContext_1 = require("../../arbitrary/_internals/helpers/NoUndefinedAsContext");
const globals_1 = require("../../utils/globals");
class Property {
constructor(arb, predicate) {
this.arb = arb;
this.predicate = predicate;
const { beforeEach = Property.dummyHook, afterEach = Property.dummyHook, asyncBeforeEach, asyncAfterEach, } = (0, GlobalParameters_1.readConfigureGlobal)() || {};
if (asyncBeforeEach !== undefined) {
throw (0, globals_1.Error)('"asyncBeforeEach" can\'t be set when running synchronous properties');
}
if (asyncAfterEach !== undefined) {
throw (0, globals_1.Error)('"asyncAfterEach" can\'t be set when running synchronous properties');
}
this.beforeEachHook = beforeEach;
this.afterEachHook = afterEach;
}
isAsync() {
return false;
}
generate(mrng, runId) {
const value = this.arb.generate(mrng, runId != null ? (0, IRawProperty_1.runIdToFrequency)(runId) : undefined);
return (0, NoUndefinedAsContext_1.noUndefinedAsContext)(value);
}
shrink(value) {
if (value.context === undefined && !this.arb.canShrinkWithoutContext(value.value_)) {
return Stream_1.Stream.nil();
}
const safeContext = value.context !== NoUndefinedAsContext_1.UndefinedContextPlaceholder ? value.context : undefined;
return this.arb.shrink(value.value_, safeContext).map(NoUndefinedAsContext_1.noUndefinedAsContext);
}
runBeforeEach() {
this.beforeEachHook();
}
runAfterEach() {
this.afterEachHook();
}
run(v, dontRunHook) {
if (!dontRunHook) {
this.beforeEachHook();
}
try {
const output = this.predicate(v);
return output == null || output === true
? null
: {
error: new globals_1.Error('Property failed by returning false'),
errorMessage: 'Error: Property failed by returning false',
};
}
catch (err) {
if (PreconditionFailure_1.PreconditionFailure.isFailure(err))
return err;
if (err instanceof globals_1.Error && err.stack) {
return { error: err, errorMessage: err.stack };
}
return { error: err, errorMessage: (0, globals_1.String)(err) };
}
finally {
if (!dontRunHook) {
this.afterEachHook();
}
}
}
beforeEach(hookFunction) {
const previousBeforeEachHook = this.beforeEachHook;
this.beforeEachHook = () => hookFunction(previousBeforeEachHook);
return this;
}
afterEach(hookFunction) {
const previousAfterEachHook = this.afterEachHook;
this.afterEachHook = () => hookFunction(previousAfterEachHook);
return this;
}
}
exports.Property = Property;
Property.dummyHook = () => { };

View File

@@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.property = property;
const Arbitrary_1 = require("../arbitrary/definition/Arbitrary");
const tuple_1 = require("../../arbitrary/tuple");
const Property_generic_1 = require("./Property.generic");
const AlwaysShrinkableArbitrary_1 = require("../../arbitrary/_internals/AlwaysShrinkableArbitrary");
const globals_1 = require("../../utils/globals");
function property(...args) {
if (args.length < 2) {
throw new Error('property expects at least two parameters');
}
const arbs = (0, globals_1.safeSlice)(args, 0, args.length - 1);
const p = args[args.length - 1];
(0, globals_1.safeForEach)(arbs, Arbitrary_1.assertIsArbitrary);
const mappedArbs = (0, globals_1.safeMap)(arbs, (arb) => new AlwaysShrinkableArbitrary_1.AlwaysShrinkableArbitrary(arb));
return new Property_generic_1.Property((0, tuple_1.tuple)(...mappedArbs), (t) => p(...t));
}

View File

@@ -0,0 +1,60 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SkipAfterProperty = void 0;
const PreconditionFailure_1 = require("../precondition/PreconditionFailure");
function interruptAfter(timeMs, setTimeoutSafe, clearTimeoutSafe) {
let timeoutHandle = null;
const promise = new Promise((resolve) => {
timeoutHandle = setTimeoutSafe(() => {
const preconditionFailure = new PreconditionFailure_1.PreconditionFailure(true);
resolve(preconditionFailure);
}, timeMs);
});
return {
clear: () => clearTimeoutSafe(timeoutHandle),
promise,
};
}
class SkipAfterProperty {
constructor(property, getTime, timeLimit, interruptExecution, setTimeoutSafe, clearTimeoutSafe) {
this.property = property;
this.getTime = getTime;
this.interruptExecution = interruptExecution;
this.setTimeoutSafe = setTimeoutSafe;
this.clearTimeoutSafe = clearTimeoutSafe;
this.skipAfterTime = this.getTime() + timeLimit;
if (this.property.runBeforeEach !== undefined && this.property.runAfterEach !== undefined) {
this.runBeforeEach = () => this.property.runBeforeEach();
this.runAfterEach = () => this.property.runAfterEach();
}
}
isAsync() {
return this.property.isAsync();
}
generate(mrng, runId) {
return this.property.generate(mrng, runId);
}
shrink(value) {
return this.property.shrink(value);
}
run(v, dontRunHook) {
const remainingTime = this.skipAfterTime - this.getTime();
if (remainingTime <= 0) {
const preconditionFailure = new PreconditionFailure_1.PreconditionFailure(this.interruptExecution);
if (this.isAsync()) {
return Promise.resolve(preconditionFailure);
}
else {
return preconditionFailure;
}
}
if (this.interruptExecution && this.isAsync()) {
const t = interruptAfter(remainingTime, this.setTimeoutSafe, this.clearTimeoutSafe);
const propRun = Promise.race([this.property.run(v, dontRunHook), t.promise]);
propRun.then(t.clear, t.clear);
return propRun;
}
return this.property.run(v, dontRunHook);
}
}
exports.SkipAfterProperty = SkipAfterProperty;

View File

@@ -0,0 +1,47 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimeoutProperty = void 0;
const globals_1 = require("../../utils/globals");
const timeoutAfter = (timeMs, setTimeoutSafe, clearTimeoutSafe) => {
let timeoutHandle = null;
const promise = new Promise((resolve) => {
timeoutHandle = setTimeoutSafe(() => {
resolve({
error: new globals_1.Error(`Property timeout: exceeded limit of ${timeMs} milliseconds`),
errorMessage: `Property timeout: exceeded limit of ${timeMs} milliseconds`,
});
}, timeMs);
});
return {
clear: () => clearTimeoutSafe(timeoutHandle),
promise,
};
};
class TimeoutProperty {
constructor(property, timeMs, setTimeoutSafe, clearTimeoutSafe) {
this.property = property;
this.timeMs = timeMs;
this.setTimeoutSafe = setTimeoutSafe;
this.clearTimeoutSafe = clearTimeoutSafe;
if (this.property.runBeforeEach !== undefined && this.property.runAfterEach !== undefined) {
this.runBeforeEach = () => Promise.resolve(this.property.runBeforeEach());
this.runAfterEach = () => Promise.resolve(this.property.runAfterEach());
}
}
isAsync() {
return true;
}
generate(mrng, runId) {
return this.property.generate(mrng, runId);
}
shrink(value) {
return this.property.shrink(value);
}
async run(v, dontRunHook) {
const t = timeoutAfter(this.timeMs, this.setTimeoutSafe, this.clearTimeoutSafe);
const propRun = Promise.race([this.property.run(v, dontRunHook), t.promise]);
propRun.then(t.clear, t.clear);
return propRun;
}
}
exports.TimeoutProperty = TimeoutProperty;

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UnbiasedProperty = void 0;
class UnbiasedProperty {
constructor(property) {
this.property = property;
if (this.property.runBeforeEach !== undefined && this.property.runAfterEach !== undefined) {
this.runBeforeEach = () => this.property.runBeforeEach();
this.runAfterEach = () => this.property.runAfterEach();
}
}
isAsync() {
return this.property.isAsync();
}
generate(mrng, _runId) {
return this.property.generate(mrng, undefined);
}
shrink(value) {
return this.property.shrink(value);
}
run(v, dontRunHook) {
return this.property.run(v, dontRunHook);
}
}
exports.UnbiasedProperty = UnbiasedProperty;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.decorateProperty = decorateProperty;
const SkipAfterProperty_1 = require("../property/SkipAfterProperty");
const TimeoutProperty_1 = require("../property/TimeoutProperty");
const UnbiasedProperty_1 = require("../property/UnbiasedProperty");
const IgnoreEqualValuesProperty_1 = require("../property/IgnoreEqualValuesProperty");
const safeDateNow = Date.now;
const safeSetTimeout = setTimeout;
const safeClearTimeout = clearTimeout;
function decorateProperty(rawProperty, qParams) {
let prop = rawProperty;
if (rawProperty.isAsync() && qParams.timeout != null) {
prop = new TimeoutProperty_1.TimeoutProperty(prop, qParams.timeout, safeSetTimeout, safeClearTimeout);
}
if (qParams.unbiased) {
prop = new UnbiasedProperty_1.UnbiasedProperty(prop);
}
if (qParams.skipAllAfterTimeLimit != null) {
prop = new SkipAfterProperty_1.SkipAfterProperty(prop, safeDateNow, qParams.skipAllAfterTimeLimit, false, safeSetTimeout, safeClearTimeout);
}
if (qParams.interruptAfterTimeLimit != null) {
prop = new SkipAfterProperty_1.SkipAfterProperty(prop, safeDateNow, qParams.interruptAfterTimeLimit, true, safeSetTimeout, safeClearTimeout);
}
if (qParams.skipEqualValues) {
prop = new IgnoreEqualValuesProperty_1.IgnoreEqualValuesProperty(prop, true);
}
if (qParams.ignoreEqualValues) {
prop = new IgnoreEqualValuesProperty_1.IgnoreEqualValuesProperty(prop, false);
}
return prop;
}

View File

@@ -0,0 +1,74 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.check = check;
exports.assert = assert;
const Stream_1 = require("../../stream/Stream");
const GlobalParameters_1 = require("./configuration/GlobalParameters");
const QualifiedParameters_1 = require("./configuration/QualifiedParameters");
const DecorateProperty_1 = require("./DecorateProperty");
const RunnerIterator_1 = require("./RunnerIterator");
const SourceValuesIterator_1 = require("./SourceValuesIterator");
const Tosser_1 = require("./Tosser");
const PathWalker_1 = require("./utils/PathWalker");
const RunDetailsFormatter_1 = require("./utils/RunDetailsFormatter");
const safeObjectAssign = Object.assign;
function runIt(property, shrink, sourceValues, verbose, interruptedAsFailure) {
const isModernProperty = property.runBeforeEach !== undefined && property.runAfterEach !== undefined;
const runner = new RunnerIterator_1.RunnerIterator(sourceValues, shrink, verbose, interruptedAsFailure);
for (const v of runner) {
if (isModernProperty) {
property.runBeforeEach();
}
const out = property.run(v, isModernProperty);
if (isModernProperty) {
property.runAfterEach();
}
runner.handleResult(out);
}
return runner.runExecution;
}
async function asyncRunIt(property, shrink, sourceValues, verbose, interruptedAsFailure) {
const isModernProperty = property.runBeforeEach !== undefined && property.runAfterEach !== undefined;
const runner = new RunnerIterator_1.RunnerIterator(sourceValues, shrink, verbose, interruptedAsFailure);
for (const v of runner) {
if (isModernProperty) {
await property.runBeforeEach();
}
const out = await property.run(v, isModernProperty);
if (isModernProperty) {
await property.runAfterEach();
}
runner.handleResult(out);
}
return runner.runExecution;
}
function check(rawProperty, params) {
if (rawProperty == null || rawProperty.generate == null)
throw new Error('Invalid property encountered, please use a valid property');
if (rawProperty.run == null)
throw new Error('Invalid property encountered, please use a valid property not an arbitrary');
const qParams = QualifiedParameters_1.QualifiedParameters.read(safeObjectAssign(safeObjectAssign({}, (0, GlobalParameters_1.readConfigureGlobal)()), params));
if (qParams.reporter !== null && qParams.asyncReporter !== null)
throw new Error('Invalid parameters encountered, reporter and asyncReporter cannot be specified together');
if (qParams.asyncReporter !== null && !rawProperty.isAsync())
throw new Error('Invalid parameters encountered, only asyncProperty can be used when asyncReporter specified');
const property = (0, DecorateProperty_1.decorateProperty)(rawProperty, qParams);
const maxInitialIterations = qParams.path.length === 0 || qParams.path.indexOf(':') === -1 ? qParams.numRuns : -1;
const maxSkips = qParams.numRuns * qParams.maxSkipsPerRun;
const shrink = (...args) => property.shrink(...args);
const initialValues = qParams.path.length === 0
? (0, Tosser_1.toss)(property, qParams.seed, qParams.randomType, qParams.examples)
: (0, PathWalker_1.pathWalk)(qParams.path, (0, Stream_1.stream)((0, Tosser_1.lazyToss)(property, qParams.seed, qParams.randomType, qParams.examples)), shrink);
const sourceValues = new SourceValuesIterator_1.SourceValuesIterator(initialValues, maxInitialIterations, maxSkips);
const finalShrink = !qParams.endOnFailure ? shrink : Stream_1.Stream.nil;
return property.isAsync()
? asyncRunIt(property, finalShrink, sourceValues, qParams.verbose, qParams.markInterruptAsFailure).then((e) => e.toRunDetails(qParams.seed, qParams.path, maxSkips, qParams))
: runIt(property, finalShrink, sourceValues, qParams.verbose, qParams.markInterruptAsFailure).toRunDetails(qParams.seed, qParams.path, maxSkips, qParams);
}
function assert(property, params) {
const out = check(property, params);
if (property.isAsync())
return out.then(RunDetailsFormatter_1.asyncReportRunDetails);
else
(0, RunDetailsFormatter_1.reportRunDetails)(out);
}

View File

@@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RunnerIterator = void 0;
const PreconditionFailure_1 = require("../precondition/PreconditionFailure");
const RunExecution_1 = require("./reporter/RunExecution");
class RunnerIterator {
constructor(sourceValues, shrink, verbose, interruptedAsFailure) {
this.sourceValues = sourceValues;
this.shrink = shrink;
this.runExecution = new RunExecution_1.RunExecution(verbose, interruptedAsFailure);
this.currentIdx = -1;
this.nextValues = sourceValues;
}
[Symbol.iterator]() {
return this;
}
next() {
const nextValue = this.nextValues.next();
if (nextValue.done || this.runExecution.interrupted) {
return { done: true, value: undefined };
}
this.currentValue = nextValue.value;
++this.currentIdx;
return { done: false, value: nextValue.value.value_ };
}
handleResult(result) {
if (result != null && typeof result === 'object' && !PreconditionFailure_1.PreconditionFailure.isFailure(result)) {
this.runExecution.fail(this.currentValue.value_, this.currentIdx, result);
this.currentIdx = -1;
this.nextValues = this.shrink(this.currentValue);
}
else if (result != null) {
if (!result.interruptExecution) {
this.runExecution.skip(this.currentValue.value_);
this.sourceValues.skippedOne();
}
else {
this.runExecution.interrupt();
}
}
else {
this.runExecution.success(this.currentValue.value_);
}
}
}
exports.RunnerIterator = RunnerIterator;

View File

@@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sample = sample;
exports.statistics = statistics;
const Stream_1 = require("../../stream/Stream");
const Property_generic_1 = require("../property/Property.generic");
const UnbiasedProperty_1 = require("../property/UnbiasedProperty");
const GlobalParameters_1 = require("./configuration/GlobalParameters");
const QualifiedParameters_1 = require("./configuration/QualifiedParameters");
const Tosser_1 = require("./Tosser");
const PathWalker_1 = require("./utils/PathWalker");
function toProperty(generator, qParams) {
const prop = !Object.prototype.hasOwnProperty.call(generator, 'isAsync')
? new Property_generic_1.Property(generator, () => true)
: generator;
return qParams.unbiased === true ? new UnbiasedProperty_1.UnbiasedProperty(prop) : prop;
}
function streamSample(generator, params) {
const extendedParams = typeof params === 'number'
? Object.assign(Object.assign({}, (0, GlobalParameters_1.readConfigureGlobal)()), { numRuns: params }) : Object.assign(Object.assign({}, (0, GlobalParameters_1.readConfigureGlobal)()), params);
const qParams = QualifiedParameters_1.QualifiedParameters.read(extendedParams);
const nextProperty = toProperty(generator, qParams);
const shrink = nextProperty.shrink.bind(nextProperty);
const tossedValues = qParams.path.length === 0
? (0, Stream_1.stream)((0, Tosser_1.toss)(nextProperty, qParams.seed, qParams.randomType, qParams.examples))
: (0, PathWalker_1.pathWalk)(qParams.path, (0, Stream_1.stream)((0, Tosser_1.lazyToss)(nextProperty, qParams.seed, qParams.randomType, qParams.examples)), shrink);
return tossedValues.take(qParams.numRuns).map((s) => s.value_);
}
function sample(generator, params) {
return [...streamSample(generator, params)];
}
function round2(n) {
return (Math.round(n * 100) / 100).toFixed(2);
}
function statistics(generator, classify, params) {
const extendedParams = typeof params === 'number'
? Object.assign(Object.assign({}, (0, GlobalParameters_1.readConfigureGlobal)()), { numRuns: params }) : Object.assign(Object.assign({}, (0, GlobalParameters_1.readConfigureGlobal)()), params);
const qParams = QualifiedParameters_1.QualifiedParameters.read(extendedParams);
const recorded = {};
for (const g of streamSample(generator, params)) {
const out = classify(g);
const categories = Array.isArray(out) ? out : [out];
for (const c of categories) {
recorded[c] = (recorded[c] || 0) + 1;
}
}
const data = Object.entries(recorded)
.sort((a, b) => b[1] - a[1])
.map((i) => [i[0], `${round2((i[1] * 100.0) / qParams.numRuns)}%`]);
const longestName = data.map((i) => i[0].length).reduce((p, c) => Math.max(p, c), 0);
const longestPercent = data.map((i) => i[1].length).reduce((p, c) => Math.max(p, c), 0);
for (const item of data) {
qParams.logger(`${item[0].padEnd(longestName, '.')}..${item[1].padStart(longestPercent, '.')}`);
}
}

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SourceValuesIterator = void 0;
class SourceValuesIterator {
constructor(initialValues, maxInitialIterations, remainingSkips) {
this.initialValues = initialValues;
this.maxInitialIterations = maxInitialIterations;
this.remainingSkips = remainingSkips;
}
[Symbol.iterator]() {
return this;
}
next() {
if (--this.maxInitialIterations !== -1 && this.remainingSkips >= 0) {
const n = this.initialValues.next();
if (!n.done)
return { value: n.value, done: false };
}
return { value: undefined, done: true };
}
skippedOne() {
--this.remainingSkips;
++this.maxInitialIterations;
}
}
exports.SourceValuesIterator = SourceValuesIterator;

View File

@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.toss = toss;
exports.lazyToss = lazyToss;
const pure_rand_1 = require("pure-rand");
const Random_1 = require("../../random/generator/Random");
const Value_1 = require("../arbitrary/definition/Value");
const globals_1 = require("../../utils/globals");
function tossNext(generator, rng, index) {
rng.unsafeJump();
return generator.generate(new Random_1.Random(rng), index);
}
function* toss(generator, seed, random, examples) {
for (let idx = 0; idx !== examples.length; ++idx) {
yield new Value_1.Value(examples[idx], undefined);
}
for (let idx = 0, rng = random(seed);; ++idx) {
yield tossNext(generator, rng, idx);
}
}
function lazyGenerate(generator, rng, idx) {
return () => generator.generate(new Random_1.Random(rng), idx);
}
function* lazyToss(generator, seed, random, examples) {
yield* (0, globals_1.safeMap)(examples, (e) => () => new Value_1.Value(e, undefined));
let idx = 0;
let rng = random(seed);
for (;;) {
rng = rng.jump ? rng.jump() : (0, pure_rand_1.skipN)(rng, 42);
yield lazyGenerate(generator, rng, idx++);
}
}

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.configureGlobal = configureGlobal;
exports.readConfigureGlobal = readConfigureGlobal;
exports.resetConfigureGlobal = resetConfigureGlobal;
let globalParameters = {};
function configureGlobal(parameters) {
globalParameters = parameters;
}
function readConfigureGlobal() {
return globalParameters;
}
function resetConfigureGlobal() {
globalParameters = {};
}

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,144 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QualifiedParameters = void 0;
const pure_rand_1 = require("pure-rand");
const VerbosityLevel_1 = require("./VerbosityLevel");
const safeDateNow = Date.now;
const safeMathMin = Math.min;
const safeMathRandom = Math.random;
class QualifiedParameters {
constructor(op) {
const p = op || {};
this.seed = QualifiedParameters.readSeed(p);
this.randomType = QualifiedParameters.readRandomType(p);
this.numRuns = QualifiedParameters.readNumRuns(p);
this.verbose = QualifiedParameters.readVerbose(p);
this.maxSkipsPerRun = QualifiedParameters.readOrDefault(p, 'maxSkipsPerRun', 100);
this.timeout = QualifiedParameters.safeTimeout(QualifiedParameters.readOrDefault(p, 'timeout', null));
this.skipAllAfterTimeLimit = QualifiedParameters.safeTimeout(QualifiedParameters.readOrDefault(p, 'skipAllAfterTimeLimit', null));
this.interruptAfterTimeLimit = QualifiedParameters.safeTimeout(QualifiedParameters.readOrDefault(p, 'interruptAfterTimeLimit', null));
this.markInterruptAsFailure = QualifiedParameters.readBoolean(p, 'markInterruptAsFailure');
this.skipEqualValues = QualifiedParameters.readBoolean(p, 'skipEqualValues');
this.ignoreEqualValues = QualifiedParameters.readBoolean(p, 'ignoreEqualValues');
this.logger = QualifiedParameters.readOrDefault(p, 'logger', (v) => {
console.log(v);
});
this.path = QualifiedParameters.readOrDefault(p, 'path', '');
this.unbiased = QualifiedParameters.readBoolean(p, 'unbiased');
this.examples = QualifiedParameters.readOrDefault(p, 'examples', []);
this.endOnFailure = QualifiedParameters.readBoolean(p, 'endOnFailure');
this.reporter = QualifiedParameters.readOrDefault(p, 'reporter', null);
this.asyncReporter = QualifiedParameters.readOrDefault(p, 'asyncReporter', null);
this.errorWithCause = QualifiedParameters.readBoolean(p, 'errorWithCause');
}
toParameters() {
const orUndefined = (value) => (value !== null ? value : undefined);
const parameters = {
seed: this.seed,
randomType: this.randomType,
numRuns: this.numRuns,
maxSkipsPerRun: this.maxSkipsPerRun,
timeout: orUndefined(this.timeout),
skipAllAfterTimeLimit: orUndefined(this.skipAllAfterTimeLimit),
interruptAfterTimeLimit: orUndefined(this.interruptAfterTimeLimit),
markInterruptAsFailure: this.markInterruptAsFailure,
skipEqualValues: this.skipEqualValues,
ignoreEqualValues: this.ignoreEqualValues,
path: this.path,
logger: this.logger,
unbiased: this.unbiased,
verbose: this.verbose,
examples: this.examples,
endOnFailure: this.endOnFailure,
reporter: orUndefined(this.reporter),
asyncReporter: orUndefined(this.asyncReporter),
errorWithCause: this.errorWithCause,
};
return parameters;
}
static read(op) {
return new QualifiedParameters(op);
}
}
exports.QualifiedParameters = QualifiedParameters;
QualifiedParameters.createQualifiedRandomGenerator = (random) => {
return (seed) => {
const rng = random(seed);
if (rng.unsafeJump === undefined) {
rng.unsafeJump = () => (0, pure_rand_1.unsafeSkipN)(rng, 42);
}
return rng;
};
};
QualifiedParameters.readSeed = (p) => {
if (p.seed == null)
return safeDateNow() ^ (safeMathRandom() * 0x100000000);
const seed32 = p.seed | 0;
if (p.seed === seed32)
return seed32;
const gap = p.seed - seed32;
return seed32 ^ (gap * 0x100000000);
};
QualifiedParameters.readRandomType = (p) => {
if (p.randomType == null)
return pure_rand_1.default.xorshift128plus;
if (typeof p.randomType === 'string') {
switch (p.randomType) {
case 'mersenne':
return QualifiedParameters.createQualifiedRandomGenerator(pure_rand_1.default.mersenne);
case 'congruential':
case 'congruential32':
return QualifiedParameters.createQualifiedRandomGenerator(pure_rand_1.default.congruential32);
case 'xorshift128plus':
return pure_rand_1.default.xorshift128plus;
case 'xoroshiro128plus':
return pure_rand_1.default.xoroshiro128plus;
default:
throw new Error(`Invalid random specified: '${p.randomType}'`);
}
}
const mrng = p.randomType(0);
if ('min' in mrng && mrng.min !== -0x80000000) {
throw new Error(`Invalid random number generator: min must equal -0x80000000, got ${String(mrng.min)}`);
}
if ('max' in mrng && mrng.max !== 0x7fffffff) {
throw new Error(`Invalid random number generator: max must equal 0x7fffffff, got ${String(mrng.max)}`);
}
if ('unsafeJump' in mrng) {
return p.randomType;
}
return QualifiedParameters.createQualifiedRandomGenerator(p.randomType);
};
QualifiedParameters.readNumRuns = (p) => {
const defaultValue = 100;
if (p.numRuns != null)
return p.numRuns;
if (p.num_runs != null)
return p.num_runs;
return defaultValue;
};
QualifiedParameters.readVerbose = (p) => {
if (p.verbose == null)
return VerbosityLevel_1.VerbosityLevel.None;
if (typeof p.verbose === 'boolean') {
return p.verbose === true ? VerbosityLevel_1.VerbosityLevel.Verbose : VerbosityLevel_1.VerbosityLevel.None;
}
if (p.verbose <= VerbosityLevel_1.VerbosityLevel.None) {
return VerbosityLevel_1.VerbosityLevel.None;
}
if (p.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
return VerbosityLevel_1.VerbosityLevel.VeryVerbose;
}
return p.verbose | 0;
};
QualifiedParameters.readBoolean = (p, key) => p[key] === true;
QualifiedParameters.readOrDefault = (p, key, defaultValue) => {
const value = p[key];
return value != null ? value : defaultValue;
};
QualifiedParameters.safeTimeout = (value) => {
if (value === null) {
return null;
}
return safeMathMin(value, 0x7fffffff);
};

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VerbosityLevel = void 0;
var VerbosityLevel;
(function (VerbosityLevel) {
VerbosityLevel[VerbosityLevel["None"] = 0] = "None";
VerbosityLevel[VerbosityLevel["Verbose"] = 1] = "Verbose";
VerbosityLevel[VerbosityLevel["VeryVerbose"] = 2] = "VeryVerbose";
})(VerbosityLevel || (exports.VerbosityLevel = VerbosityLevel = {}));

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExecutionStatus = void 0;
var ExecutionStatus;
(function (ExecutionStatus) {
ExecutionStatus[ExecutionStatus["Success"] = 0] = "Success";
ExecutionStatus[ExecutionStatus["Skipped"] = -1] = "Skipped";
ExecutionStatus[ExecutionStatus["Failure"] = 1] = "Failure";
})(ExecutionStatus || (exports.ExecutionStatus = ExecutionStatus = {}));

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,2 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

View File

@@ -0,0 +1,118 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RunExecution = void 0;
const VerbosityLevel_1 = require("../configuration/VerbosityLevel");
const ExecutionStatus_1 = require("./ExecutionStatus");
const globals_1 = require("../../../utils/globals");
class RunExecution {
constructor(verbosity, interruptedAsFailure) {
this.verbosity = verbosity;
this.interruptedAsFailure = interruptedAsFailure;
this.isSuccess = () => this.pathToFailure == null;
this.firstFailure = () => (this.pathToFailure ? +(0, globals_1.safeSplit)(this.pathToFailure, ':')[0] : -1);
this.numShrinks = () => (this.pathToFailure ? (0, globals_1.safeSplit)(this.pathToFailure, ':').length - 1 : 0);
this.rootExecutionTrees = [];
this.currentLevelExecutionTrees = this.rootExecutionTrees;
this.failure = null;
this.numSkips = 0;
this.numSuccesses = 0;
this.interrupted = false;
}
appendExecutionTree(status, value) {
const currentTree = { status, value, children: [] };
this.currentLevelExecutionTrees.push(currentTree);
return currentTree;
}
fail(value, id, failure) {
if (this.verbosity >= VerbosityLevel_1.VerbosityLevel.Verbose) {
const currentTree = this.appendExecutionTree(ExecutionStatus_1.ExecutionStatus.Failure, value);
this.currentLevelExecutionTrees = currentTree.children;
}
if (this.pathToFailure == null)
this.pathToFailure = `${id}`;
else
this.pathToFailure += `:${id}`;
this.value = value;
this.failure = failure;
}
skip(value) {
if (this.verbosity >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
this.appendExecutionTree(ExecutionStatus_1.ExecutionStatus.Skipped, value);
}
if (this.pathToFailure == null) {
++this.numSkips;
}
}
success(value) {
if (this.verbosity >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
this.appendExecutionTree(ExecutionStatus_1.ExecutionStatus.Success, value);
}
if (this.pathToFailure == null) {
++this.numSuccesses;
}
}
interrupt() {
this.interrupted = true;
}
extractFailures() {
if (this.isSuccess()) {
return [];
}
const failures = [];
let cursor = this.rootExecutionTrees;
while (cursor.length > 0 && cursor[cursor.length - 1].status === ExecutionStatus_1.ExecutionStatus.Failure) {
const failureTree = cursor[cursor.length - 1];
failures.push(failureTree.value);
cursor = failureTree.children;
}
return failures;
}
toRunDetails(seed, basePath, maxSkips, qParams) {
if (!this.isSuccess()) {
return {
failed: true,
interrupted: this.interrupted,
numRuns: this.firstFailure() + 1 - this.numSkips,
numSkips: this.numSkips,
numShrinks: this.numShrinks(),
seed,
counterexample: this.value,
counterexamplePath: RunExecution.mergePaths(basePath, this.pathToFailure),
error: this.failure.errorMessage,
errorInstance: this.failure.error,
failures: this.extractFailures(),
executionSummary: this.rootExecutionTrees,
verbose: this.verbosity,
runConfiguration: qParams.toParameters(),
};
}
const considerInterruptedAsFailure = this.interruptedAsFailure || this.numSuccesses === 0;
const failed = this.numSkips > maxSkips || (this.interrupted && considerInterruptedAsFailure);
const out = {
failed,
interrupted: this.interrupted,
numRuns: this.numSuccesses,
numSkips: this.numSkips,
numShrinks: 0,
seed,
counterexample: null,
counterexamplePath: null,
error: null,
errorInstance: null,
failures: [],
executionSummary: this.rootExecutionTrees,
verbose: this.verbosity,
runConfiguration: qParams.toParameters(),
};
return out;
}
}
exports.RunExecution = RunExecution;
RunExecution.mergePaths = (offsetPath, path) => {
if (offsetPath.length === 0)
return path;
const offsetItems = offsetPath.split(':');
const remainingItems = path.split(':');
const middle = +offsetItems[offsetItems.length - 1] + +remainingItems[0];
return [...offsetItems.slice(0, offsetItems.length - 1), `${middle}`, ...remainingItems.slice(1)].join(':');
};

View File

@@ -0,0 +1,25 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.pathWalk = pathWalk;
function produce(producer) {
return producer();
}
function pathWalk(path, initialProducers, shrink) {
const producers = initialProducers;
const segments = path.split(':').map((text) => +text);
if (segments.length === 0) {
return producers.map(produce);
}
if (!segments.every((v) => !Number.isNaN(v))) {
throw new Error(`Unable to replay, got invalid path=${path}`);
}
let values = producers.drop(segments[0]).map(produce);
for (const s of segments.slice(1)) {
const valueToShrink = values.getNthOrLast(0);
if (valueToShrink === null) {
throw new Error(`Unable to replay, got wrong path=${path}`);
}
values = shrink(valueToShrink).drop(s);
}
return values;
}

View File

@@ -0,0 +1,166 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reportRunDetails = reportRunDetails;
exports.asyncReportRunDetails = asyncReportRunDetails;
exports.defaultReportMessage = defaultReportMessage;
exports.asyncDefaultReportMessage = asyncDefaultReportMessage;
const globals_1 = require("../../../utils/globals");
const stringify_1 = require("../../../utils/stringify");
const VerbosityLevel_1 = require("../configuration/VerbosityLevel");
const ExecutionStatus_1 = require("../reporter/ExecutionStatus");
const safeObjectAssign = Object.assign;
function formatHints(hints) {
if (hints.length === 1) {
return `Hint: ${hints[0]}`;
}
return hints.map((h, idx) => `Hint (${idx + 1}): ${h}`).join('\n');
}
function formatFailures(failures, stringifyOne) {
return `Encountered failures were:\n- ${failures.map(stringifyOne).join('\n- ')}`;
}
function formatExecutionSummary(executionTrees, stringifyOne) {
const summaryLines = [];
const remainingTreesAndDepth = [];
for (const tree of executionTrees.slice().reverse()) {
remainingTreesAndDepth.push({ depth: 1, tree });
}
while (remainingTreesAndDepth.length !== 0) {
const currentTreeAndDepth = remainingTreesAndDepth.pop();
const currentTree = currentTreeAndDepth.tree;
const currentDepth = currentTreeAndDepth.depth;
const statusIcon = currentTree.status === ExecutionStatus_1.ExecutionStatus.Success
? '\x1b[32m\u221A\x1b[0m'
: currentTree.status === ExecutionStatus_1.ExecutionStatus.Failure
? '\x1b[31m\xD7\x1b[0m'
: '\x1b[33m!\x1b[0m';
const leftPadding = Array(currentDepth).join('. ');
summaryLines.push(`${leftPadding}${statusIcon} ${stringifyOne(currentTree.value)}`);
for (const tree of currentTree.children.slice().reverse()) {
remainingTreesAndDepth.push({ depth: currentDepth + 1, tree });
}
}
return `Execution summary:\n${summaryLines.join('\n')}`;
}
function preFormatTooManySkipped(out, stringifyOne) {
const message = `Failed to run property, too many pre-condition failures encountered\n{ seed: ${out.seed} }\n\nRan ${out.numRuns} time(s)\nSkipped ${out.numSkips} time(s)`;
let details = null;
const hints = [
'Try to reduce the number of rejected values by combining map, flatMap and built-in arbitraries',
'Increase failure tolerance by setting maxSkipsPerRun to an higher value',
];
if (out.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
details = formatExecutionSummary(out.executionSummary, stringifyOne);
}
else {
(0, globals_1.safePush)(hints, 'Enable verbose mode at level VeryVerbose in order to check all generated values and their associated status');
}
return { message, details, hints };
}
function preFormatFailure(out, stringifyOne) {
const noErrorInMessage = out.runConfiguration.errorWithCause;
const messageErrorPart = noErrorInMessage ? '' : `\nGot ${(0, globals_1.safeReplace)(out.error, /^Error: /, 'error: ')}`;
const message = `Property failed after ${out.numRuns} tests\n{ seed: ${out.seed}, path: "${out.counterexamplePath}", endOnFailure: true }\nCounterexample: ${stringifyOne(out.counterexample)}\nShrunk ${out.numShrinks} time(s)${messageErrorPart}`;
let details = null;
const hints = [];
if (out.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
details = formatExecutionSummary(out.executionSummary, stringifyOne);
}
else if (out.verbose === VerbosityLevel_1.VerbosityLevel.Verbose) {
details = formatFailures(out.failures, stringifyOne);
}
else {
(0, globals_1.safePush)(hints, 'Enable verbose mode in order to have the list of all failing values encountered during the run');
}
return { message, details, hints };
}
function preFormatEarlyInterrupted(out, stringifyOne) {
const message = `Property interrupted after ${out.numRuns} tests\n{ seed: ${out.seed} }`;
let details = null;
const hints = [];
if (out.verbose >= VerbosityLevel_1.VerbosityLevel.VeryVerbose) {
details = formatExecutionSummary(out.executionSummary, stringifyOne);
}
else {
(0, globals_1.safePush)(hints, 'Enable verbose mode at level VeryVerbose in order to check all generated values and their associated status');
}
return { message, details, hints };
}
function defaultReportMessageInternal(out, stringifyOne) {
if (!out.failed)
return;
const { message, details, hints } = out.counterexamplePath === null
? out.interrupted
? preFormatEarlyInterrupted(out, stringifyOne)
: preFormatTooManySkipped(out, stringifyOne)
: preFormatFailure(out, stringifyOne);
let errorMessage = message;
if (details != null)
errorMessage += `\n\n${details}`;
if (hints.length > 0)
errorMessage += `\n\n${formatHints(hints)}`;
return errorMessage;
}
function defaultReportMessage(out) {
return defaultReportMessageInternal(out, stringify_1.stringify);
}
async function asyncDefaultReportMessage(out) {
const pendingStringifieds = [];
function stringifyOne(value) {
const stringified = (0, stringify_1.possiblyAsyncStringify)(value);
if (typeof stringified === 'string') {
return stringified;
}
pendingStringifieds.push(Promise.all([value, stringified]));
return '\u2026';
}
const firstTryMessage = defaultReportMessageInternal(out, stringifyOne);
if (pendingStringifieds.length === 0) {
return firstTryMessage;
}
const registeredValues = new globals_1.Map(await Promise.all(pendingStringifieds));
function stringifySecond(value) {
const asyncStringifiedIfRegistered = (0, globals_1.safeMapGet)(registeredValues, value);
if (asyncStringifiedIfRegistered !== undefined) {
return asyncStringifiedIfRegistered;
}
return (0, stringify_1.stringify)(value);
}
return defaultReportMessageInternal(out, stringifySecond);
}
function buildError(errorMessage, out) {
if (!out.runConfiguration.errorWithCause) {
throw new globals_1.Error(errorMessage);
}
const ErrorWithCause = globals_1.Error;
const error = new ErrorWithCause(errorMessage, { cause: out.errorInstance });
if (!('cause' in error)) {
safeObjectAssign(error, { cause: out.errorInstance });
}
return error;
}
function throwIfFailed(out) {
if (!out.failed)
return;
throw buildError(defaultReportMessage(out), out);
}
async function asyncThrowIfFailed(out) {
if (!out.failed)
return;
throw buildError(await asyncDefaultReportMessage(out), out);
}
function reportRunDetails(out) {
if (out.runConfiguration.asyncReporter)
return out.runConfiguration.asyncReporter(out);
else if (out.runConfiguration.reporter)
return out.runConfiguration.reporter(out);
else
return throwIfFailed(out);
}
async function asyncReportRunDetails(out) {
if (out.runConfiguration.asyncReporter)
return out.runConfiguration.asyncReporter(out);
else if (out.runConfiguration.reporter)
return out.runConfiguration.reporter(out);
else
return asyncThrowIfFailed(out);
}

15
backend/node_modules/fast-check/lib/check/symbols.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cloneMethod = void 0;
exports.hasCloneMethod = hasCloneMethod;
exports.cloneIfNeeded = cloneIfNeeded;
exports.cloneMethod = Symbol.for('fast-check/cloneMethod');
function hasCloneMethod(instance) {
return (instance !== null &&
(typeof instance === 'object' || typeof instance === 'function') &&
exports.cloneMethod in instance &&
typeof instance[exports.cloneMethod] === 'function');
}
function cloneIfNeeded(instance) {
return hasCloneMethod(instance) ? instance[exports.cloneMethod]() : instance;
}