opal 1.8.2 → 1.8.3.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +30 -41
  3. data/.rubocop.yml +3 -1
  4. data/Gemfile +1 -0
  5. data/UNRELEASED.md +13 -3
  6. data/docs/compiled_ruby.md +14 -14
  7. data/docs/releasing.md +4 -2
  8. data/exe/opal-build +1 -1
  9. data/lib/opal/compiler.rb +1 -1
  10. data/lib/opal/nodes/call_special.rb +1 -1
  11. data/lib/opal/nodes/literal.rb +1 -1
  12. data/lib/opal/nodes/rescue.rb +1 -1
  13. data/lib/opal/nodes/scope.rb +1 -1
  14. data/lib/opal/version.rb +1 -1
  15. data/opal/corelib/array.rb +1 -1
  16. data/opal/corelib/basic_object.rb +1 -1
  17. data/opal/corelib/constants.rb +3 -3
  18. data/opal/corelib/error.rb +16 -1
  19. data/opal/corelib/hash.rb +1 -1
  20. data/opal/corelib/io.rb +1 -1
  21. data/opal/corelib/module.rb +1 -1
  22. data/opal/corelib/object_space.rb +1 -1
  23. data/opal/corelib/runtime.js +1 -1
  24. data/opal/corelib/string/encoding.rb +6 -6
  25. data/opal.gemspec +2 -1
  26. data/spec/lib/compiler_spec.rb +16 -6
  27. data/spec/lib/fixtures/build_order/file5.rb.erb +1 -1
  28. data/spec/lib/rewriters/hashes/key_duplicates_rewriter_spec.rb +1 -1
  29. data/spec/lib/spec_helper.rb +11 -0
  30. data/spec/opal/core/array/include_spec.rb +12 -0
  31. data/spec/opal/core/runtime/rescue_spec.rb +5 -5
  32. data/spec/opal/stdlib/opal_raw_spec.rb +74 -0
  33. data/spec/support/source_map_helper.rb +1 -3
  34. data/stdlib/bigdecimal.rb +14 -14
  35. data/stdlib/date/date_time.rb +1 -1
  36. data/stdlib/deno/file.rb +1 -1
  37. data/stdlib/js.rb +7 -66
  38. data/stdlib/nodejs/file.rb +7 -7
  39. data/stdlib/opal/raw.rb +73 -0
  40. data/stdlib/optparse.rb +6 -6
  41. data/stdlib/shellwords.rb +1 -1
  42. data/tasks/testing.rake +13 -2
  43. metadata +27 -10
  44. data/spec/opal/stdlib/js_spec.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8f2fff5a3c3229c43f5390af4758bb523362ea6ee1a1df8d2d90c53d502b575
4
- data.tar.gz: 70966774cb6f97e29ed4b8516831ea94492c6f1cb83d42493a3ed88d146956a9
3
+ metadata.gz: 0b7bdbaa11982b36e41c9595ac6cba3ced898573fa40bee52b0d599aee66c0d9
4
+ data.tar.gz: 23b40fdd12f4b82aafb53ffcc376aff8ee7635e74f37fe7b711d99dbc2c315ac
5
5
  SHA512:
6
- metadata.gz: 693fe7106ef50e1bda17b92c8d548e5cd8419cfce0a4b5f2bde7accc87c905b0e407c5dd9ade1ff47249d0ffa2b8ca3d7fcbe2a12b5d1a2e45453a8a3400c72f
7
- data.tar.gz: 22958073241a8d912931f9f3ce5c2d05674d82e74a2952f60f28664474ddc58fdf4639778ff3ac9cc67e9040ed8496aac91ab49c7de3d44a26f9687a33c96ba5
6
+ metadata.gz: 419a5ea103d370ec908f98bd2e4e24d79401d8704b781eea52b359041b12b6a012eb048caa01bd2ccedd34746e22b0b6a2fbce51802bc040157855a393b58244
7
+ data.tar.gz: 2ba934b813ebb3fb51291273cb4653f80652a1a2a02555b7fd97d8d4c1813fe13938c85495b18b426e59a384dc0cdf706b1e4df63a117163d8327418ac83ec2d
@@ -14,82 +14,64 @@ permissions:
14
14
  jobs:
15
15
  rake:
16
16
  name: ${{ matrix.combo.name || matrix.combo.ruby }}
17
+ env:
18
+ DEFAULT_RUBY: '3.3'
17
19
  strategy:
18
20
  fail-fast: false
19
21
  matrix:
20
22
  combo:
21
23
  - name: mspec-nodejs
22
- ruby: '3.0'
23
24
  command: bin/rake mspec_nodejs
24
25
  - name: mspec-chrome
25
- ruby: '3.0'
26
26
  command: bin/rake mspec_chrome
27
27
  - name: mspec-firefox
28
- env:
29
- # when changing version, also change it below
30
- MOZILLA_FIREFOX_BINARY: '/opt/hostedtoolcache/firefox/106.0.4/x64/firefox'
31
- ruby: '3.0'
28
+ firefox: '106.0.4'
32
29
  command: xvfb-run bin/rake mspec_firefox
33
30
  - name: minitest
34
- ruby: '3.0'
35
31
  command: bin/rake minitest
36
32
  - name: minitest-strict-mode
37
- ruby: '3.0'
38
33
  command: bin/rake minitest
39
34
  strict: 'true'
40
- - name: head-ruby
41
- ruby: head
42
- permissive: true
35
+ # - name: head-ruby
36
+ # ruby: head
37
+ # permissive: true
43
38
  - name: current-ruby
44
- ruby: 3.1
39
+ ruby: '3.3'
45
40
  - name: previous-ruby
46
- ruby: '3.0'
41
+ ruby: '3.2'
47
42
  - name: older-ruby
48
- ruby: 2.7
43
+ ruby: '3.1'
49
44
  - name: near-eol-ruby
50
- ruby: 2.6
51
- - name: smoke-test
52
45
  ruby: '3.0'
46
+ - name: smoke-test
53
47
  command: bin/rake smoke_test
54
48
  - name: windows-mspec-nodejs
55
49
  command: bundle exec rake mspec_nodejs
56
- ruby: '3.0'
57
50
  os: windows-latest
58
51
  - name: windows-mspec-chrome
59
52
  command: bundle exec rake mspec_chrome
60
- ruby: '3.0'
61
53
  os: windows-latest
62
54
  # - name: windows-mspec-firefox
63
- # env:
64
- # # when changing version, also change it below and above
65
- # MOZILLA_FIREFOX_BINARY: 'C:/Program Files/Firefox_106.0.4/firefox.exe'
66
- # ruby: '3.0'
55
+ # firefox: '106.0.4'
67
56
  # command: bundle exec rake mspec_firefox
68
57
  # os: windows-latest
69
58
  - name: macos-mspec-safari
70
59
  command: bundle exec rake mspec_safari
71
- ruby: '3.0'
72
60
  os: 'macos-latest'
73
61
  - name: windows-minitest
74
62
  command: bundle exec rake minitest
75
- ruby: '3.0'
76
63
  os: windows-latest
77
64
  - name: windows
78
65
  command: bundle exec rake rspec
79
- ruby: '3.0'
80
66
  os: windows-latest
81
67
  - name: macos
82
68
  command: bundle exec rake rspec
83
- ruby: '3.0'
84
69
  os: 'macos-latest'
85
70
  - name: lint
86
71
  command: bin/rake lint
87
- ruby: '3.0'
88
72
  - name: timezone
89
73
  command: bin/rake mspec_nodejs TZ="Pacific/Fiji"
90
- ruby: '3.0'
91
74
  - name: performance
92
- ruby: '3.0'
93
75
  permissive: true
94
76
  fetchdepth: '0'
95
77
  command: bin/rake performance:compare
@@ -102,29 +84,32 @@ jobs:
102
84
  runs-on: ${{ matrix.combo.os || 'ubuntu-latest' }}
103
85
  continue-on-error: ${{ matrix.combo.permissive || false }}
104
86
  steps:
105
- - uses: browser-actions/setup-firefox@latest
87
+ - if: ${{ matrix.combo.firefox }}
88
+ id: setup-firefox
89
+ uses: browser-actions/setup-firefox@latest
106
90
  with:
107
- # when changing version, also change it above
108
- firefox-version: '106.0.4'
109
- - uses: actions/checkout@v2
91
+ firefox-version: ${{ matrix.combo.firefox }}
92
+ - uses: actions/checkout@v4
110
93
  with:
111
94
  fetch-depth: ${{ fromJSON(matrix.combo.fetchdepth || '1') }}
112
95
  - if: ${{ matrix.combo.os != 'ryzen' }}
113
96
  uses: ruby/setup-ruby@v1
114
97
  with:
115
- ruby-version: ${{ matrix.combo.ruby }}
98
+ ruby-version: ${{ matrix.combo.ruby || env.DEFAULT_RUBY }}
116
99
  bundler-cache: false
117
100
  - run: ruby bin/git-submodule-fast-install
118
101
  - run: bundle lock
119
- - uses: actions/cache@v2
102
+ - uses: actions/cache@v4
103
+ env:
104
+ KEY_PREFIX: ${{ runner.os }}-${{ matrix.combo.ruby || env.DEFAULT_RUBY }}
120
105
  with:
121
106
  path: ./vendor/bundle
122
- key: ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-${{ github.ref }}-${{ hashFiles('**/Gemfile.lock') }}
107
+ key: ${{ env.KEY_PREFIX }}-gem-${{ github.ref }}-${{ hashFiles('**/Gemfile.lock') }}
123
108
  restore-keys: |
124
- ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-${{ github.ref }}
125
- ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-master
126
- ${{ runner.os }}-${{ matrix.combo.ruby }}-gem-
127
- - uses: actions/cache@v2
109
+ ${{ env.KEY_PREFIX }}-gem-${{ github.ref }}
110
+ ${{ env.KEY_PREFIX }}-gem-master
111
+ ${{ env.KEY_PREFIX }}-gem-
112
+ - uses: actions/cache@v4
128
113
  with:
129
114
  path: ./node_modules
130
115
  key: ${{ runner.os }}-npm-${{ github.ref }}-${{ hashFiles('**/yarn.lock') }}
@@ -138,8 +123,12 @@ jobs:
138
123
  bundle config path $PWD/vendor/bundle
139
124
  bundle install --jobs 4 --retry 3
140
125
  bundle clean
141
- - name: set environment variables
126
+ - name: set environment variables USE_STRICT
142
127
  if: ${{ matrix.combo.strict == 'true' }}
143
128
  run: |
144
129
  echo "USE_STRICT=true" >> $GITHUB_ENV
130
+ - name: set environment variables MOZILLA_FIREFOX_BINARY
131
+ if: ${{ matrix.combo.firefox }}
132
+ run: |
133
+ echo "MOZILLA_FIREFOX_BINARY=${{ steps.setup-firefox.outputs.firefox-path }}" >> $GITHUB_ENV
145
134
  - run: ${{ matrix.combo.command || 'bin/rake rspec' }}
data/.rubocop.yml CHANGED
@@ -214,7 +214,9 @@ Naming/BinaryOperatorParameterName:
214
214
 
215
215
  Naming/PredicateName:
216
216
  # Ruby has "has_key?" method
217
- ForbiddenPrefixes: is_, have_
217
+ ForbiddenPrefixes:
218
+ - is_
219
+ - have_
218
220
 
219
221
  Performance/FlatMap:
220
222
  Exclude:
data/Gemfile CHANGED
@@ -40,6 +40,7 @@ group :development do
40
40
  gem 'rb-fsevent'
41
41
  gem 'guard', require: false
42
42
  gem 'listen', require: false
43
+ gem 'simplecov', require: false
43
44
 
44
45
  if RUBY_PLATFORM =~ /darwin/
45
46
  gem 'terminal-notifier-guard'
data/UNRELEASED.md CHANGED
@@ -1,10 +1,20 @@
1
1
  <!--
2
- ### Internal
3
- ### Changed
4
2
  ### Added
5
3
  ### Removed
6
4
  ### Deprecated
7
5
  ### Performance
8
- ### Fixed
9
6
  -->
10
7
 
8
+ ### Changed
9
+ - Use of `JS` constant is now deprecated. The constant has been renamed to `Opal::Raw`. Throw a warning if such a constant is in use (#2525)
10
+
11
+ ### Fixed
12
+ - `String#chars`: Fix iteration over out-of-BMP characters (#2620)
13
+ - Fix `Array#include?` to respect nil return value (#2661)
14
+ - Fix `opal-build` command line utility for newer Ruby versions (#2675)
15
+ - Depend on `base64` gem for Ruby 3.4 compatibility (#2652)
16
+
17
+ ### Internal
18
+ - Ensure we default to later Ruby versions in CI (#2624)
19
+ - Unassorted CI/Rubocop/testing system changes (#2676, #2654, #2644, #2631, #2627, #2626)
20
+
@@ -423,48 +423,48 @@ foo. JS[:a]
423
423
 
424
424
  ### Calling JavaScript Operators
425
425
 
426
- Opal has a `js` library in the stdlib that provides a `JS` module which can
426
+ Opal has a `opal/raw` library in the stdlib that provides a `Opal::Raw` module which can
427
427
  be used to call JavaScript operators such as `new`. Example:
428
428
 
429
429
  ```ruby
430
- require 'js'
430
+ require 'opal/raw'
431
431
 
432
432
  # new foo(bar)
433
- JS.new(foo, bar)
433
+ Opal::Raw.new(foo, bar)
434
434
 
435
435
  # delete foo["bar"]
436
- JS.delete(foo, :bar)
436
+ Opal::Raw.delete(foo, :bar)
437
437
 
438
438
  # "bar" in foo
439
- JS.in(:bar, foo)
439
+ Opal::Raw.in(:bar, foo)
440
440
 
441
441
  # foo instanceof bar
442
- JS.instanceof(foo, bar)
442
+ Opal::Raw.instanceof(foo, bar)
443
443
 
444
444
  # typeof foo
445
- JS.typeof(foo)
445
+ Opal::Raw.typeof(foo)
446
446
  ```
447
447
 
448
448
  ### Calling JavaScript Global Functions
449
449
 
450
- You can also use the `js` library to call JavaScript global functions via
451
- `JS.call`:
450
+ You can also use the `opal/raw` library to call JavaScript global functions via
451
+ `Opal::Raw.call`:
452
452
 
453
453
  ```ruby
454
- require 'js'
454
+ require 'opal/raw'
455
455
 
456
456
  # parseFloat("1.1")
457
- JS.call(:parseFloat, "1.1")
457
+ Opal::Raw.call(:parseFloat, "1.1")
458
458
  ```
459
459
 
460
460
  For convenience, `method_missing` is aliased to call, allowing you to call
461
- global JavaScript methods directly on the `JS` module:
461
+ global JavaScript methods directly on the `Opal::Raw` module:
462
462
 
463
463
  ```ruby
464
- require 'js'
464
+ require 'opal/raw'
465
465
 
466
466
  # parseFloat("1.1")
467
- JS.parseFloat("1.1")
467
+ Opal::Raw.parseFloat("1.1")
468
468
  ```
469
469
 
470
470
 
data/docs/releasing.md CHANGED
@@ -21,7 +21,7 @@ All of the following is now covered by `bin/rake release:prepare VERSION=v1.2.3`
21
21
 
22
22
  ## Release!
23
23
 
24
- - Push the commit to `master`
24
+ - Push the commit to `master` or the current stable branch
25
25
  - Run `bin/rake release` to release the new version to Rubygems
26
26
  - Go to GitHub releases and create a new release from the latest tag pasting the contents from CHANGELOG.md (or UNRELEASED.md for pre-releases)
27
27
 
@@ -36,7 +36,9 @@ All of the following is now covered by `bin/rake release:prepare VERSION=v1.2.3`
36
36
 
37
37
  ### [skip for pre-releases] Opal site
38
38
 
39
- - Open `opal.github.io` and update the opal version in the `Gemfile`
39
+ - Open `opal.github.io`
40
+ - checkout the `source` branch
41
+ - update the opal version in the `Gemfile` with `bundle update opal`
40
42
  - run `bin/build`
41
43
  - `git push` the latest changes
42
44
 
data/exe/opal-build CHANGED
@@ -71,7 +71,7 @@ else
71
71
  lib_name = ARGV.first
72
72
 
73
73
  output = options[:output] ? File.open(options[:output], 'w') : $stdout
74
- output.puts Opal::Builder.build(lib_name.dup.untaint)
74
+ output.puts Opal::Builder.build(lib_name.dup)
75
75
  end
76
76
 
77
77
 
data/lib/opal/compiler.rb CHANGED
@@ -190,7 +190,7 @@ module Opal
190
190
 
191
191
  # @!method backtick_javascript?
192
192
  #
193
- # Allows use of a backtick operator (and `%x{}``) to embed verbatim JavaScript.
193
+ # Allows use of a backtick operator (and `%x{}`) to embed verbatim JavaScript.
194
194
  # If false, backtick operator will
195
195
  compiler_option :backtick_javascript, default: nil, as: :backtick_javascript?, magic_comment: true
196
196
 
@@ -37,7 +37,7 @@ module Opal
37
37
  # For .JS. call we pass a block
38
38
  # as a plain JS callback
39
39
  if @iter
40
- @arglist = @arglist << @iter
40
+ @arglist <<= @iter
41
41
  end
42
42
  @iter = nil
43
43
  end
@@ -132,7 +132,7 @@ module Opal
132
132
  if SUPPORTED_FLAGS =~ flag
133
133
  true
134
134
  else
135
- compiler.warning "Skipping the '#{flag}' Regexp flag as it's not widely supported by JavaScript vendors."
135
+ compiler.warning "Skipping the '#{flag}' Regexp flag as it's not widely supported by JavaScript vendors.", @sexp.line
136
136
  false
137
137
  end
138
138
  end
@@ -221,7 +221,7 @@ module Opal
221
221
  end
222
222
 
223
223
  def rescue_body
224
- body_code = (body || s(:nil))
224
+ body_code = body || s(:nil)
225
225
  body_code = compiler.returns(body_code) unless stmt?
226
226
  body_code
227
227
  end
@@ -267,7 +267,7 @@ module Opal
267
267
  @identity = "$$#{mid}"
268
268
  else
269
269
  # Parent scope is the defining module/class
270
- name ||= [(parent && (parent.name || parent.scope_name)), mid].compact.join('_')
270
+ name ||= [parent && (parent.name || parent.scope_name), mid].compact.join('_')
271
271
  @identity = @compiler.unique_temp(name)
272
272
  end
273
273
 
data/lib/opal/version.rb CHANGED
@@ -3,5 +3,5 @@
3
3
  module Opal
4
4
  # WHEN RELEASING:
5
5
  # Remember to update RUBY_ENGINE_VERSION in opal/corelib/constants.rb too!
6
- VERSION = '1.8.2'
6
+ VERSION = '1.8.3.rc1'
7
7
  end
@@ -1322,7 +1322,7 @@ class ::Array < `Array`
1322
1322
  def include?(member)
1323
1323
  %x{
1324
1324
  for (var i = 0, length = self.length; i < length; i++) {
1325
- if (#{`self[i]` == member}) {
1325
+ if ($eqeq(self[i], member)) {
1326
1326
  return true;
1327
1327
  }
1328
1328
  }
@@ -63,7 +63,7 @@ class ::BasicObject
63
63
  ::Kernel.raise ::ArgumentError, 'wrong number of arguments (0 for 1..3)' unless (1..3).cover? args.size
64
64
 
65
65
  string, file, _lineno = *args
66
- default_eval_options = { file: (file || '(eval)'), eval: true }
66
+ default_eval_options = { file: file || '(eval)', eval: true }
67
67
  compiling_options = __OPAL_COMPILER_CONFIG__.merge(default_eval_options)
68
68
  compiled = ::Opal.compile string, compiling_options
69
69
  block = ::Kernel.proc do
@@ -1,9 +1,9 @@
1
1
  ::RUBY_PLATFORM = 'opal'
2
2
  ::RUBY_ENGINE = 'opal'
3
3
  ::RUBY_VERSION = '3.2.0'
4
- ::RUBY_ENGINE_VERSION = '1.8.2'
5
- ::RUBY_RELEASE_DATE = '2023-11-23'
4
+ ::RUBY_ENGINE_VERSION = '1.8.3.rc1'
5
+ ::RUBY_RELEASE_DATE = '2024-08-08'
6
6
  ::RUBY_PATCHLEVEL = 0
7
7
  ::RUBY_REVISION = '0'
8
- ::RUBY_COPYRIGHT = 'opal - Copyright (C) 2011-2023 Adam Beynon and the Opal contributors'
8
+ ::RUBY_COPYRIGHT = 'opal - Copyright (C) 2011-2024 Adam Beynon and the Opal contributors'
9
9
  ::RUBY_DESCRIPTION = "opal #{::RUBY_ENGINE_VERSION} (#{::RUBY_RELEASE_DATE} revision #{::RUBY_REVISION})"
@@ -326,7 +326,22 @@ class ::LocalJumpError
326
326
  end
327
327
  end
328
328
 
329
+ module ::Opal
330
+ module Raw
331
+ class Error
332
+ end
333
+ end
334
+ end
335
+
329
336
  module ::JS
330
- class Error
337
+ def self.const_missing(const)
338
+ if const == :Error
339
+ warn '[Opal] JS::Error class has been renamed to Opal::Raw::Error and will change semantics in Opal 2.1. ' \
340
+ 'To ensure forward compatibility, please update your rescue clauses.'
341
+
342
+ ::JS::Raw::Error
343
+ else
344
+ super
345
+ end
331
346
  end
332
347
  end
data/opal/corelib/hash.rb CHANGED
@@ -127,7 +127,7 @@ class ::Hash < `Map`
127
127
 
128
128
  result = true
129
129
 
130
- other.each do |other_key, other_val|
130
+ other.each do |other_key, other_val| # rubocop:disable Style/HashEachMethods
131
131
  val = fetch(other_key, `null`)
132
132
 
133
133
  %x{
data/opal/corelib/io.rb CHANGED
@@ -157,7 +157,7 @@ class ::IO
157
157
  end while data = sysread_noraise(sep == '' ? 65_536 : 1)
158
158
 
159
159
  unless ret
160
- ret, @read_buffer = (@read_buffer || ''), ''
160
+ ret, @read_buffer = @read_buffer || '', ''
161
161
  ret = nil if ret == ''
162
162
  end
163
163
 
@@ -581,7 +581,7 @@ class ::Module
581
581
  ::Kernel.raise ::ArgumentError, 'wrong number of arguments (0 for 1..3)' unless (1..3).cover? args.size
582
582
 
583
583
  string, file, _lineno = *args
584
- default_eval_options = { file: (file || '(eval)'), eval: true }
584
+ default_eval_options = { file: file || '(eval)', eval: true }
585
585
  compiling_options = __OPAL_COMPILER_CONFIG__.merge(default_eval_options)
586
586
  compiled = ::Opal.compile string, compiling_options
587
587
  block = ::Kernel.proc do
@@ -55,7 +55,7 @@ module ::ObjectSpace
55
55
  end
56
56
 
57
57
  def undefine_finalizer(obj)
58
- %{
58
+ %x{
59
59
  var id = #{obj.__id__};
60
60
  registry.unregister(obj);
61
61
  delete_callers(id);
@@ -1747,7 +1747,7 @@
1747
1747
  return result;
1748
1748
  }
1749
1749
  }
1750
- else if (candidate === Opal.JS.Error || candidate['$==='](exception)) {
1750
+ else if ((Opal.Opal.Raw && candidate === Opal.Opal.Raw.Error) || candidate['$==='](exception)) {
1751
1751
  return candidate;
1752
1752
  }
1753
1753
  }
@@ -75,16 +75,16 @@ class ::Encoding
75
75
 
76
76
  def each_char(string, &block)
77
77
  %x{
78
- var low_surrogate = "";
78
+ var high_surrogate = "";
79
79
  for (var i = 0, length = string.length; i < length; i++) {
80
80
  var charcode = string.charCodeAt(i);
81
81
  var chr = string.charAt(i);
82
- if (charcode >= 0xDC00 && charcode <= 0xDFFF) {
83
- low_surrogate = chr;
82
+ if (charcode >= 0xD800 && charcode <= 0xDBFF) {
83
+ high_surrogate = chr;
84
84
  continue;
85
85
  }
86
- else if (charcode >= 0xD800 && charcode <= 0xDBFF) {
87
- chr = low_surrogate + chr;
86
+ else if (charcode >= 0xDC00 && charcode <= 0xDFFF) {
87
+ chr = high_surrogate + chr;
88
88
  }
89
89
  if (string.encoding.name != "UTF-8") {
90
90
  chr = new String(chr);
@@ -400,7 +400,7 @@ class ::String
400
400
  end
401
401
 
402
402
  def initialize_copy(other)
403
- %{
403
+ %x{
404
404
  self.encoding = other.encoding;
405
405
  self.internal_encoding = other.internal_encoding;
406
406
  }
data/opal.gemspec CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.required_ruby_version = '>= 2.3'
35
35
 
36
36
  spec.add_dependency 'ast', '>= 2.3.0'
37
+ spec.add_dependency 'base64', '>= 0.2.0'
37
38
  spec.add_dependency 'parser', ['~> 3.0', '>= 3.0.3.2']
38
39
 
39
40
  spec.add_development_dependency 'sourcemap', '~> 0.1.0'
@@ -44,7 +45,7 @@ Gem::Specification.new do |spec|
44
45
  spec.add_development_dependency 'rack-test'
45
46
  spec.add_development_dependency 'selenium-webdriver'
46
47
  spec.add_development_dependency 'benchmark-ips', '< 2.8'
47
- spec.add_development_dependency 'sinatra', '~> 3.0'
48
+ spec.add_development_dependency 'sinatra', '~> 3.2'
48
49
  spec.add_development_dependency 'rubocop', '~> 1.50'
49
50
  spec.add_development_dependency 'rubocop-performance', '~> 1.1'
50
51
  spec.add_development_dependency 'rack', '~> 2.2'
@@ -487,7 +487,7 @@ RSpec.describe Opal::Compiler do
487
487
  options = options.merge(eval: true)
488
488
  warnings_number = 0
489
489
  compiler = Opal::Compiler.new(code, options)
490
- allow(compiler).to receive(:warning) { warnings_number += 1}
490
+ allow(compiler).to receive(:warning) { warnings_number += 1 }
491
491
  compiler.compile
492
492
  expect(warnings_number)
493
493
  end
@@ -644,12 +644,12 @@ RSpec.describe Opal::Compiler do
644
644
  it 'adds the file and line to the backtrace' do
645
645
  error = nil
646
646
  begin
647
- compiled('BEGIN {}', file: 'foobar.js.rb')
647
+ compiled('BEGIN {}', file: "#{File.basename(__FILE__)}/foobar.js.rb")
648
648
  rescue Opal::SyntaxError => syntax_error
649
649
  error = syntax_error
650
650
  end
651
651
 
652
- expect(error.backtrace[0]).to eq("foobar.js.rb:in `BEGIN {}'")
652
+ expect(error.backtrace[0]).to eq("#{File.basename(__FILE__)}/foobar.js.rb:in `BEGIN {}'")
653
653
  expect(compiler_backtrace(error)[0]).to end_with(":in `error'")
654
654
  expect(compiler_backtrace(error)[-3]).to end_with(":in `block in compile'")
655
655
  expect(compiler_backtrace(error)[-1]).to end_with(":in `compile'")
@@ -660,14 +660,21 @@ RSpec.describe Opal::Compiler do
660
660
  context 'at parse time' do
661
661
  it 'adds the file and line to the backtrace' do
662
662
  error = nil
663
+
663
664
  begin
664
- parsed('def foo', file: 'foobar.js.rb')
665
+ parsed('def foo', file: "#{File.basename(__FILE__)}/foobar.js.rb")
665
666
  rescue Opal::SyntaxError => syntax_error
666
667
  error = syntax_error
667
668
  end
668
- expect(error.backtrace[0]).to eq("foobar.js.rb:1:in `def foo'")
669
+ expect(error.backtrace[0]).to eq("#{File.basename(__FILE__)}/foobar.js.rb:1:in `def foo'")
669
670
  expect(compiler_backtrace(error)[0]).to end_with(":in `block in parse'")
670
671
  expect(error.backtrace.size).to be > 1
672
+
673
+ expect($diagnostic_messages.flatten).to eq([
674
+ "#{File.basename(__FILE__)}/foobar.js.rb:1:8: error: unexpected token $end",
675
+ "#{File.basename(__FILE__)}/foobar.js.rb:1: def foo",
676
+ "#{File.basename(__FILE__)}/foobar.js.rb:1: ",
677
+ ])
671
678
  end
672
679
  end
673
680
 
@@ -707,7 +714,10 @@ RSpec.describe Opal::Compiler do
707
714
  end
708
715
 
709
716
  def compiled(code, options = compiler_options)
710
- Opal::Compiler.new(code, options).compile
717
+ compiler = Opal::Compiler.new(code, options)
718
+ @compiler_warnings = []
719
+ allow(compiler).to receive(:warning) { |*args| @compiler_warnings << args }
720
+ compiler.compile
711
721
  end
712
722
 
713
723
  def parsed(code, options = compiler_options)
@@ -1,4 +1,4 @@
1
1
  # Try loading a file with an absolute path.
2
- require "<%= p __dir__.inspect[1..-2] %>/file51.js"
2
+ require "<%= __dir__.inspect[1..-2] %>/file51.js"
3
3
 
4
4
  FILE_5 = true
@@ -8,7 +8,7 @@ RSpec.describe Opal::Rewriters::Hashes::KeyDuplicatesRewriter do
8
8
  shared_examples 'it warns' do |code, key_to_warn|
9
9
  context "for #{code} code" do
10
10
  it "warns about #{key_to_warn.inspect} being overwritten" do
11
- expect(Kernel).to receive(:warn).with("warning: key #{key_to_warn.inspect} is duplicated and overwritten")
11
+ expect(Kernel).to receive(:warn).with("warning: key #{key_to_warn.inspect} is duplicated and overwritten") { nil }
12
12
 
13
13
  ast = parse_without_rewriting(code)
14
14
  rewrite(ast)
@@ -5,15 +5,26 @@ if ENV['CHECK_COVERAGE']
5
5
  Coveralls.wear!
6
6
  end
7
7
 
8
+ if ENV['CHECK_COVERAGE_SIMPLECOV']
9
+ require 'simplecov'
10
+ SimpleCov.start
11
+ end
12
+
8
13
  require 'opal'
9
14
 
10
15
  ENV['OPAL_DISABLE_PREFORK_LOGS'] = '1'
11
16
 
17
+ $diagnostic_messages = []
18
+ Opal::Parser.default_parser_class.diagnostics_consumer = ->(diagnostic) do
19
+ $diagnostic_messages << diagnostic.render
20
+ end
21
+
12
22
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
13
23
  RSpec.configure do |config|
14
24
  config.before { Opal.reset_paths! unless RUBY_PLATFORM == 'opal' }
15
25
  config.before { Opal::Config.reset! if defined? Opal::Config }
16
26
  config.before { Opal::Processor.reset_cache_key! if defined? Opal::Processor }
27
+ config.before { $diagnostic_messages.clear }
17
28
 
18
29
  # rspec-expectations config goes here. You can use an alternate
19
30
  # assertion/expectation library such as wrong or the stdlib/minitest
@@ -0,0 +1,12 @@
1
+ # backtick_javascript: true
2
+
3
+ describe "Array#include" do
4
+ it "should respect nil values" do
5
+ nileq = Object.new
6
+ def nileq.==(other)
7
+ nil
8
+ end
9
+
10
+ [nileq].should_not include("no match expected")
11
+ end
12
+ end