Files
zeekayandClaude Opus 5 7b23b7e68d Go 1.27.1, and the code it can say more simply
Modules declare go 1.27.1 and the build images follow. go fix applied the
modernizers; omitzero is not applied, since it changes what the JSON says.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-16 19:25:40 -07:00

577 lines
11 KiB
Go

package file
import (
"testing"
"github.com/hanzoai/ingress-parser/parser"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_decodeRawToNode(t *testing.T) {
testCases := []struct {
desc string
data map[string]any
expected *parser.Node
}{
{
desc: "empty",
data: map[string]any{},
expected: &parser.Node{
Name: "ingress",
},
},
{
desc: "string",
data: map[string]any{
"foo": "bar",
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "bar"},
},
},
},
{
desc: "string named type",
data: map[string]any{
"foo": bar("bar"),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "bar"},
},
},
},
{
desc: "bool",
data: map[string]any{
"foo": true,
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "true"},
},
},
},
{
desc: "int",
data: map[string]any{
"foo": 1,
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "int8",
data: map[string]any{
"foo": int8(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "int16",
data: map[string]any{
"foo": int16(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "int32",
data: map[string]any{
"foo": int32(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "int64",
data: map[string]any{
"foo": int64(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "uint",
data: map[string]any{
"foo": uint(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "uint8",
data: map[string]any{
"foo": uint8(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "uint16",
data: map[string]any{
"foo": uint16(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "uint32",
data: map[string]any{
"foo": uint32(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "uint64",
data: map[string]any{
"foo": uint64(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "float32",
data: map[string]any{
"foo": float32(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "float64",
data: map[string]any{
"foo": float64(1),
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "1"},
},
},
},
{
desc: "string slice",
data: map[string]any{
"foo": []string{"A", "B"},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘24â•‘Aâ•‘B"},
},
},
},
{
desc: "int slice",
data: map[string]any{
"foo": []int{1, 2},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘2â•‘1â•‘2"},
},
},
},
{
desc: "int8 slice",
data: map[string]any{
"foo": []int8{1, 2},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘3â•‘1â•‘2"},
},
},
},
{
desc: "int16 slice",
data: map[string]any{
"foo": []int16{1, 2},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘4â•‘1â•‘2"},
},
},
},
{
desc: "int32 slice",
data: map[string]any{
"foo": []int32{1, 2},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘5â•‘1â•‘2"},
},
},
},
{
desc: "int64 slice",
data: map[string]any{
"foo": []int64{1, 2},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘6â•‘1â•‘2"},
},
},
},
{
desc: "bool slice",
data: map[string]any{
"foo": []bool{true, false},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘1â•‘trueâ•‘false"},
},
},
},
{
desc: "interface (string) slice",
data: map[string]any{
"foo": []any{"A", "B"},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘24â•‘Aâ•‘B"},
},
},
},
{
desc: "interface (int) slice",
data: map[string]any{
"foo": []any{1, 2},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Value: "â•‘2â•‘1â•‘2"},
},
},
},
{
desc: "2 strings",
data: map[string]any{
"foo": "bar",
"fii": "bir",
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Value: "bir"},
{Name: "foo", Value: "bar"},
},
},
},
{
desc: "string, level 2",
data: map[string]any{
"fii": map[any]any{
"fuu": "bur",
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "bur"}}},
},
},
},
{
desc: "int, level 2",
data: map[string]any{
"fii": map[any]any{
"fuu": 1,
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}},
},
},
},
{
desc: "uint, level 2",
data: map[string]any{
"fii": map[any]any{
"fuu": uint(1),
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}},
},
},
},
{
desc: "bool, level 2",
data: map[string]any{
"fii": map[any]any{
"fuu": true,
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "true"}}},
},
},
},
{
desc: "string, level 3",
data: map[string]any{
"foo": map[any]any{
"fii": map[any]any{
"fuu": "bur",
},
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "bur"}}},
}},
},
},
},
{
desc: "int, level 3",
data: map[string]any{
"fii": map[any]any{
"fuu": 1,
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}},
},
},
},
{
desc: "uint, level 3",
data: map[string]any{
"fii": map[any]any{
"fuu": uint(1),
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "1"}}},
},
},
},
{
desc: "bool, level 3",
data: map[string]any{
"fii": map[any]any{
"fuu": true,
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii", Children: []*parser.Node{{Name: "fuu", Value: "true"}}},
},
},
},
{
desc: "struct",
data: map[string]any{
"foo": map[any]any{
"field1": "C",
"field2": "C",
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Children: []*parser.Node{
{Name: "field1", Value: "C"},
{Name: "field2", Value: "C"},
}},
},
},
},
{
desc: "slice struct 1",
data: map[string]any{
"foo": []map[string]any{
{"field1": "A", "field2": "A"},
{"field1": "B", "field2": "B"},
{"field2": "C", "field1": "C"},
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Children: []*parser.Node{
{Name: "[0]", Children: []*parser.Node{
{Name: "field1", Value: "A"},
{Name: "field2", Value: "A"},
}},
{Name: "[1]", Children: []*parser.Node{
{Name: "field1", Value: "B"},
{Name: "field2", Value: "B"},
}},
{Name: "[2]", Children: []*parser.Node{
{Name: "field1", Value: "C"},
{Name: "field2", Value: "C"},
}},
}},
},
},
},
{
desc: "slice struct 2",
data: map[string]any{
"foo": []any{
map[any]any{
"field2": "A",
"field1": "A",
},
map[any]any{
"field1": "B",
"field2": "B",
},
map[any]any{
"field1": "C",
"field2": "C",
},
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "foo", Children: []*parser.Node{
{Name: "[0]", Children: []*parser.Node{
{Name: "field1", Value: "A"},
{Name: "field2", Value: "A"},
}},
{Name: "[1]", Children: []*parser.Node{
{Name: "field1", Value: "B"},
{Name: "field2", Value: "B"},
}},
{Name: "[2]", Children: []*parser.Node{
{Name: "field1", Value: "C"},
{Name: "field2", Value: "C"},
}},
}},
},
},
},
{
desc: "nil value",
data: map[string]any{
"fii": map[any]any{
"fuu": nil,
},
},
expected: &parser.Node{
Name: "ingress",
Children: []*parser.Node{
{Name: "fii"},
},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
node, err := decodeRawToNode(test.data)
require.NoError(t, err)
assert.Equal(t, test.expected, node)
})
}
}
func Test_decodeRawToNode_errors(t *testing.T) {
testCases := []struct {
desc string
data map[string]any
}{
{
desc: "invalid type",
data: map[string]any{
"foo": struct{}{},
},
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
_, err := decodeRawToNode(test.data)
require.Error(t, err)
})
}
}