{"id":15375889,"url":"https://github.com/rictic/fuzz-complete","last_synced_at":"2025-07-03T11:03:47.089Z","repository":{"id":248618601,"uuid":"133421978","full_name":"rictic/fuzz-complete","owner":"rictic","description":null,"archived":false,"fork":false,"pushed_at":"2018-06-02T19:13:47.000Z","size":78,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-03T10:29:21.601Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rictic.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-14T21:11:01.000Z","updated_at":"2024-07-16T11:03:08.000Z","dependencies_parsed_at":"2024-07-16T05:12:57.272Z","dependency_job_id":"d789a835-6de9-467f-a98f-77474db8e593","html_url":"https://github.com/rictic/fuzz-complete","commit_stats":null,"previous_names":["rictic/fuzz-complete"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rictic/fuzz-complete","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rictic%2Ffuzz-complete","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rictic%2Ffuzz-complete/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rictic%2Ffuzz-complete/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rictic%2Ffuzz-complete/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rictic","download_url":"https://codeload.github.com/rictic/fuzz-complete/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rictic%2Ffuzz-complete/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263314103,"owners_count":23447291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T14:05:11.768Z","updated_at":"2025-07-03T11:03:47.060Z","avatar_url":"https://github.com/rictic.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## fuzz-complete\n\nA deterministic data generator for [fuzz testing](https://en.wikipedia.org/wiki/Fuzzing) that will lazily generate every program in a language in roughly increasing order of complexity.\n\n### A demo is worth a thousand words.\n\n\n* **https://fuzz.rictic.com/**\n\n\n### Overview\n\nDefine a language in [Backus–Naur form](https://en.wikipedia.org/wiki/Backus%E2%80%93Naur_form)\n\n```\nLanguage \"simple arithmetic\":\n  expression = number |\n              '(' unaryOp expression ')' |\n              '(' expression ' ' binaryOp ' ' expression ')';\n  unaryOp = '-';\n  binaryOp = '+' | '-' | '*' | '/' | '**' | '\u003c\u003c' | '\u003e\u003e' | '|' | '\u0026';\n  number = digit+ | digit+ '.' digit+;\n  digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';\n```\n[Demo on the playground](https://fuzz.rictic.com/?input=Language+%22simple+arithmetic%22%3A%0A++expression+%3D+number+%7C%0A++++++++++++++%27%28%27+unaryOp+expression+%27%29%27+%7C%0A++++++++++++++%27%28%27+expression+%27+%27+binaryOp+%27+%27+expression+%27%29%27%3B%0A++unaryOp+%3D+%27-%27%3B%0A++binaryOp+%3D+%27%2B%27+%7C+%27-%27+%7C+%27*%27+%7C+%27%2F%27+%7C+%27**%27+%7C+%27%3C%3C%27+%7C+%27%3E%3E%27+%7C+%27%7C%27+%7C+%27%26%27%3B%0A++number+%3D+digit%2B+%7C+digit%2B+%27.%27+digit%2B%3B%0A++digit+%3D+%270%27+%7C+%271%27+%7C+%272%27+%7C+%273%27+%7C+%274%27+%7C+%275%27+%7C+%276%27+%7C+%277%27+%7C+%278%27+%7C+%279%27%3B)\n\nfuzz-complete will produce every sentence in that language, in roughly increasing complexity. More formally, for every finite N there is a finite K such that every sentence in the language of length ≤N is in fuzz-complete's output at an index less than K.\n\n### Usage\n\n```bash\n  npm install -g fuzz-complete\n  fuzz-complete ./examples/hello-world.fuzzlang\n```\n\n### API\n\n**hello-fuzz.js**\n```javascript\nimport {parse} from 'fuzz-complete'\nconst language = parse(`Language \"foo*\": foo = 'foo'*;`);\nfor (const sentence of language) {\n  console.log(sentence);\n}\n```\n\n```bash\n  npm install esm fuzz-complete\n  node -r esm hello-fuzz.js | less\n```\n\n### Iteration order\n\nThe iteration strategy is an unusual one. The tree of possible outputs is infinite in both depth and bredth, so doing either a depth first or a bredth first walk would quickly end up getting stuck in an uninteresting loop of output. For example, emitting string literal before emitting a single numeric literal, or only emitting program with exactly one statement.\n\nfuzz-complete interleaves exploration by depth and breadth to produce a complete walk of the tree while avoiding getting stuck in repetitive loops.\n\n### Backus–Naur form\n\nThere's no standard to Backus–Naur. In fuzz-complete's dialect, the first rule is the starting point. Whitespace is not significant, rules are terminated by semicolon.\n\n#### Labeled rules\n\nCompare the output of these two examples:\n\n* [Without labelling](https://fuzz.rictic.com/?input=Language+%22add+two+variables%22%3A%0A++++file+%3D+%27var+%27+identifier+%27+%3D+%27+identifier+%27+%2B+%27+identifier%3B%0A++++identifier+%3D+%28%27a%27+%7C+%27b%27+%7C+%27c%27+%7C+%27d%27+%7C+%27e%27+%7C+%27f%27+%7C+%27g%27%29%2B%3B)\n* [With labelling](https://fuzz.rictic.com/?input=Language+%22add+two+variables%22%3A%0A++++file+%3D+%27var+%27+identifier+%27+%3D+%27+identifier+%27+%2B+%27+identifier%3B%0A++++identifier%21+%3D+%28%27a%27+%7C+%27b%27+%7C+%27c%27+%7C+%27d%27+%7C+%27e%27+%7C+%27f%27+%7C+%27g%27%29%2B%3B)\n\nWhen generating variable names for programs, it's often the case that all you want to test is the _labeling_ of those variables, while ignoring what the labels are. For example: `var a = b + c;` is analogous to `var x = y + z;`, but distinct from `var a = b + b;`.\n\nIf a rule is declared with an exclamation point after its name like so:\n\n```\n  identifier! = letters+;\n```\n\nThen when expanding that rule, fuzz-complete will consider that rule to be a label, and it will not generate sentences with that are structurally the same but with different labels.\n\n### Operators\n\nFor any expression, you can use the following operators:\n\n  * `+` – expands the expression one or more times\n  * `*` – expands the expression zero or more times\n  * `?` – expands to the expression or to the empty string\n\nThese operators are often useful with parentheses. For example, `(\"foo\" | \"bar\")+` will produce `foo, bar, foobar, barfoo, foofoobar...`, and `\"[\" (number (\", \" number)*)? \"]\"` will produce `[], [0], [1], [0, 1], [1, 0], [2]...`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frictic%2Ffuzz-complete","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frictic%2Ffuzz-complete","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frictic%2Ffuzz-complete/lists"}