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

     1  package goja
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  func TestGoMapReflectGetSet(t *testing.T) {
     8  	const SCRIPT = `
     9  	m.c = m.a + m.b;
    10  	`
    11  
    12  	vm := New()
    13  	m := map[string]string{
    14  		"a": "4",
    15  		"b": "2",
    16  	}
    17  	vm.Set("m", m)
    18  
    19  	_, err := vm.RunString(SCRIPT)
    20  	if err != nil {
    21  		t.Fatal(err)
    22  	}
    23  
    24  	if c := m["c"]; c != "42" {
    25  		t.Fatalf("Unexpected value: '%s'", c)
    26  	}
    27  }
    28  
    29  func TestGoMapReflectIntKey(t *testing.T) {
    30  	const SCRIPT = `
    31  	m[2] = m[0] + m[1];
    32  	`
    33  
    34  	vm := New()
    35  	m := map[int]int{
    36  		0: 40,
    37  		1: 2,
    38  	}
    39  	vm.Set("m", m)
    40  
    41  	_, err := vm.RunString(SCRIPT)
    42  	if err != nil {
    43  		t.Fatal(err)
    44  	}
    45  
    46  	if c := m[2]; c != 42 {
    47  		t.Fatalf("Unexpected value: '%d'", c)
    48  	}
    49  }
    50  
    51  func TestGoMapReflectDelete(t *testing.T) {
    52  	const SCRIPT = `
    53  	delete m.a;
    54  	`
    55  
    56  	vm := New()
    57  	m := map[string]string{
    58  		"a": "4",
    59  		"b": "2",
    60  	}
    61  	vm.Set("m", m)
    62  
    63  	_, err := vm.RunString(SCRIPT)
    64  	if err != nil {
    65  		t.Fatal(err)
    66  	}
    67  
    68  	if _, exists := m["a"]; exists {
    69  		t.Fatal("a still exists")
    70  	}
    71  
    72  	if b := m["b"]; b != "2" {
    73  		t.Fatalf("Unexpected b: '%s'", b)
    74  	}
    75  }
    76  
    77  func TestGoMapReflectJSON(t *testing.T) {
    78  	const SCRIPT = `
    79  	function f(m) {
    80  		return JSON.stringify(m);
    81  	}
    82  	`
    83  
    84  	vm := New()
    85  	m := map[string]string{
    86  		"t": "42",
    87  	}
    88  	_, err := vm.RunString(SCRIPT)
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  	f := vm.Get("f")
    93  	if call, ok := AssertFunction(f); ok {
    94  		v, err := call(nil, ([]Value{vm.ToValue(m)})...)
    95  		if err != nil {
    96  			t.Fatal(err)
    97  		}
    98  		if !v.StrictEquals(asciiString(`{"t":"42"}`)) {
    99  			t.Fatalf("Unexpected value: %v", v)
   100  		}
   101  	} else {
   102  		t.Fatalf("Not a function: %v", f)
   103  	}
   104  }
   105  
   106  func TestGoMapReflectProto(t *testing.T) {
   107  	const SCRIPT = `
   108  	m.hasOwnProperty("t");
   109  	`
   110  
   111  	vm := New()
   112  	m := map[string]string{
   113  		"t": "42",
   114  	}
   115  	vm.Set("m", m)
   116  	v, err := vm.RunString(SCRIPT)
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	if !v.StrictEquals(valueTrue) {
   121  		t.Fatalf("Expected true, got %v", v)
   122  	}
   123  }
   124  
   125  type gomapReflect_noMethods map[string]interface{}
   126  type gomapReflect_withMethods map[string]interface{}
   127  
   128  func (m gomapReflect_withMethods) Method() bool {
   129  	return true
   130  }
   131  
   132  func TestGoMapReflectNoMethods(t *testing.T) {
   133  	const SCRIPT = `
   134  	typeof m === "object" && m.hasOwnProperty("t") && m.t === 42;
   135  	`
   136  
   137  	vm := New()
   138  	m := make(gomapReflect_noMethods)
   139  	m["t"] = 42
   140  	vm.Set("m", m)
   141  	v, err := vm.RunString(SCRIPT)
   142  	if err != nil {
   143  		t.Fatal(err)
   144  	}
   145  	if !v.StrictEquals(valueTrue) {
   146  		t.Fatalf("Expected true, got %v", v)
   147  	}
   148  
   149  }
   150  
   151  func TestGoMapReflectWithMethods(t *testing.T) {
   152  	const SCRIPT = `
   153  	typeof m === "object" && !m.hasOwnProperty("t") && m.hasOwnProperty("Method") && m.Method();
   154  	`
   155  
   156  	vm := New()
   157  	m := make(gomapReflect_withMethods)
   158  	m["t"] = 42
   159  	vm.Set("m", m)
   160  	v, err := vm.RunString(SCRIPT)
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  	if !v.StrictEquals(valueTrue) {
   165  		t.Fatalf("Expected true, got %v", v)
   166  	}
   167  
   168  }
   169  
   170  func TestGoMapReflectWithProto(t *testing.T) {
   171  	vm := New()
   172  	m := map[string]string{
   173  		"t": "42",
   174  	}
   175  	vm.Set("m", m)
   176  	vm.testScriptWithTestLib(`
   177  	(function() {
   178  	'use strict';
   179  	var proto = {};
   180  	var getterAllowed = false;
   181  	var setterAllowed = false;
   182  	var tHolder = "proto t";
   183  	Object.defineProperty(proto, "t", {
   184  		get: function() {
   185  			if (!getterAllowed) throw new Error("getter is called");
   186  			return tHolder;
   187  		},
   188  		set: function(v) {
   189  			if (!setterAllowed) throw new Error("setter is called");
   190  			tHolder = v;
   191  		}
   192  	});
   193  	var t1Holder;
   194  	Object.defineProperty(proto, "t1", {
   195  		get: function() {
   196  			return t1Holder;
   197  		},
   198  		set: function(v) {
   199  			t1Holder = v;
   200  		}
   201  	});
   202  	Object.setPrototypeOf(m, proto);
   203  	assert.sameValue(m.t, "42");
   204  	m.t = 43;
   205  	assert.sameValue(m.t, "43");
   206  	t1Holder = "test";
   207  	assert.sameValue(m.t1, "test");
   208  	m.t1 = "test1";
   209  	assert.sameValue(m.t1, "test1");
   210  	delete m.t;
   211  	getterAllowed = true;
   212  	assert.sameValue(m.t, "proto t", "after delete");
   213  	setterAllowed = true;
   214  	m.t = true;
   215  	assert.sameValue(m.t, true, "m.t === true");
   216  	assert.sameValue(tHolder, true, "tHolder === true");
   217  	Object.preventExtensions(m);
   218  	assert.throws(TypeError, function() {
   219  		m.t2 = 1;
   220  	});
   221  	m.t1 = "test2";
   222  	assert.sameValue(m.t1, "test2");
   223  	})();
   224  	`, _undefined, t)
   225  }
   226  
   227  func TestGoMapReflectProtoProp(t *testing.T) {
   228  	const SCRIPT = `
   229  	(function() {
   230  	"use strict";
   231  	var proto = {};
   232  	Object.defineProperty(proto, "ro", {value: 42});
   233  	Object.setPrototypeOf(m, proto);
   234  	assert.throws(TypeError, function() {
   235  		m.ro = 43;
   236  	});
   237  	Object.defineProperty(m, "ro", {value: 43});
   238  	assert.sameValue(m.ro, "43");
   239  	})();
   240  	`
   241  
   242  	r := New()
   243  	r.Set("m", map[string]string{})
   244  	r.testScriptWithTestLib(SCRIPT, _undefined, t)
   245  }
   246  
   247  func TestGoMapReflectUnicode(t *testing.T) {
   248  	const SCRIPT = `
   249  	Object.setPrototypeOf(m, s);
   250  	if (m.Тест !== "passed") {
   251  		throw new Error("m.Тест: " + m.Тест);
   252  	}
   253  	m["é"];
   254  	`
   255  	type S struct {
   256  		Тест string
   257  	}
   258  	vm := New()
   259  	m := map[string]int{
   260  		"é": 42,
   261  	}
   262  	s := S{
   263  		Тест: "passed",
   264  	}
   265  	vm.Set("m", m)
   266  	vm.Set("s", &s)
   267  	res, err := vm.RunString(SCRIPT)
   268  	if err != nil {
   269  		t.Fatal(err)
   270  	}
   271  	if res == nil || !res.StrictEquals(valueInt(42)) {
   272  		t.Fatalf("Unexpected value: %v", res)
   273  	}
   274  }
   275  
   276  func TestGoMapReflectStruct(t *testing.T) {
   277  	type S struct {
   278  		Test int
   279  	}
   280  
   281  	m := map[string]S{
   282  		"1": {Test: 1},
   283  	}
   284  
   285  	vm := New()
   286  	vm.Set("m", m)
   287  	res, err := vm.RunString("m[1].Test = 2; m[1].Test")
   288  	if err != nil {
   289  		t.Fatal(err)
   290  	}
   291  	if res.Export() != int64(1) {
   292  		t.Fatal(res)
   293  	}
   294  }
   295  
   296  func TestGoMapReflectElt(t *testing.T) {
   297  	type mapping map[string]interface{}
   298  
   299  	const SCRIPT = `a.s() && a.t === null && a.t1 === undefined;`
   300  
   301  	r := New()
   302  
   303  	r.Set("a", mapping{
   304  		"s": func() bool { return true },
   305  		"t": nil,
   306  	})
   307  
   308  	r.testScript(SCRIPT, valueTrue, t)
   309  }