From ca6f89a99c9e00b32e8b10b50d6251bdf593a366 Mon Sep 17 00:00:00 2001 From: Snider Date: Mon, 3 Nov 2025 18:41:28 +0000 Subject: [PATCH] Add examples for KDTree and enable errcheck linter in CI --- .github/workflows/ci.yml | 1 + .golangci.yml | 9 +++++++++ CHANGELOG.md | 4 ++++ examples_test.go | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8566995..c2db2bf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} + cache: true - name: Go env run: go env diff --git a/.golangci.yml b/.golangci.yml index abcbe10..c5e57df 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -8,13 +8,22 @@ linters: - ineffassign - gofmt - revive + - errcheck issues: exclude-use-default: false max-issues-per-linter: 0 max-same-issues: 0 + exclude-rules: + # Errcheck is noisy in examples and doc tests; ignore *_test.go for errcheck only. + - path: _test\.go + linters: + - errcheck linters-settings: revive: severity: warning rules: - name: exported arguments: ["disable"] # keep comments pragmatic; we have pkg docs and key API docs + errcheck: + # Be pragmatic: don't require checking of Close for defer patterns in tests/examples. + # (Keep defaults; exclusions above handle test files.) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49bc481..3cc58e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file. The format is based on Keep a Changelog and this project adheres to Semantic Versioning. ## [Unreleased] +### Added +- pkg.go.dev Examples: `ExampleNewKDTreeFromDim_Insert`, `ExampleKDTree_TiesBehavior`, `ExampleKDTree_Radius_none`. +- Lint: enable `errcheck` in `.golangci.yml` with test-file exclusion to reduce noise. +- CI: enable module cache in `actions/setup-go` to speed up workflows. ## [0.2.1] - 2025-11-03 ### Added diff --git a/examples_test.go b/examples_test.go index 259669b..3c1ca81 100644 --- a/examples_test.go +++ b/examples_test.go @@ -163,3 +163,38 @@ func ExampleBuild4DWithStats() { fmt.Println(tr.Dim()) // Output: 4 } + +func ExampleNewKDTreeFromDim_Insert() { + // Construct an empty 2D tree, insert a point, then query. + tr, _ := poindexter.NewKDTreeFromDim[string](2) + tr.Insert(poindexter.KDPoint[string]{ID: "A", Coords: []float64{0.1, 0.2}, Value: "alpha"}) + p, _, ok := tr.Nearest([]float64{0, 0}) + fmt.Printf("ok=%v id=%s dim=%d len=%d", ok, p.ID, tr.Dim(), tr.Len()) + // Output: ok=true id=A dim=2 len=1 +} + +func ExampleKDTree_TiesBehavior() { + // Two points equidistant from the query; tie ordering is arbitrary, + // but distances are equal. + pts := []poindexter.KDPoint[int]{ + {ID: "L", Coords: []float64{-1}}, + {ID: "R", Coords: []float64{+1}}, + } + tr, _ := poindexter.NewKDTree(pts) + ns, ds := tr.KNearest([]float64{0}, 2) + _ = ns // neighbor order is unspecified + fmt.Printf("equal=%.1f==%.1f? %v", ds[0], ds[1], ds[0] == ds[1]) + // Output: equal=1.0==1.0? true +} + +func ExampleKDTree_Radius_none() { + // Radius query that yields no matches. + pts := []poindexter.KDPoint[int]{ + {ID: "a", Coords: []float64{10}}, + {ID: "b", Coords: []float64{20}}, + } + tr, _ := poindexter.NewKDTree(pts) + within, _ := tr.Radius([]float64{0}, 5) + fmt.Println(len(within)) + // Output: 0 +}