opal 1.1.0.rc1 → 1.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +4 -4
- 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/CHANGELOG.md +42 -1
- data/Gemfile +0 -4
- data/HACKING.md +1 -1
- data/LICENSE +1 -1
- data/README.md +20 -16
- data/UNRELEASED.md +32 -95
- data/benchmark-ips/bm_array_unshift.rb +7 -0
- data/benchmark-ips/bm_js_symbols_vs_strings.rb +7 -2
- data/bin/build-browser-source-map-support +2 -3
- 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 +5 -1
- data/lib/opal/cli_runners/source-map-support-browser.js +8 -2
- data/lib/opal/cli_runners/source-map-support-node.js +3706 -0
- 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.gemspec +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/package.json +1 -1
- 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 +35 -12
- 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
|