2024-11-06 16:42:45 +01:00
|
|
|
package literal
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
|
2024-11-12 12:14:58 +01:00
|
|
|
"github.com/ipfs/go-cid"
|
2024-11-06 16:42:45 +01:00
|
|
|
"github.com/ipld/go-ipld-prime/datamodel"
|
2024-11-12 12:14:58 +01:00
|
|
|
cidlink "github.com/ipld/go-ipld-prime/linking/cid"
|
2024-11-06 16:42:45 +01:00
|
|
|
"github.com/ipld/go-ipld-prime/printer"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
2024-12-02 11:59:16 +01:00
|
|
|
|
2024-11-29 13:00:00 +01:00
|
|
|
"github.com/ucan-wg/go-ucan/pkg/policy/limits"
|
2024-11-06 16:42:45 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestList(t *testing.T) {
|
|
|
|
|
n, err := List([]int{1, 2, 3})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_List, n.Kind())
|
|
|
|
|
require.Equal(t, int64(3), n.Length())
|
|
|
|
|
require.Equal(t, `list{
|
|
|
|
|
0: int{1}
|
|
|
|
|
1: int{2}
|
|
|
|
|
2: int{3}
|
|
|
|
|
}`, printer.Sprint(n))
|
|
|
|
|
|
|
|
|
|
n, err = List([][]int{{1, 2, 3}, {4, 5, 6}})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_List, n.Kind())
|
|
|
|
|
require.Equal(t, int64(2), n.Length())
|
|
|
|
|
require.Equal(t, `list{
|
|
|
|
|
0: list{
|
|
|
|
|
0: int{1}
|
|
|
|
|
1: int{2}
|
|
|
|
|
2: int{3}
|
|
|
|
|
}
|
|
|
|
|
1: list{
|
|
|
|
|
0: int{4}
|
|
|
|
|
1: int{5}
|
|
|
|
|
2: int{6}
|
|
|
|
|
}
|
|
|
|
|
}`, printer.Sprint(n))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestMap(t *testing.T) {
|
|
|
|
|
n, err := Map(map[string]any{
|
|
|
|
|
"bool": true,
|
|
|
|
|
"string": "foobar",
|
|
|
|
|
"bytes": []byte{1, 2, 3, 4},
|
|
|
|
|
"int": 1234,
|
|
|
|
|
"uint": uint(12345),
|
|
|
|
|
"float": 1.45,
|
|
|
|
|
"slice": []int{1, 2, 3},
|
|
|
|
|
"array": [2]int{1, 2},
|
|
|
|
|
"map": map[string]any{
|
|
|
|
|
"foo": "bar",
|
|
|
|
|
"foofoo": map[string]string{
|
|
|
|
|
"barbar": "foo",
|
|
|
|
|
},
|
|
|
|
|
},
|
2024-11-12 12:14:58 +01:00
|
|
|
"link": cid.MustParse("bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm"),
|
2024-11-06 16:42:45 +01:00
|
|
|
})
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
v, err := n.LookupByString("bool")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Bool, v.Kind())
|
|
|
|
|
require.Equal(t, true, must(v.AsBool()))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("string")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_String, v.Kind())
|
|
|
|
|
require.Equal(t, "foobar", must(v.AsString()))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("bytes")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Bytes, v.Kind())
|
|
|
|
|
require.Equal(t, []byte{1, 2, 3, 4}, must(v.AsBytes()))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("int")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Int, v.Kind())
|
|
|
|
|
require.Equal(t, int64(1234), must(v.AsInt()))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("uint")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Int, v.Kind())
|
|
|
|
|
require.Equal(t, int64(12345), must(v.AsInt()))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("float")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Float, v.Kind())
|
|
|
|
|
require.Equal(t, 1.45, must(v.AsFloat()))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("slice")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_List, v.Kind())
|
|
|
|
|
require.Equal(t, int64(3), v.Length())
|
|
|
|
|
require.Equal(t, `list{
|
|
|
|
|
0: int{1}
|
|
|
|
|
1: int{2}
|
|
|
|
|
2: int{3}
|
|
|
|
|
}`, printer.Sprint(v))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("array")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_List, v.Kind())
|
|
|
|
|
require.Equal(t, int64(2), v.Length())
|
|
|
|
|
require.Equal(t, `list{
|
|
|
|
|
0: int{1}
|
|
|
|
|
1: int{2}
|
|
|
|
|
}`, printer.Sprint(v))
|
|
|
|
|
|
|
|
|
|
v, err = n.LookupByString("map")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Map, v.Kind())
|
|
|
|
|
require.Equal(t, int64(2), v.Length())
|
|
|
|
|
require.Equal(t, `map{
|
|
|
|
|
string{"foo"}: string{"bar"}
|
|
|
|
|
string{"foofoo"}: map{
|
|
|
|
|
string{"barbar"}: string{"foo"}
|
|
|
|
|
}
|
|
|
|
|
}`, printer.Sprint(v))
|
2024-11-12 12:14:58 +01:00
|
|
|
|
|
|
|
|
v, err = n.LookupByString("link")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Link, v.Kind())
|
|
|
|
|
asLink, err := v.AsLink()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.True(t, asLink.(cidlink.Link).Equals(cid.MustParse("bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm")))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestAny(t *testing.T) {
|
|
|
|
|
data := map[string]any{
|
|
|
|
|
"bool": true,
|
|
|
|
|
"string": "foobar",
|
|
|
|
|
"bytes": []byte{1, 2, 3, 4},
|
|
|
|
|
"int": 1234,
|
|
|
|
|
"uint": uint(12345),
|
|
|
|
|
"float": 1.45,
|
|
|
|
|
"slice": []int{1, 2, 3},
|
|
|
|
|
"array": [2]int{1, 2},
|
|
|
|
|
"map": map[string]any{
|
|
|
|
|
"foo": "bar",
|
|
|
|
|
"foofoo": map[string]string{
|
|
|
|
|
"barbar": "foo",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"link": cid.MustParse("bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm"),
|
|
|
|
|
"func": func() {},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v, err := Any(data["bool"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Bool, v.Kind())
|
|
|
|
|
require.Equal(t, true, must(v.AsBool()))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["string"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_String, v.Kind())
|
|
|
|
|
require.Equal(t, "foobar", must(v.AsString()))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["bytes"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Bytes, v.Kind())
|
|
|
|
|
require.Equal(t, []byte{1, 2, 3, 4}, must(v.AsBytes()))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["int"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Int, v.Kind())
|
|
|
|
|
require.Equal(t, int64(1234), must(v.AsInt()))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["uint"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Int, v.Kind())
|
|
|
|
|
require.Equal(t, int64(12345), must(v.AsInt()))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["float"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Float, v.Kind())
|
|
|
|
|
require.Equal(t, 1.45, must(v.AsFloat()))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["slice"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_List, v.Kind())
|
|
|
|
|
require.Equal(t, int64(3), v.Length())
|
|
|
|
|
require.Equal(t, `list{
|
|
|
|
|
0: int{1}
|
|
|
|
|
1: int{2}
|
|
|
|
|
2: int{3}
|
|
|
|
|
}`, printer.Sprint(v))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["array"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_List, v.Kind())
|
|
|
|
|
require.Equal(t, int64(2), v.Length())
|
|
|
|
|
require.Equal(t, `list{
|
|
|
|
|
0: int{1}
|
|
|
|
|
1: int{2}
|
|
|
|
|
}`, printer.Sprint(v))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["map"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Map, v.Kind())
|
|
|
|
|
require.Equal(t, int64(2), v.Length())
|
|
|
|
|
require.Equal(t, `map{
|
|
|
|
|
string{"foo"}: string{"bar"}
|
|
|
|
|
string{"foofoo"}: map{
|
|
|
|
|
string{"barbar"}: string{"foo"}
|
|
|
|
|
}
|
|
|
|
|
}`, printer.Sprint(v))
|
|
|
|
|
|
|
|
|
|
v, err = Any(data["link"])
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.Equal(t, datamodel.Kind_Link, v.Kind())
|
|
|
|
|
asLink, err := v.AsLink()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.True(t, asLink.(cidlink.Link).Equals(cid.MustParse("bafzbeigai3eoy2ccc7ybwjfz5r3rdxqrinwi4rwytly24tdbh6yk7zslrm")))
|
|
|
|
|
|
2024-11-29 13:00:00 +01:00
|
|
|
_, err = Any(data["func"])
|
2024-11-12 12:14:58 +01:00
|
|
|
require.Error(t, err)
|
2024-11-06 16:42:45 +01:00
|
|
|
}
|
|
|
|
|
|
2024-11-12 13:05:48 +01:00
|
|
|
func BenchmarkAny(b *testing.B) {
|
|
|
|
|
b.Run("bool", func(b *testing.B) {
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
|
_, _ = Any(true)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
b.Run("string", func(b *testing.B) {
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
|
_, _ = Any("foobar")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
b.Run("bytes", func(b *testing.B) {
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
|
_, _ = Any([]byte{1, 2, 3, 4})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
b.Run("map", func(b *testing.B) {
|
|
|
|
|
b.ReportAllocs()
|
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
|
_, _ = Any(map[string]any{
|
|
|
|
|
"foo": "bar",
|
|
|
|
|
"foofoo": map[string]string{
|
|
|
|
|
"barbar": "foo",
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-29 13:00:00 +01:00
|
|
|
func TestAnyAssembleIntegerOverflow(t *testing.T) {
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
input interface{}
|
|
|
|
|
shouldErr bool
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "valid int",
|
|
|
|
|
input: 42,
|
|
|
|
|
shouldErr: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "max safe int",
|
|
|
|
|
input: limits.MaxInt53,
|
|
|
|
|
shouldErr: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "min safe int",
|
|
|
|
|
input: limits.MinInt53,
|
|
|
|
|
shouldErr: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "overflow int",
|
|
|
|
|
input: int64(limits.MaxInt53 + 1),
|
|
|
|
|
shouldErr: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "underflow int",
|
|
|
|
|
input: int64(limits.MinInt53 - 1),
|
|
|
|
|
shouldErr: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "overflow uint",
|
|
|
|
|
input: uint64(limits.MaxInt53 + 1),
|
|
|
|
|
shouldErr: true,
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2024-12-02 11:59:16 +01:00
|
|
|
_, err := Any(tt.input)
|
2024-11-29 13:00:00 +01:00
|
|
|
if tt.shouldErr {
|
2024-12-02 11:59:16 +01:00
|
|
|
require.Error(t, err)
|
2024-11-29 13:00:00 +01:00
|
|
|
} else {
|
2024-12-02 11:59:16 +01:00
|
|
|
require.NoError(t, err)
|
2024-11-29 13:00:00 +01:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-06 16:42:45 +01:00
|
|
|
func must[T any](t T, err error) T {
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
}
|
|
|
|
|
return t
|
|
|
|
|
}
|