package downloader import ( "testing" ) const sampleIdx = `1:0:d=2024010100:HGT:1000 mb:0 hour fcst: 2:289012:d=2024010100:HGT:975 mb:0 hour fcst: 3:541876:d=2024010100:TMP:1000 mb:0 hour fcst: 4:789012:d=2024010100:UGRD:1000 mb:0 hour fcst: 5:1045678:d=2024010100:VGRD:1000 mb:0 hour fcst: 6:1298765:d=2024010100:UGRD:975 mb:0 hour fcst: 7:1567890:d=2024010100:UGRD:2 m above ground:0 hour fcst: 8:1812345:d=2024010100:VGRD:975 mb:0 hour fcst: 9:2098765:d=2024010100:HGT:500 mb:3 hour fcst: ` func TestParseIdx(t *testing.T) { entries := ParseIdx([]byte(sampleIdx)) if len(entries) != 9 { t.Fatalf("expected 9 entries, got %d", len(entries)) } // Check first entry e := entries[0] if e.Index != 1 || e.Offset != 0 || e.Variable != "HGT" || e.LevelMB != 1000 || e.Hour != 0 { t.Errorf("entry 0: got %+v", e) } if e.EndOffset != 289012 { t.Errorf("entry 0 EndOffset: got %d, want 289012", e.EndOffset) } // Check "2 m above ground" is not a pressure level e = entries[6] // UGRD at "2 m above ground" if e.LevelMB != 0 { t.Errorf("non-pressure level should have LevelMB=0, got %d", e.LevelMB) } // Last entry should have EndOffset = -1 last := entries[len(entries)-1] if last.EndOffset != -1 { t.Errorf("last entry EndOffset: got %d, want -1", last.EndOffset) } } func TestFilterIdx(t *testing.T) { entries := ParseIdx([]byte(sampleIdx)) filtered := FilterIdx(entries, neededVariables) // Should include HGT/UGRD/VGRD at pressure levels, exclude TMP and "above ground" // And exclude last entry (no EndOffset) for _, e := range filtered { if !neededVariables[e.Variable] { t.Errorf("unexpected variable %s", e.Variable) } if e.LevelMB <= 0 { t.Errorf("non-pressure level included: %+v", e) } if e.Length() <= 0 { t.Errorf("entry with unknown length included: %+v", e) } } // Count expected: HGT@1000, HGT@975, UGRD@1000, VGRD@1000, UGRD@975, VGRD@975 = 6 // But HGT@500 at 3hr fcst is the last entry (no EndOffset), so excluded if len(filtered) != 6 { t.Errorf("expected 6 filtered entries, got %d", len(filtered)) for _, e := range filtered { t.Logf(" %s %d mb (offset %d, len %d)", e.Variable, e.LevelMB, e.Offset, e.Length()) } } } func TestParseLevelMB(t *testing.T) { tests := []struct { input string want int }{ {"1000 mb", 1000}, {"975 mb", 975}, {"1 mb", 1}, {"2 m above ground", 0}, {"surface", 0}, {"tropopause", 0}, } for _, tt := range tests { got := parseLevelMB(tt.input) if got != tt.want { t.Errorf("parseLevelMB(%q) = %d, want %d", tt.input, got, tt.want) } } } func TestParseHour(t *testing.T) { tests := []struct { input string want int }{ {"0 hour fcst", 0}, {"3 hour fcst", 3}, {"192 hour fcst", 192}, {"anl", 0}, } for _, tt := range tests { got := parseHour(tt.input) if got != tt.want { t.Errorf("parseHour(%q) = %d, want %d", tt.input, got, tt.want) } } }