mirror of
https://github.com/pocketbase/pocketbase.git
synced 2026-10-15 18:48:14 +02:00
(experimental) upgraded to encoding/json/v2
This commit is contained in:
1 parent
4d4275c9aa
commit
97dd775455
125 files changed
+433
-364
No files matched your search
@@ -48,7 +48,7 @@ func TestCreateSuccess(t *testing.T) {
|
||||
t.Fatalf("Expected zip with name %q, got %q", zipName, name)
|
||||
}
|
||||
|
||||
expectedSize := int64(544)
|
||||
expectedSize := int64(532)
|
||||
if size := info.Size(); size != expectedSize {
|
||||
t.Fatalf("Expected zip with size %d, got %d", expectedSize, size)
|
||||
}
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package auth
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
@@ -215,12 +215,12 @@ func TestExtra(t *testing.T) {
|
||||
|
||||
after := b.Extra()
|
||||
|
||||
rawExtra, err := json.Marshal(extra)
|
||||
rawExtra, err := json.Marshal(extra, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
rawAfter, err := json.Marshal(after)
|
||||
rawAfter, err := json.Marshal(after, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -53,12 +53,14 @@ func (p *Facebook) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
||||
}
|
||||
|
||||
extracted := struct {
|
||||
Id string
|
||||
Name string
|
||||
Email string
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Picture struct {
|
||||
Data struct{ Url string }
|
||||
}
|
||||
Data struct {
|
||||
Url string `json:"url"`
|
||||
} `json:"data"`
|
||||
} `json:"picture"`
|
||||
}{}
|
||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||
return nil, err
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -119,9 +119,9 @@ func (p *Gitea) fetchVerifiedPrimaryEmail(token *oauth2.Token) (string, error) {
|
||||
}
|
||||
|
||||
emails := []struct {
|
||||
Email string
|
||||
Verified bool
|
||||
Primary bool
|
||||
Email string `json:"email"`
|
||||
Verified bool `json:"verified"`
|
||||
Primary bool `json:"primary"`
|
||||
}{}
|
||||
if err := json.Unmarshal(content, &emails); err != nil {
|
||||
return "", err
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
@@ -120,9 +120,9 @@ func (p *Gitee) fetchPrimaryEmail(token *oauth2.Token) (string, error) {
|
||||
}
|
||||
|
||||
emails := []struct {
|
||||
Email string
|
||||
State string
|
||||
Scope []string
|
||||
Email string `json:"email"`
|
||||
State string `json:"state"`
|
||||
Scope []string `json:"scope"`
|
||||
}{}
|
||||
if err := json.Unmarshal(content, &emails); err != nil {
|
||||
// ignore unmarshal error in case "Keep my email address private"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"io"
|
||||
"strconv"
|
||||
|
||||
@@ -116,9 +116,9 @@ func (p *Github) fetchVerifiedPrimaryEmail(token *oauth2.Token) (string, error)
|
||||
}
|
||||
|
||||
emails := []struct {
|
||||
Email string
|
||||
Verified bool
|
||||
Primary bool
|
||||
Email string `json:"email"`
|
||||
Verified bool `json:"verified"`
|
||||
Primary bool `json:"primary"`
|
||||
}{}
|
||||
if err := json.Unmarshal(content, &emails); err != nil {
|
||||
return "", err
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -105,7 +105,7 @@ func Fetch(ctx context.Context, jwksURL string, kid string) (*JWK, error) {
|
||||
}
|
||||
|
||||
jwks := struct {
|
||||
Keys []*JWK
|
||||
Keys []*JWK `json:"keys"`
|
||||
}{}
|
||||
|
||||
err = json.Unmarshal(rawBody, &jwks)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net/http"
|
||||
@@ -252,7 +252,7 @@ func TestValidateTokenSignature(t *testing.T) {
|
||||
}
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
|
||||
_ = json.NewEncoder(res).Encode(map[string]any{"keys": []*jwk.JWK{
|
||||
_ = json.MarshalWrite(res, map[string]any{"keys": []*jwk.JWK{
|
||||
{
|
||||
Kid: "key1",
|
||||
Kty: "OKP",
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"strconv"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -3,7 +3,7 @@ package auth
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
@@ -68,7 +68,6 @@ func (p *Linear) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
||||
} `json:"viewer"`
|
||||
} `json:"data"`
|
||||
}{}
|
||||
|
||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"slices"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package auth
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"net/http"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
@@ -62,7 +62,7 @@ func (p *Planningcenter) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
||||
// don't map the email because users can have multiple assigned
|
||||
// and it's not clear if they are verified
|
||||
}
|
||||
}
|
||||
} `json:"data"`
|
||||
}{}
|
||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"strconv"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"net/http"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
+1
-2
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -69,7 +69,6 @@ func (p *VK) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
||||
AvatarURL string `json:"photo_max"`
|
||||
} `json:"response"`
|
||||
}{}
|
||||
|
||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -62,7 +62,6 @@ func (p *Wakatime) FetchAuthUser(token *oauth2.Token) (*AuthUser, error) {
|
||||
IsEmailConfirmed bool `json:"is_email_confirmed"`
|
||||
} `json:"data"`
|
||||
}{}
|
||||
|
||||
if err := json.Unmarshal(data, &extracted); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/types"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"slices"
|
||||
"sync"
|
||||
"testing"
|
||||
@@ -128,7 +128,7 @@ func TestCronAddAndRemove(t *testing.T) {
|
||||
"test5": `{"minutes":{"1":{}},"hours":{"2":{}},"days":{"3":{}},"months":{"4":{}},"daysOfWeek":{"5":{}}}`,
|
||||
}
|
||||
for k, v := range expectedSchedules {
|
||||
raw, err := json.Marshal(indexedJobs[k].schedule)
|
||||
raw, err := json.Marshal(indexedJobs[k].schedule, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package cron
|
||||
|
||||
import "encoding/json"
|
||||
import "encoding/json/v2"
|
||||
|
||||
// Job defines a single registered cron job.
|
||||
type Job struct {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -59,7 +59,7 @@ func TestJobMarshalJSON(t *testing.T) {
|
||||
|
||||
j := Job{id: "test_id", schedule: s}
|
||||
|
||||
raw, err := json.Marshal(j)
|
||||
raw, err := json.Marshal(j, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cron_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -265,7 +265,7 @@ func TestNewSchedule(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
encoded, err := json.Marshal(schedule)
|
||||
encoded, err := json.Marshal(schedule, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshalize the result schedule: %v", err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package dbutils_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -64,8 +64,8 @@ func TestNewFileFromPath(t *testing.T) {
|
||||
if match, err := regexp.Match(normalizedNamePattern, []byte(f.Name)); !match {
|
||||
t.Fatalf("Expected Name to match %v, got %q (%v)", normalizedNamePattern, f.Name, err)
|
||||
}
|
||||
if f.Size != 73 {
|
||||
t.Fatalf("Expected Size %v, got %v", 73, f.Size)
|
||||
if f.Size != 77 {
|
||||
t.Fatalf("Expected Size %v, got %v", 77, f.Size)
|
||||
}
|
||||
if _, ok := f.Reader.(*filesystem.PathReader); !ok {
|
||||
t.Fatalf("Expected Reader to be PathReader, got %v", f.Reader)
|
||||
|
||||
@@ -444,7 +444,7 @@ func TestFilesystemServe(t *testing.T) {
|
||||
map[string]string{
|
||||
"Content-Disposition": `inline; filename="test_name.png"`,
|
||||
"Content-Type": "image/png",
|
||||
"Content-Length": "73",
|
||||
"Content-Length": "77",
|
||||
"Content-Security-Policy": csp,
|
||||
"Cache-Control": cacheControl,
|
||||
},
|
||||
@@ -459,7 +459,7 @@ func TestFilesystemServe(t *testing.T) {
|
||||
map[string]string{
|
||||
"Content-Disposition": `attachment; filename="test_name_download.png"`,
|
||||
"Content-Type": "image/png",
|
||||
"Content-Length": "73",
|
||||
"Content-Length": "77",
|
||||
"Content-Security-Policy": csp,
|
||||
"Cache-Control": cacheControl,
|
||||
},
|
||||
@@ -792,8 +792,8 @@ func TestFilesystemCopy(t *testing.T) {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if f.Size() != 73 {
|
||||
t.Fatalf("Expected file size %d, got %d", 73, f.Size())
|
||||
if f.Size() != 77 {
|
||||
t.Fatalf("Expected file size %d, got %d", 77, f.Size())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -895,7 +895,7 @@ func TestFilesystemServeSingleRange(t *testing.T) {
|
||||
t.Fatalf("Expected StatusCode %d, got %d", http.StatusPartialContent, result.StatusCode)
|
||||
}
|
||||
|
||||
expectedRange := "bytes 0-20/73"
|
||||
expectedRange := "bytes 0-20/77"
|
||||
if cr := result.Header.Get("Content-Range"); cr != expectedRange {
|
||||
t.Fatalf("Expected Content-Range %q, got %q", expectedRange, cr)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package fileblob
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
@@ -50,7 +50,8 @@ func setAttrs(path string, xa xattrs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(f).Encode(xa); err != nil {
|
||||
err = json.MarshalWrite(f, xa)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
os.Remove(f.Name())
|
||||
return err
|
||||
@@ -75,7 +76,9 @@ func getAttrs(path string) (xattrs, error) {
|
||||
}
|
||||
|
||||
xa := new(xattrs)
|
||||
if err := json.NewDecoder(f).Decode(xa); err != nil {
|
||||
|
||||
err = json.UnmarshalRead(f, xa)
|
||||
if err != nil {
|
||||
f.Close()
|
||||
return xattrs{}, err
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package s3_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"encoding/xml"
|
||||
"testing"
|
||||
|
||||
@@ -29,7 +29,7 @@ func TestResponseErrorSerialization(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
jsonRaw, err := json.Marshal(respErr)
|
||||
jsonRaw, err := json.Marshal(respErr, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package s3_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -78,7 +78,7 @@ func TestS3GetObject(t *testing.T) {
|
||||
}
|
||||
|
||||
// check serialized attributes
|
||||
raw, err := json.Marshal(resp)
|
||||
raw, err := json.Marshal(resp, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package s3_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestS3HeadObject(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(resp)
|
||||
raw, err := json.Marshal(resp, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package s3_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
@@ -143,7 +143,7 @@ func TestS3ListObjects(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(resp)
|
||||
raw, err := json.Marshal(resp, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package s3blob_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -261,7 +261,11 @@ func TestDriverAttributes(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(attrs)
|
||||
raw, err := json.Marshal(
|
||||
attrs,
|
||||
json.Deterministic(true),
|
||||
json.FormatNilSliceAsNull(true),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -362,7 +366,11 @@ func TestDriverListPaged(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(page)
|
||||
raw, err := json.Marshal(
|
||||
page,
|
||||
json.Deterministic(true),
|
||||
json.FormatNilSliceAsNull(true),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -510,7 +518,11 @@ func TestDriverNewRangeReader(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
rawAttrs, err := json.Marshal(r.Attributes())
|
||||
rawAttrs, err := json.Marshal(
|
||||
r.Attributes(),
|
||||
json.Deterministic(true),
|
||||
json.FormatNilSliceAsNull(true),
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package list
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package list_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"sync"
|
||||
|
||||
@@ -2,6 +2,7 @@ package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
@@ -326,7 +327,7 @@ func TestBatchHandlerAttrsFormat(t *testing.T) {
|
||||
for i, data := range expected {
|
||||
t.Run(fmt.Sprintf("log handler %d", i), func(t *testing.T) {
|
||||
log := beforeLogs[i]
|
||||
raw, _ := log.Data.MarshalJSON()
|
||||
raw, _ := json.Marshal(log.Data, json.Deterministic(true))
|
||||
if string(raw) != data {
|
||||
t.Fatalf("Expected \n%s \ngot \n%s", data, raw)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package picker
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"strings"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/search"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package picker_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/pocketbase/tools/picker"
|
||||
@@ -263,7 +263,7 @@ func TestPickFields(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
serialized, err := json.Marshal(result)
|
||||
serialized, err := json.Marshal(result, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
+10
-10
@@ -2,7 +2,7 @@ package router_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
@@ -22,7 +22,7 @@ func TestNewApiErrorWithRawData(t *testing.T) {
|
||||
"rawData_test",
|
||||
)
|
||||
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
expected := `{"data":{},"message":"Message_test.","status":300}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -61,7 +61,7 @@ func TestNewApiErrorWithValidationData(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
expected := `{"data":{"err1":{"code":"validation_invalid_value","message":"Invalid value."},"err2":{"code":"validation_required","message":"Cannot be blank."},"err3":{"err3.1":{"code":"validation_invalid_value","message":"Invalid value."},"err3.2":{"code":"validation_required","message":"Cannot be blank."},"err3.3":{"err3.3.1":{"code":"validation_required","message":"Cannot be blank."}}},"err4":{"code":"mock_code","message":"Mock_error.","mock_resolve":123},"err5":{"err5.1":{"code":"validation_required","message":"Cannot be blank."}}},"message":"Message_test.","status":300}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -93,7 +93,7 @@ func TestNewNotFoundError(t *testing.T) {
|
||||
for i, s := range scenarios {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
e := router.NewNotFoundError(s.message, s.data)
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
|
||||
if str := string(result); str != s.expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", s.expected, str)
|
||||
@@ -118,7 +118,7 @@ func TestNewBadRequestError(t *testing.T) {
|
||||
for i, s := range scenarios {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
e := router.NewBadRequestError(s.message, s.data)
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
|
||||
if str := string(result); str != s.expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", s.expected, str)
|
||||
@@ -143,7 +143,7 @@ func TestNewForbiddenError(t *testing.T) {
|
||||
for i, s := range scenarios {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
e := router.NewForbiddenError(s.message, s.data)
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
|
||||
if str := string(result); str != s.expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", s.expected, str)
|
||||
@@ -168,7 +168,7 @@ func TestNewUnauthorizedError(t *testing.T) {
|
||||
for i, s := range scenarios {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
e := router.NewUnauthorizedError(s.message, s.data)
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
|
||||
if str := string(result); str != s.expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", s.expected, str)
|
||||
@@ -193,7 +193,7 @@ func TestNewInternalServerError(t *testing.T) {
|
||||
for i, s := range scenarios {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
e := router.NewInternalServerError(s.message, s.data)
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
|
||||
if str := string(result); str != s.expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", s.expected, str)
|
||||
@@ -218,7 +218,7 @@ func TestNewTooManyRequestsError(t *testing.T) {
|
||||
for i, s := range scenarios {
|
||||
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
||||
e := router.NewTooManyRequestsError(s.message, s.data)
|
||||
result, _ := json.Marshal(e)
|
||||
result, _ := json.Marshal(e, json.Deterministic(true))
|
||||
|
||||
if str := string(result); str != s.expected {
|
||||
t.Fatalf("Expected\n%v\ngot\n%v", s.expected, str)
|
||||
@@ -321,7 +321,7 @@ func TestToApiError(t *testing.T) {
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.name, func(t *testing.T) {
|
||||
raw, err := json.Marshal(router.ToApiError(s.err))
|
||||
raw, err := json.Marshal(router.ToApiError(s.err), json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
+20
-6
@@ -1,7 +1,8 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/jsontext"
|
||||
"encoding/json/v2"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"io"
|
||||
@@ -192,7 +193,7 @@ func (e *Event) JSON(status int, data any) error {
|
||||
|
||||
// error response or no fields to pick
|
||||
if rawFields == "" || status < 200 || status > 299 {
|
||||
return json.NewEncoder(e.Response).Encode(data)
|
||||
return json.MarshalWrite(e.Response, data)
|
||||
}
|
||||
|
||||
// pick only the requested fields
|
||||
@@ -201,7 +202,7 @@ func (e *Event) JSON(status int, data any) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return json.NewEncoder(e.Response).Encode(modified)
|
||||
return json.MarshalWrite(e.Response, modified)
|
||||
}
|
||||
|
||||
// XML writes an XML response.
|
||||
@@ -359,10 +360,23 @@ func (e *Event) BindBody(dst any) error {
|
||||
contentType := e.Request.Header.Get(headerContentType)
|
||||
|
||||
if strings.HasPrefix(contentType, "application/json") {
|
||||
dec := json.NewDecoder(e.Request.Body)
|
||||
err := dec.Decode(dst)
|
||||
// note: don't use json.UnmarshalRead because it perfoms an extra
|
||||
// whitespace scanning which will trigger the auto reread and
|
||||
// will start again from the beginning and causing an error
|
||||
//
|
||||
// (technically json.UnmarshalRead is the better option here but to make
|
||||
// it work it will require extra interface or other mechanism to temp disable
|
||||
// the auto reread functionality and this could be a footgun for middlewares
|
||||
// that wraps the body so for now it is kept as it is and it should
|
||||
// be similar to the old json.NewDecoder(e.Request.Body).Decode(dst))
|
||||
dec := jsontext.NewDecoder(e.Request.Body)
|
||||
err := json.UnmarshalDecode(dec, dst,
|
||||
// minimize breaking changes with earlier version
|
||||
// @todo remove with the "Stage 2" refactoring
|
||||
json.MatchCaseInsensitiveNames(true),
|
||||
)
|
||||
if err == nil {
|
||||
// manually call Reread because single call of json.Decoder.Decode()
|
||||
// manually call Reread because single call of json.UnmarshalDecode
|
||||
// doesn't ensure that the entire body is a valid json string
|
||||
// and it is not guaranteed that it will reach EOF to trigger the reread reset
|
||||
// (ex. in case of trailing spaces or invalid trailing parts like: `{"test":1},something`)
|
||||
|
||||
+28
-25
@@ -3,7 +3,7 @@ package router_test
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -328,7 +328,7 @@ func TestEventSetAllGetAll(t *testing.T) {
|
||||
"a": 123,
|
||||
"b": 456,
|
||||
}
|
||||
rawData, err := json.Marshal(data)
|
||||
rawData, err := json.Marshal(data, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -340,7 +340,7 @@ func TestEventSetAllGetAll(t *testing.T) {
|
||||
data["c"] = 789
|
||||
|
||||
result := event.GetAll()
|
||||
rawResult, err := json.Marshal(result)
|
||||
rawResult, err := json.Marshal(result, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -410,8 +410,8 @@ func TestEventHTML(t *testing.T) {
|
||||
|
||||
func TestEventJSON(t *testing.T) {
|
||||
body := map[string]any{"a": 123, "b": 456, "c": "test"}
|
||||
expectedPickedBody := `{"a":123,"c":"test"}` + "\n"
|
||||
expectedFullBody := `{"a":123,"b":456,"c":"test"}` + "\n"
|
||||
expectedPickedBody := `{"a":123,"c":"test"}`
|
||||
expectedFullBody := `{"a":123,"b":456,"c":"test"}`
|
||||
|
||||
scenarios := []testResponseWriteScenario[any]{
|
||||
{
|
||||
@@ -673,7 +673,7 @@ func TestEventFileFS(t *testing.T) {
|
||||
func TestEventError(t *testing.T) {
|
||||
err := new(router.Event).Error(123, "message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":123}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -684,7 +684,7 @@ func TestEventError(t *testing.T) {
|
||||
func TestEventBadRequestError(t *testing.T) {
|
||||
err := new(router.Event).BadRequestError("message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":400}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -695,7 +695,7 @@ func TestEventBadRequestError(t *testing.T) {
|
||||
func TestEventNotFoundError(t *testing.T) {
|
||||
err := new(router.Event).NotFoundError("message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":404}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -706,7 +706,7 @@ func TestEventNotFoundError(t *testing.T) {
|
||||
func TestEventForbiddenError(t *testing.T) {
|
||||
err := new(router.Event).ForbiddenError("message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":403}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -717,7 +717,7 @@ func TestEventForbiddenError(t *testing.T) {
|
||||
func TestEventUnauthorizedError(t *testing.T) {
|
||||
err := new(router.Event).UnauthorizedError("message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":401}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -728,7 +728,7 @@ func TestEventUnauthorizedError(t *testing.T) {
|
||||
func TestEventTooManyRequestsError(t *testing.T) {
|
||||
err := new(router.Event).TooManyRequestsError("message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":429}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -739,7 +739,7 @@ func TestEventTooManyRequestsError(t *testing.T) {
|
||||
func TestEventInternalServerError(t *testing.T) {
|
||||
err := new(router.Event).InternalServerError("message_test", map[string]any{"a": validation.Required, "b": "test"})
|
||||
|
||||
result, _ := json.Marshal(err)
|
||||
result, _ := json.Marshal(err, json.Deterministic(true))
|
||||
expected := `{"data":{"a":{"code":"validation_invalid_value","message":"Invalid value."},"b":{"code":"validation_invalid_value","message":"Invalid value."}},"message":"Message_test.","status":500}`
|
||||
|
||||
if string(result) != expected {
|
||||
@@ -873,7 +873,7 @@ func TestEventBindBody(t *testing.T) {
|
||||
t.Fatalf("Expected hasErr %v, got %v (%v)", s.expectError, hasErr, err)
|
||||
}
|
||||
|
||||
dstRaw, err := json.Marshal(dst)
|
||||
dstRaw, err := json.Marshal(dst, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -925,29 +925,32 @@ func testEventResponseWrite[T any](
|
||||
}
|
||||
|
||||
result := rec.Result()
|
||||
defer result.Body.Close()
|
||||
|
||||
if result.StatusCode != scenario.expectedStatus {
|
||||
t.Fatalf("Expected status code %d, got %d", scenario.expectedStatus, result.StatusCode)
|
||||
}
|
||||
|
||||
resultBody, err := io.ReadAll(result.Body)
|
||||
result.Body.Close()
|
||||
rawBody, err := io.ReadAll(result.Body)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read response body: %v", err)
|
||||
}
|
||||
strBody := string(rawBody)
|
||||
|
||||
resultBody, err = json.Marshal(string(resultBody))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
// try to deserialize into a map and then serialize again in a
|
||||
// deterministic manner in case it is json
|
||||
var jsonBody any
|
||||
err = json.Unmarshal(rawBody, &jsonBody)
|
||||
if err == nil {
|
||||
normalized, err := json.Marshal(jsonBody, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to deterministicly serialize json body\n%s\ngot\n%v", jsonBody, err)
|
||||
}
|
||||
strBody = string(normalized)
|
||||
}
|
||||
|
||||
expectedBody, err := json.Marshal(scenario.expectedBody)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(resultBody, expectedBody) {
|
||||
t.Fatalf("Expected body\n%s\ngot\n%s", expectedBody, resultBody)
|
||||
if scenario.expectedBody != strBody {
|
||||
t.Fatalf("Expected body\n%s\ngot\n%s", scenario.expectedBody, strBody)
|
||||
}
|
||||
|
||||
for k, ev := range scenario.expectedHeaders {
|
||||
|
||||
@@ -2,7 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
@@ -176,7 +176,9 @@ func ErrorHandler(resp http.ResponseWriter, req *http.Request, err error) {
|
||||
resp.WriteHeader(apiErr.Status)
|
||||
|
||||
if req.Method != http.MethodHead {
|
||||
if jsonErr := json.NewEncoder(resp).Encode(apiErr); jsonErr != nil {
|
||||
// note: deterministic because some logs may depend on the exact serialized error
|
||||
jsonErr := json.MarshalWrite(resp, apiErr, json.Deterministic(true))
|
||||
if jsonErr != nil {
|
||||
log.Println(jsonErr) // truly rare case, log to stderr only for dev purposes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package router
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
@@ -2,7 +2,7 @@ package router_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -428,7 +428,7 @@ func TestUnmarshalRequestData(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(s.dst)
|
||||
raw, err := json.Marshal(s.dst, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -69,7 +69,7 @@ func (f FilterData) BuildExprWithLimit(
|
||||
|
||||
// try to json serialize as fallback
|
||||
if replacement == "" {
|
||||
raw, _ := json.Marshal(v)
|
||||
raw, _ := json.Marshal(v, json.Deterministic(true))
|
||||
replacement = string(raw)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package search_test
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"testing"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
@@ -40,7 +40,7 @@ func TestMultiMatchSubqueryBuild(t *testing.T) {
|
||||
}
|
||||
|
||||
// the params from all expressions should be merged in the root
|
||||
rawParams, err := json.Marshal(params)
|
||||
rawParams, err := json.Marshal(params, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package search
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
@@ -138,7 +138,7 @@ func TestProviderSort(t *testing.T) {
|
||||
Sort(initialSort).
|
||||
AddSort(SortField{"test3", SortDesc})
|
||||
|
||||
encoded, _ := json.Marshal(p.sort)
|
||||
encoded, _ := json.Marshal(p.sort, json.Deterministic(true))
|
||||
expected := `[{"name":"test1","direction":"ASC"},{"name":"test2","direction":"ASC"},{"name":"test3","direction":"DESC"}]`
|
||||
|
||||
if string(encoded) != expected {
|
||||
@@ -153,7 +153,7 @@ func TestProviderFilter(t *testing.T) {
|
||||
Filter(initialFilter).
|
||||
AddFilter("test3")
|
||||
|
||||
encoded, _ := json.Marshal(p.filter)
|
||||
encoded, _ := json.Marshal(p.filter, json.Deterministic(true))
|
||||
expected := `["test1","test2","test3"]`
|
||||
|
||||
if string(encoded) != expected {
|
||||
@@ -246,12 +246,12 @@ func TestProviderParse(t *testing.T) {
|
||||
t.Fatalf("Expected perPage %v, got %v", s.expectPerPage, p.perPage)
|
||||
}
|
||||
|
||||
encodedSort, _ := json.Marshal(p.sort)
|
||||
encodedSort, _ := json.Marshal(p.sort, json.Deterministic(true))
|
||||
if string(encodedSort) != s.expectSort {
|
||||
t.Fatalf("Expected sort %v, got \n%v", s.expectSort, string(encodedSort))
|
||||
}
|
||||
|
||||
encodedFilter, _ := json.Marshal(p.filter)
|
||||
encodedFilter, _ := json.Marshal(p.filter, json.Deterministic(true))
|
||||
if string(encodedFilter) != s.expectFilter {
|
||||
t.Fatalf("Expected filter %v, got \n%v", s.expectFilter, string(encodedFilter))
|
||||
}
|
||||
@@ -453,7 +453,7 @@ func TestProviderExecNonEmptyQuery(t *testing.T) {
|
||||
t.Fatalf("Expected resolver.Update to be called %d, got %d", 1, testResolver.UpdateQueryCalls)
|
||||
}
|
||||
|
||||
encoded, _ := json.Marshal(result)
|
||||
encoded, _ := json.Marshal(result, json.Deterministic(true))
|
||||
if string(encoded) != s.expectResult {
|
||||
t.Fatalf("Expected result %v, got \n%v", s.expectResult, string(encoded))
|
||||
}
|
||||
@@ -722,7 +722,7 @@ func TestProviderParseAndExec(t *testing.T) {
|
||||
t.Fatalf("Expected %d db queries, got %d: \n%v", expectedQueries, len(testDB.CalledQueries), testDB.CalledQueries)
|
||||
}
|
||||
|
||||
encoded, _ := json.Marshal(result)
|
||||
encoded, _ := json.Marshal(result, json.Deterministic(true))
|
||||
if string(encoded) != s.expectResult {
|
||||
t.Fatalf("Expected result \n%v\ngot\n%v", s.expectResult, string(encoded))
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package search_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@@ -67,7 +67,7 @@ func TestParseSortFromString(t *testing.T) {
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.value, func(t *testing.T) {
|
||||
result := search.ParseSortFromString(s.value)
|
||||
encoded, _ := json.Marshal(result)
|
||||
encoded, _ := json.Marshal(result, json.Deterministic(true))
|
||||
encodedStr := string(encoded)
|
||||
|
||||
if encodedStr != s.expected {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package store_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"slices"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
data := map[string]int{"test1": 1, "test2": 2}
|
||||
originalRawData, err := json.Marshal(data)
|
||||
originalRawData, err := json.Marshal(data, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -22,7 +22,7 @@ func TestNew(t *testing.T) {
|
||||
s.Remove("test1") // remove 1 item
|
||||
|
||||
// check if data was shallow copied
|
||||
rawData, _ := json.Marshal(data)
|
||||
rawData, _ := json.Marshal(data, json.Deterministic(true))
|
||||
if !bytes.Equal(originalRawData, rawData) {
|
||||
t.Fatalf("Expected data \n%s, \ngot \n%s", originalRawData, rawData)
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func TestReset(t *testing.T) {
|
||||
s := store.New(map[string]int{"test1": 1})
|
||||
|
||||
data := map[string]int{"test2": 2}
|
||||
originalRawData, err := json.Marshal(data)
|
||||
originalRawData, err := json.Marshal(data, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func TestReset(t *testing.T) {
|
||||
s.Set("test3", 3)
|
||||
|
||||
// check if data was shallow copied
|
||||
rawData, _ := json.Marshal(data)
|
||||
rawData, _ := json.Marshal(data, json.Deterministic(true))
|
||||
if !bytes.Equal(originalRawData, rawData) {
|
||||
t.Fatalf("Expected data \n%s, \ngot \n%s", originalRawData, rawData)
|
||||
}
|
||||
@@ -371,7 +371,7 @@ func TestMarshalJSON(t *testing.T) {
|
||||
|
||||
expected := []byte(`{"a":"test1", "b":"test2"}`)
|
||||
|
||||
result, err := json.Marshal(s)
|
||||
result, err := json.Marshal(s, json.Deterministic(true))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package subscriptions
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package subscriptions_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
|
||||
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
|
||||
+13
-10
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -14,12 +14,9 @@ type jsonArrayAlias[T any] JSONArray[T]
|
||||
|
||||
// MarshalJSON implements the [json.Marshaler] interface.
|
||||
func (m JSONArray[T]) MarshalJSON() ([]byte, error) {
|
||||
// initialize an empty map to ensure that `[]` is returned as json
|
||||
if m == nil {
|
||||
m = JSONArray[T]{}
|
||||
}
|
||||
|
||||
return json.Marshal(jsonArrayAlias[T](m))
|
||||
// note: forces the Deterministic option to ensure consistent output
|
||||
// in mixed json v1 and v2 configurations
|
||||
return json.Marshal(jsonArrayAlias[T](m), json.Deterministic(true))
|
||||
}
|
||||
|
||||
// String returns the string representation of the current json array.
|
||||
@@ -30,8 +27,7 @@ func (m JSONArray[T]) String() string {
|
||||
|
||||
// Value implements the [driver.Valuer] interface.
|
||||
func (m JSONArray[T]) Value() (driver.Value, error) {
|
||||
data, err := json.Marshal(m)
|
||||
|
||||
data, err := m.MarshalJSON()
|
||||
return string(data), err
|
||||
}
|
||||
|
||||
@@ -54,5 +50,12 @@ func (m *JSONArray[T]) Scan(value any) error {
|
||||
data = []byte("[]")
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, m)
|
||||
err := json.Unmarshal(data, m)
|
||||
if err != nil {
|
||||
// reset because jsonv2 performs streaming decoding and mutates the dst even on error
|
||||
*m = JSONArray[T]{}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package types_test
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@@ -115,7 +115,7 @@ func TestJSONArrayScan(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
result, _ := arr.MarshalJSON()
|
||||
result, _ := json.Marshal(arr, json.Deterministic(true))
|
||||
|
||||
if string(result) != s.expectJSON {
|
||||
t.Errorf("(%d) Expected %s, got %v", i, s.expectJSON, string(result))
|
||||
|
||||
+25
-22
@@ -2,31 +2,13 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// JSONMap defines a map that is safe for json and db read/write.
|
||||
type JSONMap[T any] map[string]T
|
||||
|
||||
// MarshalJSON implements the [json.Marshaler] interface.
|
||||
func (m JSONMap[T]) MarshalJSON() ([]byte, error) {
|
||||
type alias JSONMap[T] // prevent recursion
|
||||
|
||||
// initialize an empty map to ensure that `{}` is returned as json
|
||||
if m == nil {
|
||||
m = JSONMap[T]{}
|
||||
}
|
||||
|
||||
return json.Marshal(alias(m))
|
||||
}
|
||||
|
||||
// String returns the string representation of the current json map.
|
||||
func (m JSONMap[T]) String() string {
|
||||
v, _ := m.MarshalJSON()
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// Get retrieves a single value from the current JSONMap[T].
|
||||
//
|
||||
// This helper was added primarily to assist the goja integration since custom map types
|
||||
@@ -43,10 +25,24 @@ func (m JSONMap[T]) Set(key string, value T) {
|
||||
m[key] = value
|
||||
}
|
||||
|
||||
// MarshalJSON implements the [json.Marshaler] interface.
|
||||
func (m JSONMap[T]) MarshalJSON() ([]byte, error) {
|
||||
type alias JSONMap[T] // prevent recursion
|
||||
|
||||
// note: forces the Deterministic option to ensure consistent output
|
||||
// in mixed json v1 and v2 configurations
|
||||
return json.Marshal(alias(m), json.Deterministic(true))
|
||||
}
|
||||
|
||||
// String returns the string representation of the current json map.
|
||||
func (m JSONMap[T]) String() string {
|
||||
v, _ := m.MarshalJSON()
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// Value implements the [driver.Valuer] interface.
|
||||
func (m JSONMap[T]) Value() (driver.Value, error) {
|
||||
data, err := json.Marshal(m)
|
||||
|
||||
data, err := m.MarshalJSON()
|
||||
return string(data), err
|
||||
}
|
||||
|
||||
@@ -69,5 +65,12 @@ func (m *JSONMap[T]) Scan(value any) error {
|
||||
data = []byte("{}")
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, m)
|
||||
err := json.Unmarshal(data, m)
|
||||
if err != nil {
|
||||
// reset because jsonv2 performs streaming decoding and mutates the dst even on error
|
||||
*m = JSONMap[T]{}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package types_test
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json/v2"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@@ -154,7 +155,7 @@ func TestJSONArrayMapScan(t *testing.T) {
|
||||
t.Fatalf("Expected %v, got %v (%v)", s.expectError, hasErr, scanErr)
|
||||
}
|
||||
|
||||
result, _ := arr.MarshalJSON()
|
||||
result, _ := json.Marshal(arr, json.Deterministic(true))
|
||||
|
||||
if string(result) != s.expectJSON {
|
||||
t.Fatalf("Expected %s, got %s", s.expectJSON, result)
|
||||
|
||||
@@ -2,7 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
||||
Reference in new issue
Block a user