package spc import ( "strings" "testing" "time" ) func TestDecodeGeoJSONExposesSPCPropertiesAndCompactGeometry(t *testing.T) { raw := readTestFile(t, "day1_cat.geojson") got, err := DecodeGeoJSON(raw) if err != nil { t.Fatalf("DecodeGeoJSON() error = %v", err) } if got.Type != "FeatureCollection" { t.Fatalf("Type = %q, want FeatureCollection", got.Type) } if len(got.Features) != 1 { t.Fatalf("Features length = %d, want 1", len(got.Features)) } feature := got.Features[0] props := feature.Properties if props.ValidISO != "2026-06-11T13:00:00Z" { t.Fatalf("VALID_ISO = %q", props.ValidISO) } if props.ExpireISO != "2026-06-12T12:00:00Z" { t.Fatalf("EXPIRE_ISO = %q", props.ExpireISO) } if props.IssueISO != "2026-06-11T12:34:56Z" { t.Fatalf("ISSUE_ISO = %q", props.IssueISO) } if props.Forecaster != "SMITH" { t.Fatalf("FORECASTER = %q", props.Forecaster) } if props.Label != "SLGT" { t.Fatalf("LABEL = %q", props.Label) } if props.Label2 != "Slight Risk" { t.Fatalf("LABEL2 = %q", props.Label2) } if props.DN == nil || *props.DN != 3 { t.Fatalf("DN = %v, want 3", props.DN) } wantGeometry := `{"type":"Polygon","coordinates":[[[-91.0,38.0],[-90.0,38.0],[-90.0,39.0],[-91.0,39.0],[-91.0,38.0]]]}` if string(feature.Geometry) != wantGeometry { t.Fatalf("Geometry = %s, want %s", feature.Geometry, wantGeometry) } if strings.Contains(string(feature.Geometry), "\n") || strings.Contains(string(feature.Geometry), " ") { t.Fatalf("Geometry is not compact: %q", feature.Geometry) } } func TestDecodeGeoJSONParsesSeverityRankString(t *testing.T) { raw := readTestFile(t, "day2_torn.geojson") got, err := DecodeGeoJSON(raw) if err != nil { t.Fatalf("DecodeGeoJSON() error = %v", err) } props := got.Features[0].Properties if props.DN == nil || *props.DN != 5 { t.Fatalf("DN = %v, want 5", props.DN) } } func TestIsEmptyGeometryCollection(t *testing.T) { tests := []struct { name string raw string want bool }{ { name: "empty geometry collection", raw: `{"type":"GeometryCollection","geometries":[]}`, want: true, }, { name: "non-empty geometry collection", raw: `{"type":"GeometryCollection","geometries":[{"type":"Polygon","coordinates":[]} ]}`, want: false, }, { name: "polygon", raw: `{"type":"Polygon","coordinates":[]}`, want: false, }, { name: "invalid json", raw: `{`, want: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := IsEmptyGeometryCollection([]byte(tt.raw)); got != tt.want { t.Fatalf("IsEmptyGeometryCollection() = %v, want %v", got, tt.want) } }) } } func TestParseISOTimestampTrimsAndReturnsUTC(t *testing.T) { got, err := ParseISOTimestamp(" 2026-06-11T12:34:56Z ") if err != nil { t.Fatalf("ParseISOTimestamp() error = %v", err) } want := time.Date(2026, 6, 11, 12, 34, 56, 0, time.UTC) if !got.Equal(want) { t.Fatalf("ParseISOTimestamp() = %s, want %s", got, want) } }