Add NWS forecast discussion fixture coverage

This commit is contained in:
2026-08-03 00:22:51 +00:00
parent 6943a5ebc9
commit 3740c779eb
4 changed files with 235 additions and 0 deletions

View File

@@ -1089,6 +1089,75 @@ func TestParseForecastDiscussionHTMLSupportsMixedHeadingFormats(t *testing.T) {
}
}
func TestParseForecastDiscussionHTMLParsesNumberedAndKeyPointsFixtures(t *testing.T) {
tests := []struct {
name string
filename string
officeID string
officeName string
issuedAt time.Time
messages []string
unwanted []string
}{
{
name: "numbered key messages",
filename: "forecast_discussion_bgm_numbered_sample.html",
officeID: "BGM",
officeName: "National Weather Service Binghamton NY",
issuedAt: time.Date(2026, 4, 10, 17, 30, 0, 0, time.UTC),
messages: []string{
"Periods of rain are expected through Saturday, with locally heavier amounts possible.",
"Cooler temperatures return late this weekend.",
},
unwanted: []string{
"1)", "2.", "DISCUSSION", "Discussion details remain boundary-only content.",
},
},
{
name: "key points alias",
filename: "forecast_discussion_mfr_key_points_sample.html",
officeID: "MFR",
officeName: "National Weather Service Medford OR",
issuedAt: time.Date(2026, 4, 10, 19, 45, 0, 0, time.UTC),
messages: []string{
"Gusty winds will develop over exposed ridges, especially during the afternoon.",
"Inland valleys remain dry through Saturday.",
},
unwanted: []string{
"*", "DISCUSSION", "(Today through Thursday)", "Discussion details must not be included with key points.",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseForecastDiscussionHTML(loadForecastDiscussionFixtureHTML(t, tt.filename))
if err != nil {
t.Fatalf("ParseForecastDiscussionHTML() error = %v", err)
}
if got.OfficeID != tt.officeID || got.OfficeName != tt.officeName {
t.Fatalf("OfficeID=%q OfficeName=%q, want %q %q", got.OfficeID, got.OfficeName, tt.officeID, tt.officeName)
}
if !got.IssuedAt.Equal(tt.issuedAt) {
t.Fatalf("IssuedAt = %s, want %s", got.IssuedAt.Format(time.RFC3339), tt.issuedAt.Format(time.RFC3339))
}
if !reflect.DeepEqual(got.KeyMessages, tt.messages) {
t.Fatalf("KeyMessages = %#v, want %#v", got.KeyMessages, tt.messages)
}
if got.ShortTerm != nil || got.LongTerm != nil {
t.Fatalf("ShortTerm=%#v LongTerm=%#v, want both nil", got.ShortTerm, got.LongTerm)
}
allText := strings.Join(got.KeyMessages, "\n")
for _, unwanted := range tt.unwanted {
if strings.Contains(allText, unwanted) {
t.Fatalf("KeyMessages contain %q: %q", unwanted, allText)
}
}
})
}
}
func TestParseForecastDiscussionHTMLMissingPreBlock(t *testing.T) {
_, err := ParseForecastDiscussionHTML("<html><body><div>no pre block</div></body></html>")
if err == nil {
@@ -1131,6 +1200,17 @@ func loadForecastDiscussionBOUSampleHTML(t *testing.T) string {
return string(b)
}
func loadForecastDiscussionFixtureHTML(t *testing.T, filename string) string {
t.Helper()
path := filepath.Join("testdata", filename)
b, err := os.ReadFile(path)
if err != nil {
t.Fatalf("os.ReadFile(%q) error = %v", path, err)
}
return string(b)
}
func loadMixedFormatForecastDiscussionSampleHTML(t *testing.T) string {
t.Helper()