fp-ts-quickcheck
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -1,8 +0,1 @@ | ||
/** | ||
* @summary | ||
* The `Arbitrary` typeclass represents a value that can be generated and shrunk. | ||
* | ||
* Please note that shrinking has not been implemented yet. | ||
*/ | ||
import * as gen from "@no-day/fp-ts-generators"; | ||
import { Applicative1 } from "fp-ts/lib/Applicative"; | ||
@@ -12,2 +5,5 @@ import { Apply1 } from "fp-ts/lib/Apply"; | ||
import { Pointed1 } from "fp-ts/lib/Pointed"; | ||
import { Predicate } from "fp-ts/lib/Predicate"; | ||
import { Refinement } from "fp-ts/lib/Refinement"; | ||
import { generator as gen } from "./modules"; | ||
import { EnforceNonEmptyRecord } from "./utils"; | ||
@@ -73,2 +69,11 @@ /** | ||
/** | ||
* Arbitrary cannot have a Compactable typeclass instance, as the state needs | ||
* to be supplied and called before being able to seperate the output | ||
* conditionally. | ||
* | ||
* @category Combinators | ||
*/ | ||
export declare function filter<A, B extends A>(refinement: Refinement<A, B>): (fa: Arbitrary<A>) => Arbitrary<B>; | ||
export declare function filter<A>(predicate: Predicate<A>): (fa: Arbitrary<A>) => Arbitrary<A>; | ||
/** | ||
* @summary | ||
@@ -80,4 +85,9 @@ * Generates an array with a random size, then each has the random contents. | ||
export declare function array<A>(arbitrary: Arbitrary<A>): Arbitrary<ReadonlyArray<A>>; | ||
/** | ||
* Generates an array with a fixed size, then each has the random contents.s | ||
* @summary Combinators | ||
*/ | ||
export declare function vector(size: number): <A>(fa: Arbitrary<A>) => Arbitrary<readonly A[]>; | ||
/** | ||
* Adds the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* @category Combinators | ||
@@ -88,3 +98,3 @@ */ | ||
* @summary | ||
* Removes the `Readonly` constraint from the value within an `Arbitrary` instance. | ||
* Removes the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* | ||
@@ -91,0 +101,0 @@ * @category Combinators |
@@ -13,23 +13,29 @@ "use strict"; | ||
}; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.boolean = exports.string = exports.character = exports.int = exports.number = exports.struct = exports.tuple = exports.mutable = exports.readonly = exports.vector = exports.array = exports.fromGen = exports.Applicative = exports.Apply = exports.Functor = exports.Pointed = exports.chain = exports.ap = exports.map = exports.of = exports.URI = void 0; | ||
exports.boolean = exports.string = exports.character = exports.int = exports.number = exports.struct = exports.tuple = exports.mutable = exports.readonly = exports.vector = exports.array = exports.filter = exports.fromGen = exports.Applicative = exports.Apply = exports.Functor = exports.Pointed = exports.chain = exports.ap = exports.map = exports.of = exports.URI = void 0; | ||
/** | ||
@@ -41,6 +47,6 @@ * @summary | ||
*/ | ||
var gen = __importStar(require("@no-day/fp-ts-generators")); | ||
var fp_ts_1 = require("fp-ts"); | ||
var Apply_1 = require("fp-ts/lib/Apply"); | ||
var function_1 = require("fp-ts/lib/function"); | ||
var modules_1 = require("./modules"); | ||
/** | ||
@@ -105,3 +111,8 @@ * @category Model | ||
exports.fromGen = fromGen; | ||
// COMBINATORS | ||
function filter(predicate) { | ||
return function (fa) { return ({ | ||
arbitrary: (0, function_1.pipe)(fa.arbitrary, modules_1.generator.chain((0, function_1.flow)(fp_ts_1.option.fromPredicate(predicate), fp_ts_1.option.match(function () { return (0, function_1.pipe)(fa.arbitrary, fp_ts_1.state.apFirst(modules_1.generator.nextSeed)); }, modules_1.generator.of)))), | ||
}); }; | ||
} | ||
exports.filter = filter; | ||
/** | ||
@@ -115,9 +126,13 @@ * @summary | ||
return { | ||
arbitrary: gen.arrayOf(arbitrary.arbitrary), | ||
arbitrary: modules_1.generator.arrayOf(arbitrary.arbitrary), | ||
}; | ||
} | ||
exports.array = array; | ||
/** | ||
* Generates an array with a fixed size, then each has the random contents.s | ||
* @summary Combinators | ||
*/ | ||
function vector(size) { | ||
return function (fa) { return ({ | ||
arbitrary: gen.vectorOf(size)(fa.arbitrary), | ||
arbitrary: modules_1.generator.vectorOf(size)(fa.arbitrary), | ||
}); }; | ||
@@ -127,2 +142,3 @@ } | ||
/** | ||
* Adds the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* @category Combinators | ||
@@ -133,3 +149,3 @@ */ | ||
* @summary | ||
* Removes the `Readonly` constraint from the value within an `Arbitrary` instance. | ||
* Removes the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* | ||
@@ -147,3 +163,3 @@ * @category Combinators | ||
} | ||
return (0, Apply_1.sequenceT)(exports.Apply).apply(void 0, arbitraries); | ||
return (0, Apply_1.sequenceT)(exports.Apply).apply(void 0, __spreadArray([], __read(arbitraries), false)); | ||
} | ||
@@ -163,3 +179,3 @@ exports.tuple = tuple; | ||
exports.number = { | ||
arbitrary: gen.int({ | ||
arbitrary: modules_1.generator.int({ | ||
min: Number.MAX_SAFE_INTEGER, | ||
@@ -173,3 +189,3 @@ max: Number.MAX_SAFE_INTEGER, | ||
function int(options) { | ||
return { arbitrary: gen.int(options) }; | ||
return { arbitrary: modules_1.generator.int(options) }; | ||
} | ||
@@ -185,3 +201,3 @@ exports.int = int; | ||
exports.character = { | ||
arbitrary: gen.char(), | ||
arbitrary: modules_1.generator.char(), | ||
}; | ||
@@ -192,3 +208,3 @@ /** | ||
exports.string = { | ||
arbitrary: gen.string(), | ||
arbitrary: modules_1.generator.string(), | ||
}; | ||
@@ -199,3 +215,3 @@ /** | ||
exports.boolean = { | ||
arbitrary: gen.boolean, | ||
arbitrary: modules_1.generator.boolean, | ||
}; |
@@ -10,3 +10,3 @@ /** | ||
import { Arbitrary } from "./arbitrary"; | ||
import * as gen from "./modules/generators"; | ||
import { generator as gen } from "./modules"; | ||
/** | ||
@@ -13,0 +13,0 @@ * @category Model |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -29,3 +10,3 @@ exports.reader = exports.either = exports.option = exports.boolean = exports.ordering = exports.contramap = exports.Contravariant = exports.URI = void 0; | ||
var function_1 = require("fp-ts/lib/function"); | ||
var gen = __importStar(require("./modules/generators")); | ||
var modules_1 = require("./modules"); | ||
/** | ||
@@ -49,4 +30,4 @@ * @category Model | ||
coarbitrary: function (ordering) { | ||
return gen.chainFirst(function () { | ||
return gen.variant(ordering === 1 ? 0 : ordering === 0 ? 1 : 2); | ||
return modules_1.generator.chainFirst(function () { | ||
return modules_1.generator.variant(ordering === 1 ? 0 : ordering === 0 ? 1 : 2); | ||
}); | ||
@@ -56,8 +37,8 @@ }, | ||
exports.boolean = { | ||
coarbitrary: function (bool) { return gen.chainFirst(function () { return gen.variant(bool ? 1 : 0); }); }, | ||
coarbitrary: function (bool) { return modules_1.generator.chainFirst(function () { return modules_1.generator.variant(bool ? 1 : 0); }); }, | ||
}; | ||
function option(fa) { | ||
return { | ||
coarbitrary: fp_ts_1.option.fold(function () { return gen.chainFirst(function () { return gen.variant(0); }); }, function (a) { | ||
return (0, function_1.flow)(fa.coarbitrary(a), gen.chainFirst(function () { return gen.variant(1); })); | ||
coarbitrary: fp_ts_1.option.fold(function () { return modules_1.generator.chainFirst(function () { return modules_1.generator.variant(0); }); }, function (a) { | ||
return (0, function_1.flow)(fa.coarbitrary(a), modules_1.generator.chainFirst(function () { return modules_1.generator.variant(1); })); | ||
}), | ||
@@ -70,5 +51,5 @@ }; | ||
coarbitrary: fp_ts_1.either.fold(function (e) { | ||
return (0, function_1.flow)(fe.coarbitrary(e), gen.chainFirst(function () { return gen.variant(0); })); | ||
return (0, function_1.flow)(fe.coarbitrary(e), modules_1.generator.chainFirst(function () { return modules_1.generator.variant(0); })); | ||
}, function (a) { | ||
return (0, function_1.flow)(fa.coarbitrary(a), gen.chainFirst(function () { return gen.variant(1); })); | ||
return (0, function_1.flow)(fa.coarbitrary(a), modules_1.generator.chainFirst(function () { return modules_1.generator.variant(1); })); | ||
}), | ||
@@ -81,3 +62,3 @@ }; | ||
coarbitrary: function (fea) { return function (fr) { | ||
return (0, function_1.pipe)(ge.arbitrary, gen.map(fea), gen.chain(function (a) { return (0, function_1.pipe)(fr, fa.coarbitrary(a)); })); | ||
return (0, function_1.pipe)(ge.arbitrary, modules_1.generator.map(fea), modules_1.generator.chain(function (a) { return (0, function_1.pipe)(fr, fa.coarbitrary(a)); })); | ||
}; }, | ||
@@ -84,0 +65,0 @@ }; |
export * as state from "./state"; | ||
export * as stateT from "./stateT"; | ||
export * as task from "./task"; | ||
export * as stateTask from "./state-task"; |
@@ -22,4 +22,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.stateT = exports.state = void 0; | ||
exports.stateTask = exports.task = exports.stateT = exports.state = void 0; | ||
exports.state = __importStar(require("./state")); | ||
exports.stateT = __importStar(require("./stateT")); | ||
exports.task = __importStar(require("./task")); | ||
exports.stateTask = __importStar(require("./state-task")); |
@@ -35,2 +35,18 @@ "use strict"; | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -42,3 +58,3 @@ exports.chainRec = exports.ChainRec = void 0; | ||
exports.ChainRec = __assign(__assign({}, State_1.Chain), { chainRec: function (a, f) { return function (s) { | ||
var _a = f(a)(s), _ea = _a[0], _state = _a[1]; | ||
var _a = __read(f(a)(s), 2), _ea = _a[0], _state = _a[1]; | ||
while (E.isLeft(_ea)) { | ||
@@ -45,0 +61,0 @@ var result = f(_ea.left)(_state); |
@@ -12,2 +12,18 @@ "use strict"; | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
if (!m) return o; | ||
var i = m.call(o), r, ar = [], e; | ||
try { | ||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); | ||
} | ||
catch (error) { e = { error: error }; } | ||
finally { | ||
try { | ||
if (r && !r.done && (m = i["return"])) m.call(i); | ||
} | ||
finally { if (e) throw e.error; } | ||
} | ||
return ar; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -39,5 +55,5 @@ exports.modify = exports.chainRec = exports.chainFirst = exports.get = exports.gets = void 0; | ||
return M.chainRec([a, s], function (_a) { | ||
var a = _a[0], s = _a[1]; | ||
var _b = __read(_a, 2), a = _b[0], s = _b[1]; | ||
return M.map(f(a)(s), function (_a) { | ||
var ea = _a[0], s = _a[1]; | ||
var _b = __read(_a, 2), ea = _b[0], s = _b[1]; | ||
return (0, function_1.pipe)(ea, fp_ts_1.either.bimap(function (e) { return [e, s]; }, function (a) { return [a, s]; })); | ||
@@ -44,0 +60,0 @@ }); |
@@ -1,3 +0,3 @@ | ||
import { io as IO, task as T } from "fp-ts"; | ||
import { ChainRec1 } from "fp-ts/lib/ChainRec"; | ||
import { io as IO } from "fp-ts"; | ||
import { task as T } from "../modules/fp-ts"; | ||
export interface QuickCheckOptions { | ||
@@ -8,4 +8,7 @@ initialSeed: number; | ||
} | ||
export declare const assertIO: <I>(property: (value: I) => void, options?: Partial<QuickCheckOptions> | undefined) => (arbitrary: import("../arbitrary").Arbitrary<I>) => IO.IO<void>; | ||
export declare const ChainRecTask: ChainRec1<T.URI>; | ||
export declare const assert: <I>(property: (value: I) => import("../testable").Promisable<boolean | void> | import("../testable").Thunk<import("../testable").Promisable<boolean | void>>, options?: Partial<QuickCheckOptions> | undefined) => (arbitrary: import("../arbitrary").Arbitrary<I>) => T.Task<void>; | ||
export declare type InitialQuickCheckOptions = Partial<QuickCheckOptions>; | ||
export declare const defaults: QuickCheckOptions; | ||
export declare const assertIO: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => void, options?: Partial<QuickCheckOptions> | undefined) => IO.IO<void>; | ||
export declare const unsafeAssertSync: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => void, options?: Partial<QuickCheckOptions> | undefined) => void; | ||
export declare const assertTask: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => import("../testable").Assertion, options?: Partial<QuickCheckOptions> | undefined) => T.Task<void>; | ||
export declare const unsafeAssertAsync: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => import("../testable").Assertion, options?: Partial<QuickCheckOptions> | undefined) => Promise<void>; |
@@ -14,8 +14,9 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.assert = exports.ChainRecTask = exports.assertIO = void 0; | ||
exports.unsafeAssertAsync = exports.assertTask = exports.unsafeAssertSync = exports.assertIO = exports.defaults = void 0; | ||
var fp_ts_1 = require("fp-ts"); | ||
var function_1 = require("fp-ts/lib/function"); | ||
var fp_ts_2 = require("../modules/fp-ts"); | ||
var testable_1 = require("../testable"); | ||
var make_assert_1 = require("./make-assert"); | ||
var testable_1 = require("../testable"); | ||
var fp_ts_1 = require("fp-ts"); | ||
var utils_1 = require("../utils"); | ||
var defaults = { | ||
exports.defaults = { | ||
count: 100, | ||
@@ -28,9 +29,10 @@ initialSeed: 100, | ||
MonadRecIO: __assign(__assign(__assign({}, fp_ts_1.io.ChainRec), fp_ts_1.io.FromIO), fp_ts_1.io.Pointed), | ||
defaults: defaults, | ||
defaults: exports.defaults, | ||
}); | ||
exports.ChainRecTask = __assign(__assign({}, fp_ts_1.task.Chain), { chainRec: function (fa, f) { return (0, utils_1.tailRecM)(fp_ts_1.task.Monad)(f)(fp_ts_1.task.of(fa)); } }); | ||
exports.assert = (0, make_assert_1.makeAssert)({ | ||
MonadRecIO: __assign(__assign(__assign({}, exports.ChainRecTask), fp_ts_1.task.FromIO), fp_ts_1.task.Pointed), | ||
exports.unsafeAssertSync = (0, function_1.flow)(exports.assertIO, function (io) { return io(); }); | ||
exports.assertTask = (0, make_assert_1.makeAssert)({ | ||
MonadRecIO: __assign(__assign(__assign({}, fp_ts_2.task.ChainRec), fp_ts_2.task.FromIO), fp_ts_2.task.Pointed), | ||
Testable: testable_1.assertion, | ||
defaults: defaults, | ||
defaults: exports.defaults, | ||
}); | ||
exports.unsafeAssertAsync = (0, function_1.flow)(exports.assertTask, function (a) { return a(); }); |
@@ -5,3 +5,3 @@ import { HKT, Kind, URIS } from "fp-ts/HKT"; | ||
import { Pointed, Pointed1 } from "fp-ts/lib/Pointed"; | ||
import { QuickCheckOptions } from "."; | ||
import { InitialQuickCheckOptions, QuickCheckOptions } from "./index"; | ||
import { Arbitrary } from "../arbitrary"; | ||
@@ -23,3 +23,3 @@ import { Testable, Testable1 } from "../testable"; | ||
} | ||
export declare function makeAssert<F extends URIS, A>(depenencies: MakeAssertDeps1<F, A>): <I>(property: (value: I) => A, options?: Partial<QuickCheckOptions>) => (arbitrary: Arbitrary<I>) => Kind<F, void>; | ||
export declare function makeAssert<F, A>(dependencies: AssertDeps<F, A>): <I>(property: (value: I) => A, options?: Partial<QuickCheckOptions>) => (arbitrary: Arbitrary<I>) => HKT<F, void>; | ||
export declare function makeAssert<F extends URIS, A>(depenencies: MakeAssertDeps1<F, A>): <I>(arbitrary: Arbitrary<I>, property: (value: I) => A, options?: InitialQuickCheckOptions) => Kind<F, void>; | ||
export declare function makeAssert<F, A>(dependencies: AssertDeps<F, A>): <I>(arbitrary: Arbitrary<I>, property: (value: I) => A, options?: InitialQuickCheckOptions) => HKT<F, void>; |
@@ -20,17 +20,14 @@ "use strict"; | ||
var M = _a.MonadRecIO, Testable = _a.Testable, defaults = _a.defaults; | ||
return function (property, options) { | ||
if (options === void 0) { options = {}; } | ||
return function (Arbitrary) { | ||
return (0, function_1.pipe)((0, tests_1.tests)(M)(__assign(__assign({ Arbitrary: Arbitrary, Testable: Testable, property: property }, defaults), options)), function (fa) { | ||
return M.chain(fa, function (a) { | ||
return (0, function_1.pipe)(a.failure, fp_ts_1.option.match(function () { return M.of((0, function_1.constVoid)()); }, function (failure) { | ||
return M.fromIO(function () { | ||
throw failure; | ||
}); | ||
})); | ||
}); | ||
return function (Arbitrary, property, options) { | ||
return (0, function_1.pipe)((0, tests_1.tests)(M)(__assign(__assign({ Arbitrary: Arbitrary, Testable: Testable, property: property }, defaults), options)), function (fa) { | ||
return M.chain(fa, function (a) { | ||
return (0, function_1.pipe)(a.failure, fp_ts_1.option.match(function () { return M.of((0, function_1.constVoid)()); }, function (failure) { | ||
return M.fromIO(function () { | ||
throw failure; | ||
}); | ||
})); | ||
}); | ||
}; | ||
}); | ||
}; | ||
} | ||
exports.makeAssert = makeAssert; |
@@ -16,4 +16,4 @@ import { identity as I, io as IO, option as O, task as T } from "fp-ts"; | ||
export declare type Thunkable<A> = A | Thunk<A>; | ||
declare type Assertion = Thunkable<Promisable<boolean | void>>; | ||
export declare type PropertyValue = boolean | void; | ||
export declare type Assertion = Thunkable<Promisable<PropertyValue>>; | ||
export declare const assertion: Testable1<T.URI, Assertion>; | ||
export {}; |
@@ -29,18 +29,11 @@ "use strict"; | ||
}; | ||
// todo - make functionally via composition | ||
var fromMain = function (property) { | ||
return function (i) { | ||
return function () { | ||
var main = property(i); | ||
try { | ||
var promisable = void 0; | ||
typeof main === "function" ? (promisable = main()) : (promisable = main); | ||
return promisable instanceof Promise | ||
? promisable.then(fp_ts_1.either.right).catch(fp_ts_1.either.left) | ||
: Promise.resolve(fp_ts_1.either.right(promisable)); | ||
} | ||
catch (e) { | ||
return Promise.resolve(fp_ts_1.either.left(e)); | ||
} | ||
}; | ||
return (0, function_1.pipe)(fp_ts_1.ioEither.tryCatchK(property, function_1.identity)(i), fp_ts_1.ioEither.chainIOK(function (assertion) { | ||
return typeof assertion === "function" ? assertion : function () { return assertion; }; | ||
}), fp_ts_1.ioEither.chainW((0, function_1.flow)(fp_ts_1.either.fromPredicate(function (promisable) { | ||
return promisable instanceof Promise; | ||
}, function (e) { return e; }), fp_ts_1.either.map(function (promisable) { return fp_ts_1.ioEither.tryCatch(function () { return promisable; }, function_1.identity); }), fp_ts_1.either.getOrElseW(function (propertyValue) { | ||
return fp_ts_1.ioEither.rightIO(function () { return Promise.resolve(propertyValue); }); | ||
}))), fp_ts_1.taskEither.fromIOEither, fp_ts_1.taskEither.chainTaskK(function_1.constant)); | ||
}; | ||
@@ -47,0 +40,0 @@ }; |
@@ -1,8 +0,1 @@ | ||
/** | ||
* @summary | ||
* The `Arbitrary` typeclass represents a value that can be generated and shrunk. | ||
* | ||
* Please note that shrinking has not been implemented yet. | ||
*/ | ||
import * as gen from "@no-day/fp-ts-generators"; | ||
import { Applicative1 } from "fp-ts/lib/Applicative"; | ||
@@ -12,2 +5,5 @@ import { Apply1 } from "fp-ts/lib/Apply"; | ||
import { Pointed1 } from "fp-ts/lib/Pointed"; | ||
import { Predicate } from "fp-ts/lib/Predicate"; | ||
import { Refinement } from "fp-ts/lib/Refinement"; | ||
import { generator as gen } from "./modules"; | ||
import { EnforceNonEmptyRecord } from "./utils"; | ||
@@ -73,2 +69,11 @@ /** | ||
/** | ||
* Arbitrary cannot have a Compactable typeclass instance, as the state needs | ||
* to be supplied and called before being able to seperate the output | ||
* conditionally. | ||
* | ||
* @category Combinators | ||
*/ | ||
export declare function filter<A, B extends A>(refinement: Refinement<A, B>): (fa: Arbitrary<A>) => Arbitrary<B>; | ||
export declare function filter<A>(predicate: Predicate<A>): (fa: Arbitrary<A>) => Arbitrary<A>; | ||
/** | ||
* @summary | ||
@@ -80,4 +85,9 @@ * Generates an array with a random size, then each has the random contents. | ||
export declare function array<A>(arbitrary: Arbitrary<A>): Arbitrary<ReadonlyArray<A>>; | ||
/** | ||
* Generates an array with a fixed size, then each has the random contents.s | ||
* @summary Combinators | ||
*/ | ||
export declare function vector(size: number): <A>(fa: Arbitrary<A>) => Arbitrary<readonly A[]>; | ||
/** | ||
* Adds the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* @category Combinators | ||
@@ -88,3 +98,3 @@ */ | ||
* @summary | ||
* Removes the `Readonly` constraint from the value within an `Arbitrary` instance. | ||
* Removes the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* | ||
@@ -91,0 +101,0 @@ * @category Combinators |
@@ -7,6 +7,6 @@ /** | ||
*/ | ||
import * as gen from "@no-day/fp-ts-generators"; | ||
import { state as S } from "fp-ts"; | ||
import { option as O, state as S } from "fp-ts"; | ||
import { sequenceS, sequenceT } from "fp-ts/lib/Apply"; | ||
import { flow, pipe, unsafeCoerce } from "fp-ts/lib/function"; | ||
import { generator as gen } from "./modules"; | ||
/** | ||
@@ -66,3 +66,7 @@ * @category Model | ||
} | ||
// COMBINATORS | ||
export function filter(predicate) { | ||
return (fa) => ({ | ||
arbitrary: pipe(fa.arbitrary, gen.chain(flow(O.fromPredicate(predicate), O.match(() => pipe(fa.arbitrary, S.apFirst(gen.nextSeed)), gen.of)))), | ||
}); | ||
} | ||
/** | ||
@@ -79,2 +83,6 @@ * @summary | ||
} | ||
/** | ||
* Generates an array with a fixed size, then each has the random contents.s | ||
* @summary Combinators | ||
*/ | ||
export function vector(size) { | ||
@@ -86,2 +94,3 @@ return (fa) => ({ | ||
/** | ||
* Adds the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* @category Combinators | ||
@@ -92,3 +101,3 @@ */ | ||
* @summary | ||
* Removes the `Readonly` constraint from the value within an `Arbitrary` instance. | ||
* Removes the `Readonly` type constraint from the value within an `Arbitrary` instance. | ||
* | ||
@@ -95,0 +104,0 @@ * @category Combinators |
@@ -10,3 +10,3 @@ /** | ||
import { Arbitrary } from "./arbitrary"; | ||
import * as gen from "./modules/generators"; | ||
import { generator as gen } from "./modules"; | ||
/** | ||
@@ -13,0 +13,0 @@ * @category Model |
@@ -7,3 +7,3 @@ /** | ||
import { flow, pipe } from "fp-ts/lib/function"; | ||
import * as gen from "./modules/generators"; | ||
import { generator as gen } from "./modules"; | ||
/** | ||
@@ -10,0 +10,0 @@ * @category Model |
export * as state from "./state"; | ||
export * as stateT from "./stateT"; | ||
export * as task from "./task"; | ||
export * as stateTask from "./state-task"; |
@@ -5,1 +5,5 @@ import * as state_1 from "./state"; | ||
export { stateT_1 as stateT }; | ||
import * as task_1 from "./task"; | ||
export { task_1 as task }; | ||
import * as stateTask_1 from "./state-task"; | ||
export { stateTask_1 as stateTask }; |
@@ -1,3 +0,3 @@ | ||
import { io as IO, task as T } from "fp-ts"; | ||
import { ChainRec1 } from "fp-ts/lib/ChainRec"; | ||
import { io as IO } from "fp-ts"; | ||
import { task as T } from "../modules/fp-ts"; | ||
export interface QuickCheckOptions { | ||
@@ -8,4 +8,7 @@ initialSeed: number; | ||
} | ||
export declare const assertIO: <I>(property: (value: I) => void, options?: Partial<QuickCheckOptions> | undefined) => (arbitrary: import("../arbitrary").Arbitrary<I>) => IO.IO<void>; | ||
export declare const ChainRecTask: ChainRec1<T.URI>; | ||
export declare const assert: <I>(property: (value: I) => import("../testable").Promisable<boolean | void> | import("../testable").Thunk<import("../testable").Promisable<boolean | void>>, options?: Partial<QuickCheckOptions> | undefined) => (arbitrary: import("../arbitrary").Arbitrary<I>) => T.Task<void>; | ||
export declare type InitialQuickCheckOptions = Partial<QuickCheckOptions>; | ||
export declare const defaults: QuickCheckOptions; | ||
export declare const assertIO: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => void, options?: Partial<QuickCheckOptions> | undefined) => IO.IO<void>; | ||
export declare const unsafeAssertSync: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => void, options?: Partial<QuickCheckOptions> | undefined) => void; | ||
export declare const assertTask: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => import("../testable").Assertion, options?: Partial<QuickCheckOptions> | undefined) => T.Task<void>; | ||
export declare const unsafeAssertAsync: <I>(arbitrary: import("../arbitrary").Arbitrary<I>, property: (value: I) => import("../testable").Assertion, options?: Partial<QuickCheckOptions> | undefined) => Promise<void>; |
@@ -0,6 +1,7 @@ | ||
import { io as IO } from "fp-ts"; | ||
import { flow } from "fp-ts/lib/function"; | ||
import { task as T } from "../modules/fp-ts"; | ||
import { assertion, assertionSync } from "../testable"; | ||
import { makeAssert } from "./make-assert"; | ||
import { assertionSync, assertion } from "../testable"; | ||
import { io as IO, task as T } from "fp-ts"; | ||
import { tailRecM } from "../utils"; | ||
const defaults = { | ||
export const defaults = { | ||
count: 100, | ||
@@ -15,7 +16,8 @@ initialSeed: 100, | ||
}); | ||
export const ChainRecTask = Object.assign(Object.assign({}, T.Chain), { chainRec: (fa, f) => tailRecM(T.Monad)(f)(T.of(fa)) }); | ||
export const assert = makeAssert({ | ||
MonadRecIO: Object.assign(Object.assign(Object.assign({}, ChainRecTask), T.FromIO), T.Pointed), | ||
export const unsafeAssertSync = flow(assertIO, (io) => io()); | ||
export const assertTask = makeAssert({ | ||
MonadRecIO: Object.assign(Object.assign(Object.assign({}, T.ChainRec), T.FromIO), T.Pointed), | ||
Testable: assertion, | ||
defaults, | ||
}); | ||
export const unsafeAssertAsync = flow(assertTask, (a) => a()); |
@@ -5,3 +5,3 @@ import { HKT, Kind, URIS } from "fp-ts/HKT"; | ||
import { Pointed, Pointed1 } from "fp-ts/lib/Pointed"; | ||
import { QuickCheckOptions } from "."; | ||
import { InitialQuickCheckOptions, QuickCheckOptions } from "./index"; | ||
import { Arbitrary } from "../arbitrary"; | ||
@@ -23,3 +23,3 @@ import { Testable, Testable1 } from "../testable"; | ||
} | ||
export declare function makeAssert<F extends URIS, A>(depenencies: MakeAssertDeps1<F, A>): <I>(property: (value: I) => A, options?: Partial<QuickCheckOptions>) => (arbitrary: Arbitrary<I>) => Kind<F, void>; | ||
export declare function makeAssert<F, A>(dependencies: AssertDeps<F, A>): <I>(property: (value: I) => A, options?: Partial<QuickCheckOptions>) => (arbitrary: Arbitrary<I>) => HKT<F, void>; | ||
export declare function makeAssert<F extends URIS, A>(depenencies: MakeAssertDeps1<F, A>): <I>(arbitrary: Arbitrary<I>, property: (value: I) => A, options?: InitialQuickCheckOptions) => Kind<F, void>; | ||
export declare function makeAssert<F, A>(dependencies: AssertDeps<F, A>): <I>(arbitrary: Arbitrary<I>, property: (value: I) => A, options?: InitialQuickCheckOptions) => HKT<F, void>; |
@@ -5,5 +5,5 @@ import { option as O } from "fp-ts"; | ||
export function makeAssert({ MonadRecIO: M, Testable, defaults, }) { | ||
return (property, options = {}) => (Arbitrary) => pipe(tests(M)(Object.assign(Object.assign({ Arbitrary, Testable, property }, defaults), options)), (fa) => M.chain(fa, (a) => pipe(a.failure, O.match(() => M.of(constVoid()), (failure) => M.fromIO(() => { | ||
return (Arbitrary, property, options) => pipe(tests(M)(Object.assign(Object.assign({ Arbitrary, Testable, property }, defaults), options)), (fa) => M.chain(fa, (a) => pipe(a.failure, O.match(() => M.of(constVoid()), (failure) => M.fromIO(() => { | ||
throw failure; | ||
}))))); | ||
} |
@@ -16,4 +16,4 @@ import { identity as I, io as IO, option as O, task as T } from "fp-ts"; | ||
export declare type Thunkable<A> = A | Thunk<A>; | ||
declare type Assertion = Thunkable<Promisable<boolean | void>>; | ||
export declare type PropertyValue = boolean | void; | ||
export declare type Assertion = Thunkable<Promisable<PropertyValue>>; | ||
export declare const assertion: Testable1<T.URI, Assertion>; | ||
export {}; |
import { AssertionError } from "assert"; | ||
import { either as E, ioEither as IOE, option as O, taskEither as TE, } from "fp-ts"; | ||
import { pipe } from "fp-ts/lib/function"; | ||
import { constant, flow, identity, pipe } from "fp-ts/lib/function"; | ||
export const boolean = { | ||
@@ -20,16 +20,3 @@ test: (value) => (property) => property(value) | ||
}; | ||
// todo - make functionally via composition | ||
const fromMain = (property) => (i) => () => { | ||
const main = property(i); | ||
try { | ||
let promisable; | ||
typeof main === "function" ? (promisable = main()) : (promisable = main); | ||
return promisable instanceof Promise | ||
? promisable.then(E.right).catch(E.left) | ||
: Promise.resolve(E.right(promisable)); | ||
} | ||
catch (e) { | ||
return Promise.resolve(E.left(e)); | ||
} | ||
}; | ||
const fromMain = (property) => (i) => pipe(IOE.tryCatchK(property, identity)(i), IOE.chainIOK((assertion) => typeof assertion === "function" ? assertion : () => assertion), IOE.chainW(flow(E.fromPredicate((promisable) => promisable instanceof Promise, (e) => e), E.map((promisable) => IOE.tryCatch(() => promisable, identity)), E.getOrElseW((propertyValue) => IOE.rightIO(() => Promise.resolve(propertyValue))))), TE.fromIOEither, TE.chainTaskK(constant)); | ||
export const assertion = { | ||
@@ -36,0 +23,0 @@ test: (value) => (property) => pipe(fromMain(property)(value), TE.chainEitherKW(E.fromPredicate((a) => typeof a !== "boolean" || a, () => new AssertionError({ |
@@ -7,3 +7,3 @@ { | ||
"homepage": "https://github.com/fp-ts-quickcheck", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"files": [ | ||
@@ -27,2 +27,4 @@ "dist" | ||
"fp-ts": "^2.11.4", | ||
"fp-ts-contrib": "^0.1.26", | ||
"fp-ts-std": "^0.13.1", | ||
"monocle-ts": "^2.3.11" | ||
@@ -33,6 +35,5 @@ }, | ||
"test": "jest", | ||
"docs": "docs-ts", | ||
"prepublish": "yarn build && yarn test && yarn docs" | ||
"docs": "docs-ts" | ||
}, | ||
"readme": "# fp-ts-test\n\nfp-ts port of Haskell's QuickCheck.\n\n> **NOTE**\n> Please note that shrinking is not yet available.\n> Purescript did the same, so this should be enough to get you started.\n> When shrinking is available, it will be transparently added as major release.\n\n## Features\n\n- [x] Purely functional implementation.\n- [x] Compatible - Easily integrates into existing testing frameworks.\n- [x] Polymorphic - Create custom assert functions using fp-ts typeclass instances.\n- [x] Extensible - Simply add compatibilty assertions for data structures\n\n## Installation\n\n```sh\nyarn add fp-ts && yarn add -D fp-ts-test\n```\n\n## Quick Start\n\nGrab your favourite test library, in this case `jest`, and put the assertion call of this library into the test caller.\n\n```ts\n// main.ts\nexport function subtract(x: number, y: number) {\n return x - y\n}\n\n// main.spec.ts\nimport { quickcheck as qc, arbitrary as AT } from \"fp-ts-test\"\nimport { expect, it, describe } from \"@jest/globals\"\n\nimport { pipe } from \"fp-ts/function\"\n\nimport { subtract } from \"./main\"\n\ndescribe(subtract, () => {\n const arbitrary = AT.tuple(AT.number, AT.number)\n\n it(\n \"should always be smaller than the first argument\",\n pipe(\n arbitrary,\n // returns a thunk by default, because `qc.assert` throws\n qc.assert(([x, y]) => x > subract(x, y)),\n ),\n )\n\n it(\n \"should matter which order the arguments are passed\",\n pipe(\n arbitrary,\n // returns a thunk by default, because `qc.assert` throws\n qc.assert(([x, y]) => subtract(y, x) !== subract(x, y)),\n ),\n )\n})\n```\n" | ||
"readme": "# fp-ts-test\n\nfp-ts port of Haskell's QuickCheck.\n\n> **NOTE**\n> Please note that shrinking is not yet available.\n> Purescript did the same, so this should be enough to get you started.\n> When shrinking is available, it will be transparently added as major release.\n\n## Features\n\n- [x] Purely functional implementation.\n- [x] Compatible - Easily integrates into existing testing frameworks.\n- [x] Polymorphic - Create custom assert functions using fp-ts typeclass instances.\n- [x] Extensible - Simply add compatibilty assertions for data structures\n\n## Installation\n\n```sh\nyarn add -D fp-ts-test\n```\n\n## Quick Start\n\nGrab your favourite test library, in this case `jest`, and put the assertion call of this library into the test caller.\n\n```ts\n// main.ts\nexport function subtract(x: number, y: number) {\n return x - y\n}\n\n// main.spec.ts\nimport { quickcheck as qc, arbitrary as AT } from \"fp-ts-test\"\nimport { expect, it, describe } from \"@jest/globals\"\n\nimport { pipe } from \"fp-ts/function\"\n\nimport { subtract } from \"./main\"\n\ndescribe(subtract, () => {\n const arbitrary = AT.tuple(AT.number, AT.number)\n\n it(\n \"should always be smaller than the first argument\",\n pipe(\n arbitrary,\n // returns a thunk by default, because `qc.assert` throws\n qc.assert(([x, y]) => x > subract(x, y)),\n ),\n )\n\n it(\n \"should matter which order the arguments are passed\",\n pipe(\n arbitrary,\n // returns a thunk by default, because `qc.assert` throws\n qc.assert(([x, y]) => subtract(y, x) !== subract(x, y)),\n ),\n )\n})\n```\n" | ||
} |
@@ -20,3 +20,3 @@ # fp-ts-test | ||
```sh | ||
yarn add fp-ts && yarn add -D fp-ts-test | ||
yarn add -D fp-ts-test | ||
``` | ||
@@ -23,0 +23,0 @@ |
146716
82
3644
6
+ Addedfp-ts-contrib@^0.1.26
+ Addedfp-ts-std@^0.13.1
+ Addedfp-ts-contrib@0.1.29(transitive)
+ Addedfp-ts-std@0.13.1(transitive)
+ Addednewtype-ts@0.3.5(transitive)