ek9_generate_edge_case_tests
Writes a compile-checked edge-case @Test program file for one .ek9 source and answers status (applied | ready | unchanged | blocked | error), written, testCount, the echoed seed and modifiedFiles[] - every harvested constructor, method, operator and function gets the tri-state UNSET value among its inputs.
When to use it
'Give this file systematic edge-case tests' is one call: {file:'account.ek9', outputFile:'dev/account_tests.ek9'} sprays type-aware edge values (always UNSET) over every public surface.
When not to use it
- ONE specific test you already know how to write - use
ek9_add_program(isTest:true). - You already have tests and just want to run them - use
ek9_run_tests. - The counterexample + a paste-ready directed test for ONE function at a cursor - use
ek9_verify_method(this tool's mode:'verify' is its whole-file dual). - Business-logic / contract assertions the generator can't infer - hand-author the test.
Details
Two modes share one compile-filter/assemble/write engine: 'edge' is type-aware fuzz (seed echoed - pass it back to reproduce a survivor set; maxResults defaults 200), 'verify' is deterministic (seed/maxResults ignored). The editor envelope: applied (written:true) | ready (dryRun, written:false) | unchanged (reason no-candidates or no-counterexamples - nothing to write) | blocked (output-exists / output-not-dev-source / no-testable-symbols / source-compile-failed / invalid-test-module) | error (write-failed, or assembled-compile-failed where the file IS written for inspection, written:true). Intent-dependent set-state asserts carry an //AI-REVIEW marker. Workspace-independent: each call compiles the source against a fresh builtins-only program, so no prior ek9_compile is needed; paths are absolute, or relative to the server's working directory.
Arguments
| Argument | Type | Required | What it is |
|---|---|---|---|
dryRun | boolean | Default false. Preview only: harvest, generate, compile-filter and assemble exactly as a real run, but write NOTHING. Returns status 'ready' with testCount and the full fileContent that a committing call would write. Re-invoke without dryRun to commit. Use this to check testCount > 0 before writing. | |
file | string | yes | The .ek9 source file to generate tests for - absolute, or relative to the MCP server's working directory (this tool runs against a fresh builtins-only program, not the workspace). |
includeGeneratedTests | boolean | Default false. When true, include a compact [{name, description}] index of the surviving tests for inline curation (full bodies are written to outputFile). | |
maxResults | integer | Max candidate tests to generate before compile-filtering; testCount will be <= this. | |
mode | string: edge | verify | Default 'edge' — spray type-aware edge values (fuzz). 'verify' — run bounded-model verification per function and synthesise a directed test for each counterexample (seed/count are ignored in this mode). | |
outputFile | string | yes | Destination: the generated test file. MUST be a dev source — under a 'dev/' subdirectory or a QA####_dev_ filename — because the generated @Test/assert constructs only compile there (E81015); a non-dev path is blocked. Also blocked if it already exists unless overwrite:true. |
overwrite | boolean | Default false. Replace outputFile if it exists. | |
seed | integer | Reproducibility seed. Default: random (always echoed in the response). Pass the echoed seed back to regenerate the exact same survivor set after a source edit. | |
targets | array of string | Optional. Restrict generation to these construct names (types and/or functions, e.g. ["Location"]). Tests are generated ONLY for the named constructs, but nested arguments still use the full source for fidelity. Omit or empty = all testable constructs. | |
testModule | string | Module to declare the generated @Test programs in. Omit to DETECT: whichever module already holds tests referencing the source's module wins, else a conventional '<sourceModule>.tests' if the project has one, else the source's own module. When it differs from the source's module the file gains an alphabetically-ordered references block (E11026) and its edge-value constants are de-duplicated against that module, not the source's. Validated when supplied: an illegal module name is rejected up front with status 'blocked' / reason 'invalid-test-module'. Note a segment may not be a reserved keyword EK9 excludes from moduleSegment — 'some.other.mod' is illegal ('mod' is an operator), 'some.other.place' is fine. | |
verbose | boolean | Default false. Verbose compiler reporting. |
See also
- Show me in the IDE: Chapter 5: tests, built