opal 1.3.2 → 1.4.0.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.eslintrc.js +1 -0
- data/.github/workflows/build.yml +0 -3
- data/.rubocop.yml +5 -1
- data/UNRELEASED.md +66 -2
- data/benchmark-ips/bm_truthy.rb +30 -0
- data/bin/opal-mspec +1 -3
- data/bin/opal-repl +1 -2
- data/bin/remove-filters +1 -4
- data/docs/compiled_ruby.md +10 -6
- data/exe/opal-repl +1 -3
- data/lib/opal/ast/builder.rb +1 -1
- data/lib/opal/cli.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +9 -2
- data/lib/opal/cli_runners/source-map-support-browser.js +80 -216
- data/lib/opal/cli_runners/source-map-support-node.js +80 -216
- data/lib/opal/cli_runners/source-map-support.js +5 -1
- data/lib/opal/cli_runners/system_runner.rb +10 -4
- data/lib/opal/compiler.rb +3 -5
- data/lib/opal/fragment.rb +5 -1
- data/lib/opal/nodes/args/extract_block_arg.rb +1 -8
- data/lib/opal/nodes/args/extract_kwoptarg.rb +1 -3
- data/lib/opal/nodes/args/extract_optarg.rb +1 -3
- data/lib/opal/nodes/args/extract_post_arg.rb +2 -5
- data/lib/opal/nodes/args/extract_post_optarg.rb +2 -7
- data/lib/opal/nodes/args/initialize_iterarg.rb +1 -3
- data/lib/opal/nodes/args/prepare_post_args.rb +5 -1
- data/lib/opal/nodes/base.rb +3 -2
- data/lib/opal/nodes/call.rb +20 -9
- data/lib/opal/nodes/call_special.rb +50 -0
- data/lib/opal/nodes/class.rb +24 -15
- data/lib/opal/nodes/constants.rb +23 -5
- data/lib/opal/nodes/def.rb +20 -23
- data/lib/opal/nodes/defined.rb +5 -5
- data/lib/opal/nodes/definitions.rb +2 -2
- data/lib/opal/nodes/defs.rb +2 -5
- data/lib/opal/nodes/helpers.rb +48 -18
- data/lib/opal/nodes/if.rb +109 -8
- data/lib/opal/nodes/iter.rb +23 -16
- data/lib/opal/nodes/literal.rb +18 -4
- data/lib/opal/nodes/logic.rb +2 -1
- data/lib/opal/nodes/masgn.rb +4 -9
- data/lib/opal/nodes/module.rb +29 -19
- data/lib/opal/nodes/node_with_args.rb +1 -7
- data/lib/opal/nodes/scope.rb +54 -15
- data/lib/opal/nodes/singleton_class.rb +5 -3
- data/lib/opal/nodes/super.rb +3 -3
- data/lib/opal/nodes/top.rb +34 -31
- data/lib/opal/nodes/variables.rb +2 -2
- data/lib/opal/nodes/x_string.rb +3 -0
- data/lib/opal/nodes.rb +0 -1
- data/lib/opal/parser/patch.rb +75 -0
- data/lib/opal/parser/with_ruby_lexer.rb +1 -1
- data/lib/opal/regexp_anchors.rb +7 -7
- data/lib/opal/requires.rb +19 -0
- data/lib/opal/rewriters/pattern_matching.rb +1 -1
- data/lib/opal/rewriters/returnable_logic.rb +102 -4
- data/lib/opal/util.rb +2 -2
- data/lib/opal/version.rb +1 -1
- data/lib/opal.rb +1 -17
- data/opal/corelib/array/pack.rb +11 -11
- data/opal/corelib/array.rb +193 -152
- data/opal/corelib/basic_object.rb +14 -14
- data/opal/corelib/binding.rb +7 -7
- data/opal/corelib/boolean.rb +12 -15
- data/opal/corelib/class.rb +23 -1
- data/opal/corelib/comparable.rb +8 -8
- data/opal/corelib/complex/base.rb +2 -2
- data/opal/corelib/complex.rb +79 -88
- data/opal/corelib/constants.rb +9 -9
- data/opal/corelib/dir.rb +4 -3
- data/opal/corelib/enumerable.rb +140 -127
- data/opal/corelib/enumerator/arithmetic_sequence.rb +177 -0
- data/opal/corelib/enumerator/chain.rb +42 -0
- data/opal/corelib/enumerator/generator.rb +35 -0
- data/opal/corelib/enumerator/lazy.rb +243 -0
- data/opal/corelib/enumerator/yielder.rb +36 -0
- data/opal/corelib/enumerator.rb +45 -300
- data/opal/corelib/error/errno.rb +47 -0
- data/opal/corelib/error.rb +62 -60
- data/opal/corelib/file.rb +26 -12
- data/opal/corelib/hash.rb +98 -107
- data/opal/corelib/helpers.rb +62 -13
- data/opal/corelib/io.rb +47 -34
- data/opal/corelib/kernel/format.rb +29 -29
- data/opal/corelib/kernel.rb +86 -83
- data/opal/corelib/main.rb +14 -12
- data/opal/corelib/marshal/read_buffer.rb +15 -15
- data/opal/corelib/marshal/write_buffer.rb +45 -44
- data/opal/corelib/marshal.rb +3 -3
- data/opal/corelib/math.rb +50 -50
- data/opal/corelib/method.rb +12 -8
- data/opal/corelib/module.rb +96 -79
- data/opal/corelib/nil.rb +9 -11
- data/opal/corelib/number.rb +113 -118
- data/opal/corelib/numeric.rb +37 -33
- data/opal/corelib/object_space.rb +11 -10
- data/opal/corelib/pack_unpack/format_string_parser.rb +3 -3
- data/opal/corelib/pattern_matching/base.rb +7 -7
- data/opal/corelib/pattern_matching.rb +1 -1
- data/opal/corelib/proc.rb +15 -16
- data/opal/corelib/process/base.rb +2 -2
- data/opal/corelib/process/status.rb +21 -0
- data/opal/corelib/process.rb +5 -5
- data/opal/corelib/random/formatter.rb +11 -11
- data/opal/corelib/random/math_random.js.rb +1 -1
- data/opal/corelib/random/mersenne_twister.rb +3 -3
- data/opal/corelib/random/seedrandom.js.rb +3 -3
- data/opal/corelib/random.rb +17 -17
- data/opal/corelib/range.rb +51 -35
- data/opal/corelib/rational/base.rb +4 -4
- data/opal/corelib/rational.rb +61 -62
- data/opal/corelib/regexp.rb +47 -38
- data/opal/corelib/runtime.js +245 -139
- data/opal/corelib/string/encoding.rb +21 -21
- data/opal/corelib/string/unpack.rb +19 -14
- data/opal/corelib/string.rb +135 -128
- data/opal/corelib/struct.rb +59 -46
- data/opal/corelib/time.rb +47 -57
- data/opal/corelib/trace_point.rb +2 -2
- data/opal/corelib/unsupported.rb +31 -120
- data/opal/corelib/variables.rb +3 -3
- data/opal/opal/base.rb +9 -8
- data/opal/opal/full.rb +8 -8
- data/opal/opal/mini.rb +17 -17
- data/opal/opal.rb +17 -18
- data/opal.gemspec +1 -1
- data/spec/filters/bugs/array.rb +4 -24
- data/spec/filters/bugs/bigdecimal.rb +0 -23
- data/spec/filters/bugs/binding.rb +0 -1
- data/spec/filters/bugs/boolean.rb +3 -0
- data/spec/filters/bugs/class.rb +2 -0
- data/spec/filters/bugs/date.rb +0 -5
- data/spec/filters/bugs/encoding.rb +8 -50
- data/spec/filters/bugs/enumerable.rb +4 -1
- data/spec/filters/bugs/enumerator.rb +3 -36
- data/spec/filters/bugs/exception.rb +0 -2
- data/spec/filters/bugs/file.rb +0 -2
- data/spec/filters/bugs/float.rb +0 -3
- data/spec/filters/bugs/hash.rb +5 -3
- data/spec/filters/bugs/integer.rb +2 -3
- data/spec/filters/bugs/kernel.rb +2 -31
- data/spec/filters/bugs/language.rb +29 -49
- data/spec/filters/bugs/main.rb +0 -2
- data/spec/filters/bugs/marshal.rb +2 -3
- data/spec/filters/bugs/matrix.rb +0 -36
- data/spec/filters/bugs/module.rb +7 -61
- data/spec/filters/bugs/numeric.rb +0 -7
- data/spec/filters/bugs/objectspace.rb +1 -1
- data/spec/filters/bugs/pack_unpack.rb +0 -4
- data/spec/filters/bugs/proc.rb +0 -9
- data/spec/filters/bugs/random.rb +0 -5
- data/spec/filters/bugs/range.rb +1 -6
- data/spec/filters/bugs/regexp.rb +0 -3
- data/spec/filters/bugs/set.rb +8 -1
- data/spec/filters/bugs/string.rb +9 -34
- data/spec/filters/bugs/stringscanner.rb +8 -7
- data/spec/filters/bugs/struct.rb +2 -3
- data/spec/filters/bugs/symbol.rb +0 -1
- data/spec/filters/bugs/time.rb +0 -8
- data/spec/filters/bugs/unboundmethod.rb +0 -8
- data/spec/filters/bugs/warnings.rb +1 -7
- data/spec/filters/unsupported/freeze.rb +24 -0
- data/spec/filters/unsupported/integer.rb +1 -0
- data/spec/filters/unsupported/kernel.rb +12 -0
- data/spec/filters/unsupported/privacy.rb +3 -0
- data/spec/filters/unsupported/string.rb +2 -0
- data/spec/lib/builder_spec.rb +2 -2
- data/spec/lib/cli_spec.rb +1 -1
- data/spec/lib/compiler_spec.rb +37 -37
- data/spec/lib/simple_server_spec.rb +2 -2
- data/spec/lib/source_map/file_spec.rb +1 -1
- data/spec/opal/compiler/irb_spec.rb +2 -2
- data/spec/opal/core/kernel/puts_spec.rb +90 -0
- data/spec/opal/core/language/super_spec.rb +24 -0
- data/spec/ruby_specs +4 -2
- data/spec/support/rewriters_helper.rb +1 -1
- data/stdlib/bigdecimal.rb +7 -11
- data/stdlib/buffer/view.rb +2 -2
- data/stdlib/buffer.rb +2 -2
- data/stdlib/date.rb +5 -6
- data/stdlib/erb.rb +1 -0
- data/stdlib/js.rb +2 -1
- data/stdlib/native.rb +7 -8
- data/stdlib/nodejs/argf.rb +4 -4
- data/stdlib/nodejs/base.rb +29 -0
- data/stdlib/nodejs/dir.rb +1 -1
- data/stdlib/nodejs/env.rb +6 -9
- data/stdlib/nodejs/file.rb +23 -17
- data/stdlib/nodejs/fileutils.rb +3 -3
- data/stdlib/nodejs/io.rb +2 -20
- data/stdlib/nodejs/irb.rb +0 -0
- data/stdlib/nodejs/kernel.rb +2 -37
- data/stdlib/nodejs.rb +1 -3
- data/stdlib/opal/miniracer.rb +2 -0
- data/stdlib/opal/platform.rb +6 -13
- data/stdlib/opal/replutils.rb +16 -5
- data/stdlib/opal-parser.rb +2 -2
- data/stdlib/optparse/ac.rb +54 -0
- data/stdlib/optparse/date.rb +14 -0
- data/stdlib/optparse/kwargs.rb +22 -0
- data/stdlib/optparse/shellwords.rb +7 -0
- data/stdlib/optparse/time.rb +15 -0
- data/stdlib/optparse/uri.rb +7 -0
- data/stdlib/optparse/version.rb +69 -0
- data/stdlib/optparse.rb +2279 -0
- data/stdlib/pathname.rb +5 -6
- data/stdlib/pp.rb +18 -2
- data/stdlib/promise/v2.rb +18 -22
- data/stdlib/promise.rb +15 -21
- data/stdlib/set.rb +32 -32
- data/stdlib/shellwords.rb +240 -0
- data/stdlib/stringio.rb +3 -6
- data/stdlib/strscan.rb +5 -8
- data/stdlib/template.rb +2 -2
- data/stdlib/thread.rb +7 -9
- data/tasks/performance.rake +5 -2
- data/tasks/testing/mspec_special_calls.rb +0 -12
- data/tasks/testing.rake +55 -37
- data/test/nodejs/test_file.rb +11 -0
- metadata +55 -10
- data/lib/opal/nodes/case.rb +0 -114
@@ -19,6 +19,8 @@ opal_unsupported_filter "Kernel" do
|
|
19
19
|
fails "Kernel#eql? is a public instance method"
|
20
20
|
fails "Kernel#fail is a private method"
|
21
21
|
fails "Kernel#format is a private method"
|
22
|
+
fails "Kernel#initialize_clone returns the receiver" # Expected nil == #<Object:0x63440> to be truthy but was false
|
23
|
+
fails "Kernel#initialize_dup returns the receiver" # Expected nil == #<Object:0x4c314> to be truthy but was false
|
22
24
|
fails "Kernel#inspect returns an untrusted string if self is untrusted"
|
23
25
|
fails "Kernel#raise is a private method"
|
24
26
|
fails "Kernel#sleep accepts a Rational"
|
@@ -27,9 +29,19 @@ opal_unsupported_filter "Kernel" do
|
|
27
29
|
fails "Kernel#sprintf is a private method"
|
28
30
|
fails "Kernel#to_s returns a tainted result if self is tainted"
|
29
31
|
fails "Kernel#to_s returns an untrusted result if self is untrusted"
|
32
|
+
fails "Kernel#warn calls Warning.warn with category: nil if Warning.warn accepts keyword arguments" # NameError: uninitialized constant Warning
|
33
|
+
fails "Kernel#warn calls Warning.warn with given category keyword converted to a symbol" # NameError: uninitialized constant Warning
|
34
|
+
fails "Kernel#warn calls Warning.warn without keyword arguments if Warning.warn does not accept keyword arguments" # NameError: uninitialized constant Warning
|
30
35
|
fails "Kernel#warn is a private method"
|
31
36
|
fails "Kernel.Float raises a TypeError if #to_f returns an Integer"
|
32
37
|
fails "Kernel.Integer calls to_i on Rationals"
|
33
38
|
fails "Kernel.Integer returns a Fixnum or Bignum object"
|
34
39
|
fails "Kernel.fail is a private method"
|
40
|
+
fails "Kernel.lambda when called without a literal block warns when proc isn't a lambda" # Expected warning: "ruby/core/kernel/lambda_spec.rb:142: warning: lambda without a literal block is deprecated; use the proc without lambda instead\n" but got: ""
|
41
|
+
fails "Kernel.printf formatting io is specified other formats s formats nil with width and precision" # Exception: format_string.indexOf is not a function
|
42
|
+
fails "Kernel.printf formatting io is specified other formats s formats nli with precision" # Exception: format_string.indexOf is not a function
|
43
|
+
fails "Kernel.printf formatting io is specified other formats s formats nli with width" # Exception: format_string.indexOf is not a function
|
44
|
+
fails "Kernel.printf formatting io is specified other formats s formats string with width and precision" # Exception: format_string.indexOf is not a function
|
45
|
+
fails "Kernel.printf formatting io is specified other formats s formats string with width" # Exception: format_string.indexOf is not a function
|
46
|
+
fails "Kernel.printf formatting io is specified other formats s substitutes '' for nil" # Exception: format_string.indexOf is not a function
|
35
47
|
end
|
@@ -15,12 +15,15 @@ opal_unsupported_filter "private" do
|
|
15
15
|
fails "Defining an 'initialize_copy' method sets the method's visibility to private"
|
16
16
|
fails "Defining an 'initialize_dup' method sets the method's visibility to private"
|
17
17
|
fails "Enumerator#initialize is a private method"
|
18
|
+
fails "Enumerator::Chain#initialize is a private method" # Expected Enumerator::Chain to have private instance method 'initialize' but it does not
|
18
19
|
fails "Enumerator::Generator#initialize is a private method" # Expected Enumerator::Generator to have private instance method 'initialize' but it does not
|
19
20
|
fails "Enumerator::Lazy#initialize is a private method" # Expected Enumerator::Lazy to have private instance method 'initialize' but it does not
|
20
21
|
fails "Enumerator::Yielder#initialize is a private method" # Expected Enumerator::Yielder to have private instance method 'initialize' but it does not
|
21
22
|
fails "Invoking a private getter method does not permit self as a receiver"
|
22
23
|
fails "Kernel#block_given? is a private method"
|
23
24
|
fails "Kernel#eval is a private method"
|
25
|
+
fails "Kernel#initialize_clone is a private instance method" # Expected Kernel to have private instance method 'initialize_clone' but it does not
|
26
|
+
fails "Kernel#initialize_dup is a private instance method" # Expected Kernel to have private instance method 'initialize_dup' but it does not
|
24
27
|
fails "Kernel#iterator? is a private method"
|
25
28
|
fails "Kernel#local_variables is a private method"
|
26
29
|
fails "Kernel#methods returns private singleton methods defined by obj.meth"
|
@@ -419,6 +419,7 @@ opal_unsupported_filter "String" do
|
|
419
419
|
fails "String#lstrip! raises a RuntimeError on a frozen instance that is modified"
|
420
420
|
fails "String#lstrip! raises a RuntimeError on a frozen instance that would not be modified"
|
421
421
|
fails "String#lstrip! returns nil if no modifications were made"
|
422
|
+
fails "String#lstrip! strips leading \\0" # NotImplementedError: String#lstrip! not supported. Mutable String methods are not supported in Opal.
|
422
423
|
fails "String#match matches \\G at the start of the string"
|
423
424
|
fails "String#next taints the result if self is tainted"
|
424
425
|
fails "String#next! is equivalent to succ, but modifies self in place (still returns self)"
|
@@ -554,6 +555,7 @@ opal_unsupported_filter "String" do
|
|
554
555
|
fails "String#strip! modifies self removing trailing NULL bytes and whitespace"
|
555
556
|
fails "String#strip! raises a RuntimeError on a frozen instance that is modified"
|
556
557
|
fails "String#strip! raises a RuntimeError on a frozen instance that would not be modified"
|
558
|
+
fails "String#strip! removes leading and trailing NULL bytes and whitespace" # NotImplementedError: String#strip! not supported. Mutable String methods are not supported in Opal.
|
557
559
|
fails "String#strip! returns nil if no modifications where made"
|
558
560
|
fails "String#sub with pattern and Hash ignores non-String keys" # Expected "tazoo" == "taboo" to be truthy but was false
|
559
561
|
fails "String#sub with pattern and Hash taints the result if a hash value is tainted"
|
data/spec/lib/builder_spec.rb
CHANGED
@@ -76,14 +76,14 @@ RSpec.describe Opal::Builder do
|
|
76
76
|
expect(Opal::Config.compiler_options[:arity_check]).to eq(false)
|
77
77
|
builder = described_class.new
|
78
78
|
builder.build_str('def foo; end', 'foo')
|
79
|
-
expect(builder.to_s).not_to include('
|
79
|
+
expect(builder.to_s).not_to include('$$parameters: []')
|
80
80
|
|
81
81
|
Opal::Config.arity_check_enabled = true
|
82
82
|
expect(Opal::Config.arity_check_enabled).to eq(true)
|
83
83
|
expect(Opal::Config.compiler_options[:arity_check]).to eq(true)
|
84
84
|
builder = described_class.new
|
85
85
|
builder.build_str('def foo; end', 'foo')
|
86
|
-
expect(builder.to_s).to include('
|
86
|
+
expect(builder.to_s).to include('$$parameters: []')
|
87
87
|
end
|
88
88
|
|
89
89
|
describe '#missing_require_severity' do
|
data/spec/lib/cli_spec.rb
CHANGED
@@ -223,7 +223,7 @@ RSpec.describe Opal::CLI do
|
|
223
223
|
let(:options) { { parse_comments: true, evals: [code], runner: :compiler } }
|
224
224
|
|
225
225
|
it 'sets $$comment prop for compiled methods' do
|
226
|
-
expect_output_of { subject.run }.to include('$$comments
|
226
|
+
expect_output_of { subject.run }.to include('$$comments: ["# multiline", "# comment"]')
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
data/spec/lib/compiler_spec.rb
CHANGED
@@ -35,7 +35,7 @@ RSpec.describe Opal::Compiler do
|
|
35
35
|
expect_compiled("123E+10").to include("return 1230000000000")
|
36
36
|
expect_compiled("false").to include("return false")
|
37
37
|
expect_compiled("true").to include("return true")
|
38
|
-
expect_compiled("nil").to include("return nil")
|
38
|
+
expect_compiled("0;nil").to include("return nil") # NB: Empty nil return is compiled-out
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should compile ruby strings" do
|
@@ -66,15 +66,15 @@ RSpec.describe Opal::Compiler do
|
|
66
66
|
|
67
67
|
it "should compile method calls" do
|
68
68
|
expect_compiled("self.inspect").to include("$inspect()")
|
69
|
-
expect_compiled("self.map { |a| a + 10 }").to include("
|
69
|
+
expect_compiled("self.map { |a| a + 10 }").to include("'map'")
|
70
70
|
end
|
71
71
|
|
72
72
|
it "adds method missing stubs" do
|
73
|
-
expect_compiled("self.puts 'hello'").to include("Opal.add_stubs(
|
73
|
+
expect_compiled("self.puts 'hello'").to include("Opal.add_stubs('puts')")
|
74
74
|
end
|
75
75
|
|
76
76
|
it 'adds method missing stubs with operators' do
|
77
|
-
expect_compiled("class Foo; end; Foo.new > 5").to include("Opal.add_stubs(
|
77
|
+
expect_compiled("class Foo; end; Foo.new > 5").to include("Opal.add_stubs('>,new')")
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should compile constant lookups" do
|
@@ -99,8 +99,8 @@ RSpec.describe Opal::Compiler do
|
|
99
99
|
end
|
100
100
|
|
101
101
|
context "when function name is not valid" do
|
102
|
-
it "
|
103
|
-
expect_compiled("def test_method?; end").to include("function()")
|
102
|
+
it "generates a name in a safe way" do
|
103
|
+
expect_compiled("def test_method?; end").to include("function $test_method$ques$1()")
|
104
104
|
end
|
105
105
|
end
|
106
106
|
end
|
@@ -207,34 +207,42 @@ RSpec.describe Opal::Compiler do
|
|
207
207
|
expect_compiled('foo = 42 if 2 > 3').to include('if ($rb_gt(2, 3))')
|
208
208
|
expect_compiled('foo = 42 if 2.5 > 3.5').to include('if ($rb_gt(2.5, 3.5))')
|
209
209
|
expect_compiled('foo = 42 if true > false').to include('if ($rb_gt(true, false))')
|
210
|
-
|
211
|
-
expect_compiled('foo = 42 if 2 == 3').to include("if ((2)['$=='](3))")
|
212
|
-
expect_compiled('foo = 42 if 2.5 == 3.5').to include("if ((2.5)['$=='](3.5))")
|
213
|
-
expect_compiled('foo = 42 if true == false').to include("if (true['$=='](false))")
|
214
210
|
end
|
215
211
|
|
216
212
|
it 'adds nil check for strings' do
|
217
213
|
expect_compiled('foo = 42 if "test" > "bar"').to include('if ($truthy($rb_gt("test", "bar")))')
|
218
214
|
end
|
219
215
|
|
220
|
-
it 'specifically == excludes nil check for strings' do
|
221
|
-
expect_compiled('foo = 42 if "test" == "bar"').to include("if (\"test\"['$=='](\"bar\"))")
|
222
|
-
end
|
223
|
-
|
224
216
|
it 'adds nil check for lvars' do
|
225
217
|
expect_compiled("bar = 4\nfoo = 42 if bar > 5").to include('if ($truthy($rb_gt(bar, 5)))')
|
226
218
|
end
|
227
219
|
|
228
|
-
it '
|
229
|
-
expect_compiled("
|
220
|
+
it 'adds nil check for constants' do
|
221
|
+
expect_compiled("foo = 42 if Test > 4").to include("if ($truthy($rb_gt($$('Test'), 4))) ")
|
230
222
|
end
|
231
223
|
|
232
|
-
it '
|
233
|
-
expect_compiled(
|
224
|
+
it 'converts each == call inside if to an $eqeq wrapper, which does a truthy check' do
|
225
|
+
expect_compiled('foo = 42 if 2 == 3').to include("if ($eqeq(2, 3))")
|
226
|
+
expect_compiled('foo = 42 if 2.5 == 3.5').to include("if ($eqeq(2.5, 3.5))")
|
227
|
+
expect_compiled('foo = 42 if true == false').to include("if ($eqeq(true, false))")
|
228
|
+
expect_compiled('foo = 42 if "test" == "bar"').to include("if ($eqeq(\"test\", \"bar\"))")
|
229
|
+
expect_compiled("bar = 4\nfoo = 42 if bar == 5").to include("if ($eqeq(bar, 5))")
|
230
|
+
expect_compiled("foo = 42 if Test == 4").to include("if ($eqeq($$('Test'), 4))")
|
231
|
+
expect_compiled("bar = 4\nfoo = 42 if bar == 5").to include("if ($eqeq(bar, 5))")
|
232
|
+
end
|
233
|
+
|
234
|
+
it "doesn't convert ==/=== calls to $eqeq(eq) wrappers outside of an if" do
|
235
|
+
expect_compiled("bar == 5").not_to include("$eqeq(bar, 5)")
|
234
236
|
end
|
235
237
|
|
236
|
-
it '
|
237
|
-
expect_compiled(
|
238
|
+
it 'converts each === call inside if to an $eqeqeq wrapper, which does a truthy check' do
|
239
|
+
expect_compiled('foo = 42 if 2 === 3').to include("if ($eqeqeq(2, 3))")
|
240
|
+
expect_compiled('foo = 42 if 2.5 === 3.5').to include("if ($eqeqeq(2.5, 3.5))")
|
241
|
+
expect_compiled('foo = 42 if true === false').to include("if ($eqeqeq(true, false))")
|
242
|
+
expect_compiled('foo = 42 if "test" === "bar"').to include("if ($eqeqeq(\"test\", \"bar\"))")
|
243
|
+
expect_compiled("bar = 4\nfoo = 42 if bar === 5").to include("if ($eqeqeq(bar, 5))")
|
244
|
+
expect_compiled("foo = 42 if Test === 4").to include("if ($eqeqeq($$('Test'), 4))")
|
245
|
+
expect_compiled("bar = 4\nfoo = 42 if bar === 5").to include("if ($eqeqeq(bar, 5))")
|
238
246
|
end
|
239
247
|
end
|
240
248
|
|
@@ -258,36 +266,28 @@ RSpec.describe Opal::Compiler do
|
|
258
266
|
end
|
259
267
|
|
260
268
|
it 'adds nil check for constants' do
|
261
|
-
expect_compiled("foo = 42 if Test").to include("if ($truthy($$(
|
269
|
+
expect_compiled("foo = 42 if Test").to include("if ($truthy($$('Test')))")
|
262
270
|
end
|
263
271
|
end
|
264
272
|
end
|
265
273
|
|
266
274
|
context 'parentheses' do
|
267
275
|
context 'with operators' do
|
268
|
-
it 'adds nil check for primitives' do
|
269
|
-
expect_compiled('foo = 42 if (2 > 3)').to include('if ($truthy($rb_gt(2, 3))')
|
270
|
-
expect_compiled('foo = 42 if (2.5 > 3.5)').to include('if ($truthy($rb_gt(2.5, 3.5))')
|
271
|
-
expect_compiled('foo = 42 if (true > false)').to include('if ($truthy($rb_gt(true, false))')
|
272
|
-
|
273
|
-
expect_compiled('foo = 42 if (2 == 3)').to include("if ($truthy((2)['$=='](3))")
|
274
|
-
expect_compiled('foo = 42 if (2.5 == 3.5)').to include("if ($truthy((2.5)['$=='](3.5))")
|
275
|
-
expect_compiled('foo = 42 if (true == false)').to include("if ($truthy(true['$=='](false)))")
|
276
|
-
end
|
277
|
-
|
278
276
|
it 'adds nil check for strings' do
|
279
277
|
expect_compiled('foo = 42 if ("test" > "bar")').to include('if ($truthy($rb_gt("test", "bar"))')
|
280
|
-
expect_compiled('foo = 42 if ("test" == "bar")').to include("if ($truthy(\"test\"['$=='](\"bar\"))")
|
281
278
|
end
|
282
279
|
|
283
280
|
it 'adds nil check for lvars' do
|
284
281
|
expect_compiled("bar = 4\nfoo = 42 if (bar > 5)").to include('if ($truthy($rb_gt(bar, 5))')
|
285
|
-
expect_compiled("bar = 4\nfoo = 42 if (bar == 5)").to include("if ($truthy(bar['$=='](5))) ")
|
286
282
|
end
|
287
283
|
|
288
|
-
it '
|
289
|
-
expect_compiled(
|
290
|
-
expect_compiled(
|
284
|
+
it 'converts == expressions to $eqeq checks' do
|
285
|
+
expect_compiled('foo = 42 if (2 == 3)').to include("if ($eqeq(2, 3))")
|
286
|
+
expect_compiled('foo = 42 if (2.5 == 3.5)').to include("if ($eqeq(2.5, 3.5))")
|
287
|
+
expect_compiled('foo = 42 if (true == false)').to include("if ($eqeq(true, false))")
|
288
|
+
expect_compiled('foo = 42 if ("test" == "bar")').to include("if ($eqeq(\"test\", \"bar\")")
|
289
|
+
expect_compiled("bar = 4\nfoo = 42 if (bar == 5)").to include("if ($eqeq(bar, 5))")
|
290
|
+
expect_compiled("foo = 42 if (Test == 4)").to include("if ($eqeq($$('Test'), 4))")
|
291
291
|
end
|
292
292
|
end
|
293
293
|
|
@@ -311,7 +311,7 @@ RSpec.describe Opal::Compiler do
|
|
311
311
|
end
|
312
312
|
|
313
313
|
it 'adds nil check for constants' do
|
314
|
-
expect_compiled("foo = 42 if (Test)").to include("if ($truthy($$(
|
314
|
+
expect_compiled("foo = 42 if (Test)").to include("if ($truthy($$('Test'))")
|
315
315
|
end
|
316
316
|
end
|
317
317
|
end
|
@@ -47,10 +47,10 @@ RSpec.describe Opal::SimpleServer do
|
|
47
47
|
|
48
48
|
it 'respects config set in Opal::Config' do
|
49
49
|
Opal::Config.arity_check_enabled = false
|
50
|
-
expect(get('/assets/console.js').body).not_to include('
|
50
|
+
expect(get('/assets/console.js').body).not_to include('$$parameters: []')
|
51
51
|
|
52
52
|
Opal::Config.arity_check_enabled = true
|
53
53
|
self.app = described_class.new(main: 'console')
|
54
|
-
expect(get('/assets/console.js').body).to include('
|
54
|
+
expect(get('/assets/console.js').body).to include('$$parameters: []')
|
55
55
|
end
|
56
56
|
end
|
@@ -19,7 +19,7 @@ RSpec.describe Opal::SourceMap::File do
|
|
19
19
|
fragment(line: nil, column: nil, source_map_name: nil, code: "\n ", sexp_type: :top),
|
20
20
|
fragment(line: nil, column: nil, source_map_name: nil, code: "var self = Opal.top, $nesting = [], nil = Opal.nil, $$$ = Opal.$$$, $$ = Opal.$$, $breaker = Opal.breaker, $slice = Opal.slice;\n", sexp_type: :top),
|
21
21
|
fragment(line: nil, column: nil, source_map_name: nil, code: "\n ", sexp_type: :top),
|
22
|
-
fragment(line: nil, column: nil, source_map_name: nil, code: "Opal.add_stubs(
|
22
|
+
fragment(line: nil, column: nil, source_map_name: nil, code: "Opal.add_stubs('puts');", sexp_type: :top),
|
23
23
|
fragment(line: nil, column: nil, source_map_name: nil, code: "\n ", sexp_type: :top),
|
24
24
|
fragment(line: 1, column: 0, source_map_name: nil, code: "\n ", sexp_type: :begin),
|
25
25
|
fragment(line: nil, column: nil, source_map_name: "self", code: "self", sexp_type: :self),
|
@@ -5,14 +5,14 @@ describe Opal::Compiler do
|
|
5
5
|
describe "irb parser option" do
|
6
6
|
it "creates Opal.irb_vars if it does not exist" do
|
7
7
|
$global["Opal"].irb_vars = nil
|
8
|
-
eval_js compile("nil", :irb => true)
|
8
|
+
eval_js compile("0;nil", :irb => true)
|
9
9
|
|
10
10
|
($global["Opal"].irb_vars == nil).should be_false
|
11
11
|
end
|
12
12
|
|
13
13
|
it "does not create Opal.irb_vars if :irb option not passed" do
|
14
14
|
$global["Opal"].irb_vars = nil
|
15
|
-
eval_js compile("nil")
|
15
|
+
eval_js compile("0;nil")
|
16
16
|
|
17
17
|
($global["Opal"].irb_vars == nil).should be_true
|
18
18
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
describe "IO#puts" do
|
2
|
+
before :each do
|
3
|
+
@before_separator = $/
|
4
|
+
@io = IO.new(123)
|
5
|
+
ScratchPad.record []
|
6
|
+
def @io.write(str)
|
7
|
+
ScratchPad << str
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
after :each do
|
12
|
+
ScratchPad.clear
|
13
|
+
@io.close if @io
|
14
|
+
suppress_warning {$/ = @before_separator}
|
15
|
+
end
|
16
|
+
|
17
|
+
it "writes just a newline when given no args" do
|
18
|
+
@io.puts.should == nil
|
19
|
+
ScratchPad.recorded.join("").should == "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "writes just a newline when given just a newline" do
|
23
|
+
@io.puts("\n").should == nil
|
24
|
+
ScratchPad.recorded.should == ["\n"]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "writes empty string with a newline when given nil as an arg" do
|
28
|
+
@io.puts(nil).should == nil
|
29
|
+
ScratchPad.recorded.join("").should == "\n"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "writes empty string with a newline when when given nil as multiple args" do
|
33
|
+
@io.puts(nil, nil).should == nil
|
34
|
+
ScratchPad.recorded.join("").should == "\n\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "calls :to_s before writing non-string objects that don't respond to :to_ary" do
|
38
|
+
object = mock('hola')
|
39
|
+
object.should_receive(:to_s).and_return("hola")
|
40
|
+
|
41
|
+
@io.puts(object).should == nil
|
42
|
+
ScratchPad.recorded.join("").should == "hola\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
# it "returns general object info if :to_s does not return a string" do
|
46
|
+
# object = mock('hola')
|
47
|
+
# object.should_receive(:to_s).and_return(false)
|
48
|
+
#
|
49
|
+
# @io.puts(object).should == nil
|
50
|
+
# ScratchPad.recorded.join("").should == object.inspect.split(" ")[0] + ">\n"
|
51
|
+
# end
|
52
|
+
|
53
|
+
it "writes each arg if given several" do
|
54
|
+
@io.puts(1, "two", 3).should == nil
|
55
|
+
ScratchPad.recorded.join("").should == "1\ntwo\n3\n"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "flattens a nested array before writing it" do
|
59
|
+
@io.puts([1, 2, [3]]).should == nil
|
60
|
+
ScratchPad.recorded.join("").should == "1\n2\n3\n"
|
61
|
+
end
|
62
|
+
|
63
|
+
it "writes nothing for an empty array" do
|
64
|
+
@io.puts([]).should == nil
|
65
|
+
ScratchPad.recorded.should == []
|
66
|
+
end
|
67
|
+
|
68
|
+
# it "writes [...] for a recursive array arg" do
|
69
|
+
# x = []
|
70
|
+
# x << 2 << x
|
71
|
+
# @io.puts(x).should == nil
|
72
|
+
# ScratchPad.recorded.join("").should == "2\n[...]\n"
|
73
|
+
# end
|
74
|
+
|
75
|
+
it "writes a newline after objects that do not end in newlines" do
|
76
|
+
@io.puts(5).should == nil
|
77
|
+
ScratchPad.recorded.join("").should == "5\n"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "does not write a newline after objects that end in newlines" do
|
81
|
+
@io.puts("5\n").should == nil
|
82
|
+
ScratchPad.recorded.join("").should == "5\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "ignores the $/ separator global" do
|
86
|
+
suppress_warning {$/ = ":"}
|
87
|
+
@io.puts(5).should == nil
|
88
|
+
ScratchPad.recorded.join("").should == "5\n"
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
describe "a block with super" do
|
2
|
+
it "can be used to define multiple methods" do
|
3
|
+
block = proc {
|
4
|
+
super()
|
5
|
+
}
|
6
|
+
|
7
|
+
c1 = Class.new {
|
8
|
+
def foo; :foo; end
|
9
|
+
def bar; :bar; end
|
10
|
+
def foo_bar; [foo, bar]; end
|
11
|
+
}
|
12
|
+
|
13
|
+
c2 = Class.new(c1) {
|
14
|
+
define_method :foo, block
|
15
|
+
define_method :bar, block
|
16
|
+
define_method :foo_bar, block
|
17
|
+
}
|
18
|
+
|
19
|
+
obj = c2.new
|
20
|
+
obj.foo.should == :foo
|
21
|
+
obj.bar.should == :bar
|
22
|
+
obj.foo_bar.should == [:foo, :bar]
|
23
|
+
end
|
24
|
+
end
|
data/spec/ruby_specs
CHANGED
@@ -39,8 +39,8 @@ ruby/core/complex
|
|
39
39
|
|
40
40
|
ruby/core/enumerable
|
41
41
|
ruby/core/enumerator
|
42
|
-
|
43
|
-
|
42
|
+
ruby/core/enumerator/arithmetic_sequence
|
43
|
+
ruby/core/enumerator/chain
|
44
44
|
ruby/core/enumerator/generator
|
45
45
|
ruby/core/enumerator/lazy
|
46
46
|
ruby/core/enumerator/yielder
|
@@ -198,7 +198,9 @@ ruby/library/matrix/vector
|
|
198
198
|
ruby/library/pp
|
199
199
|
ruby/library/securerandom
|
200
200
|
ruby/library/set
|
201
|
+
ruby/library/shellwords
|
201
202
|
ruby/library/singleton
|
202
203
|
ruby/library/stringio/each_line_spec
|
203
204
|
ruby/library/stringio/each_spec
|
204
205
|
ruby/library/stringscanner
|
206
|
+
ruby/library/optionparser
|
data/stdlib/bigdecimal.rb
CHANGED
@@ -67,8 +67,6 @@ class BigDecimal < Numeric
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
alias === ==
|
71
|
-
|
72
70
|
def <=>(other)
|
73
71
|
result = case other
|
74
72
|
when self.class
|
@@ -123,8 +121,6 @@ class BigDecimal < Numeric
|
|
123
121
|
self.class.new(result)
|
124
122
|
end
|
125
123
|
|
126
|
-
alias + add
|
127
|
-
|
128
124
|
def ceil(n = nil)
|
129
125
|
unless bignumber.JS.isFinite
|
130
126
|
raise FloatDomainError, "Computation results to 'Infinity'"
|
@@ -188,8 +184,6 @@ class BigDecimal < Numeric
|
|
188
184
|
self.class.new(bignumber.JS.minus(other.bignumber))
|
189
185
|
end
|
190
186
|
|
191
|
-
alias - minus
|
192
|
-
|
193
187
|
def mult(other, digits = nil)
|
194
188
|
other, _ = coerce(other)
|
195
189
|
|
@@ -200,8 +194,6 @@ class BigDecimal < Numeric
|
|
200
194
|
self.class.new(bignumber.JS.times(other.bignumber).JS.round(digits, self.class.mode(ROUND_MODE)))
|
201
195
|
end
|
202
196
|
|
203
|
-
alias * mult
|
204
|
-
|
205
197
|
def nan?
|
206
198
|
bignumber.JS.isNaN
|
207
199
|
end
|
@@ -211,8 +203,6 @@ class BigDecimal < Numeric
|
|
211
203
|
self.class.new(bignumber.JS.dividedBy(other.bignumber))
|
212
204
|
end
|
213
205
|
|
214
|
-
alias / quo
|
215
|
-
|
216
206
|
def sign
|
217
207
|
if bignumber.JS.isNaN
|
218
208
|
return SIGN_NaN
|
@@ -234,9 +224,15 @@ class BigDecimal < Numeric
|
|
234
224
|
def to_s(s = '')
|
235
225
|
bignumber.JS.toString
|
236
226
|
end
|
237
|
-
alias inspect to_s
|
238
227
|
|
239
228
|
def zero?
|
240
229
|
bignumber.JS.isZero
|
241
230
|
end
|
231
|
+
|
232
|
+
alias === ==
|
233
|
+
alias + add
|
234
|
+
alias - minus
|
235
|
+
alias * mult
|
236
|
+
alias / quo
|
237
|
+
alias inspect to_s
|
242
238
|
end
|
data/stdlib/buffer/view.rb
CHANGED
@@ -27,8 +27,6 @@ class Buffer
|
|
27
27
|
`#{@native}.byteLength`
|
28
28
|
end
|
29
29
|
|
30
|
-
alias size length
|
31
|
-
|
32
30
|
def get(offset, bits = 8, type = :unsigned, little = false)
|
33
31
|
`#{@native}["get" + #{Buffer.name_for bits, type}](offset, little)`
|
34
32
|
end
|
@@ -104,5 +102,7 @@ class Buffer
|
|
104
102
|
def set_float64(offset, value, little = false)
|
105
103
|
`#{@native}.setFloat64(offset, value, little)`
|
106
104
|
end
|
105
|
+
|
106
|
+
alias size length
|
107
107
|
end
|
108
108
|
end
|
data/stdlib/buffer.rb
CHANGED
@@ -30,8 +30,6 @@ class Buffer
|
|
30
30
|
`#{@native}.byteLength`
|
31
31
|
end
|
32
32
|
|
33
|
-
alias size length
|
34
|
-
|
35
33
|
def to_a(bits = 8, type = :unsigned)
|
36
34
|
Array.new(self, bits, type)
|
37
35
|
end
|
@@ -43,4 +41,6 @@ class Buffer
|
|
43
41
|
def to_s
|
44
42
|
to_a.to_a.pack('c*')
|
45
43
|
end
|
44
|
+
|
45
|
+
alias size length
|
46
46
|
end
|
data/stdlib/date.rb
CHANGED
@@ -83,8 +83,6 @@ class Date
|
|
83
83
|
ABBR_DAYNAMES = %w[Sun Mon Tue Wed Thu Fri Sat]
|
84
84
|
|
85
85
|
class << self
|
86
|
-
alias civil new
|
87
|
-
|
88
86
|
def wrap(native)
|
89
87
|
instance = allocate
|
90
88
|
`#{instance}.date = #{native}`
|
@@ -344,6 +342,8 @@ class Date
|
|
344
342
|
def gregorian_leap?(year)
|
345
343
|
`(new Date(#{year}, 1, 29).getMonth()-1) === 0`
|
346
344
|
end
|
345
|
+
|
346
|
+
alias civil new
|
347
347
|
end
|
348
348
|
|
349
349
|
def initialize(year = -4712, month = 1, day = 1, start = ITALY)
|
@@ -472,8 +472,6 @@ class Date
|
|
472
472
|
}
|
473
473
|
end
|
474
474
|
|
475
|
-
alias eql? ==
|
476
|
-
|
477
475
|
def clone
|
478
476
|
Date.wrap(`new Date(#{@date}.getTime())`)
|
479
477
|
end
|
@@ -588,8 +586,6 @@ class Date
|
|
588
586
|
}
|
589
587
|
end
|
590
588
|
|
591
|
-
alias succ next
|
592
|
-
|
593
589
|
def sunday?
|
594
590
|
wday == 0
|
595
591
|
end
|
@@ -680,4 +676,7 @@ class Date
|
|
680
676
|
return [31, (leap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]
|
681
677
|
}
|
682
678
|
}
|
679
|
+
|
680
|
+
alias eql? ==
|
681
|
+
alias succ next
|
683
682
|
end
|
data/stdlib/erb.rb
CHANGED
data/stdlib/js.rb
CHANGED
data/stdlib/native.rb
CHANGED
@@ -261,10 +261,6 @@ class Native::Object < BasicObject
|
|
261
261
|
`Opal.hasOwnProperty.call(#{@native}, #{name})`
|
262
262
|
end
|
263
263
|
|
264
|
-
alias key? has_key?
|
265
|
-
alias include? has_key?
|
266
|
-
alias member? has_key?
|
267
|
-
|
268
264
|
def each(*args)
|
269
265
|
if block_given?
|
270
266
|
%x{
|
@@ -341,8 +337,6 @@ class Native::Object < BasicObject
|
|
341
337
|
`Opal.is_a(self, klass)`
|
342
338
|
end
|
343
339
|
|
344
|
-
alias kind_of? is_a?
|
345
|
-
|
346
340
|
def instance_of?(klass)
|
347
341
|
`self.$$class === klass`
|
348
342
|
end
|
@@ -358,6 +352,11 @@ class Native::Object < BasicObject
|
|
358
352
|
def inspect
|
359
353
|
"#<Native:#{`String(#{@native})`}>"
|
360
354
|
end
|
355
|
+
|
356
|
+
alias include? has_key?
|
357
|
+
alias key? has_key?
|
358
|
+
alias kind_of? is_a?
|
359
|
+
alias member? has_key?
|
361
360
|
end
|
362
361
|
|
363
362
|
class Native::Array
|
@@ -435,11 +434,11 @@ class Native::Array
|
|
435
434
|
`#{@native}[#{@length}]`
|
436
435
|
end
|
437
436
|
|
438
|
-
alias to_ary to_a
|
439
|
-
|
440
437
|
def inspect
|
441
438
|
to_a.inspect
|
442
439
|
end
|
440
|
+
|
441
|
+
alias to_ary to_a
|
443
442
|
end
|
444
443
|
|
445
444
|
class Numeric
|
data/stdlib/nodejs/argf.rb
CHANGED
@@ -99,12 +99,12 @@ class << ARGF
|
|
99
99
|
file.eof?
|
100
100
|
end
|
101
101
|
|
102
|
-
alias to_io file
|
103
|
-
alias to_i fileno
|
104
|
-
alias skip close
|
105
|
-
alias path filename
|
106
102
|
alias each_line each
|
107
103
|
alias eof eof?
|
104
|
+
alias path filename
|
105
|
+
alias skip close
|
106
|
+
alias to_i fileno
|
107
|
+
alias to_io file
|
108
108
|
end
|
109
109
|
|
110
110
|
ARGF.lineno = 1
|