package tools
import (
"os"
"path/filepath"
"testing"
)
func TestLoadDataFilesFiltersFilesWithNoMatchingSegments(t *testing.T) {
// Create a temp directory with test .data files
tempDir := t.TempDir()
// File 1: Kiwi segments
file1 := `[{"Operator": "test"}, [0, 10, 100, 1000, [{"species": "Kiwi", "certainty": 90}]]]`
if err := os.WriteFile(filepath.Join(tempDir, "file1.data"), []byte(file1), 0644); err != nil {
t.Fatal(err)
}
// File 2: Tomtit segments only
file2 := `[{"Operator": "test"}, [0, 10, 100, 1000, [{"species": "Tomtit", "certainty": 90}]]]`
if err := os.WriteFile(filepath.Join(tempDir, "file2.data"), []byte(file2), 0644); err != nil {
t.Fatal(err)
}
// File 3: Kiwi segments
file3 := `[{"Operator": "test"}, [0, 10, 100, 1000, [{"species": "Kiwi", "certainty": 90}]]]`
if err := os.WriteFile(filepath.Join(tempDir, "file3.data"), []byte(file3), 0644); err != nil {
t.Fatal(err)
}
// Test 1: No filter - should load all 3 files
config1 := ClassifyConfig{Folder: tempDir}
state1, err := LoadDataFiles(config1)
if err != nil {
t.Fatal(err)
}
if len(state1.DataFiles) != 3 {
t.Errorf("No filter: expected 3 files, got %d", len(state1.DataFiles))
}
if state1.TotalSegments() != 3 {
t.Errorf("No filter: expected 3 segments total, got %d", state1.TotalSegments())
}
// Test 2: Filter by Species "Kiwi" - should load only files 1 and 3
config2 := ClassifyConfig{Folder: tempDir, Species: "Kiwi"}
state2, err := LoadDataFiles(config2)
if err != nil {
t.Fatal(err)
}
if len(state2.DataFiles) != 2 {
t.Errorf("Species=Kiwi: expected 2 files, got %d", len(state2.DataFiles))
}
if state2.TotalSegments() != 2 {
t.Errorf("Species=Kiwi: expected 2 segments total, got %d", state2.TotalSegments())
}
// Test 3: Filter by Species "Tomtit" - should load only file 2
config3 := ClassifyConfig{Folder: tempDir, Species: "Tomtit"}
state3, err := LoadDataFiles(config3)
if err != nil {
t.Fatal(err)
}
if len(state3.DataFiles) != 1 {
t.Errorf("Species=Tomtit: expected 1 file, got %d", len(state3.DataFiles))
}
if state3.TotalSegments() != 1 {
t.Errorf("Species=Tomtit: expected 1 segment total, got %d", state3.TotalSegments())
}
// Test 4: Filter by non-existent species - should return empty file list
// (handled gracefully by caller in cmd/calls_classify.go)
config4 := ClassifyConfig{Folder: tempDir, Species: "NonExistent"}
state4, err := LoadDataFiles(config4)
if err != nil {
t.Fatalf("Species=NonExistent: unexpected error: %v", err)
}
if len(state4.DataFiles) != 0 {
t.Errorf("Species=NonExistent: expected 0 files, got %d", len(state4.DataFiles))
}
if state4.TotalSegments() != 0 {
t.Errorf("Species=NonExistent: expected 0 segments, got %d", state4.TotalSegments())
}
}
func TestLoadDataFilesWithMixedSegments(t *testing.T) {
// Create a temp directory with a file containing mixed segment types
tempDir := t.TempDir()
// File with multiple segments: some Kiwi, some Tomtit
file := `[
{"Operator": "test"},
[0, 10, 100, 1000, [{"species": "Kiwi", "certainty": 90}]],
[10, 20, 100, 1000, [{"species": "Tomtit", "certainty": 80}]],
[20, 30, 100, 1000, [{"species": "Kiwi", "certainty": 95}]]
]`
if err := os.WriteFile(filepath.Join(tempDir, "mixed.data"), []byte(file), 0644); err != nil {
t.Fatal(err)
}
// Filter by Species "Kiwi" - should show 2 segments from the file
config := ClassifyConfig{Folder: tempDir, Species: "Kiwi"}
state, err := LoadDataFiles(config)
if err != nil {
t.Fatal(err)
}
if len(state.DataFiles) != 1 {
t.Errorf("Expected 1 file, got %d", len(state.DataFiles))
}
if state.TotalSegments() != 2 {
t.Errorf("Species=Kiwi: expected 2 segments, got %d", state.TotalSegments())
}
// The DataFile should still have all 3 segments internally
// but getFilteredSegments should return only the Kiwi ones
if len(state.DataFiles[0].Segments) != 3 {
t.Errorf("DataFile should have 3 segments internally, got %d", len(state.DataFiles[0].Segments))
}
filtered := state.getFilteredSegments(state.DataFiles[0])
if len(filtered) != 2 {
t.Errorf("getFilteredSegments should return 2 Kiwi segments, got %d", len(filtered))
}
}
// Test that the original DataFile segments are not modified (immutable filtering)
func TestFilteringDoesNotModifyOriginalSegments(t *testing.T) {
tempDir := t.TempDir()
file := `[
{"Operator": "test"},
[0, 10, 100, 1000, [{"species": "Kiwi", "certainty": 90}]],
[10, 20, 100, 1000, [{"species": "Tomtit", "certainty": 80}]]
]`
if err := os.WriteFile(filepath.Join(tempDir, "test.data"), []byte(file), 0644); err != nil {
t.Fatal(err)
}
config := ClassifyConfig{Folder: tempDir, Species: "Kiwi"}
state, err := LoadDataFiles(config)
if err != nil {
t.Fatal(err)
}
// Original segments should be untouched
originalSegments := state.DataFiles[0].Segments
if len(originalSegments) != 2 {
t.Errorf("Original should have 2 segments, got %d", len(originalSegments))
}
// Verify all original segments are preserved
species := []string{}
for _, seg := range originalSegments {
if len(seg.Labels) > 0 {
species = append(species, seg.Labels[0].Species)
}
}
if len(species) != 2 || species[0] != "Kiwi" || species[1] != "Tomtit" {
t.Errorf("Original segments should have both species, got %v", species)
}
}