Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
707 lines
12 KiB
Go
707 lines
12 KiB
Go
package expr
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var (
|
|
intArr = []int{}
|
|
stringArr = []string{"first"}
|
|
boolArr = []bool{true, true, false}
|
|
floatArr = []float64{69.420}
|
|
strArr = []string{"5", "3", "1", "2"}
|
|
|
|
vals = map[string]interface{}{
|
|
"intArr": intArr,
|
|
"stringArr": stringArr,
|
|
"boolArr": boolArr,
|
|
"floatArr": floatArr,
|
|
"strArr": strArr,
|
|
"intVal": 42,
|
|
"stringVal": "foobar",
|
|
"boolVal": false,
|
|
}
|
|
)
|
|
|
|
func Example_push_int() {
|
|
eval(`push(intArr, intVal)`, vals)
|
|
|
|
// output:
|
|
// [42]
|
|
}
|
|
|
|
func Example_push_string() {
|
|
eval(`push(stringArr, stringVal)`, vals)
|
|
|
|
// output:
|
|
// [first foobar]
|
|
}
|
|
|
|
func Example_push_bool() {
|
|
eval(`push(boolArr, boolVal)`, vals)
|
|
|
|
// output:
|
|
// [true true false false]
|
|
}
|
|
|
|
func Example_push_float() {
|
|
eval(`push(floatArr, 3.14)`, vals)
|
|
|
|
// output:
|
|
// [69.42 3.14]
|
|
}
|
|
|
|
func Example_pop_string() {
|
|
eval(`pop(stringArr)`, vals)
|
|
|
|
// output:
|
|
// first
|
|
}
|
|
|
|
func Example_pop_int() {
|
|
eval(`pop(intArr)`, vals)
|
|
|
|
// output:
|
|
// <nil>
|
|
}
|
|
|
|
func Example_pop_float() {
|
|
eval(`pop(floatArr)`, vals)
|
|
|
|
// output:
|
|
// 69.42
|
|
}
|
|
|
|
func Example_sort_string_asc() {
|
|
eval(`sort(strArr, false)`, vals)
|
|
|
|
// output:
|
|
// [1 2 3 5]
|
|
}
|
|
|
|
func Example_sort_string_desc() {
|
|
eval(`sort(strArr, true)`, vals)
|
|
|
|
// output:
|
|
// [5 3 2 1]
|
|
}
|
|
|
|
func Test_push(t *testing.T) {
|
|
tcc := []struct {
|
|
base interface{}
|
|
new []interface{}
|
|
expect interface{}
|
|
expError bool
|
|
}{
|
|
{
|
|
base: []string{"1", "2", "3"},
|
|
new: []interface{}{"4"},
|
|
expect: []string{"1", "2", "3", "4"},
|
|
},
|
|
{
|
|
base: Must(NewArray(nil)),
|
|
new: []interface{}{"foo"},
|
|
expect: []TypedValue{Must(NewString("foo"))},
|
|
},
|
|
{
|
|
base: Must(NewArray([]interface{}{"foo"})),
|
|
new: []interface{}{"bar"},
|
|
expect: []TypedValue{Must(NewString("foo")), Must(NewString("bar"))},
|
|
},
|
|
{
|
|
base: Must(NewArray([]interface{}{Must(NewString("foo"))})),
|
|
new: []interface{}{"bar"},
|
|
expect: []TypedValue{Must(NewString("foo")), Must(NewString("bar"))},
|
|
},
|
|
{
|
|
base: Must(NewArray([]interface{}{Must(NewString("foo"))})),
|
|
new: []interface{}{Must(NewString("bar"))},
|
|
expect: []TypedValue{Must(NewString("foo")), Must(NewString("bar"))},
|
|
},
|
|
{
|
|
base: []string{"1", "2", "3"},
|
|
new: []interface{}{4},
|
|
expError: true,
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
out, err = push(tc.base, tc.new...)
|
|
)
|
|
|
|
if tc.expError {
|
|
req.Error(err)
|
|
return
|
|
}
|
|
|
|
req.NoError(err)
|
|
req.Equal(tc.expect, out)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_shift(t *testing.T) {
|
|
tcc := []struct {
|
|
value interface{}
|
|
expect interface{}
|
|
expError bool
|
|
}{
|
|
{
|
|
value: []string{"1", "2", "3"},
|
|
expect: "1",
|
|
},
|
|
{
|
|
value: map[string]string{"test": "123"},
|
|
expect: nil,
|
|
expError: true,
|
|
},
|
|
{
|
|
value: []int{4, 5, 6, 7},
|
|
expect: 4,
|
|
},
|
|
{
|
|
value: []int{},
|
|
expect: nil,
|
|
},
|
|
{
|
|
value: int(1),
|
|
expect: nil,
|
|
expError: true,
|
|
},
|
|
{
|
|
value: []float64{11.1},
|
|
expect: 11.1,
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
val, err = shift(tc.value)
|
|
)
|
|
|
|
if tc.expError {
|
|
req.Error(err)
|
|
return
|
|
}
|
|
|
|
req.NoError(err)
|
|
req.Equal(tc.expect, val)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_find(t *testing.T) {
|
|
tcc := []struct {
|
|
expect interface{}
|
|
arr interface{}
|
|
val interface{}
|
|
}{
|
|
{
|
|
arr: must(CastToArray([]string{"123", "456"})),
|
|
val: "456",
|
|
expect: 1,
|
|
},
|
|
{
|
|
arr: []string{"1", "2", "3"},
|
|
val: "3",
|
|
expect: 2,
|
|
},
|
|
{
|
|
arr: []bool{true, false, true},
|
|
val: true,
|
|
expect: 0,
|
|
},
|
|
{
|
|
arr: []int{4, 5, 6, 7},
|
|
val: 7,
|
|
expect: 3,
|
|
},
|
|
{
|
|
arr: []int{},
|
|
val: 0,
|
|
expect: -1,
|
|
},
|
|
{
|
|
arr: []float64{11.1, 12.4},
|
|
val: 11.1,
|
|
expect: 0,
|
|
},
|
|
{
|
|
arr: []float64{11.1, 12.4},
|
|
val: 11.2,
|
|
expect: -1,
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
loc, err = find(tc.arr, tc.val)
|
|
)
|
|
|
|
req.NoError(err)
|
|
req.Equal(tc.expect, loc)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_count(t *testing.T) {
|
|
tcc := []struct {
|
|
expect interface{}
|
|
arr interface{}
|
|
val []interface{}
|
|
}{
|
|
{
|
|
arr: must(CastToArray([]string{"123"})),
|
|
val: []interface{}{"123", "567"},
|
|
expect: 1,
|
|
},
|
|
{
|
|
arr: []string{"1", "2", "3"},
|
|
val: []interface{}{"0", "3"},
|
|
expect: 1,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{false, false},
|
|
expect: 0,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{false, true},
|
|
expect: 1,
|
|
},
|
|
{
|
|
arr: []int{4, 5, 6, 7},
|
|
val: []interface{}{7, 4},
|
|
expect: 2,
|
|
},
|
|
{
|
|
arr: []float64{11.1, 12.4},
|
|
val: []interface{}{0.1, 1.1},
|
|
expect: 0,
|
|
},
|
|
{
|
|
arr: "foo",
|
|
val: nil,
|
|
expect: 3,
|
|
},
|
|
{
|
|
arr: "foo",
|
|
val: []interface{}{},
|
|
expect: 3,
|
|
},
|
|
{
|
|
arr: "foo bar",
|
|
val: []interface{}{},
|
|
expect: 7,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{},
|
|
expect: 2,
|
|
},
|
|
{
|
|
arr: "foo",
|
|
val: []interface{}{"bar", "baz"},
|
|
expect: 0,
|
|
},
|
|
{
|
|
arr: "foo",
|
|
val: []interface{}{"o", 12},
|
|
expect: 2,
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
err error
|
|
loc int
|
|
)
|
|
|
|
loc, err = count(tc.arr, tc.val...)
|
|
req.NoError(err)
|
|
req.Equal(tc.expect, loc)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_has(t *testing.T) {
|
|
tcc := []struct {
|
|
expect interface{}
|
|
arr interface{}
|
|
val []interface{}
|
|
}{
|
|
{
|
|
arr: []string{"1", "2", "3"},
|
|
val: []interface{}{"0", "3"},
|
|
expect: true,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{false, false},
|
|
expect: false,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{false, true},
|
|
expect: true,
|
|
},
|
|
{
|
|
arr: []int{4, 5, 6, 7},
|
|
val: []interface{}{7, 4},
|
|
expect: true,
|
|
},
|
|
{
|
|
arr: []float64{11.1, 12.4},
|
|
val: []interface{}{0.1, 1.1},
|
|
expect: false,
|
|
},
|
|
{
|
|
arr: map[string]interface{}{"a": 1},
|
|
val: []interface{}{"a", "b"},
|
|
expect: true,
|
|
},
|
|
{
|
|
arr: map[string]interface{}{"a": 1},
|
|
val: []interface{}{"b"},
|
|
expect: false,
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
loc bool
|
|
err error
|
|
)
|
|
|
|
loc, err = Has(tc.arr, tc.val...)
|
|
req.NoError(err)
|
|
req.Equal(tc.expect, loc)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_hasAll(t *testing.T) {
|
|
tcc := []struct {
|
|
arr interface{}
|
|
val []interface{}
|
|
hasAll bool
|
|
expError bool
|
|
}{
|
|
{
|
|
arr: []string{"1", "2", "3"},
|
|
val: []interface{}{"0", "3"},
|
|
hasAll: false,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{false, false},
|
|
hasAll: false,
|
|
},
|
|
{
|
|
arr: []bool{true, true},
|
|
val: []interface{}{false, true},
|
|
hasAll: false,
|
|
},
|
|
{
|
|
arr: []int{4, 5, 6, 7},
|
|
val: []interface{}{7, 4},
|
|
hasAll: true,
|
|
},
|
|
{
|
|
arr: []float64{11.1, 12.4},
|
|
val: []interface{}{0.1, 1.1},
|
|
hasAll: false,
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
rval, err = hasAll(tc.arr, tc.val...)
|
|
)
|
|
|
|
if tc.expError {
|
|
req.Error(err)
|
|
return
|
|
}
|
|
|
|
req.NoError(err)
|
|
req.Equal(tc.hasAll, rval)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_splice(t *testing.T) {
|
|
tcc := []struct {
|
|
vals []float64
|
|
arr interface{}
|
|
expect interface{}
|
|
}{
|
|
{
|
|
vals: []float64{0, 3},
|
|
arr: []string{"1", "2", "3"},
|
|
expect: []string{"1", "2", "3"},
|
|
},
|
|
{
|
|
vals: []float64{0, 1},
|
|
arr: []string{"1", "2", "3"},
|
|
expect: []string{"1"},
|
|
},
|
|
{
|
|
vals: []float64{2, 3},
|
|
arr: []bool{true, true},
|
|
expect: []bool{true, true},
|
|
},
|
|
{
|
|
vals: []float64{1, -1},
|
|
arr: []int{4, 5, 6, 7},
|
|
expect: []int{5, 6, 7},
|
|
},
|
|
{
|
|
vals: []float64{3, -1},
|
|
arr: []float64{11.1, 12.4},
|
|
expect: []float64{11.1, 12.4},
|
|
},
|
|
}
|
|
|
|
for p, tc := range tcc {
|
|
t.Run(fmt.Sprintf("%d", p), func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
ss = splice(tc.arr, tc.vals[0], tc.vals[1])
|
|
)
|
|
|
|
req.Equal(tc.expect, ss)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_sortSlice(t *testing.T) {
|
|
var (
|
|
s1 = Must(NewString("1"))
|
|
s2 = Must(NewString("2"))
|
|
s3 = Must(NewString("3"))
|
|
s5 = Must(NewString("5"))
|
|
|
|
f1 = Must(NewFloat(11.1))
|
|
f2 = Must(NewString(22.2))
|
|
f3 = Must(NewString(33.3))
|
|
f5 = Must(NewString(55.5))
|
|
|
|
a1 = Must(NewAny("1"))
|
|
a2 = Must(NewAny("2"))
|
|
a3 = Must(NewAny("3"))
|
|
a5 = Must(NewAny("5"))
|
|
|
|
tcc = []struct {
|
|
name string
|
|
desc bool
|
|
arr interface{}
|
|
cloneArr interface{}
|
|
expect interface{}
|
|
expectErr error
|
|
}{
|
|
{
|
|
name: "ascending sorting for string array",
|
|
arr: []string{"3", "1", "2", "5"},
|
|
cloneArr: []string{"3", "1", "2", "5"},
|
|
expect: []string{"1", "2", "3", "5"},
|
|
},
|
|
{
|
|
name: "ascending sorting for string array with multiple identical element",
|
|
arr: []string{"1", "3", "2", "2"},
|
|
cloneArr: []string{"1", "3", "2", "2"},
|
|
expect: []string{"1", "2", "2", "3"},
|
|
},
|
|
{
|
|
name: "descending sorting for string array",
|
|
desc: true,
|
|
arr: []string{"3", "1", "2", "5"},
|
|
cloneArr: []string{"3", "1", "2", "5"},
|
|
expect: []string{"5", "3", "2", "1"},
|
|
},
|
|
{
|
|
name: "ascending sorting for int array",
|
|
arr: []int{1, 3, 5, 2},
|
|
cloneArr: []int{1, 3, 5, 2},
|
|
expect: []int{1, 2, 3, 5},
|
|
},
|
|
{
|
|
name: "descending sorting for int array",
|
|
desc: true,
|
|
arr: []int{1, 3, 5, 2},
|
|
cloneArr: []int{1, 3, 5, 2},
|
|
expect: []int{5, 3, 2, 1},
|
|
},
|
|
{
|
|
name: "ascending sorting for float32 array",
|
|
arr: []float32{11.1, 33.3, 55.5, 22.2},
|
|
cloneArr: []float32{11.1, 33.3, 55.5, 22.2},
|
|
expect: []float32{11.1, 22.2, 33.3, 55.5},
|
|
},
|
|
{
|
|
name: "descending sorting for float32 array",
|
|
desc: true,
|
|
arr: []float32{11.1, 33.3, 55.5, 22.2},
|
|
cloneArr: []float32{11.1, 33.3, 55.5, 22.2},
|
|
expect: []float32{55.5, 33.3, 22.2, 11.1},
|
|
},
|
|
{
|
|
name: "ascending sorting for float64 array",
|
|
arr: []float64{11.1, 33.3, 55.5, 22.2},
|
|
cloneArr: []float64{11.1, 33.3, 55.5, 22.2},
|
|
expect: []float64{11.1, 22.2, 33.3, 55.5},
|
|
},
|
|
{
|
|
name: "descending sorting for float64 array",
|
|
desc: true,
|
|
arr: []float64{11.1, 33.3, 55.5, 22.2},
|
|
cloneArr: []float64{11.1, 33.3, 55.5, 22.2},
|
|
expect: []float64{55.5, 33.3, 22.2, 11.1},
|
|
},
|
|
{
|
|
name: "ascending sorting for typedValue array of string",
|
|
arr: []TypedValue{
|
|
s5,
|
|
s3,
|
|
s2,
|
|
s1,
|
|
},
|
|
cloneArr: []TypedValue{
|
|
s5,
|
|
s3,
|
|
s2,
|
|
s1,
|
|
},
|
|
expect: []TypedValue{
|
|
s1,
|
|
s2,
|
|
s3,
|
|
s5,
|
|
},
|
|
},
|
|
{
|
|
name: "descending sorting for typedValue array of string",
|
|
desc: true,
|
|
arr: []TypedValue{
|
|
s3,
|
|
s1,
|
|
s2,
|
|
s5,
|
|
},
|
|
cloneArr: []TypedValue{
|
|
s3,
|
|
s1,
|
|
s2,
|
|
s5,
|
|
},
|
|
expect: []TypedValue{
|
|
s5,
|
|
s3,
|
|
s2,
|
|
s1,
|
|
},
|
|
},
|
|
{
|
|
name: "ascending sorting for typedValue array of float",
|
|
arr: []TypedValue{
|
|
f5,
|
|
f3,
|
|
f2,
|
|
f1,
|
|
},
|
|
cloneArr: []TypedValue{
|
|
f5,
|
|
f3,
|
|
f2,
|
|
f1,
|
|
},
|
|
expect: []TypedValue{
|
|
f1,
|
|
f2,
|
|
f3,
|
|
f5,
|
|
},
|
|
},
|
|
{
|
|
name: "descending sorting for typedValue array of float",
|
|
desc: true,
|
|
arr: []TypedValue{
|
|
f3,
|
|
f1,
|
|
f2,
|
|
f5,
|
|
},
|
|
cloneArr: []TypedValue{
|
|
f3,
|
|
f1,
|
|
f2,
|
|
f5,
|
|
},
|
|
expect: []TypedValue{
|
|
f5,
|
|
f3,
|
|
f2,
|
|
f1,
|
|
},
|
|
},
|
|
{
|
|
name: "expect error due to sorting for typedValue array of Any(Not Comparable)",
|
|
arr: []TypedValue{
|
|
a5,
|
|
a3,
|
|
a2,
|
|
a1,
|
|
},
|
|
cloneArr: []TypedValue{
|
|
a5,
|
|
a3,
|
|
a2,
|
|
a1,
|
|
},
|
|
expectErr: fmt.Errorf("cannot compare Any and Any: unknown state"),
|
|
},
|
|
}
|
|
)
|
|
|
|
for _, tc := range tcc {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
var (
|
|
req = require.New(t)
|
|
)
|
|
|
|
ss, err := sortSlice(tc.arr, tc.desc)
|
|
if tc.expectErr != nil {
|
|
req.Equal(tc.expectErr, err)
|
|
return
|
|
}
|
|
req.NoError(err)
|
|
req.Equal(tc.expect, ss)
|
|
req.Equal(tc.cloneArr, tc.arr)
|
|
})
|
|
}
|
|
}
|
|
|
|
func must(v []TypedValue, err error) []TypedValue {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return v
|
|
}
|