- Create internal/testutil/bep package with JSON helper - Use bep.JSON in formatters/json_test.go, models/entry_test.go, and models/meta_test.go
218 lines
5.8 KiB
Go
218 lines
5.8 KiB
Go
package models
|
|
|
|
import (
|
|
"encoding"
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"codeberg.org/danjones000/my-log/internal/testutil/bep"
|
|
"github.com/nalgeon/be"
|
|
)
|
|
|
|
// Type assertions
|
|
var _ encoding.TextMarshaler = Meta{}
|
|
var _ encoding.TextUnmarshaler = new(Meta)
|
|
var _ json.Marshaler = Metas{}
|
|
var _ json.Unmarshaler = new(Metas)
|
|
|
|
var skipMarshalTest = errors.New("skip marshal")
|
|
|
|
func TestMeta(t *testing.T) {
|
|
when := time.Now()
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
value any
|
|
out string
|
|
err error
|
|
newVal any
|
|
}{
|
|
{"int", "num", 42, "@num 42", nil, 42},
|
|
{"int64", "num", int64(42), "@num 42", nil, int(42)},
|
|
{"float", "num", 42.13, "@num 42.13", nil, 42.13},
|
|
{"string", "word", "hello", "@word hello", nil, "hello"},
|
|
{"json number", "num", json.Number("42.13"), "@num 42.13", nil, 42.13},
|
|
{"true", "b", true, "@b true", nil, true},
|
|
{"false", "b", false, "@b false", nil, false},
|
|
{"nil", "n", nil, "", ErrorParsing, ErrorParsing},
|
|
{"time", "when", when, "@when " + when.Format(time.RFC3339), nil, when},
|
|
{"rune", "char", '@', "@char @", nil, "@"},
|
|
{"bytes", "byteme", []byte("yo"), "@byteme yo", nil, "yo"},
|
|
{"byte", "byteme", byte(67), "@byteme C", nil, "C"},
|
|
{"json-arr", "arr", json.RawMessage(`["foo",42,"bar", null,"quux", true]`), `@arr ["foo",42,"bar", null,"quux", true]`, nil, json.RawMessage(`["foo",42,"bar", null,"quux", true]`)},
|
|
{"chan", "nope", make(chan bool), "", errors.New("Unsupported type chan bool"), ""},
|
|
{"whitespace-key", "no space", "hi", "", errors.New("whitespace is not allowed in key: no space"), ""},
|
|
{"empty-mar", "nope", skipMarshalTest, "", nil, ErrorParsing},
|
|
{"no-key-mar", "nope", skipMarshalTest, "nope", nil, ErrorParsing},
|
|
{"no-value-mar", "nope", skipMarshalTest, "@nope ", nil, ErrorParsing},
|
|
{"space-value-mar", "nope", skipMarshalTest, "@nope ", nil, ErrorParsing},
|
|
{"space-nl-value-mar", "nope", skipMarshalTest, "@nope \n ", nil, ErrorParsing},
|
|
{"null-value-mar", "nope", skipMarshalTest, "@nope null", nil, nil},
|
|
{"tilda-value-mar", "nope", skipMarshalTest, "@nope ~", nil, nil},
|
|
{"none-value-mar", "nope", skipMarshalTest, "@nope none", nil, nil},
|
|
{"nil-value-mar", "nope", skipMarshalTest, "@nope nil", nil, nil},
|
|
{"yes-value-mar", "nope", skipMarshalTest, "@nope yes", nil, true},
|
|
{"on-value-mar", "nope", skipMarshalTest, "@nope on", nil, true},
|
|
{"no-value-mar", "nope", skipMarshalTest, "@nope no", nil, false},
|
|
{"off-value-mar", "nope", skipMarshalTest, "@nope off", nil, false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, getMetaTestRunner(tt.key, tt.value, tt.out, tt.err, tt.newVal))
|
|
}
|
|
}
|
|
|
|
func getMetaTestRunner(key string, value any, out string, err error, newVal any) func(*testing.T) {
|
|
return func(t *testing.T) {
|
|
st := Meta{key, value}
|
|
n := &Meta{}
|
|
var e error
|
|
|
|
if valE, ok := value.(error); !ok || !errors.Is(valE, skipMarshalTest) {
|
|
var o []byte
|
|
o, e = st.MarshalText()
|
|
be.Equal(t, string(o), out)
|
|
be.Equal(t, e, err)
|
|
if e != nil {
|
|
return
|
|
}
|
|
|
|
e = n.UnmarshalText(o)
|
|
} else {
|
|
e = n.UnmarshalText([]byte(out))
|
|
}
|
|
if newE, ok := newVal.(error); ok {
|
|
be.Err(t, e, newE)
|
|
} else {
|
|
be.Equal(t, n.Key, key)
|
|
if ti, ok := newVal.(time.Time); ok {
|
|
valT, ok := n.Value.(time.Time)
|
|
be.True(t, ok)
|
|
be.True(t, valT.After(ti.Add(-time.Second)) && valT.Before(ti.Add(time.Second)))
|
|
|
|
} else {
|
|
be.Equal(t, n.Value, newVal)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMetasJson(t *testing.T) {
|
|
ms := Metas{{"me", 41}, {"you", false}}
|
|
exp := `{"me":41,"you":false}`
|
|
o, err := json.Marshal(ms)
|
|
be.Err(t, err, nil)
|
|
bep.JSON(t, o, []byte(exp))
|
|
}
|
|
|
|
func TestMetasJsonUnmarshal(t *testing.T) {
|
|
ms := Metas{}
|
|
in := `{"me":"cool","you":false}`
|
|
err := json.Unmarshal([]byte(in), &ms)
|
|
be.Err(t, err, nil)
|
|
be.Equal(t, len(ms), 2)
|
|
be.Equal(t, ms, Metas{
|
|
{"me", "cool"},
|
|
{"you", false},
|
|
})
|
|
}
|
|
|
|
func TestMetasJsonError(t *testing.T) {
|
|
ms := Metas{}
|
|
in := "not json"
|
|
err := (&ms).UnmarshalJSON([]byte(in))
|
|
be.Err(t, err)
|
|
be.Equal(t, len(ms), 0)
|
|
}
|
|
|
|
func TestMetasAppend(t *testing.T) {
|
|
ms := Metas{}
|
|
ms = ms.Append("foo", 42)
|
|
be.Equal(t, len(ms), 1)
|
|
be.Equal(t, ms[0], Meta{"foo", 42})
|
|
}
|
|
|
|
func TestMetasAppendTo(t *testing.T) {
|
|
ms := &Metas{}
|
|
ms.AppendTo("foo", 42)
|
|
be.Equal(t, len(*ms), 1)
|
|
be.Equal(t, (*ms)[0], Meta{"foo", 42})
|
|
}
|
|
|
|
func TestMetasSet(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
initial Metas
|
|
key string
|
|
value any
|
|
expected Metas
|
|
}{
|
|
{
|
|
name: "Set new key",
|
|
initial: Metas{},
|
|
key: "foo",
|
|
value: 42,
|
|
expected: Metas{{"foo", 42}},
|
|
},
|
|
{
|
|
name: "Update existing key",
|
|
initial: Metas{{"foo", 1}},
|
|
key: "foo",
|
|
value: 42,
|
|
expected: Metas{{"foo", 42}},
|
|
},
|
|
{
|
|
name: "Update existing key with different type",
|
|
initial: Metas{{"foo", "hello"}},
|
|
key: "foo",
|
|
value: 42,
|
|
expected: Metas{{"foo", 42}},
|
|
},
|
|
{
|
|
name: "Set multiple new keys",
|
|
initial: Metas{},
|
|
key: "bar",
|
|
value: true,
|
|
expected: Metas{{"bar", true}},
|
|
},
|
|
{
|
|
name: "Update one of multiple existing keys",
|
|
initial: Metas{{"foo", 1}, {"bar", "hello"}},
|
|
key: "foo",
|
|
value: 42,
|
|
expected: Metas{{"foo", 42}, {"bar", "hello"}},
|
|
},
|
|
{
|
|
name: "Set new key when others exist",
|
|
initial: Metas{{"foo", 1}, {"bar", "hello"}},
|
|
key: "baz",
|
|
value: false,
|
|
expected: Metas{{"foo", 1}, {"bar", "hello"}, {"baz", false}},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := tt.initial.Set(tt.key, tt.value)
|
|
be.Equal(t, result, tt.expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMetasGet(t *testing.T) {
|
|
ms := Metas{{"foo", 42}, {"bar", "hello"}}
|
|
|
|
val, found := ms.Get("foo")
|
|
be.True(t, found)
|
|
be.Equal(t, val, 42)
|
|
|
|
val, found = ms.Get("bar")
|
|
be.True(t, found)
|
|
be.Equal(t, val, "hello")
|
|
|
|
val, found = ms.Get("baz")
|
|
be.True(t, !found)
|
|
be.Equal(t, val, nil)
|
|
}
|