opal 1.7.4 → 1.8.0.alpha1

Sign up to get free protection for your applications and to get access to all the features.
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
  require 'base64'
2
4
  require 'corelib/pack_unpack/format_string_parser'
3
5
 
@@ -1,4 +1,5 @@
1
1
  # helpers: coerce_to, respond_to, global_multiline_regexp, prop
2
+ # backtick_javascript: true
2
3
 
3
4
  require 'corelib/comparable'
4
5
  require 'corelib/regexp'
@@ -24,7 +25,7 @@ class ::String < `String`
24
25
  var opts = args[args.length-1];
25
26
  str = $coerce_to(str, #{::String}, 'to_str');
26
27
  if (opts && opts.$$is_hash) {
27
- if (opts.$$smap.encoding) str = str.$force_encoding(opts.$$smap.encoding);
28
+ if (opts.has('encoding')) str = str.$force_encoding(opts.get('encoding').value);
28
29
  }
29
30
  str = new self.$$constructor(str);
30
31
  if (!str.$initialize.$$pristine) #{`str`.initialize(*args)};
@@ -1060,17 +1061,18 @@ class ::String < `String`
1060
1061
  string = self.toString(),
1061
1062
  index = 0,
1062
1063
  match,
1063
- i, ii;
1064
+ match_count = 0,
1065
+ valid_result_length = 0,
1066
+ i, max;
1064
1067
 
1065
1068
  if (pattern.$$is_regexp) {
1066
1069
  pattern = $global_multiline_regexp(pattern);
1067
1070
  } else {
1068
1071
  pattern = $coerce_to(pattern, #{::String}, 'to_str').$to_s();
1072
+
1069
1073
  if (pattern === ' ') {
1070
1074
  pattern = /\s+/gm;
1071
1075
  string = string.replace(/^\s+/, '');
1072
- } else {
1073
- pattern = new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'gm');
1074
1076
  }
1075
1077
  }
1076
1078
 
@@ -1086,16 +1088,21 @@ class ::String < `String`
1086
1088
 
1087
1089
  if (limit === 0) {
1088
1090
  while (result[result.length - 1] === '') {
1089
- result.length -= 1;
1091
+ result.pop();
1090
1092
  }
1091
1093
  return result;
1092
1094
  }
1093
1095
 
1096
+ if (!pattern.$$is_regexp) {
1097
+ pattern = Opal.escape_regexp(pattern)
1098
+ pattern = new RegExp(pattern, 'gm');
1099
+ }
1100
+
1094
1101
  match = pattern.exec(string);
1095
1102
 
1096
1103
  if (limit < 0) {
1097
1104
  if (match !== null && match[0] === '' && pattern.source.indexOf('(?=') === -1) {
1098
- for (i = 0, ii = match.length; i < ii; i++) {
1105
+ for (i = 0, max = match.length; i < max; i++) {
1099
1106
  result.push('');
1100
1107
  }
1101
1108
  }
@@ -1103,7 +1110,8 @@ class ::String < `String`
1103
1110
  }
1104
1111
 
1105
1112
  if (match !== null && match[0] === '') {
1106
- result.splice(limit - 1, result.length - 1, result.slice(limit - 1).join(''));
1113
+ valid_result_length = (match.length - 1) * (limit - 1) + limit
1114
+ result.splice(valid_result_length - 1, result.length - 1, result.slice(valid_result_length - 1).join(''));
1107
1115
  return result;
1108
1116
  }
1109
1117
 
@@ -1111,16 +1119,16 @@ class ::String < `String`
1111
1119
  return result;
1112
1120
  }
1113
1121
 
1114
- i = 0;
1115
1122
  while (match !== null) {
1116
- i++;
1123
+ match_count++;
1117
1124
  index = pattern.lastIndex;
1118
- if (i + 1 === limit) {
1125
+ valid_result_length += match.length
1126
+ if (match_count + 1 === limit) {
1119
1127
  break;
1120
1128
  }
1121
1129
  match = pattern.exec(string);
1122
1130
  }
1123
- result.splice(limit - 1, result.length - 1, string.slice(index));
1131
+ result.splice(valid_result_length, result.length - 1, string.slice(index));
1124
1132
  return result;
1125
1133
  }
1126
1134
  end
@@ -1154,7 +1162,7 @@ class ::String < `String`
1154
1162
  } else {
1155
1163
  var prefix = $coerce_to(prefixes[i], #{::String}, 'to_str').$to_s();
1156
1164
 
1157
- if (self.indexOf(prefix) === 0) {
1165
+ if (self.length >= prefix.length && self.startsWith(prefix)) {
1158
1166
  return true;
1159
1167
  }
1160
1168
  }
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'corelib/enumerable'
2
4
 
3
5
  class ::Struct
@@ -288,7 +290,7 @@ class ::Struct
288
290
  `inspect_stack.pop()` if pushed
289
291
  end
290
292
 
291
- def to_h(&block)
293
+ def to_h(*args, &block)
292
294
  return map(&block).to_h(*args) if block_given?
293
295
 
294
296
  self.class.members.each_with_object({}) { |name, h| h[name] = self[name] }
data/opal/corelib/time.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # helpers: slice, deny_frozen_access
2
+ # backtick_javascript: true
2
3
 
3
4
  require 'corelib/comparable'
4
5
 
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class ::TracePoint
2
4
  # partial implementation of TracePoint
3
5
  # for the moment only supports the :class event
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  %x{
2
4
  var warnings = {};
3
5
 
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  # regexp matches
2
4
  %x{$gvars['&'] = $gvars['~'] = $gvars['`'] = $gvars["'"] = nil}
3
5
 
data/opal.gemspec CHANGED
@@ -45,8 +45,8 @@ Gem::Specification.new do |spec|
45
45
  spec.add_development_dependency 'selenium-webdriver'
46
46
  spec.add_development_dependency 'benchmark-ips', '< 2.8'
47
47
  spec.add_development_dependency 'sinatra', '~> 3.0'
48
- spec.add_development_dependency 'rubocop', '~> 0.67.0'
49
- spec.add_development_dependency 'rubocop-performance', '~> 1.1.0'
48
+ spec.add_development_dependency 'rubocop', '~> 1.50'
49
+ spec.add_development_dependency 'rubocop-performance', '~> 1.1'
50
50
  spec.add_development_dependency 'rack', '~> 2.2'
51
51
  spec.add_development_dependency 'webrick'
52
52
  spec.add_development_dependency 'benchmark_driver', '0.15.17' # version taken from test/cruby/common.mk
@@ -33,8 +33,6 @@ opal_filter "Array" do
33
33
  fails "Array#slice raises TypeError if to_int returns non-integer" # Expected TypeError but no exception was raised ([1, 2, 3, 4] was returned)
34
34
  fails "Array#slice raises a RangeError if passed a range with a bound that is too large" # Expected RangeError but no exception was raised (nil was returned)
35
35
  fails "Array#slice raises a type error if a range is passed with a length" # Expected TypeError but no exception was raised ([2, 3] was returned)
36
- fails "Array#to_h with block does not coerce returned pair to Array with #to_a" # Expected TypeError (/wrong element type MockObject at 0/) but got: TypeError (wrong element type NilClass at 0 (expected array))
37
- fails "Array#to_h with block raises TypeError if block returns something other than Array" # Expected TypeError (/wrong element type String at 0/) but got: TypeError (wrong element type NilClass at 0 (expected array))
38
36
  fails "Array#to_s does not call #to_str on the object returned from #to_s when it is not a String" # Exception: Cannot convert object to primitive value
39
37
  fails "Array#uniq! properly handles recursive arrays" # Expected [1, "two", 3, [...], [...], [...]] == [1, "two", 3, [1, "two", 3, [...], [...], [...]]] to be truthy but was false
40
38
  end
@@ -23,9 +23,6 @@ opal_filter "Enumerable" do
23
23
  fails "Enumerable#sort_by returns an array of elements when a block is supplied and #map returns an enumerable" # NoMethodError: undefined method `sort!' for #<EnumerableSpecs::MapReturnsEnumerable::EnumerableMapping:0x42a48 @items=#<EnumerableSpecs::MapReturnsEnumerable:0x42a46> @block=#<Proc:0x42a4a>>
24
24
  fails "Enumerable#take_while calls the block with initial args when yielded with multiple arguments" # Expected [1, [2], [3, 4], [5, 6, 7], [8, 9], nil, []] == [1, [2], 3, 5, [8, 9], nil, []] to be truthy but was false
25
25
  fails "Enumerable#tally counts values as gathered array when yielded with multiple arguments" # Expected {[]=>3, 0=>1, [0, 1]=>2, [0, 1, 2]=>3, nil=>1, "default_arg"=>1, [0]=>1} == {nil=>2, 0=>1, [0, 1]=>2, [0, 1, 2]=>3, "default_arg"=>1, []=>2, [0]=>1} to be truthy but was false
26
- fails "Enumerable#to_h with block does not coerce returned pair to Array with #to_a" # Expected TypeError (/wrong element type MockObject/) but got: TypeError (wrong element type NilClass at 0 (expected array))
27
- fails "Enumerable#to_h with block raises ArgumentError if block returns longer or shorter array" # Expected ArgumentError (/element has wrong array length/) but got: ArgumentError (wrong array length at 0 (expected 2, was 3))
28
- fails "Enumerable#to_h with block raises TypeError if block returns something other than Array" # Expected TypeError (/wrong element type String/) but got: TypeError (wrong element type NilClass at 0 (expected array))
29
26
  fails "Enumerable#uniq uses eql? semantics" # Expected [1] == [1, 1] to be truthy but was false
30
27
  fails "Enumerable#zip passes each element of the result array to a block and return nil if a block is given" # Expected [[1, 4, 7], [2, 5, 8], [3, 6, 9]] == nil to be truthy but was false
31
28
  end
@@ -21,27 +21,14 @@ opal_filter "Hash" do
21
21
  fails "Hash#inspect does not call #to_str on the object returned from #inspect when it is not a String" # Expected "{\"a\"=>#<MockObject:0x40e02>}" =~ /^\{:a=>#<MockObject:0x[0-9a-f]+>\}$/ to be truthy but was nil
22
22
  fails "Hash#inspect does not call #to_str on the object returned from #to_s when it is not a String" # Exception: Cannot convert object to primitive value
23
23
  fails "Hash#invert compares new keys with eql? semantics" # Expected "b" == "a" to be truthy but was false
24
- fails "Hash#rehash removes duplicate keys for large hashes" # Expected 102 == 101 to be truthy but was false
25
- fails "Hash#rehash removes duplicate keys" # Expected 2 == 1 to be truthy but was false
26
24
  fails "Hash#store does not dispatch to hash for Boolean, Integer, Float, String, or Symbol" # NoMethodError: undefined method `tmp' for #<MSpecEnv:0x627dc @method="store" @object=nil>
27
25
  fails "Hash#store keeps the existing String key in the hash if there is a matching one" # Expected "foo" not to be identical to "foo"
28
- fails "Hash#to_h with block does not coerce returned pair to Array with #to_a" # Expected TypeError (/wrong element type MockObject/) but got: TypeError (wrong element type NilClass at 0 (expected array))
29
- fails "Hash#to_h with block raises ArgumentError if block returns longer or shorter array" # Expected ArgumentError (/element has wrong array length/) but got: ArgumentError (wrong array length at 0 (expected 2, was 3))
30
- fails "Hash#to_h with block raises TypeError if block returns something other than Array" # Expected TypeError (/wrong element type String/) but got: TypeError (wrong element type NilClass at 0 (expected array))
31
26
  fails "Hash#to_proc the returned proc has an arity of 1" # Expected -1 == 1 to be truthy but was false
32
27
  fails "Hash#to_proc the returned proc is a lambda" # Expected #<Proc:0x42df6>.lambda? to be truthy but was false
33
28
  fails "Hash#to_s calls #to_s on the object returned from #inspect if the Object isn't a String" # Expected "{\"a\"=>abc}" == "{:a=>abc}" to be truthy but was false
34
29
  fails "Hash#to_s does not call #to_s on a String returned from #inspect" # Expected "{\"a\"=>\"abc\"}" == "{:a=>\"abc\"}" to be truthy but was false
35
30
  fails "Hash#to_s does not call #to_str on the object returned from #inspect when it is not a String" # Expected "{\"a\"=>#<MockObject:0xb4f9a>}" =~ /^\{:a=>#<MockObject:0x[0-9a-f]+>\}$/ to be truthy but was nil
36
31
  fails "Hash#to_s does not call #to_str on the object returned from #to_s when it is not a String" # Exception: Cannot convert object to primitive value
37
- fails "Hash#transform_keys allows a combination of hash and block argument" # ArgumentError: [Hash#transform_keys] wrong number of arguments (given 1, expected 0)
38
- fails "Hash#transform_keys allows a hash argument" # ArgumentError: [Hash#transform_keys] wrong number of arguments (given 1, expected 0)
39
- fails "Hash#transform_keys allows a partial transformation of keys when using a hash argument" # ArgumentError: [Hash#transform_keys] wrong number of arguments (given 1, expected 0)
40
- fails "Hash#transform_keys! allows a hash argument" # ArgumentError: [Hash#transform_keys!] wrong number of arguments (given 1, expected 0)
41
- fails "Hash#transform_keys! on frozen instance raises a FrozenError on hash argument" # Expected FrozenError but got: ArgumentError ([Hash#transform_keys!] wrong number of arguments (given 1, expected 0))
42
- fails "Hash#transform_keys! prevents conflicts between new keys and old ones" # Expected {"e"=>1} == {"b"=>1, "c"=>2, "d"=>3, "e"=>4} to be truthy but was false
43
- fails "Hash#transform_keys! returns the processed keys and non evaluated keys if we break from the block" # Expected {"c"=>1, "d"=>4} == {"b"=>1, "c"=>2, "d"=>4} to be truthy but was false
44
- fails "Hash.[] raises for elements that are not arrays" # Expected ArgumentError but no exception was raised (nil was returned)
45
32
  fails "Hash.ruby2_keywords_hash copies instance variables" # Expected nil == 42 to be truthy but was false
46
33
  fails "Hash.ruby2_keywords_hash raises TypeError for non-Hash" # Expected TypeError but no exception was raised (nil was returned)
47
34
  fails "Hash.ruby2_keywords_hash returns a copy of a Hash and marks the copy as a keywords Hash" # Expected false == true to be truthy but was false
@@ -14,25 +14,6 @@ opal_filter "Kernel" do
14
14
  fails "Kernel#Float for hexadecimal literals with binary exponent returns 0 for '0x1p-10000'" # ArgumentError: invalid value for Float(): "0x1p-10000"
15
15
  fails "Kernel#Float for hexadecimal literals with binary exponent returns Infinity for '0x1P10000'" # ArgumentError: invalid value for Float(): "0x1P10000"
16
16
  fails "Kernel#Float for hexadecimal literals with binary exponent returns Infinity for '0x1p10000'" # ArgumentError: invalid value for Float(): "0x1p10000"
17
- fails "Kernel#Float when passed exception: false and invalid input swallows an error" # ArgumentError: [Object#Float] wrong number of arguments (given 2, expected 1)
18
- fails "Kernel#Float when passed exception: false and nil swallows it" # ArgumentError: [Object#Float] wrong number of arguments (given 2, expected 1)
19
- fails "Kernel#Float when passed exception: false and valid input returns a Float number" # ArgumentError: [Object#Float] wrong number of arguments (given 2, expected 1)
20
- fails "Kernel#Integer raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" # Expected TypeError but no exception was raised ("1" was returned)
21
- fails "Kernel#Integer return a result of to_i when to_int does not return an Integer" # Expected "1" == 42 to be truthy but was false
22
- fails "Kernel#Integer when passed exception: false and an argument that contains a period swallows an error" # TypeError: no implicit conversion of Hash into Integer
23
- fails "Kernel#Integer when passed exception: false and an empty string swallows an error" # TypeError: no implicit conversion of Hash into Integer
24
- fails "Kernel#Integer when passed exception: false and invalid argument swallows an error" # ArgumentError: [MSpecEnv#Integer] wrong number of arguments (given 3, expected -2)
25
- fails "Kernel#Integer when passed exception: false and multiple leading -s swallows an error" # TypeError: no implicit conversion of Hash into Integer
26
- fails "Kernel#Integer when passed exception: false and multiple trailing -s swallows an error" # TypeError: no implicit conversion of Hash into Integer
27
- fails "Kernel#Integer when passed exception: false and no to_int or to_i methods exist swallows an error" # ArgumentError: base specified for non string value
28
- fails "Kernel#Integer when passed exception: false and passed Infinity swallows an error" # ArgumentError: base specified for non string value
29
- fails "Kernel#Integer when passed exception: false and passed NaN swallows an error" # ArgumentError: base specified for non string value
30
- fails "Kernel#Integer when passed exception: false and passed a String that can't be converted to an Integer swallows an error" # TypeError: no implicit conversion of Hash into Integer
31
- fails "Kernel#Integer when passed exception: false and passed a String that contains numbers normally parses it and returns an Integer" # TypeError: no implicit conversion of Hash into Integer
32
- fails "Kernel#Integer when passed exception: false and passed nil swallows an error" # ArgumentError: base specified for non string value
33
- fails "Kernel#Integer when passed exception: false and to_i returns a value that is not an Integer swallows an error" # ArgumentError: base specified for non string value
34
- fails "Kernel#Integer when passed exception: false and to_int returns nil and no to_i exists swallows an error" # ArgumentError: base specified for non string value
35
- fails "Kernel#Integer when passed exception: false and valid argument returns an Integer number" # ArgumentError: [MSpecEnv#Integer] wrong number of arguments (given 3, expected -2)
36
17
  fails "Kernel#Pathname returns same argument when called with a pathname argument" # Expected #<Pathname:0xb23c2 @path="foo">.equal? #<Pathname:0xb23c4 @path="foo"> to be truthy but was false
37
18
  fails "Kernel#String calls #to_s if #respond_to?(:to_s) returns true" # TypeError: no implicit conversion of MockObject into String
38
19
  fails "Kernel#String raises a TypeError if #to_s is not defined, even though #respond_to?(:to_s) returns true" # Expected TypeError but got: NoMethodError (undefined method `to_s' for #<Object:0x2961a>)
@@ -323,25 +304,6 @@ opal_filter "Kernel" do
323
304
  fails "Kernel.Float for hexadecimal literals with binary exponent returns 0 for '0x1p-10000'" # ArgumentError: invalid value for Float(): "0x1p-10000"
324
305
  fails "Kernel.Float for hexadecimal literals with binary exponent returns Infinity for '0x1P10000'" # ArgumentError: invalid value for Float(): "0x1P10000"
325
306
  fails "Kernel.Float for hexadecimal literals with binary exponent returns Infinity for '0x1p10000'" # ArgumentError: invalid value for Float(): "0x1p10000"
326
- fails "Kernel.Float when passed exception: false and invalid input swallows an error" # ArgumentError: [Kernel.Float] wrong number of arguments (given 2, expected 1)
327
- fails "Kernel.Float when passed exception: false and nil swallows it" # ArgumentError: [Kernel.Float] wrong number of arguments (given 2, expected 1)
328
- fails "Kernel.Float when passed exception: false and valid input returns a Float number" # ArgumentError: [Kernel.Float] wrong number of arguments (given 2, expected 1)
329
- fails "Kernel.Integer raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" # Expected TypeError but no exception was raised ("1" was returned)
330
- fails "Kernel.Integer return a result of to_i when to_int does not return an Integer" # Expected "1" == 42 to be truthy but was false
331
- fails "Kernel.Integer when passed exception: false and an argument that contains a period swallows an error" # TypeError: no implicit conversion of Hash into Integer
332
- fails "Kernel.Integer when passed exception: false and an empty string swallows an error" # TypeError: no implicit conversion of Hash into Integer
333
- fails "Kernel.Integer when passed exception: false and invalid argument swallows an error" # ArgumentError: [MSpecEnv#Integer] wrong number of arguments (given 3, expected -2)
334
- fails "Kernel.Integer when passed exception: false and multiple leading -s swallows an error" # TypeError: no implicit conversion of Hash into Integer
335
- fails "Kernel.Integer when passed exception: false and multiple trailing -s swallows an error" # TypeError: no implicit conversion of Hash into Integer
336
- fails "Kernel.Integer when passed exception: false and no to_int or to_i methods exist swallows an error" # ArgumentError: base specified for non string value
337
- fails "Kernel.Integer when passed exception: false and passed Infinity swallows an error" # ArgumentError: base specified for non string value
338
- fails "Kernel.Integer when passed exception: false and passed NaN swallows an error" # ArgumentError: base specified for non string value
339
- fails "Kernel.Integer when passed exception: false and passed a String that can't be converted to an Integer swallows an error" # TypeError: no implicit conversion of Hash into Integer
340
- fails "Kernel.Integer when passed exception: false and passed a String that contains numbers normally parses it and returns an Integer" # TypeError: no implicit conversion of Hash into Integer
341
- fails "Kernel.Integer when passed exception: false and passed nil swallows an error" # ArgumentError: base specified for non string value
342
- fails "Kernel.Integer when passed exception: false and to_i returns a value that is not an Integer swallows an error" # ArgumentError: base specified for non string value
343
- fails "Kernel.Integer when passed exception: false and to_int returns nil and no to_i exists swallows an error" # ArgumentError: base specified for non string value
344
- fails "Kernel.Integer when passed exception: false and valid argument returns an Integer number" # ArgumentError: [MSpecEnv#Integer] wrong number of arguments (given 3, expected -2)
345
307
  fails "Kernel.Rational when passed a String converts the String to a Rational using the same method as String#to_r" # Expected (0/1) == (13/25) to be truthy but was false
346
308
  fails "Kernel.Rational when passed a String does not use the same method as Float#to_r" # Expected (5404319552844595/9007199254740992) == (3/5) to be truthy but was false
347
309
  fails "Kernel.Rational when passed a String raises a TypeError if the first argument is a Symbol" # Expected TypeError but no exception was raised ((0/1) was returned)
@@ -87,7 +87,6 @@ opal_filter "Range" do
87
87
  fails "Range#minmax on an inclusive range should raise RangeError on an endless range without iterating the range" # Mock 'x': method <=> called with unexpected arguments (nil)
88
88
  fails "Range#minmax on an inclusive range should return the minimum and maximum values for a non-numeric range without iterating the range" # Mock 'x' expected to receive succ("any_args") exactly 0 times but received it 1 times
89
89
  fails "Range#minmax on an inclusive range should return the minimum and maximum values for a numeric range without iterating the range" # TypeError: can't iterate from Float
90
- fails "Range#size returns nil for endless ranges if the start is not numeric" # Expected Infinity == nil to be truthy but was false
91
90
  fails "Range#step when no block is given returned Enumerator size raises a TypeError if #to_int does not return an Integer" # Expected TypeError but no exception was raised (((1..2).step(#<MockObject:0x61a92>)) was returned)
92
91
  fails "Range#step when no block is given returned Enumerator size raises a TypeError if step does not respond to #to_int" # Expected TypeError but got: ArgumentError (no implicit conversion of MockObject into Integer)
93
92
  fails "Range#step when no block is given returned Enumerator size returns the range size when there's no step_size" # Expected 9 == 10 to be truthy but was false
@@ -21,8 +21,6 @@ opal_filter "Ruby 3.2" do
21
21
  fails "Module#ruby2_keywords makes a copy and unmark the Hash when calling a method taking (*args)" # Expected false == true to be truthy but was false
22
22
  fails "Proc#parameters adds * rest arg for \"star\" argument" # Expected [["req", "x"], ["rest"]] == [["req", "x"], ["rest", "*"]] to be truthy but was false
23
23
  fails "Random::DEFAULT is no longer defined" # Expected Random.const_defined? "DEFAULT" to be falsy but was true
24
- fails "Range#size returns nil for all beginless ranges if the start is numeric" # Expected Infinity == nil to be truthy but was false
25
- fails "Range#size returns nil if the start and the end is both nil" # Expected Infinity == nil to be truthy but was false
26
24
  fails "Refinement#append_features is not called by Module#include" # Expected TypeError but no exception was raised (#<Class:0x2e61c> was returned)
27
25
  fails "Refinement#extend_object is not called by Object#extend" # Expected TypeError but no exception was raised (#<Class:0x28fcc> was returned)
28
26
  fails "Refinement#prepend_features is not called by Module#prepend" # Expected TypeError but no exception was raised (#<Class:0x70cf6> was returned)
@@ -231,7 +231,6 @@ opal_filter "String" do
231
231
  fails "String#slice with index, length raises a RangeError if the index or length is too big" # Expected RangeError but no exception was raised (nil was returned)
232
232
  fails "String#slice with index, length returns a string with the same encoding as self" # Expected #<Encoding:UTF-8> == #<Encoding:US-ASCII> to be truthy but was false
233
233
  fails "String#split with Regexp allows concurrent Regexp calls in a shared context" # NotImplementedError: Thread creation not available
234
- fails "String#split with Regexp applies the limit to the number of split substrings, without counting captures" # Expected ["a", "aBa"] == ["a", "B", "", "", "aBa"] to be truthy but was false
235
234
  fails "String#split with Regexp for a String subclass yields instances of String" # Expected nil (NilClass) to be an instance of String
236
235
  fails "String#split with Regexp raises a TypeError when not called with nil, String, or Regexp" # Expected TypeError but no exception was raised (["he", "o"] was returned)
237
236
  fails "String#split with Regexp returns String instances based on self" # Expected "x:y:z:" (StringSpecs::MyString) to be an instance of String
@@ -4,11 +4,7 @@ opal_filter "Struct" do
4
4
  fails "Struct#hash returns different hashes for structs with different values when using keyword_init: true" # NameError: wrong constant name 1 non symbol member
5
5
  fails "Struct#hash returns the same integer for structs with the same content" # Expected "Hash" (String) to be kind of Integer
6
6
  fails "Struct#initialize warns about passing only keyword arguments" # Expected warning to match: /warning: Passing only keyword arguments/ but got: ""
7
- fails "Struct#to_h with block coerces returned pair to Array with #to_ary" # NoMethodError: undefined method `args' for #<struct StructClasses::Car make=nil, model=nil, year=nil>
8
- fails "Struct#to_h with block converts [key, value] pairs returned by the block to a hash" # NoMethodError: undefined method `args' for #<struct StructClasses::Car make="Ford", model="Ranger", year=nil>
9
- fails "Struct#to_h with block does not coerce returned pair to Array with #to_a" # Expected TypeError (/wrong element type MockObject/) but got: NoMethodError (undefined method `args' for #<struct StructClasses::Car make=nil, model=nil, year=nil>)
10
- fails "Struct#to_h with block raises ArgumentError if block returns longer or shorter array" # Expected ArgumentError (/element has wrong array length/) but got: NoMethodError (undefined method `args' for #<struct StructClasses::Car make=nil, model=nil, year=nil>)
11
- fails "Struct#to_h with block raises TypeError if block returns something other than Array" # Expected TypeError (/wrong element type String/) but got: NoMethodError (undefined method `args' for #<struct StructClasses::Car make=nil, model=nil, year=nil>)
7
+ fails "Struct#to_h with block converts [key, value] pairs returned by the block to a hash" # Expected {"Ford"=>"", "Ranger"=>"", ""=>""} == {"make"=>"ford", "model"=>"ranger", "year"=>""} to be truthy but was false
12
8
  fails "Struct-based class#dup retains an included module in the ancestor chain for the struct's singleton class" # NoMethodError: undefined method `hello' for #<Module:0x776e4>
13
9
  fails "Struct.new keyword_init: true option raises when there is a duplicate member" # Expected ArgumentError (duplicate member: foo) but no exception was raised (#<Class:0x76a42> was returned)
14
10
  fails "Struct.new raises ArgumentError when there is a duplicate member" # Expected ArgumentError (duplicate member: foo) but no exception was raised (#<Class:0x769fa> was returned)
@@ -10,4 +10,5 @@ opal_unsupported_filter "Hash" do
10
10
  fails "Hash#to_proc the returned proc passed as a block to instance_exec always retrieves the original hash's values" # Expected nil == 1 to be truthy but was false
11
11
  fails "Hash#to_proc the returned proc raises ArgumentError if not passed exactly one argument" # Expected ArgumentError but no exception was raised (nil was returned)
12
12
  fails "Hash#to_s does not raise if inspected result is not default external encoding" # Mock 'utf_16be' expected to receive inspect("any_args") exactly 1 times but received it 0 times
13
+ fails "Hash#[] compares key via hash" # Mock '0' expected to receive hash("any_args") exactly 1 times but received it 0 times (performance optimization)
13
14
  end
@@ -154,13 +154,6 @@ RSpec.describe Opal::Compiler do
154
154
  end
155
155
  end
156
156
 
157
- describe "escapes in x-strings" do
158
- it "compiles the exscapes directly as appearing in x-strings" do
159
- expect_compiled('`"hello\nworld"`').to include('"hello\nworld"')
160
- expect_compiled('%x{"hello\nworld"}').to include('"hello\nworld"')
161
- end
162
- end
163
-
164
157
  describe 'pre-processing require-ish methods' do
165
158
  describe '#require' do
166
159
  it 'parses and resolve #require argument' do
@@ -324,6 +317,15 @@ RSpec.describe Opal::Compiler do
324
317
  end
325
318
 
326
319
  describe 'x-strings' do
320
+ let(:compiler_options) { {backtick_javascript: true} }
321
+
322
+ describe "escapes" do
323
+ it "compiles the exscapes directly as appearing in x-strings" do
324
+ expect_compiled('`"hello\nworld"`').to include('"hello\nworld"')
325
+ expect_compiled('%x{"hello\nworld"}').to include('"hello\nworld"')
326
+ end
327
+ end
328
+
327
329
  describe 'semicolons handling' do
328
330
  def compiling(code, &block)
329
331
  compiler = Opal::Compiler.new(code)
@@ -477,9 +479,10 @@ RSpec.describe Opal::Compiler do
477
479
  }).to include("return nil\n")
478
480
  end
479
481
 
480
- def expect_number_of_warnings(code)
482
+ def expect_number_of_warnings(code, options = compiler_options)
483
+ options = options.merge(eval: true)
481
484
  warnings_number = 0
482
- compiler = Opal::Compiler.new(code, eval: true)
485
+ compiler = Opal::Compiler.new(code, options)
483
486
  allow(compiler).to receive(:warning) { warnings_number += 1}
484
487
  compiler.compile
485
488
  expect(warnings_number)
@@ -695,21 +698,25 @@ RSpec.describe Opal::Compiler do
695
698
  end
696
699
  end
697
700
 
698
- def compiled(*args)
699
- Opal::Compiler.new(*args).compile
701
+ def compiler_options
702
+ {}
703
+ end
704
+
705
+ def compiled(code, options = compiler_options)
706
+ Opal::Compiler.new(code, options).compile
700
707
  end
701
708
 
702
- def parsed(*args)
703
- Opal::Compiler.new(*args).parse
709
+ def parsed(code, options = compiler_options)
710
+ Opal::Compiler.new(code, options).parse
704
711
  end
705
712
 
706
713
  alias compile compiled
707
714
 
708
- def expect_compiled(*args)
709
- expect(compiled(*args))
715
+ def expect_compiled(code, options = compiler_options)
716
+ expect(compiled(code, options))
710
717
  end
711
718
 
712
- def compiler_for(*args)
713
- Opal::Compiler.new(*args).tap(&:compile)
719
+ def compiler_for(code, options = compiler_options)
720
+ Opal::Compiler.new(code, options).tap(&:compile)
714
721
  end
715
722
  end
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  class BaseOpalFormatter
2
4
  def initialize(out=nil)
3
5
  @exception = @failure = false
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'mspec-opal/formatters'
2
4
 
3
5
  class OSpecFilter
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  describe "Array#dup" do
2
4
  it "should use slice optimization" do
3
5
  a = Array.new
@@ -1,3 +1,5 @@
1
+ # backtick_javascript: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe "Native exception" do