Skip to content

Testing

Run the suite

nix run .#test     # equivalent to `go test -v ./...`

Pre-commit will refuse to commit if any test fails. CI runs the same suite on every PR.

What we test

Tier What Where
Unit DBSCAN cluster shapes, findNeighbors correctness, polygon circle geometry main_test.go
Integration Full handler IO over mcp.CallToolRequest main_test.go
Golden file Canonical input → canonical output JSON testdata/*.golden.json

Writing a new test

Table-driven, idiomatic Go:

func TestClusterPointsTable(t *testing.T) {
    cases := []struct {
        name     string
        in       string
        eps      float64
        minPts   int
        wantClusters int
    }{
        {"two hotspots", twoHotspotJSON, 5000, 3, 2},
        {"too sparse", sparseJSON, 100, 3, 0},
    }
    for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            req := mcp.CallToolRequest{}
            req.Params.Arguments = map[string]interface{}{
                "geojson": tc.in,
                "eps":     tc.eps,
                "minPts":  float64(tc.minPts),
            }
            res, err := clusterHandler(context.Background(), req)
            if err != nil {
                t.Fatalf("unexpected error: %v", err)
            }
            // parse res, count Features, assert == tc.wantClusters
        })
    }
}

Determinism

DBSCAN's cluster IDs are stable for a given input + parameters because the input order is deterministic. Tests can therefore compare against golden JSON byte-for-byte after pretty-printing.

Coverage

go test -cover ./...

We target ≥ 80 % coverage of main.go. New tools must ship with tests that exercise the happy path and at least one error path.

Snapshot pattern

For larger fixtures, add --update-golden flag handling so a contributor can do go test -run TestX -update to regenerate the golden file after an intentional change.