opal 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a33a6b0ec566d750d22d1bca26dcad96c9410b6c9f009c2d576d5d034d78b76
4
- data.tar.gz: cc9550e4097c954b66d556ed11a1cb90a88336383b4ff1fc8d732117f773117e
3
+ metadata.gz: 2b87866d518e2345b4aa120b4f8d457dad6f86ed9f365974161efad2e2f0dde9
4
+ data.tar.gz: a3dac2be866ce053470b56377131f7615f0ff6bc3dc7a1d567ce77a8efff5278
5
5
  SHA512:
6
- metadata.gz: fb47426dadf8b67198eaf7efcfb5b2d91bc1c567d34247fa170e8a4644236d308bcfabf53e8e428b64728feb81da6692325b9f4dd6d93ebf14a0f0345f020e80
7
- data.tar.gz: b2bbd78addde393c3489fd4d55f3df1d259457415a1593c2a46343943ff227bde4b668a829a434ad57444284681591fab31dcd73e68c6f1acb3677b2c3496649
6
+ metadata.gz: 161e91aa69fc166adf4719b56724251e97239de73dba172916a3de5c744e4d7166a33b0fdc97f9fb68079c0627815a5ae00aba0cbedb137b35a6fc34191979ac
7
+ data.tar.gz: ec37e385c55325552d2b7a82fc4c9ec4cd2a98aa3be966a6f9c193e483d0278f58ac8241eec65e12d9e965ea4eda17454430ae284352526ce408e7bc69729ad3
data/CHANGELOG.md CHANGED
@@ -15,16 +15,37 @@ Changes are grouped as follows:
15
15
 
16
16
 
17
17
 
18
- ## [3.0.1](https://github.com/opal/opal/compare/v1.3.0...v3.0.1) - 2021-11-03
18
+ ## [1.3.2](https://github.com/opal/opal/compare/v1.3.1...v1.3.2) - 2021-11-10
19
19
 
20
20
 
21
21
  ### Fixed
22
22
 
23
- * Fix REPL if bundler environment isn't set ([#2338](https://github.com/opal/opal/pull/2338))
24
- * Fix Chrome runner if bundler environment isn't set and make it work on other Unixes ([#2339](https://github.com/opal/opal/pull/2339))
25
- * `Proc#binding` to return a binding if `Binding` is defined (#2341, #2340)
26
- * `Array#zip` to correctly `yield` (#2342, #1611)
27
- * `String#scan` to correctly `yield` (#2342, #1660)
23
+ - Update documentation ([#2350](https://github.com/opal/opal/pull/2350))
24
+ - Fix `IO#gets` getting an extra char under some circumstances ([#2349](https://github.com/opal/opal/pull/2349))
25
+ - Raise a `TypeError` instead of `UndefinedMethod` if not a string is passed to `__send__` ([#2346](https://github.com/opal/opal/pull/2346))
26
+ - Do not modify `$~` when calling `String#scan` from internal methods ([#2353](https://github.com/opal/opal/pull/2353))
27
+ - Stop interpreting falsey values as a missing constant in `Module#const_get` ([#2354](https://github.com/opal/opal/pull/2354))
28
+
29
+ <!--
30
+ ### Changed
31
+ ### Deprecated
32
+ ### Removed
33
+ ### Internal
34
+ -->
35
+
36
+
37
+
38
+
39
+ ## [1.3.1](https://github.com/opal/opal/compare/v1.3.0...v1.3.1) - 2021-11-03
40
+
41
+
42
+ ### Fixed
43
+
44
+ - Fix REPL if bundler environment isn't set ([#2338](https://github.com/opal/opal/pull/2338))
45
+ - Fix Chrome runner if bundler environment isn't set and make it work on other Unixes ([#2339](https://github.com/opal/opal/pull/2339))
46
+ - `Proc#binding` to return a binding if `Binding` is defined (#2341, #2340)
47
+ - `Array#zip` to correctly `yield` (#2342, #1611)
48
+ - `String#scan` to correctly `yield` (#2342, #1660)
28
49
 
29
50
 
30
51
 
@@ -94,7 +115,7 @@ Changes are grouped as follows:
94
115
  ### Fixed
95
116
 
96
117
  - Fixed multiple line `Regexp` literal to not generate invalid syntax as JavaScript ([#1616](https://github.com/opal/opal/pull/1616))
97
- - Fix `Kernel#{try,catch}` along with `UncaughtThrowError` ([#2264](https://github.com/opal/opal/pull/2264))
118
+ - Fix `Kernel#{throw,catch}` along with `UncaughtThrowError` ([#2264](https://github.com/opal/opal/pull/2264))
98
119
  - Update source-map-support to fix an off-by-one error ([#2264](https://github.com/opal/opal/pull/2264))
99
120
  - Source map: lines should start from 1, not 0 ([#2273](https://github.com/opal/opal/pull/2273))
100
121
  - Allow for multiple underscored args with the same name in strict mode ([#2292](https://github.com/opal/opal/pull/2292))
@@ -123,10 +144,6 @@ Changes are grouped as follows:
123
144
  - `Process` is now a Module, not a Class - just like in MRI ([#2332](https://github.com/opal/opal/pull/2332))
124
145
  - `s = StringIO.new("a"); s << "b"; s.string` now returns "b", like MRI, but Opal used to return "ab" ([#2309](https://github.com/opal/opal/pull/2309))
125
146
 
126
- ### Deprecated
127
-
128
- ### Removed
129
-
130
147
  ### Internal
131
148
 
132
149
  - Switch from jshint to ESLint ([#2289](https://github.com/opal/opal/pull/2289))
data/UNRELEASED.md CHANGED
@@ -1,13 +1,7 @@
1
- ### Added
1
+ <!--
2
2
  ### Fixed
3
-
4
- * Fix REPL if bundler environment isn't set (#2338)
5
- * Fix Chrome runner if bundler environment isn't set and make it work on other Unixes (#2339)
6
- * `Proc#binding` to return a binding if `Binding` is defined (#2341, #2340)
7
- * `Array#zip` to correctly `yield` (#2342, #1611)
8
- * `String#scan` to correctly `yield` (#2342, #1660)
9
-
10
3
  ### Changed
11
4
  ### Deprecated
12
5
  ### Removed
13
6
  ### Internal
7
+ -->
@@ -30,8 +30,8 @@ to convert values to opal specific values.
30
30
 
31
31
  NOTE: Because `true` and `false` compile to their native
32
32
  javascript equivalents, they must share the same class: `Boolean`.
33
- For this reason, they do not belong to their respective `TrueClass`
34
- and `FalseClass` classes from ruby.
33
+ Thru some level of hackery, we make them pseudo-members of the appropriate
34
+ `TrueClass` and `FalseClass`.
35
35
 
36
36
  #### Strings & Symbols
37
37
 
@@ -55,11 +55,11 @@ class. Symbols and Strings can therefore be used interchangeably.
55
55
 
56
56
  #### Numbers
57
57
 
58
- In Opal there is a single class for numbers; `Numeric`. To keep Opal
58
+ In Opal there is a single class for numbers; `Number`. To keep Opal
59
59
  as performant as possible, Ruby numbers are mapped to native numbers.
60
60
  This has the side effect that all numbers must be of the same class.
61
- Most relevant methods from `Integer`, `Float` and `Numeric` are
62
- implemented on this class.
61
+ Most relevant methods from `Integer` and `Float` are implemented on
62
+ this class.
63
63
 
64
64
  ```ruby
65
65
  42 # => 42
@@ -104,7 +104,7 @@ else is a truthy value including `""`, `0` and `[]`. This differs from
104
104
  JavaScript as these values are also treated as false.
105
105
 
106
106
  For this reason, most truthy tests must check if values are `false` or
107
- `nil`.
107
+ `nil` (we also check for `null` and `undefined`).
108
108
 
109
109
  Taking the following test:
110
110
 
@@ -204,16 +204,16 @@ obvious what went wrong.
204
204
 
205
205
  As Opal just generates JavaScript, it is useful to use a native
206
206
  debugger to work through JavaScript code. To use a debugger, simply
207
- add an x-string similar to the following at the place you wish to
208
- debug:
207
+ add a `debugger` statement:
209
208
 
210
209
  ```ruby
211
210
  # .. code
212
- `debugger`
211
+ debugger
213
212
  # .. more code
214
213
  ```
215
- The x-strings just pass the debugger statement straight through to the
216
- JavaScript output.
214
+
215
+ The `debugger` statement is compiled to become a JavaScript `debugger`
216
+ statement. This statement breaks the code if you have your Inspector open.
217
217
 
218
218
  NOTE: All local variables and method/block arguments also keep their Ruby
219
219
  names except in the rare cases when the name is reserved in JavaScript.
@@ -246,7 +246,7 @@ in the browser.
246
246
  }
247
247
 
248
248
  # => opal version is:
249
- # => 0.6.0
249
+ # => 1.3.1
250
250
  ```
251
251
 
252
252
  Even interpolations are supported, as seen here.
@@ -280,6 +280,9 @@ require 'native'
280
280
  win = Native(`window`) # equivalent to Native::Object.new(`window`)
281
281
  ```
282
282
 
283
+ To access a Native-wrapped global JavaScript object, we can also use `$$`, after
284
+ we have the `native` module required.
285
+
283
286
  Now what if we want to access one of its properties?
284
287
 
285
288
  ```ruby
@@ -514,10 +517,10 @@ Opal.BAZ; // => 789
514
517
  To reach nested constants the safest way is to call `#const_get` on `Object`:
515
518
 
516
519
  ```javascript
517
- Opal.Object.$$const_get('Bar::BAR'); // => 123
518
- Opal.Object.$$const_get('Foo::BAR'); // => 123
519
- Opal.Object.$$const_get('Foo::FOO'); // => 456
520
- Opal.Object.$$const_get('BAZ'); // => 789
520
+ Opal.Object.$const_get('Bar::BAR'); // => 123
521
+ Opal.Object.$const_get('Foo::BAR'); // => 123
522
+ Opal.Object.$const_get('Foo::FOO'); // => 456
523
+ Opal.Object.$const_get('BAZ'); // => 789
521
524
  ```
522
525
 
523
526
  Constants can also be navigated using the `$$` property, although this is limited to constants defined directly under the current object:
@@ -528,6 +531,14 @@ Opal.Foo.$$.FOO // => 456
528
531
  Opal.Foo.$$.BAR // => undefined
529
532
  ```
530
533
 
534
+ A later feature also allows you to skip the `$$` property:
535
+
536
+ ```javascript
537
+ Opal.Bar.BAR // => 123
538
+ Opal.Foo.FOO // => 456
539
+ Opal.Foo.BAR // => undefined
540
+ ```
541
+
531
542
 
532
543
  ### Calling methods
533
544
 
data/docs/faq.md CHANGED
@@ -10,7 +10,7 @@ We run opal against the [ruby spec](https://github.com/ruby/spec) as our primary
10
10
 
11
11
  ### What version of ruby does Opal target?
12
12
 
13
- We are running tests under ruby 2.0.0 conditions, but are mostly compatible with 1.9 level features.
13
+ We are running tests under ruby 3.0.0 conditions, but are mostly compatible with 2.6 level features.
14
14
 
15
15
  ### Why doesn't Opal support mutable strings?
16
16
 
@@ -3,7 +3,6 @@
3
3
  ## Requirements
4
4
 
5
5
  First of all, make sure that you have Chrome at least 59.0 installed.
6
- Also for now it's supported only on Mac and Linux. (version 60 may get support on Windows)
7
6
 
8
7
  ## Using the runner
9
8
 
@@ -22,11 +21,9 @@ The runner also listens for any exceptions and prints formatted stracktraces bac
22
21
  raising_method
23
22
  "
24
23
 
25
- RuntimeError : test error
26
- at $$raise (file:///tmp/chrome-opal.js:4996:6)
27
- at $$raising_method (file:///tmp/chrome-opal.js:21144:16)
28
- at (file:///tmp/chrome-opal.js:21146:14)
29
- at (file:///tmp/chrome-opal.js:21147:2)
24
+ RuntimeError: test error
25
+ from <internal:corelib/…>:2693:7:in `<main>'
26
+ from -e:1:1:in `undefined'
30
27
 
31
28
  ## Using exit codes
32
29
 
@@ -36,10 +33,9 @@ By default headless chrome runner explicitly sets exit code to 1 when there was
36
33
  0
37
34
 
38
35
  $ opal -Rchrome -e "raise 'error'"; echo $?
39
- RuntimeError : error
40
- at $$raise (file:///tmp/chrome-opal.js:4996:6)
41
- at (file:///tmp/chrome-opal.js:21139:14)
42
- at (file:///tmp/chrome-opal.js:21140:2)
36
+ RuntimeError: error
37
+ from <internal:corelib/kerne…>:2693:7:in `<main>'
38
+ from -e:1:1:in `undefined'
43
39
  1
44
40
 
45
41
  You can change final exit code by using `Kernel#exit`, but make sure to require `opal/platform` in your code.
@@ -69,20 +65,12 @@ or runs the server on its own. It detects your platform and uses a default path
69
65
  (`Opal::CliRunners::Chrome#chrome_executable`) but you can override it by specifying `GOOGLE_CHROME_BINARY` environment
70
66
  variable.
71
67
 
72
- When the server is up and running it passes compiled js code to `node lib/opal/cli_runners/chrome.js`
68
+ When the server is up and running it passes compiled js code to `lib/opal/cli_runners/chrome_cdp_interface.rb`
73
69
  as a plain input using stdin (basically, it's a second part of the runner).
74
- `chrome.js` is a node js script that does the main job. It runs any provided code on the running chrome server,
70
+ `chrome_cdp_interface.rb` is a node js + Opal script that does the main job. It runs any provided code on the running chrome server,
75
71
  catches errors and forwards console messages.
76
72
 
77
73
 
78
- Moreover, you can actually call any js using headless chrome by running
79
-
80
- $ echo "console.log('Hello, Opal')" | node lib/opal/cli_runners/chrome.js
81
-
82
- NOTE: to run it you need to have a chrome server running on `localhost:9222` (usually `chrome.rb` does it for you)
83
-
84
- $ chrome --disable-gpu --headless --remote-debugging-port=9222
85
-
86
74
  ## Using a remote chrome server
87
75
 
88
76
  If you want to change a default chrome port or your chrome server is running on a different host:port
@@ -99,7 +87,9 @@ NOTE: `CHROME_HOST` requires a chrome server to be started. You can't start remo
99
87
 
100
88
  If you need to pass additional CLI options to the Chrome executable you can do so by setting the `CHROME_OPTS` environment variable:
101
89
 
102
- $ CHROME_OPS="--window-size=412,732" opal -Rchrome -e "puts 42"
90
+ $ CHROME_OPTS="--window-size=412,732" opal -Rchrome -e "puts 42"
103
91
  42
104
92
 
93
+ Docker users may need `CHROME_OPTS="--no-sandbox"` due to the user namespaces limitations.
94
+
105
95
  _For a list of additional options see https://developers.google.com/web/updates/2017/04/headless-chrome_
data/docs/jquery.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # JQuery
2
2
 
3
- `opal-jquery` offers a nicer ruby-like syntax for JQuery (and Zepto). It is
4
- useful for projects which cannot use `opal-browser` due to a reliance on jquery
5
- for plugins or other libraries.
3
+ `opal-jquery` offers a nicer ruby-like syntax for JQuery. It is useful for projects which cannot use `opal-browser` due to a reliance on jquery for plugins or other libraries.
6
4
 
7
5
  ```ruby
8
6
  foos = Element.find('.foo')
@@ -91,9 +89,6 @@ bridged instances of jquery objects. Just like ruby arrays are just javascript
91
89
  arrays, `Element` instances are just jquery objects. This makes interaction
92
90
  with jquery plugins much easier.
93
91
 
94
- Also, `Element` will try to bridge with Zepto if it cannot find jQuery loaded,
95
- making it ideal for mobile applications as well.
96
-
97
92
  ### Interacting with the DOM
98
93
 
99
94
  #### Finding Elements
data/docs/opal_parser.md CHANGED
@@ -8,12 +8,14 @@ Opal is able to compile its – pure Ruby – compiler to JavaScript (how cool i
8
8
  require 'opal-parser'
9
9
  ```
10
10
 
11
+ _Note: For the best performance and application load times, it is strongly recommended to design your application so that it won't need the parser. A lot of methods described in this document are more fun hacks than robust solutions. But if you really want or need to use them, for example so that you can implement a Ruby REPL or an interactive Ruby playground - we have you covered, but for all other cases, we strongly discourage you to take an advice from this guide._
12
+
11
13
 
12
14
  ## Features
13
15
 
14
16
  ### `Kernel#eval`
15
17
 
16
- `opal-parser` provides a partial implementation of `Kernel#eval` that only support the first parameter (String) and refuse any passed `binding`, `lineno` or `filename`.
18
+ `opal-parser` provides a partial implementation of `Kernel#eval`.
17
19
 
18
20
  Example:
19
21
 
data/docs/promises.md CHANGED
@@ -8,6 +8,8 @@ It can be required inside any Opal applicaton:
8
8
  require 'promise'
9
9
  ```
10
10
 
11
+ _Please also take a look at the Asynchronous code guide - we are in the process of modernizing the Promises, along with supporting async/await_
12
+
11
13
  ## Usage
12
14
 
13
15
  This example shows how to use a `HTTP` request from `opal-jquery` from a callback style, into a promise style handler.
data/docs/releasing.md CHANGED
@@ -16,6 +16,10 @@ _This guide is a work-in-progress._
16
16
 
17
17
  - Commit the updated changelog along with the version bump using this commit message:
18
18
  "Release v1.2.3"
19
+ - Push the commit and run `bin/rake release` to release the new version to Rubygems
20
+ - Go to GitHub releases and create a new release from the latest tag pasting the contents of UNRELEASED.md
21
+ - Empty UNRELEASED.md and run `bin/rake changelog`
22
+ - Push the updated changelog
19
23
 
20
24
  ## Opal docs
21
25
 
@@ -23,7 +23,6 @@ class App < Roda
23
23
  plugin :sprockets, precompile: %w(application.js),
24
24
  prefix: %w(app/),
25
25
  opal: true,
26
- debug: ENV['RACK_ENV'] != 'production'
27
26
  plugin :public
28
27
 
29
28
  route do |r|
data/docs/source_maps.md CHANGED
@@ -1,10 +1,6 @@
1
1
  # Source maps
2
2
 
3
- Source maps are available (on current stable release, v0.6.x) even without explicit support from Sprockets in a sort of hackish way.
4
-
5
- _As such even if they generally work fine there are some limitations and edge case issues._
6
-
7
- NOTE: Currently on `master` branch sourcemaps are work-in-progress and probably will integrate with the upcoming Sprockets 4 that has integrated support for them.
3
+ Source maps are available on most environments we support.
8
4
 
9
5
  #### Processor `source_map_enabled` flag
10
6
  To enable sourcemaps in the Sprockets processor you need to turn on the relative flag:
@@ -16,8 +12,7 @@ Opal::Config.source_map_enabled = true # default
16
12
 
17
13
  #### Sprockets debug mode
18
14
 
19
- The sourcemaps only work with Sprockets in debug mode because they are generated just for single files.
20
-
15
+ The source maps only work with Sprockets in debug mode - this is a limitation of Sprockets.
21
16
 
22
17
  ## Enable source maps
23
18
 
@@ -37,13 +32,17 @@ config.assets.debug = true
37
32
 
38
33
  ### Sinatra
39
34
 
40
- You can add `Opal::Server` as in the official example: [sinatra/config.ru](https://github.com/opal/opal/blob/0-6-stable/examples/sinatra/config.ru).
35
+ You can add `Opal::Server` as in the official example: [sinatra/config.ru](https://github.com/opal/opal/blob/master/examples/sinatra/config.ru).
41
36
 
42
37
  ### Opal::Server
43
38
 
44
- `Opal::Server` implements sourcemaps and can be used alone or with `Rack::Cascade` in conjunction with other apps.
39
+ `Opal::Server` (which is based on Sprockets) implements sourcemaps and can be used alone or with `Rack::Cascade` in conjunction with other apps.
40
+
41
+ ### Opal::SimpleServer
42
+
43
+ Like `Opal::Server`, `Opal::SimpleServer` (which isn't based on Sprockets) implements sourcemaps properly.
45
44
 
46
- ### Opal::Environment
45
+ ### Opal::Builder
47
46
 
48
- `Opal::Environment` is a bit lower level and doesn't support source maps by itself.
47
+ `Opal::Builder` is a bit lower level and doesn't support source maps by itself. It requires you to call in a specific method to generate them yourself.
49
48
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  `opal` makes it easy to build static opal applications. Opal uses internal load
4
4
  paths to make it easy to handle resolving requirements during building. `opal`
5
- forms the basis of rails support, so anything you can do there, you can do
5
+ forms the basis of Rails support, so anything you can do there, you can do
6
6
  standalone as well.
7
7
 
8
8
  ## Overview
@@ -11,7 +11,7 @@ First, install `opal` adding them to a `Gemfile`:
11
11
 
12
12
  ```ruby
13
13
  # Gemfile
14
- gem "opal", "~> 0.7.0"
14
+ gem "opal"
15
15
  ```
16
16
 
17
17
  Next, we want to add our main app code. Keep all opal code inside `app/`
@@ -6,6 +6,10 @@ Opal does not support some language/runtime features of ruby. These are document
6
6
 
7
7
  For performance and ease of runtime features, all strings in Opal are immutable, i.e. `#<<`, `#gsub!`, etc. do not exist. Also, symbols are just strings. There is no class, runtime or feature difference between Symbols and Strings. Their syntaxes can be used interchangeably.
8
8
 
9
+ #### Regexp differences ####
10
+
11
+ We are using JavaScript regular expressions. While we do translate a few of Ruby specific instructions like `\A` or `\z`, there are a lot of incompatibilities that you should be aware of - for example `$` and `^` don't match newlines like they do in Ruby. Support for features like named matches or lookahead/lookbehind is dependent on the JavaScript environment support for those. To support everything, we would need to [compile in the entire Ruby's regular expression engine](https://opalrb.com/blog/2021/06/26/webassembly-and-advanced-regexp-with-opal/) which is unfeasible at the current time.
12
+
9
13
  #### Integer / Float difference ####
10
14
 
11
15
  In Opal, both integers and floats belong to same class `Number` (using JavaScript native numbers). So `1 / 4` is `0.25` (not `0`) and `4.0 / 2` is `2` (not `2.0`).
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.3.1'
6
+ VERSION = '1.3.2'
7
7
  end
@@ -24,7 +24,11 @@ class BasicObject
24
24
 
25
25
  def __send__(symbol, *args, &block)
26
26
  %x{
27
- var func = self['$' + symbol]
27
+ if (!symbol.$$is_string) {
28
+ #{raise ::TypeError, "#{inspect} is not a symbol nor a string"}
29
+ }
30
+
31
+ var func = self['$' + symbol];
28
32
 
29
33
  if (func) {
30
34
  if (block !== nil) {
@@ -1,8 +1,8 @@
1
1
  RUBY_PLATFORM = 'opal'
2
2
  RUBY_ENGINE = 'opal'
3
3
  RUBY_VERSION = '3.0.2'
4
- RUBY_ENGINE_VERSION = '1.3.1'
5
- RUBY_RELEASE_DATE = '2021-11-03'
4
+ RUBY_ENGINE_VERSION = '1.3.2'
5
+ RUBY_RELEASE_DATE = '2021-11-10'
6
6
  RUBY_PATCHLEVEL = 0
7
7
  RUBY_REVISION = '0'
8
8
  RUBY_COPYRIGHT = 'opal - Copyright (C) 2013-2021 Adam Beynon and the Opal contributors'
data/opal/corelib/io.rb CHANGED
@@ -124,7 +124,7 @@ class IO
124
124
  sep = sep.to_str unless orig_sep == ''
125
125
 
126
126
  # Try to deduce length of a regexp
127
- seplen = `orig_sep == '' ? 2 : sep.length`
127
+ seplen = orig_sep == '' ? 2 : sep.length
128
128
 
129
129
  sep = / / if sep == ' ' # WTF is this, String#split(" ") matches all whitespaces???
130
130
 
@@ -245,16 +245,16 @@ class Regexp < `RegExp`
245
245
  end
246
246
 
247
247
  def names
248
- source.scan(/\(?<(\w+)>/).map(&:first).uniq
248
+ source.scan(/\(?<(\w+)>/, no_matchdata: true).map(&:first).uniq
249
249
  end
250
250
 
251
251
  def named_captures
252
- source.scan(/\(?<(\w+)>/) # Scan for capture groups
253
- .map(&:first) # Get the first regexp match (\w+)
254
- .each_with_index # Add index to an iterator
255
- .group_by(&:first) # Group by the capture group names
256
- .transform_values do |i| # Convert hash values
257
- i.map { |j| j.last + 1 } # Drop the capture group names; increase indexes by 1
252
+ source.scan(/\(?<(\w+)>/, no_matchdata: true) # Scan for capture groups
253
+ .map(&:first) # Get the first regexp match (\w+)
254
+ .each_with_index # Add index to an iterator
255
+ .group_by(&:first) # Group by the capture group names
256
+ .transform_values do |i| # Convert hash values
257
+ i.map { |j| j.last + 1 } # Drop the capture group names; increase indexes by 1
258
258
  end
259
259
  end
260
260
 
@@ -244,7 +244,7 @@
244
244
  throw e;
245
245
  }
246
246
  cref.$$autoload[name].required = true;
247
- if (cref.$$const[name]) {
247
+ if (cref.$$const[name] != null) {
248
248
  cref.$$autoload[name].success = true;
249
249
  return cref.$$const[name];
250
250
  }
@@ -268,7 +268,7 @@
268
268
  // Get the constant in the scope of the current cref
269
269
  function const_get_name(cref, name) {
270
270
  if (cref) {
271
- if (cref.$$const[name]) { return cref.$$const[name]; }
271
+ if (cref.$$const[name] != null) { return cref.$$const[name]; }
272
272
  if (cref.$$autoload && cref.$$autoload[name]) {
273
273
  return handle_autoload(cref, name);
274
274
  }
@@ -992,7 +992,7 @@ class String < `String`
992
992
  `self.replace(/[\s\u0000]*$/, '')`
993
993
  end
994
994
 
995
- def scan(pattern, &block)
995
+ def scan(pattern, no_matchdata: false, &block)
996
996
  %x{
997
997
  var result = [],
998
998
  match_data = nil,
@@ -1017,7 +1017,7 @@ class String < `String`
1017
1017
  }
1018
1018
  }
1019
1019
 
1020
- #{$~ = `match_data`}
1020
+ if (!no_matchdata) #{$~ = `match_data`};
1021
1021
 
1022
1022
  return (block !== nil ? self : result);
1023
1023
  }
@@ -1,7 +1,6 @@
1
1
  # NOTE: run bin/format-filters after changing this file
2
2
  opal_filter "BasicObject" do
3
3
  fails "BasicObject raises NoMethodError for nonexistent methods after #method_missing is removed"
4
- fails "BasicObject#__send__ raises a TypeError if the method name is not a string or symbol" # NoMethodError: undefined method `' for SendSpecs
5
4
  fails "BasicObject#initialize does not accept arguments"
6
5
  fails "BasicObject#instance_eval evaluates string with given filename and linenumber"
7
6
  fails "BasicObject#instance_eval evaluates string with given filename and negative linenumber" # Expected ["RuntimeError"] to equal ["b_file", "-98"]
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe "IO reading methods" do
4
+ examples = [
5
+ "abc\n|def\n|ghi\n",
6
+ "ab|c\nd|ef\n|ghi\n",
7
+ "©©©\n|ŋææ\n|æπ®\n",
8
+ "🫃🫃🫃\n|🫃🫃🫃\n|🫃🫃🫃\n",
9
+ "efhasdfhasf|asdfasdfasdf|asdfasdfasdf",
10
+ "gsdfgsdg🫃|🫃🫃\n|🫃",
11
+ "a\nb\nc\nd\ne\nf",
12
+ "abcððefsdf🫃|s\nd",
13
+ "a|b|c|d|e|f|g|h|i|\n|j|k|l|\n",
14
+ "a b\n|c| d\n|e f",
15
+ "",
16
+ "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfsafsdsdf\nsadfasdf"
17
+ ]
18
+ examples += examples.map { |i| i.gsub("\n", "\r\n") }
19
+ examples += examples.map { |i| i.gsub("\n", "\r|\n") }
20
+ examples = examples.uniq
21
+
22
+ prepare_io_for = proc do |example|
23
+ example_lines = example.split("|")
24
+ io = IO.new(99)
25
+ io.read_proc = proc do |_length|
26
+ example_lines.shift
27
+ end
28
+ io
29
+ end
30
+
31
+ describe "#readlines" do
32
+ examples.each do |example|
33
+ it "correctly splits messages for input #{example.inspect}" do
34
+ io = prepare_io_for.(example)
35
+ expected_output = example.gsub("|", "").split(/(?<=\n)/)
36
+ io.readlines.should == expected_output
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "#readline" do
42
+ examples.each do |example|
43
+ it "correctly splits messages for input #{example.inspect}" do
44
+ io = prepare_io_for.(example)
45
+ expected_output = example.gsub("|", "").split(/(?<=\n)/)
46
+ loop do
47
+ expected_output.shift.should == io.readline
48
+ rescue EOFError
49
+ expected_output.should == []
50
+ break
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "#gets" do
57
+ examples.each do |example|
58
+ it "correctly splits messages for input #{example.inspect}" do
59
+ io = prepare_io_for.(example)
60
+ expected_output = example.gsub("|", "").split(/(?<=\n)/)
61
+ loop do
62
+ line = io.gets
63
+ expected_output.shift.should == line
64
+ break unless line
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -27,3 +27,17 @@ describe "Bridging" do
27
27
  `typeof(String.call)`.should == "function"
28
28
  end
29
29
  end
30
+
31
+ describe "Constants" do
32
+ it "doesn't raise error when a JS falsey constant is referenced" do
33
+ z = Class.new {
34
+ C1 = 0
35
+ C2 = nil
36
+ C3 = false
37
+ C4 = ''
38
+ C5 = C3
39
+ }
40
+
41
+ [z::C1, z::C2, z::C3, z::C4, z::C5].should == [0, nil, false, '', false]
42
+ end
43
+ end
@@ -23,6 +23,14 @@ describe 'String' do
23
23
  expect("test".gsub(/$/, '2')).to eq "test2"
24
24
  expect("test".gsub(/\b/, '2')).to eq "2test2"
25
25
  end
26
+
27
+ it "doesn't override $~ when it's inspected" do
28
+ 'a:b'.gsub(/([a-z]):([a-z])/) do
29
+ $~.inspect
30
+ target, content = $1, $2
31
+ expect([target, content]).to eq(['a', 'b'])
32
+ end
33
+ end
26
34
  end
27
35
 
28
36
  describe '#sub' do
data/stdlib/quickjs/io.rb CHANGED
@@ -1,5 +1,3 @@
1
- `/* global std */`
2
-
3
1
  %x{
4
2
  Opal.gvars.stdout.write_proc = function(s) {
5
3
  std.out.printf("%s", s);
@@ -1,5 +1,3 @@
1
- `/* global std, scriptArgs */`
2
-
3
1
  ARGV = `scriptArgs`
4
2
 
5
3
  `Opal.exit = std.exit`
data/stdlib/quickjs.rb CHANGED
@@ -1,2 +1,4 @@
1
+ `/* global std, scriptArgs */`
2
+
1
3
  require 'quickjs/io'
2
4
  require 'quickjs/kernel'
@@ -37,3 +37,4 @@ results.forEach(
37
37
  )
38
38
 
39
39
  puts(`\nFailed with ${count} error${count === 1 ? '' : 's'}.`)
40
+ process.exit(count || 1)
data/tasks/linting.rake CHANGED
@@ -25,16 +25,6 @@ namespace :lint do
25
25
  puts "Successful."
26
26
  else
27
27
  sh 'node tasks/linting-parse-eslint-results.js'
28
- # results = JSON.parse File.read(result_path), symbolize_names: true
29
- # results.each do |data|
30
- # next if data[:messages].empty?
31
- #
32
- # relative_path = Pathname(data[:filePath]).relative_path_from(Pathname(dir).expand_path)
33
- # puts "* #{relative_path}"
34
- # data[:messages].each do |message|
35
- # puts " - #{relative_path}:#{message[:line]}:#{message[:column]}-#{message[:endLine]}:#{message[:endColumn]} #{message[:message]}"
36
- # end
37
- # end
38
28
  end
39
29
  end
40
30
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opal
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elia Schito
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2021-11-03 00:00:00.000000000 Z
13
+ date: 2021-11-10 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: ast
@@ -824,6 +824,7 @@ files:
824
824
  - spec/opal/core/hash/internals_spec.rb
825
825
  - spec/opal/core/hash_spec.rb
826
826
  - spec/opal/core/helpers_spec.rb
827
+ - spec/opal/core/io/read_spec.rb
827
828
  - spec/opal/core/iterable_props_spec.rb
828
829
  - spec/opal/core/kernel/at_exit_spec.rb
829
830
  - spec/opal/core/kernel/freeze_spec.rb
@@ -1123,10 +1124,10 @@ licenses:
1123
1124
  metadata:
1124
1125
  homepage_uri: https://opalrb.com/
1125
1126
  bug_tracker_uri: https://github.com/opal/opal/issues
1126
- changelog_uri: https://github.com/opal/opal/blob/v1.3.1/CHANGELOG.md
1127
- readme_uri: https://github.com/opal/opal/blob/v1.3.1/README.md
1128
- api_documentation_uri: http://opalrb.com/docs/api/v1.3.1/index.html
1129
- guides_uri: http://opalrb.com/docs/guides/v1.3.1/index.html
1127
+ changelog_uri: https://github.com/opal/opal/blob/v1.3.2/CHANGELOG.md
1128
+ readme_uri: https://github.com/opal/opal/blob/v1.3.2/README.md
1129
+ api_documentation_uri: http://opalrb.com/docs/api/v1.3.2/index.html
1130
+ guides_uri: http://opalrb.com/docs/guides/v1.3.2/index.html
1130
1131
  chat_uri: https://gitter.im/opal/opal
1131
1132
  source_code_uri: https://github.com/opal/opal
1132
1133
  post_install_message: