opal 1.7.4 → 1.8.0.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +9 -9
  3. data/.rubocop/todo.yml +2 -2
  4. data/.rubocop.yml +17 -10
  5. data/.rubocop_todo.yml +311 -0
  6. data/CHANGELOG.md +1 -15
  7. data/UNRELEASED.md +78 -1
  8. data/benchmark-ips/bm_block_vs_yield.rb +3 -0
  9. data/benchmark-ips/bm_slice_or_not.rb +53 -0
  10. data/docs/bridging.md +112 -0
  11. data/docs/compiled_ruby.md +10 -10
  12. data/docs/getting_started.md +18 -22
  13. data/lib/opal/cli_runners/chrome.rb +1 -5
  14. data/lib/opal/cli_runners/chrome_cdp_interface.rb +1 -0
  15. data/lib/opal/cli_runners/firefox_cdp_interface.rb +1 -0
  16. data/lib/opal/compiler.rb +33 -1
  17. data/lib/opal/nodes/args/extract_kwoptarg.rb +2 -1
  18. data/lib/opal/nodes/call.rb +1 -1
  19. data/lib/opal/nodes/call_special.rb +71 -47
  20. data/lib/opal/nodes/hash.rb +14 -30
  21. data/lib/opal/nodes/if.rb +37 -29
  22. data/lib/opal/nodes/literal.rb +5 -1
  23. data/lib/opal/nodes/x_string.rb +13 -0
  24. data/lib/opal/parser/patch.rb +1 -0
  25. data/lib/opal/rewriters/for_rewriter.rb +36 -24
  26. data/lib/opal/simple_server.rb +2 -2
  27. data/lib/opal/source_map/file.rb +1 -1
  28. data/lib/opal/version.rb +1 -1
  29. data/opal/corelib/array/pack.rb +1 -0
  30. data/opal/corelib/array.rb +71 -43
  31. data/opal/corelib/basic_object.rb +1 -0
  32. data/opal/corelib/binding.rb +2 -0
  33. data/opal/corelib/boolean.rb +1 -0
  34. data/opal/corelib/class.rb +2 -0
  35. data/opal/corelib/comparable.rb +1 -0
  36. data/opal/corelib/complex.rb +2 -0
  37. data/opal/corelib/constants.rb +2 -2
  38. data/opal/corelib/dir.rb +2 -0
  39. data/opal/corelib/enumerable.rb +3 -2
  40. data/opal/corelib/enumerator/arithmetic_sequence.rb +2 -0
  41. data/opal/corelib/enumerator/chain.rb +1 -0
  42. data/opal/corelib/enumerator/generator.rb +1 -0
  43. data/opal/corelib/enumerator/lazy.rb +1 -0
  44. data/opal/corelib/enumerator/yielder.rb +2 -0
  45. data/opal/corelib/enumerator.rb +1 -0
  46. data/opal/corelib/error/errno.rb +2 -0
  47. data/opal/corelib/error.rb +12 -0
  48. data/opal/corelib/file.rb +1 -0
  49. data/opal/corelib/hash.rb +197 -504
  50. data/opal/corelib/helpers.rb +1 -0
  51. data/opal/corelib/io.rb +2 -0
  52. data/opal/corelib/irb.rb +2 -0
  53. data/opal/corelib/kernel/format.rb +1 -0
  54. data/opal/corelib/kernel.rb +70 -14
  55. data/opal/corelib/main.rb +2 -0
  56. data/opal/corelib/marshal/read_buffer.rb +2 -0
  57. data/opal/corelib/marshal/write_buffer.rb +2 -0
  58. data/opal/corelib/math/polyfills.rb +2 -0
  59. data/opal/corelib/math.rb +1 -0
  60. data/opal/corelib/method.rb +2 -0
  61. data/opal/corelib/module.rb +1 -0
  62. data/opal/corelib/nil.rb +3 -1
  63. data/opal/corelib/number.rb +2 -0
  64. data/opal/corelib/numeric.rb +2 -0
  65. data/opal/corelib/object_space.rb +1 -0
  66. data/opal/corelib/pack_unpack/format_string_parser.rb +2 -0
  67. data/opal/corelib/proc.rb +30 -28
  68. data/opal/corelib/process.rb +2 -0
  69. data/opal/corelib/random/formatter.rb +2 -0
  70. data/opal/corelib/random/math_random.js.rb +2 -0
  71. data/opal/corelib/random/mersenne_twister.rb +2 -0
  72. data/opal/corelib/random/seedrandom.js.rb +2 -0
  73. data/opal/corelib/random.rb +1 -0
  74. data/opal/corelib/range.rb +34 -12
  75. data/opal/corelib/rational.rb +2 -0
  76. data/opal/corelib/regexp.rb +1 -0
  77. data/opal/corelib/runtime.js +187 -231
  78. data/opal/corelib/set.rb +2 -0
  79. data/opal/corelib/string/encoding.rb +3 -0
  80. data/opal/corelib/string/unpack.rb +2 -0
  81. data/opal/corelib/string.rb +20 -12
  82. data/opal/corelib/struct.rb +3 -1
  83. data/opal/corelib/time.rb +1 -0
  84. data/opal/corelib/trace_point.rb +2 -0
  85. data/opal/corelib/unsupported.rb +2 -0
  86. data/opal/corelib/variables.rb +2 -0
  87. data/opal.gemspec +2 -2
  88. data/spec/filters/bugs/array.rb +0 -2
  89. data/spec/filters/bugs/enumerable.rb +0 -3
  90. data/spec/filters/bugs/hash.rb +0 -13
  91. data/spec/filters/bugs/kernel.rb +0 -38
  92. data/spec/filters/bugs/range.rb +0 -1
  93. data/spec/filters/bugs/ruby-32.rb +0 -2
  94. data/spec/filters/bugs/string.rb +0 -1
  95. data/spec/filters/bugs/struct.rb +1 -5
  96. data/spec/filters/unsupported/hash.rb +1 -0
  97. data/spec/lib/compiler_spec.rb +24 -17
  98. data/spec/mspec-opal/formatters.rb +2 -0
  99. data/spec/mspec-opal/runner.rb +2 -0
  100. data/spec/opal/core/array/dup_spec.rb +2 -0
  101. data/spec/opal/core/exception_spec.rb +2 -0
  102. data/spec/opal/core/hash/internals_spec.rb +154 -206
  103. data/spec/opal/core/hash_spec.rb +2 -0
  104. data/spec/opal/core/iterable_props_spec.rb +2 -0
  105. data/spec/opal/core/kernel/at_exit_spec.rb +2 -0
  106. data/spec/opal/core/kernel/respond_to_spec.rb +2 -0
  107. data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +2 -0
  108. data/spec/opal/core/language/safe_navigator_spec.rb +2 -0
  109. data/spec/opal/core/language/xstring_send_spec.rb +15 -0
  110. data/spec/opal/core/language/xstring_spec.rb +2 -0
  111. data/spec/opal/core/language_spec.rb +2 -0
  112. data/spec/opal/core/module_spec.rb +44 -0
  113. data/spec/opal/core/number/to_i_spec.rb +2 -0
  114. data/spec/opal/core/object_id_spec.rb +2 -0
  115. data/spec/opal/core/regexp/match_spec.rb +2 -0
  116. data/spec/opal/core/runtime/bridged_classes_spec.rb +38 -0
  117. data/spec/opal/core/runtime/constants_spec.rb +2 -0
  118. data/spec/opal/core/runtime/eval_spec.rb +2 -0
  119. data/spec/opal/core/runtime/exit_spec.rb +2 -0
  120. data/spec/opal/core/runtime/is_a_spec.rb +2 -0
  121. data/spec/opal/core/runtime/loaded_spec.rb +2 -0
  122. data/spec/opal/core/runtime/method_missing_spec.rb +2 -0
  123. data/spec/opal/core/runtime/rescue_spec.rb +2 -0
  124. data/spec/opal/core/runtime/string_spec.rb +2 -0
  125. data/spec/opal/core/runtime/truthy_spec.rb +2 -0
  126. data/spec/opal/core/runtime_spec.rb +2 -6
  127. data/spec/opal/core/string/to_sym_spec.rb +2 -0
  128. data/spec/opal/stdlib/js_spec.rb +2 -0
  129. data/spec/opal/stdlib/native/alias_native_spec.rb +2 -0
  130. data/spec/opal/stdlib/native/array_spec.rb +2 -0
  131. data/spec/opal/stdlib/native/date_spec.rb +2 -0
  132. data/spec/opal/stdlib/native/each_spec.rb +2 -0
  133. data/spec/opal/stdlib/native/element_reference_spec.rb +2 -0
  134. data/spec/opal/stdlib/native/exposure_spec.rb +2 -0
  135. data/spec/opal/stdlib/native/ext_spec.rb +2 -0
  136. data/spec/opal/stdlib/native/hash_spec.rb +30 -2
  137. data/spec/opal/stdlib/native/initialize_spec.rb +2 -0
  138. data/spec/opal/stdlib/native/method_missing_spec.rb +2 -0
  139. data/spec/opal/stdlib/native/native_alias_spec.rb +2 -0
  140. data/spec/opal/stdlib/native/native_class_spec.rb +2 -0
  141. data/spec/opal/stdlib/native/native_module_spec.rb +2 -0
  142. data/spec/opal/stdlib/native/native_reader_spec.rb +2 -0
  143. data/spec/opal/stdlib/native/native_writer_spec.rb +2 -0
  144. data/spec/opal/stdlib/native/new_spec.rb +2 -0
  145. data/spec/opal/stdlib/native/struct_spec.rb +2 -0
  146. data/spec/spec_helper.rb +2 -0
  147. data/stdlib/await.rb +1 -0
  148. data/stdlib/base64.rb +2 -0
  149. data/stdlib/bigdecimal/bignumber.js.rb +2 -0
  150. data/stdlib/bigdecimal/util.rb +1 -0
  151. data/stdlib/bigdecimal.rb +2 -0
  152. data/stdlib/buffer/array.rb +2 -0
  153. data/stdlib/buffer/view.rb +2 -0
  154. data/stdlib/buffer.rb +2 -0
  155. data/stdlib/cgi.rb +14 -0
  156. data/stdlib/console.rb +2 -0
  157. data/stdlib/date/date_time.rb +2 -0
  158. data/stdlib/date.rb +2 -0
  159. data/stdlib/delegate.rb +2 -0
  160. data/stdlib/deno/base.rb +2 -0
  161. data/stdlib/deno/file.rb +2 -0
  162. data/stdlib/erb.rb +2 -0
  163. data/stdlib/gjs/io.rb +2 -0
  164. data/stdlib/gjs/kernel.rb +2 -0
  165. data/stdlib/headless_browser/base.rb +2 -0
  166. data/stdlib/headless_browser/file.rb +1 -0
  167. data/stdlib/headless_browser.rb +1 -0
  168. data/stdlib/js.rb +2 -0
  169. data/stdlib/json.rb +9 -15
  170. data/stdlib/logger.rb +2 -0
  171. data/stdlib/nashorn/file.rb +2 -0
  172. data/stdlib/nashorn/io.rb +2 -0
  173. data/stdlib/native.rb +48 -48
  174. data/stdlib/nodejs/base.rb +2 -0
  175. data/stdlib/nodejs/dir.rb +2 -0
  176. data/stdlib/nodejs/env.rb +2 -0
  177. data/stdlib/nodejs/file.rb +2 -0
  178. data/stdlib/nodejs/fileutils.rb +2 -0
  179. data/stdlib/nodejs/io.rb +2 -0
  180. data/stdlib/nodejs/js-yaml-3-6-1.js +1 -1
  181. data/stdlib/nodejs/kernel.rb +2 -0
  182. data/stdlib/nodejs/open-uri.rb +2 -0
  183. data/stdlib/nodejs/pathname.rb +2 -0
  184. data/stdlib/nodejs/require.rb +2 -0
  185. data/stdlib/nodejs/yaml.rb +9 -3
  186. data/stdlib/opal/miniracer.rb +2 -0
  187. data/stdlib/opal-parser.rb +8 -1
  188. data/stdlib/opal-platform.rb +2 -0
  189. data/stdlib/opal-replutils.rb +2 -0
  190. data/stdlib/open-uri.rb +4 -1
  191. data/stdlib/ostruct.rb +4 -2
  192. data/stdlib/pathname.rb +2 -0
  193. data/stdlib/pp.rb +1 -0
  194. data/stdlib/promise/v2.rb +2 -0
  195. data/stdlib/quickjs/io.rb +2 -0
  196. data/stdlib/quickjs/kernel.rb +2 -0
  197. data/stdlib/quickjs.rb +2 -0
  198. data/stdlib/securerandom.rb +2 -0
  199. data/stdlib/strscan.rb +2 -0
  200. data/stdlib/time.rb +2 -0
  201. data/stdlib/uri.rb +1 -0
  202. data/tasks/performance/optimization_status.rb +2 -0
  203. data/tasks/testing.rake +1 -0
  204. data/test/nodejs/test_await.rb +1 -0
  205. data/test/nodejs/test_dir.rb +2 -0
  206. data/test/nodejs/test_error.rb +2 -0
  207. data/test/nodejs/test_file.rb +2 -0
  208. data/test/nodejs/test_string.rb +2 -0
  209. data/test/nodejs/test_yaml.rb +20 -0
  210. metadata +22 -13
  211. data/spec/filters/bugs/openstruct.rb +0 -8
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe 'Hash' do
2
4
 
3
5
  describe 'internal implementation of string keys' do
@@ -5,42 +7,42 @@ describe 'Hash' do
5
7
  @h = {'a' => 123, 'b' => 456}
6
8
  end
7
9
 
8
- it 'stores keys directly as strings in the `keys` array' do
9
- `#@h.$$keys.length`.should == 2
10
- `#@h.$$keys[0]`.should == 'a'
11
- `#@h.$$keys[1]`.should == 'b'
10
+ it 'stores keys directly as strings in the `Map`' do
11
+ `#@h.size`.should == 2
12
+ `Array.from(#@h.keys())[0]`.should == 'a'
13
+ `Array.from(#@h.keys())[1]`.should == 'b'
12
14
 
13
15
  @h['c'] = 789
14
16
 
15
- `#@h.$$keys.length`.should == 3
16
- `#@h.$$keys[2]`.should == 'c'
17
+ `#@h.size`.should == 3
18
+ `Array.from(#@h.keys())[2]`.should == 'c'
17
19
  end
18
20
 
19
- it 'stores values directly as objects in the `smap` object by their corresponding string key' do
20
- `Object.keys(#@h.$$smap).length`.should == 2
21
- `#@h.$$smap['a']`.should == 123
22
- `#@h.$$smap['b']`.should == 456
21
+ it 'stores values directly as objects in the `Map`' do
22
+ `Array.from(#@h.values()).length`.should == 2
23
+ `Array.from(#@h.values())[0]`.should == 123
24
+ `Array.from(#@h.values())[1]`.should == 456
23
25
 
24
26
  @h['c'] = 789
25
27
 
26
- `Object.keys(#@h.$$smap).length`.should == 3
27
- `#@h.$$smap['c']`.should == 789
28
+ `Array.from(#@h.values()).length`.should == 3
29
+ `Array.from(#@h.values())[2]`.should == 789
28
30
  end
29
31
 
30
- it 'does not use the `map` object' do
31
- `Object.keys(#@h.$$map).length`.should == 0
32
+ it 'does not use the `Map.$$keys`' do
33
+ `(#@h.$$keys === undefined)`.should == true
32
34
 
33
35
  @h['c'] = 789
34
36
 
35
- `Object.keys(#@h.$$map).length`.should == 0
37
+ `(#@h.$$keys === undefined)`.should == true
36
38
  end
37
39
 
38
- it 'uses the `map` object when an object key is added' do
39
- `Object.keys(#@h.$$map).length`.should == 0
40
+ it 'uses the `Map.$$keys` object when an object key is added' do
41
+ `(#@h.$$keys === undefined)`.should == true
40
42
 
41
43
  @h[Object.new] = 789
42
44
 
43
- `Object.keys(#@h.$$map).length`.should == 1
45
+ `#@h.$$keys.size`.should == 1
44
46
  end
45
47
 
46
48
  it 'converts string objects to values when used to delete keys' do
@@ -58,57 +60,10 @@ describe 'Hash' do
58
60
  @h = {@obj1 => 123, @obj2 => 456}
59
61
  end
60
62
 
61
- it 'uses a data structure called "bucket", which is a wrapper object with `key`, `key_hash`, `value`, and `next` properties' do
62
- bucket = `#@h.$$keys[0]`
63
- `#{bucket}.key`.should == @obj1
64
- `#{bucket}.key_hash`.should == @obj1.hash
65
- `#{bucket}.value`.should == 123
66
- `#{bucket}.next === undefined`.should == true
67
- end
68
-
69
- it 'stores keys in the `keys` array as "bucket" objects' do
70
- `#@h.$$keys.length`.should == 2
71
- `#@h.$$keys[0].key`.should == @obj1
72
- `#@h.$$keys[1].key`.should == @obj2
73
-
74
- obj3 = Object.new
75
- @h[obj3] = 789
76
-
77
- `#@h.$$keys.length`.should == 3
78
- `#@h.$$keys[2].key`.should == obj3
79
- end
80
-
81
- it 'stores values in the `map` object as "bucket" objects by #hash string of their corresponding object key' do
82
- `Object.keys(#@h.$$map).length`.should == 2
83
- `#@h.$$map[#{@obj1.hash}].value`.should == 123
84
- `#@h.$$map[#{@obj2.hash}].value`.should == 456
85
-
86
- obj3 = Object.new
87
- @h[obj3] = 789
88
-
89
- `Object.keys(#@h.$$map).length`.should == 3
90
- `#@h.$$map[#{obj3.hash}].value`.should == 789
91
- end
92
-
93
- it 'keeps a pointer to the same "bucket" object in the `keys` array and in the `map` object' do
94
- `#@h.$$map[#{@obj1.hash}] === #@h.$$keys[0]`.should == true
95
- `#@h.$$map[#{@obj2.hash}] === #@h.$$keys[1]`.should == true
96
- end
97
-
98
- it 'does not use the `smap` object' do
99
- `Object.keys(#@h.$$smap).length`.should == 0
100
-
101
- @h[Object.new] = 789
102
-
103
- `Object.keys(#@h.$$smap).length`.should == 0
104
- end
105
-
106
- it 'uses the `smap` object when a string key is added' do
107
- `Object.keys(#@h.$$smap).length`.should == 0
108
-
109
- @h['c'] = 789
110
-
111
- `Object.keys(#@h.$$smap).length`.should == 1
63
+ it 'uses a `Map.$$keys` to keep references of objects to be used as keys' do
64
+ keys = `Array.from(#@h.$$keys.entries())`
65
+ `#{keys}[0][1][0]`.should == @obj1
66
+ `#{keys}[0][0]`.should == @obj1.hash
112
67
  end
113
68
 
114
69
  it 'allows multiple keys that #hash to the same value to be stored in the Hash' do
@@ -126,45 +81,41 @@ describe 'Hash' do
126
81
  @mock3.should_receive(:hash).at_least(1).and_return('hhh')
127
82
  @mock3.should_receive(:eql?).exactly(2).and_return(false)
128
83
 
129
- `Object.keys(#@hash.$$map).length`.should == 0
130
- `#@hash.$$keys.length`.should == 0
84
+ `#@hash.size`.should == 0
85
+ `(#@hash.$$keys === undefined)`.should == true
131
86
 
132
87
  @hash[@mock1] = 123
133
- `Object.keys(#@hash.$$map).length`.should == 1
134
- `#@hash.$$keys.length`.should == 1
135
- `#@hash.$$keys[0] === #@hash.$$map['hhh']`.should == true
136
- `#@hash.$$keys[0].key`.should == @mock1
137
- `#@hash.$$keys[0].key_hash`.should == @mock1.hash
138
- `#@hash.$$keys[0].value`.should == 123
139
- `#@hash.$$keys[0].next === undefined`.should == true
88
+ `#@hash.$$keys.size`.should == 1
89
+ keys = `Array.from(#@hash.$$keys.entries())`
90
+ `#{keys}[0][1].length`.should == 1
91
+ `#{keys}[0][1][0]`.should == @mock1
92
+ `#{keys}[0][0]`.should == @mock1.hash
93
+ `#@hash.get(#@mock1)`.should == 123
140
94
 
141
95
  @hash[@mock2] = 456
142
- `Object.keys(#@hash.$$map).length`.should == 1
143
- `#@hash.$$keys.length`.should == 2
144
- `#@hash.$$keys[1] === #@hash.$$map['hhh'].next`.should == true
145
- `#@hash.$$keys[1].key`.should == @mock2
146
- `#@hash.$$keys[1].key_hash`.should == @mock2.hash
147
- `#@hash.$$keys[1].value`.should == 456
148
- `#@hash.$$keys[1].next === undefined`.should == true
96
+ `#@hash.$$keys.size`.should == 1
97
+ keys = `Array.from(#@hash.$$keys.entries())`
98
+ `#{keys}[0][1].length`.should == 2
99
+ `#{keys}[0][1][1]`.should == @mock2
100
+ `#{keys}[0][0]`.should == @mock2.hash
101
+ `#@hash.get(#@mock2)`.should == 456
149
102
 
150
103
  @hash[@mock3] = 789
151
- `Object.keys(#@hash.$$map).length`.should == 1
152
- `#@hash.$$keys.length`.should == 3
153
- `#@hash.$$keys[2] === #@hash.$$map['hhh'].next.next`.should == true
154
- `#@hash.$$keys[2].key`.should == @mock3
155
- `#@hash.$$keys[2].key_hash`.should == @mock3.hash
156
- `#@hash.$$keys[2].value`.should == 789
157
- `#@hash.$$keys[2].next === undefined`.should == true
104
+ `#@hash.$$keys.size`.should == 1
105
+ keys = `Array.from(#@hash.$$keys.entries())`
106
+ `#{keys}[0][1].length`.should == 3
107
+ `#{keys}[0][1][2]`.should == @mock3
108
+ `#{keys}[0][0]`.should == @mock3.hash
109
+ `#@hash.get(#@mock3)`.should == 789
158
110
 
159
111
  obj = Object.new
160
112
  @hash[obj] = 999
161
- `Object.keys(#@hash.$$map).length`.should == 2
162
- `#@hash.$$keys.length`.should == 4
163
- `#@hash.$$keys[3] === #@hash.$$map[#{obj.hash}]`.should == true
164
- `#@hash.$$keys[3].key`.should == obj
165
- `#@hash.$$keys[3].key_hash`.should == obj.hash
166
- `#@hash.$$keys[3].value`.should == 999
167
- `#@hash.$$keys[3].next === undefined`.should == true
113
+ `#@hash.$$keys.size`.should == 2
114
+ keys = `Array.from(#@hash.$$keys.entries())`
115
+ `#{keys}[1][1].length`.should == 1
116
+ `#{keys}[1][1][0]`.should == obj
117
+ `#{keys}[1][0]`.should == obj.hash
118
+ `#@hash.get(#{obj})`.should == 999
168
119
  end
169
120
 
170
121
  it 'correctly updates internal data structures when deleting keys' do
@@ -195,145 +146,142 @@ describe 'Hash' do
195
146
  @obj1 => 'xyz'
196
147
  }
197
148
 
198
- `Opal.hasOwnProperty.call(#@hash.$$map, 'hhh')`.should == true
199
- `Opal.hasOwnProperty.call(#@hash.$$map, #{@obj1.hash})`.should == true
200
- `Opal.hasOwnProperty.call(#@hash.$$smap, 'a')`.should == true
201
- `Opal.hasOwnProperty.call(#@hash.$$smap, 'b')`.should == true
202
- `Opal.hasOwnProperty.call(#@hash.$$smap, 'c')`.should == true
203
-
204
- `#@hash.$$keys.length`.should == 8
205
- `Object.keys(#@hash.$$map).length`.should == 2
206
- `Object.keys(#@hash.$$smap).length`.should == 3
207
-
208
- `#@hash.$$keys[0].key`.should == @mock1
209
- `#@hash.$$keys[1]`.should == 'a'
210
- `#@hash.$$keys[2].key`.should == @mock2
211
- `#@hash.$$keys[3]`.should == 'b'
212
- `#@hash.$$keys[4].key`.should == @mock3
213
- `#@hash.$$keys[5].key`.should == @mock4
214
- `#@hash.$$keys[6]`.should == 'c'
215
- `#@hash.$$keys[7].key`.should == @obj1
216
-
217
- `#@hash.$$map['hhh'] === #@hash.$$keys[0]`.should == true
218
- `#@hash.$$keys[0].next === #@hash.$$keys[2]`.should == true
219
- `#@hash.$$keys[2].next === #@hash.$$keys[4]`.should == true
220
- `#@hash.$$keys[4].next === #@hash.$$keys[5]`.should == true
221
- `#@hash.$$keys[5].next === undefined`.should == true
149
+ `#@hash.$$keys.has('hhh')`.should == true
150
+ `#@hash.$$keys.has(#{@obj1.hash})`.should == true
151
+ `#@hash.has('a')`.should == true
152
+ `#@hash.has('b')`.should == true
153
+ `#@hash.has('c')`.should == true
154
+
155
+ `#@hash.size`.should == 8
156
+ `#@hash.$$keys.size`.should == 2
157
+
158
+ keys = `Array.from(#@hash.keys())`
159
+ keys[0].should == @mock1
160
+ keys[1].should == 'a'
161
+ keys[2].should == @mock2
162
+ keys[3].should == 'b'
163
+ keys[4].should == @mock3
164
+ keys[5].should == @mock4
165
+ keys[6].should == 'c'
166
+ keys[7].should == @obj1
167
+
168
+ keys = `Array.from(#@hash.$$keys.values())[0]`
169
+ `#{keys}.length`.should == 4
170
+ keys[0].should == @mock1
171
+ keys[1].should == @mock2
172
+ keys[2].should == @mock3
173
+ keys[3].should == @mock4
174
+ keys = `Array.from(#@hash.$$keys.values())[1]`
175
+ `#{keys}.length`.should == 1
176
+ keys[0].should == @obj1
222
177
 
223
178
  @hash.delete @mock2
224
179
 
225
- `#@hash.$$keys.length`.should == 7
226
- `Object.keys(#@hash.$$map).length`.should == 2
227
- `Object.keys(#@hash.$$smap).length`.should == 3
228
-
229
- `#@hash.$$keys[0].key`.should == @mock1
230
- `#@hash.$$keys[1]`.should == 'a'
231
- `#@hash.$$keys[2]`.should == 'b'
232
- `#@hash.$$keys[3].key`.should == @mock3
233
- `#@hash.$$keys[4].key`.should == @mock4
234
- `#@hash.$$keys[5]`.should == 'c'
235
- `#@hash.$$keys[6].key`.should == @obj1
236
-
237
- `#@hash.$$map['hhh'] === #@hash.$$keys[0]`.should == true
238
- `#@hash.$$keys[0].next === #@hash.$$keys[3]`.should == true
239
- `#@hash.$$keys[3].next === #@hash.$$keys[4]`.should == true
240
- `#@hash.$$keys[4].next === undefined`.should == true
180
+ `#@hash.size`.should == 7
181
+ keys = `Array.from(#@hash.$$keys.values())[0]`
182
+ `#{keys}.length`.should == 3
183
+ keys[0].should == @mock1
184
+ keys[1].should == @mock3
185
+ keys[2].should == @mock4
186
+
187
+ keys = `Array.from(#@hash.keys())`
188
+ keys[0].should == @mock1
189
+ keys[1].should == 'a'
190
+ keys[2].should == 'b'
191
+ keys[3].should == @mock3
192
+ keys[4].should == @mock4
193
+ keys[5].should == 'c'
194
+ keys[6].should == @obj1
241
195
 
242
196
  @hash.delete @mock4
243
197
 
244
- `#@hash.$$keys.length`.should == 6
245
- `Object.keys(#@hash.$$map).length`.should == 2
246
- `Object.keys(#@hash.$$smap).length`.should == 3
247
-
248
- `#@hash.$$keys[0].key`.should == @mock1
249
- `#@hash.$$keys[1]`.should == 'a'
250
- `#@hash.$$keys[2]`.should == 'b'
251
- `#@hash.$$keys[3].key`.should == @mock3
252
- `#@hash.$$keys[4]`.should == 'c'
253
- `#@hash.$$keys[5].key`.should == @obj1
198
+ `#@hash.size`.should == 6
199
+ keys = `Array.from(#@hash.$$keys.values())[0]`
200
+ `#{keys}.length`.should == 2
201
+ keys[0].should == @mock1
202
+ keys[1].should == @mock3
254
203
 
255
- `#@hash.$$map['hhh'] === #@hash.$$keys[0]`.should == true
256
- `#@hash.$$keys[0].next === #@hash.$$keys[3]`.should == true
257
- `#@hash.$$keys[3].next === undefined`.should == true
204
+ keys = `Array.from(#@hash.keys())`
205
+ keys[0].should == @mock1
206
+ keys[1].should == 'a'
207
+ keys[2].should == 'b'
208
+ keys[3].should == @mock3
209
+ keys[4].should == 'c'
210
+ keys[5].should == @obj1
258
211
 
259
212
  @hash.delete @mock1
260
213
 
261
- `#@hash.$$keys.length`.should == 5
262
- `Object.keys(#@hash.$$map).length`.should == 2
263
- `Object.keys(#@hash.$$smap).length`.should == 3
214
+ `#@hash.size`.should == 5
215
+ keys = `Array.from(#@hash.$$keys.values())[0]`
216
+ `#{keys}.length`.should == 1
217
+ keys[0].should == @mock3
264
218
 
265
- `#@hash.$$keys[0]`.should == 'a'
266
- `#@hash.$$keys[1]`.should == 'b'
267
- `#@hash.$$keys[2].key`.should == @mock3
268
- `#@hash.$$keys[3]`.should == 'c'
269
- `#@hash.$$keys[4].key`.should == @obj1
270
-
271
- `#@hash.$$map['hhh'] === #@hash.$$keys[2]`.should == true
272
- `#@hash.$$keys[2].next === undefined`.should == true
219
+ keys = `Array.from(#@hash.keys())`
220
+ keys[0].should == 'a'
221
+ keys[1].should == 'b'
222
+ keys[2].should == @mock3
223
+ keys[3].should == 'c'
224
+ keys[4].should == @obj1
273
225
 
274
226
  @hash.delete @mock3
275
227
 
276
- `#@hash.$$keys.length`.should == 4
277
- `Object.keys(#@hash.$$map).length`.should == 1
278
- `Object.keys(#@hash.$$smap).length`.should == 3
279
-
280
- `#@hash.$$keys[0]`.should == 'a'
281
- `#@hash.$$keys[1]`.should == 'b'
282
- `#@hash.$$keys[2]`.should == 'c'
283
- `#@hash.$$keys[3].key`.should == @obj1
228
+ `#@hash.size`.should == 4
229
+ `#@hash.$$keys.size`.should == 1
230
+ keys = `Array.from(#@hash.$$keys.values())[0]`
231
+ `#{keys}.length`.should == 1
232
+ keys[0].should == @obj1
284
233
 
285
- `#@hash.$$map['hhh'] === undefined`.should == true
234
+ keys = `Array.from(#@hash.keys())`
235
+ keys[0].should == 'a'
236
+ keys[1].should == 'b'
237
+ keys[2].should == 'c'
238
+ keys[3].should == @obj1
286
239
 
287
240
  @hash.delete @obj1
288
241
 
289
- `#@hash.$$keys.length`.should == 3
290
- `Object.keys(#@hash.$$map).length`.should == 0
291
- `Object.keys(#@hash.$$smap).length`.should == 3
242
+ `#@hash.size`.should == 3
243
+ `#@hash.$$keys.size`.should == 0
292
244
 
293
- `#@hash.$$keys[0]`.should == 'a'
294
- `#@hash.$$keys[1]`.should == 'b'
295
- `#@hash.$$keys[2]`.should == 'c'
245
+ keys = `Array.from(#@hash.keys())`
246
+ keys[0].should == 'a'
247
+ keys[1].should == 'b'
248
+ keys[2].should == 'c'
296
249
 
297
- `#@hash.$$map[#{@obj1.hash}] === undefined`.should == true
250
+ `#@hash.$$keys.get(#{@obj1.hash}) === undefined`.should == true
298
251
 
299
252
  @hash.delete 'b'
300
253
 
301
- `#@hash.$$keys.length`.should == 2
302
- `Object.keys(#@hash.$$map).length`.should == 0
303
- `Object.keys(#@hash.$$smap).length`.should == 2
254
+ `#@hash.size`.should == 2
255
+ `#@hash.$$keys.size`.should == 0
304
256
 
305
- `#@hash.$$keys[0]`.should == 'a'
306
- `#@hash.$$keys[1]`.should == 'c'
307
- `#@hash.$$smap['a']`.should == 'abc'
308
- `#@hash.$$smap['b'] === undefined`.should == true
309
- `#@hash.$$smap['c']`.should == 'ghi'
257
+ keys = `Array.from(#@hash.keys())`
258
+ keys[0].should == 'a'
259
+ keys[1].should == 'c'
260
+
261
+ `#@hash.get('a')`.should == 'abc'
262
+ `#@hash.get('b') === undefined`.should == true
263
+ `#@hash.get('c')`.should == 'ghi'
310
264
 
311
265
  @hash.delete 'c'
312
266
 
313
- `#@hash.$$keys.length`.should == 1
314
- `Object.keys(#@hash.$$map).length`.should == 0
315
- `Object.keys(#@hash.$$smap).length`.should == 1
267
+ `#@hash.size`.should == 1
268
+ `#@hash.$$keys.size`.should == 0
316
269
 
317
- `#@hash.$$keys[0]`.should == 'a'
318
- `#@hash.$$smap['a']`.should == 'abc'
319
- `#@hash.$$smap['b'] === undefined`.should == true
320
- `#@hash.$$smap['c'] === undefined`.should == true
270
+ keys = `Array.from(#@hash.keys())`
271
+ keys[0].should == 'a'
321
272
 
322
- @hash.delete 'a'
273
+ `#@hash.get('a')`.should == 'abc'
274
+ `#@hash.get('b') === undefined`.should == true
275
+ `#@hash.get('c') === undefined`.should == true
323
276
 
324
- `#@hash.$$keys.length`.should == 0
325
- `Object.keys(#@hash.$$map).length`.should == 0
326
- `Object.keys(#@hash.$$smap).length`.should == 0
277
+ @hash.delete 'a'
327
278
 
328
- `#@hash.$$smap['a'] === undefined`.should == true
329
- `#@hash.$$smap['b'] === undefined`.should == true
330
- `#@hash.$$smap['c'] === undefined`.should == true
279
+ `#@hash.size`.should == 0
280
+ `#@hash.$$keys.size`.should == 0
331
281
 
332
- `Opal.hasOwnProperty.call(#@hash.$$map, 'hhh')`.should == false
333
- `Opal.hasOwnProperty.call(#@hash.$$map, #{@obj1.hash})`.should == false
334
- `Opal.hasOwnProperty.call(#@hash.$$smap, 'a')`.should == false
335
- `Opal.hasOwnProperty.call(#@hash.$$smap, 'b')`.should == false
336
- `Opal.hasOwnProperty.call(#@hash.$$smap, 'c')`.should == false
282
+ `#@hash.get('a') === undefined`.should == true
283
+ `#@hash.get('b') === undefined`.should == true
284
+ `#@hash.get('c') === undefined`.should == true
337
285
  end
338
286
  end
339
287
  end
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe 'Hash' do
2
4
  it 'works with object-strings with regards to deleting' do
3
5
  h = {`new String('a')` => 'a'}
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Iterable props defined by Opal on core JS objects' do
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  module KernelExit
2
4
  extend self
3
5
  attr_accessor :status, :original_proc, :proc, :out
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class RespondToSpecs
2
4
  def foo
3
5
  end
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe 'mlhs argument' do
2
4
  context 'when pased value is falsey in JS' do
3
5
  it 'still returns it' do
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe 'Safe navigator' do
2
4
  it "handles also null and undefined" do
3
5
  [`null`, `undefined`].each do |value|
@@ -0,0 +1,15 @@
1
+ # backtick_javascript: false
2
+
3
+ describe "The x-string expression for send" do
4
+ def `(command)
5
+ "Linux x86_64" if command == "uname -a"
6
+ end
7
+
8
+ it "compiles as send if backtick_javascript is false" do
9
+ `uname -a`.should == "Linux x86_64"
10
+ end
11
+
12
+ it "compiles as send with dstr if backtick_javascript is false" do
13
+ `uname#{" "}-a`.should == "Linux x86_64"
14
+ end
15
+ end
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe "The x-string expression" do
2
4
  it "works with multiline, case and assignment" do
3
5
  a = case 1
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe "generated method names" do
@@ -68,4 +68,48 @@ describe 'Module' do
68
68
  OPAL_SPEC_MODULE.class.should == Module
69
69
  OPAL_SPEC_CLASS.class.should == Class
70
70
  end
71
+
72
+ describe "updates iclass" do
73
+ def included_structures
74
+ mod = Module.new { def method_to_remove; end }
75
+ klass = Class.new { include mod }
76
+ [mod, klass]
77
+ end
78
+
79
+ def prepended_structures
80
+ mod = Module.new { def method_to_remove; end }
81
+ klass = Class.new { prepend mod }
82
+ [mod, klass]
83
+ end
84
+
85
+ it "whenever a new method is added to an included module" do
86
+ mod, klass = included_structures
87
+ ->{ klass.new.nonexistent }.should raise_error NoMethodError
88
+ mod.class_exec { def added_method; end }
89
+ ->{ klass.new.added_method }.should_not raise_error NoMethodError
90
+ end
91
+
92
+ it "whenever a new method is added to a prepended module" do
93
+ mod, klass = prepended_structures
94
+ ->{ klass.new.nonexistent }.should raise_error NoMethodError
95
+ mod.class_exec { def added_method; end }
96
+ ->{ klass.new.added_method }.should_not raise_error NoMethodError
97
+ end
98
+
99
+ it "whenever a method is removed from an included module" do
100
+ mod, klass = included_structures
101
+ ->{ klass.new.nonexistent }.should raise_error NoMethodError
102
+ ->{ klass.new.method_to_remove }.should_not raise_error NoMethodError
103
+ mod.class_exec { remove_method :method_to_remove }
104
+ ->{ klass.new.method_to_remove }.should raise_error NoMethodError
105
+ end
106
+
107
+ it "whenever a method is removed from a prepended module" do
108
+ mod, klass = prepended_structures
109
+ ->{ klass.new.nonexistent }.should raise_error NoMethodError
110
+ ->{ klass.new.method_to_remove }.should_not raise_error NoMethodError
111
+ mod.class_exec { remove_method :method_to_remove }
112
+ ->{ klass.new.method_to_remove }.should raise_error NoMethodError
113
+ end
114
+ end
71
115
  end
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe 'Number#to_i' do
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe "Opal.uid()" do
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe 'Regexp#match' do
2
4
  describe 'when pos is not specified' do
3
5
  it 'calls .exec only once on the current object' do
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  %x{
@@ -122,6 +124,42 @@ describe 'Bridged classes in different modules' do
122
124
  end
123
125
  end
124
126
 
127
+ %x{
128
+ var counter = 0;
129
+ var reset_counter = function() { counter = 0; };
130
+ var bridge_class_with_constructor = function() { counter++; };
131
+ }
132
+
133
+ class BridgedLevel0 < `bridge_class_with_constructor`; end
134
+ class BridgedLevel1 < BridgedLevel0; end
135
+ class BridgedLevel2 < BridgedLevel1; end
136
+ class BridgedLevel3 < BridgedLevel2; end
137
+
138
+ describe 'Inheritance with bridged classes' do
139
+ it 'should call a JS constructor on level 0' do
140
+ `reset_counter()`
141
+ BridgedLevel0.new
142
+ `counter`.should == 1
143
+ end
144
+
145
+ it 'should call a JS constructor on level 1' do
146
+ `reset_counter()`
147
+ BridgedLevel1.new
148
+ `counter`.should == 1
149
+ end
150
+
151
+ it 'should call a JS constructor on level 2' do
152
+ `reset_counter()`
153
+ BridgedLevel2.new
154
+ `counter`.should == 1
155
+ end
156
+
157
+ it 'should call a JS constructor on level 3' do
158
+ `reset_counter()`
159
+ BridgedLevel3.new
160
+ `counter`.should == 1
161
+ end
162
+ end
125
163
 
126
164
  describe "Invalid bridged classes" do
127
165
  it "raises a TypeError when trying to extend with non-Class" do
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  module RuntimeFixtures
2
4
  class A
3
5
  end
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe "Opal.eval()" do
2
4
  it "evaluates ruby code by compiling it to javascript and running" do
3
5
  `Opal['eval']("'foo'.class")`.should == String