package gfs 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)) } if e := entries[0]; e.Index != 1 || e.Offset != 0 || e.Variable != "HGT" || e.LevelMB != 1000 || e.Hour != 0 || e.EndOffset != 289012 { t.Errorf("entry 0: %+v", e) } if e := entries[6]; e.LevelMB != 0 { t.Errorf("non-pressure level should have LevelMB=0, got %d", e.LevelMB) } if e := entries[len(entries)-1]; e.EndOffset != -1 { t.Errorf("last entry EndOffset: got %d, want -1", e.EndOffset) } } func TestFilterIdx(t *testing.T) { entries := ParseIdx([]byte(sampleIdx)) want := map[string]bool{"HGT": true, "UGRD": true, "VGRD": true} filtered := FilterIdx(entries, want) // HGT@1000, HGT@975, UGRD@1000, VGRD@1000, UGRD@975, VGRD@975 = 6 // HGT@500 at 3hr is last entry (no EndOffset), so dropped. if len(filtered) != 6 { t.Errorf("expected 6, got %d", len(filtered)) } } func TestParseLevelMB(t *testing.T) { cases := []struct { in string want int }{ {"1000 mb", 1000}, {"975 mb", 975}, {"1 mb", 1}, {"2 m above ground", 0}, {"surface", 0}, {"tropopause", 0}, } for _, c := range cases { if got := parseLevelMB(c.in); got != c.want { t.Errorf("parseLevelMB(%q) = %d, want %d", c.in, got, c.want) } } } func TestParseHour(t *testing.T) { cases := []struct { in string want int }{ {"0 hour fcst", 0}, {"3 hour fcst", 3}, {"192 hour fcst", 192}, {"anl", 0}, } for _, c := range cases { if got := parseHour(c.in); got != c.want { t.Errorf("parseHour(%q) = %d, want %d", c.in, got, c.want) } } }