opal 0.3.41 → 0.3.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +14 -1
  4. data/Gemfile +2 -5
  5. data/Rakefile +41 -3
  6. data/bin/opal +33 -0
  7. data/lib/opal.rb +2 -12
  8. data/lib/opal/core_ext.rb +5 -0
  9. data/lib/opal/grammar.rb +2207 -2138
  10. data/lib/opal/grammar.y +21 -0
  11. data/lib/opal/grammar_helpers.rb +360 -0
  12. data/lib/opal/lexer.rb +55 -401
  13. data/lib/opal/lexer_scope.rb +28 -0
  14. data/lib/opal/parser.rb +155 -171
  15. data/lib/opal/target_scope.rb +257 -0
  16. data/lib/opal/version.rb +1 -1
  17. data/opal.gemspec +6 -2
  18. data/opal/opal-parser.js.erb +3 -2
  19. data/opal/opal.rb +20 -18
  20. data/opal/opal/array.rb +21 -12
  21. data/opal/opal/basic_object.rb +2 -1
  22. data/opal/opal/boolean.rb +3 -0
  23. data/opal/opal/browser_loader.js +57 -0
  24. data/opal/opal/class.rb +51 -13
  25. data/opal/opal/date.rb +1 -20
  26. data/opal/opal/enumerable.rb +66 -33
  27. data/opal/opal/error.rb +2 -0
  28. data/opal/opal/hash.rb +1 -1
  29. data/opal/opal/kernel.rb +14 -3
  30. data/opal/opal/nil_class.rb +4 -0
  31. data/opal/opal/proc.rb +9 -1
  32. data/opal/opal/racc.rb +2 -2
  33. data/opal/opal/regexp.rb +1 -1
  34. data/opal/opal/runtime.js +14 -4
  35. data/opal/opal/string.rb +21 -4
  36. data/opal/opal/time.rb +27 -0
  37. data/spec/core/array/allocate_spec.rb +7 -1
  38. data/spec/core/array/append_spec.rb +18 -3
  39. data/spec/core/array/array_spec.rb +7 -0
  40. data/spec/core/array/assoc_spec.rb +23 -8
  41. data/spec/core/array/at_spec.rb +23 -3
  42. data/spec/core/array/choice_spec.rb +20 -0
  43. data/spec/core/array/clear_spec.rb +45 -4
  44. data/spec/core/array/combination_spec.rb +55 -0
  45. data/spec/core/array/compact_spec.rb +72 -1
  46. data/spec/core/array/constructor_spec.rb +13 -2
  47. data/spec/core/array/count_spec.rb +15 -7
  48. data/spec/core/array/delete_at_spec.rb +44 -1
  49. data/spec/core/array/delete_if_spec.rb +52 -2
  50. data/spec/core/array/delete_spec.rb +83 -2
  51. data/spec/core/array/drop_spec.rb +24 -16
  52. data/spec/core/array/drop_while_spec.rb +17 -0
  53. data/spec/core/array/each_index_spec.rb +11 -1
  54. data/spec/core/array/each_spec.rb +20 -2
  55. data/spec/core/array/empty_spec.rb +4 -1
  56. data/spec/core/array/eql_spec.rb +14 -0
  57. data/spec/core/array/fetch_spec.rb +31 -2
  58. data/spec/core/array/find_index_spec.rb +8 -0
  59. data/spec/core/array/first_spec.rb +45 -8
  60. data/spec/core/array/fixtures/classes.rb +538 -0
  61. data/spec/core/array/flatten_spec.rb +200 -7
  62. data/spec/core/array/frozen_spec.rb +32 -0
  63. data/spec/core/array/include_spec.rb +16 -1
  64. data/spec/core/array/index_spec.rb +5 -25
  65. data/spec/core/array/insert_spec.rb +37 -3
  66. data/spec/core/array/inspect_spec.rb +6 -12
  67. data/spec/core/array/intersection_spec.rb +55 -4
  68. data/spec/core/array/join_spec.rb +29 -4
  69. data/spec/core/array/keep_if_spec.rb +13 -6
  70. data/spec/core/array/last_spec.rb +35 -1
  71. data/spec/core/array/length_spec.rb +7 -4
  72. data/spec/core/array/map_spec.rb +9 -47
  73. data/spec/core/array/minus_spec.rb +68 -4
  74. data/spec/core/array/multiply_spec.rb +138 -6
  75. data/spec/core/array/new_spec.rb +92 -3
  76. data/spec/core/array/ntimes_spec.rb +26 -0
  77. data/spec/core/array/plus_spec.rb +48 -2
  78. data/spec/core/array/pop_spec.rb +159 -39
  79. data/spec/core/array/push_spec.rb +29 -1
  80. data/spec/core/array/rassoc_spec.rb +31 -2
  81. data/spec/core/array/reject_spec.rb +89 -2
  82. data/spec/core/array/replace_spec.rb +7 -29
  83. data/spec/core/array/reverse_each_spec.rb +25 -1
  84. data/spec/core/array/reverse_spec.rb +53 -1
  85. data/spec/core/array/rindex_spec.rb +55 -5
  86. data/spec/core/array/select_spec.rb +35 -8
  87. data/spec/core/array/shared/collect.rb +0 -0
  88. data/spec/core/array/shared/enumeratorize.rb +12 -0
  89. data/spec/core/array/shared/eql.rb +95 -0
  90. data/spec/core/array/shared/index.rb +37 -0
  91. data/spec/core/array/shared/inspect.rb +3 -0
  92. data/spec/core/array/shared/join.rb +7 -0
  93. data/spec/core/array/shared/keep_if.rb +0 -0
  94. data/spec/core/array/shared/length.rb +0 -0
  95. data/spec/core/array/shared/replace.rb +0 -0
  96. data/spec/core/array/shared/slice.rb +0 -0
  97. data/spec/core/array/shift_spec.rb +132 -23
  98. data/spec/core/array/shuffle_spec.rb +82 -6
  99. data/spec/core/array/size_spec.rb +7 -4
  100. data/spec/core/array/slice_spec.rb +132 -1
  101. data/spec/core/array/sort_spec.rb +263 -14
  102. data/spec/core/array/take_spec.rb +24 -16
  103. data/spec/core/array/take_while_spec.rb +14 -10
  104. data/spec/core/array/to_a_spec.rb +18 -1
  105. data/spec/core/array/to_ary_spec.rb +15 -1
  106. data/spec/core/array/try_convert_spec.rb +39 -2
  107. data/spec/core/array/uniq_spec.rb +148 -3
  108. data/spec/core/array/unshift_spec.rb +36 -1
  109. data/spec/core/array/zip_spec.rb +36 -1
  110. data/spec/core/class/new_spec.rb +8 -6
  111. data/spec/core/enumerable/all_spec.rb +37 -9
  112. data/spec/core/enumerable/any_spec.rb +45 -7
  113. data/spec/core/enumerable/collect_spec.rb +4 -1
  114. data/spec/core/enumerable/count_spec.rb +4 -1
  115. data/spec/core/enumerable/detect_spec.rb +2 -2
  116. data/spec/core/enumerable/drop_spec.rb +4 -1
  117. data/spec/core/enumerable/drop_while_spec.rb +4 -1
  118. data/spec/core/enumerable/each_slice_spec.rb +2 -1
  119. data/spec/core/enumerable/each_with_index_spec.rb +4 -1
  120. data/spec/core/enumerable/each_with_object_spec.rb +4 -1
  121. data/spec/core/enumerable/entries_spec.rb +4 -1
  122. data/spec/core/enumerable/find_all_spec.rb +4 -1
  123. data/spec/core/enumerable/find_index_spec.rb +4 -1
  124. data/spec/core/enumerable/find_spec.rb +5 -2
  125. data/spec/core/enumerable/first_spec.rb +4 -1
  126. data/spec/core/enumerable/fixtures/classes.rb +198 -2
  127. data/spec/core/enumerable/grep_spec.rb +4 -1
  128. data/spec/core/enumerable/take_spec.rb +4 -1
  129. data/spec/core/enumerable/to_a_spec.rb +4 -1
  130. data/spec/core/false/and_spec.rb +11 -0
  131. data/spec/core/false/inspect_spec.rb +7 -0
  132. data/spec/core/false/or_spec.rb +11 -0
  133. data/spec/core/false/to_s_spec.rb +7 -0
  134. data/spec/core/false/xor_spec.rb +11 -0
  135. data/spec/core/kernel/rand_spec.rb +5 -5
  136. data/spec/core/module/const_get_spec.rb +4 -4
  137. data/spec/core/module/fixtures/classes.rb +434 -0
  138. data/spec/core/module/method_defined_spec.rb +49 -0
  139. data/spec/core/module/module_function_spec.rb +28 -0
  140. data/spec/core/nil/and_spec.rb +3 -1
  141. data/spec/core/nil/dup_spec.rb +7 -0
  142. data/spec/core/nil/inspect_spec.rb +3 -1
  143. data/spec/core/nil/nil_spec.rb +3 -1
  144. data/spec/core/nil/or_spec.rb +4 -2
  145. data/spec/core/nil/to_a_spec.rb +3 -1
  146. data/spec/core/nil/to_f_spec.rb +3 -1
  147. data/spec/core/nil/to_i_spec.rb +3 -1
  148. data/spec/core/nil/to_s_spec.rb +3 -1
  149. data/spec/core/nil/xor_spec.rb +4 -2
  150. data/spec/core/string/element_reference_spec.rb +14 -1
  151. data/spec/core/string/fixtures/classes.rb +0 -0
  152. data/spec/core/true/and_spec.rb +11 -0
  153. data/spec/core/true/inspect_spec.rb +7 -0
  154. data/spec/core/true/or_spec.rb +11 -0
  155. data/spec/core/true/to_s_spec.rb +7 -0
  156. data/spec/core/true/xor_spec.rb +11 -0
  157. data/spec/{core → core_ext}/array/element_reference_spec.rb +0 -0
  158. data/spec/{core → core_ext}/array/equal_value_spec.rb +0 -0
  159. data/spec/{core → core_ext}/array/fill_spec.rb +0 -0
  160. data/spec/{core → core_ext}/array/reduce_spec.rb +0 -0
  161. data/spec/core_ext/basic_object/send_spec.rb +3 -3
  162. data/spec/{core → core_ext}/boolean/singleton_class_spec.rb +0 -0
  163. data/spec/{core → core_ext}/boolean/to_json_spec.rb +0 -0
  164. data/spec/core_ext/class/_inherited_spec.rb +3 -3
  165. data/spec/core_ext/class/proc_methods_spec.rb +2 -2
  166. data/spec/core_ext/class/singleton_methods_spec.rb +8 -8
  167. data/spec/core_ext/method_missing_spec.rb +3 -3
  168. data/spec/core_ext/native/method_missing_spec.rb +3 -2
  169. data/spec/core_ext/native/to_native_spec.rb +3 -2
  170. data/spec/{core → core_ext}/nil/to_json_spec.rb +0 -0
  171. data/spec/date.rb +0 -0
  172. data/spec/fileutils.rb +0 -0
  173. data/spec/filters/ancestors.rb +4 -0
  174. data/spec/filters/array_delete.rb +3 -0
  175. data/spec/filters/array_fetch.rb +3 -0
  176. data/spec/filters/array_first.rb +3 -0
  177. data/spec/filters/array_flatten.rb +14 -0
  178. data/spec/filters/array_intersection.rb +5 -0
  179. data/spec/filters/array_join.rb +6 -0
  180. data/spec/filters/array_subclasses.rb +4 -0
  181. data/spec/filters/block_args.rb +3 -0
  182. data/spec/filters/coerce_integer.rb +9 -0
  183. data/spec/filters/frozen.rb +4 -0
  184. data/spec/filters/mocks.rb +3 -0
  185. data/spec/filters/should_receive.rb +4 -0
  186. data/spec/filters/tainted.rb +7 -0
  187. data/spec/fixtures/class.rb +124 -0
  188. data/spec/fixtures/class_variables.rb +0 -0
  189. data/spec/fixtures/constants.rb +0 -0
  190. data/spec/grammar/alias_spec.rb +1 -1
  191. data/spec/grammar/def_spec.rb +1 -0
  192. data/spec/grammar/lvar_spec.rb +1 -2
  193. data/spec/grammar/nth_ref_spec.rb +13 -0
  194. data/spec/grammar/sclass_spec.rb +6 -7
  195. data/spec/grammar/str_spec.rb +4 -4
  196. data/spec/grammar/string_spec.rb +8 -0
  197. data/spec/grammar/xstr_spec.rb +4 -4
  198. data/spec/iconv.rb +0 -0
  199. data/spec/language/alias_spec.rb +140 -3
  200. data/spec/language/and_spec.rb +14 -7
  201. data/spec/language/array_spec.rb +57 -5
  202. data/spec/language/block_spec.rb +466 -49
  203. data/spec/language/break_spec.rb +294 -44
  204. data/spec/language/case_spec.rb +151 -3
  205. data/spec/language/class_spec.rb +196 -0
  206. data/spec/language/class_variable_spec.rb +56 -0
  207. data/spec/language/def_spec.rb +507 -4
  208. data/spec/language/defined_spec.rb +19 -7
  209. data/spec/language/ensure_spec.rb +26 -39
  210. data/spec/language/execution_spec.rb +15 -0
  211. data/spec/language/fixtures/array.rb +11 -0
  212. data/spec/language/fixtures/block.rb +57 -0
  213. data/spec/language/fixtures/break.rb +240 -0
  214. data/spec/language/fixtures/ensure.rb +72 -0
  215. data/spec/language/fixtures/literal_lambda.rb +7 -0
  216. data/spec/language/fixtures/metaclass.rb +33 -0
  217. data/spec/language/fixtures/module.rb +24 -0
  218. data/spec/language/fixtures/next.rb +78 -12
  219. data/spec/language/fixtures/return.rb +118 -0
  220. data/spec/language/fixtures/send.rb +110 -0
  221. data/spec/language/fixtures/send_1.9.rb +22 -0
  222. data/spec/language/fixtures/super.rb +308 -0
  223. data/spec/language/fixtures/variables.rb +58 -0
  224. data/spec/language/fixtures/yield.rb +5 -0
  225. data/spec/language/for_spec.rb +192 -0
  226. data/spec/language/hash_spec.rb +29 -5
  227. data/spec/language/if_spec.rb +90 -9
  228. data/spec/language/literal_lambda_spec.rb +1 -47
  229. data/spec/language/loop_spec.rb +39 -2
  230. data/spec/language/metaclass_spec.rb +151 -5
  231. data/spec/language/module_spec.rb +56 -0
  232. data/spec/language/next_spec.rb +370 -12
  233. data/spec/language/not_spec.rb +55 -0
  234. data/spec/language/numbers_spec.rb +56 -0
  235. data/spec/language/or_spec.rb +31 -3
  236. data/spec/language/order_spec.rb +79 -0
  237. data/spec/language/precedence_spec.rb +483 -0
  238. data/spec/language/proc_spec.rb +249 -21
  239. data/spec/language/redo_spec.rb +67 -0
  240. data/spec/language/rescue_spec.rb +121 -0
  241. data/spec/language/retry_spec.rb +56 -0
  242. data/spec/language/return_spec.rb +281 -0
  243. data/spec/language/send_spec.rb +141 -48
  244. data/spec/language/singleton_class_spec.rb +1 -1
  245. data/spec/language/string_spec.rb +11 -0
  246. data/spec/language/super_spec.rb +213 -133
  247. data/spec/language/symbol_spec.rb +2 -1
  248. data/spec/language/undef_spec.rb +3 -1
  249. data/spec/language/unless_spec.rb +6 -2
  250. data/spec/language/until_spec.rb +102 -3
  251. data/spec/language/variables_spec.rb +1212 -16
  252. data/spec/language/versions/array_1.9.rb +39 -0
  253. data/spec/language/versions/case_1.9.rb +20 -0
  254. data/spec/language/versions/hash_1.9.rb +18 -0
  255. data/spec/language/versions/literal_lambda_1.9.rb +143 -0
  256. data/spec/language/versions/not_1.9.rb +22 -0
  257. data/spec/language/versions/send_1.9.rb +241 -0
  258. data/spec/language/versions/symbol_1.9.rb +15 -0
  259. data/spec/language/versions/variables_1.9.rb +8 -0
  260. data/spec/language/while_spec.rb +70 -5
  261. data/spec/language/yield_spec.rb +32 -6
  262. data/spec/mspec/guards/block_device.rb +0 -0
  263. data/spec/mspec/guards/endian.rb +0 -0
  264. data/spec/mspec/helpers/environment.rb +0 -0
  265. data/spec/mspec/helpers/language_version.rb +0 -0
  266. data/spec/mspec/helpers/tmp.rb +0 -0
  267. data/spec/ospec/filter.rb +32 -0
  268. data/spec/ospec/main.rb.erb +18 -0
  269. data/spec/ospec/phantom.rb +97 -0
  270. data/spec/ospec/runner.rb +95 -0
  271. data/spec/ospec/sprockets.js +40 -0
  272. data/spec/pp.rb +3 -0
  273. data/spec/rbconfig.rb +5 -0
  274. data/spec/spec_helper.rb +53 -26
  275. data/spec/yaml.rb +0 -0
  276. metadata +275 -31
  277. data/config.ru +0 -8
  278. data/lib/opal/processor.rb +0 -47
  279. data/lib/opal/scope.rb +0 -236
  280. data/lib/opal/server.rb +0 -94
  281. data/spec/core/boolean/and_spec.rb +0 -17
  282. data/spec/core/boolean/inspect_spec.rb +0 -9
  283. data/spec/core/boolean/or_spec.rb +0 -17
  284. data/spec/core/boolean/to_s_spec.rb +0 -9
  285. data/spec/core/boolean/xor_spec.rb +0 -17
@@ -1,68 +1,204 @@
1
- module BreakSpecs
2
- class Driver
3
- def initialize(ensures=false)
4
- @ensures = ensures
5
- end
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/break', __FILE__)
6
3
 
7
- def note(value)
8
- ScratchPad << value
9
- end
4
+ describe "The break statement in a block" do
5
+ before :each do
6
+ ScratchPad.record []
7
+ @program = BreakSpecs::Block.new
10
8
  end
11
9
 
12
- class Block < Driver
13
- def break_nil
14
- note :a
15
- note yielding {
16
- note :b
17
- break
18
- note :c
19
- }
20
- note :d
10
+ it "returns nil to method invoking the method yielding to the block when not passed an argument" do
11
+ @program.break_nil
12
+ ScratchPad.recorded.should == [:a, :aa, :b, nil, :d]
13
+ end
14
+
15
+ it "returns a value to the method invoking the method yielding to the block" do
16
+ @program.break_value
17
+ ScratchPad.recorded.should == [:a, :aa, :b, :break, :d]
18
+ end
19
+ end
20
+
21
+ describe "The break statement in a captured block" do
22
+ before :each do
23
+ ScratchPad.record []
24
+ @program = BreakSpecs::Block.new
25
+ end
26
+
27
+ describe "when the invocation of the scope creating the block is still active" do
28
+ pending do
29
+ deviates_on :rubinius do
30
+ it "returns a value to the invoking scope when invoking the block from the scope creating the block" do
31
+ @program.break_in_method
32
+ ScratchPad.recorded.should == [:a, :xa, :d, :b, :break, :e]
33
+ end
34
+
35
+ it "returns a value to the scope invoking the method when invoking the block from a method" do
36
+ @program.break_in_nested_method
37
+ ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b, :break, :d]
38
+ end
39
+
40
+ it "returns a value to the scope calling the yielding scope when yielding to the block" do
41
+ @program.break_in_yielding_method
42
+ ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b, :break, :d]
43
+ end
44
+ end
45
+
46
+ not_compliant_on :rubinius do
47
+ it "raises a LocalJumpError when invoking the block from the scope creating the block" do
48
+ lambda { @program.break_in_method }.should raise_error(LocalJumpError)
49
+ ScratchPad.recorded.should == [:a, :xa, :d, :b]
50
+ end
51
+
52
+ it "raises a LocalJumpError when invoking the block from a method" do
53
+ lambda { @program.break_in_nested_method }.should raise_error(LocalJumpError)
54
+ ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b]
55
+ end
56
+
57
+ it "raises a LocalJumpError when yielding to the block" do
58
+ lambda { @program.break_in_yielding_method }.should raise_error(LocalJumpError)
59
+ ScratchPad.recorded.should == [:a, :xa, :c, :aa, :b]
60
+ end
61
+ end
21
62
  end
63
+ end
22
64
 
23
- def break_value
24
- note :a
25
- note yielding {
26
- note :b
27
- break :break
28
- note :c
29
- }
30
- note :d
65
+ describe "from a scope that has returned" do
66
+ pending "raises a LocalJumpError when calling the block from a method" do
67
+ lambda { @program.break_in_method_captured }.should raise_error(LocalJumpError)
68
+ ScratchPad.recorded.should == [:a, :za, :xa, :zd, :zb]
31
69
  end
32
70
 
33
- def yielding
34
- note :aa
35
- note yield
36
- note :bb
71
+ pending "raises a LocalJumpError when yielding to the block" do
72
+ lambda { @program.break_in_yield_captured }.should raise_error(LocalJumpError)
73
+ ScratchPad.recorded.should == [:a, :za, :xa, :zd, :aa, :zb]
37
74
  end
38
75
  end
39
76
  end
40
77
 
41
- describe "The break statement in a block" do
78
+ describe "The break statement in a lambda" do
42
79
  before :each do
43
80
  ScratchPad.record []
44
- @program = BreakSpecs::Block.new
81
+ @program = BreakSpecs::Lambda.new
45
82
  end
46
83
 
47
- it "returns nil to method invoking the method yielding to the block when not passed an argument" do
48
- @program.break_nil
49
- ScratchPad.recorded.should == [:a, :aa, :b, nil, :d]
84
+ describe "when the invocation of the scope creating the lambda is still active" do
85
+ pending "returns nil when not passed an argument" do
86
+ @program.break_in_defining_scope false
87
+ ScratchPad.recorded.should == [:a, :b, nil, :d]
88
+ end
89
+
90
+ pending "returns a value to the scope creating and calling the lambda" do
91
+ @program.break_in_defining_scope
92
+ ScratchPad.recorded.should == [:a, :b, :break, :d]
93
+ end
94
+
95
+ pending "returns a value to the method scope below invoking the lambda" do
96
+ @program.break_in_nested_scope
97
+ ScratchPad.recorded.should == [:a, :d, :aa, :b, :break, :bb, :e]
98
+ end
99
+
100
+ pending "returns a value to a block scope invoking the lambda in a method below" do
101
+ @program.break_in_nested_scope_block
102
+ ScratchPad.recorded.should == [:a, :d, :aa, :aaa, :bb, :b, :break, :cc, :bbb, :dd, :e]
103
+ end
104
+
105
+ pending do
106
+ deviates_on :rubinius do
107
+ it "returns a value when yielding to a lambda passed as a block argument" do
108
+ @program.break_in_nested_scope_yield
109
+ ScratchPad.recorded.should == [:a, :d, :aaa, :b, :break, :e]
110
+ end
111
+ end
112
+
113
+ not_compliant_on :rubinius do
114
+ it "raises a LocalJumpError when yielding to a lambda passed as a block argument" do
115
+ lambda { @program.break_in_nested_scope_yield }.should raise_error(LocalJumpError)
116
+ ScratchPad.recorded.should == [:a, :d, :aaa, :b]
117
+ end
118
+ end
119
+ end
50
120
  end
51
121
 
52
- it "returns a value to the method invoking the method yielding to the block" do
53
- @program.break_value
54
- ScratchPad.recorded.should == [:a, :aa, :b, :break, :d]
122
+ describe "created at the toplevel" do
123
+ pending "returns a value when invoking from the toplevel" do
124
+ code = fixture __FILE__, "break_lambda_toplevel.rb"
125
+ ruby_exe(code).chomp.should == "a,b,break,d"
126
+ end
127
+
128
+ pending "returns a value when invoking from a method" do
129
+ code = fixture __FILE__, "break_lambda_toplevel_method.rb"
130
+ ruby_exe(code).chomp.should == "a,d,b,break,e,f"
131
+ end
132
+
133
+ pending "returns a value when invoking from a block" do
134
+ code = fixture __FILE__, "break_lambda_toplevel_block.rb"
135
+ ruby_exe(code).chomp.should == "a,d,f,b,break,g,e,h"
136
+ end
137
+ end
138
+
139
+ describe "from a scope that has returned" do
140
+ pending "returns a value to the method scope invoking the lambda" do
141
+ @program.break_in_method
142
+ ScratchPad.recorded.should == [:a, :la, :ld, :lb, :break, :b]
143
+ end
144
+
145
+ pending "returns a value to the block scope invoking the lambda in a method" do
146
+ @program.break_in_block_in_method
147
+ ScratchPad.recorded.should == [:a, :aaa, :b, :la, :ld, :lb, :break, :c, :bbb, :d]
148
+ end
149
+
150
+ # By passing a lambda as a block argument, the user is requesting to treat
151
+ # the lambda as a block, which in this case means breaking to a scope that
152
+ # has returned. This is a subtle and confusing semantic where a block pass
153
+ # is removing the lambda-ness of a lambda.
154
+ pending "raises a LocalJumpError when yielding to a lambda passed as a block argument" do
155
+ lambda { @program.break_in_method_yield }.should raise_error(LocalJumpError)
156
+ ScratchPad.recorded.should == [:a, :la, :ld, :aaa, :lb]
157
+ end
55
158
  end
56
159
  end
57
160
 
58
161
  describe "Break inside a while loop" do
59
162
  describe "with a value" do
60
- it "exists the loop and returns the value" do
61
- a = while true; break; end; a.should == nil
62
- a = while true; break nil; end; a.should == nil
63
- a = while true; break 1; end; a.should == 1
64
- a = while true; break []; end; a.should == []
65
- a = while true; break [1]; end; a.should == [1]
163
+ it "exits the loop and returns the value" do
164
+ a = while true; break; end; a.should == nil
165
+ a = while true; break nil; end; a.should == nil
166
+ a = while true; break 1; end; a.should == 1
167
+ a = while true; break []; end; a.should == []
168
+ a = while true; break [1]; end; a.should == [1]
169
+ end
170
+ end
171
+
172
+ describe "with a splat" do
173
+ it "exits the loop and makes the splat an Array" do
174
+ a = while true; break *[1,2]; end; a.should == [1,2]
175
+ end
176
+
177
+ ruby_version_is "" ... "1.9" do
178
+ it "unwraps the value if there is only one value" do
179
+ a = while true; break *1; end; a.should == 1
180
+ end
181
+
182
+ it "makes the value nil if the splat is empty" do
183
+ a = while true; break *[]; end; a.should == nil
184
+ end
185
+ end
186
+
187
+ ruby_version_is "1.9" do
188
+ it "treats nil as an empty array" do
189
+ a = while true; break *nil; end; a.should == []
190
+ end
191
+
192
+ it "preserves an array as is" do
193
+ a = while true; break *[]; end; a.should == []
194
+ a = while true; break *[1,2]; end; a.should == [1,2]
195
+ a = while true; break *[nil]; end; a.should == [nil]
196
+ a = while true; break *[[]]; end; a.should == [[]]
197
+ end
198
+
199
+ it "wraps a non-Array in an Array" do
200
+ a = while true; break *1; end; a.should == [1]
201
+ end
66
202
  end
67
203
  end
68
204
 
@@ -83,4 +219,118 @@ describe "Break inside a while loop" do
83
219
  end.should == 2
84
220
  at.should == 2
85
221
  end
86
- end
222
+ end
223
+
224
+
225
+ # TODO: Rewrite all the specs from here to the end of the file in the style
226
+ # above.
227
+ describe "Executing break from within a block" do
228
+
229
+ before :each do
230
+ ScratchPad.clear
231
+ end
232
+
233
+ # Discovered in JRuby (see JRUBY-2756)
234
+ pending "returns from the original invoking method even in case of chained calls" do
235
+ class BreakTest
236
+ # case #1: yield
237
+ def self.meth_with_yield(&b)
238
+ yield
239
+ fail("break returned from yield to wrong place")
240
+ end
241
+ def self.invoking_method(&b)
242
+ meth_with_yield(&b)
243
+ fail("break returned from 'meth_with_yield' method to wrong place")
244
+ end
245
+
246
+ # case #2: block.call
247
+ def self.meth_with_block_call(&b)
248
+ b.call
249
+ fail("break returned from b.call to wrong place")
250
+ end
251
+ def self.invoking_method2(&b)
252
+ meth_with_block_call(&b)
253
+ fail("break returned from 'meth_with_block_call' method to wrong place")
254
+ end
255
+ end
256
+
257
+ # this calls a method that calls another method that yields to the block
258
+ BreakTest.invoking_method do
259
+ break
260
+ fail("break didn't, well, break")
261
+ end
262
+
263
+ # this calls a method that calls another method that calls the block
264
+ BreakTest.invoking_method2 do
265
+ break
266
+ fail("break didn't, well, break")
267
+ end
268
+
269
+ res = BreakTest.invoking_method do
270
+ break :return_value
271
+ fail("break didn't, well, break")
272
+ end
273
+ res.should == :return_value
274
+
275
+ res = BreakTest.invoking_method2 do
276
+ break :return_value
277
+ fail("break didn't, well, break")
278
+ end
279
+ res.should == :return_value
280
+
281
+ end
282
+
283
+ class BreakTest2
284
+ def one
285
+ two { yield }
286
+ end
287
+
288
+ def two
289
+ yield
290
+ ensure
291
+ ScratchPad << :two_ensure
292
+ end
293
+
294
+ def three
295
+ begin
296
+ one { break }
297
+ ScratchPad << :three_post
298
+ ensure
299
+ ScratchPad << :three_ensure
300
+ end
301
+ end
302
+ end
303
+
304
+ pending "runs ensures when continuing upward" do
305
+ ScratchPad.record []
306
+
307
+ bt2 = BreakTest2.new
308
+ bt2.one { break }
309
+ ScratchPad.recorded.should == [:two_ensure]
310
+ end
311
+
312
+ it "runs ensures when breaking from a loop" do
313
+ ScratchPad.record []
314
+
315
+ while true
316
+ begin
317
+ ScratchPad << :begin
318
+ break if true
319
+ ensure
320
+ ScratchPad << :ensure
321
+ end
322
+ end
323
+
324
+ ScratchPad.recorded.should == [:begin, :ensure]
325
+ end
326
+
327
+ pending "doesn't run ensures in the destination method" do
328
+ ScratchPad.record []
329
+
330
+ bt2 = BreakTest2.new
331
+ bt2.three
332
+ ScratchPad.recorded.should == [:two_ensure, :three_post, :three_ensure]
333
+ end
334
+ end
335
+
336
+ # language_version __FILE__, "break"
@@ -1,3 +1,5 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
1
3
  describe "The 'case'-construct" do
2
4
  it "evaluates the body of the when clause matching the case target expression" do
3
5
  case 1
@@ -127,7 +129,7 @@ describe "The 'case'-construct" do
127
129
 
128
130
  it "takes an expanded array in addition to a list of values" do
129
131
  case 'f'
130
- when 'f', *['a', 'b', 'c', 'd']
132
+ when 'f', *['a', 'b', 'c', 'd']
131
133
  "foo"
132
134
  when *['x', 'y', 'z']
133
135
  "bar"
@@ -141,6 +143,7 @@ describe "The 'case'-construct" do
141
143
  end.should == "foo"
142
144
  end
143
145
 
146
+ # MR: critical
144
147
  it "concats arrays before expanding them" do
145
148
  a = ['a', 'b', 'c', 'd']
146
149
  b = ['f']
@@ -153,10 +156,155 @@ describe "The 'case'-construct" do
153
156
  end.should == "foo"
154
157
  end
155
158
 
156
- it "never matchers when clauses with no values" do
159
+ it "never matches when clauses with no values" do
157
160
  case nil
158
161
  when *[]
159
162
  "foo"
160
163
  end.should == nil
161
164
  end
162
- end
165
+
166
+ pending "lets you define a method after the case statement" do
167
+ case (def foo; 'foo'; end; 'f')
168
+ when 'a'
169
+ 'foo'
170
+ when 'f'
171
+ 'bar'
172
+ end.should == 'bar'
173
+ end
174
+
175
+ it "raises a SyntaxError when 'else' is used when no 'when' is given" do
176
+ lambda {
177
+ eval <<-CODE
178
+ case 4
179
+ else
180
+ true
181
+ end
182
+ CODE
183
+ }.should raise_error(SyntaxError)
184
+ end
185
+
186
+ it "raises a SyntaxError when 'else' is used before a 'when' was given" do
187
+ lambda {
188
+ eval <<-CODE
189
+ case 4
190
+ else
191
+ true
192
+ when 4; false
193
+ end
194
+ CODE
195
+ }.should raise_error(SyntaxError)
196
+ end
197
+
198
+ it "supports nested case statements" do
199
+ result = false
200
+ case :x
201
+ when Symbol
202
+ case :y
203
+ when Symbol
204
+ result = true
205
+ end
206
+ end
207
+ result.should == true
208
+ end
209
+
210
+ it "supports nested case statements followed by a when with a splatted array" do
211
+ result = false
212
+ case :x
213
+ when Symbol
214
+ case :y
215
+ when Symbol
216
+ result = true
217
+ end
218
+ when *[Symbol]
219
+ result = false
220
+ end
221
+ result.should == true
222
+ end
223
+
224
+ it "supports nested case statements followed by a when with a splatted non-array" do
225
+ result = false
226
+ case :x
227
+ when Symbol
228
+ case :y
229
+ when Symbol
230
+ result = true
231
+ end
232
+ when *Symbol
233
+ result = false
234
+ end
235
+ result.should == true
236
+ end
237
+
238
+ it "works even if there's only one when statement" do
239
+ case 1
240
+ when 1
241
+ 100
242
+ end.should == 100
243
+ end
244
+ end
245
+
246
+ describe "The 'case'-construct with no target expression" do
247
+ pending "evaluates the body of the first clause when at least one of its condition expressions is true" do
248
+ # case
249
+ # when true, false; 'foo'
250
+ # end.should == 'foo'
251
+ end
252
+
253
+ pending "evaluates the body of the first when clause that is not false/nil" do
254
+ # case
255
+ # when false; 'foo'
256
+ # when 2; 'bar'
257
+ # when 1 == 1; 'baz'
258
+ # end.should == 'bar'
259
+
260
+ # case
261
+ # when false; 'foo'
262
+ # when nil; 'foo'
263
+ # when 1 == 1; 'bar'
264
+ # end.should == 'bar'
265
+ end
266
+
267
+ pending "evaluates the body of the else clause if all when clauses are false/nil" do
268
+ # case
269
+ # when false; 'foo'
270
+ # when nil; 'foo'
271
+ # when 1 == 2; 'bar'
272
+ # else 'baz'
273
+ # end.should == 'baz'
274
+ end
275
+
276
+ pending "evaluates multiple conditional expressions as a boolean disjunction" do
277
+ # case
278
+ # when true, false; 'foo'
279
+ # else 'bar'
280
+ # end.should == 'foo'
281
+
282
+ # case
283
+ # when false, true; 'foo'
284
+ # else 'bar'
285
+ # end.should == 'foo'
286
+ end
287
+
288
+ pending "evaluates true as only 'true' when true is the first clause" do
289
+ case 1
290
+ when true; "bad"
291
+ when Integer; "good"
292
+ end.should == "good"
293
+ end
294
+
295
+ it "evaluates false as only 'false' when false is the first clause" do
296
+ case nil
297
+ when false; "bad"
298
+ when nil; "good"
299
+ end.should == "good"
300
+ end
301
+
302
+ it "treats a literal array as its own when argument, rather than a list of arguments" do
303
+ case 'foo'
304
+ when ['foo', 'foo']; 'bad'
305
+ when 'foo'; 'good'
306
+ end.should == 'good'
307
+ end
308
+ end
309
+
310
+ # language_version __FILE__, "case"