tutus-chain/pkg/compiler/map_test.go

323 lines
4.7 KiB
Go
Executable File

package compiler_test
import (
"math/big"
"testing"
"git.marketally.com/tutus-one/tutus-chain/pkg/vm/stackitem"
)
var mapTestCases = []testCase{
{
"map composite literal",
`
package foo
func Main() int {
t := map[int]int{
1: 6,
2: 9,
}
age := t[2]
return age
}
`,
big.NewInt(9),
},
{
"nested map",
`
package foo
func Main() int {
t := map[int]map[int]int{
1: map[int]int{2: 5, 3: 1},
2: nil,
5: map[int]int{3: 4, 7: 2},
}
x := t[5][3]
return x
}
`,
big.NewInt(4),
},
{
"map with string index",
`
package foo
func Main() string {
t := map[string]string{
"name": "Valera",
"age": "33",
}
name := t["name"]
return name
}
`,
[]byte("Valera"),
},
{
"delete key",
`package foo
func Main() int {
m := map[int]int{1: 2, 3: 4}
delete(m, 1)
return len(m)
}`,
big.NewInt(1),
},
{
"delete missing key",
`package foo
func Main() int {
m := map[int]int{3: 4}
delete(m, 1)
return len(m)
}`,
big.NewInt(1),
},
{
"int value, existing",
`package foo
func Main() int {
var m = map[string]int{
"key": 1,
}
v, ok := m["key"]
if !ok {
panic("key is missing")
}
return v
}`,
big.NewInt(1),
},
{
"int value, missing",
`package foo
func Main() int {
var m = make(map[string]int)
v, ok := m["unknown"]
if ok {
panic("key is existing")
}
return v
}`,
big.NewInt(0),
},
{
"slice value, existing",
`package foo
func Main() []int {
var m = map[string][]int{
"key": []int{0, 1, 2},
}
var v, ok = m["key"]
if !ok {
panic("key is missing")
}
return v
}`,
[]stackitem.Item{stackitem.Make(0), stackitem.Make(1), stackitem.Make(2)},
},
{
"slice value, missing",
`package foo
func Main() []int {
var m = make(map[string][]int)
var v, ok = m["unknown"]
if ok {
panic("key is existing")
}
return v
}`,
nil,
},
{
"map value, missing",
`package foo
func Main() map[string]int {
var m = make(map[string]map[string]int)
v, ok := m["unknown"]
if ok {
panic("key is existing")
}
return v
}`,
nil,
},
{
"struct value, missing",
`package foo
type S struct {
A int
}
func Main() S {
var m = make(map[string]S)
var v, ok = m["key"]
if ok {
panic("key is existing")
}
return v
}`,
[]stackitem.Item{stackitem.Make(0)},
},
{
"if with comma-ok idiom",
`package foo
func Main() bool {
var m = map[string]int{
"key": 1,
}
if v, ok := m["key"]; !ok || v != 1{
return false
}
if _, ok := m["unknown"]; ok {
return false
}
return true
}`,
true,
},
{
"map returned from function, existing",
`package foo
func Get() map[string]int {
return map[string]int{"key": 1}
}
func Main() int {
var v, ok = Get()["key"]
if !ok {
panic("key is missing")
}
return v
}`,
big.NewInt(1),
},
{
"drop value, existing",
`package foo
func Main() bool {
var m = map[string]int{
"key": 1,
}
_, ok := m["key"]
return ok
}`,
true,
},
{
"drop flag, existing",
`package foo
func Main() int {
var m = map[string]int{
"key": 1,
}
var v, _ = m["key"]
return v
}`,
big.NewInt(1),
},
{
"drop value, missing",
`package foo
func Main() bool {
var m = make(map[string]int)
var _, ok = m["unknown"]
return ok
}`,
false,
},
{
"drop flag, missing",
`package foo
func Main() int {
var m = make(map[string]int)
v, _ := m["unknown"]
return v
}`,
big.NewInt(0),
},
{
"drop value and flag, missing",
`package foo
var v int
func getKey() string {
v = 5
return "key"
}
func Main() int {
var m = map[string]int{
"key": 1,
}
_, _ = m[getKey()]
return v
}`,
big.NewInt(5),
},
{
"swap map elements",
`package foo
func Main() map[string]int {
m := map[string]int{"a":1, "b":2}
m["a"], m["b"] = m["b"], m["a"]
return m
}
`,
[]stackitem.MapElement{
{
Key: stackitem.Make("a"),
Value: stackitem.Make(2),
},
{
Key: stackitem.Make("b"),
Value: stackitem.Make(1),
},
},
},
{
"range, over nil map",
`package foo
func Main() int {
var s map[any]any
cnt := 0
for range s {
cnt++
}
return cnt
}`,
big.NewInt(0),
},
{
"range, over nil map returned by func",
`package foo
func get() map[any]any { return nil }
func Main() int {
cnt := 0
for range get() {
cnt++
}
return cnt
}`,
big.NewInt(0),
},
{
"range, over nil with side-effects",
`package foo
func Main() int {
var (
i = 42
a map[int]any
)
for i = range a {
}
return i
}`,
big.NewInt(42),
},
}
func TestMaps(t *testing.T) {
runTestCases(t, mapTestCases)
}