opal 1.8.0.beta1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 506ba9114548fa5c492467950421043dbf46d0b72df49eab40c5a62e6f6c2ce6
4
- data.tar.gz: e59c280933851d6de0a63f42b19139e5b16c90f68fe0c4652cf555a5ef7e1968
3
+ metadata.gz: ea935af6a628e09fb047d39c25422f717a4a4b9ef442fe7ec06183134b3163a1
4
+ data.tar.gz: d539d6a55c69651064a272a6110498bdba7d2146fa08704f4e759ee7693c28b2
5
5
  SHA512:
6
- metadata.gz: 8536d4701b9197c3cee876bb35bb3fd34cee5726241069d108fa12f8c83753c43d8bc6ac8f95fd867ee5da23ba98b2c8a1b3e284a56df7b6656ffa17850b36c4
7
- data.tar.gz: b0f0283471809563e3ea29afcef0b911109aa7d9d9a1f04701c34f48facc8654f20cacc3bd7061273bf74d837c7ae1256d13249e1eb9371e6faa94e3f54fa22b
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.7.3](https://github.com/opal/opal/compare/v1.7.2...v1.7.3) - 2023-03-23
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
@@ -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.0.beta1'
6
+ VERSION = '1.8.0'
7
7
  end
@@ -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.beta1'
5
- ::RUBY_RELEASE_DATE = '2023-10-12'
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
- return $hash_clone(self, hash);
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
@@ -77,6 +77,7 @@ class ::UnboundMethod
77
77
  @owner = owner
78
78
  @method = method
79
79
  @name = name
80
+ `self.$$method = method`
80
81
  end
81
82
 
82
83
  def arity
@@ -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
- block ||= case method
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
- ->(*args) {
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 #{block.class} (expected Proc/Method)"
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, "$" + names[i]);
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.wrapMethodBody(body);
764
+ wrapped = Opal.wrap_method_body(body);
744
765
 
745
766
  wrapped.$$jsid = name;
746
767
  Opal.defn(to, jsid, wrapped);
@@ -19,7 +19,8 @@ class ::Range
19
19
  end
20
20
 
21
21
  def ===(value)
22
- include? value
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
- beg_cmp = (@begin.nil? && -1) || (@begin <=> value) || false
48
- end_cmp = (@end.nil? && -1) || (value <=> @end) || false
49
- if @excl
50
- end_cmp && end_cmp < 0
51
- else
52
- end_cmp && end_cmp <= 0
53
- end && beg_cmp && beg_cmp <= 0
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 include? cover?
323
- alias member? cover?
367
+ alias member? include?
324
368
  end
@@ -940,7 +940,7 @@
940
940
  };
941
941
 
942
942
  Opal.instance_methods = function(mod) {
943
- var exclude = [], results = [], ancestors = $ancestors(mod);
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 method_name = prop.slice(1),
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 && results.indexOf(method_name) === -1 && exclude.indexOf(method_name) === -1) {
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.wrapMethodBody(body);
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.wrapMethodBody = function(body) {
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
@@ -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
@@ -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)>
@@ -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 if name cannot converted to String" # Expected TypeError (/is not a symbol nor a string/) but no exception was raised (#<Class:0x33da2> was returned)
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>
@@ -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? accepts beginless range argument" # Expected false to be true
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
@@ -177,6 +177,7 @@ ruby/language
177
177
  ruby/library/base64
178
178
  ruby/library/bigdecimal
179
179
  !ruby/library/bigdecimal/util_spec
180
+ ruby/library/cgi
180
181
  ruby/library/date
181
182
  ruby/library/datetime
182
183
  ruby/library/delegate/delegate_class
@@ -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
+ "'" => '&#39;',
41
+ '&' => '&amp;',
42
+ '"' => '&quot;',
43
+ '<' => '&lt;',
44
+ '>' => '&gt;',
45
+ }
46
+
47
+ # Escape special characters in HTML, namely '&\"<>
48
+ # CGI.escapeHTML('Usage: foo "bar" <baz>')
49
+ # # => "Usage: foo &quot;bar&quot; &lt;baz&gt;"
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 &quot;bar&quot; &lt;baz&gt;")
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
@@ -1,14 +1 @@
1
- class CGI
2
- module Util
3
- def escapeURIComponent(c)
4
- `encodeURI(c)`
5
- end
6
-
7
- def unescapeURIComponent(c)
8
- `decodeURI(c)`
9
- end
10
- end
11
-
12
- include Util
13
- extend Util
14
- end
1
+ require 'cgi/util'
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.beta1
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-12 00:00:00.000000000 Z
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.beta1/CHANGELOG.md
1229
- readme_uri: https://github.com/opal/opal/blob/v1.8.0.beta1/README.md
1230
- api_documentation_uri: http://opalrb.com/docs/api/v1.8.0.beta1/index.html
1231
- guides_uri: http://opalrb.com/docs/guides/v1.8.0.beta1/index.html
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: 1.3.1
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