Fixed releases with 1e9999 ("no limit") being skipped as unreadable
This commit is contained in:
1 parent
79efcb5e91
commit
4db268550b
2 files changed
+157
-49
No files matched your search
@@ -8,6 +8,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@@ -763,7 +764,7 @@ func TestFetchAllRepeatedNextLink(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalLenientDates(t *testing.T) {
|
||||
func TestUnmarshalLenient(t *testing.T) {
|
||||
raw := json.RawMessage(`{
|
||||
"date": "2006-10-02",
|
||||
"publishedDate": "",
|
||||
@@ -793,7 +794,7 @@ func TestUnmarshalLenientDates(t *testing.T) {
|
||||
} `json:"awards"`
|
||||
Value json.Number `json:"value"`
|
||||
}
|
||||
if err := unmarshalLenientDates(raw, &got); err != nil {
|
||||
if err := unmarshalLenient(raw, &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -833,9 +834,77 @@ func TestUnmarshalLenientDates(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepairDatesLeavesValidJSONAlone(t *testing.T) {
|
||||
func TestUnmarshalLenientNumbers(t *testing.T) {
|
||||
tests := []struct {
|
||||
raw string
|
||||
wantInt int64
|
||||
wantFloat float64
|
||||
}{
|
||||
{`1e9999`, math.MaxInt64, math.MaxInt64},
|
||||
{`-1e9999`, math.MinInt64, math.MinInt64},
|
||||
{`1E+400`, math.MaxInt64, math.MaxInt64},
|
||||
{`3`, 3, 3},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.raw, func(t *testing.T) {
|
||||
var got struct {
|
||||
Int *int64 `json:"int"`
|
||||
Float *float64 `json:"float"`
|
||||
}
|
||||
raw := json.RawMessage(
|
||||
`{"int": ` + tc.raw + `, "float": ` + tc.raw + `}`,
|
||||
)
|
||||
if err := unmarshalLenient(raw, &got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if *got.Int != tc.wantInt {
|
||||
t.Errorf("int = %d; want %d", *got.Int, tc.wantInt)
|
||||
}
|
||||
if *got.Float != tc.wantFloat {
|
||||
t.Errorf("float = %v; want %v", *got.Float, tc.wantFloat)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestUnmarshalLenientNoLimit decodes OCDS's 1e9999 ("no limit") into the
|
||||
// release fields Find a Tender sends it in, and checks the release can still
|
||||
// be marshalled, as Convert does to store its JSON.
|
||||
func TestUnmarshalLenientNoLimit(t *testing.T) {
|
||||
raw := json.RawMessage(`{
|
||||
"ocid": "ocds-1",
|
||||
"id": "r1",
|
||||
"date": "2026-10-16T15:52:30+01:00",
|
||||
"tender": {
|
||||
"lotDetails": {"maximumLotsBidPerSupplier": 1e9999},
|
||||
"techniques": {
|
||||
"frameworkAgreement": {"maximumParticipants": 1e9999}
|
||||
}
|
||||
}
|
||||
}`)
|
||||
|
||||
var release ocds.Release
|
||||
if err := unmarshalLenient(raw, &release); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
lots := release.Tender.LotDetails.MaximumLotsBidPerSupplier
|
||||
if lots == nil || *lots != math.MaxInt64 {
|
||||
t.Errorf("maximumLotsBidPerSupplier = %v", lots)
|
||||
}
|
||||
framework := release.Tender.Techniques.FrameworkAgreement
|
||||
if participants := framework.MaximumParticipants; participants == nil ||
|
||||
*participants != math.MaxInt64 {
|
||||
t.Errorf("maximumParticipants = %v", participants)
|
||||
}
|
||||
|
||||
if _, err := json.Marshal(release); err != nil {
|
||||
t.Errorf("marshalling the repaired release: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepairJSONLeavesValidJSONAlone(t *testing.T) {
|
||||
raw := json.RawMessage(`{"date": "2006-10-02T15:33:02+07:00", "title": "x"}`)
|
||||
out, err := repairDates(raw)
|
||||
out, err := repairJSON(raw)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -844,15 +913,15 @@ func TestRepairDatesLeavesValidJSONAlone(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepairDatesRejectsBadJSON(t *testing.T) {
|
||||
func TestRepairJSONRejectsBadJSON(t *testing.T) {
|
||||
for _, raw := range []string{`{`, `{"date": "2006-10-02"} trailing`} {
|
||||
if _, err := repairDates(json.RawMessage(raw)); err == nil {
|
||||
if _, err := repairJSON(json.RawMessage(raw)); err == nil {
|
||||
t.Errorf("expected an error for %q", raw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalLenientDatesErrors(t *testing.T) {
|
||||
func TestUnmarshalLenientErrors(t *testing.T) {
|
||||
var v struct {
|
||||
Date time.Time `json:"date"`
|
||||
}
|
||||
@@ -864,7 +933,7 @@ func TestUnmarshalLenientDatesErrors(t *testing.T) {
|
||||
}
|
||||
for name, raw := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if err := unmarshalLenientDates(json.RawMessage(raw), &v); err == nil {
|
||||
if err := unmarshalLenient(json.RawMessage(raw), &v); err == nil {
|
||||
t.Errorf("expected an error for %s", raw)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user