406 lines
8.7 KiB
Go
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")
|
|
}
|
|
})
|
|
}
|