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,3 +1,5 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
1
3
  class UndefSpecClass
2
4
  def meth(other);other;end
3
5
  end
@@ -11,4 +13,4 @@ describe "The undef keyword" do
11
13
  end
12
14
  lambda { obj.meth 5 }.should raise_error(NoMethodError)
13
15
  end
14
- end
16
+ end
@@ -1,3 +1,5 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
1
3
  describe "The unless expression" do
2
4
  it "evaluates the unless body when the expression is false" do
3
5
  unless false
@@ -25,7 +27,7 @@ describe "The unless expression" do
25
27
  end.should == 'bar'
26
28
  end
27
29
 
28
- it "takes and optional then after the expression" do
30
+ it "takes an optional then after the expression" do
29
31
  unless false then
30
32
  'baz'
31
33
  end.should == 'baz'
@@ -38,4 +40,6 @@ describe "The unless expression" do
38
40
  it "allows expression and body to be on one line (using 'then')" do
39
41
  unless false then 'foo'; else 'bar'; end.should == 'foo'
40
42
  end
41
- end
43
+ end
44
+
45
+ # language_version __FILE__, "unless"
@@ -1,3 +1,14 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ # until bool-expr [do]
4
+ # body
5
+ # end
6
+ #
7
+ # begin
8
+ # body
9
+ # end until bool-expr
10
+ #
11
+ # expr until bool-expr
1
12
  describe "The until expression" do
2
13
  it "runs while the expression is false" do
3
14
  i = 0
@@ -91,6 +102,18 @@ describe "The until expression" do
91
102
  end
92
103
  a.should == [1, 2, 4]
93
104
  end
105
+
106
+ pending "restarts the current iteration without reevaluating condition with redo" do
107
+ a = []
108
+ i = 0
109
+ j = 0
110
+ until (i+=1)>=3
111
+ a << i
112
+ j+=1
113
+ redo if j<3
114
+ end
115
+ a.should == [1, 1, 1, 2]
116
+ end
94
117
  end
95
118
 
96
119
  describe "The until modifier" do
@@ -104,10 +127,10 @@ describe "The until modifier" do
104
127
  a = []
105
128
  i = 0
106
129
  a << i until (i+=1) >= 3
107
- a.should == [1,2]
130
+ a.should == [1, 2]
108
131
  end
109
132
 
110
- it "does not run the preceding statement if the condition is true" do
133
+ it "does not run preceding statement if the condition is true" do
111
134
  i = 0
112
135
  i += 1 until true
113
136
  i.should == 0
@@ -132,4 +155,80 @@ describe "The until modifier" do
132
155
  ((i+=1) == 3 ? next : j+=i) until i > 10
133
156
  j.should == 63
134
157
  end
135
- end
158
+
159
+ pending "restarts the current iteration without reevaluating condition with redo" do
160
+ i = 0
161
+ j = 0
162
+ (i+=1) == 4 ? redo : j+=i until (i+=1) > 10
163
+ j.should == 34
164
+ end
165
+ end
166
+
167
+ describe "The until modifier with begin .. end block" do
168
+ pending "runs block while the expression is false" do
169
+ i = 0
170
+ begin
171
+ i += 1
172
+ end until i > 9
173
+
174
+ i.should == 10
175
+ end
176
+
177
+ pending "stops running block if interrupted by break" do
178
+ i = 0
179
+ begin
180
+ i += 1
181
+ break if i > 5
182
+ end until i > 9
183
+
184
+ i.should == 6
185
+ end
186
+
187
+ pending "returns value passed to break if interrupted by break" do
188
+ (begin; break 123; end until false).should == 123
189
+ end
190
+
191
+ pending "returns nil if interrupted by break with no arguments" do
192
+ (begin; break; end until false).should == nil
193
+ end
194
+
195
+ pending "runs block at least once (even if the expression is true)" do
196
+ i = 0
197
+ begin
198
+ i += 1
199
+ end until true
200
+
201
+ i.should == 1
202
+ end
203
+
204
+ pending "evaluates condition after block execution" do
205
+ a = []
206
+ i = 0
207
+ begin
208
+ a << i
209
+ end until (i+=1)>=5
210
+ a.should == [0, 1, 2, 3, 4]
211
+ end
212
+
213
+ pending "skips to end of body with next" do
214
+ a = []
215
+ i = 0
216
+ begin
217
+ next if i==3
218
+ a << i
219
+ end until (i+=1)>=5
220
+ a.should == [0, 1, 2, 4]
221
+ end
222
+
223
+ pending "restart the current iteration without reevaluting condition with redo" do
224
+ a = []
225
+ i = 0
226
+ j = 0
227
+ begin
228
+ a << i
229
+ j+=1
230
+ redo if j<3
231
+ end until (i+=1)>=3
232
+ a.should == [0, 0, 0, 1, 2]
233
+ end
234
+ end
@@ -1,3 +1,8 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/variables', __FILE__)
3
+
4
+ # TODO: partition these specs into distinct cases based on the
5
+ # real parsed forms, not the superficial code forms.
1
6
  describe "Basic assignment" do
2
7
  it "allows the rhs to be assigned to the lhs" do
3
8
  a = nil
@@ -9,19 +14,86 @@ describe "Basic assignment" do
9
14
  a.should be_nil
10
15
  end
11
16
 
12
- it "assigns [] to lhs when rhs is an empty splat expression" do
13
- a = *()
14
- a.should == []
17
+ ruby_version_is "" ... "1.9" do
18
+ it "assigns nil to lhs when rhs is an empty splat expression" do
19
+ a = *()
20
+ a.should be_nil
21
+ end
22
+ end
23
+
24
+ ruby_version_is "1.9" do
25
+ it "assigns [] to lhs when rhs is an empty splat expression" do
26
+ a = *()
27
+ a.should == []
28
+ end
29
+ end
30
+
31
+ ruby_version_is "" ... "1.9" do
32
+ it "allows the assignment of the rhs to the lhs using the rhs splat operator" do
33
+ a = *nil; a.should == nil
34
+ a = *1; a.should == 1
35
+ a = *[]; a.should == nil
36
+ a = *[1]; a.should == 1
37
+ a = *[nil]; a.should == nil
38
+ a = *[[]]; a.should == []
39
+ a = *[1,2]; a.should == [1,2]
40
+ end
15
41
  end
16
42
 
17
- it "allows the assignment of the rhs to the lhs using the rhs splat operator" do
18
- a = *nil; a.should == []
19
- a = *1; a.should == [1]
20
- a = *[]; a.should == []
21
- a = *[1]; a.should == [1]
22
- a = *[nil]; a.should == [nil]
23
- a = *[[]]; a.should == [[]]
24
- a = *[1,2]; a.should == [1,2]
43
+ ruby_version_is "1.9" do
44
+ it "allows the assignment of the rhs to the lhs using the rhs splat operator" do
45
+ a = *nil; a.should == []
46
+ a = *1; a.should == [1]
47
+ a = *[]; a.should == []
48
+ a = *[1]; a.should == [1]
49
+ a = *[nil]; a.should == [nil]
50
+ a = *[[]]; a.should == [[]]
51
+ a = *[1,2]; a.should == [1,2]
52
+ end
53
+ end
54
+
55
+ ruby_version_is "" ... "1.9" do
56
+ it "allows the assignment of the rhs to the lhs using the lhs splat operator" do
57
+ # * = 1,2 # Valid syntax, but pretty useless! Nothing to test
58
+ *a = nil; a.should == [nil]
59
+ *a = 1; a.should == [1]
60
+ *a = []; a.should == [[]]
61
+ *a = [1]; a.should == [[1]]
62
+ *a = [1,2]; a.should == [[1,2]]
63
+ end
64
+ end
65
+
66
+ ruby_version_is "1.9" do
67
+ pending "allows the assignment of the rhs to the lhs using the lhs splat operator" do
68
+ # * = 1,2 # Valid syntax, but pretty useless! Nothing to test
69
+ *a = nil; a.should == [nil]
70
+ *a = 1; a.should == [1]
71
+ *a = []; a.should == []
72
+ *a = [1]; a.should == [1]
73
+ *a = [1,2]; a.should == [1,2]
74
+ end
75
+ end
76
+
77
+ ruby_version_is "" ... "1.9" do
78
+ it "allows the assignment of rhs to the lhs using the lhs and rhs splat operators simultaneously" do
79
+ *a = *nil; a.should == [nil]
80
+ *a = *1; a.should == [1]
81
+ *a = *[]; a.should == []
82
+ *a = *[1]; a.should == [1]
83
+ *a = *[nil]; a.should == [nil]
84
+ *a = *[1,2]; a.should == [1,2]
85
+ end
86
+ end
87
+
88
+ ruby_version_is "1.9" do
89
+ pending "allows the assignment of rhs to the lhs using the lhs and rhs splat operators simultaneously" do
90
+ *a = *nil; a.should == []
91
+ *a = *1; a.should == [1]
92
+ *a = *[]; a.should == []
93
+ *a = *[1]; a.should == [1]
94
+ *a = *[nil]; a.should == [nil]
95
+ *a = *[1,2]; a.should == [1,2]
96
+ end
25
97
  end
26
98
 
27
99
  it "sets unavailable values to nil" do
@@ -42,7 +114,7 @@ describe "Basic assignment" do
42
114
  c.should == []
43
115
  end
44
116
 
45
- it "allows multiple values to be assigned" do
117
+ pending "allows multiple values to be assigned" do
46
118
  a,b,*c = nil; [a,b,c].should == [nil, nil, []]
47
119
  a,b,*c = 1; [a,b,c].should == [1, nil, []]
48
120
  a,b,*c = []; [a,b,c].should == [nil, nil, []]
@@ -52,12 +124,29 @@ describe "Basic assignment" do
52
124
  a,b,*c = [1,2]; [a,b,c].should == [1,2,[]]
53
125
 
54
126
  a,b,*c = *nil; [a,b,c].should == [nil, nil, []]
127
+ a,b,*c = *1; [a,b,c].should == [1, nil, []]
55
128
  a,b,*c = *[]; [a,b,c].should == [nil, nil, []]
129
+ a,b,*c = *[1]; [a,b,c].should == [1, nil, []]
56
130
  a,b,*c = *[nil]; [a,b,c].should == [nil, nil, []]
57
131
  a,b,*c = *[[]]; [a,b,c].should == [[], nil, []]
58
132
  a,b,*c = *[1,2]; [a,b,c].should == [1,2,[]]
59
133
  end
60
134
 
135
+ pending "calls to_a on the given argument when using a splat" do
136
+ a,b = *VariablesSpecs::ArrayLike.new([1,2]); [a,b].should == [1,2]
137
+ end
138
+
139
+ it "supports the {|r,| } form of block assignment" do
140
+ f = lambda {|r,| r.should == []}
141
+ f.call([], *[])
142
+
143
+ f = lambda{|x,| x}
144
+ f.call(42).should == 42
145
+ f.call([42]).should == [42]
146
+ f.call([[42]]).should == [[42]]
147
+ f.call([42,55]).should == [42,55]
148
+ end
149
+
61
150
  it "allows assignment through lambda" do
62
151
  f = lambda {|r,*l| r.should == []; l.should == [1]}
63
152
  f.call([], *[1])
@@ -86,6 +175,13 @@ describe "Basic assignment" do
86
175
  end
87
176
 
88
177
  describe "Assignment using expansion" do
178
+ ruby_version_is "" ... "1.9" do
179
+ it "succeeds without conversion" do
180
+ *x = (1..7).to_a
181
+ x.should == [[1, 2, 3, 4, 5, 6, 7]]
182
+ end
183
+ end
184
+
89
185
  ruby_version_is "1.9" do
90
186
  it "succeeds without conversion" do
91
187
  *x = (1..7).to_a
@@ -94,13 +190,164 @@ describe "Assignment using expansion" do
94
190
  end
95
191
  end
96
192
 
193
+ describe "Basic multiple assignment" do
194
+ describe "with a single RHS value" do
195
+ pending "does not call #to_ary on an Array instance" do
196
+ x = [1, 2]
197
+ x.should_not_receive(:to_ary)
198
+
199
+ a, b = x
200
+ a.should == 1
201
+ b.should == 2
202
+ end
203
+
204
+ pending "does not call #to_a on an Array instance" do
205
+ x = [1, 2]
206
+ x.should_not_receive(:to_a)
207
+
208
+ a, b = x
209
+ a.should == 1
210
+ b.should == 2
211
+ end
212
+
213
+ pending "does not call #to_ary on an Array subclass instance" do
214
+ x = VariablesSpecs::ArraySubclass.new [1, 2]
215
+ x.should_not_receive(:to_ary)
216
+
217
+ a, b = x
218
+ a.should == 1
219
+ b.should == 2
220
+ end
221
+
222
+ pending "does not call #to_a on an Array subclass instance" do
223
+ x = VariablesSpecs::ArraySubclass.new [1, 2]
224
+ x.should_not_receive(:to_a)
225
+
226
+ a, b = x
227
+ a.should == 1
228
+ b.should == 2
229
+ end
230
+
231
+ pending "calls #to_ary on an object" do
232
+ x = mock("single rhs value for masgn")
233
+ x.should_receive(:to_ary).and_return([1, 2])
234
+
235
+ a, b = x
236
+ a.should == 1
237
+ b.should == 2
238
+ end
239
+
240
+ pending "does not call #to_a on an object if #to_ary is not defined" do
241
+ x = mock("single rhs value for masgn")
242
+ x.should_not_receive(:to_a)
243
+
244
+ a, b = x
245
+ a.should == x
246
+ b.should be_nil
247
+ end
248
+
249
+ it "does not call #to_a on a String" do
250
+ x = "one\ntwo"
251
+
252
+ a, b = x
253
+ a.should == x
254
+ b.should be_nil
255
+ end
256
+ end
257
+
258
+ describe "with a splatted single RHS value" do
259
+ pending "does not call #to_ary on an Array instance" do
260
+ x = [1, 2]
261
+ x.should_not_receive(:to_ary)
262
+
263
+ a, b = *x
264
+ a.should == 1
265
+ b.should == 2
266
+ end
267
+
268
+ pending "does not call #to_a on an Array instance" do
269
+ x = [1, 2]
270
+ x.should_not_receive(:to_a)
271
+
272
+ a, b = *x
273
+ a.should == 1
274
+ b.should == 2
275
+ end
276
+
277
+ pending "does not call #to_ary on an Array subclass instance" do
278
+ x = VariablesSpecs::ArraySubclass.new [1, 2]
279
+ x.should_not_receive(:to_ary)
280
+
281
+ a, b = *x
282
+ a.should == 1
283
+ b.should == 2
284
+ end
285
+
286
+ pending "does not call #to_a on an Array subclass instance" do
287
+ x = VariablesSpecs::ArraySubclass.new [1, 2]
288
+ x.should_not_receive(:to_a)
289
+
290
+ a, b = *x
291
+ a.should == 1
292
+ b.should == 2
293
+ end
294
+
295
+ pending "calls #to_a on an object if #to_ary is not defined" do
296
+ x = mock("single splatted rhs value for masgn")
297
+ x.should_receive(:to_a).and_return([1, 2])
298
+
299
+ a, b = *x
300
+ a.should == 1
301
+ b.should == 2
302
+ end
303
+
304
+ ruby_version_is ""..."1.9" do
305
+ it "calls #to_ary on an object" do
306
+ x = mock("single splatted rhs value for masgn")
307
+ x.should_receive(:to_ary).and_return([1, 2])
308
+
309
+ a, b = *x
310
+ a.should == 1
311
+ b.should == 2
312
+ end
313
+
314
+ it "calls #to_a on a String" do
315
+ x = "one\ntwo"
316
+
317
+ a, b = *x
318
+ a.should == "one\n"
319
+ b.should == "two"
320
+ end
321
+ end
322
+
323
+ ruby_version_is "1.9" do
324
+ pending "does not call #to_ary on an object" do
325
+ x = mock("single splatted rhs value for masgn")
326
+ x.should_not_receive(:to_ary)
327
+
328
+ a, b = *x
329
+ a.should == x
330
+ b.should be_nil
331
+ end
332
+
333
+ pending "does not call #to_a on a String" do
334
+ x = "one\ntwo"
335
+
336
+ a, b = *x
337
+ a.should == x
338
+ b.should be_nil
339
+ end
340
+ end
341
+ end
342
+ end
343
+
97
344
  describe "Assigning multiple values" do
98
- it "allows parallel assignment" do
345
+ pending "allows parallel assignment" do
99
346
  a, b = 1, 2
100
347
  a.should == 1
101
348
  b.should == 2
102
349
 
103
- a, = 1,2
350
+ # a, = 1,2
104
351
  a.should == 1
105
352
  end
106
353
 
@@ -111,6 +358,67 @@ describe "Assigning multiple values" do
111
358
  b.should == 1
112
359
  end
113
360
 
361
+ pending do
362
+ not_compliant_on :rubinius do
363
+ pending "returns the rhs values used for assignment as an array" do
364
+ # x = begin; a, b, c = 1, 2, 3; end
365
+ x.should == [1,2,3]
366
+ end
367
+ end
368
+ end
369
+
370
+ ruby_version_is "" ... "1.9" do
371
+ it "wraps a single value in an Array" do
372
+ *a = 1
373
+ a.should == [1]
374
+
375
+ b = [1]
376
+ *a = b
377
+ a.should == [b]
378
+ end
379
+ end
380
+
381
+ ruby_version_is "1.9" do
382
+ it "wraps a single value in an Array if it's not already one" do
383
+ *a = 1
384
+ a.should == [1]
385
+
386
+ b = [1]
387
+ *a = b
388
+ a.should == b
389
+ end
390
+ end
391
+
392
+ it "evaluates rhs left-to-right" do
393
+ a = VariablesSpecs::ParAsgn.new
394
+ d, e ,f = a.inc, a.inc, a.inc
395
+ d.should == 1
396
+ e.should == 2
397
+ f.should == 3
398
+ end
399
+
400
+ pending "supports parallel assignment to lhs args via object.method=" do
401
+ a = VariablesSpecs::ParAsgn.new
402
+ a.x, b = 1, 2
403
+
404
+ a.x.should == 1
405
+ b.should == 2
406
+
407
+ c = VariablesSpecs::ParAsgn.new
408
+ c.x, a.x = a.x, b
409
+
410
+ c.x.should == 1
411
+ a.x.should == 2
412
+ end
413
+
414
+ pending "supports parallel assignment to lhs args using []=" do
415
+ a = [1,2,3]
416
+ a[3], b = 4,5
417
+
418
+ a.should == [1,2,3,4]
419
+ b.should == 5
420
+ end
421
+
114
422
  it "bundles remaining values to an array when using the splat operator" do
115
423
  a, *b = 1, 2, 3
116
424
  a.should == 1
@@ -128,6 +436,659 @@ describe "Assigning multiple values" do
128
436
  a, = *[1]
129
437
  a.should == 1
130
438
  end
439
+
440
+ ruby_version_is ""..."1.9" do
441
+ it "calls #to_ary on rhs arg if rhs has only a single arg" do
442
+ x = VariablesSpecs::ParAsgn.new
443
+ a,b,c = x
444
+ a.should == 1
445
+ b.should == 2
446
+ c.should == 3
447
+
448
+ a,b,c = x,5
449
+ a.should == x
450
+ b.should == 5
451
+ c.should == nil
452
+
453
+ a,b,c = 5,x
454
+ a.should == 5
455
+ b.should == x
456
+ c.should == nil
457
+
458
+ a,b,*c = x,5
459
+ a.should == x
460
+ b.should == 5
461
+ c.should == []
462
+
463
+ # a,(b,c) = 5,x
464
+ a.should == 5
465
+ b.should == 1
466
+ c.should == 2
467
+
468
+ # a,(b,*c) = 5,x
469
+ a.should == 5
470
+ b.should == 1
471
+ c.should == [2,3,4]
472
+
473
+ # a,(b,(*c)) = 5,x
474
+ a.should == 5
475
+ b.should == 1
476
+ c.should == [2]
477
+
478
+ # a,(b,(*c),(*d)) = 5,x
479
+ a.should == 5
480
+ b.should == 1
481
+ c.should == [2]
482
+ d.should == [3]
483
+
484
+ # a,(b,(*c),(d,*e)) = 5,x
485
+ a.should == 5
486
+ b.should == 1
487
+ c.should == [2]
488
+ d.should == 3
489
+ e.should == []
490
+ end
491
+ end
492
+
493
+ ruby_version_is "1.9" do
494
+ pending "calls #to_ary on RHS arg if the corresponding LHS var is a splat" do
495
+ x = VariablesSpecs::ParAsgn.new
496
+
497
+ # a,(*b),c = 5,x
498
+ a.should == 5
499
+ b.should == x.to_ary
500
+ c.should == nil
501
+ end
502
+ end
503
+
504
+ ruby_version_is ""..."1.9" do
505
+ it "doen't call #to_ary on RHS arg when the corresponding LHS var is a splat" do
506
+ x = VariablesSpecs::ParAsgn.new
507
+
508
+ # a,(*b),c = 5,x
509
+ a.should == 5
510
+ b.should == [x]
511
+ c.should == nil
512
+ end
513
+ end
514
+
515
+ pending "allows complex parallel assignment" do
516
+ # a, (b, c), d = 1, [2, 3], 4
517
+ a.should == 1
518
+ b.should == 2
519
+ c.should == 3
520
+ d.should == 4
521
+
522
+ # x, (y, z) = 1, 2, 3
523
+ [x,y,z].should == [1,2,nil]
524
+ # x, (y, z) = 1, [2,3]
525
+ [x,y,z].should == [1,2,3]
526
+ # x, (y, z) = 1, [2]
527
+ [x,y,z].should == [1,2,nil]
528
+
529
+ # a,(b,c,*d),(e,f),*g = 0,[1,2,3,4],[5,6],7,8
530
+ a.should == 0
531
+ b.should == 1
532
+ c.should == 2
533
+ d.should == [3,4]
534
+ e.should == 5
535
+ f.should == 6
536
+ g.should == [7,8]
537
+
538
+ x = VariablesSpecs::ParAsgn.new
539
+ # a,(b,c,*d),(e,f),*g = 0,x,[5,6],7,8
540
+ a.should == 0
541
+ b.should == 1
542
+ c.should == 2
543
+ d.should == [3,4]
544
+ e.should == 5
545
+ f.should == 6
546
+ g.should == [7,8]
547
+ end
548
+
549
+ pending "allows a lhs arg to be used in another lhs args parallel assignment" do
550
+ c = [4,5,6]
551
+ a,b,c[a] = 1,2,3
552
+ a.should == 1
553
+ b.should == 2
554
+ c.should == [4,3,6]
555
+
556
+ c[a],b,a = 7,8,9
557
+ a.should == 9
558
+ b.should == 8
559
+ c.should == [4,7,6]
560
+ end
561
+ end
562
+
563
+ describe "Conditional assignment" do
564
+ it "assigns the lhs if previously unassigned" do
565
+ a=[]
566
+ a[0] ||= "bar"
567
+ a[0].should == "bar"
568
+
569
+ h={}
570
+ h["foo"] ||= "bar"
571
+ h["foo"].should == "bar"
572
+
573
+ h["foo".to_sym] ||= "bar"
574
+ h["foo".to_sym].should == "bar"
575
+
576
+ aa = 5
577
+ aa ||= 25
578
+ aa.should == 5
579
+
580
+ bb ||= 25
581
+ bb.should == 25
582
+
583
+ cc &&=33
584
+ cc.should == nil
585
+
586
+ cc = 5
587
+ cc &&=44
588
+ cc.should == 44
589
+ end
590
+
591
+ it "checks for class variable definition before fetching its value" do
592
+ class VariableSpecCVarSpec
593
+ @@cvarspec ||= 5
594
+ @@cvarspec.should == 5
595
+ end
596
+ end
597
+ end
598
+
599
+ describe "Unconditional operator assignment 'var op= expr'" do
600
+ it "is equivalent to 'var = var op expr'" do
601
+ x = 13
602
+ (x += 5).should == 18
603
+ x.should == 18
604
+
605
+ x = 17
606
+ (x -= 11).should == 6
607
+ x.should == 6
608
+
609
+ x = 2
610
+ (x *= 5).should == 10
611
+ x.should == 10
612
+
613
+ x = 36
614
+ (x /= 9).should == 4
615
+ x.should == 4
616
+
617
+ x = 23
618
+ (x %= 5).should == 3
619
+ x.should == 3
620
+ (x %= 3).should == 0
621
+ x.should == 0
622
+
623
+ x = 2
624
+ (x **= 3).should == 8
625
+ x.should == 8
626
+
627
+ x = 4
628
+ (x |= 3).should == 7
629
+ x.should == 7
630
+ (x |= 4).should == 7
631
+ x.should == 7
632
+
633
+ x = 6
634
+ (x &= 3).should == 2
635
+ x.should == 2
636
+ (x &= 4).should == 0
637
+ x.should == 0
638
+
639
+ # XOR
640
+ x = 2
641
+ (x ^= 3).should == 1
642
+ x.should == 1
643
+ (x ^= 4).should == 5
644
+ x.should == 5
645
+
646
+ # Bit-shift left
647
+ x = 17
648
+ (x <<= 3).should == 136
649
+ x.should == 136
650
+
651
+ # Bit-shift right
652
+ x = 5
653
+ (x >>= 1).should == 2
654
+ x.should == 2
655
+ end
656
+ end
657
+
658
+ describe "Conditional operator assignment 'var op= expr'" do
659
+ it "assigns the lhs if its truthiness is false for ||, true for &&" do
660
+ x = nil
661
+ (x ||= 17).should == 17
662
+ x.should == 17
663
+ (x ||= 2).should == 17
664
+ x.should == 17
665
+
666
+ x = false
667
+ (x &&= true).should == false
668
+ x.should == false
669
+ (x &&= false).should == false
670
+ x.should == false
671
+ x = true
672
+ (x &&= true).should == true
673
+ x.should == true
674
+ (x &&= false).should == false
675
+ x.should == false
676
+ end
677
+
678
+ pending "may not assign at all, depending on the truthiness of lhs" do
679
+ Object.new.instance_eval do
680
+ @falsey = false
681
+ @truthy = true
682
+ freeze
683
+ # lambda{ @truthy ||= 42 }.should_not raise_error
684
+ # lambda{ @falsey &&= 42 }.should_not raise_error
685
+ end
686
+ end
687
+
688
+ pending "uses short-circuit arg evaluation" do
689
+ x = 8
690
+ y = VariablesSpecs::OpAsgn.new
691
+ (x ||= y.do_side_effect).should == 8
692
+ y.side_effect.should == nil
693
+
694
+ x = nil
695
+ (x &&= y.do_side_effect).should == nil
696
+ y.side_effect.should == nil
697
+
698
+ y.a = 5
699
+ (x ||= y.do_side_effect).should == 5
700
+ y.side_effect.should == true
701
+ end
702
+ end
703
+
704
+ describe "Unconditional operator assignment 'obj.meth op= expr'" do
705
+ it "is equivalent to 'obj.meth = obj.meth op expr'" do
706
+ @x = VariablesSpecs::OpAsgn.new
707
+ @x.a = 13
708
+ (@x.a += 5).should == 18
709
+ @x.a.should == 18
710
+
711
+ @x.a = 17
712
+ (@x.a -= 11).should == 6
713
+ @x.a.should == 6
714
+
715
+ @x.a = 2
716
+ (@x.a *= 5).should == 10
717
+ @x.a.should == 10
718
+
719
+ @x.a = 36
720
+ (@x.a /= 9).should == 4
721
+ @x.a.should == 4
722
+
723
+ @x.a = 23
724
+ (@x.a %= 5).should == 3
725
+ @x.a.should == 3
726
+ (@x.a %= 3).should == 0
727
+ @x.a.should == 0
728
+
729
+ @x.a = 2
730
+ (@x.a **= 3).should == 8
731
+ @x.a.should == 8
732
+
733
+ @x.a = 4
734
+ (@x.a |= 3).should == 7
735
+ @x.a.should == 7
736
+ (@x.a |= 4).should == 7
737
+ @x.a.should == 7
738
+
739
+ @x.a = 6
740
+ (@x.a &= 3).should == 2
741
+ @x.a.should == 2
742
+ (@x.a &= 4).should == 0
743
+ @x.a.should == 0
744
+
745
+ # XOR
746
+ @x.a = 2
747
+ (@x.a ^= 3).should == 1
748
+ @x.a.should == 1
749
+ (@x.a ^= 4).should == 5
750
+ @x.a.should == 5
751
+
752
+ @x.a = 17
753
+ (@x.a <<= 3).should == 136
754
+ @x.a.should == 136
755
+
756
+ @x.a = 5
757
+ (@x.a >>= 1).should == 2
758
+ @x.a.should == 2
759
+ end
760
+ end
761
+
762
+ describe "Conditional operator assignment 'obj.meth op= expr'" do
763
+ it "is equivalent to 'obj.meth op obj.meth = expr'" do
764
+ @x = VariablesSpecs::OpAsgn.new
765
+ @x.a = nil
766
+ (@x.a ||= 17).should == 17
767
+ @x.a.should == 17
768
+ (@x.a ||= 2).should == 17
769
+ @x.a.should == 17
770
+
771
+ @x.a = false
772
+ (@x.a &&= true).should == false
773
+ @x.a.should == false
774
+ (@x.a &&= false).should == false
775
+ @x.a.should == false
776
+ @x.a = true
777
+ (@x.a &&= true).should == true
778
+ @x.a.should == true
779
+ (@x.a &&= false).should == false
780
+ @x.a.should == false
781
+ end
782
+
783
+ pending "may not assign at all, depending on the truthiness of lhs" do
784
+ m = mock("object")
785
+ m.should_receive(:foo).and_return(:truthy)
786
+ m.should_not_receive(:foo=)
787
+ # m.foo ||= 42
788
+
789
+ m.should_receive(:bar).and_return(false)
790
+ m.should_not_receive(:bar=)
791
+ # m.bar &&= 42
792
+ end
793
+
794
+ pending "uses short-circuit arg evaluation" do
795
+ x = 8
796
+ y = VariablesSpecs::OpAsgn.new
797
+ (x ||= y.do_side_effect).should == 8
798
+ y.side_effect.should == nil
799
+
800
+ x = nil
801
+ (x &&= y.do_side_effect).should == nil
802
+ y.side_effect.should == nil
803
+
804
+ y.a = 5
805
+ (x ||= y.do_side_effect).should == 5
806
+ y.side_effect.should == true
807
+ end
808
+ end
809
+
810
+ describe "Operator assignment 'obj.meth op= expr'" do
811
+ pending "evaluates lhs one time" do
812
+ x = VariablesSpecs::OpAsgn.new
813
+ x.a = 5
814
+ (x.do_more_side_effects.a += 5).should == 15
815
+ x.a.should == 15
816
+
817
+ x.a = 5
818
+ (x.do_more_side_effects.a -= 4).should == 6
819
+ x.a.should == 6
820
+
821
+ x.a = 2
822
+ (x.do_more_side_effects.a *= 5).should == 35
823
+ x.a.should == 35
824
+
825
+ x.a = 31
826
+ (x.do_more_side_effects.a /= 9).should == 4
827
+ x.a.should == 4
828
+
829
+ x.a = 18
830
+ (x.do_more_side_effects.a %= 5).should == 3
831
+ x.a.should == 3
832
+
833
+ x.a = 0
834
+ (x.do_more_side_effects.a **= 3).should == 125
835
+ x.a.should == 125
836
+
837
+ x.a = -1
838
+ (x.do_more_side_effects.a |= 3).should == 7
839
+ x.a.should == 7
840
+
841
+ x.a = 1
842
+ (x.do_more_side_effects.a &= 3).should == 2
843
+ x.a.should == 2
844
+
845
+ # XOR
846
+ x.a = -3
847
+ (x.do_more_side_effects.a ^= 3).should == 1
848
+ x.a.should == 1
849
+
850
+ x.a = 12
851
+ (x.do_more_side_effects.a <<= 3).should == 136
852
+ x.a.should == 136
853
+
854
+ x.a = 0
855
+ (x.do_more_side_effects.a >>= 1).should == 2
856
+ x.a.should == 2
857
+
858
+ x.a = nil
859
+ x.b = 0
860
+ # (x.do_bool_side_effects.a ||= 17).should == 17
861
+ # x.a.should == 17
862
+ # x.b.should == 1
863
+
864
+ x.a = false
865
+ x.b = 0
866
+ # # (x.do_bool_side_effects.a &&= true).should == false
867
+ # x.a.should == false
868
+ # x.b.should == 1
869
+ # (x.do_bool_side_effects.a &&= false).should == false
870
+ # x.a.should == false
871
+ # x.b.should == 2
872
+ # x.a = true
873
+ # x.b = 0
874
+ # (x.do_bool_side_effects.a &&= true).should == true
875
+ # x.a.should == true
876
+ # x.b.should == 1
877
+ # (x.do_bool_side_effects.a &&= false).should == false
878
+ # x.a.should == false
879
+ # x.b.should == 2
880
+ end
881
+ end
882
+
883
+ describe "Unconditional operator assignment 'obj[idx] op= expr'" do
884
+ pending "is equivalent to 'obj[idx] = obj[idx] op expr'" do
885
+ # x = [2,13,7]
886
+ # (x[1] += 5).should == 18
887
+ # x.should == [2,18,7]
888
+
889
+ # x = [17,6]
890
+ # (x[0] -= 11).should == 6
891
+ # x.should == [6,6]
892
+
893
+ # x = [nil,2,28]
894
+ # (x[2] *= 2).should == 56
895
+ # x.should == [nil,2,56]
896
+
897
+ # x = [3,9,36]
898
+ # (x[2] /= x[1]).should == 4
899
+ # x.should == [3,9,4]
900
+
901
+ # x = [23,4]
902
+ # (x[0] %= 5).should == 3
903
+ # x.should == [3,4]
904
+ # (x[0] %= 3).should == 0
905
+ # x.should == [0,4]
906
+
907
+ # x = [1,2,3]
908
+ # (x[1] **= 3).should == 8
909
+ # x.should == [1,8,3]
910
+
911
+ # x = [4,5,nil]
912
+ # (x[0] |= 3).should == 7
913
+ # x.should == [7,5,nil]
914
+ # (x[0] |= 4).should == 7
915
+ # x.should == [7,5,nil]
916
+
917
+ # x = [3,6,9]
918
+ # (x[1] &= 3).should == 2
919
+ # x.should == [3,2,9]
920
+ # (x[1] &= 4).should == 0
921
+ # x.should == [3,0,9]
922
+
923
+ # # XOR
924
+ # x = [0,1,2]
925
+ # (x[2] ^= 3).should == 1
926
+ # x.should == [0,1,1]
927
+ # (x[2] ^= 4).should == 5
928
+ # x.should == [0,1,5]
929
+
930
+ # x = [17]
931
+ # (x[0] <<= 3).should == 136
932
+ # x.should == [136]
933
+
934
+ # x = [nil,5,8]
935
+ # (x[1] >>= 1).should == 2
936
+ # x.should == [nil,2,8]
937
+ end
938
+ end
939
+
940
+ describe "Conditional operator assignment 'obj[idx] op= expr'" do
941
+ pending "is equivalent to 'obj[idx] op obj[idx] = expr'" do
942
+ # x = [1,nil,12]
943
+ # (x[1] ||= 17).should == 17
944
+ # x.should == [1,17,12]
945
+ # (x[1] ||= 2).should == 17
946
+ # x.should == [1,17,12]
947
+
948
+ # x = [true, false, false]
949
+ # (x[1] &&= true).should == false
950
+ # x.should == [true, false, false]
951
+ # (x[1] &&= false).should == false
952
+ # x.should == [true, false, false]
953
+ # (x[0] &&= true).should == true
954
+ # x.should == [true, false, false]
955
+ # (x[0] &&= false).should == false
956
+ # x.should == [false, false, false]
957
+ end
958
+
959
+ pending "may not assign at all, depending on the truthiness of lhs" do
960
+ # m = mock("object")
961
+ # m.should_receive(:[]).and_return(:truthy)
962
+ # m.should_not_receive(:[]=)
963
+ # m[:foo] ||= 42
964
+
965
+ # m = mock("object")
966
+ # m.should_receive(:[]).and_return(false)
967
+ # m.should_not_receive(:[]=)
968
+ # m[:bar] &&= 42
969
+ end
970
+
971
+ pending "uses short-circuit arg evaluation" do
972
+ # x = 8
973
+ # y = VariablesSpecs::OpAsgn.new
974
+ # (x ||= y.do_side_effect).should == 8
975
+ # y.side_effect.should == nil
976
+
977
+ # x = nil
978
+ # (x &&= y.do_side_effect).should == nil
979
+ # y.side_effect.should == nil
980
+
981
+ # y.a = 5
982
+ # (x ||= y.do_side_effect).should == 5
983
+ # y.side_effect.should == true
984
+ end
985
+ end
986
+
987
+ describe "Operator assignment 'obj[idx] op= expr'" do
988
+ class ArrayWithDefaultIndex < Array
989
+ def [](index=nil)
990
+ super(index || 0)
991
+ end
992
+
993
+ def []=(first_arg, second_arg=nil)
994
+ if second_arg
995
+ index = fist_arg
996
+ value = second_arg
997
+ else
998
+ index = 0
999
+ value = first_arg
1000
+ end
1001
+
1002
+ super(index, value)
1003
+ end
1004
+ end
1005
+
1006
+ pending "handles empty index (idx) arguments" do
1007
+ # array = ArrayWithDefaultIndex.new
1008
+ # array << 1
1009
+ # (array[] += 5).should == 6
1010
+ end
1011
+
1012
+ pending "handles complex index (idx) arguments" do
1013
+ # x = [1,2,3,4]
1014
+ # (x[0,2] += [5]).should == [1,2,5]
1015
+ # x.should == [1,2,5,3,4]
1016
+ # (x[0,2] += [3,4]).should == [1,2,3,4]
1017
+ # x.should == [1,2,3,4,5,3,4]
1018
+
1019
+ # (x[2..3] += [8]).should == [3,4,8]
1020
+ # x.should == [1,2,3,4,8,5,3,4]
1021
+
1022
+ # y = VariablesSpecs::OpAsgn.new
1023
+ # y.a = 1
1024
+ # (x[y.do_side_effect] *= 2).should == 4
1025
+ # x.should == [1,4,3,4,8,5,3,4]
1026
+
1027
+ # h = {'key1' => 23, 'key2' => 'val'}
1028
+ # (h['key1'] %= 5).should == 3
1029
+ # (h['key2'] += 'ue').should == 'value'
1030
+ # h.should == {'key1' => 3, 'key2' => 'value'}
1031
+ end
1032
+
1033
+ pending "handles empty splat index (idx) arguments" do
1034
+ # array = ArrayWithDefaultIndex.new
1035
+ # array << 5
1036
+ # splat_index = []
1037
+
1038
+ # (array[*splat_index] += 5).should == 10
1039
+ # array.should== [10]
1040
+ end
1041
+
1042
+ pending "handles single splat index (idx) arguments" do
1043
+ # array = [1,2,3,4]
1044
+ # splat_index = [0]
1045
+
1046
+ # (array[*splat_index] += 5).should == 6
1047
+ # array.should == [6,2,3,4]
1048
+ end
1049
+
1050
+ pending "handles multiple splat index (idx) arguments" do
1051
+ # array = [1,2,3,4]
1052
+ # splat_index = [0,2]
1053
+
1054
+ # (array[*splat_index] += [5]).should == [1,2,5]
1055
+ # array.should == [1,2,5,3,4]
1056
+ end
1057
+
1058
+ pending "handles splat index (idx) arguments with normal arguments" do
1059
+ # array = [1,2,3,4]
1060
+ # splat_index = [2]
1061
+
1062
+ # (array[0, *splat_index] += [5]).should == [1,2,5]
1063
+ # array.should == [1,2,5,3,4]
1064
+ end
1065
+
1066
+ # This example fails on 1.9 because of bug #2050
1067
+ pending "returns result of rhs not result of []=" do
1068
+ # a = VariablesSpecs::Hashalike.new
1069
+
1070
+ # (a[123] = 2).should == 2
1071
+ # (a[123] += 2).should == 125
1072
+ # (a[123] -= 2).should == 121
1073
+ # (a[123] *= 2).should == 246
1074
+ # # Guard against the Mathn library
1075
+ # # TODO: Make these specs not rely on specific behaviour / result values
1076
+ # # by using mocks.
1077
+ # conflicts_with :Prime do
1078
+ # (a[123] /= 2).should == 61
1079
+ # end
1080
+ # (a[123] %= 2).should == 1
1081
+ # (a[123] **= 2).should == 15129
1082
+ # (a[123] |= 2).should == 123
1083
+ # (a[123] &= 2).should == 2
1084
+ # (a[123] ^= 2).should == 121
1085
+ # (a[123] <<= 2).should == 492
1086
+ # (a[123] >>= 2).should == 30
1087
+ # (a[123] ||= 2).should == 123
1088
+ # (a[nil] ||= 2).should == 2
1089
+ # (a[123] &&= 2).should == 2
1090
+ # (a[nil] &&= 2).should == nil
1091
+ end
131
1092
  end
132
1093
 
133
1094
  describe "Single assignment" do
@@ -147,7 +1108,7 @@ describe "Single assignment" do
147
1108
  end
148
1109
 
149
1110
  it "If rhs has multiple arguments, lhs becomes an Array of them" do
150
- a = [1, 2, 3]
1111
+ a = 1, 2, 3
151
1112
  a.should == [1, 2, 3]
152
1113
 
153
1114
  a = 1, (), 3
@@ -176,4 +1137,239 @@ describe "Multiple assignment without grouping or splatting" do
176
1137
  a.should == 1
177
1138
  b.should == 2
178
1139
  end
179
- end
1140
+
1141
+ it "The assignments are done in parallel so that lhs and rhs are independent of eachother without copying" do
1142
+ o_of_a, o_of_b = mock('a'), mock('b')
1143
+ a, b = o_of_a, o_of_b
1144
+ a, b = b, a
1145
+ a.should equal(o_of_b)
1146
+ b.should equal(o_of_a)
1147
+ end
1148
+ end
1149
+
1150
+ describe "Multiple assignments with splats" do
1151
+ ruby_version_is ""..."1.9" do
1152
+ it "* on the lhs has to be applied to the last parameter" do
1153
+ lambda { eval 'a, *b, c = 1, 2, 3' }.should raise_error(SyntaxError)
1154
+ end
1155
+ end
1156
+
1157
+ it "* on the lhs collects all parameters from its position onwards as an Array or an empty Array" do
1158
+ a, *b = 1, 2
1159
+ c, *d = 1
1160
+ e, *f = 1, 2, 3
1161
+ g, *h = 1, [2, 3]
1162
+ *i = 1, [2,3]
1163
+ *k = 1,2,3
1164
+
1165
+ a.should == 1
1166
+ b.should == [2]
1167
+ c.should == 1
1168
+ d.should == []
1169
+ e.should == 1
1170
+ f.should == [2, 3]
1171
+ g.should == 1
1172
+ h.should == [[2, 3]]
1173
+ i.should == [1, [2, 3]]
1174
+ k.should == [1,2,3]
1175
+ end
1176
+
1177
+ ruby_version_is ""..."1.9" do
1178
+ it "* on the LHS returns the Array on the RHS enclosed in an Array" do
1179
+ *j = [1,2,3]
1180
+ j.should == [[1,2,3]]
1181
+ end
1182
+ end
1183
+
1184
+ ruby_version_is "1.9" do
1185
+ it "* on the LHS returns the Array on the RHS without enclosing it in an Array" do
1186
+ *j = [1,2,3]
1187
+ j.should == [1,2,3]
1188
+ end
1189
+ end
1190
+ end
1191
+
1192
+ describe "Multiple assignments with grouping" do
1193
+ pending "A group on the lhs is considered one position and treats its corresponding rhs position like an Array" do
1194
+ # a, (b, c), d = 1, 2, 3, 4
1195
+ # e, (f, g), h = 1, [2, 3, 4], 5
1196
+ # i, (j, k), l = 1, 2, 3
1197
+ a.should == 1
1198
+ b.should == 2
1199
+ c.should == nil
1200
+ d.should == 3
1201
+ e.should == 1
1202
+ f.should == 2
1203
+ g.should == 3
1204
+ h.should == 5
1205
+ i.should == 1
1206
+ j.should == 2
1207
+ k.should == nil
1208
+ l.should == 3
1209
+ end
1210
+
1211
+ pending "supports multiple levels of nested groupings" do
1212
+ # a,(b,(c,d)) = 1,[2,[3,4]]
1213
+ a.should == 1
1214
+ b.should == 2
1215
+ c.should == 3
1216
+ d.should == 4
1217
+
1218
+ # a,(b,(c,d)) = [1,[2,[3,4]]]
1219
+ a.should == 1
1220
+ b.should == 2
1221
+ c.should == 3
1222
+ d.should == 4
1223
+
1224
+ x = [1,[2,[3,4]]]
1225
+ # a,(b,(c,d)) = x
1226
+ a.should == 1
1227
+ b.should == 2
1228
+ c.should == 3
1229
+ d.should == 4
1230
+ end
1231
+
1232
+ pending "rhs cannot use parameter grouping, it is a syntax error" do
1233
+ lambda { eval '(a, b) = (1, 2)' }.should raise_error(SyntaxError)
1234
+ end
1235
+ end
1236
+
1237
+ # TODO: merge the following two describe blocks and partition the specs
1238
+ # into distinct cases.
1239
+ describe "Multiple assignment" do
1240
+ pending do
1241
+ not_compliant_on :rubinius do
1242
+ it "has the proper return value" do
1243
+ # (a,b,*c = *[5,6,7,8,9,10]).should == [5,6,7,8,9,10]
1244
+ # (d,e = VariablesSpecs.reverse_foo(4,3)).should == [3,4]
1245
+ # (f,g,h = VariablesSpecs.reverse_foo(6,7)).should == [7,6]
1246
+ # (i,*j = *[5,6,7]).should == [5,6,7]
1247
+ # (k,*l = [5,6,7]).should == [5,6,7]
1248
+ a.should == 5
1249
+ b.should == 6
1250
+ c.should == [7,8,9,10]
1251
+ d.should == 3
1252
+ e.should == 4
1253
+ f.should == 7
1254
+ g.should == 6
1255
+ h.should == nil
1256
+ i.should == 5
1257
+ j.should == [6,7]
1258
+ k.should == 5
1259
+ l.should == [6,7]
1260
+ end
1261
+ end
1262
+ end
1263
+
1264
+ # TODO: write Rubinius versions
1265
+ end
1266
+
1267
+ # For now, masgn is deliberately non-compliant with MRI wrt the return val from an masgn.
1268
+ # Rubinius returns true as the result of the assignment, but MRI returns an array
1269
+ # containing all the elements on the rhs. As this result is never used, the cost
1270
+ # of creating and then discarding this array is avoided
1271
+ describe "Multiple assignment, array-style" do
1272
+ pending do
1273
+ not_compliant_on :rubinius do
1274
+ it "returns an array of all rhs values" do
1275
+ (a,b = 5,6,7).should == [5,6,7]
1276
+ a.should == 5
1277
+ b.should == 6
1278
+
1279
+ (c,d,*e = 99,8).should == [99,8]
1280
+ c.should == 99
1281
+ d.should == 8
1282
+ e.should == []
1283
+
1284
+ (f,g,h = 99,8).should == [99,8]
1285
+ f.should == 99
1286
+ g.should == 8
1287
+ h.should == nil
1288
+ end
1289
+ end
1290
+
1291
+ deviates_on :rubinius do
1292
+ it "returns true" do
1293
+ (a,b = 5,6,7).should == true
1294
+ a.should == 5
1295
+ b.should == 6
1296
+
1297
+ (c,d,*e = 99,8).should == true
1298
+ c.should == 99
1299
+ d.should == 8
1300
+ e.should == []
1301
+
1302
+ (f,g,h = 99,8).should == true
1303
+ f.should == 99
1304
+ g.should == 8
1305
+ h.should == nil
1306
+ end
1307
+ end
1308
+ end
1309
+ end
1310
+
1311
+ describe "Scope of variables" do
1312
+ pending "instance variables not overwritten by local variable in each block" do
1313
+
1314
+ class ScopeVariables
1315
+ attr_accessor :v
1316
+
1317
+ def initialize
1318
+ @v = ['a', 'b', 'c']
1319
+ end
1320
+
1321
+ def check_access
1322
+ v.should == ['a', 'b', 'c']
1323
+ self.v.should == ['a', 'b', 'c']
1324
+ end
1325
+
1326
+ def check_local_variable
1327
+ v = nil
1328
+ self.v.should == ['a', 'b', 'c']
1329
+ end
1330
+
1331
+ def check_each_block
1332
+ self.v.each { |v|
1333
+ # Don't actually do anything
1334
+ }
1335
+ self.v.should == ['a', 'b', 'c']
1336
+ v.should == ['a', 'b', 'c']
1337
+ self.v.object_id.should == v.object_id
1338
+ end
1339
+ end # Class ScopeVariables
1340
+
1341
+ instance = ScopeVariables.new()
1342
+ instance.check_access
1343
+ instance.check_local_variable
1344
+ instance.check_each_block
1345
+ end
1346
+ end
1347
+
1348
+ describe "A local variable in a #define_method scope" do
1349
+ pending do
1350
+ ruby_bug '#1322', '1.8.7.228' do
1351
+ it "shares the lexical scope containing the call to #define_method" do
1352
+ # We need a new scope to reproduce this bug.
1353
+ handle = mock("handle for containing scope method")
1354
+
1355
+ def handle.produce_bug
1356
+ local = 1
1357
+
1358
+ klass = Class.new
1359
+ klass.send :define_method, :set_local do |arg|
1360
+ lambda { local = 2 }.call
1361
+ end
1362
+
1363
+ # We must call with at least one argument to reproduce the bug.
1364
+ klass.new.set_local(nil)
1365
+
1366
+ local
1367
+ end
1368
+
1369
+ handle.produce_bug.should == 2
1370
+ end
1371
+ end
1372
+ end
1373
+ end
1374
+
1375
+ # # language_version __FILE__, "variables"