builtin_map_test.go 4.1 KB

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