From b0a20bdb6b690de66dcdfcc335ad220b731fbb74 Mon Sep 17 00:00:00 2001 From: "Advay Mengle (at Holvonix LLC)" Date: Sat, 24 Aug 2019 23:36:02 -0700 Subject: [PATCH] feat: fluent record fuzzer configuration --- README.md | 1 + src/registry.ts | 14 ++++++ test/test-registry.ts | 112 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) diff --git a/README.md b/README.md index 7fc69bf..6cf3a0a 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ currently: - maximum array length (`array`, `readonlyArray`, `UnknownArray`) - extra properties inserted into `partial` and `type` (interface) objects - type used to fuzz `unknown` types +- maximum record count (`record`, `UnknownRecord`) ### Fuzz Recursive Types diff --git a/src/registry.ts b/src/registry.ts index 4c1c8e9..9922746 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -8,6 +8,8 @@ import { unknownFuzzer, arrayFuzzer, coreFuzzers, + recordFuzzer, + unknownRecordFuzzer, } from './core'; export interface Registry { @@ -23,6 +25,8 @@ export interface FluentRegistry extends Registry { withUnknownFuzzer(codec?: t.Decoder): FluentRegistry; withArrayFuzzer(maxLength?: number): FluentRegistry; withAnyArrayFuzzer(maxLength?: number): FluentRegistry; + withRecordFuzzer(maxCount?: number): FluentRegistry; + withUnknownRecordFuzzer(maxCount?: number): FluentRegistry; withReadonlyArrayFuzzer(maxLength?: number): FluentRegistry; withPartialFuzzer(extra?: t.Props): FluentRegistry; withInterfaceFuzzer(extra?: t.Props): FluentRegistry; @@ -63,6 +67,16 @@ class FluentifiedRegistry implements FluentRegistry { return this; } + withRecordFuzzer(maxCount?: number): FluentRegistry { + this.register(recordFuzzer(maxCount)); + return this; + } + + withUnknownRecordFuzzer(maxCount?: number): FluentRegistry { + this.register(unknownRecordFuzzer(maxCount)); + return this; + } + withReadonlyArrayFuzzer(maxLength?: number): FluentRegistry { this.register(readonlyArrayFuzzer(maxLength)); return this; diff --git a/test/test-registry.ts b/test/test-registry.ts index 775a77b..f615d0e 100644 --- a/test/test-registry.ts +++ b/test/test-registry.ts @@ -256,6 +256,118 @@ describe('registry', () => { }); }); + describe('#withRecordFuzzer', () => { + describe('on the core registry', () => { + it(`overrides the record fuzzer max count`, () => { + const b = t.record(t.string, t.number); + const r0 = lib.createCoreRegistry(); + const r = lib + .fluent(r0) + .withRecordFuzzer(3) + .exampleGenerator(b); + for (let i = 0; i < 100; i++) { + assert.ok( + Object.getOwnPropertyNames(r.encode([ + i, + fuzzContext({ maxRecursionHint: 10 }), + ]) as object).length <= 3 + ); + } + }); + + it(`does not affect unknown records`, () => { + const b = t.UnknownRecord; + const r0 = lib.createCoreRegistry(); + const r = lib + .fluent(r0) + .withRecordFuzzer(3) + .exampleGenerator(b); + let ml = 0; + for (let i = 0; i < 100; i++) { + ml = Math.max( + Object.getOwnPropertyNames(r.encode([ + i, + fuzzContext({ maxRecursionHint: 10 }), + ]) as object).length, + ml + ); + } + assert.ok(ml > 3); + }); + + it(`overrides apply to the underlying registry`, () => { + const b = t.record(t.string, t.number); + const r0 = lib.createCoreRegistry(); + lib.fluent(r0).withRecordFuzzer(3); + const r = r0.exampleGenerator(b); + for (let i = 0; i < 100; i++) { + assert.ok( + Object.getOwnPropertyNames(r.encode([ + i, + fuzzContext({ maxRecursionHint: 10 }), + ]) as object).length <= 3 + ); + } + }); + }); + }); + + describe('#withUnknownRecordFuzzer', () => { + describe('on the core registry', () => { + it(`overrides the unknown record fuzzer max count`, () => { + const b = t.UnknownRecord; + const r0 = lib.createCoreRegistry(); + const r = lib + .fluent(r0) + .withUnknownRecordFuzzer(3) + .exampleGenerator(b); + for (let i = 0; i < 100; i++) { + assert.ok( + Object.getOwnPropertyNames(r.encode([ + i, + fuzzContext({ maxRecursionHint: 10 }), + ]) as object).length <= 3 + ); + } + }); + + it(`does not affect records`, () => { + const b = t.record(t.string, t.unknown); + const r0 = lib.createCoreRegistry(); + const r = lib + .fluent(r0) + .withUnknownRecordFuzzer(3) + .exampleGenerator(b); + let ml = 0; + for (let i = 0; i < 100; i++) { + ml = Math.max( + Object.getOwnPropertyNames(r.encode([ + i, + fuzzContext({ maxRecursionHint: 10 }), + ]) as object).length, + ml + ); + } + assert.ok(ml > 3); + }); + + it(`overrides apply to the underlying registry`, () => { + const b = t.UnknownRecord; + const r0 = lib.createCoreRegistry(); + lib.fluent(r0).withUnknownRecordFuzzer(3); + const r = r0.exampleGenerator(b); + for (let i = 0; i < 100; i++) { + assert.ok( + Object.getOwnPropertyNames(r.encode([ + i, + fuzzContext({ maxRecursionHint: 10 }), + ]) as object).length <= 3 + ); + } + }); + }); + }); + describe('#withAnyArrayFuzzer', () => { describe('on the core registry', () => { it(`overrides the any array fuzzer max length`, () => {