Skip to content
This repository was archived by the owner on Jan 2, 2024. It is now read-only.

Commit 0c39bff

Browse files
feat: support recursive types (#9)
BREAKING CHANGE: `ExampleGenerator` now requires as input a tuple `[number,FuzzContext]` BREAKING CHANGE: concrete fuzzer functions are passed as their first argument a FuzzContext specifying whether to recurse further or not BREAKING CHANGE: deprecated, non-configurable versions of core fuzzers removed
1 parent 6ce66d9 commit 0c39bff

10 files changed

+750
-164
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.vscode
12
.DS_Store
23
*.DS_Store
34

README.md

+22-7
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ const target = t.union([t.string, t.type({n:t.number, b:t.boolean})]);
2121
// Builds a particular fuzzer from the registry.
2222
const fuzzer = fuzz.exampleGenerator(r, target);
2323

24-
// Make examples. The input number fully determines
25-
// the output example.
26-
console.log(fuzzer.encode(0));
27-
console.log(fuzzer.encode(1));
28-
console.log(fuzzer.encode(2));
29-
console.log(fuzzer.encode(493));
24+
// Make examples. The input integer and context
25+
// fully determines the output example.
26+
console.log(fuzzer.encode([0, fuzz.fuzzContext()]));
27+
console.log(fuzzer.encode([1, fuzz.fuzzContext()]));
28+
console.log(fuzzer.encode([2, fuzz.fuzzContext()]));
29+
console.log(fuzzer.encode([493, fuzz.fuzzContext()]));
3030
````
3131

3232
## Types Supported
@@ -45,6 +45,7 @@ Currently supports (and their nested closure):
4545
* `t.partial`
4646
* `t.readonly`
4747
* `t.readonlyArray`
48+
* `t.recursive`
4849
* `t.string`
4950
* `t.tuple`
5051
* `t.type` (interface)
@@ -59,7 +60,7 @@ Currently supports (and their nested closure):
5960
### Generating Conforming Examples and Verifying Decoder Behavior
6061

6162
Given a `d = t.Decoder<I,A>` (aka a `t.Type`), `fuzz.exampleGenerator` will
62-
build a `t.Encoder<number,A>` that will give example instances of `A`.
63+
build a `t.Encoder<[number,FuzzContext],A>` that will give example instances of `A`.
6364
The example instances should all pass on `d.decode`, which should return
6465
an identical example. No exceptions should be thrown.
6566

@@ -72,6 +73,20 @@ fuzzers, currently:
7273
* extra properties inserted into `partial` and `type` (interface) objects
7374
* type used to fuzz `unknown` types
7475

76+
### Recursive Types
77+
78+
When fuzzing recursive types, you can provide to the context
79+
a `maxRecursionHint` which specifies the requested maximum
80+
instantiations of any recursive type. Note that this is the
81+
maximum depth of *recursive* types, not all types. If the
82+
recursive depth has been reached, fuzzers that have a choice
83+
of which child(ren) to instantiate (like unions, partials,
84+
or arrays) will attempt to choose children that won't recurse.
85+
86+
Note this is only a hint -- sometimes the type definition won't allow the fuzzer to choose such a non-recursive path
87+
(and you'll get a stack limit error when attempting to
88+
generate the actual example from the generator).
89+
7590
### Fuzzing a Type (TODO)
7691

7792

package.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,17 @@
9999
"spec": "./build/test/**/test-*.js"
100100
},
101101
"dependencies": {
102+
"fp-ts": "^2.0.3",
102103
"io-ts": "^2.0.0",
103-
"fp-ts": "^2.0.3"
104+
"seedrandom": "^3.0.1"
104105
},
105106
"devDependencies": {
106107
"@holvonix-open/release-config-js": "^1.0.3",
108+
"@types/chai": "^4.1.7",
107109
"@types/mocha": "^5.2.5",
108110
"@types/node": "^12.6.9",
111+
"@types/seedrandom": "^2.4.28",
112+
"chai": "^4.2.0",
109113
"chokidar-cli": "^2.0.0",
110114
"codecov": "^3.4.0",
111115
"concurrently": "^4.1.1",

0 commit comments

Comments
 (0)