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

Commit

Permalink
feat: experimental fuzzer for nonempty arrays (#19)
Browse files Browse the repository at this point in the history
This will be superseded by a generic handler for NonEmptyArrays in io-ts-types when gcanti/io-ts-types#102 is fixed.
  • Loading branch information
holvonixAdvay authored Aug 10, 2019
1 parent 5b39314 commit 7e01e15
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
20 changes: 20 additions & 0 deletions src/experimental.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Fuzzer } from './fuzzer';
import * as t from 'io-ts';
import { NonEmptyArray, cons } from 'fp-ts/lib/NonEmptyArray';

/**
* @experimental 4.1.0 This will be superseded by a generic handler for NonEmptyArrays in io-ts-types when https://github.com/gcanti/io-ts-types/issues/102 is fixed.
*/
export const nonEmptyArrayFuzzer = <T>(
c: t.Type<T, unknown>
): Fuzzer<NonEmptyArray<T>, unknown> => ({
id: `NonEmptyArray<${c.name}>`,
idType: 'name',
impl: {
type: 'fuzzer',
children: [c, t.array(c)],
func: (ctx, n0, hc, ha) => {
return cons(hc.encode([n0, ctx]) as T, ha.encode([n0, ctx]) as T[]);
},
},
});
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ export * from './fuzzer';
export * from './extras';

import * as core from './core';
export { core };
import * as experimental from './experimental';
export { core, experimental };
78 changes: 78 additions & 0 deletions test/test-experimental.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import * as assert from 'assert';
import * as lib from '../src/experimental';

import {
exampleGenerator,
fuzzContext,
FuzzContext,
createCoreRegistry,
Fuzzer,
} from '../src/';
import * as t from 'io-ts';
import { nonEmptyArray } from 'io-ts-types/lib/nonEmptyArray';
import { Encode } from 'io-ts';
import { rngi } from '../src/rng';
import { isRight, Right } from 'fp-ts/lib/Either';

const count = 100;

// tslint:disable-next-line:no-any
const types: Array<t.Type<any>> = [
nonEmptyArray(t.string),
nonEmptyArray(t.union([t.string, t.number])),
t.partial({ a: nonEmptyArray(t.string) }),
t.type({ a: nonEmptyArray(t.string) }),
t.partial({ a: nonEmptyArray(t.union([t.string, t.number])) }),
t.type({ a: nonEmptyArray(t.union([t.string, t.number])) }),
t.type({ a: nonEmptyArray(t.union([t.string, t.number])) }),
nonEmptyArray(t.type({ a: nonEmptyArray(t.union([t.string, t.number])) })),
];

describe('experimental', () => {
describe('nonEmptyArrayFuzzer', () => {
for (const b of types) {
describe(`\`${b.name}\` codec`, () => {
let p: Encode<[number, FuzzContext], unknown>;
const old: unknown[] = [];
it(`loads extra fuzzers and builds an example generator`, async () => {
const r = createCoreRegistry()!;
const fz: Fuzzer[] = [
lib.nonEmptyArrayFuzzer(t.string),
lib.nonEmptyArrayFuzzer(t.union([t.string, t.number])),
lib.nonEmptyArrayFuzzer(
t.type({ a: nonEmptyArray(t.union([t.string, t.number])) })
),
] as Fuzzer[];
r.register(...fz);
p = exampleGenerator(r, b).encode;
});
it(`generates decodable examples for seeds '[0, ${count})`, () => {
for (const n of new Array(count).keys()) {
const v = p([rngi(n) / Math.PI, fuzzContext()]);
const d = b.decode(v);
assert.ok(
isRight(d),
`must decode ${JSON.stringify(v)}, instead ${JSON.stringify(d)}`
);
old.push(v);
const y = b.encode((d as Right<unknown>).right);
// can't use deepStrictEqual because io-ts uses {...X} to encode
// certain objects, thus they don't have null prototypes.
// tslint:disable-next-line:deprecation
assert.deepEqual(y, v, `must encode back to ${JSON.stringify(v)}`);
}
})
.timeout(5000)
.slow(500);
it(`generates same examples 2nd time`, () => {
for (const n of new Array(count).keys()) {
const v = p([rngi(n) / Math.PI, fuzzContext()]);
assert.deepStrictEqual(v, old[n]);
}
})
.timeout(5000)
.slow(500);
});
}
});
}).timeout(1000000);

0 comments on commit 7e01e15

Please sign in to comment.