Consolidate generated text test ownership
This commit is contained in:
@@ -71,27 +71,6 @@ func TestBuildHourlyRenderContext(t *testing.T) {
|
||||
if ctx.Modules.WeatherStory == nil || ctx.Modules.WeatherStory.Title != "Morning storms" {
|
||||
t.Fatalf("Modules.WeatherStory = %#v, want story", ctx.Modules.WeatherStory)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("hourly", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
for _, want := range []string{
|
||||
"# Hourly Report",
|
||||
"**Updated:** Friday, May 29, 2026 at 8:30 AM",
|
||||
"Storm chances increase through late morning.",
|
||||
"- **10:00 AM:** 75°F and showers. Probability of precipitation is 70%.",
|
||||
"- **Flood Watch**: Flood Watch in effect from May 29 at 10:00 AM to May 29 at 2:30 PM.",
|
||||
"A cold front is moving into the region.",
|
||||
"A front will keep the region unsettled.",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("rendered template missing %q:\n%s", want, text)
|
||||
}
|
||||
}
|
||||
if strings.Contains(text, "Avoid low-water crossings.") {
|
||||
t.Fatalf("rendered template includes alert instruction:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildHourlyRenderContextAllowsOmittedOptionalModules(t *testing.T) {
|
||||
@@ -268,40 +247,6 @@ func TestBuildTodayRenderContext(t *testing.T) {
|
||||
if ctx.Modules.TodayPlanning.MorningReadiness[0] != "Take sunglasses early." {
|
||||
t.Fatalf("Modules.TodayPlanning = %#v, want today planning facts", ctx.Modules.TodayPlanning)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("today", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
for _, want := range []string{
|
||||
"# Today's Weather",
|
||||
"**Forecast date:** Monday, June 15, 2026",
|
||||
"Today starts quiet, then showers become more likely later in the day.",
|
||||
"Currently, it is 58°F and clear. It feels like 57°F, with a relative humidity of 61% and winds from the northwest at 9 mph.",
|
||||
"- **Morning:** Partly cloudy, with temperatures in the low 60s.",
|
||||
"- **Afternoon:** Showers, with temperatures in the mid 70s. Chance of precipitation is 70%.",
|
||||
"## Precipitation Timing",
|
||||
"- **3:00 PM** to **6:00 PM**: Expect showers. The peak precipitation chance is 70% at 3:00 PM.",
|
||||
"The most likely rain window is from midafternoon into early evening.",
|
||||
"Morning conditions should stay mostly dry.",
|
||||
"Rain chances increase during the afternoon as deeper moisture arrives.",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("rendered template missing %q:\n%s", want, text)
|
||||
}
|
||||
}
|
||||
assertOrderedText(t, text, []string{
|
||||
"# Today's Weather",
|
||||
"## Current Conditions",
|
||||
"## Daypart Forecast",
|
||||
"- **Morning:**",
|
||||
"- **Afternoon:**",
|
||||
"## Precipitation Timing",
|
||||
"## Forecast Discussion",
|
||||
})
|
||||
if strings.Contains(text, "## Planning Notes") || strings.Contains(text, "- Take sunglasses early.") || strings.Contains(text, "Forecast details are limited") {
|
||||
t.Fatalf("rendered template included removed Today template content:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTodayRenderContextPreservesUnicodeDaypartDisplayNames(t *testing.T) {
|
||||
@@ -324,12 +269,8 @@ func TestTodayRenderContextPreservesUnicodeDaypartDisplayNames(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("BuildTodayRenderContext() error = %v", err)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("today", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
if !strings.Contains(string(rendered), "Mañana") {
|
||||
t.Fatalf("rendered report = %q, want Unicode daypart display name", rendered)
|
||||
if len(ctx.Modules.Dayparts) == 0 || ctx.Modules.Dayparts[0].Summary.DisplayName != "Mañana" {
|
||||
t.Fatalf("dayparts = %#v, want Unicode daypart display name", ctx.Modules.Dayparts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,19 +292,6 @@ func TestBuildTodayRenderContextAllowsOmittedOptionalModules(t *testing.T) {
|
||||
if ctx.Modules.HasDaypartDetails {
|
||||
t.Fatal("Modules.HasDaypartDetails = true, want no displayable dayparts")
|
||||
}
|
||||
rendered, err := reporttemplate.Render("today", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
for _, unwanted := range []string{"## Current Conditions", "## Precipitation Timing", "## Planning Notes", "Forecast details are limited"} {
|
||||
if strings.Contains(text, unwanted) {
|
||||
t.Fatalf("rendered template included %q without module data:\n%s", unwanted, text)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(text, "- No daypart forecast details are available.") {
|
||||
t.Fatalf("rendered template missing daypart fallback:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDayStyleRenderContextsPopulateSharedFieldsAndPlanningModules(t *testing.T) {
|
||||
@@ -593,42 +521,10 @@ func TestBuildDailyRenderContext(t *testing.T) {
|
||||
if ctx.Modules.DailyPlanning.MorningReadiness[0] != "Take sunglasses early." {
|
||||
t.Fatalf("Modules.DailyPlanning = %#v, want daily planning facts", ctx.Modules.DailyPlanning)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("daily", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
for _, want := range []string{
|
||||
"# Monday's Weather",
|
||||
"**Forecast date:** Monday, June 15, 2026",
|
||||
"**Updated:** Saturday, June 13, 2026 at 9:14 AM",
|
||||
"The selected day starts quiet, then showers become more likely later in the day.",
|
||||
"- **Morning:** Partly cloudy, with temperatures in the low 60s.",
|
||||
"- **Afternoon:** Showers, with temperatures in the mid 70s. Chance of precipitation is 70%.",
|
||||
"- **Evening:** Mostly cloudy, with temperatures in the upper 60s.",
|
||||
"## Precipitation Timing",
|
||||
"- **3:00 PM** to **6:00 PM**: Expect showers. The peak precipitation chance is 70% at 3:00 PM.",
|
||||
"The most likely rain window is from midafternoon into early evening.",
|
||||
"Morning conditions should stay mostly dry.",
|
||||
"Rain chances increase during the afternoon as deeper moisture arrives.",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("rendered template missing %q:\n%s", want, text)
|
||||
}
|
||||
}
|
||||
assertOrderedText(t, text, []string{
|
||||
"# Monday's Weather",
|
||||
"## Daypart Forecast",
|
||||
"- **Morning:**",
|
||||
"- **Afternoon:**",
|
||||
"- **Evening:**",
|
||||
"## Precipitation Timing",
|
||||
"## Forecast Discussion",
|
||||
})
|
||||
}
|
||||
|
||||
func TestValidatedGeneratedTextRendersAsPlainText(t *testing.T) {
|
||||
generated, err := ValidateDaily([]byte("{\"summary\":\"Summary.\\n## Fabricated Alert\\n- Fabricated warning\",\"forecast_discussion\":[\"Discussion with [unsafe](javascript:alert(1))\"],\"precipitation_timing\":\"Timing.\\n```not code```\"}"))
|
||||
func TestValidatedGeneratedTextBuildsAndRendersTypedContext(t *testing.T) {
|
||||
generated, err := ValidateDaily([]byte(`{"summary":"Daily summary.","forecast_discussion":["Daily discussion."],"precipitation_timing":"Late-day showers."}`))
|
||||
if err != nil {
|
||||
t.Fatalf("ValidateDaily() error = %v", err)
|
||||
}
|
||||
@@ -640,19 +536,9 @@ func TestValidatedGeneratedTextRendersAsPlainText(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
for _, want := range []string{
|
||||
"Summary.\n\\## Fabricated Alert\n\\- Fabricated warning",
|
||||
"Discussion with \\[unsafe\\]\\(javascript:alert\\(1\\)\\)",
|
||||
"Timing.\n\\`\\`\\`not code\\`\\`\\`",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("rendered report missing escaped generated prose %q:\n%s", want, text)
|
||||
}
|
||||
}
|
||||
for _, unwanted := range []string{"\n## Fabricated Alert", "\n- Fabricated warning", "[unsafe](javascript:alert(1))", "```not code```"} {
|
||||
if strings.Contains(text, unwanted) {
|
||||
t.Fatalf("rendered report preserved generated Markdown structure %q:\n%s", unwanted, text)
|
||||
for _, want := range []string{"# Monday's Weather", "Daily summary.", "Daily discussion.", "Late-day showers."} {
|
||||
if !strings.Contains(string(rendered), want) {
|
||||
t.Fatalf("rendered report missing %q:\n%s", want, rendered)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -672,17 +558,6 @@ func TestBuildDailyRenderContextAllowsOmittedOptionalModules(t *testing.T) {
|
||||
if ctx.Modules.CurrentConditions != nil || ctx.Modules.PrecipTiming != nil || ctx.Modules.OutdoorWindows != nil || ctx.Modules.DailyPlanning != nil || len(ctx.Modules.Dayparts) != 0 {
|
||||
t.Fatalf("Modules = %#v, want omitted optional modules", ctx.Modules)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("daily", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
if strings.Contains(text, "## Precipitation Timing") {
|
||||
t.Fatalf("rendered template included precipitation section without windows:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "- No daypart forecast details are available.") {
|
||||
t.Fatalf("rendered template missing daypart fallback:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildTomorrowRenderContext(t *testing.T) {
|
||||
@@ -735,35 +610,6 @@ func TestBuildTomorrowRenderContext(t *testing.T) {
|
||||
if ctx.Modules.AlertDigest == nil || ctx.Modules.SPCConvectiveOutlooks == nil || ctx.Modules.AreaForecastDiscussion == nil || ctx.Modules.SPCConvectiveDiscussion == nil || ctx.Modules.WeatherStory == nil || ctx.Modules.TomorrowPlanning == nil {
|
||||
t.Fatalf("optional modules missing from render context: %#v", ctx.Modules)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("tomorrow", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
for _, want := range []string{
|
||||
"# Monday's Weather",
|
||||
"**Forecast date:** Monday, June 15, 2026",
|
||||
"Tomorrow starts quiet, then showers become more likely later in the day.",
|
||||
"- **Morning:** Partly cloudy, with temperatures in the low 60s.",
|
||||
"- **Afternoon:** Showers, with temperatures in the mid 70s. Chance of precipitation is 70%.",
|
||||
"## Precipitation Timing",
|
||||
"- **3:00 PM** to **6:00 PM**: Expect showers. The peak precipitation chance is 70% at 3:00 PM.",
|
||||
"The most likely rain window is from midafternoon into early evening.",
|
||||
"Morning conditions should stay mostly dry.",
|
||||
"Rain chances increase during the afternoon as deeper moisture arrives.",
|
||||
} {
|
||||
if !strings.Contains(text, want) {
|
||||
t.Fatalf("rendered template missing %q:\n%s", want, text)
|
||||
}
|
||||
}
|
||||
assertOrderedText(t, text, []string{
|
||||
"# Monday's Weather",
|
||||
"## Daypart Forecast",
|
||||
"- **Morning:**",
|
||||
"- **Afternoon:**",
|
||||
"## Precipitation Timing",
|
||||
"## Forecast Discussion",
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuildTomorrowRenderContextAllowsOmittedOptionalModules(t *testing.T) {
|
||||
@@ -781,17 +627,6 @@ func TestBuildTomorrowRenderContextAllowsOmittedOptionalModules(t *testing.T) {
|
||||
if ctx.Modules.CurrentConditions != nil || ctx.Modules.PrecipTiming != nil || len(ctx.Modules.Dayparts) != 0 {
|
||||
t.Fatalf("Modules = %#v, want omitted optional modules", ctx.Modules)
|
||||
}
|
||||
rendered, err := reporttemplate.Render("tomorrow", ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Render() error = %v", err)
|
||||
}
|
||||
text := string(rendered)
|
||||
if strings.Contains(text, "## Precipitation Timing") {
|
||||
t.Fatalf("rendered template included precipitation section without windows:\n%s", text)
|
||||
}
|
||||
if !strings.Contains(text, "- No daypart forecast details are available.") {
|
||||
t.Fatalf("rendered template missing daypart fallback:\n%s", text)
|
||||
}
|
||||
}
|
||||
|
||||
func testMetadata() briefing.PreparedIdentity {
|
||||
@@ -1461,18 +1296,3 @@ func floatPtr(value float64) *float64 {
|
||||
func intPtr(value int) *int {
|
||||
return &value
|
||||
}
|
||||
|
||||
func assertOrderedText(t *testing.T, text string, ordered []string) {
|
||||
t.Helper()
|
||||
previousIndex := -1
|
||||
for _, want := range ordered {
|
||||
index := strings.Index(text, want)
|
||||
if index < 0 {
|
||||
t.Fatalf("text missing %q:\n%s", want, text)
|
||||
}
|
||||
if index <= previousIndex {
|
||||
t.Fatalf("%q appears out of order in:\n%s", want, text)
|
||||
}
|
||||
previousIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user