|
1 | 1 | package stdlib_test |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
4 | 5 | "fmt" |
| 6 | + "math/rand" |
| 7 | + "sort" |
| 8 | + "strings" |
5 | 9 | "testing" |
6 | 10 | "time" |
7 | 11 |
|
@@ -72,6 +76,81 @@ if !is_error(cmd) { |
72 | 76 |
|
73 | 77 | } |
74 | 78 |
|
| 79 | +func TestSortModule(t *testing.T) { |
| 80 | + // normal |
| 81 | + expect(t, ` |
| 82 | +sort := import("sort") |
| 83 | +a := [4, 5, 3, 1, 2] |
| 84 | +a = sort.sort(a, func(i, j) { |
| 85 | + return a[i] < a[j] |
| 86 | +}) |
| 87 | +out := import("json").encode(a) |
| 88 | +`, []byte("[1,2,3,4,5]")) |
| 89 | + |
| 90 | + // generate random sequences for sorting |
| 91 | + rand.Seed(time.Now().UnixNano()) |
| 92 | + generateRandomSequence := func() []int { |
| 93 | + length := 1 + rand.Intn(1000) |
| 94 | + arr := make([]int, length) |
| 95 | + for i := 0; i < length; i++ { |
| 96 | + arr[i] = rand.Intn(1000000) |
| 97 | + } |
| 98 | + return arr |
| 99 | + } |
| 100 | + for i := 0; i < 500; i++ { |
| 101 | + seq := generateRandomSequence() |
| 102 | + seqBytes, _ := json.Marshal(seq) |
| 103 | + sort.Ints(seq) |
| 104 | + sortResult, _ := json.Marshal(seq) |
| 105 | + expect(t, fmt.Sprintf(` |
| 106 | +sort := import("sort") |
| 107 | +a := %s |
| 108 | +a = sort.sort(a, func(i, j) { |
| 109 | + return a[i] < a[j] |
| 110 | +}) |
| 111 | +out := import("json").encode(a) |
| 112 | +`, string(seqBytes)), sortResult) |
| 113 | + } |
| 114 | + |
| 115 | + // less is not a function |
| 116 | + expectErr(t, ` |
| 117 | +sort := import("sort") |
| 118 | +a := [4, 5, 3, 1, 2] |
| 119 | +a = sort.sort(a, 0) |
| 120 | +out := import("json").encode(a)`, "Runtime Error: not callable: int") |
| 121 | + |
| 122 | + // arr is not an array |
| 123 | + expectErr(t, ` |
| 124 | +sort := import("sort") |
| 125 | +a := 12345 |
| 126 | +a = sort.sort(a, func(i, j) { |
| 127 | + return a[i] < a[j] |
| 128 | +}) |
| 129 | +out := import("json").encode(a)`, "Runtime Error: invalid type for argument 'first' in call to 'builtin-function:len': expected array/s") |
| 130 | + |
| 131 | + // empty array |
| 132 | + expect(t, ` |
| 133 | +sort := import("sort") |
| 134 | +a := [] |
| 135 | +a = sort.sort(a, func(i, j) { |
| 136 | + return a[i] < a[j] |
| 137 | +}) |
| 138 | +out := import("json").encode(a)`, []byte("[]")) |
| 139 | + |
| 140 | + // sort json |
| 141 | + expect(t, ` |
| 142 | +sort := import("sort") |
| 143 | +a := [{"age": 12, "name": "A"}, {"age": 18, "name": "B"}, {"age": 9, "name": "C"}, {"age": 10, "name": "D"}, {"age": 21, "name": "E"}] |
| 144 | +a = sort.sort(a, func(i, j) { |
| 145 | + return a[i].age < a[j].age |
| 146 | +}) |
| 147 | +out := [] |
| 148 | +for item in a { |
| 149 | + out = append(out, item.name) |
| 150 | +} |
| 151 | +out = import("json").encode(out)`, []byte(`["C","D","A","B","E"]`)) |
| 152 | +} |
| 153 | + |
75 | 154 | func TestGetModules(t *testing.T) { |
76 | 155 | mods := stdlib.GetModuleMap() |
77 | 156 | require.Equal(t, 0, mods.Len()) |
@@ -240,3 +319,10 @@ func expect(t *testing.T, input string, expected interface{}) { |
240 | 319 | require.NotNil(t, v) |
241 | 320 | require.Equal(t, expected, v.Value()) |
242 | 321 | } |
| 322 | + |
| 323 | +func expectErr(t *testing.T, input string, errMsg string) { |
| 324 | + s := tengo.NewScript([]byte(input)) |
| 325 | + s.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...)) |
| 326 | + _, err := s.Run() |
| 327 | + require.True(t, strings.Contains(err.Error(), errMsg)) |
| 328 | +} |
0 commit comments