/ testing / fuzz.ts
fuzz.ts
 1  import fs from "fs";
 2  import path from "path";
 3  
 4  import { ReadableStreamSearch } from "../src";
 5  import { BAD_INPUT_DIR, cmp, makeStream } from "./util";
 6  
 7  function randomString(min: number, max: number): string {
 8  	return Array.from(
 9  		{ length: min + Math.floor(Math.random() * (max - min)) },
10  		() => String.fromCharCode(Math.floor(Math.random() * 256)),
11  	).join("");
12  }
13  
14  function randomlySplit(input: string): string[] {
15  	const cuts = [
16  		...new Set(
17  			Array.from({ length: Math.floor(Math.random() * input.length) }, () =>
18  				Math.floor(Math.random() * input.length),
19  			).filter((n) => n > 0),
20  		),
21  	].sort((a, b) => a - b);
22  
23  	if (!cuts.length) {
24  		return [input];
25  	}
26  
27  	const output: string[] = [input.slice(0, cuts[0])];
28  	for (let i = 0; i < cuts.length - 1; i++) {
29  		const a = cuts[i];
30  		const b = cuts[i + 1];
31  
32  		output.push(input.slice(a, b));
33  	}
34  
35  	output.push(input.slice(cuts[cuts.length - 1]));
36  
37  	return output;
38  }
39  
40  function randomlySplice(haystack: string, needle: string): string {
41  	const split = randomlySplit(haystack);
42  	return Array.from({ length: split.length * 2 - 1 }, (_, i) =>
43  		i % 2 === 0 ? split[i / 2] : needle,
44  	).join("");
45  }
46  
47  (async () => {
48  	while (true) {
49  		const needle = randomString(1, 1 << 8);
50  		const haystack = randomlySplice(randomString(0, 1 << 8), needle);
51  		const chunks = randomlySplit(haystack);
52  		const expected = haystack.split(needle);
53  
54  		const search = new ReadableStreamSearch(needle, makeStream(chunks));
55  		const result = await search.allStrings();
56  
57  		if (
58  			result.length !== expected.length ||
59  			result.some((v, i) => !cmp(v, expected[i]))
60  		) {
61  			fs.mkdirSync(BAD_INPUT_DIR, { recursive: true });
62  			fs.writeFileSync(
63  				path.join(BAD_INPUT_DIR, `${Date.now()}.json`),
64  				JSON.stringify({ needle, chunks }),
65  			);
66  			process.stdout.write("!");
67  		} else {
68  			process.stdout.write(".");
69  		}
70  	}
71  })().catch(console.error);