opal 1.8.0.beta1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +119 -2
- data/UNRELEASED.md +1 -92
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/hash.rb +6 -2
- data/opal/corelib/method.rb +1 -0
- data/opal/corelib/module.rb +39 -18
- data/opal/corelib/range.rb +54 -10
- data/opal/corelib/runtime.js +10 -10
- data/spec/filters/bugs/cgi.rb +40 -0
- data/spec/filters/bugs/kernel.rb +0 -1
- data/spec/filters/bugs/method.rb +0 -3
- data/spec/filters/bugs/module.rb +1 -10
- data/spec/filters/bugs/range.rb +2 -16
- data/spec/opal/core/module/define_method_spec.rb +29 -0
- data/spec/ruby_specs +1 -0
- data/stdlib/cgi/util.rb +89 -0
- data/stdlib/cgi.rb +1 -14
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea935af6a628e09fb047d39c25422f717a4a4b9ef442fe7ec06183134b3163a1
|
4
|
+
data.tar.gz: d539d6a55c69651064a272a6110498bdba7d2146fa08704f4e759ee7693c28b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 603568ce7472d94e52edc2b4862a5cadb72313e8e1f344c723655a7a691b09cbde1d208e30935a68a2a78c59fa073724d66b24ef7cf56cf69eb8567b9aa851f4
|
7
|
+
data.tar.gz: 7ea6135b1f97d50584259706244705273b429d1eff03c44742f7c165b6caec782a06d33ac209f94545ec2c4f8665c1992367aebbf5699052fc62163414c99e1d
|
data/CHANGELOG.md
CHANGED
@@ -16,18 +16,135 @@ Changes are grouped as follows:
|
|
16
16
|
|
17
17
|
|
18
18
|
|
19
|
-
## [1.
|
19
|
+
## [1.8.0](https://github.com/opal/opal/compare/v1.7.4...v1.8.0) - 2023-10-26
|
20
20
|
|
21
21
|
|
22
22
|
<!--
|
23
23
|
### Internal
|
24
|
-
### Changed
|
25
24
|
### Added
|
26
25
|
### Removed
|
27
26
|
### Deprecated
|
28
27
|
### Performance
|
28
|
+
### Fixed
|
29
|
+
### Documentation
|
29
30
|
-->
|
30
31
|
|
32
|
+
## Highlights
|
33
|
+
|
34
|
+
### `Hash` is now bridged to JavaScript `Map`
|
35
|
+
|
36
|
+
This change brings a lot of benefits, but also some incompatibilities. The main benefit is that `Hash` now is both more performant and relies on native JavaScript capabilities.
|
37
|
+
This improves interoperability with JavaScript. As a downside, applications reaching for internal `Hash` data structures will need to be updated.
|
38
|
+
|
39
|
+
Interacting with `Hash` from `JavaScript` is easier than ever:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
hash = `new Map([['a', 1], ['b', 2]])`
|
43
|
+
hash # => {a: 1, b: 2}
|
44
|
+
`console.log(hash)` # => Map(2) {"a" => 1, "b" => 2}
|
45
|
+
`hash.get('a')` # => 1
|
46
|
+
`hash.set('c', 3)`
|
47
|
+
hash # => {a: 1, b: 2, c: 3}
|
48
|
+
hash.keys # => ["a", "b", "c"]
|
49
|
+
hash.values # => [1, 2, 3]
|
50
|
+
```
|
51
|
+
|
52
|
+
### Performance improvements
|
53
|
+
|
54
|
+
This release brings a lot of performance improvements, our tests on Asciidoctor show a 25% improvement in performance, but we've seen up to 66% performance improvement on some applications.
|
55
|
+
|
56
|
+
## Changelog
|
57
|
+
|
58
|
+
### Deprecated
|
59
|
+
|
60
|
+
- Deprecate using x-string to access JavaScript without an explicit magic-comment ([#2543](https://github.com/opal/opal/pull/2543))
|
61
|
+
|
62
|
+
### Compatibility
|
63
|
+
|
64
|
+
- Add a magic-comment that will disable x-string compilation to JavaScript ([#2543](https://github.com/opal/opal/pull/2543))
|
65
|
+
- Pass value in `PromiseV2#always` just like `PromiseV1#always` does it ([#2579](https://github.com/opal/opal/pull/2579))
|
66
|
+
- `#hash` now returns integers ([#2582](https://github.com/opal/opal/pull/2582))
|
67
|
+
- Improve `Range#include?`/`member?`/`cover?`/`===` ([#2598](https://github.com/opal/opal/pull/2598))
|
68
|
+
- Make `Module#define_method` more compatible with CRuby ([#2593](https://github.com/opal/opal/pull/2593))
|
69
|
+
- `Hash#clone` must freeze clone if original is frozen, but `Hash#dup` must not ([#2603](https://github.com/opal/opal/pull/2603))
|
70
|
+
|
71
|
+
### Fixed
|
72
|
+
|
73
|
+
- Fix `Kernel#Float` with `exception:` option ([#2532](https://github.com/opal/opal/pull/2532))
|
74
|
+
- Fix `Kernel#Integer` with `exception:` option ([#2531](https://github.com/opal/opal/pull/2531))
|
75
|
+
- Fix `String#split` with limit and capturing regexp ([#2544](https://github.com/opal/opal/pull/2544))
|
76
|
+
- Fix `switch` with Object-wrapped values ([#2542](https://github.com/opal/opal/pull/2542))
|
77
|
+
- Fix non-direct subclasses of bridged classes not calling the original constructor ([#2546](https://github.com/opal/opal/pull/2546))
|
78
|
+
- Regexp.escape: Cast to String or drop exception ([#2552](https://github.com/opal/opal/pull/2552))
|
79
|
+
- Propagate removal of method from included/prepended modules ([#2553](https://github.com/opal/opal/pull/2553))
|
80
|
+
- Restore `nodejs/yaml` functionality ([#2551](https://github.com/opal/opal/pull/2551))
|
81
|
+
- Fix sine `Range#size` edge cases ([#2541](https://github.com/opal/opal/pull/2541))
|
82
|
+
- Use a Map instead of a POJO for the jsid_cache ([#2584](https://github.com/opal/opal/pull/2584))
|
83
|
+
- Fix `String#object_id`, `String#__id__`, `String#hash` to match CRuby's behavior ([#2576](https://github.com/opal/opal/pull/2576))
|
84
|
+
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility ([#2578](https://github.com/opal/opal/pull/2578))
|
85
|
+
- Fix `Module#clone` and `Module#dup` to properly copy methods ([#2572](https://github.com/opal/opal/pull/2572))
|
86
|
+
- Chrome runner fix: support code that contains `</script>` ([#2581](https://github.com/opal/opal/pull/2581))
|
87
|
+
- Do not skip `$truthy` when left hand side of a comparison is `self` ([#2596](https://github.com/opal/opal/pull/2596))
|
88
|
+
- Unexpected `return`/`break` should raise `LocalJumpError` ([#2591](https://github.com/opal/opal/pull/2591))
|
89
|
+
|
90
|
+
### Added
|
91
|
+
|
92
|
+
- SourceMap support for `Kernel#eval` ([#2534](https://github.com/opal/opal/pull/2534))
|
93
|
+
- Add `CGI::Util#escapeURIComponent` and `CGI::Util#unescapeURIComponent` ([#2566](https://github.com/opal/opal/pull/2566))
|
94
|
+
- `CGI::Util` implement additional methods ([#2601](https://github.com/opal/opal/pull/2601))
|
95
|
+
|
96
|
+
### Changed
|
97
|
+
|
98
|
+
- Change compilation of Regexp nodes that may contain advanced features, so if invalid that they would raise at runtime, not parse-time ([#2548](https://github.com/opal/opal/pull/2548))
|
99
|
+
- `Hash` is now bridged to JavaScript `Map` and support for non-symbol keys in keyword arguments ([#2568](https://github.com/opal/opal/pull/2568))
|
100
|
+
|
101
|
+
### Documentation
|
102
|
+
|
103
|
+
- Bridging documentation ([#2541](https://github.com/opal/opal/pull/2541))
|
104
|
+
- Fix Typo in Running tests Section of README.md File ([#2580](https://github.com/opal/opal/pull/2580))
|
105
|
+
|
106
|
+
### Performance
|
107
|
+
|
108
|
+
- Improve performance of `Array#intersect?` and `#intersection` ([#2533](https://github.com/opal/opal/pull/2533))
|
109
|
+
- `Proc#call`: Refactor for performance ([#2541](https://github.com/opal/opal/pull/2541))
|
110
|
+
- Opal.stub_for: optimize ([#2541](https://github.com/opal/opal/pull/2541))
|
111
|
+
- Hash: Optimize `#to_a` ([#2541](https://github.com/opal/opal/pull/2541))
|
112
|
+
- Array: Optimize `#collect`/`#map` ([#2541](https://github.com/opal/opal/pull/2541))
|
113
|
+
- Optimize argument slicing in runtime for performance ([#2555](https://github.com/opal/opal/pull/2555))
|
114
|
+
- Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor ([#2556](https://github.com/opal/opal/pull/2556))
|
115
|
+
- Optimize `String#split` and `String#start_with` ([#2560](https://github.com/opal/opal/pull/2560))
|
116
|
+
- Compute `$@` dynamically ([#2592](https://github.com/opal/opal/pull/2592))
|
117
|
+
- Optimize the `$prop` helper ([#2597](https://github.com/opal/opal/pull/2597))
|
118
|
+
- Improve `Array.push()` performance when pushing many items ([#2565](https://github.com/opal/opal/pull/2565))
|
119
|
+
- Optimize `Opal.instance_methods` ([#2600](https://github.com/opal/opal/pull/2600))
|
120
|
+
|
121
|
+
### Internal
|
122
|
+
|
123
|
+
- Update rubocop ([#2535](https://github.com/opal/opal/pull/2535))
|
124
|
+
- Match3Node Cleanup ([#2541](https://github.com/opal/opal/pull/2541))
|
125
|
+
- IFlipFlop/EFlipFlop: Refactor for readability ([#2541](https://github.com/opal/opal/pull/2541))
|
126
|
+
- ForRewriter: Refactor for readability ([#2541](https://github.com/opal/opal/pull/2541))
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
## [1.7.4](https://github.com/opal/opal/compare/v1.7.3...v1.7.4) - 2023-09-14
|
132
|
+
|
133
|
+
|
134
|
+
### Fixed
|
135
|
+
|
136
|
+
- Use a Map instead of a POJO for the jsid_cache ([#2584](https://github.com/opal/opal/pull/2584))
|
137
|
+
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility ([#2578](https://github.com/opal/opal/pull/2578))
|
138
|
+
- Fix `switch` with Object-wrapped values ([#2542](https://github.com/opal/opal/pull/2542))
|
139
|
+
- Regexp.escape: Cast to String or drop exception ([#2552](https://github.com/opal/opal/pull/2552))
|
140
|
+
- Chrome runner fix: support code that contains `</script>` ([#2581](https://github.com/opal/opal/pull/2581))
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
## [1.7.3](https://github.com/opal/opal/compare/v1.7.2...v1.7.3) - 2023-03-23
|
146
|
+
|
147
|
+
|
31
148
|
### Fixed
|
32
149
|
|
33
150
|
- Disallow to define a singleton class for Number ([#2521](https://github.com/opal/opal/pull/2521))
|
data/UNRELEASED.md
CHANGED
@@ -1,101 +1,10 @@
|
|
1
1
|
<!--
|
2
2
|
### Internal
|
3
|
+
### Changed
|
3
4
|
### Added
|
4
5
|
### Removed
|
5
6
|
### Deprecated
|
6
7
|
### Performance
|
7
8
|
### Fixed
|
8
|
-
### Documentation
|
9
9
|
-->
|
10
10
|
|
11
|
-
## Highlights
|
12
|
-
|
13
|
-
### `Hash` is now bridged to JavaScript `Map`
|
14
|
-
|
15
|
-
This change brings a lot of benefits, but also some incompatibilities. The main benefit is that `Hash` now is both more performant and relies on native JavaScript capabilities.
|
16
|
-
This improves interoperability with JavaScript. As a downside, applications reaching for internal `Hash` data structures will need to be updated.
|
17
|
-
|
18
|
-
Interacting with `Hash` from `JavaScript` is easier than ever:
|
19
|
-
|
20
|
-
```ruby
|
21
|
-
hash = `new Map([['a', 1], ['b', 2]])`
|
22
|
-
hash # => {a: 1, b: 2}
|
23
|
-
`console.log(hash)` # => Map(2) {"a" => 1, "b" => 2}
|
24
|
-
`hash.get('a')` # => 1
|
25
|
-
`hash.set('c', 3)`
|
26
|
-
hash # => {a: 1, b: 2, c: 3}
|
27
|
-
hash.keys # => ["a", "b", "c"]
|
28
|
-
hash.values # => [1, 2, 3]
|
29
|
-
```
|
30
|
-
|
31
|
-
### Performance improvements
|
32
|
-
|
33
|
-
This release brings a lot of performance improvements, our tests on Asciidoctor show a 25% improvement in performance, but we've seen up to 66% performance improvement on some applications.
|
34
|
-
|
35
|
-
## Changelog
|
36
|
-
|
37
|
-
### Deprecated
|
38
|
-
|
39
|
-
- Deprecate using x-string to access JavaScript without an explicit magic-comment (#2543)
|
40
|
-
|
41
|
-
### Compatibility
|
42
|
-
|
43
|
-
- Add a magic-comment that will disable x-string compilation to JavaScript (#2543)
|
44
|
-
- Pass value in `PromiseV2#always` just like `PromiseV1#always` does it (#2579)
|
45
|
-
- `#hash` now returns integers #2582)
|
46
|
-
|
47
|
-
### Fixed
|
48
|
-
|
49
|
-
- Fix `Kernel#Float` with `exception:` option (#2532)
|
50
|
-
- Fix `Kernel#Integer` with `exception:` option (#2531)
|
51
|
-
- Fix `String#split` with limit and capturing regexp (#2544)
|
52
|
-
- Fix `switch` with Object-wrapped values (#2542)
|
53
|
-
- Fix non-direct subclasses of bridged classes not calling the original constructor (#2546)
|
54
|
-
- Regexp.escape: Cast to String or drop exception (#2552)
|
55
|
-
- Propagate removal of method from included/prepended modules (#2553)
|
56
|
-
- Restore `nodejs/yaml` functionality (#2551)
|
57
|
-
- Fix sine `Range#size` edge cases (#2541)
|
58
|
-
- Use a Map instead of a POJO for the jsid_cache (#2584)
|
59
|
-
- Fix `String#object_id`, `String#__id__`, `String#hash` to match CRuby's behavior (#2576)
|
60
|
-
- Lowercase response headers in `SimpleServer` for rack 3.0 compatibility (#2578)
|
61
|
-
- Fix `Module#clone` and `Module#dup` to properly copy methods (#2572)
|
62
|
-
- Chrome runner fix: support code that contains `</script>` (#2581)
|
63
|
-
- Do not skip `$truthy` when left hand side of a comparison is `self` (#2596)
|
64
|
-
- Unexpected `return`/`break` should raise `LocalJumpError` (#2591)
|
65
|
-
|
66
|
-
### Added
|
67
|
-
|
68
|
-
- SourceMap support for `Kernel#eval` (#2534)
|
69
|
-
- Add `CGI::Util#escapeURIComponent` and `CGI::Util#unescapeURIComponent` (#2566)
|
70
|
-
|
71
|
-
### Changed
|
72
|
-
|
73
|
-
- Change compilation of Regexp nodes that may contain advanced features, so if invalid that they would raise at runtime, not parse-time (#2548)
|
74
|
-
- `Hash` is now bridged to JavaScript `Map` and support for non-symbol keys in keyword arguments (#2568)
|
75
|
-
|
76
|
-
### Documentation
|
77
|
-
|
78
|
-
- Bridging documentation (#2541)
|
79
|
-
- Fix Typo in Running tests Section of README.md File (#2580)
|
80
|
-
|
81
|
-
### Performance
|
82
|
-
|
83
|
-
- Improve performance of `Array#intersect?` and `#intersection` (#2533)
|
84
|
-
- `Proc#call`: Refactor for performance (#2541)
|
85
|
-
- Opal.stub_for: optimize (#2541)
|
86
|
-
- Hash: Optimize `#to_a` (#2541)
|
87
|
-
- Array: Optimize `#collect`/`#map` (#2541)
|
88
|
-
- Optimize argument slicing in runtime for performance (#2555)
|
89
|
-
- Closure: Generate a JavaScript object, not an Error, gain up to 15% on Asciidoctor (#2556)
|
90
|
-
- Optimize `String#split` and `String#start_with` (#2560)
|
91
|
-
- Compute `$@` dynamically (#2592)
|
92
|
-
- Optimize the `$prop` helper (#2597)
|
93
|
-
- Improve `Array.push()` performance when pushing many items (#2565)
|
94
|
-
-
|
95
|
-
|
96
|
-
### Internal
|
97
|
-
|
98
|
-
- Update rubocop (#2535)
|
99
|
-
- Match3Node Cleanup (#2541)
|
100
|
-
- IFlipFlop/EFlipFlop: Refactor for readability (#2541)
|
101
|
-
- ForRewriter: Refactor for readability (#2541)
|
data/lib/opal/version.rb
CHANGED
data/opal/corelib/constants.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
::RUBY_PLATFORM = 'opal'
|
2
2
|
::RUBY_ENGINE = 'opal'
|
3
3
|
::RUBY_VERSION = '3.2.0'
|
4
|
-
::RUBY_ENGINE_VERSION = '1.8.0
|
5
|
-
::RUBY_RELEASE_DATE = '2023-10-
|
4
|
+
::RUBY_ENGINE_VERSION = '1.8.0'
|
5
|
+
::RUBY_RELEASE_DATE = '2023-10-26'
|
6
6
|
::RUBY_PATCHLEVEL = 0
|
7
7
|
::RUBY_REVISION = '0'
|
8
8
|
::RUBY_COPYRIGHT = 'opal - Copyright (C) 2011-2023 Adam Beynon and the Opal contributors'
|
data/opal/corelib/hash.rb
CHANGED
@@ -210,7 +210,8 @@ class ::Hash < `Map`
|
|
210
210
|
def clone
|
211
211
|
%x{
|
212
212
|
var hash = self.$class().$new();
|
213
|
-
|
213
|
+
$hash_clone(self, hash);
|
214
|
+
return self["$frozen?"]() ? hash.$freeze() : hash;
|
214
215
|
}
|
215
216
|
end
|
216
217
|
|
@@ -365,6 +366,10 @@ class ::Hash < `Map`
|
|
365
366
|
item.dig(*keys)
|
366
367
|
end
|
367
368
|
|
369
|
+
def dup
|
370
|
+
`$hash_clone(self, self.$class().$new())`
|
371
|
+
end
|
372
|
+
|
368
373
|
def each(&block)
|
369
374
|
return enum_for(:each) { size } unless block
|
370
375
|
|
@@ -932,7 +937,6 @@ class ::Hash < `Map`
|
|
932
937
|
`Array.from(self.values())`
|
933
938
|
end
|
934
939
|
|
935
|
-
alias dup clone
|
936
940
|
alias each_pair each
|
937
941
|
alias eql? ==
|
938
942
|
alias filter select
|
data/opal/corelib/method.rb
CHANGED
data/opal/corelib/module.rb
CHANGED
@@ -2,6 +2,22 @@
|
|
2
2
|
# backtick_javascript: true
|
3
3
|
|
4
4
|
class ::Module
|
5
|
+
%x{
|
6
|
+
function ensure_symbol_or_string(name) {
|
7
|
+
if (name.$$is_string) {
|
8
|
+
return name;
|
9
|
+
};
|
10
|
+
var converted_name = #{::Opal.try_convert(`name`, ::String, :to_str)};
|
11
|
+
if (converted_name.$$is_string) {
|
12
|
+
return converted_name;
|
13
|
+
} else if (converted_name === nil) {
|
14
|
+
#{::Kernel.raise ::TypeError, "#{`name`} is not a symbol nor a string"}
|
15
|
+
} else {
|
16
|
+
#{::Kernel.raise ::TypeError, "can't convert #{`name`.class} to String (#{`name`.class}#to_str gives #{`converted_name`.class}"}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
5
21
|
def self.allocate
|
6
22
|
%x{
|
7
23
|
var module = Opal.allocate_module(nil, function(){});
|
@@ -388,9 +404,12 @@ class ::Module
|
|
388
404
|
|
389
405
|
if (method === undefined && block === nil)
|
390
406
|
#{::Kernel.raise ::ArgumentError, 'tried to create a Proc object without a block'}
|
407
|
+
|
408
|
+
name = ensure_symbol_or_string(name);
|
391
409
|
}
|
392
410
|
|
393
|
-
|
411
|
+
if `method !== undefined`
|
412
|
+
block = case method
|
394
413
|
when ::Proc
|
395
414
|
method
|
396
415
|
|
@@ -398,15 +417,21 @@ class ::Module
|
|
398
417
|
`#{method.to_proc}.$$unbound`
|
399
418
|
|
400
419
|
when ::UnboundMethod
|
401
|
-
|
402
|
-
bound = method.bind(self)
|
403
|
-
bound.call(*args)
|
404
|
-
}
|
420
|
+
`Opal.wrap_method_body(method.$$method)`
|
405
421
|
|
406
422
|
else
|
407
|
-
::Kernel.raise ::TypeError, "wrong argument type #{
|
423
|
+
::Kernel.raise ::TypeError, "wrong argument type #{method.class} (expected Proc/Method/UnboundMethod)"
|
408
424
|
end
|
409
425
|
|
426
|
+
if `!method.$$is_proc`
|
427
|
+
owner = method.owner
|
428
|
+
if `owner.$$is_class` && !(self <= owner) # rubocop:disable Style/InverseMethods
|
429
|
+
message = `owner.$$is_singleton` ? "can't bind singleton method to a different class" : "bind argument must be a subclass of #{owner}"
|
430
|
+
::Kernel.raise ::TypeError, message
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
410
435
|
%x{
|
411
436
|
if (typeof(Proxy) !== 'undefined') {
|
412
437
|
var meta = Object.create(null)
|
@@ -414,15 +439,17 @@ class ::Module
|
|
414
439
|
block.$$proxy_target = block
|
415
440
|
block = new Proxy(block, {
|
416
441
|
apply: function(target, self, args) {
|
417
|
-
var old_name = target.$$jsid
|
442
|
+
var old_name = target.$$jsid, old_lambda = target.$$is_lambda;
|
418
443
|
target.$$jsid = name;
|
444
|
+
target.$$is_lambda = true;
|
419
445
|
try {
|
420
446
|
return target.apply(self, args);
|
421
447
|
} catch(e) {
|
422
448
|
if (e === target.$$brk || e === target.$$ret) return e.$v;
|
423
449
|
throw e;
|
424
450
|
} finally {
|
425
|
-
target.$$jsid = old_name
|
451
|
+
target.$$jsid = old_name;
|
452
|
+
target.$$is_lambda = old_lambda;
|
426
453
|
}
|
427
454
|
}
|
428
455
|
})
|
@@ -453,10 +480,7 @@ class ::Module
|
|
453
480
|
def remove_method(*names)
|
454
481
|
%x{
|
455
482
|
for (var i = 0; i < names.length; i++) {
|
456
|
-
var name = names[i];
|
457
|
-
if (!(typeof name === "string" || name.$$is_string)) {
|
458
|
-
#{raise ::TypeError, "#{name} is not a symbol nor a string"}
|
459
|
-
}
|
483
|
+
var name = ensure_symbol_or_string(names[i]);
|
460
484
|
$deny_frozen_access(self);
|
461
485
|
|
462
486
|
Opal.rdef(self, "$" + name);
|
@@ -705,13 +729,10 @@ class ::Module
|
|
705
729
|
def undef_method(*names)
|
706
730
|
%x{
|
707
731
|
for (var i = 0; i < names.length; i++) {
|
708
|
-
var name = names[i];
|
709
|
-
if (!(typeof name === "string" || name.$$is_string)) {
|
710
|
-
#{raise ::TypeError, "#{name} is not a symbol nor a string"}
|
711
|
-
}
|
732
|
+
var name = ensure_symbol_or_string(names[i]);
|
712
733
|
$deny_frozen_access(self);
|
713
734
|
|
714
|
-
Opal.udef(self, "$" +
|
735
|
+
Opal.udef(self, "$" + name);
|
715
736
|
}
|
716
737
|
}
|
717
738
|
|
@@ -740,7 +761,7 @@ class ::Module
|
|
740
761
|
var name = method_names[i],
|
741
762
|
jsid = $jsid(name),
|
742
763
|
body = from.$$prototype[jsid],
|
743
|
-
wrapped = Opal.
|
764
|
+
wrapped = Opal.wrap_method_body(body);
|
744
765
|
|
745
766
|
wrapped.$$jsid = name;
|
746
767
|
Opal.defn(to, jsid, wrapped);
|
data/opal/corelib/range.rb
CHANGED
@@ -19,7 +19,8 @@ class ::Range
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def ===(value)
|
22
|
-
|
22
|
+
return false if `value.$$is_range`
|
23
|
+
cover? value
|
23
24
|
end
|
24
25
|
|
25
26
|
%x{
|
@@ -44,13 +45,34 @@ class ::Range
|
|
44
45
|
end
|
45
46
|
|
46
47
|
def cover?(value)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
48
|
+
compare = ->(a, b) {
|
49
|
+
a <=> b || 1
|
50
|
+
}
|
51
|
+
|
52
|
+
if `value.$$is_range`
|
53
|
+
val_begin = value.begin
|
54
|
+
val_end = value.end
|
55
|
+
val_excl = value.exclude_end?
|
56
|
+
if (@begin && val_begin.nil?) ||
|
57
|
+
(@end && val_end.nil?) ||
|
58
|
+
(val_begin && val_end && compare.call(val_begin, val_end).then { |c| val_excl ? c >= 0 : c > 0 }) ||
|
59
|
+
(val_begin && !cover?(val_begin))
|
60
|
+
return false
|
61
|
+
end
|
62
|
+
|
63
|
+
cmp = compare.call(@end, val_end)
|
64
|
+
return cmp >= 0 if @excl == val_excl
|
65
|
+
return cmp > 0 if @excl
|
66
|
+
return true if cmp >= 0
|
67
|
+
|
68
|
+
val_max = value.max
|
69
|
+
return !val_max.nil? && compare.call(val_max, @end) <= 0
|
70
|
+
end
|
71
|
+
|
72
|
+
return false if @begin && compare.call(@begin, value) > 0
|
73
|
+
return true if @end.nil?
|
74
|
+
end_cmp = compare.call(value, @end)
|
75
|
+
@excl ? end_cmp < 0 : end_cmp <= 0
|
54
76
|
end
|
55
77
|
|
56
78
|
def each(&block)
|
@@ -113,6 +135,29 @@ class ::Range
|
|
113
135
|
super
|
114
136
|
end
|
115
137
|
|
138
|
+
def include?(val)
|
139
|
+
if `self.begin.$$is_number || self.end.$$is_number` ||
|
140
|
+
@begin.is_a?(::Time) || @end.is_a?(::Time) ||
|
141
|
+
::Integer.try_convert(@begin) || ::Integer.try_convert(@end)
|
142
|
+
return cover?(val)
|
143
|
+
end
|
144
|
+
|
145
|
+
if `self.begin.$$is_string || self.end.$$is_string`
|
146
|
+
if `self.begin.$$is_string && self.end.$$is_string`
|
147
|
+
return @begin.upto(@end, @excl).any? { |s| s == val }
|
148
|
+
elsif @begin.nil?
|
149
|
+
cmp = val <=> @end
|
150
|
+
return !cmp.nil? && (@excl ? cmp < 0 : cmp <= 0)
|
151
|
+
elsif @end.nil?
|
152
|
+
cmp = @begin <=> val
|
153
|
+
return !cmp.nil? && cmp <= 0
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# invoke Enumerable#include?
|
158
|
+
super
|
159
|
+
end
|
160
|
+
|
116
161
|
def last(n = undefined)
|
117
162
|
::Kernel.raise ::RangeError, 'cannot get the maximum of endless range' if @end.nil?
|
118
163
|
return @end if `n == null`
|
@@ -319,6 +364,5 @@ class ::Range
|
|
319
364
|
end
|
320
365
|
|
321
366
|
alias == eql?
|
322
|
-
alias
|
323
|
-
alias member? cover?
|
367
|
+
alias member? include?
|
324
368
|
end
|
data/opal/corelib/runtime.js
CHANGED
@@ -940,7 +940,7 @@
|
|
940
940
|
};
|
941
941
|
|
942
942
|
Opal.instance_methods = function(mod) {
|
943
|
-
var
|
943
|
+
var processed = Object.create(null), results = [], ancestors = $ancestors(mod);
|
944
944
|
|
945
945
|
for (var i = 0, l = ancestors.length; i < l; i++) {
|
946
946
|
var ancestor = ancestors[i],
|
@@ -955,18 +955,18 @@
|
|
955
955
|
for (var j = 0, ll = props.length; j < ll; j++) {
|
956
956
|
var prop = props[j];
|
957
957
|
|
958
|
+
if (processed[prop]) {
|
959
|
+
continue;
|
960
|
+
}
|
958
961
|
if (Opal.is_method(prop)) {
|
959
|
-
var
|
960
|
-
method = proto[prop];
|
961
|
-
|
962
|
-
if (method.$$stub && exclude.indexOf(method_name) === -1) {
|
963
|
-
exclude.push(method_name);
|
964
|
-
}
|
962
|
+
var method = proto[prop];
|
965
963
|
|
966
|
-
if (!method.$$stub
|
964
|
+
if (!method.$$stub) {
|
965
|
+
var method_name = prop.slice(1);
|
967
966
|
results.push(method_name);
|
968
967
|
}
|
969
968
|
}
|
969
|
+
processed[prop] = true;
|
970
970
|
}
|
971
971
|
}
|
972
972
|
|
@@ -2207,7 +2207,7 @@
|
|
2207
2207
|
|
2208
2208
|
// We need a wrapper because otherwise properties
|
2209
2209
|
// would be overwritten on the original body.
|
2210
|
-
alias = Opal.
|
2210
|
+
alias = Opal.wrap_method_body(body);
|
2211
2211
|
|
2212
2212
|
// Try to make the browser pick the right name
|
2213
2213
|
alias.displayName = name;
|
@@ -2219,7 +2219,7 @@
|
|
2219
2219
|
return obj;
|
2220
2220
|
};
|
2221
2221
|
|
2222
|
-
Opal.
|
2222
|
+
Opal.wrap_method_body = function(body) {
|
2223
2223
|
var wrapped = function() {
|
2224
2224
|
var block = wrapped.$$p;
|
2225
2225
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# NOTE: run bin/format-filters after changing this file
|
2
|
+
opal_filter "CGI" do
|
3
|
+
fails "CGI#http_header CGI#http_header when passed Hash includes Cookies in the @output_cookies field" # NoMethodError: undefined method `http_header' for #<CGI:0x98198 @output_cookies=["multiple", "cookies"]>
|
4
|
+
fails "CGI#http_header CGI#http_header when passed Hash returns a HTTP header based on the Hash's key/value pairs" # NoMethodError: undefined method `http_header' for #<CGI:0x98194>
|
5
|
+
fails "CGI#http_header CGI#http_header when passed Hash returns a HTTP header specifying the Content-Type as text/html when passed an empty Hash" # NoMethodError: undefined method `http_header' for #<CGI:0x98190>
|
6
|
+
fails "CGI#http_header CGI#http_header when passed String includes Cookies in the @output_cookies field" # NoMethodError: undefined method `http_header' for #<CGI:0x98186 @output_cookies=["multiple", "cookies"]>
|
7
|
+
fails "CGI#http_header CGI#http_header when passed String returns a HTTP header specifying the Content-Type as the passed String's content" # NoMethodError: undefined method `http_header' for #<CGI:0x9818c>
|
8
|
+
fails "CGI#http_header CGI#http_header when passed no arguments includes Cookies in the @output_cookies field" # NoMethodError: undefined method `http_header' for #<CGI:0x9817c @output_cookies=["multiple", "cookies"]>
|
9
|
+
fails "CGI#http_header CGI#http_header when passed no arguments returns a HTTP header specifying the Content-Type as text/html" # NoMethodError: undefined method `http_header' for #<CGI:0x98182>
|
10
|
+
fails "CGI#initialize is private" # Expected CGI to have private instance method 'initialize' but it does not
|
11
|
+
fails "CGI#initialize when passed no arguments does not extend self with CGI::HtmlExtension" # NameError: uninitialized constant CGI::HtmlExtension
|
12
|
+
fails "CGI#initialize when passed no arguments does not extend self with any of the other HTML modules" # NameError: uninitialized constant CGI::Html3
|
13
|
+
fails "CGI#initialize when passed no arguments extends self with CGI::QueryExtension" # NameError: uninitialized constant CGI::QueryExtension
|
14
|
+
fails "CGI#initialize when passed no arguments sets #cookies based on ENV['HTTP_COOKIE']" # NoMethodError: undefined method `cookies' for #<CGI:0x12604>
|
15
|
+
fails "CGI#initialize when passed no arguments sets #params based on ENV['QUERY_STRING'] when ENV['REQUEST_METHOD'] is GET" # NoMethodError: undefined method `params' for #<CGI:0x12614>
|
16
|
+
fails "CGI#initialize when passed no arguments sets #params based on ENV['QUERY_STRING'] when ENV['REQUEST_METHOD'] is HEAD" # NoMethodError: undefined method `params' for #<CGI:0x12600>
|
17
|
+
fails "CGI#initialize when passed type extends self with CGI::QueryExtension" # NameError: uninitialized constant CGI::QueryExtension
|
18
|
+
fails "CGI#initialize when passed type extends self with CGI::QueryExtension, CGI::Html3 and CGI::HtmlExtension when the passed type is 'html3'" # NameError: uninitialized constant CGI::Html3
|
19
|
+
fails "CGI#initialize when passed type extends self with CGI::QueryExtension, CGI::Html4 and CGI::HtmlExtension when the passed type is 'html4'" # NameError: uninitialized constant CGI::Html4
|
20
|
+
fails "CGI#initialize when passed type extends self with CGI::QueryExtension, CGI::Html4Tr and CGI::HtmlExtension when the passed type is 'html4Tr'" # NameError: uninitialized constant CGI::Html4Tr
|
21
|
+
fails "CGI#initialize when passed type extends self with CGI::QueryExtension, CGI::Html4Tr, CGI::Html4Fr and CGI::HtmlExtension when the passed type is 'html4Fr'" # NameError: uninitialized constant CGI::Html4Tr
|
22
|
+
fails "CGI#out appends the block's return value to the HTML header" # NoMethodError: undefined method `out' for #<CGI:0x86a80>
|
23
|
+
fails "CGI#out automatically sets the Content-Length Header based on the block's return value" # NoMethodError: undefined method `out' for #<CGI:0x86a8c>
|
24
|
+
fails "CGI#out includes Cookies in the @output_cookies field" # NoMethodError: undefined method `out' for #<CGI:0x86a74 @output_cookies=["multiple", "cookies"]>
|
25
|
+
fails "CGI#out it writes a HTMl header based on the passed argument to $stdout" # NoMethodError: undefined method `out' for #<CGI:0x86a86>
|
26
|
+
fails "CGI#out when passed no block raises a LocalJumpError" # Expected LocalJumpError but got: NoMethodError (undefined method `out' for #<CGI:0x86a96>)
|
27
|
+
fails "CGI.escape url-encodes the passed argument" # Expected "%20!%22\#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D" == "+%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D" to be truthy but was false
|
28
|
+
fails "CGI.escapeElement when passed String, elements, ... escapes only the tags of the passed elements in the passed String" # NoMethodError: undefined method `escapeElement' for CGI
|
29
|
+
fails "CGI.escapeElement when passed String, elements, ... is case-insensitive" # NoMethodError: undefined method `escapeElement' for CGI
|
30
|
+
fails "CGI.parse when passed String allows passing multiple values for one key" # NoMethodError: undefined method `parse' for CGI
|
31
|
+
fails "CGI.parse when passed String parses a HTTP Query String into a Hash" # NoMethodError: undefined method `parse' for CGI
|
32
|
+
fails "CGI.parse when passed String parses query strings with semicolons in place of ampersands" # NoMethodError: undefined method `parse' for CGI
|
33
|
+
fails "CGI.parse when passed String unescapes keys and values" # NoMethodError: undefined method `parse' for CGI
|
34
|
+
fails "CGI.pretty when passed html indents the passed html String with two spaces" # NoMethodError: undefined method `pretty' for CGI
|
35
|
+
fails "CGI.pretty when passed html, indentation_unit indents the passed html String with the passed indentation_unit" # NoMethodError: undefined method `pretty' for CGI
|
36
|
+
fails "CGI.rfc1123_date when passed Time returns the passed Time formatted in RFC1123 ('Sat, 01 Dec 2007 15:56:42 GMT')" # NoMethodError: undefined method `rfc1123_date' for CGI
|
37
|
+
fails "CGI.unescape url-decodes the passed argument" # Expected "+!\"%23%24%%26'()*%2B%2C-.%2F0123456789%3A%3B<%3D>%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" == " !\"\#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" to be truthy but was false
|
38
|
+
fails "CGI.unescapeElement when passed String, elements, ... is case-insensitive" # NoMethodError: undefined method `unescapeElement' for CGI
|
39
|
+
fails "CGI.unescapeElement when passed String, elements, ... unescapes only the tags of the passed elements in the passed String" # NoMethodError: undefined method `unescapeElement' for CGI
|
40
|
+
end
|
data/spec/filters/bugs/kernel.rb
CHANGED
@@ -36,7 +36,6 @@ opal_filter "Kernel" do
|
|
36
36
|
fails "Kernel#class returns the class of the object" # Expected Number to be identical to Integer
|
37
37
|
fails "Kernel#clone replaces a singleton object's metaclass with a new copy with the same superclass" # NoMethodError: undefined method `singleton_methods' for #<#<Class:0x5537a>:0x55378>
|
38
38
|
fails "Kernel#clone uses the internal allocator and does not call #allocate" # RuntimeError: allocate should not be called
|
39
|
-
fails "Kernel#define_singleton_method when given an UnboundMethod will raise when attempting to define an object's singleton method from another object's singleton method" # Expected TypeError but no exception was raised ("other_singleton_method" was returned)
|
40
39
|
fails "Kernel#dup uses the internal allocator and does not call #allocate" # RuntimeError: allocate should not be called
|
41
40
|
fails "Kernel#eval allows a binding to be captured inside an eval" # NoMethodError: undefined method `w' for #<MSpecEnv:0x4be5a>
|
42
41
|
fails "Kernel#eval allows creating a new class in a binding" # RuntimeError: Evaluation on a Proc#binding is not supported
|
data/spec/filters/bugs/method.rb
CHANGED
@@ -27,8 +27,6 @@ opal_filter "Method" do
|
|
27
27
|
fails "Method#curry with optional arity argument raises ArgumentError when the method requires less arguments than the given arity" # Expected ArgumentError but no exception was raised (#<Proc:0x7c68a> was returned)
|
28
28
|
fails "Method#curry with optional arity argument raises ArgumentError when the method requires more arguments than the given arity" # Expected ArgumentError but no exception was raised (#<Proc:0x7c66a> was returned)
|
29
29
|
fails "Method#define_method when passed a Proc object and a method is defined inside defines the nested method in the default definee where the Proc was created" # Expected #<#<Class:0x51aa0>:0x51a9c> NOT to have method 'nested_method_in_proc_for_define_method' but it does
|
30
|
-
fails "Method#define_method when passed an UnboundMethod object defines a method with the same #arity as the original" # Expected -1 == -3 to be truthy but was false
|
31
|
-
fails "Method#define_method when passed an UnboundMethod object defines a method with the same #parameters as the original" # Expected [["rest", "args"]] == [["req", "a"], ["req", "b"], ["rest", "c"]] to be truthy but was false
|
32
30
|
fails "Method#eql? missing methods returns true for the same method missing" # NameError: undefined method `handled_via_method_missing' for class `MethodSpecs::Methods'
|
33
31
|
fails "Method#eql? returns true if a method was defined using the other one" # Expected false to be true
|
34
32
|
fails "Method#eql? returns true if methods are the same" # Expected false to be true
|
@@ -54,7 +52,6 @@ opal_filter "Method" do
|
|
54
52
|
fails "Method#source_location for a Method generated by respond_to_missing? returns nil" # NameError: undefined method `handled_via_method_missing' for class `MethodSpecs::Methods'
|
55
53
|
fails "Method#source_location sets the first value to the path of the file in which the method was defined" # Expected "ruby/core/method/fixtures/classes.rb" == "./ruby/core/method/fixtures/classes.rb" to be truthy but was false
|
56
54
|
fails "Method#source_location works for eval with a given line" # Expected ["(eval)", 0] == ["foo", 100] to be truthy but was false
|
57
|
-
fails "Method#source_location works for methods defined with an UnboundMethod" # Expected "<internal:corelib/module.rb>" =~ /ruby\/core\/method\/source_location_spec.rb/ to be truthy but was nil
|
58
55
|
fails "Method#super_method after aliasing an inherited method returns the expected super_method" # NoMethodError: undefined method `super_method' for #<Method: MethodSpecs::InheritedMethods::C#meow (defined in MethodSpecs::InheritedMethods::C in ruby/core/method/fixtures/classes.rb:233)>
|
59
56
|
fails "Method#super_method after changing an inherited methods visibility returns the expected super_method" # NoMethodError: undefined method `super_method' for #<Method: MethodSpecs::InheritedMethods::C#derp (defined in MethodSpecs::InheritedMethods::B in ruby/core/method/fixtures/classes.rb:233)>
|
60
57
|
fails "Method#super_method returns nil when the parent's method is removed" # NoMethodError: undefined method `super_method' for #<Method: #<Class:0x50682>#overridden (defined in #<Class:0x50682> in ruby/core/method/super_method_spec.rb:36)>
|
data/spec/filters/bugs/module.rb
CHANGED
@@ -87,18 +87,9 @@ opal_filter "Module" do
|
|
87
87
|
fails "Module#const_source_location works for eval with a given line" # NoMethodError: undefined method `const_source_location' for #<Class:0x2f66a>
|
88
88
|
fails "Module#constants doesn't returns inherited constants when passed nil" # Expected ["CS_CONST10", "CS_CONST10_LINE", "CS_CONST23", "CS_CONST24", "CS_CONST5", "ChildA"] == ["CS_CONST10", "CS_CONST10_LINE", "CS_CONST23", "CS_CONST5", "ChildA"] to be truthy but was false
|
89
89
|
fails "Module#constants returns only public constants" # Expected ["PRIVATE_CONSTANT", "PUBLIC_CONSTANT"] == ["PUBLIC_CONSTANT"] to be truthy but was false
|
90
|
-
fails "Module#define_method converts non-String name to String with #to_str" # NoMethodError: undefined method `foo' for #<#<Class:0x33ce6>:0x33ce4>
|
91
90
|
fails "Module#define_method defines the new method according to the scope visibility when a Method passed and the class/module of the context is equal to the receiver of #define_method" # Expected NoMethodError but no exception was raised (nil was returned)
|
92
91
|
fails "Module#define_method passed { |a,| } creates a method that does not destructure the passed argument" # Expected [1, 2] == 1 to be truthy but was false
|
93
|
-
fails "Module#define_method raises TypeError
|
94
|
-
fails "Module#define_method raises TypeError when #to_str called on non-String name returns non-String value" # Expected TypeError (/can't convert Object to String/) but no exception was raised (#<Class:0x33d52> was returned)
|
95
|
-
fails "Module#define_method raises a TypeError when a Method from a singleton class is defined on another class" # Expected TypeError (/can't bind singleton method to a different class/) but no exception was raised (#<Class:0x33cdc> was returned)
|
96
|
-
fails "Module#define_method raises a TypeError when a Method from one class is defined on an unrelated class" # Expected TypeError but no exception was raised (#<Class:0x33d6c> was returned)
|
97
|
-
fails "Module#define_method raises a TypeError when an UnboundMethod from a child class is defined on a parent class" # Expected TypeError (/bind argument must be a subclass of ChildClass/) but no exception was raised ("foo" was returned)
|
98
|
-
fails "Module#define_method raises a TypeError when an UnboundMethod from a singleton class is defined on another class" # Expected TypeError (/can't bind singleton method to a different class/) but no exception was raised (#<Class:0x33cac> was returned)
|
99
|
-
fails "Module#define_method raises a TypeError when an UnboundMethod from one class is defined on an unrelated class" # Expected TypeError (/bind argument must be a subclass of ModuleSpecs::InstanceMeth/) but no exception was raised (DestinationClass was returned)
|
100
|
-
fails "Module#define_method raises a TypeError when the given method is no Method/Proc" # Expected TypeError (wrong argument type String (expected Proc/Method/UnboundMethod)) but got: TypeError (wrong argument type NilClass (expected Proc/Method))
|
101
|
-
fails "Module#define_method uses provided Method/Proc even if block is specified" # Expected "block_is_called" == "method_is_called" to be truthy but was false
|
92
|
+
fails "Module#define_method raises a TypeError when the given method is no Method/Proc" # Expected TypeError (wrong argument type Integer (expected Proc/Method/UnboundMethod)) but got: TypeError (wrong argument type Number (expected Proc/Method/UnboundMethod))
|
102
93
|
fails "Module#deprecate_constant accepts multiple symbols and strings as constant names" # NoMethodError: undefined method `deprecate_constant' for #<Module:0x3bf08>
|
103
94
|
fails "Module#deprecate_constant raises a NameError when given an undefined name" # NoMethodError: undefined method `deprecate_constant' for #<Module:0x3bf04>
|
104
95
|
fails "Module#deprecate_constant returns self" # NoMethodError: undefined method `deprecate_constant' for #<Module:0x3bf0c>
|
data/spec/filters/bugs/range.rb
CHANGED
@@ -50,22 +50,12 @@ opal_filter "Range" do
|
|
50
50
|
fails "Range#bsearch with endless ranges and Integer values with a block returning negative, zero, positive numbers returns nil if the block returns less than zero for every element" # NotImplementedError: Can't #bsearch an infinite range
|
51
51
|
fails "Range#bsearch with endless ranges and Integer values with a block returning true or false returns minimum element if the block returns true for every element" # NotImplementedError: Can't #bsearch an infinite range
|
52
52
|
fails "Range#bsearch with endless ranges and Integer values with a block returning true or false returns the smallest element for which block returns true" # NotImplementedError: Can't #bsearch an infinite range
|
53
|
-
fails "Range#cover?
|
54
|
-
fails "Range#cover? accepts endless range argument" # Expected false to be true
|
55
|
-
fails "Range#cover? allows self to be a beginless range" # Expected false to be true
|
56
|
-
fails "Range#cover? allows self to be a endless range" # Expected false to be true
|
57
|
-
fails "Range#cover? range argument accepts range argument" # Expected false to be true
|
58
|
-
fails "Range#cover? range argument honors exclusion of right boundary (:exclude_end option)" # Expected false to be true
|
59
|
-
fails "Range#cover? range argument supports boundaries of different comparable types" # Expected false to be true
|
53
|
+
fails "Range#cover? range argument honors exclusion of right boundary (:exclude_end option)" # Expected true to be false
|
60
54
|
fails "Range#eql? returns false if the endpoints are not eql?" # Expected 0..1 not to have same value or type as 0..1
|
61
55
|
fails "Range#first raises a TypeError if #to_int does not return an Integer" # Expected TypeError but no exception was raised ([2] was returned)
|
62
56
|
fails "Range#frozen? is true for Range.new" # Expected 1..2.frozen? to be truthy but was false
|
63
57
|
fails "Range#frozen? is true for literal ranges" # Expected 1..2.frozen? to be truthy but was false
|
64
58
|
fails "Range#include? does not include U+9995 in the range U+0999..U+9999" # Expected true to be false
|
65
|
-
fails "Range#include? on string elements returns false if other is not matched by element.succ" # Expected true to be false
|
66
|
-
fails "Range#include? with weird succ when excluded end value returns false if other is not matched by element.succ" # Expected true to be false
|
67
|
-
fails "Range#include? with weird succ when included end value returns false if other is equal as last element but not matched by element.succ" # Expected true to be false
|
68
|
-
fails "Range#include? with weird succ when included end value returns false if other is not matched by element.succ" # Expected true to be false
|
69
59
|
fails "Range#initialize raises a FrozenError if called on an already initialized Range" # Expected FrozenError but got: NameError ('initialize' called twice)
|
70
60
|
fails "Range#inspect works for nil ... nil ranges" # Expected ".." == "nil..nil" to be truthy but was false
|
71
61
|
fails "Range#last raises a TypeError if #to_int does not return an Integer" # Expected TypeError but no exception was raised ([3] was returned)
|
@@ -75,10 +65,6 @@ opal_filter "Range" do
|
|
75
65
|
fails "Range#max raises TypeError when called on an exclusive range and a non Integer value" # Expected TypeError but no exception was raised (907.1111 was returned)
|
76
66
|
fails "Range#max raises for an exclusive beginless range" # Expected TypeError (cannot exclude end value with non Integer begin value) but no exception was raised (0 was returned)
|
77
67
|
fails "Range#max returns the maximum value in the range when called with no arguments" # Expected NaN == "e" to be truthy but was false
|
78
|
-
fails "Range#member? on string elements returns false if other is not matched by element.succ" # Expected true to be false
|
79
|
-
fails "Range#member? with weird succ when excluded end value returns false if other is not matched by element.succ" # Expected true to be false
|
80
|
-
fails "Range#member? with weird succ when included end value returns false if other is equal as last element but not matched by element.succ" # Expected true to be false
|
81
|
-
fails "Range#member? with weird succ when included end value returns false if other is not matched by element.succ" # Expected true to be false
|
82
68
|
fails "Range#min given a block calls #> and #< on the return value of the block" # Mock 'obj' expected to receive >("any_args") exactly 2 times but received it 0 times
|
83
69
|
fails "Range#minmax on an exclusive range raises TypeError if the end value is not an integer" # Expected TypeError (cannot exclude non Integer end value) but got: TypeError (can't iterate from Float)
|
84
70
|
fails "Range#minmax on an exclusive range should raise RangeError on a beginless range" # Expected RangeError (/cannot get the maximum of beginless range with custom comparison method|cannot get the minimum of beginless range/) but got: TypeError (can't iterate from NilClass)
|
@@ -99,7 +85,7 @@ opal_filter "Range" do
|
|
99
85
|
fails "Range#to_a works with Ranges of 64-bit integers" # Expected [256, 257] == [1099511627776, 1099511627777] to be truthy but was false
|
100
86
|
fails "Range#to_s can show beginless ranges" # Expected "...1" == "...1.0" to be truthy but was false
|
101
87
|
fails "Range#to_s can show endless ranges" # Expected "1..." == "1.0..." to be truthy but was false
|
102
|
-
fails "Range.new beginless/endless range creates a frozen range if the class is Range.class" # Expected 1..2.frozen? to be truthy but was false
|
88
|
+
fails "Range.new beginless/endless range creates a frozen range if the class is Range.class" # Expected 1..2.frozen? to be truthy but was false
|
103
89
|
fails_badly "Range#min given a block raises RangeError when called with custom comparison method on an endless range" # Expected RangeError but got: Opal::SyntaxError (undefined method `type' for nil)
|
104
90
|
fails_badly "Range#minmax on an exclusive range should return the minimum and maximum values for a numeric range without iterating the range"
|
105
91
|
fails_badly "Range#step with an endless range and String values raises a TypeError when passed a Float step" # Expected TypeError but got: Opal::SyntaxError (undefined method `type' for nil)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Module#define_method" do
|
4
|
+
describe "when passed an UnboundMethod object" do
|
5
|
+
it "defines a method taking a block" do
|
6
|
+
klass = Class.new do
|
7
|
+
def foo = yield :bar
|
8
|
+
end
|
9
|
+
klass.define_method(:baz, klass.instance_method(:foo))
|
10
|
+
klass.new.baz { |a| a }.should == :bar
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "when called inside a def" do
|
15
|
+
it "returns correctly" do
|
16
|
+
klass = Class.new do
|
17
|
+
def self.my_method_definer
|
18
|
+
define_method(:a) do
|
19
|
+
return :foo
|
20
|
+
:bar
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
klass.my_method_definer
|
26
|
+
klass.new.a.should == :foo
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/ruby_specs
CHANGED
data/stdlib/cgi/util.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# backtick_javascript: true
|
2
|
+
|
3
|
+
# This file contains parts of https://github.com/ruby/ruby/blob/master/lib/cgi/util.rb
|
4
|
+
# licensed under a Ruby license.
|
5
|
+
|
6
|
+
class CGI
|
7
|
+
module Util
|
8
|
+
# URL-encode a string into application/x-www-form-urlencoded.
|
9
|
+
# Space characters (+" "+) are encoded with plus signs (+"+"+)
|
10
|
+
# url_encoded_string = CGI.escape("'Stop!' said Fred")
|
11
|
+
# # => "%27Stop%21%27+said+Fred"
|
12
|
+
def escape(c)
|
13
|
+
`encodeURI(c)`
|
14
|
+
end
|
15
|
+
|
16
|
+
# URL-decode an application/x-www-form-urlencoded string with encoding(optional).
|
17
|
+
# string = CGI.unescape("%27Stop%21%27+said+Fred")
|
18
|
+
# # => "'Stop!' said Fred"
|
19
|
+
def unescape(c)
|
20
|
+
`decodeURI(c)`
|
21
|
+
end
|
22
|
+
|
23
|
+
# URL-encode a string following RFC 3986
|
24
|
+
# Space characters (+" "+) are encoded with (+"%20"+)
|
25
|
+
# url_encoded_string = CGI.escapeURIComponent("'Stop!' said Fred")
|
26
|
+
# # => "%27Stop%21%27%20said%20Fred"
|
27
|
+
def escapeURIComponent(c)
|
28
|
+
`encodeURIComponent(c)`
|
29
|
+
end
|
30
|
+
|
31
|
+
# URL-decode a string following RFC 3986 with encoding(optional).
|
32
|
+
# string = CGI.unescapeURIComponent("%27Stop%21%27+said%20Fred")
|
33
|
+
# # => "'Stop!'+said Fred"
|
34
|
+
def unescapeURIComponent(c)
|
35
|
+
`decodeURIComponent(c)`
|
36
|
+
end
|
37
|
+
|
38
|
+
# The set of special characters and their escaped values
|
39
|
+
TABLE_FOR_ESCAPE_HTML__ = {
|
40
|
+
"'" => ''',
|
41
|
+
'&' => '&',
|
42
|
+
'"' => '"',
|
43
|
+
'<' => '<',
|
44
|
+
'>' => '>',
|
45
|
+
}
|
46
|
+
|
47
|
+
# Escape special characters in HTML, namely '&\"<>
|
48
|
+
# CGI.escapeHTML('Usage: foo "bar" <baz>')
|
49
|
+
# # => "Usage: foo "bar" <baz>"
|
50
|
+
def escapeHTML(string)
|
51
|
+
string.gsub(/['&"<>]/, TABLE_FOR_ESCAPE_HTML__)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Unescape a string that has been HTML-escaped
|
55
|
+
# CGI.unescapeHTML("Usage: foo "bar" <baz>")
|
56
|
+
# # => "Usage: foo \"bar\" <baz>"
|
57
|
+
def unescapeHTML(string)
|
58
|
+
string.gsub(/&(apos|amp|quot|gt|lt|\#[0-9]+|\#[xX][0-9A-Fa-f]+);/) do
|
59
|
+
match = ::Regexp.last_match(1)
|
60
|
+
case match
|
61
|
+
when 'apos' then "'"
|
62
|
+
when 'amp' then '&'
|
63
|
+
when 'quot' then '"'
|
64
|
+
when 'gt' then '>'
|
65
|
+
when 'lt' then '<'
|
66
|
+
when /\A#0*(\d+)\z/
|
67
|
+
n = ::Regexp.last_match(1).to_i
|
68
|
+
n.chr('utf-8')
|
69
|
+
when /\A#x([0-9a-f]+)\z/i
|
70
|
+
n = ::Regexp.last_match(1).hex
|
71
|
+
n.chr('utf-8')
|
72
|
+
else
|
73
|
+
"&#{match};"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Synonym for CGI.escapeHTML(str)
|
79
|
+
alias escape_html escapeHTML
|
80
|
+
|
81
|
+
# Synonym for CGI.unescapeHTML(str)
|
82
|
+
alias unescape_html unescapeHTML
|
83
|
+
|
84
|
+
alias h escapeHTML
|
85
|
+
end
|
86
|
+
|
87
|
+
include Util
|
88
|
+
extend Util
|
89
|
+
end
|
data/stdlib/cgi.rb
CHANGED
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.8.0
|
4
|
+
version: 1.8.0
|
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: 2023-10-
|
13
|
+
date: 2023-10-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: ast
|
@@ -706,6 +706,7 @@ files:
|
|
706
706
|
- spec/filters/bugs/basicobject.rb
|
707
707
|
- spec/filters/bugs/bigdecimal.rb
|
708
708
|
- spec/filters/bugs/binding.rb
|
709
|
+
- spec/filters/bugs/cgi.rb
|
709
710
|
- spec/filters/bugs/class.rb
|
710
711
|
- spec/filters/bugs/complex.rb
|
711
712
|
- spec/filters/bugs/date.rb
|
@@ -924,6 +925,7 @@ files:
|
|
924
925
|
- spec/opal/core/language_spec.rb
|
925
926
|
- spec/opal/core/marshal/dump_spec.rb
|
926
927
|
- spec/opal/core/marshal/load_spec.rb
|
928
|
+
- spec/opal/core/module/define_method_spec.rb
|
927
929
|
- spec/opal/core/module_spec.rb
|
928
930
|
- spec/opal/core/number/to_i_spec.rb
|
929
931
|
- spec/opal/core/number/to_s_spec.rb
|
@@ -1013,6 +1015,7 @@ files:
|
|
1013
1015
|
- stdlib/buffer/array.rb
|
1014
1016
|
- stdlib/buffer/view.rb
|
1015
1017
|
- stdlib/cgi.rb
|
1018
|
+
- stdlib/cgi/util.rb
|
1016
1019
|
- stdlib/console.rb
|
1017
1020
|
- stdlib/date.rb
|
1018
1021
|
- stdlib/date/date_time.rb
|
@@ -1225,10 +1228,10 @@ licenses:
|
|
1225
1228
|
metadata:
|
1226
1229
|
homepage_uri: https://opalrb.com/
|
1227
1230
|
bug_tracker_uri: https://github.com/opal/opal/issues
|
1228
|
-
changelog_uri: https://github.com/opal/opal/blob/v1.8.0
|
1229
|
-
readme_uri: https://github.com/opal/opal/blob/v1.8.0
|
1230
|
-
api_documentation_uri: http://opalrb.com/docs/api/v1.8.0
|
1231
|
-
guides_uri: http://opalrb.com/docs/guides/v1.8.0
|
1231
|
+
changelog_uri: https://github.com/opal/opal/blob/v1.8.0/CHANGELOG.md
|
1232
|
+
readme_uri: https://github.com/opal/opal/blob/v1.8.0/README.md
|
1233
|
+
api_documentation_uri: http://opalrb.com/docs/api/v1.8.0/index.html
|
1234
|
+
guides_uri: http://opalrb.com/docs/guides/v1.8.0/index.html
|
1232
1235
|
chat_uri: https://gitter.im/opal/opal
|
1233
1236
|
source_code_uri: https://github.com/opal/opal
|
1234
1237
|
post_install_message:
|
@@ -1242,9 +1245,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
1242
1245
|
version: '2.3'
|
1243
1246
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
1244
1247
|
requirements:
|
1245
|
-
- - "
|
1248
|
+
- - ">="
|
1246
1249
|
- !ruby/object:Gem::Version
|
1247
|
-
version:
|
1250
|
+
version: '0'
|
1248
1251
|
requirements: []
|
1249
1252
|
rubygems_version: 3.4.5
|
1250
1253
|
signing_key:
|
@@ -1707,6 +1710,7 @@ test_files:
|
|
1707
1710
|
- stdlib/buffer/array.rb
|
1708
1711
|
- stdlib/buffer/view.rb
|
1709
1712
|
- stdlib/cgi.rb
|
1713
|
+
- stdlib/cgi/util.rb
|
1710
1714
|
- stdlib/console.rb
|
1711
1715
|
- stdlib/date.rb
|
1712
1716
|
- stdlib/date/date_time.rb
|