github.com/nuvolaris/goja@v0.0.0-20230825100449-967811910c6d/object_goslice_test.go (about)

     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  }