flabk/pkg/asld/walker_test.go

191 lines
4.3 KiB
Go

package asld
import (
"encoding/json"
"math"
"testing"
"git.sectorinf.com/emilis/asflab/pkg/epk"
"github.com/stretchr/testify/require"
)
func TestWalkerSliceInner(t *testing.T) {
tests := map[string]struct {
data string
position int
expect bool
expected string
}{
"paren simple": {
data: `{"hello":"world"}`,
expect: true,
expected: `"hello":"world"`,
},
"paren child nested": {
data: `{"hello":"world", "sub":{"hello":"world", "sub":{"hello":"world", "sub":{"hello":"world"}}}}`,
expect: true,
expected: `"hello":"world", "sub":{"hello":"world", "sub":{"hello":"world", "sub":{"hello":"world"}}}`,
},
"get within string": {
data: `{"hello":"world"}`,
position: 1,
expect: true,
expected: `hello`,
},
"inverted array": {
data: `][`,
expect: false,
expected: `][`,
},
}
for name, test := range tests {
test := test
// if name != "get within string" {
// continue
// }
t.Run(name, func(tt *testing.T) {
that := require.New(tt)
w := newWalker([]byte(test.data))
w.position = test.position
sub, ok := w.SliceInner()
that.Equal(test.expect, ok)
that.Equal(test.expected, string(sub.content))
})
}
}
func TestNexts(t *testing.T) {
tests := map[string]struct {
contents string
expPos int
}{
"doesn't stay at the same location if is on a next": {
contents: `"hello"`,
expPos: 6,
},
}
for name, test := range tests {
test := test
t.Run(name, func(tt *testing.T) {
that := require.New(t)
w := newWalker([]byte(test.contents))
w, ok := w.To('"')
that.True(ok)
w, sym := w.ToNext()
that.Equal(symbolEOB, sym)
that.Equal(test.expPos, w.position, "positions are not the same")
})
}
}
func TestMapMembers(t *testing.T) {
tests := map[string]struct {
object map[string]any
errCheck epk.ErrorTest
}{
"all types": {
object: map[string]any{
"hello": "world",
"object_with_children": map[string]any{
"hello": "world",
},
"floating point": 123.456,
"integer": -50,
"uint": uint(math.MaxUint),
"array": []string{"hello", "world"},
},
},
}
for name, test := range tests {
test := test
t.Run(name, func(tt *testing.T) {
that := require.New(tt)
objJson, err := json.Marshal(test.object)
that.NoError(err)
w := newWalker(objJson)
members, err := mapMembers(w)
if test.errCheck == nil {
test.errCheck = epk.NoError
}
test.errCheck(that, err)
for key, val := range test.object {
valJson, err := json.Marshal(val)
that.NoError(err)
walker, exists := members[key]
that.True(exists)
that.Equal(valJson, walker.content, key)
}
})
}
}
func jsonElemList[T any](that *require.Assertions, a any) [][]byte {
that.NotNil(a)
v, ok := a.([]T)
that.True(ok)
fields := make([][]byte, len(v))
for index, field := range v {
jsonField, err := json.Marshal(field)
that.NoError(err)
fields[index] = jsonField
}
return fields
}
type hello struct {
Hello string
}
func TestArrayMembers(t *testing.T) {
tests := map[string]struct {
object any
errCheck epk.ErrorTest
toJsonElementList func(*require.Assertions, any) [][]byte
}{
"strings": {
object: []string{"a", "b", "c", "d"},
toJsonElementList: jsonElemList[string],
},
"ints": {
object: []int{1, 2, 3, 4, 5, 6},
toJsonElementList: jsonElemList[int],
},
"floats": {
object: []float64{123.456, 789.0123, 456.789},
toJsonElementList: jsonElemList[float64],
},
"strings with commas": {
object: []string{"this, is what I do", "what, don't like it?"},
toJsonElementList: jsonElemList[string],
},
"objects": {
object: []hello{{"world"}, {"mom, dad"}},
toJsonElementList: jsonElemList[hello],
},
}
for name, test := range tests {
test := test
t.Run(name, func(tt *testing.T) {
that := require.New(tt)
objJson, err := json.Marshal(test.object)
that.NoError(err)
w := newWalker(objJson)
members, err := arrayMembers(w)
if test.errCheck == nil {
test.errCheck = epk.NoError
}
test.errCheck(that, err)
expected := test.toJsonElementList(that, test.object)
that.Len(members, len(expected))
for index, elem := range expected {
equivMember := members[index]
that.Equal(elem, equivMember.content)
}
})
}
}