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.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.gitignore +2 -3
  4. data/.gitmodules +5 -2
  5. data/.jshintrc +1 -8
  6. data/.rspec +1 -1
  7. data/.travis.yml +15 -23
  8. data/CHANGELOG.md +511 -326
  9. data/CODE_OF_CONDUCT.md +13 -15
  10. data/CONTRIBUTING.md +26 -216
  11. data/Gemfile +20 -12
  12. data/Guardfile +2 -2
  13. data/HACKING.md +230 -0
  14. data/README.md +6 -7
  15. data/bin/opal-mspec +1 -1
  16. data/config.ru +2 -2
  17. data/docs/faq.md +1 -1
  18. data/docs/source_maps.md +1 -1
  19. data/lib/opal.rb +1 -0
  20. data/lib/opal/builder.rb +1 -1
  21. data/lib/opal/cli.rb +30 -28
  22. data/lib/opal/cli_options.rb +3 -0
  23. data/lib/opal/cli_runners.rb +14 -1
  24. data/lib/opal/cli_runners/{apple_script.rb → applescript.rb} +3 -3
  25. data/lib/opal/cli_runners/nashorn.rb +2 -2
  26. data/lib/opal/cli_runners/nodejs.rb +2 -2
  27. data/lib/opal/cli_runners/phantom.js +24 -0
  28. data/lib/opal/cli_runners/phantomjs.rb +10 -10
  29. data/lib/opal/cli_runners/server.rb +3 -3
  30. data/lib/opal/compiler.rb +43 -4
  31. data/lib/opal/config.rb +3 -1
  32. data/lib/opal/errors.rb +13 -0
  33. data/lib/opal/fragment.rb +0 -13
  34. data/lib/opal/nodes.rb +10 -0
  35. data/lib/opal/nodes/args/initialize_kwargs.rb +28 -0
  36. data/lib/opal/nodes/args/kwarg.rb +29 -0
  37. data/lib/opal/nodes/args/kwoptarg.rb +29 -0
  38. data/lib/opal/nodes/args/kwrestarg.rb +39 -0
  39. data/lib/opal/nodes/args/mlhsarg.rb +79 -0
  40. data/lib/opal/nodes/args/normarg.rb +26 -0
  41. data/lib/opal/nodes/args/optarg.rb +27 -0
  42. data/lib/opal/nodes/args/post_args.rb +200 -0
  43. data/lib/opal/nodes/args/post_kwargs.rb +31 -0
  44. data/lib/opal/nodes/args/restarg.rb +33 -0
  45. data/lib/opal/nodes/base.rb +12 -0
  46. data/lib/opal/nodes/call.rb +92 -33
  47. data/lib/opal/nodes/def.rb +26 -169
  48. data/lib/opal/nodes/hash.rb +10 -4
  49. data/lib/opal/nodes/helpers.rb +6 -3
  50. data/lib/opal/nodes/inline_args.rb +61 -0
  51. data/lib/opal/nodes/iter.rb +73 -82
  52. data/lib/opal/nodes/logic.rb +12 -2
  53. data/lib/opal/nodes/masgn.rb +1 -2
  54. data/lib/opal/nodes/node_with_args.rb +141 -0
  55. data/lib/opal/nodes/rescue.rb +121 -43
  56. data/lib/opal/nodes/scope.rb +24 -5
  57. data/lib/opal/nodes/super.rb +122 -54
  58. data/lib/opal/nodes/top.rb +0 -12
  59. data/lib/opal/nodes/yield.rb +2 -13
  60. data/lib/opal/parser.rb +67 -39
  61. data/lib/opal/parser/grammar.rb +3319 -2961
  62. data/lib/opal/parser/grammar.y +234 -46
  63. data/lib/opal/parser/lexer.rb +105 -17
  64. data/lib/opal/parser/sexp.rb +4 -0
  65. data/lib/opal/paths.rb +4 -0
  66. data/lib/opal/regexp_anchors.rb +19 -1
  67. data/lib/opal/sprockets.rb +21 -18
  68. data/lib/opal/sprockets/environment.rb +0 -8
  69. data/lib/opal/sprockets/processor.rb +13 -16
  70. data/lib/opal/sprockets/server.rb +6 -12
  71. data/lib/opal/version.rb +1 -1
  72. data/opal.gemspec +1 -0
  73. data/opal/corelib/array.rb +209 -131
  74. data/opal/corelib/basic_object.rb +7 -3
  75. data/opal/corelib/class.rb +11 -17
  76. data/opal/corelib/constants.rb +2 -2
  77. data/opal/corelib/enumerable.rb +178 -355
  78. data/opal/corelib/enumerator.rb +3 -46
  79. data/opal/corelib/error.rb +2 -2
  80. data/opal/corelib/file.rb +13 -1
  81. data/opal/corelib/hash.rb +26 -56
  82. data/opal/corelib/helpers.rb +10 -0
  83. data/opal/corelib/kernel.rb +6 -3
  84. data/opal/corelib/module.rb +62 -31
  85. data/opal/corelib/number.rb +7 -16
  86. data/opal/corelib/proc.rb +24 -9
  87. data/opal/corelib/range.rb +4 -13
  88. data/opal/corelib/runtime.js +515 -378
  89. data/opal/corelib/string.rb +21 -49
  90. data/opal/corelib/struct.rb +50 -35
  91. data/opal/corelib/unsupported.rb +18 -30
  92. data/opal/opal.rb +0 -1
  93. data/opal/opal/mini.rb +1 -0
  94. data/spec/README.md +6 -4
  95. data/spec/filters/bugs/array.rb +0 -42
  96. data/spec/filters/bugs/basicobject.rb +0 -2
  97. data/spec/filters/bugs/bigdecimal.rb +160 -0
  98. data/spec/filters/bugs/class.rb +0 -5
  99. data/spec/filters/bugs/date.rb +1 -48
  100. data/spec/filters/bugs/enumerable.rb +4 -12
  101. data/spec/filters/bugs/enumerator.rb +0 -1
  102. data/spec/filters/bugs/exception.rb +4 -3
  103. data/spec/filters/bugs/float.rb +4 -2
  104. data/spec/filters/bugs/kernel.rb +25 -10
  105. data/spec/filters/bugs/language.rb +119 -68
  106. data/spec/filters/bugs/method.rb +135 -0
  107. data/spec/filters/bugs/module.rb +13 -28
  108. data/spec/filters/bugs/proc.rb +18 -8
  109. data/spec/filters/bugs/range.rb +0 -3
  110. data/spec/filters/bugs/rational.rb +4 -0
  111. data/spec/filters/bugs/regexp.rb +68 -36
  112. data/spec/filters/bugs/string.rb +1 -1
  113. data/spec/filters/bugs/struct.rb +0 -12
  114. data/spec/filters/bugs/time.rb +1 -0
  115. data/spec/filters/bugs/unboundmethod.rb +2 -1
  116. data/spec/filters/unsupported/freeze.rb +3 -1
  117. data/spec/filters/unsupported/language.rb +0 -7
  118. data/spec/filters/unsupported/privacy.rb +7 -6
  119. data/spec/filters/unsupported/string.rb +10 -0
  120. data/spec/filters/unsupported/struct.rb +3 -0
  121. data/spec/filters/unsupported/symbol.rb +9 -0
  122. data/spec/filters/unsupported/taint.rb +0 -3
  123. data/spec/filters/unsupported/thread.rb +1 -0
  124. data/spec/lib/cli_runners/phantomjs_spec.rb +39 -0
  125. data/spec/lib/cli_spec.rb +42 -1
  126. data/spec/lib/compiler/call_spec.rb +700 -0
  127. data/spec/lib/compiler_spec.rb +46 -28
  128. data/spec/lib/config_spec.rb +13 -0
  129. data/spec/lib/parser/call_spec.rb +18 -0
  130. data/spec/lib/parser/def_spec.rb +29 -0
  131. data/spec/lib/parser/iter_spec.rb +15 -15
  132. data/spec/lib/parser/lambda_spec.rb +153 -12
  133. data/spec/lib/parser/string_spec.rb +5 -0
  134. data/spec/lib/parser/undef_spec.rb +1 -1
  135. data/spec/lib/parser/variables_spec.rb +24 -0
  136. data/spec/lib/paths_spec.rb +12 -5
  137. data/spec/lib/spec_helper.rb +5 -0
  138. data/spec/lib/sprockets/processor_spec.rb +6 -5
  139. data/spec/lib/sprockets_spec.rb +8 -0
  140. data/spec/mspec-opal/formatters.rb +188 -0
  141. data/spec/mspec-opal/runner.rb +193 -0
  142. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  143. data/spec/opal/core/kernel/define_singleton_method_spec.rb +1 -1
  144. data/spec/opal/core/kernel/instance_variables_spec.rb +14 -0
  145. data/spec/opal/core/kernel/loop_spec.rb +1 -1
  146. data/spec/opal/core/kernel/raise_spec.rb +1 -1
  147. data/spec/opal/core/language/heredoc_spec.rb +42 -0
  148. data/spec/opal/core/language/rescue_spec.rb +18 -0
  149. data/spec/opal/core/language_spec.rb +22 -0
  150. data/spec/opal/core/module/const_defined_spec.rb +1 -2
  151. data/spec/opal/core/module/name_spec.rb +6 -0
  152. data/spec/opal/core/runtime/bridged_classes_spec.rb +14 -2
  153. data/spec/opal/core/runtime/rescue_spec.rb +12 -2
  154. data/spec/opal/core/runtime/super_spec.rb +1 -0
  155. data/spec/opal/core/string_spec.rb +21 -0
  156. data/spec/opal/stdlib/js_spec.rb +1 -1
  157. data/spec/opal/stdlib/native/hash_spec.rb +7 -0
  158. data/spec/opal/stdlib/promise/always_spec.rb +24 -5
  159. data/spec/opal/stdlib/promise/rescue_spec.rb +15 -6
  160. data/spec/opal/stdlib/promise/then_spec.rb +13 -5
  161. data/spec/opal/stdlib/promise/trace_spec.rb +5 -6
  162. data/spec/opal/stdlib/strscan/scan_spec.rb +1 -1
  163. data/spec/ruby_specs +122 -0
  164. data/spec/spec_helper.rb +3 -15
  165. data/stdlib/base64.rb +51 -121
  166. data/stdlib/bigdecimal.rb +231 -0
  167. data/stdlib/bigdecimal/bignumber.js.rb +11 -0
  168. data/stdlib/bigdecimal/kernel.rb +5 -0
  169. data/stdlib/date.rb +252 -10
  170. data/stdlib/native.rb +38 -38
  171. data/stdlib/nodejs/dir.rb +8 -6
  172. data/stdlib/nodejs/file.rb +28 -3
  173. data/stdlib/nodejs/node_modules/.bin/js-yaml +1 -0
  174. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esparse +1 -0
  175. data/stdlib/nodejs/node_modules/js-yaml/node_modules/.bin/esvalidate +1 -0
  176. data/stdlib/nodejs/require.rb +1 -1
  177. data/stdlib/nodejs/yaml.rb +3 -2
  178. data/stdlib/opal-parser.rb +7 -2
  179. data/stdlib/pathname.rb +23 -1
  180. data/stdlib/phantomjs.rb +10 -0
  181. data/stdlib/promise.rb +38 -23
  182. data/tasks/building.rake +3 -3
  183. data/tasks/testing.rake +27 -14
  184. data/tasks/testing/mspec_special_calls.rb +1 -1
  185. data/tasks/testing/sprockets-phantomjs.js +4 -0
  186. data/test/opal/test_keyword.rb +110 -110
  187. data/test/opal/unsupported_and_bugs.rb +30 -0
  188. data/vendored-minitest/minitest/assertions.rb +1 -1
  189. metadata +65 -15
  190. data/.spectator +0 -2
  191. data/.spectator-mspec +0 -3
  192. data/opal/corelib/array/inheritance.rb +0 -127
  193. data/spec/rubyspecs +0 -139
@@ -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"
@@ -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
@@ -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#extended is private in its default implementation"
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) { nil }
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