opal 1.1.1 → 1.2.0.beta1
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 +4 -4
- data/.codeclimate.yml +3 -2
- data/.github/ISSUE_TEMPLATE/bug-report.md +47 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/build.yml +11 -5
- data/.gitignore +1 -0
- data/.jshintrc +1 -1
- data/Gemfile +0 -4
- data/HACKING.md +1 -1
- data/README.md +19 -15
- data/UNRELEASED.md +41 -0
- data/benchmark-ips/bm_array_unshift.rb +7 -0
- data/bin/opal-mspec +2 -0
- data/docs/compiler.md +1 -1
- data/examples/rack/Gemfile +0 -1
- data/examples/rack/Gemfile.lock +0 -4
- data/lib/opal/cli.rb +1 -0
- data/lib/opal/cli_options.rb +4 -0
- data/lib/opal/cli_runners/nodejs.rb +4 -0
- data/lib/opal/cli_runners/source-map-support-browser.js +3 -1
- data/lib/opal/cli_runners/source-map-support-node.js +3 -1
- data/lib/opal/cli_runners/source-map-support.js +3 -1
- data/lib/opal/compiler.rb +2 -2
- data/lib/opal/nodes/args/arity_check.rb +1 -0
- data/lib/opal/nodes/args/parameters.rb +6 -0
- data/lib/opal/nodes/class.rb +1 -13
- data/lib/opal/nodes/literal.rb +14 -7
- data/lib/opal/nodes/module.rb +13 -9
- data/lib/opal/nodes/variables.rb +13 -4
- data/lib/opal/nodes/while.rb +54 -17
- data/lib/opal/parser.rb +1 -5
- data/lib/opal/parser/patch.rb +34 -0
- data/lib/opal/repl.rb +7 -0
- data/lib/opal/rewriter.rb +2 -0
- data/lib/opal/rewriters/arguments.rb +4 -1
- data/lib/opal/rewriters/forward_args.rb +54 -0
- data/lib/opal/rewriters/logical_operator_assignment.rb +5 -2
- data/lib/opal/rewriters/opal_engine_check.rb +5 -7
- data/lib/opal/version.rb +1 -1
- data/opal/corelib/array.rb +42 -20
- data/opal/corelib/array/pack.rb +6 -1
- data/opal/corelib/complex.rb +2 -0
- data/opal/corelib/constants.rb +3 -3
- data/opal/corelib/hash.rb +36 -38
- data/opal/corelib/module.rb +2 -7
- data/opal/corelib/number.rb +2 -180
- data/opal/corelib/numeric.rb +156 -0
- data/opal/corelib/object_space.rb +102 -0
- data/opal/corelib/random.rb +31 -66
- data/opal/corelib/random/formatter.rb +122 -0
- data/opal/corelib/range.rb +50 -19
- data/opal/corelib/runtime.js +82 -21
- data/opal/corelib/string.rb +86 -52
- data/opal/corelib/string/encoding.rb +140 -25
- data/opal/corelib/string/unpack.rb +26 -40
- data/opal/opal.rb +1 -0
- data/opal/opal/full.rb +1 -0
- data/spec/filters/bugs/array.rb +0 -22
- data/spec/filters/bugs/basicobject.rb +3 -0
- data/spec/filters/bugs/encoding.rb +0 -2
- data/spec/filters/bugs/exception.rb +1 -0
- data/spec/filters/bugs/float.rb +0 -2
- data/spec/filters/bugs/hash.rb +2 -7
- data/spec/filters/bugs/integer.rb +0 -2
- data/spec/filters/bugs/kernel.rb +16 -3
- data/spec/filters/bugs/language.rb +6 -14
- data/spec/filters/bugs/marshal.rb +1 -3
- data/spec/filters/bugs/module.rb +16 -1
- data/spec/filters/bugs/numeric.rb +4 -12
- data/spec/filters/bugs/objectspace.rb +67 -0
- data/spec/filters/bugs/pack_unpack.rb +0 -9
- data/spec/filters/bugs/pathname.rb +1 -0
- data/spec/filters/bugs/proc.rb +8 -0
- data/spec/filters/bugs/random.rb +3 -6
- data/spec/filters/bugs/range.rb +83 -113
- data/spec/filters/bugs/set.rb +2 -0
- data/spec/filters/bugs/string.rb +31 -70
- data/spec/filters/bugs/struct.rb +2 -0
- data/spec/filters/bugs/time.rb +8 -2
- data/spec/filters/unsupported/float.rb +3 -0
- data/spec/filters/unsupported/freeze.rb +1 -0
- data/spec/filters/unsupported/integer.rb +3 -0
- data/spec/filters/unsupported/refinements.rb +5 -0
- data/spec/filters/unsupported/string.rb +100 -95
- data/spec/filters/unsupported/time.rb +4 -0
- data/spec/lib/compiler_spec.rb +16 -0
- data/spec/lib/rewriters/forward_args_spec.rb +61 -0
- data/spec/lib/rewriters/logical_operator_assignment_spec.rb +1 -1
- data/spec/lib/rewriters/numblocks_spec.rb +44 -0
- data/spec/lib/rewriters/opal_engine_check_spec.rb +49 -4
- data/spec/opal/core/language/forward_args_spec.rb +53 -0
- data/spec/opal/core/language/infinite_range_spec.rb +13 -0
- data/spec/opal/core/language/memoization_spec.rb +16 -0
- data/spec/opal/core/module_spec.rb +38 -2
- data/spec/opal/core/number/to_i_spec.rb +28 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +16 -0
- data/spec/opal/core/runtime/constants_spec.rb +20 -1
- data/spec/opal/core/string/subclassing_spec.rb +16 -0
- data/spec/opal/core/string/unpack_spec.rb +22 -0
- data/spec/opal/core/string_spec.rb +4 -4
- data/spec/ruby_specs +4 -1
- data/stdlib/json.rb +3 -1
- data/stdlib/securerandom.rb +55 -35
- data/tasks/testing.rake +6 -3
- data/test/nodejs/test_string.rb +25 -0
- data/vendored-minitest/minitest/assertions.rb +2 -0
- metadata +31 -10
- data/lib/opal/parser/with_c_lexer.rb +0 -15
|
@@ -123,6 +123,7 @@ opal_unsupported_filter "Time" do
|
|
|
123
123
|
fails "Time#utc_offset returns the correct offset for US Eastern time zone around daylight savings time change"
|
|
124
124
|
fails "Time#utc_offset returns the offset in seconds between the timezone of time and UTC"
|
|
125
125
|
fails "Time#wday returns an integer representing the day of the week, 0..6, with Sunday being 0"
|
|
126
|
+
fails "Time#yday returns an integer representing the day of the year, 1..366" # Expected 117 == 116
|
|
126
127
|
fails "Time#year returns the four digit year for a Time with a fixed offset"
|
|
127
128
|
fails "Time#year returns the four digit year for a local Time as an Integer"
|
|
128
129
|
fails "Time#zone Encoding.default_internal is set doesn't raise errors for a Time with a fixed offset"
|
|
@@ -201,4 +202,7 @@ opal_unsupported_filter "Time" do
|
|
|
201
202
|
fails "Time.utc ignores fractional seconds if a passed fractional number of microseconds"
|
|
202
203
|
fails "Time.utc ignores fractional seconds if a passed whole number of microseconds"
|
|
203
204
|
fails "Time.utc returns subclass instances"
|
|
205
|
+
fails_badly "Marshal.load for a Time loads the zone" # Seasonal failure
|
|
206
|
+
fails_badly "Time#inspect formats the local time following the pattern 'yyyy-MM-dd HH:mm:ss Z'" # Seasonal failure
|
|
207
|
+
fails_badly "Time#to_s formats the local time following the pattern 'yyyy-MM-dd HH:mm:ss Z'" # Seasonal failure
|
|
204
208
|
end
|
data/spec/lib/compiler_spec.rb
CHANGED
|
@@ -42,6 +42,22 @@ RSpec.describe Opal::Compiler do
|
|
|
42
42
|
expect_compiled('"hello #{100}"').to include('"hello "', '100')
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
+
it "should compile ruby ranges" do
|
|
46
|
+
expect_compiled('1..1').to include('$range(1, 1, false)')
|
|
47
|
+
expect_compiled('1...1').to include('$range(1, 1, true)')
|
|
48
|
+
expect_compiled('..1').to include('$range(nil, 1, false)')
|
|
49
|
+
expect_compiled('...1').to include('$range(nil, 1, true)')
|
|
50
|
+
expect_compiled('1..').to include('$range(1, nil, false)')
|
|
51
|
+
expect_compiled('1...').to include('$range(1, nil, true)')
|
|
52
|
+
# Following return Opal.range.$new instead of $range. Some also miss a space.
|
|
53
|
+
expect_compiled('nil..1').to include('(nil, 1, false)')
|
|
54
|
+
expect_compiled('nil...1').to include('(nil,1, true)')
|
|
55
|
+
expect_compiled('"a"..nil').to include('("a", nil, false)')
|
|
56
|
+
expect_compiled('"a"...nil').to include('("a",nil, true)')
|
|
57
|
+
expect_compiled('..nil').to include('(nil, nil, false)')
|
|
58
|
+
expect_compiled('...nil').to include('(nil,nil, true)')
|
|
59
|
+
end
|
|
60
|
+
|
|
45
61
|
it "should compile method calls" do
|
|
46
62
|
expect_compiled("self.inspect").to include("$inspect()")
|
|
47
63
|
expect_compiled("self.map { |a| a + 10 }").to include("$map")
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'lib/spec_helper'
|
|
2
|
+
require 'support/rewriters_helper'
|
|
3
|
+
require 'opal/rewriters/forward_args'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Opal::Rewriters::ForwardArgs do
|
|
6
|
+
include RewritersHelper
|
|
7
|
+
extend RewritersHelper
|
|
8
|
+
|
|
9
|
+
before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
|
|
10
|
+
|
|
11
|
+
correct_names = proc do |ast|
|
|
12
|
+
case ast
|
|
13
|
+
when Opal::AST::Node
|
|
14
|
+
ast.children.map do |i|
|
|
15
|
+
correct_names.(i)
|
|
16
|
+
end.yield_self { |children| s(ast.type, *children) }
|
|
17
|
+
when :fwd_rest
|
|
18
|
+
"$fwd_rest"
|
|
19
|
+
when :fwd_block
|
|
20
|
+
"$fwd_block"
|
|
21
|
+
else
|
|
22
|
+
ast
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
|
|
27
|
+
def forward(...)
|
|
28
|
+
other(...)
|
|
29
|
+
end
|
|
30
|
+
ENDSOURCE
|
|
31
|
+
def forward(*fwd_rest, &fwd_block)
|
|
32
|
+
other(*fwd_rest, &fwd_block)
|
|
33
|
+
end
|
|
34
|
+
ENDDEST
|
|
35
|
+
|
|
36
|
+
include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
|
|
37
|
+
def forward(first_arg, ...)
|
|
38
|
+
other(first_arg, second_arg, ...)
|
|
39
|
+
other(other_arg, ...)
|
|
40
|
+
other(...)
|
|
41
|
+
end
|
|
42
|
+
ENDSOURCE
|
|
43
|
+
def forward(first_arg, *fwd_rest, &fwd_block)
|
|
44
|
+
other(first_arg, second_arg, *fwd_rest, &fwd_block)
|
|
45
|
+
other(other_arg, *fwd_rest, &fwd_block)
|
|
46
|
+
other(*fwd_rest, &fwd_block)
|
|
47
|
+
end
|
|
48
|
+
ENDDEST
|
|
49
|
+
|
|
50
|
+
# Not supported by the parser (nor by the rewriter which would have to rearrange the arguments)
|
|
51
|
+
|
|
52
|
+
# include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
|
|
53
|
+
# def forward(a:, ...)
|
|
54
|
+
# other(...)
|
|
55
|
+
# end
|
|
56
|
+
# ENDSOURCE
|
|
57
|
+
# def forward(*fwd_rest, a:, &fwd_block)
|
|
58
|
+
# other(*fwd_rest, &fwd_block)
|
|
59
|
+
# end
|
|
60
|
+
# ENDDEST
|
|
61
|
+
end
|
|
@@ -57,7 +57,7 @@ RSpec.describe Opal::Rewriters::LogicalOperatorAssignment do
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
context 'class variable' do
|
|
60
|
-
include_examples 'it rewrites', '@@a ||= 1', '@@a = @@a || 1'
|
|
60
|
+
include_examples 'it rewrites', '@@a ||= 1', '@@a = defined?(@@a) ? (@@a || 1) : 1'
|
|
61
61
|
include_examples 'it rewrites', '@@a &&= 1', '@@a = @@a && 1'
|
|
62
62
|
end
|
|
63
63
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require 'lib/spec_helper'
|
|
2
|
+
require 'support/rewriters_helper'
|
|
3
|
+
require 'opal/rewriters/numblocks'
|
|
4
|
+
|
|
5
|
+
RSpec.describe Opal::Rewriters::Numblocks do
|
|
6
|
+
include RewritersHelper
|
|
7
|
+
extend RewritersHelper
|
|
8
|
+
|
|
9
|
+
before(:each) { Opal::Rewriters::ForRewriter.reset_tmp_counter! }
|
|
10
|
+
|
|
11
|
+
correct_names = proc do |ast|
|
|
12
|
+
case ast
|
|
13
|
+
when Opal::AST::Node
|
|
14
|
+
ast.children.map do |i|
|
|
15
|
+
correct_names.(i)
|
|
16
|
+
end.yield_self { |children| s(ast.type, *children) }
|
|
17
|
+
when :arg1 then :_1
|
|
18
|
+
when :arg2 then :_2
|
|
19
|
+
when :arg3 then :_3
|
|
20
|
+
else
|
|
21
|
+
ast
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
|
|
26
|
+
proc do
|
|
27
|
+
_1
|
|
28
|
+
end
|
|
29
|
+
ENDSOURCE
|
|
30
|
+
proc do |arg1|
|
|
31
|
+
arg1
|
|
32
|
+
end
|
|
33
|
+
ENDDEST
|
|
34
|
+
|
|
35
|
+
include_examples 'it rewrites source-to-AST', <<~ENDSOURCE, correct_names.(parse(<<~ENDDEST))
|
|
36
|
+
proc do
|
|
37
|
+
_3
|
|
38
|
+
end
|
|
39
|
+
ENDSOURCE
|
|
40
|
+
proc do |arg1, arg2, arg3|
|
|
41
|
+
arg3
|
|
42
|
+
end
|
|
43
|
+
ENDDEST
|
|
44
|
+
end
|
|
@@ -30,11 +30,11 @@ RSpec.describe Opal::Rewriters::OpalEngineCheck do
|
|
|
30
30
|
s(:send, ruby_const_sexp, :==, opal_str_sexp)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
it 'replaces
|
|
33
|
+
it 'replaces the expression with the true branch' do
|
|
34
34
|
expect_rewritten(
|
|
35
35
|
s(:if, check, true_branch, false_branch)
|
|
36
36
|
).to eq(
|
|
37
|
-
|
|
37
|
+
true_branch
|
|
38
38
|
)
|
|
39
39
|
end
|
|
40
40
|
end
|
|
@@ -58,11 +58,11 @@ RSpec.describe Opal::Rewriters::OpalEngineCheck do
|
|
|
58
58
|
s(:send, ruby_const_sexp, :!=, opal_str_sexp)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
it 'replaces
|
|
61
|
+
it 'replaces the expression with the false branch' do
|
|
62
62
|
expect_rewritten(
|
|
63
63
|
s(:if, check, true_branch, false_branch)
|
|
64
64
|
).to eq(
|
|
65
|
-
|
|
65
|
+
false_branch
|
|
66
66
|
)
|
|
67
67
|
end
|
|
68
68
|
end
|
|
@@ -79,6 +79,51 @@ RSpec.describe Opal::Rewriters::OpalEngineCheck do
|
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
|
+
|
|
83
|
+
it 'supports nested blocks' do
|
|
84
|
+
expect_rewritten(
|
|
85
|
+
# if true
|
|
86
|
+
# if RUBY_ENGINE == 'opal'
|
|
87
|
+
# if RUBY_ENGINE == 'opal'
|
|
88
|
+
# :a
|
|
89
|
+
# end
|
|
90
|
+
# if RUBY_ENGINE != 'opal'
|
|
91
|
+
# :b
|
|
92
|
+
# end
|
|
93
|
+
# end
|
|
94
|
+
# end
|
|
95
|
+
|
|
96
|
+
s(:if,
|
|
97
|
+
s(:true),
|
|
98
|
+
s(:if,
|
|
99
|
+
s(:send, ruby_const_sexp, :==, opal_str_sexp),
|
|
100
|
+
s(:begin,
|
|
101
|
+
s(:if,
|
|
102
|
+
s(:send, ruby_const_sexp, :==, opal_str_sexp),
|
|
103
|
+
s(:sym, :a)
|
|
104
|
+
),
|
|
105
|
+
s(:if,
|
|
106
|
+
s(:send, ruby_const_sexp, :!=, opal_str_sexp),
|
|
107
|
+
s(:sym, :b)
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
).to eq(
|
|
113
|
+
# if true
|
|
114
|
+
# :a
|
|
115
|
+
# nil
|
|
116
|
+
# end
|
|
117
|
+
|
|
118
|
+
s(:if,
|
|
119
|
+
s(:true),
|
|
120
|
+
s(:begin,
|
|
121
|
+
s(:sym, :a),
|
|
122
|
+
s(:nil)
|
|
123
|
+
)
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
end
|
|
82
127
|
end
|
|
83
128
|
end
|
|
84
129
|
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
describe "Forward arguments" do
|
|
2
|
+
it "forwards args, kwargs and blocks" do
|
|
3
|
+
def fwd_t1_pass1(...)
|
|
4
|
+
fwd_t1_pass2(...)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def fwd_t1_pass2(*args, **kwargs, &block)
|
|
8
|
+
[args.count, kwargs.count, block_given?]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
fwd_t1_pass1(1, 2, 3, a: 1, b: 2).should == [3, 2, false]
|
|
12
|
+
fwd_t1_pass1(1, 2, &:itself).should == [2, 0, true]
|
|
13
|
+
fwd_t1_pass1(a: 1, b: 2).should == [0, 2, false]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "supports forwarding with initial arguments (3.0 behavior)" do
|
|
17
|
+
def fwd_t2_pass1(initial, ...)
|
|
18
|
+
fwd_t2_pass2(0, initial + 1, ...)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def fwd_t2_pass2(a, b, c)
|
|
22
|
+
a + b + c
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
fwd_t2_pass1(2, 3).should == 6
|
|
26
|
+
error = nil
|
|
27
|
+
begin
|
|
28
|
+
fwd_t2_pass1(2, 3, 4) # Too many arguments passwd to fwd_t2_pass2
|
|
29
|
+
rescue ArgumentError
|
|
30
|
+
error = :ArgumentError
|
|
31
|
+
end
|
|
32
|
+
error.should == :ArgumentError
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "supports forwarding to multiple methods at once" do
|
|
36
|
+
def fwd_t3_pass1(...)
|
|
37
|
+
fwd_t3_pass2a(...) + fwd_t3_pass2b(...) + fwd_t3_pass2c(...)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def fwd_t3_pass2a(*args)
|
|
41
|
+
-2 * args.count
|
|
42
|
+
end
|
|
43
|
+
def fwd_t3_pass2b(*args)
|
|
44
|
+
1 * args.count
|
|
45
|
+
end
|
|
46
|
+
def fwd_t3_pass2c(*args)
|
|
47
|
+
0 * args.count
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
fwd_t3_pass1(0, 0, 0).should == -3
|
|
51
|
+
fwd_t3_pass1(0, 0).should == -2
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
describe "Infinite ranges" do
|
|
2
|
+
it "supports endless ranges" do
|
|
3
|
+
range = (10..)
|
|
4
|
+
range.begin.should == 10
|
|
5
|
+
range.end.should == nil
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "supports beginless ranges" do
|
|
9
|
+
range = (..10)
|
|
10
|
+
range.begin.should == nil
|
|
11
|
+
range.end.should == 10
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
describe "memoization" do
|
|
2
|
+
it "memoizes a value with complex internal logic" do
|
|
3
|
+
klass = Class.new do
|
|
4
|
+
def memoized_value(dependency: nil)
|
|
5
|
+
@memoized_value ||= begin
|
|
6
|
+
return nil if dependency.nil?
|
|
7
|
+
|
|
8
|
+
dependency.call
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
expect(klass.new.memoized_value(dependency: proc { :value })).to eq :value
|
|
14
|
+
expect(klass.new.memoized_value).to eq nil
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -15,8 +15,30 @@ module ModuleSubclassIncludedSpec
|
|
|
15
15
|
M2 = Module2.new
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
module ModuleCVarSpec
|
|
19
|
+
module Mod0
|
|
20
|
+
def cvar0; @@cvar; end
|
|
21
|
+
def cvarx0; @@cvarx ||= 5; end
|
|
22
|
+
def cvary0; @@cvary; 0; end
|
|
23
|
+
def cvarz0; @@cvarz = @@cvarz || 5; end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
module Mod1
|
|
27
|
+
include Mod0
|
|
28
|
+
@@cvar = 10
|
|
29
|
+
def cvar1; @@cvar; end
|
|
30
|
+
def cvar1=(new); @@cvar=new; end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
module Mod2
|
|
34
|
+
include Mod1
|
|
35
|
+
def cvar2; @@cvar; end
|
|
36
|
+
def cvar2=(new); @@cvar=new; end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe 'Module' do
|
|
41
|
+
it '#included gets called in subclasses (regression for https://github.com/opal/opal/issues/1900)' do
|
|
20
42
|
$ScratchPad = []
|
|
21
43
|
klass = Class.new
|
|
22
44
|
klass.include ::ModuleSubclassIncludedSpec::M0
|
|
@@ -24,4 +46,18 @@ describe 'Module#included' do
|
|
|
24
46
|
klass.include ::ModuleSubclassIncludedSpec::M2
|
|
25
47
|
$ScratchPad.should == ['A included', 'B included']
|
|
26
48
|
end
|
|
49
|
+
|
|
50
|
+
it "can access ancestor's @@cvar" do
|
|
51
|
+
klass = Class.new
|
|
52
|
+
klass.include ::ModuleCVarSpec::Mod2
|
|
53
|
+
klass.new.cvar1.should == 10
|
|
54
|
+
klass.new.cvar2.should == 10
|
|
55
|
+
klass.new.cvar2 = 50
|
|
56
|
+
klass.new.cvar1.should == 50
|
|
57
|
+
klass.new.cvar2.should == 50
|
|
58
|
+
klass.new.cvarx0.should == 5
|
|
59
|
+
klass.new.cvary0.should == 0
|
|
60
|
+
->{ klass.new.cvarz0 }.should raise_error NameError
|
|
61
|
+
->{ klass.new.cvar0 }.should raise_error NameError
|
|
62
|
+
end
|
|
27
63
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Number#to_i' do
|
|
4
|
+
it "should not change huge number" do
|
|
5
|
+
1504642339053716000000.to_i.should == 1504642339053716000000
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should not change negative huge number" do
|
|
9
|
+
-1504642339053716000000.to_i.should == -1504642339053716000000
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "equals Number#truncate(0) with huge number" do
|
|
13
|
+
1504642339053716000000.to_i.should == 1504642339053716000000.truncate(0)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should not change Infinity" do
|
|
17
|
+
`Infinity`.to_i.should == `Infinity`
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "should not change -Infinity" do
|
|
21
|
+
`-Infinity`.to_i.should == `-Infinity`
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should not change NaN" do
|
|
25
|
+
x = `NaN`.to_i
|
|
26
|
+
`Number.isNaN(x)`.should be_true
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -121,3 +121,19 @@ describe 'Bridged classes in different modules' do
|
|
|
121
121
|
@bridged.new.some_bridged_method.should == [4, 5, 6]
|
|
122
122
|
end
|
|
123
123
|
end
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
describe "Invalid bridged classes" do
|
|
127
|
+
it "raises a TypeError when trying to extend with non-Class" do
|
|
128
|
+
error_msg = /superclass must be a Class/
|
|
129
|
+
-> { class TestClass < `""`; end }.should raise_error(TypeError, error_msg)
|
|
130
|
+
-> { class TestClass < `3`; end }.should raise_error(TypeError, error_msg)
|
|
131
|
+
-> { class TestClass < `true`; end }.should raise_error(TypeError, error_msg)
|
|
132
|
+
-> { class TestClass < `Math`; end }.should raise_error(TypeError, error_msg)
|
|
133
|
+
-> { class TestClass < `Object.create({})`; end }.should raise_error(TypeError, error_msg)
|
|
134
|
+
-> { class TestClass < `Object.create(null)`; end }.should raise_error(TypeError, error_msg)
|
|
135
|
+
-> { class TestClass < Module.new; end }.should raise_error(TypeError, error_msg)
|
|
136
|
+
-> { class TestClass < BasicObject.new; end }.should raise_error(TypeError, error_msg)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
@@ -4,9 +4,15 @@ module RuntimeFixtures
|
|
|
4
4
|
|
|
5
5
|
class A::B
|
|
6
6
|
module C
|
|
7
|
-
|
|
8
7
|
end
|
|
9
8
|
end
|
|
9
|
+
|
|
10
|
+
module ModuleB
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module ModuleA
|
|
14
|
+
include ModuleB
|
|
15
|
+
end
|
|
10
16
|
end
|
|
11
17
|
|
|
12
18
|
describe "Constants access via .$$ with dots (regression for #1418)" do
|
|
@@ -14,3 +20,16 @@ describe "Constants access via .$$ with dots (regression for #1418)" do
|
|
|
14
20
|
`Opal.Object.$$.RuntimeFixtures.$$.A.$$.B.$$.C`.should == RuntimeFixtures::A::B::C
|
|
15
21
|
end
|
|
16
22
|
end
|
|
23
|
+
|
|
24
|
+
describe "Inclusion of modules" do
|
|
25
|
+
it "that have been included by other modules works" do
|
|
26
|
+
# here ClassC would have failed to be created due to a bug in Opal.append_features
|
|
27
|
+
module RuntimeFixtures
|
|
28
|
+
class ClassC
|
|
29
|
+
include ModuleA
|
|
30
|
+
include ModuleB
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
RuntimeFixtures::ClassC.new.class.should == RuntimeFixtures::ClassC
|
|
34
|
+
end
|
|
35
|
+
end
|