Retire dormant prompt compatibility APIs

This commit is contained in:
2026-08-13 04:10:45 +00:00
parent 17468cb8dd
commit 7884b9a6c3
20 changed files with 89 additions and 314 deletions

View File

@@ -23,7 +23,7 @@ const (
templateIDTomorrow = "tomorrow"
)
type validator func([]byte) (any, []byte, error)
type validator func([]byte) (any, error)
type renderContextBuilder func(report.ID, string, briefing.PreparedIdentity, module.Snapshot, facts.DerivedFacts, any) (any, error)
@@ -133,9 +133,9 @@ func (h Handler) Template() (string, error) {
return source, nil
}
func (h Handler) Validate(data []byte) (any, []byte, error) {
func (h Handler) Validate(data []byte) (any, error) {
if h.validate == nil {
return nil, nil, fmt.Errorf("generated text validator is not registered for schema %q on report %q", h.schemaID, h.reportID)
return nil, fmt.Errorf("generated text validator is not registered for schema %q on report %q", h.schemaID, h.reportID)
}
return h.validate(data)
}
@@ -155,19 +155,19 @@ func (h Handler) Render(data any) ([]byte, error) {
return rendered, nil
}
func validateHourly(data []byte) (any, []byte, error) {
func validateHourly(data []byte) (any, error) {
return ValidateHourly(data)
}
func validateDaily(data []byte) (any, []byte, error) {
func validateDaily(data []byte) (any, error) {
return ValidateDaily(data)
}
func validateToday(data []byte) (any, []byte, error) {
func validateToday(data []byte) (any, error) {
return ValidateToday(data)
}
func validateTomorrow(data []byte) (any, []byte, error) {
func validateTomorrow(data []byte) (any, error) {
return ValidateTomorrow(data)
}

View File

@@ -189,7 +189,7 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if err != nil {
t.Fatalf("LookupDefinition(hourly) error = %v", err)
}
hourly, normalized, err := hourlyHandler.Validate([]byte(`{
hourly, err := hourlyHandler.Validate([]byte(`{
"summary": " Storm chances increase. ",
"forecast_discussion": " A front will keep the region unsettled. ",
"precipitation_timing": ""
@@ -200,15 +200,15 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if _, ok := hourly.(Hourly); !ok {
t.Fatalf("hourly generated text type = %T, want generatedtext.Hourly", hourly)
}
if !strings.Contains(string(normalized), `"summary":"Storm chances increase."`) {
t.Fatalf("hourly normalized text = %s, want trimmed summary", normalized)
if hourly.(Hourly).Summary != "Storm chances increase." {
t.Fatalf("hourly summary = %q, want trimmed summary", hourly.(Hourly).Summary)
}
tomorrowHandler, err := LookupDefinition(report.DefaultRegistry().MustLookup(report.Tomorrow))
if err != nil {
t.Fatalf("LookupDefinition(tomorrow) error = %v", err)
}
tomorrow, normalized, err := tomorrowHandler.Validate([]byte(`{
tomorrow, err := tomorrowHandler.Validate([]byte(`{
"summary": " Storms become more likely tomorrow. ",
"forecast_discussion": [" A front will keep showers in the forecast. ", ""],
"precipitation_timing": ""
@@ -219,8 +219,8 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if _, ok := tomorrow.(Tomorrow); !ok {
t.Fatalf("tomorrow generated text type = %T, want generatedtext.Tomorrow", tomorrow)
}
if !strings.Contains(string(normalized), `"forecast_discussion":["A front will keep showers in the forecast."]`) {
t.Fatalf("tomorrow normalized text = %s, want trimmed discussion paragraph", normalized)
if tomorrow.(Tomorrow).ForecastDiscussion[0] != "A front will keep showers in the forecast." {
t.Fatalf("tomorrow discussion = %#v, want trimmed paragraph", tomorrow.(Tomorrow).ForecastDiscussion)
}
todayHandler, err := LookupDefinition(report.Definition{
@@ -231,7 +231,7 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if err != nil {
t.Fatalf("LookupDefinition(today) error = %v", err)
}
today, normalized, err := todayHandler.Validate([]byte(`{
today, err := todayHandler.Validate([]byte(`{
"summary": " Showers are likely today. ",
"forecast_discussion": [" A front will keep rain chances elevated. ", ""],
"precipitation_timing": ""
@@ -242,8 +242,8 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if _, ok := today.(Today); !ok {
t.Fatalf("today generated text type = %T, want generatedtext.Today", today)
}
if !strings.Contains(string(normalized), `"forecast_discussion":["A front will keep rain chances elevated."]`) {
t.Fatalf("today normalized text = %s, want trimmed discussion paragraph", normalized)
if today.(Today).ForecastDiscussion[0] != "A front will keep rain chances elevated." {
t.Fatalf("today discussion = %#v, want trimmed paragraph", today.(Today).ForecastDiscussion)
}
dailyHandler, err := LookupDefinition(report.Definition{
@@ -254,7 +254,7 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if err != nil {
t.Fatalf("LookupDefinition(daily) error = %v", err)
}
daily, normalized, err := dailyHandler.Validate([]byte(`{
daily, err := dailyHandler.Validate([]byte(`{
"summary": " Showers are possible during the selected day. ",
"forecast_discussion": [" A front will keep rain chances in the forecast. ", ""],
"precipitation_timing": ""
@@ -265,8 +265,8 @@ func TestCatalogValidationDispatchSupportsKnownSchemas(t *testing.T) {
if _, ok := daily.(Daily); !ok {
t.Fatalf("daily generated text type = %T, want generatedtext.Daily", daily)
}
if !strings.Contains(string(normalized), `"forecast_discussion":["A front will keep rain chances in the forecast."]`) {
t.Fatalf("daily normalized text = %s, want trimmed discussion paragraph", normalized)
if daily.(Daily).ForecastDiscussion[0] != "A front will keep rain chances in the forecast." {
t.Fatalf("daily discussion = %#v, want trimmed paragraph", daily.(Daily).ForecastDiscussion)
}
}

View File

@@ -6,7 +6,7 @@ type Daily struct {
PrecipitationTiming string `json:"precipitation_timing"`
}
func ValidateDaily(data []byte) (Daily, []byte, error) {
func ValidateDaily(data []byte) (Daily, error) {
return validateDayStyleGeneratedText[Daily, *Daily](data, "daily")
}

View File

@@ -5,8 +5,8 @@ import (
"testing"
)
func TestValidateDailyNormalizesJSON(t *testing.T) {
value, normalized, err := ValidateDaily([]byte(`{
func TestValidateDailyNormalizesFields(t *testing.T) {
value, err := ValidateDaily([]byte(`{
"summary": " Showers are possible during the selected day. ",
"forecast_discussion": [
" A front will keep rain chances in the forecast. ",
@@ -27,14 +27,10 @@ func TestValidateDailyNormalizesJSON(t *testing.T) {
if value.PrecipitationTiming != "Rain is most likely during the afternoon." {
t.Fatalf("PrecipitationTiming = %q, want trimmed precipitation timing", value.PrecipitationTiming)
}
want := `{"summary":"Showers are possible during the selected day.","forecast_discussion":["A front will keep rain chances in the forecast.","Temperatures stay seasonable by afternoon."],"precipitation_timing":"Rain is most likely during the afternoon."}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
}
}
func TestValidateDailyPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
_, normalized, err := ValidateDaily([]byte(`{
value, err := ValidateDaily([]byte(`{
"summary": "Showers are possible during the selected day.",
"forecast_discussion": ["A front will keep rain chances in the forecast."],
"precipitation_timing": " "
@@ -42,9 +38,8 @@ func TestValidateDailyPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
if err != nil {
t.Fatalf("ValidateDaily() error = %v", err)
}
want := `{"summary":"Showers are possible during the selected day.","forecast_discussion":["A front will keep rain chances in the forecast."],"precipitation_timing":""}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
if value.PrecipitationTiming != "" {
t.Fatalf("PrecipitationTiming = %q, want required empty value", value.PrecipitationTiming)
}
}
@@ -97,7 +92,7 @@ func TestValidateDailyRejectsInvalidInput(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, _, err := ValidateDaily([]byte(test.in))
_, err := ValidateDaily([]byte(test.in))
if err == nil {
t.Fatal("ValidateDaily() error = nil, want error")
}

View File

@@ -19,11 +19,11 @@ type dayStyleGeneratedText interface {
func validateDayStyleGeneratedText[T any, PT interface {
*T
dayStyleGeneratedText
}](data []byte, name string) (T, []byte, error) {
}](data []byte, name string) (T, error) {
value, err := decodeGeneratedText[T](data, name)
if err != nil {
var zero T
return zero, nil, err
return zero, err
}
pointer := PT(&value)
@@ -33,24 +33,18 @@ func validateDayStyleGeneratedText[T any, PT interface {
fields.ForecastDiscussion = trimNonEmpty(fields.ForecastDiscussion)
if fields.Summary == "" {
var zero T
return zero, nil, fmt.Errorf("%s generated text summary is required", name)
return zero, fmt.Errorf("%s generated text summary is required", name)
}
if len(fields.ForecastDiscussion) == 0 {
var zero T
return zero, nil, fmt.Errorf("%s generated text forecast discussion is required", name)
return zero, fmt.Errorf("%s generated text forecast discussion is required", name)
}
if err := requireGeneratedTextStringField(data, name, "precipitation_timing"); err != nil {
var zero T
return zero, nil, err
return zero, err
}
pointer.setDayStyleFields(fields)
normalized, err := normalizeGeneratedText(value, name)
if err != nil {
var zero T
return zero, nil, err
}
return value, normalized, nil
return value, nil
}
func trimNonEmpty(values []string) []string {

View File

@@ -9,27 +9,27 @@ import (
func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
reports := []struct {
name string
validate func([]byte) (any, []byte, error)
validate func([]byte) (any, error)
}{
{
name: "daily",
validate: func(data []byte) (any, []byte, error) {
value, normalized, err := ValidateDaily(data)
return value, normalized, err
validate: func(data []byte) (any, error) {
value, err := ValidateDaily(data)
return value, err
},
},
{
name: "today",
validate: func(data []byte) (any, []byte, error) {
value, normalized, err := ValidateToday(data)
return value, normalized, err
validate: func(data []byte) (any, error) {
value, err := ValidateToday(data)
return value, err
},
},
{
name: "tomorrow",
validate: func(data []byte) (any, []byte, error) {
value, normalized, err := ValidateTomorrow(data)
return value, normalized, err
validate: func(data []byte) (any, error) {
value, err := ValidateTomorrow(data)
return value, err
},
},
}
@@ -37,7 +37,7 @@ func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
for _, report := range reports {
t.Run(report.name, func(t *testing.T) {
t.Run("requires summary", func(t *testing.T) {
_, _, err := report.validate([]byte(`{"forecast_discussion":["First paragraph."]}`))
_, err := report.validate([]byte(`{"forecast_discussion":["First paragraph."]}`))
want := fmt.Sprintf("%s generated text summary is required", report.name)
if err == nil || err.Error() != want {
t.Fatalf("validate() error = %v, want %q", err, want)
@@ -45,15 +45,15 @@ func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
})
t.Run("requires non-empty forecast discussion", func(t *testing.T) {
_, _, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":[" ",""]}`))
_, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":[" ",""]}`))
want := fmt.Sprintf("%s generated text forecast discussion is required", report.name)
if err == nil || err.Error() != want {
t.Fatalf("validate() error = %v, want %q", err, want)
}
})
t.Run("trims and normalizes", func(t *testing.T) {
value, normalized, err := report.validate([]byte(`{
t.Run("normalizes fields", func(t *testing.T) {
value, err := report.validate([]byte(`{
"summary": " Shared summary. ",
"forecast_discussion": [
" First paragraph. ",
@@ -75,14 +75,10 @@ func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
if fields.PrecipitationTiming != "Afternoon." {
t.Fatalf("PrecipitationTiming = %q, want trimmed precipitation timing", fields.PrecipitationTiming)
}
want := `{"summary":"Shared summary.","forecast_discussion":["First paragraph.","Second paragraph."],"precipitation_timing":"Afternoon."}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
}
})
t.Run("preserves required empty precipitation timing", func(t *testing.T) {
_, normalized, err := report.validate([]byte(`{
value, err := report.validate([]byte(`{
"summary": "Shared summary.",
"forecast_discussion": ["First paragraph."],
"precipitation_timing": " "
@@ -90,14 +86,13 @@ func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
if err != nil {
t.Fatalf("validate() error = %v", err)
}
want := `{"summary":"Shared summary.","forecast_discussion":["First paragraph."],"precipitation_timing":""}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
if fields := dayStyleFieldsForTest(t, value); fields.PrecipitationTiming != "" {
t.Fatalf("PrecipitationTiming = %q, want required empty value", fields.PrecipitationTiming)
}
})
t.Run("requires precipitation timing field", func(t *testing.T) {
_, _, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":["First paragraph."]}`))
_, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":["First paragraph."]}`))
want := fmt.Sprintf("%s generated text precipitation timing is required", report.name)
if err == nil || err.Error() != want {
t.Fatalf("validate() error = %v, want %q", err, want)
@@ -105,7 +100,7 @@ func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
})
t.Run("rejects unknown fields", func(t *testing.T) {
_, _, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":["First paragraph."],"extra":"value"}`))
_, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":["First paragraph."],"extra":"value"}`))
if err == nil {
t.Fatal("validate() error = nil, want error")
}
@@ -115,7 +110,7 @@ func TestValidateDayStyleGeneratedTextSharedBehavior(t *testing.T) {
})
t.Run("rejects retired confidence field", func(t *testing.T) {
_, _, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":["First paragraph."],"precipitation_timing":"","confidence":"Medium"}`))
_, err := report.validate([]byte(`{"summary":"Shared summary.","forecast_discussion":["First paragraph."],"precipitation_timing":"","confidence":"Medium"}`))
if err == nil || !strings.Contains(err.Error(), "unsupported field") {
t.Fatalf("validate() error = %v, want retired confidence field rejection", err)
}

View File

@@ -12,28 +12,23 @@ type Hourly struct {
PrecipitationTiming string `json:"precipitation_timing"`
}
func ValidateHourly(data []byte) (Hourly, []byte, error) {
func ValidateHourly(data []byte) (Hourly, error) {
value, err := decodeGeneratedText[Hourly](data, "hourly")
if err != nil {
return Hourly{}, nil, err
return Hourly{}, err
}
value.Summary = strings.TrimSpace(value.Summary)
value.ForecastDiscussion = strings.TrimSpace(value.ForecastDiscussion)
value.PrecipitationTiming = strings.TrimSpace(value.PrecipitationTiming)
if value.Summary == "" {
return Hourly{}, nil, fmt.Errorf("hourly generated text summary is required")
return Hourly{}, fmt.Errorf("hourly generated text summary is required")
}
if value.ForecastDiscussion == "" {
return Hourly{}, nil, fmt.Errorf("hourly generated text forecast discussion is required")
return Hourly{}, fmt.Errorf("hourly generated text forecast discussion is required")
}
if err := requireGeneratedTextStringField(data, "hourly", "precipitation_timing"); err != nil {
return Hourly{}, nil, err
return Hourly{}, err
}
normalized, err := normalizeGeneratedText(value, "hourly")
if err != nil {
return Hourly{}, nil, err
}
return value, normalized, nil
return value, nil
}

View File

@@ -5,8 +5,8 @@ import (
"testing"
)
func TestValidateHourlyNormalizesJSON(t *testing.T) {
value, normalized, err := ValidateHourly([]byte(`{
func TestValidateHourlyNormalizesFields(t *testing.T) {
value, err := ValidateHourly([]byte(`{
"summary": " Storm chances increase. ",
"forecast_discussion": " A front will keep the region unsettled. ",
"precipitation_timing": " Showers are most likely early this afternoon. "
@@ -23,14 +23,10 @@ func TestValidateHourlyNormalizesJSON(t *testing.T) {
if value.PrecipitationTiming != "Showers are most likely early this afternoon." {
t.Fatalf("PrecipitationTiming = %q, want trimmed precipitation timing", value.PrecipitationTiming)
}
want := `{"summary":"Storm chances increase.","forecast_discussion":"A front will keep the region unsettled.","precipitation_timing":"Showers are most likely early this afternoon."}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
}
}
func TestValidateHourlyPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
_, normalized, err := ValidateHourly([]byte(`{
value, err := ValidateHourly([]byte(`{
"summary": "Storm chances increase.",
"forecast_discussion": "A front will keep the region unsettled.",
"precipitation_timing": " "
@@ -38,9 +34,8 @@ func TestValidateHourlyPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
if err != nil {
t.Fatalf("ValidateHourly() error = %v", err)
}
want := `{"summary":"Storm chances increase.","forecast_discussion":"A front will keep the region unsettled.","precipitation_timing":""}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
if value.PrecipitationTiming != "" {
t.Fatalf("PrecipitationTiming = %q, want required empty value", value.PrecipitationTiming)
}
}
@@ -103,7 +98,7 @@ func TestValidateHourlyRejectsInvalidInput(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, _, err := ValidateHourly([]byte(test.in))
_, err := ValidateHourly([]byte(test.in))
if err == nil {
t.Fatal("ValidateHourly() error = nil, want error")
}

View File

@@ -89,11 +89,3 @@ func requireGeneratedTextStringField(data []byte, name, field string) error {
}
return nil
}
func normalizeGeneratedText[T any](value T, name string) ([]byte, error) {
normalized, err := json.Marshal(value)
if err != nil {
return nil, fmt.Errorf("normalize %s generated text: %w", name, err)
}
return normalized, nil
}

View File

@@ -160,21 +160,21 @@ func generatedTextSchema(t *testing.T, id string) *jsonschema.Schema {
}
func validateDailyJSON(data []byte) error {
_, _, err := ValidateDaily(data)
_, err := ValidateDaily(data)
return err
}
func validateTodayJSON(data []byte) error {
_, _, err := ValidateToday(data)
_, err := ValidateToday(data)
return err
}
func validateTomorrowJSON(data []byte) error {
_, _, err := ValidateTomorrow(data)
_, err := ValidateTomorrow(data)
return err
}
func validateHourlyJSON(data []byte) error {
_, _, err := ValidateHourly(data)
_, err := ValidateHourly(data)
return err
}

View File

@@ -628,7 +628,7 @@ func TestBuildDailyRenderContext(t *testing.T) {
}
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```\"}"))
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```\"}"))
if err != nil {
t.Fatalf("ValidateDaily() error = %v", err)
}

View File

@@ -6,7 +6,7 @@ type Today struct {
PrecipitationTiming string `json:"precipitation_timing"`
}
func ValidateToday(data []byte) (Today, []byte, error) {
func ValidateToday(data []byte) (Today, error) {
return validateDayStyleGeneratedText[Today, *Today](data, "today")
}

View File

@@ -5,8 +5,8 @@ import (
"testing"
)
func TestValidateTodayNormalizesJSON(t *testing.T) {
value, normalized, err := ValidateToday([]byte(`{
func TestValidateTodayNormalizesFields(t *testing.T) {
value, err := ValidateToday([]byte(`{
"summary": " Showers are likely today. ",
"forecast_discussion": [
" A front will keep rain chances elevated. ",
@@ -27,14 +27,10 @@ func TestValidateTodayNormalizesJSON(t *testing.T) {
if value.PrecipitationTiming != "Rain is most likely during the afternoon." {
t.Fatalf("PrecipitationTiming = %q, want trimmed precipitation timing", value.PrecipitationTiming)
}
want := `{"summary":"Showers are likely today.","forecast_discussion":["A front will keep rain chances elevated.","Temperatures stay mild through the afternoon."],"precipitation_timing":"Rain is most likely during the afternoon."}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
}
}
func TestValidateTodayPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
_, normalized, err := ValidateToday([]byte(`{
value, err := ValidateToday([]byte(`{
"summary": "Showers are likely today.",
"forecast_discussion": ["A front will keep rain chances elevated."],
"precipitation_timing": " "
@@ -42,9 +38,8 @@ func TestValidateTodayPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
if err != nil {
t.Fatalf("ValidateToday() error = %v", err)
}
want := `{"summary":"Showers are likely today.","forecast_discussion":["A front will keep rain chances elevated."],"precipitation_timing":""}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
if value.PrecipitationTiming != "" {
t.Fatalf("PrecipitationTiming = %q, want required empty value", value.PrecipitationTiming)
}
}
@@ -97,7 +92,7 @@ func TestValidateTodayRejectsInvalidInput(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, _, err := ValidateToday([]byte(test.in))
_, err := ValidateToday([]byte(test.in))
if err == nil {
t.Fatal("ValidateToday() error = nil, want error")
}

View File

@@ -6,7 +6,7 @@ type Tomorrow struct {
PrecipitationTiming string `json:"precipitation_timing"`
}
func ValidateTomorrow(data []byte) (Tomorrow, []byte, error) {
func ValidateTomorrow(data []byte) (Tomorrow, error) {
return validateDayStyleGeneratedText[Tomorrow, *Tomorrow](data, "tomorrow")
}

View File

@@ -5,8 +5,8 @@ import (
"testing"
)
func TestValidateTomorrowNormalizesJSON(t *testing.T) {
value, normalized, err := ValidateTomorrow([]byte(`{
func TestValidateTomorrowNormalizesFields(t *testing.T) {
value, err := ValidateTomorrow([]byte(`{
"summary": " Storms become more likely tomorrow. ",
"forecast_discussion": [
" A front will keep showers in the forecast. ",
@@ -27,14 +27,10 @@ func TestValidateTomorrowNormalizesJSON(t *testing.T) {
if value.PrecipitationTiming != "Rain is most likely before sunrise." {
t.Fatalf("PrecipitationTiming = %q, want trimmed precipitation timing", value.PrecipitationTiming)
}
want := `{"summary":"Storms become more likely tomorrow.","forecast_discussion":["A front will keep showers in the forecast.","Temperatures stay seasonable by afternoon."],"precipitation_timing":"Rain is most likely before sunrise."}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
}
}
func TestValidateTomorrowPreservesRequiredEmptyPrecipitationTiming(t *testing.T) {
_, normalized, err := ValidateTomorrow([]byte(`{
value, err := ValidateTomorrow([]byte(`{
"summary": "Storms become more likely tomorrow.",
"forecast_discussion": ["A front will keep showers in the forecast."],
"precipitation_timing": " "
@@ -42,9 +38,8 @@ func TestValidateTomorrowPreservesRequiredEmptyPrecipitationTiming(t *testing.T)
if err != nil {
t.Fatalf("ValidateTomorrow() error = %v", err)
}
want := `{"summary":"Storms become more likely tomorrow.","forecast_discussion":["A front will keep showers in the forecast."],"precipitation_timing":""}`
if string(normalized) != want {
t.Fatalf("normalized = %s, want %s", normalized, want)
if value.PrecipitationTiming != "" {
t.Fatalf("PrecipitationTiming = %q, want required empty value", value.PrecipitationTiming)
}
}
@@ -97,7 +92,7 @@ func TestValidateTomorrowRejectsInvalidInput(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, _, err := ValidateTomorrow([]byte(test.in))
_, err := ValidateTomorrow([]byte(test.in))
if err == nil {
t.Fatal("ValidateTomorrow() error = nil, want error")
}