Files
x/encoding/json/json_test.go
Colin Henry 54aae5f242
All checks were successful
Go / build (1.23) (push) Successful in 3m51s
big updates: tests, bug fixed, documentation. oh my
2026-01-03 15:53:50 -08:00

406 lines
8.7 KiB
Go

package json
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
)
type testStruct struct {
Name string `json:"name"`
Value int `json:"value"`
}
func TestEncoder(t *testing.T) {
t.Run("successful encode", func(t *testing.T) {
var buf bytes.Buffer
data := testStruct{Name: "test", Value: 42}
err := Encoder(&buf, data)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
expected := `{"name":"test","value":42}`
result := strings.TrimSpace(buf.String())
if result != expected {
t.Errorf("expected %q, got %q", expected, result)
}
})
t.Run("encode nil", func(t *testing.T) {
var buf bytes.Buffer
err := Encoder(&buf, nil)
if err != nil {
t.Fatalf("expected no error encoding nil, got %v", err)
}
result := strings.TrimSpace(buf.String())
if result != "null" {
t.Errorf("expected 'null', got %q", result)
}
})
t.Run("encode slice", func(t *testing.T) {
var buf bytes.Buffer
data := []int{1, 2, 3}
err := Encoder(&buf, data)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
expected := `[1,2,3]`
result := strings.TrimSpace(buf.String())
if result != expected {
t.Errorf("expected %q, got %q", expected, result)
}
})
t.Run("encode map", func(t *testing.T) {
var buf bytes.Buffer
data := map[string]string{"key": "value"}
err := Encoder(&buf, data)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
expected := `{"key":"value"}`
result := strings.TrimSpace(buf.String())
if result != expected {
t.Errorf("expected %q, got %q", expected, result)
}
})
}
func TestDecoder(t *testing.T) {
t.Run("successful decode", func(t *testing.T) {
input := `{"name":"test","value":42}`
reader := strings.NewReader(input)
var result testStruct
err := Decoder(reader, &result)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if result.Name != "test" {
t.Errorf("expected name 'test', got %q", result.Name)
}
if result.Value != 42 {
t.Errorf("expected value 42, got %d", result.Value)
}
})
t.Run("decode empty object", func(t *testing.T) {
input := `{}`
reader := strings.NewReader(input)
var result testStruct
err := Decoder(reader, &result)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if result.Name != "" {
t.Errorf("expected empty name, got %q", result.Name)
}
if result.Value != 0 {
t.Errorf("expected zero value, got %d", result.Value)
}
})
t.Run("decode array", func(t *testing.T) {
input := `[1,2,3]`
reader := strings.NewReader(input)
var result []int
err := Decoder(reader, &result)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if len(result) != 3 {
t.Fatalf("expected 3 elements, got %d", len(result))
}
for i, expected := range []int{1, 2, 3} {
if result[i] != expected {
t.Errorf("element %d: expected %d, got %d", i, expected, result[i])
}
}
})
t.Run("decode invalid JSON", func(t *testing.T) {
input := `{invalid json}`
reader := strings.NewReader(input)
var result testStruct
err := Decoder(reader, &result)
if err == nil {
t.Fatal("expected error for invalid JSON, got nil")
}
})
t.Run("decode empty input", func(t *testing.T) {
reader := strings.NewReader("")
var result testStruct
err := Decoder(reader, &result)
if err == nil {
t.Fatal("expected error for empty input, got nil")
}
})
}
func TestUnknown(t *testing.T) {
t.Run("unmarshal object", func(t *testing.T) {
data := []byte(`{"key":"value"}`)
var u Unknown
err := u.UnmarshalJSON(data)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if u.Object == nil {
t.Fatal("expected Object to be set")
}
if u.Array != nil {
t.Error("expected Array to be nil")
}
obj := *u.Object
if obj["key"] != "value" {
t.Errorf("expected key='value', got %v", obj["key"])
}
})
t.Run("unmarshal array", func(t *testing.T) {
data := []byte(`[1,2,3]`)
var u Unknown
err := u.UnmarshalJSON(data)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if u.Array == nil {
t.Fatal("expected Array to be set")
}
if u.Object != nil {
t.Error("expected Object to be nil")
}
arr := *u.Array
if len(arr) != 3 {
t.Errorf("expected 3 elements, got %d", len(arr))
}
})
t.Run("resolve object", func(t *testing.T) {
obj := Object{"test": "value"}
u := Unknown{Object: &obj}
result := u.Resolve()
if result == nil {
t.Fatal("expected non-nil result")
}
resolved, ok := result.(*Object)
if !ok {
t.Fatal("expected result to be *Object")
}
if (*resolved)["test"] != "value" {
t.Error("unexpected resolved value")
}
})
t.Run("resolve array", func(t *testing.T) {
arr := Array{1, 2, 3}
u := Unknown{Array: &arr}
result := u.Resolve()
if result == nil {
t.Fatal("expected non-nil result")
}
resolved, ok := result.(*Array)
if !ok {
t.Fatal("expected result to be *Array")
}
if len(*resolved) != 3 {
t.Error("unexpected resolved length")
}
})
t.Run("resolve uninitialized panics", func(t *testing.T) {
u := Unknown{}
defer func() {
if r := recover(); r == nil {
t.Fatal("expected panic for uninitialized Unknown")
}
}()
u.Resolve()
})
}
func TestLoadJSONFromReader(t *testing.T) {
t.Run("successful load", func(t *testing.T) {
input := `{"name":"test","value":42}`
reader := strings.NewReader(input)
data, err := LoadJSONFromReader(reader)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if string(data) != input {
t.Errorf("expected %q, got %q", input, string(data))
}
})
t.Run("empty input", func(t *testing.T) {
reader := strings.NewReader("")
data, err := LoadJSONFromReader(reader)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if len(data) != 0 {
t.Errorf("expected empty data, got %d bytes", len(data))
}
})
}
func TestLoadJSONFromFile(t *testing.T) {
t.Run("successful load", func(t *testing.T) {
tmpDir := t.TempDir()
filePath := filepath.Join(tmpDir, "test.json")
content := `{"name":"test","value":42}`
err := os.WriteFile(filePath, []byte(content), 0644)
if err != nil {
t.Fatalf("failed to create test file: %v", err)
}
file, err := os.Open(filePath)
if err != nil {
t.Fatalf("failed to open test file: %v", err)
}
data, err := LoadJSONFromFile(file)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if string(data) != content {
t.Errorf("expected %q, got %q", content, string(data))
}
})
t.Run("empty file", func(t *testing.T) {
tmpDir := t.TempDir()
filePath := filepath.Join(tmpDir, "empty.json")
err := os.WriteFile(filePath, []byte(""), 0644)
if err != nil {
t.Fatalf("failed to create test file: %v", err)
}
file, err := os.Open(filePath)
if err != nil {
t.Fatalf("failed to open test file: %v", err)
}
data, err := LoadJSONFromFile(file)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if len(data) != 0 {
t.Errorf("expected empty data, got %d bytes", len(data))
}
})
}
func TestLoadJSONFromFileToType(t *testing.T) {
t.Run("successful load and unmarshal", func(t *testing.T) {
tmpDir := t.TempDir()
filePath := filepath.Join(tmpDir, "test.json")
content := `{"name":"test","value":42}`
err := os.WriteFile(filePath, []byte(content), 0644)
if err != nil {
t.Fatalf("failed to create test file: %v", err)
}
file, err := os.Open(filePath)
if err != nil {
t.Fatalf("failed to open test file: %v", err)
}
var result testStruct
err = LoadJSONFromFileToType(file, &result)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if result.Name != "test" {
t.Errorf("expected name 'test', got %q", result.Name)
}
if result.Value != 42 {
t.Errorf("expected value 42, got %d", result.Value)
}
})
t.Run("invalid JSON", func(t *testing.T) {
tmpDir := t.TempDir()
filePath := filepath.Join(tmpDir, "invalid.json")
content := `{invalid json}`
err := os.WriteFile(filePath, []byte(content), 0644)
if err != nil {
t.Fatalf("failed to create test file: %v", err)
}
file, err := os.Open(filePath)
if err != nil {
t.Fatalf("failed to open test file: %v", err)
}
var result testStruct
err = LoadJSONFromFileToType(file, &result)
if err == nil {
t.Fatal("expected error for invalid JSON, got nil")
}
})
t.Run("empty file", func(t *testing.T) {
tmpDir := t.TempDir()
filePath := filepath.Join(tmpDir, "empty.json")
err := os.WriteFile(filePath, []byte(""), 0644)
if err != nil {
t.Fatalf("failed to create test file: %v", err)
}
file, err := os.Open(filePath)
if err != nil {
t.Fatalf("failed to open test file: %v", err)
}
var result testStruct
err = LoadJSONFromFileToType(file, &result)
if err == nil {
t.Fatal("expected error for empty JSON, got nil")
}
})
}