opal 0.9.4 → 0.10.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitattributes +1 -0
- data/.gitignore +2 -3
- data/.gitmodules +5 -2
- data/.jshintrc +1 -8
- data/.rspec +1 -1
- data/.travis.yml +15 -23
- data/CHANGELOG.md +511 -326
- data/CODE_OF_CONDUCT.md +13 -15
- data/CONTRIBUTING.md +26 -216
- data/Gemfile +20 -12
- data/Guardfile +2 -2
- data/HACKING.md +230 -0
- data/README.md +6 -7
- data/bin/opal-mspec +1 -1
- data/config.ru +2 -2
- data/docs/faq.md +1 -1
- data/docs/source_maps.md +1 -1
- data/lib/opal.rb +1 -0
- data/lib/opal/builder.rb +1 -1
- data/lib/opal/cli.rb +30 -28
- data/lib/opal/cli_options.rb +3 -0
- data/lib/opal/cli_runners.rb +14 -1
- data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
- data/lib/opal/cli_runners/nashorn.rb +2 -2
- data/lib/opal/cli_runners/nodejs.rb +2 -2
- data/lib/opal/cli_runners/phantom.js +24 -0
- data/lib/opal/cli_runners/phantomjs.rb +10 -10
- data/lib/opal/cli_runners/server.rb +3 -3
- data/lib/opal/compiler.rb +43 -4
- data/lib/opal/config.rb +3 -1
- data/lib/opal/errors.rb +13 -0
- data/lib/opal/fragment.rb +0 -13
- data/lib/opal/nodes.rb +10 -0
- data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
- data/lib/opal/nodes/args/kwarg.rb +29 -0
- data/lib/opal/nodes/args/kwoptarg.rb +29 -0
- data/lib/opal/nodes/args/kwrestarg.rb +39 -0
- data/lib/opal/nodes/args/mlhsarg.rb +79 -0
- data/lib/opal/nodes/args/normarg.rb +26 -0
- data/lib/opal/nodes/args/optarg.rb +27 -0
- data/lib/opal/nodes/args/post_args.rb +200 -0
- data/lib/opal/nodes/args/post_kwargs.rb +31 -0
- data/lib/opal/nodes/args/restarg.rb +33 -0
- data/lib/opal/nodes/base.rb +12 -0
- data/lib/opal/nodes/call.rb +92 -33
- data/lib/opal/nodes/def.rb +26 -169
- data/lib/opal/nodes/hash.rb +10 -4
- data/lib/opal/nodes/helpers.rb +6 -3
- data/lib/opal/nodes/inline_args.rb +61 -0
- data/lib/opal/nodes/iter.rb +73 -82
- data/lib/opal/nodes/logic.rb +12 -2
- data/lib/opal/nodes/masgn.rb +1 -2
- data/lib/opal/nodes/node_with_args.rb +141 -0
- data/lib/opal/nodes/rescue.rb +121 -43
- data/lib/opal/nodes/scope.rb +24 -5
- data/lib/opal/nodes/super.rb +122 -54
- data/lib/opal/nodes/top.rb +0 -12
- data/lib/opal/nodes/yield.rb +2 -13
- data/lib/opal/parser.rb +67 -39
- data/lib/opal/parser/grammar.rb +3319 -2961
- data/lib/opal/parser/grammar.y +234 -46
- data/lib/opal/parser/lexer.rb +105 -17
- data/lib/opal/parser/sexp.rb +4 -0
- data/lib/opal/paths.rb +4 -0
- data/lib/opal/regexp_anchors.rb +19 -1
- data/lib/opal/sprockets.rb +21 -18
- data/lib/opal/sprockets/environment.rb +0 -8
- data/lib/opal/sprockets/processor.rb +13 -16
- data/lib/opal/sprockets/server.rb +6 -12
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +1 -0
- data/opal/corelib/array.rb +209 -131
- data/opal/corelib/basic_object.rb +7 -3
- data/opal/corelib/class.rb +11 -17
- data/opal/corelib/constants.rb +2 -2
- data/opal/corelib/enumerable.rb +178 -355
- data/opal/corelib/enumerator.rb +3 -46
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +13 -1
- data/opal/corelib/hash.rb +26 -56
- data/opal/corelib/helpers.rb +10 -0
- data/opal/corelib/kernel.rb +6 -3
- data/opal/corelib/module.rb +62 -31
- data/opal/corelib/number.rb +7 -16
- data/opal/corelib/proc.rb +24 -9
- data/opal/corelib/range.rb +4 -13
- data/opal/corelib/runtime.js +515 -378
- data/opal/corelib/string.rb +21 -49
- data/opal/corelib/struct.rb +50 -35
- data/opal/corelib/unsupported.rb +18 -30
- data/opal/opal.rb +0 -1
- data/opal/opal/mini.rb +1 -0
- data/spec/README.md +6 -4
- data/spec/filters/bugs/array.rb +0 -42
- data/spec/filters/bugs/basicobject.rb +0 -2
- data/spec/filters/bugs/bigdecimal.rb +160 -0
- data/spec/filters/bugs/class.rb +0 -5
- data/spec/filters/bugs/date.rb +1 -48
- data/spec/filters/bugs/enumerable.rb +4 -12
- data/spec/filters/bugs/enumerator.rb +0 -1
- data/spec/filters/bugs/exception.rb +4 -3
- data/spec/filters/bugs/float.rb +4 -2
- data/spec/filters/bugs/kernel.rb +25 -10
- data/spec/filters/bugs/language.rb +119 -68
- data/spec/filters/bugs/method.rb +135 -0
- data/spec/filters/bugs/module.rb +13 -28
- data/spec/filters/bugs/proc.rb +18 -8
- data/spec/filters/bugs/range.rb +0 -3
- data/spec/filters/bugs/rational.rb +4 -0
- data/spec/filters/bugs/regexp.rb +68 -36
- data/spec/filters/bugs/string.rb +1 -1
- data/spec/filters/bugs/struct.rb +0 -12
- data/spec/filters/bugs/time.rb +1 -0
- data/spec/filters/bugs/unboundmethod.rb +2 -1
- data/spec/filters/unsupported/freeze.rb +3 -1
- data/spec/filters/unsupported/language.rb +0 -7
- data/spec/filters/unsupported/privacy.rb +7 -6
- data/spec/filters/unsupported/string.rb +10 -0
- data/spec/filters/unsupported/struct.rb +3 -0
- data/spec/filters/unsupported/symbol.rb +9 -0
- data/spec/filters/unsupported/taint.rb +0 -3
- data/spec/filters/unsupported/thread.rb +1 -0
- data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
- data/spec/lib/cli_spec.rb +42 -1
- data/spec/lib/compiler/call_spec.rb +700 -0
- data/spec/lib/compiler_spec.rb +46 -28
- data/spec/lib/config_spec.rb +13 -0
- data/spec/lib/parser/call_spec.rb +18 -0
- data/spec/lib/parser/def_spec.rb +29 -0
- data/spec/lib/parser/iter_spec.rb +15 -15
- data/spec/lib/parser/lambda_spec.rb +153 -12
- data/spec/lib/parser/string_spec.rb +5 -0
- data/spec/lib/parser/undef_spec.rb +1 -1
- data/spec/lib/parser/variables_spec.rb +24 -0
- data/spec/lib/paths_spec.rb +12 -5
- data/spec/lib/spec_helper.rb +5 -0
- data/spec/lib/sprockets/processor_spec.rb +6 -5
- data/spec/lib/sprockets_spec.rb +8 -0
- data/spec/mspec-opal/formatters.rb +188 -0
- data/spec/mspec-opal/runner.rb +193 -0
- data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
- data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
- data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
- data/spec/opal/core/kernel/loop_spec.rb +1 -1
- data/spec/opal/core/kernel/raise_spec.rb +1 -1
- data/spec/opal/core/language/heredoc_spec.rb +42 -0
- data/spec/opal/core/language/rescue_spec.rb +18 -0
- data/spec/opal/core/language_spec.rb +22 -0
- data/spec/opal/core/module/const_defined_spec.rb +1 -2
- data/spec/opal/core/module/name_spec.rb +6 -0
- data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
- data/spec/opal/core/runtime/rescue_spec.rb +12 -2
- data/spec/opal/core/runtime/super_spec.rb +1 -0
- data/spec/opal/core/string_spec.rb +21 -0
- data/spec/opal/stdlib/js_spec.rb +1 -1
- data/spec/opal/stdlib/native/hash_spec.rb +7 -0
- data/spec/opal/stdlib/promise/always_spec.rb +24 -5
- data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
- data/spec/opal/stdlib/promise/then_spec.rb +13 -5
- data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
- data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
- data/spec/ruby_specs +122 -0
- data/spec/spec_helper.rb +3 -15
- data/stdlib/base64.rb +51 -121
- data/stdlib/bigdecimal.rb +231 -0
- data/stdlib/bigdecimal/bignumber.js.rb +11 -0
- data/stdlib/bigdecimal/kernel.rb +5 -0
- data/stdlib/date.rb +252 -10
- data/stdlib/native.rb +38 -38
- data/stdlib/nodejs/dir.rb +8 -6
- data/stdlib/nodejs/file.rb +28 -3
- data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
- data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
- data/stdlib/nodejs/require.rb +1 -1
- data/stdlib/nodejs/yaml.rb +3 -2
- data/stdlib/opal-parser.rb +7 -2
- data/stdlib/pathname.rb +23 -1
- data/stdlib/phantomjs.rb +10 -0
- data/stdlib/promise.rb +38 -23
- data/tasks/building.rake +3 -3
- data/tasks/testing.rake +27 -14
- data/tasks/testing/mspec_special_calls.rb +1 -1
- data/tasks/testing/sprockets-phantomjs.js +4 -0
- data/test/opal/test_keyword.rb +110 -110
- data/test/opal/unsupported_and_bugs.rb +30 -0
- data/vendored-minitest/minitest/assertions.rb +1 -1
- metadata +65 -15
- data/.spectator +0 -2
- data/.spectator-mspec +0 -3
- data/opal/corelib/array/inheritance.rb +0 -127
- data/spec/rubyspecs +0 -139
data/spec/filters/bugs/string.rb
CHANGED
@@ -35,7 +35,7 @@ opal_filter "String" do
|
|
35
35
|
fails "String#getbyte returns nil for out-of-bound indexes"
|
36
36
|
fails "String#getbyte starts indexing at 0"
|
37
37
|
fails "String#slice with Range calls to_int on range arguments"
|
38
|
-
fails "String#split with Regexp includes all captures in the result array"
|
38
|
+
fails "String#split with Regexp includes all captures in the result array" # fails with phantomjs
|
39
39
|
fails "String#to_c returns a Complex object"
|
40
40
|
fails "String#to_c returns a complex number with 0 as the real part, 0 as the imaginary part for unrecognised Strings"
|
41
41
|
fails "String#to_c understands 'a+bi' to mean a complex number with 'a' as the real part, 'b' as the imaginary"
|
data/spec/filters/bugs/struct.rb
CHANGED
@@ -1,15 +1,3 @@
|
|
1
1
|
opal_filter "Struct" do
|
2
2
|
fails "Struct#hash returns the same fixnum for structs with the same content"
|
3
|
-
fails "Struct#initialize can be overriden"
|
4
|
-
fails "Struct#inspect returns a string representation of some kind"
|
5
|
-
fails "Struct#members does not override the instance accessor method"
|
6
|
-
fails "Struct.new calls to_str on its first argument (constant name)"
|
7
|
-
fails "Struct.new creates a new anonymous class with nil first argument"
|
8
|
-
fails "Struct.new does not create a constant with symbol as first argument"
|
9
|
-
fails "Struct.new fails with invalid constant name as first argument"
|
10
|
-
fails "Struct.new on subclasses creates a constant in subclass' namespace"
|
11
|
-
fails "Struct.new on subclasses fails with too many arguments"
|
12
|
-
fails "Struct.new raises a TypeError if object doesn't respond to to_sym"
|
13
|
-
fails "Struct.new raises a TypeError if object is not a Symbol"
|
14
|
-
fails "Struct.new with a block passes same struct class to the block"
|
15
3
|
end
|
data/spec/filters/bugs/time.rb
CHANGED
@@ -24,5 +24,6 @@ opal_filter "Time" do
|
|
24
24
|
fails "Time#to_f returns the float number of seconds + usecs since the epoch"
|
25
25
|
fails "Time#to_s formats the fixed offset time following the pattern 'yyyy-MM-dd HH:mm:ss +/-HHMM'"
|
26
26
|
fails "Time#zone Encoding.default_internal is set returns an ASCII string"
|
27
|
+
fails "Time.at passed Numeric passed BigDecimal doesn't round input value"
|
27
28
|
fails "Time.at passed Numeric roundtrips a Rational produced by #to_r"
|
28
29
|
end
|
@@ -4,6 +4,7 @@ opal_filter "UnboundMethod" do
|
|
4
4
|
fails "UnboundMethod#== returns true if objects refer to the same method"
|
5
5
|
fails "UnboundMethod#== returns true if same method is extracted from the same subclass"
|
6
6
|
fails "UnboundMethod#arity for a Method generated by respond_to_missing? returns -1"
|
7
|
+
fails "UnboundMethod#arity returns negative values for method definition 'def m(a=1, *b, c:, d: 2, **k, &l) end'"
|
7
8
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(*) end\n def n(*a) end"
|
8
9
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(**k, &l) end\n def n(*a, **k) end\n def o(a: 1, b: 2, **k) end"
|
9
10
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(*a, b) end\n def n(*a, b, c) end\n def o(*a, b, c, d) end"
|
@@ -15,7 +16,6 @@ opal_filter "UnboundMethod" do
|
|
15
16
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(a: 1) end\n def n(a: 1, b: 2) end"
|
16
17
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(a=1) end\n def n(a=1, b=2) end"
|
17
18
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(a=1, *b) end\n def n(a=1, b=2, *c) end"
|
18
|
-
fails "UnboundMethod#arity returns negative values for method definition \n def m(a=1, *b, c:, d: 2, **k, &l) end"
|
19
19
|
fails "UnboundMethod#arity returns negative values for method definition \n def m(a=1, b: 2) end\n def n(*a, b: 1) end\n def o(a=1, b: 2) end\n def p(a=1, *b, c: 2, &l) end"
|
20
20
|
fails "UnboundMethod#bind Method returned for obj is equal to one directly returned by obj.method"
|
21
21
|
fails "UnboundMethod#bind raises TypeError if object is not kind_of? the Module the method defined in"
|
@@ -25,6 +25,7 @@ opal_filter "UnboundMethod" do
|
|
25
25
|
fails "UnboundMethod#hash returns the same value for user methods that are eql?"
|
26
26
|
fails "UnboundMethod#inspect the String shows the method name, Module defined in and Module extracted from"
|
27
27
|
fails "UnboundMethod#owner returns the class/module it was defined in"
|
28
|
+
fails "UnboundMethod#owner returns the new owner for aliased methods on singleton classes"
|
28
29
|
fails "UnboundMethod#owner returns the new owner for aliased methods"
|
29
30
|
fails "UnboundMethod#source_location returns the last place the method was defined"
|
30
31
|
fails "UnboundMethod#source_location returns the location of the original method even if it was aliased"
|
@@ -5,6 +5,8 @@ opal_filter "freezing" do
|
|
5
5
|
fails "Array#rotate! raises a RuntimeError on a frozen array"
|
6
6
|
fails "Array#select! on frozen objects returns an Enumerator if no block is given"
|
7
7
|
fails "Array#sort does not freezes self during being sorted"
|
8
|
+
fails "Array#sort_by! raises a RuntimeError on a frozen array"
|
9
|
+
fails "Array#sort_by! raises a RuntimeError on an empty frozen array"
|
8
10
|
fails "Date constants freezes MONTHNAMES, DAYNAMES, ABBR_MONTHNAMES, ABBR_DAYSNAMES"
|
9
11
|
fails "Enumerable#sort doesn't raise an error if #to_a returns a frozen Array"
|
10
12
|
fails "Hash#== compares keys with matching hash codes via eql?"
|
@@ -25,11 +27,11 @@ opal_filter "freezing" do
|
|
25
27
|
fails "Kernel#freeze prevents self from being further modified"
|
26
28
|
fails "Kernel#freeze returns self"
|
27
29
|
fails "Kernel#frozen? on a Symbol returns true"
|
28
|
-
fails "Kernel#frozen? on true, false and nil returns false"
|
29
30
|
fails "Kernel#frozen? returns true if self is frozen"
|
30
31
|
fails "MatchData#string returns a frozen copy of the match string"
|
31
32
|
fails "Module#alias_method raises RuntimeError if frozen"
|
32
33
|
fails "Module#append_features when other is frozen raises a RuntimeError before appending self"
|
34
|
+
fails "Module#const_set on a frozen module raises a RuntimeError before setting the name"
|
33
35
|
fails "Module#extend_object when given a frozen object raises a RuntimeError before extending the object"
|
34
36
|
fails "Module#remove_method on frozen instance does not raise exceptions when no arguments given"
|
35
37
|
fails "Module#remove_method on frozen instance raises a RuntimeError when passed a missing name"
|
@@ -6,13 +6,6 @@ opal_filter "language" do
|
|
6
6
|
fails "Magic comment is case-insensitive"
|
7
7
|
fails "Magic comment must be at the first line"
|
8
8
|
fails "Magic comment must be the first token of the line"
|
9
|
-
fails "Regexps with modifers supports /x (extended syntax)"
|
10
|
-
fails "Regexps with modifers supports /o (once)"
|
11
|
-
fails "Regexps with modifers invokes substitutions for /o only once"
|
12
|
-
fails "Regexps with modifers supports modifier combinations"
|
13
|
-
fails "Regexps with modifers supports (?imx-imx) (inline modifiers)"
|
14
|
-
fails "Regexps with modifers supports (?imx-imx:expr) (scoped inline modifiers)"
|
15
|
-
fails "Regexps with modifers supports ASII/Unicode modifiers"
|
16
9
|
fails "The defined? keyword for pseudo-variables returns 'expression' for __ENCODING__"
|
17
10
|
fails "The defined? keyword when called with a method name having a module as receiver returns nil if the method is private"
|
18
11
|
fails "The defined? keyword when called with a method name having a module as receiver returns nil if the method is protected"
|
@@ -16,9 +16,10 @@ opal_filter "private" do
|
|
16
16
|
fails "Module#attr_accessor is a private method"
|
17
17
|
fails "Module#attr_reader is a private method"
|
18
18
|
fails "Module#attr_writer is a private method"
|
19
|
-
fails "Module#
|
19
|
+
fails "Module#define_method when name is not a special private name given an UnboundMethod sets the visibility of the method to the current visibility"
|
20
20
|
fails "Module#extend_object is a private method"
|
21
21
|
fails "Module#extend_object is called even when private"
|
22
|
+
fails "Module#extended is private in its default implementation"
|
22
23
|
fails "Module#included is private in its default implementation"
|
23
24
|
fails "Module#method_added is a private instance method"
|
24
25
|
fails "Module#method_removed is a private instance method"
|
@@ -26,11 +27,11 @@ opal_filter "private" do
|
|
26
27
|
fails "Module#module_function is a private method"
|
27
28
|
fails "Module#module_function with specific method names can make accessible private methods"
|
28
29
|
fails "Module#module_function with specific method names makes the instance methods private"
|
29
|
-
fails "Module#prepended is a private method"
|
30
30
|
fails "Module#prepend_features is a private method"
|
31
|
+
fails "Module#prepended is a private method"
|
31
32
|
fails "Module#private is a private method"
|
32
|
-
fails "Module#private makes a public Object instance method private in a new module"
|
33
33
|
fails "Module#private makes a public Object instance method private in Kernel"
|
34
|
+
fails "Module#private makes a public Object instance method private in a new module"
|
34
35
|
fails "Module#private makes the target method uncallable from other types"
|
35
36
|
fails "Module#private raises a NameError when given an undefined name"
|
36
37
|
fails "Module#private returns self"
|
@@ -67,8 +68,8 @@ opal_filter "private" do
|
|
67
68
|
fails "Module#private_method_defined? raises a TypeError if passed nil"
|
68
69
|
fails "Module#private_method_defined? returns true if the named private method is defined by module or its ancestors"
|
69
70
|
fails "Module#protected is a private method"
|
70
|
-
fails "Module#protected makes a public Object instance method protected in a new module"
|
71
71
|
fails "Module#protected makes a public Object instance method protected in Kernel"
|
72
|
+
fails "Module#protected makes a public Object instance method protected in a new module"
|
72
73
|
fails "Module#protected makes an existing class method protected"
|
73
74
|
fails "Module#protected raises a NameError when given an undefined name"
|
74
75
|
fails "Module#protected returns self"
|
@@ -96,8 +97,8 @@ opal_filter "private" do
|
|
96
97
|
fails "Module#protected_method_defined? raises a TypeError if passed nil"
|
97
98
|
fails "Module#protected_method_defined? returns true if the named protected method is defined by module or its ancestors"
|
98
99
|
fails "Module#public is a private method"
|
99
|
-
fails "Module#public makes a private Object instance method public in a new module"
|
100
100
|
fails "Module#public makes a private Object instance method public in Kernel"
|
101
|
+
fails "Module#public makes a private Object instance method public in a new module"
|
101
102
|
fails "Module#public raises a NameError when given an undefined name"
|
102
103
|
fails "Module#public returns self"
|
103
104
|
fails "Module#public without arguments affects evaled method definitions when itself is outside the eval"
|
@@ -131,6 +132,6 @@ opal_filter "private" do
|
|
131
132
|
fails "Module#remove_method is a private method"
|
132
133
|
fails "Module#undef_method is a private method"
|
133
134
|
fails "OpenStruct#initialize is private"
|
134
|
-
fails "OpenStruct#table is protected"
|
135
135
|
fails "OpenStruct#new_ostruct_member is protected"
|
136
|
+
fails "OpenStruct#table is protected"
|
136
137
|
end
|
@@ -233,6 +233,7 @@ opal_filter "String" do
|
|
233
233
|
fails "String#insert with index, other raises an IndexError if the index is beyond string"
|
234
234
|
fails "String#insert with index, other taints self if string to insert is tainted"
|
235
235
|
fails "String#inspect returns a string with non-printing characters replaced by \\x notation"
|
236
|
+
fails "String#inspect returns a string with a NUL character replaced by \\x notation"
|
236
237
|
fails "String#inspect taints the result if self is tainted"
|
237
238
|
fails "String#inspect untrusts the result if self is untrusted"
|
238
239
|
fails "String#lines does not care if the string is modified while substituting"
|
@@ -523,4 +524,13 @@ opal_filter "String" do
|
|
523
524
|
fails "String.new returns a binary String"
|
524
525
|
fails "String.new returns a fully-formed String"
|
525
526
|
fails "String.new returns a new string given a string argument"
|
527
|
+
fails "Ruby character strings taints the result of interpolation when an interpolated value is tainted"
|
528
|
+
fails "Ruby character strings untrusts the result of interpolation when an interpolated value is untrusted"
|
529
|
+
fails "Ruby character strings backslashes follow the same rules as interpolation"
|
530
|
+
fails "Ruby character strings are produced from control character shortcuts"
|
531
|
+
fails "Ruby character strings Unicode escaping can be done with \\u{} and one to six hex digits"
|
532
|
+
fails "Ruby character strings Unicode escaping with US-ASCII source encoding produces an ASCII string when escaping ASCII characters via \\u"
|
533
|
+
fails "Ruby character strings Unicode escaping with US-ASCII source encoding produces an ASCII string when escaping ASCII characters via \\u{}"
|
534
|
+
fails "Ruby character strings Unicode escaping with US-ASCII source encoding produces a UTF-8-encoded string when escaping non-ASCII characters via \\u"
|
535
|
+
fails "Ruby character strings Unicode escaping with US-ASCII source encoding produces a UTF-8-encoded string when escaping non-ASCII characters via \\u{}"
|
526
536
|
end
|
@@ -1,3 +1,6 @@
|
|
1
1
|
opal_filter "Struct" do
|
2
2
|
fails "Struct#initialize is private"
|
3
|
+
fails "Struct.new does not create a constant with symbol as first argument"
|
4
|
+
fails "Struct.new fails with invalid constant name as first argument" # this invalid name gets interpreted as a struct member
|
5
|
+
fails "Struct.new raises a TypeError if object is not a Symbol"
|
3
6
|
end
|
@@ -1,5 +1,14 @@
|
|
1
1
|
opal_filter "Symbol" do
|
2
2
|
fails "Numeric#coerce raises a TypeError when passed a Symbol"
|
3
3
|
fails "Fixnum#coerce raises a TypeError when given an Object that does not respond to #to_f"
|
4
|
+
fails "Symbol#to_proc produces a proc that always returns [[:rest]] for #parameters"
|
4
5
|
fails "The throw keyword does not convert strings to a symbol"
|
6
|
+
fails "Module#const_get raises a NameError if a Symbol has a toplevel scope qualifier"
|
7
|
+
fails "Module#const_get raises a NameError if a Symbol is a scoped constant name"
|
8
|
+
fails "A Symbol literal is a ':' followed by any number of valid characters"
|
9
|
+
fails "A Symbol literal is a ':' followed by a single- or double-quoted string that may contain otherwise invalid characters"
|
10
|
+
fails "A Symbol literal is converted to a literal, unquoted representation if the symbol contains only valid characters"
|
11
|
+
fails "A Symbol literal can be created by the %s-delimited expression"
|
12
|
+
fails "A Symbol literal can contain null in the string"
|
13
|
+
fails "A Symbol literal can be an empty string"
|
5
14
|
end
|
@@ -1,9 +1,6 @@
|
|
1
1
|
opal_filter "taint" do
|
2
2
|
fails "Hash#reject with extra state does not taint the resulting hash"
|
3
3
|
|
4
|
-
fails "Range#to_s ignores own tainted status"
|
5
|
-
fails "Range#inspect ignores own tainted status"
|
6
|
-
|
7
4
|
fails "String#% doesn't taint the result for %e when argument is tainted"
|
8
5
|
fails "String#% doesn't taint the result for %E when argument is tainted"
|
9
6
|
fails "String#% doesn't taint the result for %f when argument is tainted"
|
@@ -2,4 +2,5 @@ opal_filter "Thread" do
|
|
2
2
|
fails "StandardError is a superclass of ThreadError"
|
3
3
|
fails "The throw keyword raises an ArgumentError if used to exit a thread"
|
4
4
|
fails "The throw keyword clears the current exception"
|
5
|
+
fails "Module#autoload loads the registered constant even if the constant was already loaded by another thread"
|
5
6
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'lib/spec_helper'
|
2
|
+
require 'opal/cli_runners/phantomjs'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
describe Opal::CliRunners::Phantomjs do
|
6
|
+
# FIXME: Unfotunately there are some issues on jruby and 1.9.3, probably
|
7
|
+
# related to IO.pipe and process spawning in general.
|
8
|
+
before { pending if RUBY_PLATFORM == 'java' or RUBY_VERSION == '1.9.3' }
|
9
|
+
|
10
|
+
it 'accepts arguments' do
|
11
|
+
expect(output_of(%{
|
12
|
+
var ARGV = JSON.parse(callPhantom(['argv']));
|
13
|
+
callPhantom(['stdout', JSON.stringify(ARGV)]);
|
14
|
+
callPhantom(['exit', 0]);
|
15
|
+
}, ['foo', 'bar'])).to eq('["foo","bar"]')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'sets env' do
|
19
|
+
ENV['FOO'] = 'BAR'
|
20
|
+
expect(output_of(%{
|
21
|
+
var ENV = JSON.parse(callPhantom(['env']));
|
22
|
+
callPhantom(['stdout', JSON.stringify(ENV)]);
|
23
|
+
callPhantom(['exit', 0]);
|
24
|
+
}, [])).to include(%{"FOO":"BAR"})
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def output_of(*args)
|
31
|
+
read, write = IO.pipe
|
32
|
+
runner = described_class.new(output: write)
|
33
|
+
|
34
|
+
runner.run(*args)
|
35
|
+
write.close
|
36
|
+
|
37
|
+
return read.read
|
38
|
+
end
|
39
|
+
end
|
data/spec/lib/cli_spec.rb
CHANGED
@@ -5,7 +5,7 @@ require 'stringio'
|
|
5
5
|
describe Opal::CLI do
|
6
6
|
let(:fake_stdout) { StringIO.new }
|
7
7
|
let(:file) { File.expand_path('../fixtures/opal_file.rb', __FILE__) }
|
8
|
-
let(:options) {
|
8
|
+
let(:options) { {} }
|
9
9
|
subject(:cli) { described_class.new(options) }
|
10
10
|
|
11
11
|
context 'with a file' do
|
@@ -14,6 +14,14 @@ describe Opal::CLI do
|
|
14
14
|
it 'runs the file' do
|
15
15
|
expect_output_of{ subject.run }.to eq("hi from opal!\n")
|
16
16
|
end
|
17
|
+
|
18
|
+
context 'with lib_only: true' do
|
19
|
+
let(:options) { super().merge lib_only: true }
|
20
|
+
|
21
|
+
it 'raises ArgumentError' do
|
22
|
+
expect{subject.run}.to raise_error(ArgumentError)
|
23
|
+
end
|
24
|
+
end
|
17
25
|
end
|
18
26
|
|
19
27
|
describe ':evals option' do
|
@@ -21,6 +29,14 @@ describe Opal::CLI do
|
|
21
29
|
it 'raises ArgumentError' do
|
22
30
|
expect { subject.run }.to raise_error(ArgumentError)
|
23
31
|
end
|
32
|
+
|
33
|
+
context 'with lib_only: true' do
|
34
|
+
let(:options) { super().merge lib_only: true }
|
35
|
+
|
36
|
+
it 'does not raise an error' do
|
37
|
+
expect{subject.run}.not_to raise_error
|
38
|
+
end
|
39
|
+
end
|
24
40
|
end
|
25
41
|
|
26
42
|
context 'with one eval' do
|
@@ -29,6 +45,14 @@ describe Opal::CLI do
|
|
29
45
|
it 'executes the code' do
|
30
46
|
expect_output_of{ subject.run }.to eq("hello\n")
|
31
47
|
end
|
48
|
+
|
49
|
+
context 'with lib_only: true' do
|
50
|
+
let(:options) { super().merge lib_only: true }
|
51
|
+
|
52
|
+
it 'raises ArgumentError' do
|
53
|
+
expect{subject.run}.to raise_error(ArgumentError)
|
54
|
+
end
|
55
|
+
end
|
32
56
|
end
|
33
57
|
|
34
58
|
context 'with many evals' do
|
@@ -56,6 +80,23 @@ describe Opal::CLI do
|
|
56
80
|
end
|
57
81
|
end
|
58
82
|
|
83
|
+
describe ':lib_only option' do
|
84
|
+
context 'when false' do
|
85
|
+
let(:options) { {lib_only: false, compile: true, evals: [''], skip_opal_require: true, no_exit: true} }
|
86
|
+
it 'appends an empty code block at the end of the source' do
|
87
|
+
expect_output_of{ subject.run }.to include("function(Opal)")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when true' do
|
92
|
+
let(:options) { {lib_only: true, compile: true, skip_opal_require: true, no_exit: true} }
|
93
|
+
|
94
|
+
it 'does not append code block at the end of the source' do
|
95
|
+
expect_output_of{ subject.run }.to eq("\n")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
59
100
|
describe ':requires options' do
|
60
101
|
context 'with an absolute path' do
|
61
102
|
let(:options) { {:requires => [file], :evals => ['']} }
|
@@ -0,0 +1,700 @@
|
|
1
|
+
require 'lib/spec_helper'
|
2
|
+
|
3
|
+
describe Opal::Compiler do
|
4
|
+
let(:compiler) { Opal::Compiler.new(method) }
|
5
|
+
|
6
|
+
subject(:compiled) { compiler.compile }
|
7
|
+
|
8
|
+
describe 'defined' do
|
9
|
+
let(:method) do
|
10
|
+
<<-CODE
|
11
|
+
def some_method
|
12
|
+
defined? super()
|
13
|
+
end
|
14
|
+
CODE
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'outside block' do
|
18
|
+
context 'method missing on' do
|
19
|
+
it { is_expected.to include "return (!(Opal.find_super_dispatcher(self, 'some_method', TMP_1, true).$$stub) ? \"super\" : nil);" }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'method missing off' do
|
23
|
+
let(:compiler) { Opal::Compiler.new(method, method_missing: false) }
|
24
|
+
|
25
|
+
it { is_expected.to include "return ((Opal.find_super_dispatcher(self, 'some_method', TMP_1, true)) != null ? \"super\" : nil);" }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'inside block' do
|
30
|
+
context 'implicit' do
|
31
|
+
let(:method) { 'lambda { defined? super }' }
|
32
|
+
|
33
|
+
it { is_expected.to include "return (!(Opal.find_iter_super_dispatcher(self, null, (TMP_1.$$def || null), true, false).$$stub) ? \"super\" : nil)}, TMP_1.$$s = self, TMP_1), $a).call($b)" }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'explicit' do
|
37
|
+
let(:method) { 'lambda { defined? super() }' }
|
38
|
+
|
39
|
+
it { is_expected.to include "return (!(Opal.find_iter_super_dispatcher(self, null, (TMP_1.$$def || null), true, false).$$stub) ? \"super\" : nil)}, TMP_1.$$s = self, TMP_1), $a).call($b)" }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'call' do
|
45
|
+
context 'regular method' do
|
46
|
+
context 'formal parameters with splat' do
|
47
|
+
context 'and block with actual params of' do
|
48
|
+
let(:method) do
|
49
|
+
<<-CODE
|
50
|
+
def some_method(*stuff, &block2)
|
51
|
+
#{invocation}
|
52
|
+
end
|
53
|
+
CODE
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'splat' do
|
57
|
+
context 'with block' do
|
58
|
+
context 'via variable' do
|
59
|
+
let(:invocation) { 'call_method(*stuff) {|a| foobar }' }
|
60
|
+
|
61
|
+
it do
|
62
|
+
is_expected.to include <<-CODE
|
63
|
+
return ($b = ($c = self).$call_method, $b.$$p = (TMP_2 = function(a){var self = TMP_2.$$s || this;
|
64
|
+
if (a == null) a = nil;
|
65
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $b).apply($c, Opal.to_a(stuff));
|
66
|
+
CODE
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'via reference' do
|
71
|
+
let(:invocation) { 'call_method *stuff, &block2' }
|
72
|
+
|
73
|
+
it { is_expected.to include "return ($b = ($c = self).$call_method, $b.$$p = block2.$to_proc(), $b).apply($c, Opal.to_a(stuff));" }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'no splat' do
|
79
|
+
context 'with block' do
|
80
|
+
context 'via variable' do
|
81
|
+
let(:invocation) { 'call_method {|a| foobar }' }
|
82
|
+
|
83
|
+
it do
|
84
|
+
is_expected.to include <<-CODE
|
85
|
+
return ($b = ($c = self).$call_method, $b.$$p = (TMP_2 = function(a){var self = TMP_2.$$s || this;
|
86
|
+
if (a == null) a = nil;
|
87
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $b).call($c);
|
88
|
+
CODE
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'via reference' do
|
93
|
+
let(:invocation) { 'call_method &block2' }
|
94
|
+
|
95
|
+
it { is_expected.to include "return ($b = ($c = self).$call_method, $b.$$p = block2.$to_proc(), $b).call($c);" }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'actual params of' do
|
102
|
+
let(:method) do
|
103
|
+
<<-CODE
|
104
|
+
def some_method(*stuff)
|
105
|
+
#{invocation}
|
106
|
+
end
|
107
|
+
CODE
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'splat' do
|
111
|
+
context 'with block' do
|
112
|
+
context 'via variable' do
|
113
|
+
let(:invocation) { 'call_method(*stuff) {|a| foobar }' }
|
114
|
+
|
115
|
+
it do
|
116
|
+
is_expected.to include <<-CODE
|
117
|
+
return ($b = ($c = self).$call_method, $b.$$p = (TMP_1 = function(a){var self = TMP_1.$$s || this;
|
118
|
+
if (a == null) a = nil;
|
119
|
+
return self.$foobar()}, TMP_1.$$s = self, TMP_1), $b).apply($c, Opal.to_a(stuff));
|
120
|
+
CODE
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'via reference' do
|
125
|
+
let(:invocation) { 'call_method *stuff, &block2' }
|
126
|
+
|
127
|
+
it { is_expected.to include "return ($b = ($c = self).$call_method, $b.$$p = self.$block2().$to_proc(), $b).apply($c, Opal.to_a(stuff));" }
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'no splat' do
|
133
|
+
context 'with block' do
|
134
|
+
context 'via variable' do
|
135
|
+
let(:invocation) { 'call_method {|a| foobar }' }
|
136
|
+
|
137
|
+
it do
|
138
|
+
is_expected.to include <<-CODE
|
139
|
+
return ($b = ($c = self).$call_method, $b.$$p = (TMP_1 = function(a){var self = TMP_1.$$s || this;
|
140
|
+
if (a == null) a = nil;
|
141
|
+
return self.$foobar()}, TMP_1.$$s = self, TMP_1), $b).call($c);
|
142
|
+
CODE
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'via reference' do
|
147
|
+
let(:invocation) { 'call_method &block2' }
|
148
|
+
|
149
|
+
it { is_expected.to include "return ($b = ($c = self).$call_method, $b.$$p = self.$block2().$to_proc(), $b).call($c);" }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
context 'no formal parameters with actual params of' do
|
157
|
+
let(:method) do
|
158
|
+
<<-CODE
|
159
|
+
def regular_method
|
160
|
+
#{invocation}
|
161
|
+
end
|
162
|
+
CODE
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'no splat' do
|
166
|
+
let(:invocation) { 'another_method(42)' }
|
167
|
+
|
168
|
+
it { is_expected.to include 'return self.$another_method(42);' }
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'splat' do
|
172
|
+
context 'with no block' do
|
173
|
+
let(:invocation) { 'another_method(*args)' }
|
174
|
+
|
175
|
+
it { is_expected.to include 'return ($a = self).$another_method.apply($a, Opal.to_a(self.$args()));' }
|
176
|
+
end
|
177
|
+
|
178
|
+
context 'with block' do
|
179
|
+
context 'via variable' do
|
180
|
+
let(:invocation) { 'another_method(*args) {|b| foobar }' }
|
181
|
+
|
182
|
+
it { is_expected.to include "return ($a = ($b = self).$another_method, $a.$$p = (TMP_1 = function(b){var self = TMP_1.$$s || this;\nif (b == null) b = nil;\n return self.$foobar()}, TMP_1.$$s = self, TMP_1), $a).apply($b, Opal.to_a(self.$args()));" }
|
183
|
+
end
|
184
|
+
|
185
|
+
context 'via reference' do
|
186
|
+
let(:invocation) { 'another_method(*args, &block2)' }
|
187
|
+
|
188
|
+
it { is_expected.to include "return ($a = ($b = self).$another_method, $a.$$p = self.$block2().$to_proc(), $a).apply($b, Opal.to_a(self.$args()));" }
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'block' do
|
194
|
+
context 'via variable' do
|
195
|
+
let(:invocation) { 'another_method {|b| foobar }' }
|
196
|
+
|
197
|
+
it { is_expected.to include "return ($a = ($b = self).$another_method, $a.$$p = (TMP_1 = function(b){var self = TMP_1.$$s || this;\nif (b == null) b = nil;\n return self.$foobar()}, TMP_1.$$s = self, TMP_1), $a).call($b);" }
|
198
|
+
end
|
199
|
+
|
200
|
+
context 'via reference' do
|
201
|
+
let(:invocation) { 'another_method(&block)' }
|
202
|
+
|
203
|
+
it { is_expected.to include 'return ($a = ($b = self).$another_method, $a.$$p = self.$block().$to_proc(), $a).call($b);' }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'super' do
|
210
|
+
context 'normal method' do
|
211
|
+
context 'formal parameters' do
|
212
|
+
context 'without splat' do
|
213
|
+
let(:method) do
|
214
|
+
<<-CODE
|
215
|
+
class Foobar
|
216
|
+
def some_method(foo, bar)
|
217
|
+
#{invocation}
|
218
|
+
end
|
219
|
+
end
|
220
|
+
CODE
|
221
|
+
end
|
222
|
+
|
223
|
+
context 'no arguments' do
|
224
|
+
let(:invocation) { 'super()' }
|
225
|
+
|
226
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $a.$$p = null, $a).call($b);" }
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'implicit arguments' do
|
230
|
+
let(:invocation) { 'super' }
|
231
|
+
|
232
|
+
context 'no block' do
|
233
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $a.$$p = $iter, $a).apply($b, $zuper);" }
|
234
|
+
end
|
235
|
+
|
236
|
+
context 'block' do
|
237
|
+
let(:method) do
|
238
|
+
<<-CODE
|
239
|
+
class Foobar
|
240
|
+
def some_method(foo, &bar)
|
241
|
+
#{invocation}
|
242
|
+
end
|
243
|
+
end
|
244
|
+
CODE
|
245
|
+
end
|
246
|
+
|
247
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $a.$$p = $iter, $a).apply($b, $zuper);" }
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context 'with splat' do
|
253
|
+
context 'and block with actual params of' do
|
254
|
+
let(:method) do
|
255
|
+
<<-CODE
|
256
|
+
class Foobar
|
257
|
+
def some_method(*stuff, &block2)
|
258
|
+
#{invocation}
|
259
|
+
end
|
260
|
+
end
|
261
|
+
CODE
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'splat' do
|
265
|
+
context 'with block' do
|
266
|
+
context 'via variable' do
|
267
|
+
let(:invocation) { 'super(*stuff) {|a| foobar }' }
|
268
|
+
|
269
|
+
it do
|
270
|
+
is_expected.to include <<-CODE
|
271
|
+
return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = (TMP_2 = function(a){var self = TMP_2.$$s || this;
|
272
|
+
if (a == null) a = nil;
|
273
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $b).apply($c, Opal.to_a(stuff));
|
274
|
+
CODE
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
context 'via reference' do
|
279
|
+
let(:invocation) { 'super *stuff, &block2' }
|
280
|
+
|
281
|
+
it { is_expected.to include "return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = block2.$to_proc(), $b).apply($c, Opal.to_a(stuff));" }
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'no splat' do
|
287
|
+
context 'with block' do
|
288
|
+
context 'via variable' do
|
289
|
+
let(:invocation) { 'super {|a| foobar }' }
|
290
|
+
|
291
|
+
it do
|
292
|
+
is_expected.to include <<-CODE
|
293
|
+
return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = (TMP_2 = function(a){var self = TMP_2.$$s || this;
|
294
|
+
if (a == null) a = nil;
|
295
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $b).apply($c, $zuper);
|
296
|
+
CODE
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'via reference' do
|
301
|
+
let(:invocation) { 'super &block2' }
|
302
|
+
|
303
|
+
it { is_expected.to include "return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = block2.$to_proc(), $b).call($c);" }
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context 'no arguments' do
|
309
|
+
let(:invocation) { 'super()' }
|
310
|
+
|
311
|
+
it { is_expected.to include "return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = null, $b).call($c);" }
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context 'actual params of' do
|
316
|
+
let(:method) do
|
317
|
+
<<-CODE
|
318
|
+
class Foobar
|
319
|
+
def some_method(*stuff)
|
320
|
+
#{invocation}
|
321
|
+
end
|
322
|
+
end
|
323
|
+
CODE
|
324
|
+
end
|
325
|
+
|
326
|
+
context 'splat' do
|
327
|
+
context 'with block' do
|
328
|
+
context 'via variable' do
|
329
|
+
let(:invocation) { 'super(*stuff) {|a| foobar }' }
|
330
|
+
|
331
|
+
it do
|
332
|
+
is_expected.to include <<-CODE
|
333
|
+
return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = (TMP_2 = function(a){var self = TMP_2.$$s || this;
|
334
|
+
if (a == null) a = nil;
|
335
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $b).apply($c, Opal.to_a(stuff));
|
336
|
+
CODE
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context 'via reference' do
|
341
|
+
let(:invocation) { 'super *stuff, &block2' }
|
342
|
+
|
343
|
+
it { is_expected.to include "return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = self.$block2().$to_proc(), $b).apply($c, Opal.to_a(stuff));" }
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'no splat' do
|
349
|
+
context 'with block' do
|
350
|
+
context 'via variable' do
|
351
|
+
let(:invocation) { 'super {|a| foobar }' }
|
352
|
+
|
353
|
+
it do
|
354
|
+
is_expected.to include <<-CODE
|
355
|
+
return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = (TMP_2 = function(a){var self = TMP_2.$$s || this;
|
356
|
+
if (a == null) a = nil;
|
357
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $b).apply($c, $zuper);
|
358
|
+
CODE
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
context 'via reference' do
|
363
|
+
let(:invocation) { 'super &block2' }
|
364
|
+
|
365
|
+
it { is_expected.to include "return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = self.$block2().$to_proc(), $b).call($c);" }
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
context 'no arguments' do
|
371
|
+
let(:invocation) { 'super()' }
|
372
|
+
|
373
|
+
it { is_expected.to include "return ($b = ($c = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false)), $b.$$p = null, $b).call($c);" }
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context 'no formal parameters with actual params of' do
|
380
|
+
let(:method) do
|
381
|
+
<<-CODE
|
382
|
+
class Foobar
|
383
|
+
def regular_method
|
384
|
+
#{invocation}
|
385
|
+
end
|
386
|
+
end
|
387
|
+
CODE
|
388
|
+
end
|
389
|
+
|
390
|
+
context 'no splat' do
|
391
|
+
let(:invocation) { 'super(42)' }
|
392
|
+
|
393
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = null, $a).call($b, 42);" }
|
394
|
+
end
|
395
|
+
|
396
|
+
context 'splat' do
|
397
|
+
context 'with no block' do
|
398
|
+
let(:invocation) { "args=[1,2,3]\nsuper(*args)" }
|
399
|
+
|
400
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = null, $a).apply($b, Opal.to_a(args));" }
|
401
|
+
end
|
402
|
+
|
403
|
+
context 'with block' do
|
404
|
+
context 'via variable' do
|
405
|
+
let(:invocation) { 'super(*args) {|b| foobar }' }
|
406
|
+
|
407
|
+
it do
|
408
|
+
is_expected.to include <<-CODE
|
409
|
+
return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = (TMP_2 = function(b){var self = TMP_2.$$s || this;
|
410
|
+
if (b == null) b = nil;
|
411
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $a).apply($b, Opal.to_a(self.$args()));
|
412
|
+
CODE
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context 'via reference' do
|
417
|
+
let(:invocation) { 'super(*args, &block2)' }
|
418
|
+
|
419
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = self.$block2().$to_proc(), $a).apply($b, Opal.to_a(self.$args()));" }
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
context 'block' do
|
425
|
+
context 'via variable' do
|
426
|
+
let(:invocation) { 'super {|b| foobar }' }
|
427
|
+
|
428
|
+
it do
|
429
|
+
is_expected.to include <<-CODE
|
430
|
+
return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = (TMP_2 = function(b){var self = TMP_2.$$s || this;
|
431
|
+
if (b == null) b = nil;
|
432
|
+
return self.$foobar()}, TMP_2.$$s = self, TMP_2), $a).apply($b, $zuper);
|
433
|
+
CODE
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
context 'via reference' do
|
438
|
+
let(:invocation) { 'super(&block)' }
|
439
|
+
|
440
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = self.$block().$to_proc(), $a).call($b);" }
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
context 'no arguments' do
|
445
|
+
let(:invocation) { 'super()' }
|
446
|
+
|
447
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'regular_method', TMP_1, false)), $a.$$p = null, $a).call($b);" }
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
context 'block' do
|
453
|
+
let(:method) { 'stuff = lambda { super }'}
|
454
|
+
|
455
|
+
it { is_expected.to include "return ($c = ($d = self, Opal.find_iter_super_dispatcher(self, null, (TMP_1.$$def || null), false, true)), $c.$$p = $iter, $c).apply($d)}, TMP_1.$$s = self, TMP_1), $a).call($b)" }
|
456
|
+
end
|
457
|
+
|
458
|
+
context 'block inside method' do
|
459
|
+
context 'first node' do
|
460
|
+
let(:method) do
|
461
|
+
<<-CODE
|
462
|
+
def in_method
|
463
|
+
foo { super }
|
464
|
+
end
|
465
|
+
CODE
|
466
|
+
end
|
467
|
+
|
468
|
+
it { is_expected.to include "return ($c = ($d = self, Opal.find_iter_super_dispatcher(self, 'in_method', (TMP_1.$$def || TMP_2), false, true)), $c.$$p = $iter, $c).apply($d, $zuper)}, TMP_1.$$s = self, TMP_1), $a).call($b);" }
|
469
|
+
end
|
470
|
+
|
471
|
+
context 'not first node' do
|
472
|
+
let(:method) do
|
473
|
+
<<-CODE
|
474
|
+
module Foo
|
475
|
+
def foo
|
476
|
+
foobar
|
477
|
+
fetch { return super }
|
478
|
+
end
|
479
|
+
end
|
480
|
+
CODE
|
481
|
+
end
|
482
|
+
|
483
|
+
it { is_expected.to include "Opal.ret(($c = ($d = self, Opal.find_iter_super_dispatcher(self, 'foo', (TMP_1.$$def || TMP_2), false, true)), $c.$$p = $iter, $c).apply($d, $zuper))}, TMP_1.$$s = self, TMP_1), $a).call($b);" }
|
484
|
+
end
|
485
|
+
|
486
|
+
context 'right method is called, IS THIS A NEW CASE??' do
|
487
|
+
let(:method) do
|
488
|
+
<<-CODE
|
489
|
+
class Bar
|
490
|
+
def m
|
491
|
+
:abc
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
class Foo < Bar
|
496
|
+
def self.do_defining(name, &body)
|
497
|
+
define_method(name, &body)
|
498
|
+
end
|
499
|
+
|
500
|
+
def self.setup
|
501
|
+
do_defining(:m) { |*args| super(*args) }
|
502
|
+
end
|
503
|
+
end
|
504
|
+
CODE
|
505
|
+
end
|
506
|
+
|
507
|
+
# runtime if (current_func.$$def) code should take care of locating the correct method here
|
508
|
+
it { is_expected.to include "return ($d = ($e = self, Opal.find_iter_super_dispatcher(self, 'setup', (TMP_2.$$def || TMP_3), false, false)), $d.$$p = null, $d).apply($e, Opal.to_a(args))}, TMP_2.$$s = self, TMP_2), $a).call($b, \"m\");" }
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
context 'define_method' do
|
513
|
+
let(:method) do
|
514
|
+
<<-CODE
|
515
|
+
class Foobar
|
516
|
+
#{invocation}
|
517
|
+
end
|
518
|
+
CODE
|
519
|
+
end
|
520
|
+
|
521
|
+
context 'implicit' do
|
522
|
+
let(:invocation) { 'define_method(:wilma) { super }' }
|
523
|
+
|
524
|
+
it { is_expected.to include "return ($c = ($d = self, Opal.find_iter_super_dispatcher(self, null, (TMP_1.$$def || null), false, true)), $c.$$p = $iter, $c).apply($d)}, TMP_1.$$s = self, TMP_1), $a).call($b, \"wilma\")" }
|
525
|
+
end
|
526
|
+
|
527
|
+
context 'module' do
|
528
|
+
let(:method) do
|
529
|
+
<<-CODE
|
530
|
+
module Foobar
|
531
|
+
define_method(:wilma) { super() }
|
532
|
+
end
|
533
|
+
CODE
|
534
|
+
end
|
535
|
+
|
536
|
+
it do
|
537
|
+
is_expected.to include <<-CODE
|
538
|
+
($a = ($b = self).$define_method, $a.$$p = (TMP_1 = function(){var self = TMP_1.$$s || this, $c, $d;
|
539
|
+
|
540
|
+
return ($c = ($d = self, Opal.find_iter_super_dispatcher(self, null, (TMP_1.$$def || null), false, false)), $c.$$p = null, $c).call($d)}, TMP_1.$$s = self, TMP_1), $a).call($b, "wilma")
|
541
|
+
CODE
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
context 'anonymous class' do
|
546
|
+
context 'not nested, only item in class' do
|
547
|
+
let(:method) do
|
548
|
+
<<-CODE
|
549
|
+
Class.new do
|
550
|
+
define_method :foo do
|
551
|
+
super()
|
552
|
+
end
|
553
|
+
end
|
554
|
+
CODE
|
555
|
+
end
|
556
|
+
|
557
|
+
it { is_expected.to include "return ($e = ($f = self, Opal.find_iter_super_dispatcher(self, null, (TMP_2.$$def || TMP_1.$$def || null), false, false)), $e.$$p = null, $e).call($f)}, TMP_2.$$s = self, TMP_2), $c).call($d, \"foo\")}, TMP_1.$$s = self, TMP_1), $a).call($b)" }
|
558
|
+
end
|
559
|
+
|
560
|
+
context 'alongside def''d method' do
|
561
|
+
let(:method) do
|
562
|
+
<<-CODE
|
563
|
+
sup = Class.new do
|
564
|
+
def a
|
565
|
+
:abc
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
Class.new(sup) do
|
570
|
+
def fetch(&block)
|
571
|
+
block.call
|
572
|
+
end
|
573
|
+
|
574
|
+
define_method(:a) { fetch { super(&nil)} }
|
575
|
+
end
|
576
|
+
CODE
|
577
|
+
end
|
578
|
+
|
579
|
+
it { is_expected.to include "return ($h = ($i = self, Opal.find_iter_super_dispatcher(self, null, (TMP_5.$$def || TMP_4.$$def || TMP_2.$$def || null), false, false)), $h.$$p = nil.$to_proc(), $h).call($i)}, TMP_5.$$s = self, TMP_5), $f).call($g)}, TMP_4.$$s = self, TMP_4), $d).call($e, \"a\");}, TMP_2.$$s = self, TMP_2), $a).call($c, sup);" }
|
580
|
+
end
|
581
|
+
|
582
|
+
context 'alongside another define_method' do
|
583
|
+
let(:method) do
|
584
|
+
<<-CODE
|
585
|
+
sup = Class.new do
|
586
|
+
def a
|
587
|
+
:abc
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
Class.new(sup) do
|
592
|
+
define_method(:fetch) do |&block|
|
593
|
+
block.call
|
594
|
+
end
|
595
|
+
|
596
|
+
define_method(:a) { fetch { super(&nil)} }
|
597
|
+
end
|
598
|
+
CODE
|
599
|
+
end
|
600
|
+
|
601
|
+
it { is_expected.to include "return ($i = ($j = self, Opal.find_iter_super_dispatcher(self, null, (TMP_5.$$def || TMP_4.$$def || TMP_2.$$def || null), false, false)), $i.$$p = nil.$to_proc(), $i).call($j)}, TMP_5.$$s = self, TMP_5), $g).call($h)}, TMP_4.$$s = self, TMP_4), $d).call($f, \"a\");}, TMP_2.$$s = self, TMP_2), $a).call($c, sup);" }
|
602
|
+
end
|
603
|
+
|
604
|
+
context 'not last method in class' do
|
605
|
+
let(:method) do
|
606
|
+
<<-CODE
|
607
|
+
sup = Class.new do
|
608
|
+
def a
|
609
|
+
:abc
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
Class.new(sup) do
|
614
|
+
define_method(:a) { fetch { super(&nil)} }
|
615
|
+
|
616
|
+
def fetch(&block)
|
617
|
+
block.call
|
618
|
+
end
|
619
|
+
end
|
620
|
+
CODE
|
621
|
+
end
|
622
|
+
|
623
|
+
it { is_expected.to include "return ($h = ($i = self, Opal.find_iter_super_dispatcher(self, null, (TMP_4.$$def || TMP_3.$$def || TMP_2.$$def || null), false, false)), $h.$$p = nil.$to_proc(), $h).call($i)}, TMP_4.$$s = self, TMP_4), $f).call($g)}, TMP_3.$$s = self, TMP_3), $d).call($e, \"a\");" }
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
context 'inside a method' do
|
628
|
+
let(:method) do
|
629
|
+
<<-CODE
|
630
|
+
module Bar
|
631
|
+
def fetch
|
632
|
+
end
|
633
|
+
|
634
|
+
def foo
|
635
|
+
some_call
|
636
|
+
|
637
|
+
if some_arg
|
638
|
+
block2 = lambda { the_block }
|
639
|
+
define_method(:a) { fetch { super(some_arg, &block2)} }
|
640
|
+
else
|
641
|
+
define_method(:a) { fetch { super(&nil)} }
|
642
|
+
end
|
643
|
+
end
|
644
|
+
end
|
645
|
+
CODE
|
646
|
+
end
|
647
|
+
|
648
|
+
it { is_expected.to include "return ($f = ($g = self, Opal.find_iter_super_dispatcher(self, 'foo', (TMP_3.$$def || TMP_2.$$def || TMP_4), false, false)), $f.$$p = block2.$to_proc(), $f).call($g, self.$some_arg())}, TMP_3.$$s = self, TMP_3), $d).call($e)}, TMP_2.$$s = self, TMP_2), $a).call($c, \"a\");" }
|
649
|
+
it { is_expected.to include "return ($g = ($h = self, Opal.find_iter_super_dispatcher(self, 'foo', (TMP_6.$$def || TMP_5.$$def || TMP_4), false, false)), $g.$$p = nil.$to_proc(), $g).call($h)}, TMP_6.$$s = self, TMP_6), $e).call($f)}, TMP_5.$$s = self, TMP_5), $a).call($d, \"a\")" }
|
650
|
+
end
|
651
|
+
|
652
|
+
context 'explicit' do
|
653
|
+
let(:invocation) { 'define_method(:wilma) { super() }' }
|
654
|
+
|
655
|
+
it do
|
656
|
+
is_expected.to include <<-CODE
|
657
|
+
return ($a = ($b = self).$define_method, $a.$$p = (TMP_1 = function(){var self = TMP_1.$$s || this, $c, $d;
|
658
|
+
|
659
|
+
return ($c = ($d = self, Opal.find_iter_super_dispatcher(self, null, (TMP_1.$$def || null), false, false)), $c.$$p = null, $c).call($d)}, TMP_1.$$s = self, TMP_1), $a).call($b, "wilma")
|
660
|
+
CODE
|
661
|
+
end
|
662
|
+
end
|
663
|
+
|
664
|
+
context 'invalid case alongside other valid super cases' do
|
665
|
+
let(:method) do
|
666
|
+
<<-CODE
|
667
|
+
Class.new do
|
668
|
+
define_method(:foo) { super }
|
669
|
+
|
670
|
+
Class.new(c1) do
|
671
|
+
def m
|
672
|
+
other_method { super }
|
673
|
+
end
|
674
|
+
end
|
675
|
+
end
|
676
|
+
CODE
|
677
|
+
end
|
678
|
+
|
679
|
+
it { is_expected.to include "return ($e = ($f = self, Opal.find_iter_super_dispatcher(self, null, (TMP_2.$$def || TMP_1.$$def || null), false, true)), $e.$$p = $iter, $e).apply($f)}, TMP_2.$$s = self, TMP_2), $c).call($d, \"foo\");" }
|
680
|
+
|
681
|
+
it { is_expected.to include "return ($c = ($d = self, Opal.find_iter_super_dispatcher(self, 'm', (TMP_5.$$def || TMP_6), false, true)), $c.$$p = $iter, $c).apply($d, $zuper)}, TMP_5.$$s = self, TMP_5), $a).call($b);" }
|
682
|
+
end
|
683
|
+
end
|
684
|
+
|
685
|
+
context 'singleton' do
|
686
|
+
let(:method) do
|
687
|
+
<<-CODE
|
688
|
+
class Foobar
|
689
|
+
def self.some_method
|
690
|
+
super
|
691
|
+
end
|
692
|
+
end
|
693
|
+
CODE
|
694
|
+
end
|
695
|
+
|
696
|
+
it { is_expected.to include "return ($a = ($b = self, Opal.find_super_dispatcher(self, 'some_method', TMP_1, false, $Foobar)), $a.$$p = $iter, $a).apply($b, $zuper);" }
|
697
|
+
end
|
698
|
+
end
|
699
|
+
end
|
700
|
+
end
|