Add Today report to morning batch

This commit is contained in:
2026-06-15 14:54:37 +00:00
parent 8ff5c44324
commit 3d5f71e72d
15 changed files with 431 additions and 32 deletions

View File

@@ -33,6 +33,41 @@ func TestDailyValidPeriodCanUseExplicitDate(t *testing.T) {
assertPeriod(t, resolved.ValidPeriod, "2026-05-31T00:00:00-05:00", "2026-06-01T00:00:00-05:00")
}
func TestTodayValidPeriod(t *testing.T) {
location := mustLoadLocation(t)
now := mustParse("2026-05-29T17:45:00-05:00")
resolved, err := Resolve(Today, ResolveRequest{Now: now, Location: location})
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
assertPeriod(t, resolved.ValidPeriod, "2026-05-29T00:00:00-05:00", "2026-05-30T00:00:00-05:00")
if resolved.Definition.PromptID != "weather.today_generated_text" {
t.Fatalf("PromptID = %q, want weather.today_generated_text", resolved.Definition.PromptID)
}
if resolved.Definition.GenerationMode != GenerationModeGeneratedTextTemplate {
t.Fatalf("GenerationMode = %q, want generated_text_template", resolved.Definition.GenerationMode)
}
if resolved.Definition.TemplateID != "today" {
t.Fatalf("TemplateID = %q, want today", resolved.Definition.TemplateID)
}
if resolved.Definition.GeneratedTextSchemaID != "today" {
t.Fatalf("GeneratedTextSchemaID = %q, want today", resolved.Definition.GeneratedTextSchemaID)
}
}
func TestTodayValidPeriodCanUseExplicitDate(t *testing.T) {
location := mustLoadLocation(t)
now := mustParse("2026-05-29T17:45:00-05:00")
date := mustParse("2026-05-31T12:00:00-05:00")
resolved, err := Resolve(Today, ResolveRequest{Now: now, Location: location, Date: date})
if err != nil {
t.Fatalf("Resolve() error = %v", err)
}
assertPeriod(t, resolved.ValidPeriod, "2026-05-31T00:00:00-05:00", "2026-06-01T00:00:00-05:00")
}
func TestTomorrowValidPeriodFromEveningGeneration(t *testing.T) {
location := mustLoadLocation(t)
now := mustParse("2026-05-29T20:00:00-05:00")
@@ -201,8 +236,8 @@ func TestMorningBatchSkipsWeekendOnSunday(t *testing.T) {
t.Fatalf("BatchReports() error = %v", err)
}
ids := resolvedIDs(resolved)
if strings.Join(ids, ",") != "daily_today,three_day" {
t.Fatalf("ids = %v, want daily_today and three_day", ids)
if strings.Join(ids, ",") != "today,three_day" {
t.Fatalf("ids = %v, want today and three_day", ids)
}
}
@@ -246,6 +281,7 @@ func TestIDForCommandName(t *testing.T) {
want ID
}{
{name: "daily", want: DailyToday},
{name: "today", want: Today},
{name: "tomorrow", want: Tomorrow},
{name: "hourly", want: Hourly},
{name: "three-day", want: ThreeDay},
@@ -263,9 +299,20 @@ func TestIDForCommandName(t *testing.T) {
}
})
}
if names := strings.Join(CommandNames(), ","); names != "daily,tomorrow,hourly,three-day,weekend,storm" {
if names := strings.Join(CommandNames(), ","); names != "daily,today,tomorrow,hourly,three-day,weekend,storm" {
t.Fatalf("CommandNames() = %s, want stable command names", names)
}
dailyID, err := IDForCommandName("daily")
if err != nil {
t.Fatalf("IDForCommandName(daily) error = %v", err)
}
todayID, err := IDForCommandName("today")
if err != nil {
t.Fatalf("IDForCommandName(today) error = %v", err)
}
if dailyID == todayID {
t.Fatalf("daily and today both resolve to %q, want distinct report IDs", dailyID)
}
if _, err := IDForCommandName("near-term"); err == nil || !strings.Contains(err.Error(), `unknown report command "near-term"`) {
t.Fatalf("IDForCommandName(near-term) error = %v, want unknown command", err)
}
@@ -278,6 +325,7 @@ func TestIDForConfigKey(t *testing.T) {
}{
{key: "daily", want: DailyToday},
{key: "daily_today", want: DailyToday},
{key: "today", want: Today},
{key: "tomorrow", want: Tomorrow},
{key: "hourly", want: Hourly},
{key: "three_day", want: ThreeDay},
@@ -303,6 +351,17 @@ func TestIDForConfigKey(t *testing.T) {
if _, err := IDForConfigKey("daily_tomorrow"); err == nil || !strings.Contains(err.Error(), `report config key "daily_tomorrow" is not a known report`) {
t.Fatalf("IDForConfigKey(daily_tomorrow) error = %v, want unknown key", err)
}
dailyID, err := IDForConfigKey("daily")
if err != nil {
t.Fatalf("IDForConfigKey(daily) error = %v", err)
}
todayID, err := IDForConfigKey("today")
if err != nil {
t.Fatalf("IDForConfigKey(today) error = %v", err)
}
if dailyID == todayID {
t.Fatalf("daily and today config keys both resolve to %q, want distinct report IDs", dailyID)
}
}
func TestBatchForCommandName(t *testing.T) {
@@ -342,7 +401,7 @@ func TestMorningBatchReportOrder(t *testing.T) {
t.Fatalf("BatchReports() error = %v", err)
}
ids := resolvedIDs(resolved)
if strings.Join(ids, ",") != "daily_today,three_day,weekend" {
if strings.Join(ids, ",") != "today,three_day,weekend" {
t.Fatalf("ids = %v, want morning report order", ids)
}
}
@@ -359,7 +418,7 @@ func TestRegistryLookupErrorIsActionable(t *testing.T) {
func TestRegistryAllIncludesHourlyInStableOrder(t *testing.T) {
ids := resolvedDefinitionIDs(DefaultRegistry().All())
want := []string{"daily_today", "tomorrow", "hourly", "three_day", "weekend", "storm"}
want := []string{"daily_today", "today", "tomorrow", "hourly", "three_day", "weekend", "storm"}
if strings.Join(ids, ",") != strings.Join(want, ",") {
t.Fatalf("All() ids = %#v, want %#v", ids, want)
}
@@ -384,7 +443,7 @@ func TestRegistryDefinitionsDeclareGenerationMetadata(t *testing.T) {
if !definition.Generated {
continue
}
if definition.ID == Hourly || definition.ID == Tomorrow {
if definition.ID == Hourly || definition.ID == Today || definition.ID == Tomorrow {
wantTemplate := string(definition.ID)
if definition.GenerationMode != GenerationModeGeneratedTextTemplate {
t.Fatalf("%s GenerationMode = %q, want %q", definition.ID, definition.GenerationMode, GenerationModeGeneratedTextTemplate)
@@ -426,6 +485,14 @@ func TestRegistryDefinitionsDeclarePathAndCompatibilityPolicy(t *testing.T) {
compatiblePriorIDs: []ID{DailyToday},
comparisonStrategy: CompareSameValidDate,
},
{
id: Today,
artifactGroup: "today",
batchOutputName: "today.md",
generated: true,
compatiblePriorIDs: []ID{Today},
comparisonStrategy: CompareSameValidDate,
},
{
id: Tomorrow,
artifactGroup: "tomorrow",
@@ -522,6 +589,25 @@ func TestRegistryDefinitionsDeclareDefaultModules(t *testing.T) {
module.HourlyForecast,
},
},
{
id: Today,
want: []module.ID{
module.Metadata,
module.CurrentConditions,
module.NarrativeForecast,
module.DerivedDailySummary,
module.DerivedDaypartSummaries,
module.PrecipTiming,
module.AlertDigest,
module.SPCConvectiveOutlooks,
module.AreaForecastDiscussion,
module.SPCConvectiveDiscussion,
module.WeatherStory,
module.OutdoorWindows,
module.HourlyForecast,
module.TodayPlanning,
},
},
{
id: Tomorrow,
want: []module.ID{