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
@@ -0,0 +1,55 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "The not keyword" do
4
+ it "negates a `true' value" do
5
+ (not true).should be_false
6
+ (not 'true').should be_false
7
+ end
8
+
9
+ it "negates a `false' value" do
10
+ (not false).should be_true
11
+ (not nil).should be_true
12
+ end
13
+
14
+ it "accepts an argument" do
15
+ lambda do
16
+ not(true)
17
+ end.should_not raise_error(SyntaxError)
18
+ end
19
+
20
+ it "returns false if the argument is true" do
21
+ (not(true)).should be_false
22
+ end
23
+
24
+ it "returns true if the argument is false" do
25
+ (not(false)).should be_true
26
+ end
27
+
28
+ it "returns true if the argument is nil" do
29
+ (not(nil)).should be_true
30
+ end
31
+ end
32
+
33
+ # language_version __FILE__, "not"
34
+
35
+ describe "The `!' keyword" do
36
+ it "negates a `true' value" do
37
+ (!true).should be_false
38
+ (!'true').should be_false
39
+ end
40
+
41
+ it "negates a `false' value" do
42
+ (!false).should be_true
43
+ (!nil).should be_true
44
+ end
45
+
46
+ it "turns a truthful object into `true'" do
47
+ (!!true).should be_true
48
+ (!!'true').should be_true
49
+ end
50
+
51
+ it "turns a not truthful object into `false'" do
52
+ (!!false).should be_false
53
+ (!!nil).should be_false
54
+ end
55
+ end
@@ -0,0 +1,56 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "Ruby numbers in various ways" do
4
+
5
+ it "the standard way" do
6
+ 435.should == 435
7
+ end
8
+
9
+ it "with underscore separations" do
10
+ 4_35.should == 435
11
+ end
12
+
13
+ it "with some decimals" do
14
+ 4.35.should == 4.35
15
+ end
16
+
17
+ it "with decimals but no integer part should be a SyntaxError" do
18
+ lambda { eval(".75") }.should raise_error(SyntaxError)
19
+ lambda { eval("-.75") }.should raise_error(SyntaxError)
20
+ end
21
+
22
+ # TODO : find a better description
23
+ it "using the e expression" do
24
+ 1.2e-3.should == 0.0012
25
+ end
26
+
27
+ pending "the hexdecimal notation" do
28
+ 0xffff.should == 65535
29
+ end
30
+
31
+ pending "the binary notation" do
32
+ # 0b01011.should == 11
33
+ end
34
+
35
+ pending "octal representation" do
36
+ 0377.should == 255
37
+ end
38
+
39
+ ruby_version_is '' ... '1.9' do
40
+ it "character to numeric shortcut" do
41
+ ?z.should == 122
42
+ end
43
+
44
+ it "character with control character to numeric shortcut" do
45
+ # Control-Z
46
+ #?\C-z.should == 26
47
+
48
+ # Meta-Z
49
+ #?\M-z.should == 250
50
+
51
+ # Meta-Control-Z
52
+ #?\M-\C-z.should == 154
53
+ end
54
+ end
55
+
56
+ end
@@ -1,3 +1,5 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
1
3
  describe "The || operator" do
2
4
  it "evaluates to true if any of its operands are true" do
3
5
  if false || true || nil
@@ -6,7 +8,7 @@ describe "The || operator" do
6
8
  x.should == true
7
9
  end
8
10
 
9
- it "evaluates to false if all of its operands are false" do
11
+ it "evaluated to false if all of its operands are false" do
10
12
  if false || nil
11
13
  x = true
12
14
  end
@@ -30,6 +32,19 @@ describe "The || operator" do
30
32
  (false || ()).should be_nil
31
33
  (() || ()).should be_nil
32
34
  end
35
+
36
+ it "has a higher precedence than 'break' in 'break true || false'" do
37
+ # see also 'break true or false' below
38
+ lambda { break false || true }.call.should be_true
39
+ end
40
+
41
+ it "has a higher precedence than 'next' in 'next true || false'" do
42
+ lambda { next false || true }.call.should be_true
43
+ end
44
+
45
+ it "has a higher precedence than 'return' in 'return true || false'" do
46
+ lambda { return false || true }.call.should be_true
47
+ end
33
48
  end
34
49
 
35
50
  describe "The or operator" do
@@ -47,7 +62,7 @@ describe "The or operator" do
47
62
  end
48
63
 
49
64
  it "has a lower precedence than the || operator" do
50
- x = y= nil
65
+ x,y = nil
51
66
  x = true || false or y = 1
52
67
  y.should == nil
53
68
  end
@@ -59,4 +74,17 @@ describe "The or operator" do
59
74
  (false or ()).should be_nil
60
75
  (() or ()).should be_nil
61
76
  end
62
- end
77
+
78
+ it "has a lower precedence than 'break' in 'break true or false'" do
79
+ # see also 'break true || false' above
80
+ lambda { eval "break true or false" }.should raise_error(SyntaxError, /void value expression/)
81
+ end
82
+
83
+ pending "has a lower precedence than 'next' in 'next true or false'" do
84
+ lambda { eval "next true or false" }.should raise_error(SyntaxError, /void value expression/)
85
+ end
86
+
87
+ it "has a lower precedence than 'return' in 'return true or false'" do
88
+ lambda { eval "return true or false" }.should raise_error(SyntaxError, /void value expression/)
89
+ end
90
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe "A method call" do
4
+ before :each do
5
+ @obj = Object.new
6
+ def @obj.foo0(&a)
7
+ [a ? a.call : nil]
8
+ end
9
+ def @obj.foo1(a, &b)
10
+ [a, b ? b.call : nil]
11
+ end
12
+ def @obj.foo2(a, b, &c)
13
+ [a, b, c ? c.call : nil]
14
+ end
15
+ def @obj.foo3(a, b, c, &d)
16
+ [a, b, c, d ? d.call : nil]
17
+ end
18
+ def @obj.foo4(a, b, c, d, &e)
19
+ [a, b, c, d, e ? e.call : nil]
20
+ end
21
+ end
22
+
23
+ it "evaluates the receiver first" do
24
+ (obj = @obj).foo1(obj = nil).should == [nil, nil]
25
+ (obj = @obj).foo2(obj = nil, obj = nil).should == [nil, nil, nil]
26
+ (obj = @obj).foo3(obj = nil, obj = nil, obj = nil).should == [nil, nil, nil, nil]
27
+ (obj = @obj).foo4(obj = nil, obj = nil, obj = nil, obj = nil).should == [nil, nil, nil, nil, nil]
28
+ end
29
+
30
+ pending "evaluates arguments after receiver" do
31
+ a = 0
32
+ # (a += 1; @obj).foo1(a).should == [1, nil]
33
+ # (a += 1; @obj).foo2(a, a).should == [2, 2, nil]
34
+ # (a += 1; @obj).foo3(a, a, a).should == [3, 3, 3, nil]
35
+ # (a += 1; @obj).foo4(a, a, a, a).should == [4, 4, 4, 4, nil]
36
+ a.should == 4
37
+ end
38
+
39
+ it "evaluates arguments left-to-right" do
40
+ a = 0
41
+ @obj.foo1(a += 1).should == [1, nil]
42
+ @obj.foo2(a += 1, a += 1).should == [2, 3, nil]
43
+ @obj.foo3(a += 1, a += 1, a += 1).should == [4, 5, 6, nil]
44
+ @obj.foo4(a += 1, a += 1, a += 1, a += 1).should == [7, 8, 9, 10, nil]
45
+ a.should == 10
46
+ end
47
+
48
+ pending do
49
+ ruby_bug "redmine #1034", "1.8" do
50
+ pending "evaluates block pass after arguments" do
51
+ a = 0
52
+ p = proc {true}
53
+ # @obj.foo1(a += 1, &(a += 1; p)).should == [1, true]
54
+ # @obj.foo2(a += 1, a += 1, &(a += 1; p)).should == [3, 4, true]
55
+ # @obj.foo3(a += 1, a += 1, a += 1, &(a += 1; p)).should == [6, 7, 8, true]
56
+ # @obj.foo4(a += 1, a += 1, a += 1, a += 1, &(a += 1; p)).should == [10, 11, 12, 13, true]
57
+ a.should == 14
58
+ end
59
+
60
+ pending "evaluates block pass after receiver" do
61
+ p1 = proc {true}
62
+ p2 = proc {false}
63
+ p1.should_not == p2
64
+
65
+ p = p1
66
+ # (p = p2; @obj).foo0(&p).should == [false]
67
+ p = p1
68
+ # (p = p2; @obj).foo1(1, &p).should == [1, false]
69
+ p = p1
70
+ # (p = p2; @obj).foo2(1, 1, &p).should == [1, 1, false]
71
+ p = p1
72
+ # (p = p2; @obj).foo3(1, 1, 1, &p).should == [1, 1, 1, false]
73
+ p = p1
74
+ # (p = p2; @obj).foo4(1, 1, 1, 1, &p).should == [1, 1, 1, 1, false]
75
+ p = p1
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,483 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ # Specifying the behavior of operators in combination could
4
+ # lead to combinatorial explosion. A better way seems to be
5
+ # to use a technique from formal proofs that involve a set of
6
+ # equivalent statements. Suppose you have statements A, B, C.
7
+ # If they are claimed to be equivalent, this can be shown by
8
+ # proving that A implies B, B implies C, and C implies A.
9
+ # (Actually any closed circuit of implications.)
10
+ #
11
+ # Here, we can use a similar technique where we show starting
12
+ # at the top that each level of operator has precedence over
13
+ # the level below (as well as showing associativity within
14
+ # the precedence level).
15
+
16
+
17
+ # Excerpted from 'Programming Ruby: The Pragmatic Programmer's Guide'
18
+ # Second Edition by Dave Thomas, Chad Fowler, and Andy Hunt, page 324
19
+
20
+ # Table 22.4. Ruby operators (high to low precedence)
21
+ # Method Operator Description
22
+ # -----------------------------------------------------------------------
23
+ # :: .
24
+ # x* [ ] [ ]= Element reference, element set
25
+ # x ** Exponentiation
26
+ # x ! ~ + - Not, complement, unary plus and minus
27
+ # (method names for the last two are +@ and -@)
28
+ # x * / % Multiply, divide, and modulo
29
+ # x + - Plus and minus
30
+ # x >> << Right and left shift
31
+ # x & “And” (bitwise for integers)
32
+ # x ^ | Exclusive “or” and regular “or” (bitwise for integers)
33
+ # x <= < > >= Comparison operators
34
+ # x <=> == === != =~ !~ Equality and pattern match operators (!=
35
+ # and !~ may not be defined as methods)
36
+ # && Logical “and”
37
+ # || Logical “or”
38
+ # .. ... Range (inclusive and exclusive)
39
+ # ? : Ternary if-then-else
40
+ # = %= /= -= += |= &= Assignment
41
+ # >>= <<= *= &&= ||= **=
42
+ # defined? Check if symbol defined
43
+ # not Logical negation
44
+ # or and Logical composition
45
+ # if unless while until Expression modifiers
46
+ # begin/end Block expression
47
+ # -----------------------------------------------------------------------
48
+
49
+ # * Operators marked with 'x' in the Method column are implemented as methods
50
+ # and can be overridden (except != and !~ as noted). (But see the specs
51
+ # below for implementations that define != and !~ as methods.)
52
+
53
+ # ** These are not included in the excerpted table but are shown here for
54
+ # completeness.
55
+
56
+
57
+ # -----------------------------------------------------------------------
58
+ # It seems that this table is not correct as of MRI 1.8.6
59
+ # The correct table derived from MRI's parse.y is as follows:
60
+ #
61
+ # Operator Assoc Description
62
+ #---------------------------------------------------------------
63
+ # ! ~ + > Not, complement, unary plus
64
+ # ** > Exponentiation
65
+ # - > Unary minus
66
+ # * / % < Multiply, divide, and modulo
67
+ # + - < Plus and minus
68
+ # >> << < Right and left shift
69
+ # & < “And” (bitwise for integers)
70
+ # ^ | < Exclusive “or” and regular “or” (bitwise for integers)
71
+ # <= < > >= < Comparison operators
72
+ # <=> == === != =~ !~ no Equality and pattern match operators (!=
73
+ # and !~ may not be defined as methods)
74
+ # && < Logical “and”
75
+ # || < Logical “or”
76
+ # .. ... no Range (inclusive and exclusive)
77
+ # ? : > Ternary if-then-else
78
+ # rescue < Rescue modifier
79
+ # = %= /= -= += |= &= > Assignment
80
+ # >>= <<= *= &&= ||= **=
81
+ # defined? no Check if symbol defined
82
+ # not > Logical negation
83
+ # or and < Logical composition
84
+ # if unless while until no Expression modifiers
85
+ # -----------------------------------------------------------------------
86
+ #
87
+ # [] and []= seem to fall out of here, as well as begin/end
88
+ #
89
+
90
+ # TODO: Resolve these two tables with actual specs. As the comment at the
91
+ # top suggests, these specs need to be reorganized into a single describe
92
+ # block for each operator. The describe block should include an example
93
+ # for associativity (if relevant), an example for any short circuit behavior
94
+ # (e.g. &&, ||, etc.) and an example block for each operator over which the
95
+ # instant operator has immediately higher precedence.
96
+
97
+ describe "Operators" do
98
+ it "! ~ + is right-associative" do
99
+ (!!true).should == true
100
+ (~~0).should == 0
101
+ (++2).should == 2
102
+ end
103
+
104
+ ruby_version_is "" ... "1.9" do
105
+ it "! ~ + have a higher precedence than **" do
106
+ class FalseClass; def **(a); 1000; end; end
107
+ (!0**2).should == 1000
108
+ class FalseClass; undef_method :**; end
109
+
110
+ class UnaryPlusTest; def +@; 50; end; end
111
+ a = UnaryPlusTest.new
112
+ (+a**2).should == 2500
113
+
114
+ (~0**2).should == 1
115
+ end
116
+ end
117
+
118
+ it "** is right-associative" do
119
+ (2**2**3).should == 256
120
+ end
121
+
122
+ it "** has higher precedence than unary minus" do
123
+ (-2**2).should == -4
124
+ end
125
+
126
+ it "unary minus is right-associative" do
127
+ (--2).should == 2
128
+ end
129
+
130
+ pending "unary minus has higher precedence than * / %" do
131
+ class UnaryMinusTest; def -@; 50; end; end
132
+ b = UnaryMinusTest.new
133
+
134
+ (-b * 5).should == 250
135
+ (-b / 5).should == 10
136
+ (-b % 7).should == 1
137
+ end
138
+
139
+ pending "* / % are left-associative" do
140
+ (2*1/2).should == (2*1)/2
141
+ # Guard against the Mathn library
142
+ # TODO: Make these specs not rely on specific behaviour / result values
143
+ # by using mocks.
144
+ conflicts_with :Prime do
145
+ (2*1/2).should_not == 2*(1/2)
146
+ end
147
+
148
+ (10/7/5).should == (10/7)/5
149
+ (10/7/5).should_not == 10/(7/5)
150
+
151
+ (101 % 55 % 7).should == (101 % 55) % 7
152
+ (101 % 55 % 7).should_not == 101 % (55 % 7)
153
+
154
+ (50*20/7%42).should == ((50*20)/7)%42
155
+ (50*20/7%42).should_not == 50*(20/(7%42))
156
+ end
157
+
158
+ it "* / % have higher precedence than + -" do
159
+ (2+2*2).should == 6
160
+ (1+10/5).should == 3
161
+ (2+10%5).should == 2
162
+
163
+ (2-2*2).should == -2
164
+ (1-10/5).should == -1
165
+ (10-10%4).should == 8
166
+ end
167
+
168
+ pending "+ - are left-associative" do
169
+ (2-3-4).should == -5
170
+ (4-3+2).should == 3
171
+
172
+ class BinaryPlusTest < String; alias_method :plus, :+; def +(a); plus(a) + "!"; end; end
173
+ s = BinaryPlusTest.new("a")
174
+
175
+ (s+s+s).should == (s+s)+s
176
+ (s+s+s).should_not == s+(s+s)
177
+ end
178
+
179
+ pending "+ - have higher precedence than >> <<" do
180
+ (2<<1+2).should == 16
181
+ (8>>1+2).should == 1
182
+ (4<<1-3).should == 1
183
+ (2>>1-3).should == 8
184
+ end
185
+
186
+ it ">> << are left-associative" do
187
+ (1 << 2 << 3).should == 32
188
+ (10 >> 1 >> 1).should == 2
189
+ (10 << 4 >> 1).should == 80
190
+ end
191
+
192
+ it ">> << have higher precedence than &" do
193
+ (4 & 2 << 1).should == 4
194
+ (2 & 4 >> 1).should == 2
195
+ end
196
+
197
+ pending "& is left-associative" do
198
+ class BitwiseAndTest; def &(a); a+1; end; end
199
+ c = BitwiseAndTest.new
200
+
201
+ (c & 5 & 2).should == (c & 5) & 2
202
+ (c & 5 & 2).should_not == c & (5 & 2)
203
+ end
204
+
205
+ it "& has higher precedence than ^ |" do
206
+ (8 ^ 16 & 16).should == 24
207
+ (8 | 16 & 16).should == 24
208
+ end
209
+
210
+ pending "^ | are left-associative" do
211
+ class OrAndXorTest; def ^(a); a+10; end; def |(a); a-10; end; end
212
+ d = OrAndXorTest.new
213
+
214
+ (d ^ 13 ^ 16).should == (d ^ 13) ^ 16
215
+ (d ^ 13 ^ 16).should_not == d ^ (13 ^ 16)
216
+
217
+ (d | 13 | 4).should == (d | 13) | 4
218
+ (d | 13 | 4).should_not == d | (13 | 4)
219
+ end
220
+
221
+ it "^ | have higher precedence than <= < > >=" do
222
+ (10 <= 7 ^ 7).should == false
223
+ (10 < 7 ^ 7).should == false
224
+ (10 > 7 ^ 7).should == true
225
+ (10 >= 7 ^ 7).should == true
226
+ (10 <= 7 | 7).should == false
227
+ (10 < 7 | 7).should == false
228
+ (10 > 7 | 7).should == true
229
+ (10 >= 7 | 7).should == true
230
+ end
231
+
232
+ pending "<= < > >= are left-associative" do
233
+ class ComparisonTest
234
+ def <=(a); 0; end;
235
+ def <(a); 0; end;
236
+ def >(a); 0; end;
237
+ def >=(a); 0; end;
238
+ end
239
+
240
+ e = ComparisonTest.new
241
+
242
+ (e <= 0 <= 1).should == (e <= 0) <= 1
243
+ (e <= 0 <= 1).should_not == e <= (0 <= 1)
244
+
245
+ (e < 0 < 1).should == (e < 0) < 1
246
+ (e < 0 < 1).should_not == e < (0 < 1)
247
+
248
+ (e >= 0 >= 1).should == (e >= 0) >= 1
249
+ (e >= 0 >= 1).should_not == e >= (0 >= 1)
250
+
251
+ (e > 0 > 1).should == (e > 0) > 1
252
+ (e > 0 > 1).should_not == e > (0 > 1)
253
+ end
254
+
255
+ ruby_version_is "" ... "1.9" do
256
+ it "<= < > >= have higher precedence than <=> == === != =~ !~" do
257
+ (1 <=> 5 < 1).should == nil
258
+ (1 <=> 5 <= 1).should == nil
259
+ (1 <=> 5 > 1).should == nil
260
+ (1 <=> 5 >= 1).should == nil
261
+
262
+ (1 == 5 < 1).should == false
263
+ (1 == 5 <= 1).should == false
264
+ (1 == 5 > 1).should == false
265
+ (1 == 5 >= 1).should == false
266
+
267
+ (1 === 5 < 1).should == false
268
+ (1 === 5 <= 1).should == false
269
+ (1 === 5 > 1).should == false
270
+ (1 === 5 >= 1).should == false
271
+
272
+ (1 != 5 < 1).should == true
273
+ (1 != 5 <= 1).should == true
274
+ (1 != 5 > 1).should == true
275
+ (1 != 5 >= 1).should == true
276
+
277
+ (1 =~ 5 < 1).should == false
278
+ (1 =~ 5 <= 1).should == false
279
+ (1 =~ 5 > 1).should == false
280
+ (1 =~ 5 >= 1).should == false
281
+
282
+ (1 !~ 5 < 1).should == true
283
+ (1 !~ 5 <= 1).should == true
284
+ (1 !~ 5 > 1).should == true
285
+ (1 !~ 5 >= 1).should == true
286
+ end
287
+ end
288
+
289
+ it "<=> == === != =~ !~ are non-associative" do
290
+ lambda { eval("1 <=> 2 <=> 3") }.should raise_error(SyntaxError)
291
+ lambda { eval("1 == 2 == 3") }.should raise_error(SyntaxError)
292
+ lambda { eval("1 === 2 === 3") }.should raise_error(SyntaxError)
293
+ lambda { eval("1 != 2 != 3") }.should raise_error(SyntaxError)
294
+ lambda { eval("1 =~ 2 =~ 3") }.should raise_error(SyntaxError)
295
+ lambda { eval("1 !~ 2 !~ 3") }.should raise_error(SyntaxError)
296
+ end
297
+
298
+ pending "<=> == === != =~ !~ have higher precedence than &&" do
299
+ (false && 2 <=> 3).should == false
300
+ (false && 3 == false).should == false
301
+ (false && 3 === false).should == false
302
+ (false && 3 != true).should == false
303
+
304
+ class FalseClass; def =~(o); o == false; end; end
305
+ (false && true =~ false).should == (false && (true =~ false))
306
+ (false && true =~ false).should_not == ((false && true) =~ false)
307
+ class FalseClass; undef_method :=~; end
308
+
309
+ (false && true !~ true).should == false
310
+ end
311
+
312
+ # XXX: figure out how to test it
313
+ # (a && b) && c equals to a && (b && c) for all a,b,c values I can imagine so far
314
+ pending "&& is left-associative"
315
+
316
+ it "&& has higher precedence than ||" do
317
+ (true || false && false).should == true
318
+ end
319
+
320
+ # XXX: figure out how to test it
321
+ pending "|| is left-associative"
322
+
323
+ it "|| has higher precedence than .. ..." do
324
+ (1..false||10).should == (1..10)
325
+ (1...false||10).should == (1...10)
326
+ end
327
+
328
+ it ".. ... are non-associative" do
329
+ lambda { eval("1..2..3") }.should raise_error(SyntaxError)
330
+ lambda { eval("1...2...3") }.should raise_error(SyntaxError)
331
+ end
332
+
333
+ # XXX: this is commented now due to a bug in compiler, which cannot
334
+ # distinguish between range and flip-flop operator so far. zenspider is
335
+ # currently working on a new lexer, which will be able to do that.
336
+ # As soon as it's done, these piece should be reenabled.
337
+ #
338
+ # it ".. ... have higher precedence than ? :" do
339
+ # (1..2 ? 3 : 4).should == 3
340
+ # (1...2 ? 3 : 4).should == 3
341
+ # end
342
+
343
+ it "? : is right-associative" do
344
+ (true ? 2 : 3 ? 4 : 5).should == 2
345
+ end
346
+
347
+ def oops; raise end
348
+
349
+ pending "? : has higher precedence than rescue" do
350
+
351
+ (true ? oops : 0 rescue 10).should == 10
352
+ end
353
+
354
+ # XXX: figure how to test it (problem similar to || associativity)
355
+ pending "rescue is left-associative"
356
+
357
+ pending "rescue has higher precedence than =" do
358
+ # a = oops rescue 10
359
+ a.should == 10
360
+
361
+ # rescue doesn't have the same sense for %= /= and friends
362
+ end
363
+
364
+ pending "= %= /= -= += |= &= >>= <<= *= &&= ||= **= are right-associative" do
365
+ # a = b = 10
366
+ # a.should == 10
367
+ # b.should == 10
368
+
369
+ # a = b = 10
370
+ # a %= b %= 3
371
+ # a.should == 0
372
+ # b.should == 1
373
+
374
+ # a = b = 10
375
+ # a /= b /= 2
376
+ # a.should == 2
377
+ # b.should == 5
378
+
379
+ # a = b = 10
380
+ # a -= b -= 2
381
+ # a.should == 2
382
+ # b.should == 8
383
+
384
+ # a = b = 10
385
+ # a += b += 2
386
+ # a.should == 22
387
+ # b.should == 12
388
+
389
+ # a,b = 32,64
390
+ # a |= b |= 2
391
+ # a.should == 98
392
+ # b.should == 66
393
+
394
+ # a,b = 25,13
395
+ # a &= b &= 7
396
+ # a.should == 1
397
+ # b.should == 5
398
+
399
+ # a,b=8,2
400
+ # a >>= b >>= 1
401
+ # a.should == 4
402
+ # b.should == 1
403
+
404
+ # a,b=8,2
405
+ # a <<= b <<= 1
406
+ # a.should == 128
407
+ # b.should == 4
408
+
409
+ # a,b=8,2
410
+ # a *= b *= 2
411
+ # a.should == 32
412
+ # b.should == 4
413
+
414
+ # a,b=10,20
415
+ # a &&= b &&= false
416
+ # a.should == false
417
+ # b.should == false
418
+
419
+ # a,b=nil,nil
420
+ # a ||= b ||= 10
421
+ # a.should == 10
422
+ # b.should == 10
423
+
424
+ # a,b=2,3
425
+ # a **= b **= 2
426
+ # a.should == 512
427
+ # b.should == 9
428
+ end
429
+
430
+ pending "= %= /= -= += |= &= >>= <<= *= &&= ||= **= have higher precedence than defined? operator" do
431
+ # (defined? a = 10).should == "assignment"
432
+ # (defined? a %= 10).should == "assignment"
433
+ # (defined? a /= 10).should == "assignment"
434
+ # (defined? a -= 10).should == "assignment"
435
+ # (defined? a += 10).should == "assignment"
436
+ # (defined? a |= 10).should == "assignment"
437
+ # (defined? a &= 10).should == "assignment"
438
+ # (defined? a >>= 10).should == "assignment"
439
+ # (defined? a <<= 10).should == "assignment"
440
+ # (defined? a *= 10).should == "assignment"
441
+ # (defined? a &&= 10).should == "assignment"
442
+ # (defined? a ||= 10).should == "assignment"
443
+ # (defined? a **= 10).should == "assignment"
444
+ end
445
+
446
+ # XXX: figure out how to test it
447
+ pending "defined? is non-associative"
448
+
449
+ it "defined? has higher precedence than not" do
450
+ # does it have sense?
451
+ (not defined? qqq).should == true
452
+ end
453
+
454
+ it "not is right-associative" do
455
+ (not not false).should == false
456
+ (not not 10).should == true
457
+ end
458
+
459
+ it "not has higher precedence than or/and" do
460
+ (not false and false).should == false
461
+ (not false or true).should == true
462
+ end
463
+
464
+ # XXX: figure out how to test it
465
+ pending "or/and are left-associative"
466
+
467
+ pending "or/and have higher precedence than if unless while until modifiers" do
468
+ (1 if 2 and 3).should == 1
469
+ (1 if 2 or 3).should == 1
470
+
471
+ (1 unless false and true).should == 1
472
+ (1 unless false or false).should == 1
473
+
474
+ (1 while true and false).should == nil # would hang upon error
475
+ (1 while false or false).should == nil
476
+
477
+ ((raise until true and false) rescue 10).should == 10
478
+ (1 until false or true).should == nil # would hang upon error
479
+ end
480
+
481
+ # XXX: it seems to me they are right-associative
482
+ pending "if unless while until are non-associative"
483
+ end