diff options
| author | Arnaud Bailly <arnaud.bailly@iohk.io> | 2025-01-26 12:25:24 +0100 |
|---|---|---|
| committer | Arnaud Bailly <arnaud.bailly@iohk.io> | 2025-01-26 12:25:24 +0100 |
| commit | b8d51740ef8236639b7ac1eada6cf1a64750529a (patch) | |
| tree | 7fb3b678479f9da10b3eee81fef679525e75f323 | |
| parent | cc78d5d55b6e1a941b4f4d99c28e35f1363dbcab (diff) | |
| download | lambda-nantes-b8d51740ef8236639b7ac1eada6cf1a64750529a.tar.gz | |
Move shared code to library
| -rw-r--r-- | pbt/README.md | 1 | ||||
| -rw-r--r-- | pbt/ts/src/index.ts | 44 | ||||
| -rw-r--r-- | pbt/ts/src/property.ts | 37 |
3 files changed, 42 insertions, 40 deletions
diff --git a/pbt/README.md b/pbt/README.md index 4832394..308ebd9 100644 --- a/pbt/README.md +++ b/pbt/README.md @@ -75,3 +75,4 @@ Quelques liens intéressants glanés au fil de mes recherches sur le sujet : * [Using relational problems to teach PBT](https://cs.brown.edu/~tbn/publications/wnk-pj20-pbt.pdf) : une étude sur l'impact de l'apprentissage du PBT (par exemple sur un [tri topologique](https://cs.brown.edu/courses/cs195y/2019/historical/oracle.pdf)) * [Choosing properties for PBT](https://fsharpforfunandprofit.com/posts/property-based-testing-2/) * [PBT in practice](https://harrisongoldste.in/papers/icse24-pbt-in-practice.pdf): une étude à base d'entretiens sur l'efficacité _en pratique_ du PBT +* [Integrated vs. type-based shrinking](https://hypothesis.works/articles/integrated-shrinking/) : un post du créateur d'[hypothesis](https://hypothesis.works), outil de PBT en Python, justifiant la _minimisation intégrée_ diff --git a/pbt/ts/src/index.ts b/pbt/ts/src/index.ts index c6fc73a..1e9b8c0 100644 --- a/pbt/ts/src/index.ts +++ b/pbt/ts/src/index.ts @@ -1,11 +1,6 @@ import "dotenv/config"; import Prando from 'prando'; -import { Gen, property } from "./property"; - -let genint: Gen<number> = (rng: Prando) => - (size: number) => - rng.nextInt(-size, size); - +import { Gen, listOf, property, shrinklist, someInt } from "./property"; function arrayEquals<A>(a: A[], b: A[]): boolean { return Array.isArray(a) && @@ -14,19 +9,6 @@ function arrayEquals<A>(a: A[], b: A[]): boolean { a.every((val, index) => val === b[index]); } -function genlist<A>(gen: Gen<A>): Gen<A[]> { - return (rng: Prando) => { - let g = gen(rng); - return (size: number) => { - let result = []; - for (let i = 0; i < size; i++) { - result.push(g(size)); - } - return result; - }; - }; -} - function reverse<A>(arr: A[]): A[] { let result = []; for (let i = arr.length - 1; i >= 0; i--) { @@ -39,27 +21,9 @@ function reverse_is_self_inverse(arr: number[]): boolean { return arrayEquals(reverse(reverse(arr)), arr); } -function shrinklist<A>(arr: A[]): A[][] { - let result = []; - - let tail = arr.slice(1); - let keep1 = arr.slice(); - keep1.splice(1, 1); - result.push(tail,keep1); - - if (arr.length >3) { - let half = Math.floor(arr.length / 2); - let copy = arr.slice(); - let secondHalf = copy.slice(half); - result.push(secondHalf); - } - - return result; -} - function gen2lists<A>(gen: Gen<A>): Gen<[A[], A[]]> { return (rng: Prando) => { - let gl = genlist(gen)(rng); + let gl = listOf(gen)(rng); return (size: number) => { return [gl(size), gl(size)] }; @@ -84,10 +48,10 @@ function shrink2lists<A>([l1, l2]: [A[], A[]]): [A[], A[]][] { } let prop_reverse_with_two_lists = - property<[number[], number[]]>(reverse_with_two_lists, gen2lists(genint), shrink2lists); + property<[number[], number[]]>(reverse_with_two_lists, gen2lists(someInt), shrink2lists); let prop_reverse_is_self_inverse = - property(reverse_is_self_inverse, genlist(genint), shrinklist); + property(reverse_is_self_inverse, listOf(someInt), shrinklist); async function main() { let rng = new Prando(Math.random() * 1000); diff --git a/pbt/ts/src/property.ts b/pbt/ts/src/property.ts index a8c59ba..d4eea28 100644 --- a/pbt/ts/src/property.ts +++ b/pbt/ts/src/property.ts @@ -64,3 +64,40 @@ export function property<A>( return { result: 'OK', tests: i, counterexample: null }; }; } + +// basic generators + +export function listOf<A>(gen: Gen<A>): Gen<A[]> { + return (rng: Prando) => { + let g = gen(rng); + return (size: number) => { + let result = []; + for (let i = 0; i < size; i++) { + result.push(g(size)); + } + return result; + }; + }; +} + +export function shrinklist<A>(arr: A[]): A[][] { + let result = []; + + let tail = arr.slice(1); + let keep1 = arr.slice(); + keep1.splice(1, 1); + result.push(tail,keep1); + + if (arr.length >3) { + let half = Math.floor(arr.length / 2); + let copy = arr.slice(); + let secondHalf = copy.slice(half); + result.push(secondHalf); + } + + return result; +} + +export let someInt : Gen<number> = (rng: Prando) => + (size: number) => + rng.nextInt(-size, size); |
