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

     1  package goja
     2  
     3  import (
     4  	"fmt"
     5  	"hash/maphash"
     6  	"testing"
     7  )
     8  
     9  func TestMapEvilIterator(t *testing.T) {
    10  	const SCRIPT = `
    11  	'use strict';
    12  	var o = {};
    13  
    14  	function Iter(value) {
    15  		this.value = value;
    16  		this.idx = 0;
    17  	}
    18  
    19  	Iter.prototype.next = function() {
    20  		var idx = this.idx;
    21  		if (idx === 0) {
    22  			this.idx++;
    23  			return this.value;
    24  		}
    25  		return {done: true};
    26  	}
    27  
    28  	o[Symbol.iterator] = function() {
    29  		return new Iter({});
    30  	}
    31  
    32  	assert.throws(TypeError, function() {
    33  		new Map(o);
    34  	});
    35  
    36  	o[Symbol.iterator] = function() {
    37  		return new Iter({value: []});
    38  	}
    39  
    40  	function t(prefix) {
    41  		var m = new Map(o);
    42  		assert.sameValue(1, m.size, prefix+": m.size");
    43  		assert.sameValue(true, m.has(undefined), prefix+": m.has(undefined)");
    44  		assert.sameValue(undefined, m.get(undefined), prefix+": m.get(undefined)");
    45  	}
    46  
    47  	t("standard adder");
    48  
    49  	var count = 0;
    50  	var origSet = Map.prototype.set;
    51  
    52  	Map.prototype.set = function() {
    53  		count++;
    54  		origSet.apply(this, arguments);
    55  	}
    56  
    57  	t("custom adder");
    58  	assert.sameValue(1, count, "count");
    59  
    60  	undefined;
    61  	`
    62  	testScriptWithTestLib(SCRIPT, _undefined, t)
    63  }
    64  
    65  func TestMapExportToNilMap(t *testing.T) {
    66  	vm := New()
    67  	var m map[int]interface{}
    68  	res, err := vm.RunString("new Map([[1, true]])")
    69  	if err != nil {
    70  		t.Fatal(err)
    71  	}
    72  	err = vm.ExportTo(res, &m)
    73  	if err != nil {
    74  		t.Fatal(err)
    75  	}
    76  	if len(m) != 1 {
    77  		t.Fatal(m)
    78  	}
    79  	if _, exists := m[1]; !exists {
    80  		t.Fatal(m)
    81  	}
    82  }
    83  
    84  func TestMapExportToNonNilMap(t *testing.T) {
    85  	vm := New()
    86  	m := map[int]interface{}{
    87  		2: true,
    88  	}
    89  	res, err := vm.RunString("new Map([[1, true]])")
    90  	if err != nil {
    91  		t.Fatal(err)
    92  	}
    93  	err = vm.ExportTo(res, &m)
    94  	if err != nil {
    95  		t.Fatal(err)
    96  	}
    97  	if len(m) != 1 {
    98  		t.Fatal(m)
    99  	}
   100  	if _, exists := m[1]; !exists {
   101  		t.Fatal(m)
   102  	}
   103  }
   104  
   105  func TestMapGetAdderGetIteratorOrder(t *testing.T) {
   106  	const SCRIPT = `
   107  	let getterCalled = 0;
   108  
   109  	class M extends Map {
   110  	    get set() {
   111  	        getterCalled++;
   112  	        return null;
   113  	    }
   114  	}
   115  
   116  	let getIteratorCalled = 0;
   117  
   118  	let iterable = {};
   119  	iterable[Symbol.iterator] = () => {
   120  	    getIteratorCalled++
   121  	    return {
   122  	        next: 1
   123  	    };
   124  	}
   125  
   126  	let thrown = false;
   127  
   128  	try {
   129  	    new M(iterable);
   130  	} catch (e) {
   131  	    if (e instanceof TypeError) {
   132  	        thrown = true;
   133  	    } else {
   134  	        throw e;
   135  	    }
   136  	}
   137  
   138  	thrown && getterCalled === 1 && getIteratorCalled === 0;
   139  	`
   140  	testScript(SCRIPT, valueTrue, t)
   141  }
   142  
   143  func ExampleObject_Export_map() {
   144  	vm := New()
   145  	m, err := vm.RunString(`
   146  	new Map([[1, true], [2, false]]);
   147  	`)
   148  	if err != nil {
   149  		panic(err)
   150  	}
   151  	exp := m.Export()
   152  	fmt.Printf("%T, %v\n", exp, exp)
   153  	// Output: [][2]interface {}, [[1 true] [2 false]]
   154  }
   155  
   156  func ExampleRuntime_ExportTo_mapToMap() {
   157  	vm := New()
   158  	m, err := vm.RunString(`
   159  	new Map([[1, true], [2, false]]);
   160  	`)
   161  	if err != nil {
   162  		panic(err)
   163  	}
   164  	exp := make(map[int]bool)
   165  	err = vm.ExportTo(m, &exp)
   166  	if err != nil {
   167  		panic(err)
   168  	}
   169  	fmt.Println(exp)
   170  	// Output: map[1:true 2:false]
   171  }
   172  
   173  func ExampleRuntime_ExportTo_mapToSlice() {
   174  	vm := New()
   175  	m, err := vm.RunString(`
   176  	new Map([[1, true], [2, false]]);
   177  	`)
   178  	if err != nil {
   179  		panic(err)
   180  	}
   181  	exp := make([][]interface{}, 0)
   182  	err = vm.ExportTo(m, &exp)
   183  	if err != nil {
   184  		panic(err)
   185  	}
   186  	fmt.Println(exp)
   187  	// Output: [[1 true] [2 false]]
   188  }
   189  
   190  func ExampleRuntime_ExportTo_mapToTypedSlice() {
   191  	vm := New()
   192  	m, err := vm.RunString(`
   193  	new Map([[1, true], [2, false]]);
   194  	`)
   195  	if err != nil {
   196  		panic(err)
   197  	}
   198  	exp := make([][2]interface{}, 0)
   199  	err = vm.ExportTo(m, &exp)
   200  	if err != nil {
   201  		panic(err)
   202  	}
   203  	fmt.Println(exp)
   204  	// Output: [[1 true] [2 false]]
   205  }
   206  
   207  func BenchmarkMapDelete(b *testing.B) {
   208  	var key1 Value = asciiString("a")
   209  	var key2 Value = asciiString("b")
   210  	one := intToValue(1)
   211  	two := intToValue(2)
   212  	for i := 0; i < b.N; i++ {
   213  		m := newOrderedMap(&maphash.Hash{})
   214  		m.set(key1, one)
   215  		m.set(key2, two)
   216  		if !m.remove(key1) {
   217  			b.Fatal("remove() returned false")
   218  		}
   219  	}
   220  }
   221  
   222  func BenchmarkMapDeleteJS(b *testing.B) {
   223  	prg, err := Compile("test.js", `
   224  	var m = new Map([['a',1], ['b', 2]]);
   225  	
   226  	var result = m.delete('a');
   227  
   228  	if (!result || m.size !== 1) {
   229  		throw new Error("Fail!");
   230  	}
   231  	`,
   232  		false)
   233  	if err != nil {
   234  		b.Fatal(err)
   235  	}
   236  	b.ResetTimer()
   237  	for i := 0; i < b.N; i++ {
   238  		vm := New()
   239  		_, err := vm.RunProgram(prg)
   240  		if err != nil {
   241  			b.Fatal(err)
   242  		}
   243  	}
   244  }