1package goja
2
3import (
4	"hash/maphash"
5	"testing"
6)
7
8func TestMapEvilIterator(t *testing.T) {
9	const SCRIPT = `
10	'use strict';
11	var o = {};
12
13	function Iter(value) {
14		this.value = value;
15		this.idx = 0;
16	}
17
18	Iter.prototype.next = function() {
19		var idx = this.idx;
20		if (idx === 0) {
21			this.idx++;
22			return this.value;
23		}
24		return {done: true};
25	}
26
27	o[Symbol.iterator] = function() {
28		return new Iter({});
29	}
30
31	assert.throws(TypeError, function() {
32		new Map(o);
33	});
34
35	o[Symbol.iterator] = function() {
36		return new Iter({value: []});
37	}
38
39	function t(prefix) {
40		var m = new Map(o);
41		assert.sameValue(1, m.size, prefix+": m.size");
42		assert.sameValue(true, m.has(undefined), prefix+": m.has(undefined)");
43		assert.sameValue(undefined, m.get(undefined), prefix+": m.get(undefined)");
44	}
45
46	t("standard adder");
47
48	var count = 0;
49	var origSet = Map.prototype.set;
50
51	Map.prototype.set = function() {
52		count++;
53		origSet.apply(this, arguments);
54	}
55
56	t("custom adder");
57	assert.sameValue(1, count, "count");
58
59	undefined;
60	`
61	testScript1(TESTLIB+SCRIPT, _undefined, t)
62}
63
64func BenchmarkMapDelete(b *testing.B) {
65	var key1 Value = asciiString("a")
66	var key2 Value = asciiString("b")
67	one := intToValue(1)
68	two := intToValue(2)
69	for i := 0; i < b.N; i++ {
70		m := newOrderedMap(&maphash.Hash{})
71		m.set(key1, one)
72		m.set(key2, two)
73		if !m.remove(key1) {
74			b.Fatal("remove() returned false")
75		}
76	}
77}
78
79func BenchmarkMapDeleteJS(b *testing.B) {
80	prg, err := Compile("test.js", `
81	var m = new Map([['a',1], ['b', 2]]);
82
83	var result = m.delete('a');
84
85	if (!result || m.size !== 1) {
86		throw new Error("Fail!");
87	}
88	`,
89		false)
90	if err != nil {
91		b.Fatal(err)
92	}
93	b.ResetTimer()
94	for i := 0; i < b.N; i++ {
95		vm := New()
96		_, err := vm.RunProgram(prg)
97		if err != nil {
98			b.Fatal(err)
99		}
100	}
101}
102