forked from Snider/Poindexter
63 lines
2 KiB
Go
63 lines
2 KiB
Go
package poindexter
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
"testing"
|
|
)
|
|
|
|
// TestBuildNDNoErr_Parity checks that BuildNDNoErr matches BuildND on valid inputs.
|
|
func TestBuildNDNoErr_Parity(t *testing.T) {
|
|
type rec struct {
|
|
A, B, C float64
|
|
ID string
|
|
}
|
|
items := []rec{
|
|
{A: 10, B: 100, C: 1, ID: "x"},
|
|
{A: 20, B: 200, C: 2, ID: "y"},
|
|
{A: 30, B: 300, C: 3, ID: "z"},
|
|
}
|
|
features := []func(rec) float64{
|
|
func(r rec) float64 { return r.A },
|
|
func(r rec) float64 { return r.B },
|
|
func(r rec) float64 { return r.C },
|
|
}
|
|
weights := []float64{1, 0.5, 2}
|
|
invert := []bool{false, true, false}
|
|
idfn := func(r rec) string { return r.ID }
|
|
|
|
ptsStrict, err := BuildND(items, idfn, features, weights, invert)
|
|
if err != nil {
|
|
t.Fatalf("BuildND returned error: %v", err)
|
|
}
|
|
ptsLoose := BuildNDNoErr(items, idfn, features, weights, invert)
|
|
if len(ptsStrict) != len(ptsLoose) {
|
|
t.Fatalf("length mismatch: strict %d loose %d", len(ptsStrict), len(ptsLoose))
|
|
}
|
|
for i := range ptsStrict {
|
|
if ptsStrict[i].ID != ptsLoose[i].ID {
|
|
t.Fatalf("ID mismatch at %d: %s vs %s", i, ptsStrict[i].ID, ptsLoose[i].ID)
|
|
}
|
|
if len(ptsStrict[i].Coords) != len(ptsLoose[i].Coords) {
|
|
t.Fatalf("dim mismatch at %d: %d vs %d", i, len(ptsStrict[i].Coords), len(ptsLoose[i].Coords))
|
|
}
|
|
for d := range ptsStrict[i].Coords {
|
|
if math.Abs(ptsStrict[i].Coords[d]-ptsLoose[i].Coords[d]) > 1e-12 {
|
|
t.Fatalf("coord mismatch at %d dim %d: %v vs %v", i, d, ptsStrict[i].Coords[d], ptsLoose[i].Coords[d])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestBuildNDNoErr_Lenient ensures the no-error builder is lenient and returns nil on bad lengths.
|
|
func TestBuildNDNoErr_Lenient(t *testing.T) {
|
|
type rec struct{ A float64 }
|
|
items := []rec{{A: 1}, {A: 2}}
|
|
features := []func(rec) float64{func(r rec) float64 { return r.A }}
|
|
weightsBad := []float64{} // wrong length
|
|
invert := []bool{false}
|
|
pts := BuildNDNoErr(items, func(r rec) string { return fmt.Sprint(r.A) }, features, weightsBad, invert)
|
|
if pts != nil {
|
|
t.Fatalf("expected nil result on bad weights length, got %v", pts)
|
|
}
|
|
}
|