opal 1.4.0.alpha1 → 1.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +5 -3
  3. data/.github/workflows/build.yml +20 -18
  4. data/.rubocop.yml +1 -0
  5. data/CHANGELOG.md +98 -7
  6. data/UNRELEASED.md +31 -59
  7. data/benchmark-ips/bm_js_symbols_vs_strings.rb +39 -14
  8. data/docs/releasing.md +11 -4
  9. data/lib/opal/ast/matcher.rb +77 -0
  10. data/lib/opal/cache.rb +1 -1
  11. data/lib/opal/cli_runners/applescript.rb +2 -0
  12. data/lib/opal/compiler.rb +18 -9
  13. data/lib/opal/nodes/call.rb +73 -28
  14. data/lib/opal/nodes/def.rb +31 -27
  15. data/lib/opal/nodes/definitions.rb +2 -0
  16. data/lib/opal/nodes/helpers.rb +4 -23
  17. data/lib/opal/nodes/if.rb +226 -0
  18. data/lib/opal/nodes/iter.rb +41 -37
  19. data/lib/opal/nodes/literal.rb +2 -2
  20. data/lib/opal/nodes/masgn.rb +15 -17
  21. data/lib/opal/nodes/node_with_args/shortcuts.rb +100 -0
  22. data/lib/opal/nodes/node_with_args.rb +1 -0
  23. data/lib/opal/nodes/super.rb +9 -9
  24. data/lib/opal/nodes/top.rb +26 -10
  25. data/lib/opal/nodes/x_string.rb +27 -28
  26. data/lib/opal/nodes.rb +0 -1
  27. data/lib/opal/parser/default_config.rb +3 -2
  28. data/lib/opal/repl.rb +1 -1
  29. data/lib/opal/rewriter.rb +13 -6
  30. data/lib/opal/rewriters/base.rb +12 -1
  31. data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +1 -0
  32. data/lib/opal/version.rb +1 -1
  33. data/opal/corelib/array.rb +23 -28
  34. data/opal/corelib/binding.rb +14 -4
  35. data/opal/corelib/constants.rb +3 -3
  36. data/opal/corelib/hash.rb +2 -2
  37. data/opal/corelib/irb.rb +192 -0
  38. data/opal/corelib/math/polyfills.rb +127 -0
  39. data/opal/corelib/math.rb +14 -194
  40. data/opal/corelib/module.rb +25 -40
  41. data/opal/corelib/number.rb +63 -14
  42. data/opal/corelib/regexp.rb +2 -0
  43. data/opal/corelib/runtime.js +56 -20
  44. data/opal/corelib/string.rb +38 -59
  45. data/opal/corelib/time.rb +106 -68
  46. data/opal/opal/full.rb +0 -1
  47. data/opal/opal.rb +4 -1
  48. data/spec/filters/bugs/date.rb +0 -3
  49. data/spec/filters/bugs/datetime.rb +65 -0
  50. data/spec/filters/bugs/float.rb +0 -18
  51. data/spec/filters/bugs/hash.rb +0 -2
  52. data/spec/filters/bugs/language.rb +0 -3
  53. data/spec/filters/bugs/marshal.rb +0 -1
  54. data/spec/filters/bugs/string.rb +0 -30
  55. data/spec/filters/bugs/time.rb +18 -8
  56. data/spec/lib/cli_spec.rb +2 -2
  57. data/spec/lib/compiler_spec.rb +8 -8
  58. data/spec/lib/rewriters/base_spec.rb +1 -1
  59. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +34 -59
  60. data/spec/lib/rewriters/block_to_iter_spec.rb +3 -6
  61. data/spec/lib/rewriters/dot_js_syntax_spec.rb +2 -5
  62. data/spec/lib/rewriters/for_rewriter_spec.rb +0 -1
  63. data/spec/lib/rewriters/forward_args_spec.rb +2 -3
  64. data/spec/lib/rewriters/js_reserved_words_spec.rb +2 -15
  65. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +64 -89
  66. data/spec/lib/rewriters/numblocks_spec.rb +3 -5
  67. data/spec/lib/rewriters/opal_engine_check_spec.rb +2 -14
  68. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +10 -2
  69. data/spec/opal/compiler/irb_spec.rb +4 -0
  70. data/spec/opal/core/language/super_spec.rb +40 -17
  71. data/spec/opal/core/language/xstring_spec.rb +13 -0
  72. data/spec/opal/core/regexp/assertions_spec.rb +19 -0
  73. data/spec/opal/core/string/to_proc_spec.rb +19 -0
  74. data/spec/ruby_specs +4 -0
  75. data/spec/support/rewriters_helper.rb +43 -23
  76. data/stdlib/date/date_time.rb +71 -0
  77. data/stdlib/date/formatters.rb +28 -0
  78. data/stdlib/date/infinity.rb +73 -0
  79. data/stdlib/date.rb +77 -214
  80. data/stdlib/opal/repl_js.rb +1 -1
  81. data/stdlib/{opal/replutils.rb → opal-replutils.rb} +3 -3
  82. data/stdlib/promise/v2.rb +0 -7
  83. data/stdlib/time.rb +39 -2
  84. data/stdlib/uri.rb +53 -0
  85. data/tasks/performance/asciidoctor_test.rb.erb +3 -1
  86. data/tasks/performance/optimization_status.rb +3 -2
  87. data/tasks/performance.rake +69 -35
  88. data/tasks/testing.rake +1 -0
  89. data/test/opal/test_uri.rb +35 -0
  90. data/yarn.lock +27 -5
  91. metadata +30 -16
  92. data/lib/opal/nodes/csend.rb +0 -24
  93. data/lib/opal/rewriters/explicit_writer_return.rb +0 -59
  94. data/spec/lib/rewriters/explicit_writer_return_spec.rb +0 -186
  95. data/stdlib/nodejs/irb.rb +0 -43
@@ -25,7 +25,6 @@ opal_filter "Time" do
25
25
  fails "Time#getlocal with a timezone argument subject's class implements .find_timezone method does not call .find_timezone if passed any not string/numeric/timezone timezone argument" # Expected TypeError (/can't convert \w+ into an exact number/) but got: NoMethodError (undefined method `getlocal' for 2000-01-01 12:00:00 UTC)
26
26
  fails "Time#gmtime converts self to UTC, modifying the receiver" # Expected 2007-01-09 03:00:00 UTC to equal 2007-01-09 12:00:00 UTC
27
27
  fails "Time#hash returns an Integer" # Expected "Time:100000" (String) to be an instance of Integer
28
- fails "Time#inspect formats the fixed offset time following the pattern 'yyyy-MM-dd HH:mm:ss +/-HHMM'"
29
28
  fails "Time#inspect omits trailing zeros from microseconds" # Expected "2007-11-01 15:25:00 UTC" == "2007-11-01 15:25:00.1 UTC" to be truthy but was false
30
29
  fails "Time#inspect preserves microseconds" # Expected "2007-11-01 15:25:00 UTC" == "2007-11-01 15:25:00.123456 UTC" to be truthy but was false
31
30
  fails "Time#inspect preserves nanoseconds" # Expected "2007-11-01 15:25:00 UTC" == "2007-11-01 15:25:00.123456789 UTC" to be truthy but was false
@@ -44,7 +43,6 @@ opal_filter "Time" do
44
43
  fails "Time#strftime should be able to show default Logger format" # Expected "2001-12-03T04:05:06.000000 " == "2001-12-03T04:05:06.100000 " to be truthy but was false
45
44
  fails "Time#strftime should be able to show the commercial week day"
46
45
  fails "Time#strftime should be able to show the number of seconds since the unix epoch" # fails under FIJI et al TZs
47
- fails "Time#strftime should be able to show the timezone if available"
48
46
  fails "Time#strftime should be able to show the timezone of the date with a : separator"
49
47
  fails "Time#strftime should be able to show the week number with the week starting on Sunday (%U) and Monday (%W)"
50
48
  fails "Time#strftime with %N formats the microseconds of the second with %6N"
@@ -53,9 +51,13 @@ opal_filter "Time" do
53
51
  fails "Time#strftime with %N formats the nanoseconds of the second with %N"
54
52
  fails "Time#strftime with %N formats the picoseconds of the second with %12N"
55
53
  fails "Time#subsec returns 0 as an Integer for a Time with a whole number of seconds" # NoMethodError: undefined method `subsec' for 1970-01-01 01:01:40 +0100
54
+ fails "Time#to_date yields accurate julian date for Julian-Gregorian gap value" # Expected 2299170 == 2299160 to be truthy but was false
55
+ fails "Time#to_date yields accurate julian date for ambiguous pre-Gregorian reform value" # Expected 2299160 == 2299150 to be truthy but was false
56
+ fails "Time#to_date yields accurate julian date for post-Gregorian reform value" # Expected 2299171 == 2299161 to be truthy but was false
57
+ fails "Time#to_date yields same julian day regardless of UTC time value" # Expected 2299171 == 2299161 to be truthy but was false
58
+ fails "Time#to_date yields same julian day regardless of local time or zone" # Expected 2299171 == 2299161 to be truthy but was false
56
59
  fails "Time#to_f returns the float number of seconds + usecs since the epoch"
57
60
  fails "Time#to_i rounds fractional seconds toward zero" # Expected -315619200 == -315619199 to be truthy but was false
58
- fails "Time#to_s formats the fixed offset time following the pattern 'yyyy-MM-dd HH:mm:ss +/-HHMM'"
59
61
  fails "Time#tv_sec rounds fractional seconds toward zero" # Expected -315619200 == -315619199 to be truthy but was false
60
62
  fails "Time#usec returns a positive value for dates before the epoch" # Expected 0 to equal 404240
61
63
  fails "Time#utc converts self to UTC, modifying the receiver" # Expected 2007-01-09 03:00:00 UTC to equal 2007-01-09 12:00:00 UTC
@@ -77,6 +79,7 @@ opal_filter "Time" do
77
79
  fails "Time.at passed non-Time, non-Numeric with an argument that responds to #to_r needs for the argument to respond to #to_int too" # Mock 'rational-but-no-to_int' expected to receive to_r("any_args") exactly 1 times but received it 0 times
78
80
  fails "Time.gm handles fractional usec close to rounding limit" # NoMethodError: undefined method `nsec' for 2000-01-01 12:30:00 UTC:Time
79
81
  fails "Time.gm raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 UTC was returned)
82
+ fails "Time.httpdate parses RFC-2616 strings" # NoMethodError: undefined method `httpdate' for Time
80
83
  fails "Time.local raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 +0200 was returned)
81
84
  fails "Time.mktime raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 +0200 was returned)
82
85
  fails "Time.new has at least microsecond precision" # NoMethodError: undefined method `nsec' for 2019-05-16 23:25:01 +0200
@@ -85,12 +88,12 @@ opal_filter "Time" do
85
88
  fails "Time.new with a timezone argument #name method uses the optional #name method for marshaling" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
86
89
  fails "Time.new with a timezone argument Time-like argument of #utc_to_local and #local_to_utc methods has attribute values the same as a Time object in UTC" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
87
90
  fails "Time.new with a timezone argument Time-like argument of #utc_to_local and #local_to_utc methods implements subset of Time methods" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
88
- fails "Time.new with a timezone argument accepts timezone argument that must have #local_to_utc and #utc_to_local methods" # Expected to not get Exception but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
89
- fails "Time.new with a timezone argument does not raise exception if timezone does not implement #utc_to_local method" # Expected to not get Exception but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
91
+ fails "Time.new with a timezone argument accepts timezone argument that must have #local_to_utc and #utc_to_local methods" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
92
+ fails "Time.new with a timezone argument does not raise exception if timezone does not implement #utc_to_local method" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
90
93
  fails "Time.new with a timezone argument raises TypeError if timezone does not implement #local_to_utc method" # Expected TypeError (/can't convert \w+ into an exact number/) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
91
- fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time instance" # Expected to not get Exception but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
92
- fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time subclass instance" # Expected to not get Exception but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
93
- fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be any object with #to_i method" # Expected to not get Exception but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
94
+ fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time instance" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
95
+ fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be Time subclass instance" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
96
+ fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could be any object with #to_i method" # Expected to not get Exception but got: ArgumentError (Opal doesn't support other types for a timezone argument than Integer and String)
94
97
  fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods could have any #zone and #utc_offset because they are ignored" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
95
98
  fails "Time.new with a timezone argument returned value by #utc_to_local and #local_to_utc methods leads to raising Argument error if difference between argument and result is too large" # Expected ArgumentError (utc_offset out of range) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
96
99
  fails "Time.new with a timezone argument returns a Time in the timezone" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
@@ -98,10 +101,17 @@ opal_filter "Time" do
98
101
  fails "Time.new with a timezone argument subject's class implements .find_timezone method calls .find_timezone to build a time object if passed zone name as a timezone argument" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
99
102
  fails "Time.new with a timezone argument subject's class implements .find_timezone method does not call .find_timezone if passed any not string/numeric/timezone timezone argument" # Expected TypeError (/can't convert \w+ into an exact number/) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
100
103
  fails "Time.new with a timezone argument the #abbr method is used by '%Z' in #strftime" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
104
+ fails "Time.new with a utc_offset argument raises ArgumentError if the String argument is not in an ASCII-compatible encoding" # Expected ArgumentError but no exception was raised (1999-12-31 18:50:00 -0410.000000000000028 was returned)
101
105
  fails "Time.new with a utc_offset argument raises ArgumentError if the month is greater than 12" # Expected ArgumentError (/(mon|argument) out of range/) but got: ArgumentError (Opal does not support explicitly specifying UTC offset for Time)
106
+ fails "Time.new with a utc_offset argument raises ArgumentError if the utc_offset argument is greater than or equal to 10e9" # Expected ArgumentError but no exception was raised (2031-09-09 00:46:40 +27777746.66666666418314 was returned)
102
107
  fails "Time.new with a utc_offset argument returns a Time with a UTC offset specified as +HH:MM:SS" # ArgumentError: Opal does not support explicitly specifying UTC offset for Time
103
108
  fails "Time.now has at least microsecond precision" # NoMethodError: undefined method `nsec' for 2019-05-16 23:25:03 +0200
104
109
  fails "Time.now uses the local timezone" # Expected 10800 to equal -28800
110
+ fails "Time.rfc2822 parses RFC-2822 strings" # NoMethodError: undefined method `rfc2822' for Time
111
+ fails "Time.rfc2822 parses RFC-822 strings" # NoMethodError: undefined method `rfc2822' for Time
112
+ fails "Time.rfc822 parses RFC-2822 strings" # NoMethodError: undefined method `rfc2822' for Time
113
+ fails "Time.rfc822 parses RFC-822 strings" # NoMethodError: undefined method `rfc2822' for Time
105
114
  fails "Time.utc handles fractional usec close to rounding limit" # NoMethodError: undefined method `nsec' for 2000-01-01 12:30:00 UTC:Time
106
115
  fails "Time.utc raises an ArgumentError for out of range microsecond" # Expected ArgumentError but no exception was raised (2000-01-01 20:15:01 UTC was returned)
116
+ fails "Time.xmlschema parses ISO-8601 strings" # NoMethodError: undefined method `xmlschema' for Time
107
117
  end
data/spec/lib/cli_spec.rb CHANGED
@@ -84,7 +84,7 @@ RSpec.describe Opal::CLI do
84
84
  context 'when false' do
85
85
  let(:options) { {lib_only: false, runner: :compiler, evals: [''], skip_opal_require: true, no_exit: true} }
86
86
  it 'appends an empty code block at the end of the source' do
87
- expect_output_of{ subject.run }.to include("function(Opal)")
87
+ expect_output_of{ subject.run }.to include("Opal.nil")
88
88
  end
89
89
  end
90
90
 
@@ -207,7 +207,7 @@ RSpec.describe Opal::CLI do
207
207
  describe ':sexp option' do
208
208
  let(:options) { {evals: ['puts 4'], sexp: true} }
209
209
  it 'prints syntax expressions for the given code' do
210
- expect_output_of{ subject.run }.to eq("s(:send, nil, :puts,\n s(:int, 4))\n")
210
+ expect_output_of{ subject.run }.to eq("s(:top,\n s(:send, nil, :puts,\n s(:int, 4)))\n")
211
211
  end
212
212
  end
213
213
 
@@ -17,15 +17,15 @@ RSpec.describe Opal::Compiler do
17
17
 
18
18
  describe 'requirable' do
19
19
  it 'executes the file' do
20
- expect_compiled("").to include('(function(Opal) {')
21
- expect_compiled("").to start_with('Opal.queue(function(Opal) {')
22
- expect_compiled("").to end_with("});\n")
20
+ expect_compiled("true").to include('(function(Opal) {')
21
+ expect_compiled("true").to start_with('Opal.queue(function(Opal) {')
22
+ expect_compiled("true").to end_with("});\n")
23
23
  end
24
24
 
25
25
  it 'puts the compiled into "Opal.modules"' do
26
26
  options = { :requirable => true, :file => "pippo" }
27
- expect_compiled("", options).to include('Opal.modules["pippo"] = function(Opal) {')
28
- expect_compiled("", options).to end_with("};\n")
27
+ expect_compiled("true", options).to include('Opal.modules["pippo"] = function(Opal) {')
28
+ expect_compiled("true", options).to end_with("};\n")
29
29
  end
30
30
  end
31
31
 
@@ -89,18 +89,18 @@ RSpec.describe Opal::Compiler do
89
89
 
90
90
  describe "method names" do
91
91
  it "generates a named function for method" do
92
- expect_compiled("def test_method; end").to include("function $$test_method()")
92
+ expect_compiled("def test_method; []; end").to include("function $$test_method()")
93
93
  end
94
94
 
95
95
  context "when function name is reserved" do
96
96
  it "generates a valid named function for method" do
97
- expect_compiled("def Array; end").to include("function $$Array()")
97
+ expect_compiled("def Array; []; end").to include("function $$Array()")
98
98
  end
99
99
  end
100
100
 
101
101
  context "when function name is not valid" do
102
102
  it "generates a name in a safe way" do
103
- expect_compiled("def test_method?; end").to include("function $test_method$ques$1()")
103
+ expect_compiled("def test_method?; []; end").to include("function $test_method$ques$1()")
104
104
  end
105
105
  end
106
106
  end
@@ -6,7 +6,7 @@ RSpec.describe Opal::Rewriters::Base do
6
6
  include RewritersHelper
7
7
 
8
8
  def body_ast_of(method_source)
9
- def_ast = parse_without_rewriting(method_source)
9
+ def_ast = parse_without_rewriting(method_source).children.first
10
10
  _, _, body_ast = *def_ast
11
11
  body_ast
12
12
  end
@@ -1,71 +1,46 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::BinaryOperatorAssignment.new }
5
+ include RewritersHelper
9
6
 
10
- def parse(source)
11
- parser = Opal::Parser.default_parser
12
- buffer = ::Opal::Parser::SourceBuffer.new('(eval)')
13
- buffer.source = source
14
- parser.parse(buffer)
15
- end
16
-
17
- def rewrite(ast)
18
- rewriter.process(ast)
19
- end
7
+ use_only_described_rewriter!
20
8
 
21
- around(:each) do |e|
22
- Opal::Rewriters::BinaryOperatorAssignment.reset_tmp_counter!
23
- Opal::Rewriter.disable { e.run }
24
- end
9
+ before(:each) { Opal::Rewriters::BinaryOperatorAssignment.reset_tmp_counter! }
25
10
  let(:cache_tmp_name) { :$binary_op_recvr_tmp_1 }
26
11
  let(:cached) { s(:js_tmp, cache_tmp_name) }
27
12
 
28
- shared_examples 'it rewrites' do |from, to|
29
- it "rewrites #{from.inspect} to #{to.inspect}" do
30
- input = parse(from)
31
- rewritten = rewrite(input)
32
- expected = parse(to)
33
-
34
- expect(rewritten).to eq(expected)
35
- end
36
- end
37
-
38
13
  context 'rewriting or_asgn and and_asgn nodes' do
39
14
  context 'local variable' do
40
- include_examples 'it rewrites', 'a = 1; a += 2', 'a = 1; a = a + 2'
15
+ include_examples 'it rewrites source-to-source', 'a = 1; a += 2', 'a = 1; a = a + 2'
41
16
  end
42
17
 
43
18
  context 'instance variable' do
44
- include_examples 'it rewrites', '@a += 1', '@a = @a + 1'
19
+ include_examples 'it rewrites source-to-source', '@a += 1', '@a = @a + 1'
45
20
  end
46
21
 
47
22
  context 'constant' do
48
- include_examples 'it rewrites', 'CONST += 1', 'CONST = CONST + 1'
23
+ include_examples 'it rewrites source-to-source', 'CONST += 1', 'CONST = CONST + 1'
49
24
  end
50
25
 
51
26
  context 'global variable' do
52
- include_examples 'it rewrites', '$g += 1', '$g = $g + 1'
27
+ include_examples 'it rewrites source-to-source', '$g += 1', '$g = $g + 1'
53
28
  end
54
29
 
55
30
  context 'class variable' do
56
- include_examples 'it rewrites', '@@a += 1', '@@a = @@a + 1'
31
+ include_examples 'it rewrites source-to-source', '@@a += 1', '@@a = @@a + 1'
57
32
  end
58
33
 
59
34
  context 'simple method call' do
60
- include_examples 'it rewrites', 'recvr = 1; recvr.meth += rhs', 'recvr = 1; recvr.meth = recvr.meth + rhs'
35
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr.meth += rhs', 'recvr = 1; recvr.meth = recvr.meth + rhs'
61
36
  end
62
37
 
63
38
  context '[] / []= method call' do
64
- include_examples 'it rewrites', 'recvr = 1; recvr[idx] += rhs', 'recvr = 1; recvr[idx] = recvr[idx] + rhs'
39
+ include_examples 'it rewrites source-to-source', 'recvr = 1; recvr[idx] += rhs', 'recvr = 1; recvr[idx] = recvr[idx] + rhs'
65
40
  end
66
41
 
67
42
  context '[] / []= method call with multiple arguments' do
68
- include_examples 'it rewrites',
43
+ include_examples 'it rewrites source-to-source',
69
44
  'recvr = 1; recvr[idx1, idx2] += rhs',
70
45
  'recvr = 1; recvr[idx1, idx2] = recvr[idx1, idx2] + rhs'
71
46
  end
@@ -73,15 +48,15 @@ RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
73
48
  context 'chain of method calls' do
74
49
  it 'rewrites += by caching receiver to a temporary local variable' do
75
50
  input = parse('recvr.a.b += rhs')
76
- rewritten = rewrite(input)
51
+ rewritten = rewrite(input).children.first
77
52
 
78
53
  expected = s(:begin,
79
- s(:lvasgn, cache_tmp_name, parse('recvr.a')), # cached = recvr.a
54
+ s(:lvasgn, cache_tmp_name, ast_of('recvr.a')), # cached = recvr.a
80
55
  s(:send, cached, :b=,
81
56
  s(:send,
82
57
  s(:send, cached, :b),
83
58
  :+,
84
- parse('rhs'))))
59
+ ast_of('rhs'))))
85
60
 
86
61
  expect(rewritten).to eq(expected)
87
62
  end
@@ -90,19 +65,19 @@ RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
90
65
  context 'method call using safe nafigator' do
91
66
  it 'rewrites += by caching receiver and rewriting it to if and or_asgn' do
92
67
  input = parse('recvr&.meth += rhs')
93
- rewritten = rewrite(input)
68
+ rewritten = rewrite(input).children.first
94
69
 
95
70
  expected = s(:begin,
96
- s(:lvasgn, cache_tmp_name, parse('recvr')), # cached = recvr
97
- s(:if, s(:send, cached, :nil?), # if cached.nil?
98
- s(:nil), # nil
99
- # else
100
- s(:send, cached, :meth=, # cached.meth =
71
+ s(:lvasgn, cache_tmp_name, ast_of('recvr')), # cached = recvr
72
+ s(:if, s(:send, cached, :nil?), # if cached.nil?
73
+ s(:nil), # nil
74
+ # else
75
+ s(:send, cached, :meth=, # cached.meth =
101
76
  s(:send,
102
- s(:send, cached, :meth), # cached.meth +
77
+ s(:send, cached, :meth), # cached.meth +
103
78
  :+,
104
- parse('rhs'))) # rhs
105
- )) # end
79
+ ast_of('rhs'))) # rhs
80
+ )) # end
106
81
 
107
82
  expect(rewritten).to eq(expected)
108
83
  end
@@ -111,43 +86,43 @@ RSpec.describe Opal::Rewriters::BinaryOperatorAssignment do
111
86
 
112
87
  context 'rewriting defined?(or_asgn) and defined?(and_asgn)' do
113
88
  context 'local variable' do
114
- include_examples 'it rewrites', 'a = nil; defined?(a += 1)', 'a = nil; "assignment"'
89
+ include_examples 'it rewrites source-to-source', 'a = nil; defined?(a += 1)', 'a = nil; "assignment"'
115
90
  end
116
91
 
117
92
  context 'instance variable' do
118
- include_examples 'it rewrites', 'defined?(@a += 1)', %q("assignment")
93
+ include_examples 'it rewrites source-to-source', 'defined?(@a += 1)', %q("assignment")
119
94
  end
120
95
 
121
96
  context 'constant' do
122
- include_examples 'it rewrites', 'defined?(CONST += 1)', %q("assignment")
97
+ include_examples 'it rewrites source-to-source', 'defined?(CONST += 1)', %q("assignment")
123
98
  end
124
99
 
125
100
  context 'global variable' do
126
- include_examples 'it rewrites', 'defined?($g += 1)', %q("assignment")
101
+ include_examples 'it rewrites source-to-source', 'defined?($g += 1)', %q("assignment")
127
102
  end
128
103
 
129
104
  context 'class variable' do
130
- include_examples 'it rewrites', 'defined?(@@a += 1)', %q("assignment")
105
+ include_examples 'it rewrites source-to-source', 'defined?(@@a += 1)', %q("assignment")
131
106
  end
132
107
 
133
108
  context 'simple method call' do
134
- include_examples 'it rewrites', 'defined?(recvr.meth += rhs)', %q("assignment")
109
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.meth += rhs)', %q("assignment")
135
110
  end
136
111
 
137
112
  context '[] / []= method call' do
138
- include_examples 'it rewrites', 'defined?(recvr[idx] += rhs)', %q("assignment")
113
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx] += rhs)', %q("assignment")
139
114
  end
140
115
 
141
116
  context '[] / []= method call with multiple arguments' do
142
- include_examples 'it rewrites', 'defined?(recvr[idx1, idx2] += rhs)', %q("assignment")
117
+ include_examples 'it rewrites source-to-source', 'defined?(recvr[idx1, idx2] += rhs)', %q("assignment")
143
118
  end
144
119
 
145
120
  context 'chain of method calls' do
146
- include_examples 'it rewrites', 'defined?(recvr.a.b.c += rhs)', %q("assignment")
121
+ include_examples 'it rewrites source-to-source', 'defined?(recvr.a.b.c += rhs)', %q("assignment")
147
122
  end
148
123
 
149
124
  context 'method call using safe nafigator' do
150
- include_examples 'it rewrites', 'defined?(recvr&.meth += rhs)', %q("assignment")
125
+ include_examples 'it rewrites source-to-source', 'defined?(recvr&.meth += rhs)', %q("assignment")
151
126
  end
152
127
  end
153
128
  end
@@ -1,11 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::BlockToIter do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::BlockToIter.new }
5
+ include RewritersHelper
9
6
 
10
7
  let(:block_node) do
11
8
  # m { |arg1| 1 }
@@ -23,6 +20,6 @@ RSpec.describe Opal::Rewriters::BlockToIter do
23
20
  end
24
21
 
25
22
  it 'rewriters s(:block) to s(:iter)' do
26
- expect(rewriter.process(block_node)).to eq(iter_node)
23
+ expect(rewritten(block_node)).to eq(iter_node)
27
24
  end
28
25
  end
@@ -1,11 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::DotJsSyntax do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- let(:rewriter) { Opal::Rewriters::DotJsSyntax.new }
5
+ include RewritersHelper
9
6
 
10
7
  context '.JS. syntax' do
11
8
  let(:send_node) do
@@ -4,7 +4,6 @@ require 'opal/rewriters/for_rewriter'
4
4
 
5
5
  RSpec.describe Opal::Rewriters::ForRewriter do
6
6
  include RewritersHelper
7
- extend RewritersHelper
8
7
 
9
8
  before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
10
9
 
@@ -4,7 +4,6 @@ require 'opal/rewriters/forward_args'
4
4
 
5
5
  RSpec.describe Opal::Rewriters::ForwardArgs do
6
6
  include RewritersHelper
7
- extend RewritersHelper
8
7
 
9
8
  before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
10
9
 
@@ -23,7 +22,7 @@ RSpec.describe Opal::Rewriters::ForwardArgs do
23
22
  end
24
23
  end
25
24
 
26
- include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
25
+ include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(ast_of(<<~ENDDEST))
27
26
  def forward(...)
28
27
  other(...)
29
28
  end
@@ -33,7 +32,7 @@ RSpec.describe Opal::Rewriters::ForwardArgs do
33
32
  end
34
33
  ENDDEST
35
34
 
36
- include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
35
+ include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(ast_of(<<~ENDDEST))
37
36
  def forward(first_arg, ...)
38
37
  other(first_arg, second_arg, ...)
39
38
  other(other_arg, ...)
@@ -1,21 +1,8 @@
1
1
  require 'lib/spec_helper'
2
+ require 'support/rewriters_helper'
2
3
 
3
4
  RSpec.describe Opal::Rewriters::JsReservedWords do
4
- def s(type, *children)
5
- ::Opal::AST::Node.new(type, children)
6
- end
7
-
8
- def rewrite(sexp)
9
- Opal::Rewriters::JsReservedWords.new.process(sexp)
10
- end
11
-
12
- def expect_rewritten(sexp)
13
- expect(rewrite(sexp))
14
- end
15
-
16
- def expect_no_rewriting_for(sexp)
17
- expect_rewritten(sexp).to eq(sexp)
18
- end
5
+ include RewritersHelper
19
6
 
20
7
  reserved_lvars = %i(
21
8
  do if in for let new try var case else enum eval false