# zimmski/go-mutesting architecture

> Architecture diagram of the GitHub repository zimmski/go-mutesting, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-23). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/zimmski/go-mutesting
- Repository: https://github.com/zimmski/go-mutesting

## Overview

1. **Purpose and scope**
   - This repo is a Go mutation-testing framework and CLI, not an application service.
   - Its core job is to take Go source targets, generate small source-level mutations, run tests against each mutant, and report which changes survive.

2. **Top-level execution path**
   - The binary entrypoint is `cmd/go-mutesting/main.go`.
   - Users pass files, directories, or package patterns; the tool resolves those targets, finds Go source files, generates mutations, runs an exec command for each mutation, and aggregates a mutation score.

3. **Source discovery and parsing boundary**
   - `parse.go` and `walk.go` handle repository-wide source selection and AST traversal.
   - The tool explicitly excludes `_test.go` files from mutation targets so the test harness itself is not mutated.
   - This layer is the boundary between filesystem/package resolution and AST-level mutation generation.

4. **AST utility layer**
   - `astutil/` contains helpers for creating and querying AST nodes.
   - These helpers support mutator implementation by making it easier to inspect and rewrite syntax trees without duplicating AST plumbing.

5. **Mutation framework core**
   - `mutator/` defines the mutation abstraction and registry used by the CLI.
   - `mutator/mutator.go` provides the interface and registration mechanism for plugging in new mutators.
   - `mutator/mutation.go` represents a specific mutation instance, including the original location and the changed source.

6. **Concrete mutator families**
   - The mutators are organized by syntax category:
     - `mutator/branch/`: empties `if`, `else`, and `case` blocks.
     - `mutator/expression/`: changes comparison operators and removes boolean-expression terms.
     - `mutator/statement/`: removes assignments, increments/decrements, and expression statements.
   - This structure mirrors the syntax tree and makes it easy to reason about what kind of code is being attacked.

7. **Mutation generation model**
   - Mutations are generated from AST nodes, not by string substitution.
   - That means the framework aims to produce syntactically valid mutants tied to real language constructs, reducing invalid edits and making patches meaningful.

8. **Test execution boundary**
   - The framework does not hardcode one testing strategy.
   - A mutation is applied, then an exec command is invoked to determine whether that mutant is “killed,” “alive,” or skipped.
   - The built-in behavior is to replace the file, run the package tests, and restore/clean up afterward.

9. **External exec command contract**
   - `scripts/exec/` contains sample shell scripts that implement the mutation-test lifecycle for Go projects.
   - The README documents the environment variables passed to these commands, such as the original and changed file paths, package import path, timeout, and verbosity flags.
   - This isolates the mutation engine from the actual test runner implementation.

10. **Results, diffing, and scoring**
    - For surviving mutants, the tool prints the patch so engineers can inspect what was not covered by tests.
    - It also computes a mutation score from killed vs total mutants.
    - A checksum-based blacklist can suppress known false positives, though the README notes this mechanism is brittle if source changes.

11. **Example and golden test assets**
    - `example/` is a small package used to demonstrate the CLI and verify end-to-end behavior.
    - `testdata/` contains many golden mutated outputs for branch, expression, and statement mutators.
    - The large set of numbered `*.go` fixtures indicates the project uses snapshot-style tests to validate exact mutation output.

12. **Automated verification and repo hygiene**
    - Each mutator has dedicated unit tests alongside its implementation.
    - `cmd/go-mutesting/main_test.go`, `parse_test.go`, and `mutator/*_test.go` validate the framework pieces.
    - `travis` config, `Makefile`, and shell scripts suggest standard CI/lint/test automation around the CLI and mutator suite.

13. **Architecture summary for a diagram**
    - Draw this as a pipeline: target resolution → AST parsing/traversal → mutator registry and concrete mutators → mutation materialization to temp files → external test exec → result reporting/scoring.
    - The main boundaries are: source discovery vs AST rewriting, mutation generation vs test execution, and core engine vs external exec scripts.

Main entry points: [`mutator/mutator.go`](https://github.com/zimmski/go-mutesting/blob/master/mutator/mutator.go) (Mutator API), [`mutator/branch/mutateif.go`](https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutateif.go) (Mutate if), [`testdata`](https://github.com/zimmski/go-mutesting/tree/master/testdata) (Golden outputs), [`cmd/go-mutesting/main.go`](https://github.com/zimmski/go-mutesting/blob/master/cmd/go-mutesting/main.go) (go-mutesting)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["CLI entrypoint"]
  node_cmd_main["go-mutesting<br/>CLI binary<br/>[main.go]"]
end

subgraph group_core["Mutation engine"]
  node_parse["Parse targets<br/>source resolver<br/>[parse.go]"]
  node_walk["AST walk<br/>traversal<br/>[walk.go]"]
  node_mutator_api["Mutator API<br/>registry<br/>[mutator.go]"]
  node_mutation["Mutation model<br/>data model<br/>[mutation.go]"]
  node_runner["Apply and run<br/>orchestration"]
  node_report["Score report<br/>results"]
end

subgraph group_mutators["Mutator families"]
  node_branch_if["Mutate if<br/>branch mutator<br/>[mutateif.go]"]
  node_branch_else["Mutate else<br/>branch mutator<br/>[mutateelse.go]"]
  node_branch_case["Mutate case<br/>branch mutator<br/>[mutatecase.go]"]
  node_expr_cmp["Compare ops<br/>expression mutator<br/>[comparison.go]"]
  node_expr_remove["Bool remove<br/>expression mutator<br/>[remove.go]"]
  node_stmt_remove["Stmt remove<br/>statement mutator<br/>[remove.go]"]
end

subgraph group_support["Support code"]
  node_ast_create["AST create<br/>ast helper<br/>[create.go]"]
  node_ast_query["AST query<br/>ast helper<br/>[query.go]"]
end

subgraph group_assets["Examples and fixtures"]
  node_example_pkg["Example app<br/>sample package<br/>[example.go]"]
  node_goldens[("Golden outputs<br/>fixture corpus")]
end

subgraph group_scripts["Scripts"]
  node_exec_scripts["Exec scripts<br/>external runner scripts"]
  node_ci_scripts["Lint and CI<br/>automation<br/>[lint.sh]"]
end

node_cmd_main -->|"resolve targets"| node_parse
node_parse -->|"parse source"| node_walk
node_walk -->|"emit candidates"| node_mutator_api
node_mutator_api -->|"registers"| node_branch_if
node_mutator_api -->|"registers"| node_branch_else
node_mutator_api -->|"registers"| node_branch_case
node_mutator_api -->|"registers"| node_expr_cmp
node_mutator_api -->|"registers"| node_expr_remove
node_mutator_api -->|"registers"| node_stmt_remove
node_ast_create -->|"supports"| node_branch_if
node_ast_query -->|"supports"| node_branch_if
node_ast_create -->|"supports"| node_expr_cmp
node_ast_query -->|"supports"| node_expr_remove
node_mutation -->|"materialized by"| node_runner
node_runner -->|"invokes"| node_exec_scripts
node_runner -->|"feeds results"| node_report
node_example_pkg -->|"exercise"| node_cmd_main
node_goldens -->|"verifies"| node_branch_if
node_goldens -->|"verifies"| node_expr_cmp
node_goldens -->|"verifies"| node_stmt_remove
node_ci_scripts -->|"checks"| node_cmd_main

click node_cmd_main "https://github.com/zimmski/go-mutesting/blob/master/cmd/go-mutesting/main.go"
click node_parse "https://github.com/zimmski/go-mutesting/blob/master/parse.go"
click node_walk "https://github.com/zimmski/go-mutesting/blob/master/walk.go"
click node_mutator_api "https://github.com/zimmski/go-mutesting/blob/master/mutator/mutator.go"
click node_mutation "https://github.com/zimmski/go-mutesting/blob/master/mutator/mutation.go"
click node_ast_create "https://github.com/zimmski/go-mutesting/blob/master/astutil/create.go"
click node_ast_query "https://github.com/zimmski/go-mutesting/blob/master/astutil/query.go"
click node_branch_if "https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutateif.go"
click node_branch_else "https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutateelse.go"
click node_branch_case "https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutatecase.go"
click node_expr_cmp "https://github.com/zimmski/go-mutesting/blob/master/mutator/expression/comparison.go"
click node_expr_remove "https://github.com/zimmski/go-mutesting/blob/master/mutator/expression/remove.go"
click node_stmt_remove "https://github.com/zimmski/go-mutesting/blob/master/mutator/statement/remove.go"
click node_example_pkg "https://github.com/zimmski/go-mutesting/blob/master/example/example.go"
click node_goldens "https://github.com/zimmski/go-mutesting/tree/master/testdata"
click node_exec_scripts "https://github.com/zimmski/go-mutesting/tree/master/scripts/exec"
click node_ci_scripts "https://github.com/zimmski/go-mutesting/blob/master/scripts/lint.sh"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cmd_main toneBlue
class node_parse,node_walk,node_mutator_api,node_mutation,node_runner,node_report toneAmber
class node_branch_if,node_branch_else,node_branch_case,node_expr_cmp,node_expr_remove,node_stmt_remove toneMint
class node_ast_create,node_ast_query toneRose
class node_example_pkg,node_goldens toneIndigo
class node_exec_scripts,node_ci_scripts toneTeal
```

## Components

### CLI entrypoint

Command-line interface and target resolution

- [go-mutesting](https://github.com/zimmski/go-mutesting/blob/master/cmd/go-mutesting/main.go): CLI binary · Main command that drives mutation testing · `cmd/go-mutesting/main.go`

### Mutation engine

Parsing, traversal, mutation orchestration, and reporting

- [Parse targets](https://github.com/zimmski/go-mutesting/blob/master/parse.go): source resolver · Resolves files, directories, and package patterns into Go sources · `parse.go`
- [AST walk](https://github.com/zimmski/go-mutesting/blob/master/walk.go): traversal · Traverses parsed source and finds mutation points · `walk.go`
- [Mutator API](https://github.com/zimmski/go-mutesting/blob/master/mutator/mutator.go): registry · Defines mutation interfaces and registration · `mutator/mutator.go`
- [Mutation model](https://github.com/zimmski/go-mutesting/blob/master/mutator/mutation.go): data model · Represents a specific mutant and its source replacement · `mutator/mutation.go`
- **Apply and run**: orchestration · Materializes a mutant, invokes tests, and restores state
- **Score report**: results · Aggregates killed, alive, skipped mutants and prints surviving patches

### Mutator families

Concrete AST mutation strategies

- [Mutate if](https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutateif.go): branch mutator · Empties if blocks · `mutator/branch/mutateif.go`
- [Mutate else](https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutateelse.go): branch mutator · Empties else blocks · `mutator/branch/mutateelse.go`
- [Mutate case](https://github.com/zimmski/go-mutesting/blob/master/mutator/branch/mutatecase.go): branch mutator · Empties case blocks · `mutator/branch/mutatecase.go`
- [Compare ops](https://github.com/zimmski/go-mutesting/blob/master/mutator/expression/comparison.go): expression mutator · Changes comparison operators · `mutator/expression/comparison.go`
- [Bool remove](https://github.com/zimmski/go-mutesting/blob/master/mutator/expression/remove.go): expression mutator · Removes boolean expression terms · `mutator/expression/remove.go`
- [Stmt remove](https://github.com/zimmski/go-mutesting/blob/master/mutator/statement/remove.go): statement mutator · Removes assignments, increments, and expression statements · `mutator/statement/remove.go`

### Support code

AST helpers and test harness utilities

- [AST create](https://github.com/zimmski/go-mutesting/blob/master/astutil/create.go): ast helper · Builds AST nodes for mutation implementations · `astutil/create.go`
- [AST query](https://github.com/zimmski/go-mutesting/blob/master/astutil/query.go): ast helper · Inspects and matches AST nodes for mutators · `astutil/query.go`

### Examples and fixtures

Demonstration package and golden mutation outputs

- [Example app](https://github.com/zimmski/go-mutesting/blob/master/example/example.go): sample package · Small package used for CLI demonstration and end-to-end checks · `example/example.go`
- [Golden outputs](https://github.com/zimmski/go-mutesting/tree/master/testdata): fixture corpus · Snapshot mutated files for branch, expression, and statement mutators · `testdata`

### Scripts

External exec and CI helpers

- [Exec scripts](https://github.com/zimmski/go-mutesting/tree/master/scripts/exec): external runner scripts · Sample shell scripts that implement the mutation-test lifecycle · `scripts/exec`
- [Lint and CI](https://github.com/zimmski/go-mutesting/blob/master/scripts/lint.sh): automation · Project scripts and CI wiring for validation · `scripts/lint.sh`

## Connections

- go-mutesting → Parse targets: resolve targets · CLI turns user input into mutation targets
- Parse targets → AST walk: parse source · Discovered files are parsed and traversed
- AST walk → Mutator API: emit candidates · Traversal identifies AST nodes that mutators can handle
- Mutator API → Mutate if: registers · Registry exposes concrete mutators
- Mutator API → Mutate else: registers · Registry exposes concrete mutators
- Mutator API → Mutate case: registers · Registry exposes concrete mutators
- Mutator API → Compare ops: registers · Registry exposes concrete mutators
- Mutator API → Bool remove: registers · Registry exposes concrete mutators
- Mutator API → Stmt remove: registers · Registry exposes concrete mutators
- AST create → Mutate if: supports · AST construction helpers used by mutators
- AST query → Mutate if: supports · AST query helpers used by mutators
- AST create → Compare ops: supports · AST construction helpers used by mutators
- AST query → Bool remove: supports · AST query helpers used by mutators
- Mutation model → Apply and run: materialized by · Mutation instances are applied to files for execution
- Apply and run → Exec scripts: invokes · External scripts execute package tests against the mutant
- Apply and run → Score report: feeds results · Execution outcome is aggregated into score and patches
- Example app → go-mutesting: exercise · Example package demonstrates the CLI path
- Golden outputs → Mutate if: verifies · Golden fixtures validate branch mutator output
- Golden outputs → Compare ops: verifies · Golden fixtures validate expression mutator output
- Golden outputs → Stmt remove: verifies · Golden fixtures validate statement mutator output
- Lint and CI → go-mutesting: checks · Automation runs tests and lint around the CLI
