Recognize NWS key points sections
This commit is contained in:
@@ -48,6 +48,7 @@ type forecastDiscussionSectionBlock struct {
|
||||
var (
|
||||
forecastDiscussionSectionRoles = map[string]forecastDiscussionSectionRole{
|
||||
"KEY MESSAGES": forecastDiscussionSectionRoleKeyMessages,
|
||||
"KEY POINTS": forecastDiscussionSectionRoleKeyMessages,
|
||||
"SHORT TERM": forecastDiscussionSectionRoleShortTerm,
|
||||
"LONG TERM": forecastDiscussionSectionRoleLongTerm,
|
||||
}
|
||||
|
||||
@@ -279,11 +279,29 @@ func TestParseForecastDiscussionSectionHeading(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestForecastDiscussionSectionRoleHeadingsParse(t *testing.T) {
|
||||
if len(forecastDiscussionSectionRoles) != 3 {
|
||||
t.Fatalf("role registry has %d entries, want 3", len(forecastDiscussionSectionRoles))
|
||||
if len(forecastDiscussionSectionRoles) != 4 {
|
||||
t.Fatalf("role registry has %d entries, want 4", len(forecastDiscussionSectionRoles))
|
||||
}
|
||||
if _, ok := forecastDiscussionSectionRoles["AVIATION"]; ok {
|
||||
t.Fatalf("AVIATION must remain boundary-only")
|
||||
|
||||
for _, tt := range []struct {
|
||||
section string
|
||||
role forecastDiscussionSectionRole
|
||||
}{
|
||||
{section: "KEY MESSAGES", role: forecastDiscussionSectionRoleKeyMessages},
|
||||
{section: "KEY POINTS", role: forecastDiscussionSectionRoleKeyMessages},
|
||||
{section: "SHORT TERM", role: forecastDiscussionSectionRoleShortTerm},
|
||||
{section: "LONG TERM", role: forecastDiscussionSectionRoleLongTerm},
|
||||
} {
|
||||
role, ok := forecastDiscussionSectionRoles[tt.section]
|
||||
if !ok || role != tt.role {
|
||||
t.Fatalf("role for %q = %d, present = %t; want %d", tt.section, role, ok, tt.role)
|
||||
}
|
||||
}
|
||||
|
||||
for _, section := range []string{"NEAR TERM", "DISCUSSION", "AVIATION"} {
|
||||
if _, ok := forecastDiscussionSectionRoles[section]; ok {
|
||||
t.Fatalf("%s must remain boundary-only", section)
|
||||
}
|
||||
}
|
||||
|
||||
for section := range forecastDiscussionSectionRoles {
|
||||
@@ -464,6 +482,90 @@ func TestParseForecastDiscussionTextKeepsFirstMappedSections(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseForecastDiscussionTextKeepsFirstKeyMessageRole(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
lines []string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "key points only",
|
||||
lines: []string{
|
||||
".KEY POINTS...",
|
||||
"- First key point.",
|
||||
},
|
||||
want: []string{"First key point."},
|
||||
},
|
||||
{
|
||||
name: "key points before key messages",
|
||||
lines: []string{
|
||||
".KEY POINTS...",
|
||||
"- First key point.",
|
||||
"&&",
|
||||
".KEY MESSAGES...",
|
||||
"- Later key message.",
|
||||
},
|
||||
want: []string{"First key point."},
|
||||
},
|
||||
{
|
||||
name: "key messages before key points",
|
||||
lines: []string{
|
||||
".KEY MESSAGES...",
|
||||
"- First key message.",
|
||||
"&&",
|
||||
".KEY POINTS...",
|
||||
"- Later key point.",
|
||||
},
|
||||
want: []string{"First key message."},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
text := strings.Join(append([]string{
|
||||
"AFDLSX",
|
||||
"National Weather Service Saint Louis MO",
|
||||
"224 PM CDT Sat Mar 28 2026",
|
||||
"",
|
||||
}, tt.lines...), "\n")
|
||||
|
||||
got, err := ParseForecastDiscussionText(text)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseForecastDiscussionText() error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got.KeyMessages, tt.want) {
|
||||
t.Fatalf("KeyMessages = %#v, want %#v", got.KeyMessages, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseForecastDiscussionTextKeepsUnmappedSectionsBoundaryOnly(t *testing.T) {
|
||||
text := strings.Join([]string{
|
||||
"AFDLSX",
|
||||
"National Weather Service Saint Louis MO",
|
||||
"224 PM CDT Sat Mar 28 2026",
|
||||
"",
|
||||
".SHORT TERM... (Tonight)",
|
||||
"Short-term prose.",
|
||||
".NEAR TERM... (This Evening)",
|
||||
"Near-term prose.",
|
||||
".LONG TERM... (Tomorrow)",
|
||||
"Long-term prose.",
|
||||
}, "\n")
|
||||
|
||||
got, err := ParseForecastDiscussionText(text)
|
||||
if err != nil {
|
||||
t.Fatalf("ParseForecastDiscussionText() error = %v", err)
|
||||
}
|
||||
if got.ShortTerm == nil || got.ShortTerm.Text != "Short-term prose." {
|
||||
t.Fatalf("ShortTerm = %#v, want only short-term prose", got.ShortTerm)
|
||||
}
|
||||
if got.LongTerm == nil || got.LongTerm.Text != "Long-term prose." {
|
||||
t.Fatalf("LongTerm = %#v, want only long-term prose", got.LongTerm)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseForecastDiscussionTextSectionKeepsHeadingQualifiers(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user