1 package goja
2
3 import (
4 "testing"
5 )
6
7 func TestGoSliceBasic(t *testing.T) {
8 const SCRIPT = `
9 var sum = 0;
10 for (var i = 0; i < a.length; i++) {
11 sum += a[i];
12 }
13 sum;
14 `
15 r := New()
16 r.Set("a", []interface{}{1, 2, 3, 4})
17 v, err := r.RunString(SCRIPT)
18 if err != nil {
19 t.Fatal(err)
20 }
21 if i := v.ToInteger(); i != 10 {
22 t.Fatalf("Expected 10, got: %d", i)
23 }
24 }
25
26 func TestGoSliceIn(t *testing.T) {
27 const SCRIPT = `
28 var idx = "";
29 for (var i in a) {
30 idx += i;
31 }
32 idx;
33 `
34 r := New()
35 r.Set("a", []interface{}{1, 2, 3, 4})
36 v, err := r.RunString(SCRIPT)
37 if err != nil {
38 t.Fatal(err)
39 }
40 if i := v.String(); i != "0123" {
41 t.Fatalf("Expected '0123', got: '%s'", i)
42 }
43 }
44
45 func TestGoSliceExpand(t *testing.T) {
46 const SCRIPT = `
47 var l = a.length;
48 for (var i = 0; i < l; i++) {
49 a[l + i] = a[i] * 2;
50 }
51
52 var sum = 0;
53 for (var i = 0; i < a.length; i++) {
54 sum += a[i];
55 }
56 sum;
57 `
58 r := New()
59 a := []interface{}{int64(1), int64(2), int64(3), int64(4)}
60 r.Set("a", &a)
61 v, err := r.RunString(SCRIPT)
62 if err != nil {
63 t.Fatal(err)
64 }
65 sum := int64(0)
66 for _, v := range a {
67 sum += v.(int64)
68 }
69 if i := v.ToInteger(); i != sum {
70 t.Fatalf("Expected %d, got: %d", sum, i)
71 }
72 }
73
74 func TestGoSliceProtoMethod(t *testing.T) {
75 const SCRIPT = `
76 a.join(",")
77 `
78
79 r := New()
80 a := []interface{}{1, 2, 3, 4}
81 r.Set("a", a)
82 ret, err := r.RunString(SCRIPT)
83 if err != nil {
84 t.Fatal(err)
85 }
86 if s := ret.String(); s != "1,2,3,4" {
87 t.Fatalf("Unexpected result: '%s'", s)
88 }
89 }
90
91 func TestGoSliceSetLength(t *testing.T) {
92 r := New()
93 a := []interface{}{1, 2, 3, 4}
94 r.Set("a", &a)
95 _, err := r.RunString(`
96 'use strict';
97 a.length = 3;
98 if (a.length !== 3) {
99 throw new Error("length="+a.length);
100 }
101 if (a[3] !== undefined) {
102 throw new Error("a[3](1)="+a[3]);
103 }
104 a.length = 5;
105 if (a.length !== 5) {
106 throw new Error("length="+a.length);
107 }
108 if (a[3] !== null) {
109 throw new Error("a[3](2)="+a[3]);
110 }
111 if (a[4] !== null) {
112 throw new Error("a[4]="+a[4]);
113 }
114 `)
115 if err != nil {
116 t.Fatal(err)
117 }
118 }
119
120 func TestGoSliceProto(t *testing.T) {
121 r := New()
122 a := []interface{}{1, nil, 3}
123 r.Set("a", &a)
124 r.testScriptWithTestLib(`
125 var proto = [,2,,4];
126 Object.setPrototypeOf(a, proto);
127 assert.sameValue(a[1], null, "a[1]");
128 assert.sameValue(a[3], 4, "a[3]");
129 var desc = Object.getOwnPropertyDescriptor(a, "1");
130 assert.sameValue(desc.value, null, "desc.value");
131 assert(desc.writable, "writable");
132 assert(desc.enumerable, "enumerable");
133 assert(!desc.configurable, "configurable");
134 var v5;
135 Object.defineProperty(proto, "5", {
136 set: function(v) {
137 v5 = v;
138 }
139 });
140 a[5] = "test";
141 assert.sameValue(v5, "test", "v5");
142 `, _undefined, t)
143 }
144
145 func TestGoSliceProtoProto(t *testing.T) {
146 r := New()
147 a := []interface{}{1, nil, 3}
148 proto := []interface{}{1, 2, 3, 4}
149 r.Set("a", &a)
150 r.Set("proto", proto)
151 _, err := r.RunString(`
152 "use strict";
153 var protoproto = Object.create(null);
154 Object.defineProperty(protoproto, "3", {
155 value: 42
156 });
157 Object.setPrototypeOf(proto, protoproto);
158 Object.setPrototypeOf(a, proto);
159 a[3] = 11;
160 if (a[3] !== 11) {
161 throw new Error("a[3]=" + a[3]);
162 }
163 `)
164 if err != nil {
165 t.Fatal(err)
166 }
167 }
168
169 func TestGoSliceDelete(t *testing.T) {
170 r := New()
171 a := []interface{}{1, nil, 3}
172 r.Set("a", a)
173 v, err := r.RunString(`
174 delete a[0] && delete a[1] && delete a[3];
175 `)
176 if err != nil {
177 t.Fatal(err)
178 }
179 if v != valueTrue {
180 t.Fatalf("not true: %v", v)
181 }
182 }
183
184 func TestGoSlicePop(t *testing.T) {
185 r := New()
186 a := []interface{}{1, nil, 3}
187 r.Set("a", &a)
188 v, err := r.RunString(`
189 a.pop()
190 `)
191 if err != nil {
192 t.Fatal(err)
193 }
194 if !v.SameAs(intToValue(3)) {
195 t.Fatal(v)
196 }
197 }
198
199 func TestGoSlicePopNoPtr(t *testing.T) {
200 r := New()
201 a := []interface{}{1, nil, 3}
202 r.Set("a", a)
203 v, err := r.RunString(`
204 a.pop()
205 `)
206 if err != nil {
207 t.Fatal(err)
208 }
209 if !v.SameAs(intToValue(3)) {
210 t.Fatal(v)
211 }
212 }
213
214 func TestGoSliceShift(t *testing.T) {
215 r := New()
216 a := []interface{}{1, nil, 3}
217 r.Set("a", &a)
218 v, err := r.RunString(`
219 a.shift()
220 `)
221 if err != nil {
222 t.Fatal(err)
223 }
224 if !v.SameAs(intToValue(1)) {
225 t.Fatal(v)
226 }
227 }
228
229 func TestGoSliceLengthProperty(t *testing.T) {
230 vm := New()
231 vm.Set("s", []interface{}{2, 3, 4})
232 _, err := vm.RunString(`
233 if (!s.hasOwnProperty("length")) {
234 throw new Error("hasOwnProperty() returned false");
235 }
236 let desc = Object.getOwnPropertyDescriptor(s, "length");
237 if (desc.value !== 3 || !desc.writable || desc.enumerable || desc.configurable) {
238 throw new Error("incorrect property descriptor: " + JSON.stringify(desc));
239 }
240 `)
241 if err != nil {
242 t.Fatal(err)
243 }
244 }
245
246 func TestGoSliceSort(t *testing.T) {
247 vm := New()
248 s := []interface{}{4, 2, 3}
249 vm.Set("s", &s)
250 _, err := vm.RunString(`s.sort()`)
251 if err != nil {
252 t.Fatal(err)
253 }
254 if len(s) != 3 {
255 t.Fatalf("len: %d", len(s))
256 }
257 if s[0] != 2 || s[1] != 3 || s[2] != 4 {
258 t.Fatalf("val: %v", s)
259 }
260 }
261
262 func TestGoSliceToString(t *testing.T) {
263 vm := New()
264 s := []interface{}{4, 2, 3}
265 vm.Set("s", &s)
266 res, err := vm.RunString("`${s}`")
267 if err != nil {
268 t.Fatal(err)
269 }
270 if exp := res.Export(); exp != "4,2,3" {
271 t.Fatal(exp)
272 }
273 }
274
275 func TestGoSliceExternalLenUpdate(t *testing.T) {
276 data := &[]interface{}{1}
277
278 vm := New()
279 vm.Set("data", data)
280 vm.Set("append", func(a *[]interface{}, v int) {
281 if a != data {
282 panic(vm.NewTypeError("a != data"))
283 }
284 *a = append(*a, v)
285 })
286
287 vm.testScriptWithTestLib(`
288 assert.sameValue(data.length, 1);
289
290 // modify with js
291 data.push(1);
292 assert.sameValue(data.length, 2);
293
294 // modify with go
295 append(data, 2);
296 assert.sameValue(data.length, 3);
297 `, _undefined, t)
298 }
299
View as plain text