opal 0.8.1 → 0.9.0.beta1

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 (331) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -2
  3. data/.gitmodules +3 -3
  4. data/.jshintrc +17 -20
  5. data/.travis.yml +22 -11
  6. data/CHANGELOG.md +51 -1
  7. data/CODE_OF_CONDUCT.md +15 -0
  8. data/CONTRIBUTING.md +125 -9
  9. data/Gemfile +1 -1
  10. data/Guardfile +2 -2
  11. data/README.md +95 -29
  12. data/Rakefile +1 -1
  13. data/benchmark/benchmarks +103 -0
  14. data/benchmark/bm_array_flatten.rb +9 -0
  15. data/benchmark/bm_array_intersection_numbers.rb +7 -0
  16. data/benchmark/bm_array_intersection_objects.rb +7 -0
  17. data/benchmark/bm_array_intersection_strings.rb +7 -0
  18. data/benchmark/bm_array_join_ary.rb +9 -0
  19. data/benchmark/bm_array_minus_numbers.rb +7 -0
  20. data/benchmark/bm_array_minus_objects.rb +7 -0
  21. data/benchmark/bm_array_minus_strings.rb +7 -0
  22. data/benchmark/bm_array_union_numbers.rb +7 -0
  23. data/benchmark/bm_array_union_objects.rb +7 -0
  24. data/benchmark/bm_array_union_strings.rb +7 -0
  25. data/benchmark/bm_array_uniq_bang_numbers.rb +5 -0
  26. data/benchmark/bm_array_uniq_bang_objects.rb +5 -0
  27. data/benchmark/bm_array_uniq_bang_strings.rb +5 -0
  28. data/benchmark/bm_array_uniq_numbers.rb +5 -0
  29. data/benchmark/bm_array_uniq_objects.rb +5 -0
  30. data/benchmark/bm_array_uniq_strings.rb +5 -0
  31. data/benchmark/bm_dispatch_bind_table.rb +57 -0
  32. data/benchmark/bm_dispatch_code_gen.rb +65 -0
  33. data/benchmark/bm_dispatch_code_gen_if.rb +64 -0
  34. data/benchmark/bm_dispatch_hardcoded.rb +44 -0
  35. data/benchmark/bm_dispatch_send.rb +38 -0
  36. data/benchmark/bm_dispatch_send_table.rb +57 -0
  37. data/benchmark/bm_hash_assoc_object.rb +11 -0
  38. data/benchmark/bm_hash_assoc_string.rb +9 -0
  39. data/benchmark/bm_hash_clone_object.rb +9 -0
  40. data/benchmark/bm_hash_clone_string.rb +9 -0
  41. data/benchmark/bm_hash_delete_object.rb +11 -0
  42. data/benchmark/bm_hash_delete_string.rb +9 -0
  43. data/benchmark/bm_hash_each_key_object.rb +9 -0
  44. data/benchmark/bm_hash_each_key_string.rb +9 -0
  45. data/benchmark/bm_hash_each_object.rb +9 -0
  46. data/benchmark/bm_hash_each_string.rb +9 -0
  47. data/benchmark/bm_hash_each_value_object.rb +9 -0
  48. data/benchmark/bm_hash_each_value_string.rb +9 -0
  49. data/benchmark/bm_hash_element_reference_object.rb +11 -0
  50. data/benchmark/bm_hash_element_reference_string.rb +9 -0
  51. data/benchmark/bm_hash_element_set_object.rb +5 -0
  52. data/benchmark/bm_hash_element_set_string.rb +5 -0
  53. data/benchmark/bm_hash_equal_value_object.rb +14 -0
  54. data/benchmark/bm_hash_equal_value_string.rb +11 -0
  55. data/benchmark/bm_hash_fetch_object.rb +11 -0
  56. data/benchmark/bm_hash_fetch_string.rb +9 -0
  57. data/benchmark/bm_hash_flatten_object.rb +9 -0
  58. data/benchmark/bm_hash_flatten_string.rb +9 -0
  59. data/benchmark/bm_hash_has_key_object.rb +11 -0
  60. data/benchmark/bm_hash_has_key_string.rb +9 -0
  61. data/benchmark/bm_hash_has_value_object.rb +9 -0
  62. data/benchmark/bm_hash_has_value_string.rb +9 -0
  63. data/benchmark/bm_hash_hash_object.rb +9 -0
  64. data/benchmark/bm_hash_hash_string.rb +9 -0
  65. data/benchmark/bm_hash_inspect_object.rb +9 -0
  66. data/benchmark/bm_hash_inspect_string.rb +9 -0
  67. data/benchmark/bm_hash_invert_object.rb +9 -0
  68. data/benchmark/bm_hash_invert_string.rb +9 -0
  69. data/benchmark/bm_hash_keep_if_object.rb +9 -0
  70. data/benchmark/bm_hash_keep_if_string.rb +9 -0
  71. data/benchmark/bm_hash_key_object.rb +9 -0
  72. data/benchmark/bm_hash_key_string.rb +9 -0
  73. data/benchmark/bm_hash_keys_object.rb +9 -0
  74. data/benchmark/bm_hash_keys_string.rb +9 -0
  75. data/benchmark/bm_hash_literal_mixed_large.rb +3 -0
  76. data/benchmark/bm_hash_literal_mixed_small.rb +3 -0
  77. data/benchmark/bm_hash_literal_object_large.rb +4 -0
  78. data/benchmark/bm_hash_literal_object_small.rb +3 -0
  79. data/benchmark/bm_hash_literal_string_large.rb +4 -0
  80. data/benchmark/bm_hash_literal_string_small.rb +3 -0
  81. data/benchmark/bm_hash_merge_object.rb +22 -0
  82. data/benchmark/bm_hash_merge_string.rb +18 -0
  83. data/benchmark/bm_hash_rassoc_object.rb +9 -0
  84. data/benchmark/bm_hash_rassoc_string.rb +9 -0
  85. data/benchmark/bm_hash_rehash_object.rb +9 -0
  86. data/benchmark/bm_hash_rehash_string.rb +9 -0
  87. data/benchmark/bm_hash_reject_bang_object.rb +9 -0
  88. data/benchmark/bm_hash_reject_bang_string.rb +9 -0
  89. data/benchmark/bm_hash_reject_object.rb +9 -0
  90. data/benchmark/bm_hash_reject_string.rb +9 -0
  91. data/benchmark/bm_hash_replace_object.rb +18 -0
  92. data/benchmark/bm_hash_replace_string.rb +14 -0
  93. data/benchmark/bm_hash_select_bang_object.rb +9 -0
  94. data/benchmark/bm_hash_select_bang_string.rb +9 -0
  95. data/benchmark/bm_hash_select_object.rb +9 -0
  96. data/benchmark/bm_hash_select_string.rb +9 -0
  97. data/benchmark/bm_hash_shift_object.rb +10 -0
  98. data/benchmark/bm_hash_shift_string.rb +10 -0
  99. data/benchmark/bm_hash_to_a_object.rb +9 -0
  100. data/benchmark/bm_hash_to_a_string.rb +9 -0
  101. data/benchmark/bm_hash_to_h_object.rb +10 -0
  102. data/benchmark/bm_hash_to_h_string.rb +10 -0
  103. data/benchmark/bm_hash_values_object.rb +9 -0
  104. data/benchmark/bm_hash_values_string.rb +9 -0
  105. data/benchmark/run.rb +48 -0
  106. data/bin/opal-mspec +1 -1
  107. data/bin/opal-repl +4 -4
  108. data/docs/compiled_ruby.md +214 -56
  109. data/docs/configuring_gems.md +2 -2
  110. data/docs/faq.md +2 -2
  111. data/docs/getting_started.md +19 -2
  112. data/docs/jquery.md +5 -5
  113. data/docs/opal_parser.md +53 -0
  114. data/docs/unsupported_features.md +2 -2
  115. data/docs/upgrading.md +22 -0
  116. data/docs/using_sprockets.md +15 -0
  117. data/examples/rack/config.ru +13 -0
  118. data/examples/sinatra/config.ru +4 -5
  119. data/lib/mspec/opal/runner.rb +54 -11
  120. data/lib/opal.rb +1 -1
  121. data/lib/opal/builder.rb +1 -1
  122. data/lib/opal/builder_processors.rb +1 -1
  123. data/lib/opal/cli.rb +17 -13
  124. data/lib/opal/cli_options.rb +1 -1
  125. data/lib/opal/compiler.rb +12 -0
  126. data/lib/opal/config.rb +4 -0
  127. data/lib/opal/nodes/arglist.rb +5 -7
  128. data/lib/opal/nodes/call.rb +6 -1
  129. data/lib/opal/nodes/call_special.rb +74 -0
  130. data/lib/opal/nodes/def.rb +35 -28
  131. data/lib/opal/nodes/definitions.rb +3 -5
  132. data/lib/opal/nodes/for.rb +13 -0
  133. data/lib/opal/nodes/helpers.rb +15 -1
  134. data/lib/opal/nodes/if.rb +5 -5
  135. data/lib/opal/nodes/iter.rb +6 -1
  136. data/lib/opal/nodes/literal.rb +1 -1
  137. data/lib/opal/nodes/logic.rb +2 -2
  138. data/lib/opal/nodes/masgn.rb +1 -2
  139. data/lib/opal/nodes/module.rb +2 -1
  140. data/lib/opal/nodes/rescue.rb +10 -1
  141. data/lib/opal/nodes/scope.rb +8 -2
  142. data/lib/opal/nodes/singleton_class.rb +1 -1
  143. data/lib/opal/nodes/top.rb +11 -0
  144. data/lib/opal/nodes/variables.rb +4 -4
  145. data/lib/opal/parser.rb +21 -3
  146. data/lib/opal/parser/grammar.rb +3115 -2961
  147. data/lib/opal/parser/grammar.y +29 -6
  148. data/lib/opal/parser/lexer.rb +18 -8
  149. data/lib/opal/sprockets.rb +85 -0
  150. data/lib/opal/sprockets/processor.rb +11 -35
  151. data/lib/opal/sprockets/server.rb +3 -15
  152. data/lib/opal/version.rb +2 -2
  153. data/opal.gemspec +4 -4
  154. data/opal/README.md +9 -0
  155. data/opal/corelib/array.rb +433 -181
  156. data/opal/corelib/basic_object.rb +48 -4
  157. data/opal/corelib/boolean.rb +15 -6
  158. data/opal/corelib/class.rb +6 -5
  159. data/opal/corelib/comparable.rb +12 -0
  160. data/opal/corelib/complex.rb +282 -0
  161. data/opal/corelib/constants.rb +9 -0
  162. data/opal/corelib/enumerable.rb +83 -34
  163. data/opal/corelib/enumerator.rb +3 -1
  164. data/opal/corelib/error.rb +49 -10
  165. data/opal/corelib/file.rb +1 -0
  166. data/opal/corelib/hash.rb +353 -577
  167. data/opal/corelib/helpers.rb +20 -0
  168. data/opal/corelib/kernel.rb +114 -59
  169. data/opal/corelib/math.rb +470 -0
  170. data/opal/corelib/method.rb +11 -2
  171. data/opal/corelib/module.rb +96 -96
  172. data/opal/corelib/{nil_class.rb → nil.rb} +20 -1
  173. data/opal/corelib/number.rb +751 -0
  174. data/opal/corelib/numeric.rb +77 -437
  175. data/opal/corelib/proc.rb +81 -1
  176. data/opal/corelib/process.rb +27 -0
  177. data/opal/corelib/rational.rb +358 -0
  178. data/opal/corelib/regexp.rb +156 -27
  179. data/opal/corelib/runtime.js +724 -335
  180. data/opal/corelib/string.rb +93 -104
  181. data/opal/corelib/string/encoding.rb +177 -0
  182. data/opal/corelib/string/inheritance.rb +2 -0
  183. data/opal/corelib/struct.rb +105 -18
  184. data/opal/corelib/time.rb +267 -146
  185. data/opal/corelib/unsupported.rb +216 -0
  186. data/opal/corelib/variables.rb +0 -6
  187. data/opal/opal.rb +8 -22
  188. data/opal/opal/base.rb +9 -0
  189. data/opal/opal/mini.rb +17 -0
  190. data/spec/README.md +1 -1
  191. data/spec/filters/bugs/array.rb +38 -136
  192. data/spec/filters/bugs/{basic_object.rb → basicobject.rb} +14 -15
  193. data/spec/filters/bugs/class.rb +6 -12
  194. data/spec/filters/bugs/complex.rb +3 -0
  195. data/spec/filters/bugs/date.rb +162 -10
  196. data/spec/filters/bugs/enumerable.rb +31 -58
  197. data/spec/filters/bugs/enumerator.rb +42 -0
  198. data/spec/filters/bugs/exception.rb +66 -10
  199. data/spec/filters/bugs/float.rb +17 -0
  200. data/spec/filters/bugs/hash.rb +11 -97
  201. data/spec/filters/bugs/inheritance.rb +5 -0
  202. data/spec/filters/bugs/integer.rb +28 -0
  203. data/spec/filters/bugs/kernel.rb +304 -12
  204. data/spec/filters/bugs/language.rb +133 -399
  205. data/spec/filters/bugs/language_opal.rb +88 -0
  206. data/spec/filters/bugs/module.rb +203 -62
  207. data/spec/filters/bugs/numeric.rb +32 -0
  208. data/spec/filters/bugs/proc.rb +39 -0
  209. data/spec/filters/bugs/range.rb +148 -0
  210. data/spec/filters/bugs/regexp.rb +168 -0
  211. data/spec/filters/bugs/set.rb +46 -3
  212. data/spec/filters/bugs/singleton.rb +1 -2
  213. data/spec/filters/bugs/string.rb +59 -90
  214. data/spec/filters/bugs/strscan.rb +80 -0
  215. data/spec/filters/bugs/struct.rb +10 -20
  216. data/spec/filters/bugs/time.rb +17 -184
  217. data/spec/filters/bugs/unboundmethod.rb +22 -0
  218. data/spec/filters/unsupported/array.rb +163 -0
  219. data/spec/filters/unsupported/basicobject.rb +14 -0
  220. data/spec/filters/unsupported/bignum.rb +46 -0
  221. data/spec/filters/unsupported/class.rb +4 -0
  222. data/spec/filters/unsupported/delegator.rb +5 -0
  223. data/spec/filters/unsupported/enumerable.rb +11 -0
  224. data/spec/filters/unsupported/enumerator.rb +8 -9
  225. data/spec/filters/unsupported/fixnum.rb +14 -0
  226. data/spec/filters/unsupported/float.rb +41 -7
  227. data/spec/filters/unsupported/freeze.rb +45 -0
  228. data/spec/filters/unsupported/hash.rb +50 -0
  229. data/spec/filters/unsupported/integer.rb +3 -0
  230. data/spec/filters/unsupported/kernel.rb +31 -0
  231. data/spec/filters/unsupported/language.rb +17 -0
  232. data/spec/filters/unsupported/matchdata.rb +30 -0
  233. data/spec/filters/unsupported/math.rb +3 -0
  234. data/spec/filters/unsupported/module.rb +5 -3
  235. data/spec/filters/unsupported/pathname.rb +3 -0
  236. data/spec/filters/unsupported/privacy.rb +136 -0
  237. data/spec/filters/unsupported/proc.rb +3 -0
  238. data/spec/filters/unsupported/regexp.rb +59 -0
  239. data/spec/filters/unsupported/set.rb +4 -0
  240. data/spec/filters/unsupported/{marshal.rb → singleton.rb} +4 -2
  241. data/spec/filters/unsupported/{mutable_strings.rb → string.rb} +456 -336
  242. data/spec/filters/unsupported/struct.rb +3 -0
  243. data/spec/filters/unsupported/symbol.rb +5 -0
  244. data/spec/filters/unsupported/taint.rb +16 -0
  245. data/spec/filters/unsupported/thread.rb +5 -0
  246. data/spec/filters/unsupported/time.rb +197 -16
  247. data/spec/lib/cli_spec.rb +14 -4
  248. data/spec/lib/compiler_spec.rb +9 -1
  249. data/spec/lib/parser/call_spec.rb +18 -0
  250. data/spec/lib/parser/not_spec.rb +2 -8
  251. data/spec/lib/sprockets_spec.rb +24 -0
  252. data/spec/opal/core/array/intersection_spec.rb +38 -0
  253. data/spec/opal/core/array/minus_spec.rb +38 -0
  254. data/spec/opal/core/array/union_spec.rb +38 -0
  255. data/spec/opal/core/array/uniq_spec.rb +49 -0
  256. data/spec/opal/core/exception_spec.rb +7 -0
  257. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  258. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  259. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  260. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  261. data/spec/opal/core/hash/internals_spec.rb +332 -0
  262. data/spec/opal/core/helpers_spec.rb +14 -0
  263. data/spec/opal/core/kernel/freeze_spec.rb +1 -1
  264. data/spec/opal/core/kernel/raise_spec.rb +13 -0
  265. data/spec/opal/core/kernel/require_tree_spec.rb +9 -0
  266. data/spec/opal/core/language/class_spec.rb +55 -0
  267. data/spec/opal/core/language/fixtures/send.rb +1 -0
  268. data/spec/opal/core/language/keyword_arguments_spec.rb +11 -0
  269. data/spec/opal/core/language/send_spec.rb +5 -0
  270. data/spec/opal/core/method/to_proc_spec.rb +28 -0
  271. data/spec/opal/core/module/name_spec.rb +0 -17
  272. data/spec/opal/core/runtime/bridged_classes_spec.rb +2 -2
  273. data/spec/opal/core/runtime/eval_spec.rb +1 -1
  274. data/spec/opal/core/runtime/method_missing_spec.rb +6 -0
  275. data/spec/opal/core/runtime_spec.rb +51 -0
  276. data/spec/opal/stdlib/js_spec.rb +66 -0
  277. data/spec/opal/stdlib/native/hash_spec.rb +36 -0
  278. data/spec/rubyspecs +152 -273
  279. data/spec/spec_helper.rb +10 -11
  280. data/stdlib/base64.rb +9 -9
  281. data/stdlib/benchmark.rb +551 -4
  282. data/stdlib/console.rb +94 -0
  283. data/stdlib/date.rb +1 -1
  284. data/stdlib/encoding.rb +1 -170
  285. data/stdlib/js.rb +56 -0
  286. data/stdlib/json.rb +9 -14
  287. data/stdlib/math.rb +1 -370
  288. data/stdlib/native.rb +133 -63
  289. data/stdlib/nodejs/file.rb +5 -0
  290. data/stdlib/nodejs/fileutils.rb +13 -6
  291. data/stdlib/nodejs/node_modules/js-yaml/node_modules/argparse/README.md +1 -1
  292. data/stdlib/opal-parser.rb +1 -2
  293. data/stdlib/ostruct.rb +65 -6
  294. data/stdlib/pp.rb +2 -4
  295. data/stdlib/rbconfig.rb +1 -3
  296. data/stdlib/strscan.rb +164 -28
  297. data/tasks/benchmarking.rake +88 -0
  298. data/tasks/testing.rake +181 -55
  299. data/{lib/mspec/opal/special_calls.rb → tasks/testing/mspec_special_calls.rb} +1 -1
  300. data/{lib/mspec/opal/sprockets.js → tasks/testing/phantomjs1-sprockets.js} +17 -6
  301. data/test/opal/test_keyword.rb +590 -0
  302. data/vendored-minitest/minitest.rb +2 -2
  303. data/vendored-minitest/test/unit.rb +5 -0
  304. metadata +229 -62
  305. data/benchmarks/operators.rb +0 -11
  306. data/benchmarks/prova.js.rb +0 -13
  307. data/docs/libraries.md +0 -36
  308. data/lib/mspec/opal/new.html.erb +0 -1
  309. data/lib/mspec/opal/rake_task.rb +0 -248
  310. data/opal/corelib/match_data.rb +0 -128
  311. data/spec/filters/bugs/math.rb +0 -95
  312. data/spec/filters/bugs/nil.rb +0 -7
  313. data/spec/filters/bugs/opal.rb +0 -9
  314. data/spec/filters/bugs/regular_expressions.rb +0 -41
  315. data/spec/filters/bugs/stringscanner.rb +0 -33
  316. data/spec/filters/unsupported/encoding.rb +0 -102
  317. data/spec/filters/unsupported/frozen.rb +0 -92
  318. data/spec/filters/unsupported/hash_compare_by_identity.rb +0 -16
  319. data/spec/filters/unsupported/integer_size.rb +0 -59
  320. data/spec/filters/unsupported/method_added.rb +0 -10
  321. data/spec/filters/unsupported/private_constants.rb +0 -30
  322. data/spec/filters/unsupported/private_methods.rb +0 -55
  323. data/spec/filters/unsupported/random.rb +0 -4
  324. data/spec/filters/unsupported/rational_numbers.rb +0 -4
  325. data/spec/filters/unsupported/regular_expressions.rb +0 -137
  326. data/spec/filters/unsupported/ruby_exe.rb +0 -5
  327. data/spec/filters/unsupported/symbols.rb +0 -17
  328. data/spec/filters/unsupported/tainted.rb +0 -180
  329. data/spec/filters/unsupported/trusted.rb +0 -88
  330. data/stdlib/process.rb +0 -10
  331. data/tasks/documenting.rake +0 -37
@@ -0,0 +1,3 @@
1
+ opal_filter "Struct" do
2
+ fails "Struct#initialize is private"
3
+ end
@@ -0,0 +1,5 @@
1
+ opal_filter "Symbol" do
2
+ fails "Numeric#coerce raises a TypeError when passed a Symbol"
3
+ fails "Fixnum#coerce raises a TypeError when given an Object that does not respond to #to_f"
4
+ fails "The throw keyword does not convert strings to a symbol"
5
+ end
@@ -0,0 +1,16 @@
1
+ opal_filter "taint" do
2
+ fails "Range#to_s ignores own tainted status"
3
+ fails "Range#inspect ignores own tainted status"
4
+
5
+ fails "String#% doesn't taint the result for %e when argument is tainted"
6
+ fails "String#% doesn't taint the result for %E when argument is tainted"
7
+ fails "String#% doesn't taint the result for %f when argument is tainted"
8
+ fails "String#% doesn't taint the result for %g when argument is tainted"
9
+ fails "String#% doesn't taint the result for %G when argument is tainted"
10
+ fails "String#byteslice with index, length always taints resulting strings when self is tainted"
11
+ fails "String#byteslice with Range always taints resulting strings when self is tainted"
12
+
13
+ fails "StringScanner#pre_match taints the returned String if the input was tainted"
14
+ fails "StringScanner#post_match taints the returned String if the input was tainted"
15
+ fails "StringScanner#rest taints the returned String if the input was tainted"
16
+ end
@@ -0,0 +1,5 @@
1
+ opal_filter "Thread" do
2
+ fails "StandardError is a superclass of ThreadError"
3
+ fails "The throw keyword raises an ArgumentError if used to exit a thread"
4
+ fails "The throw keyword clears the current exception"
5
+ end
@@ -1,21 +1,202 @@
1
1
  opal_filter "Time" do
2
- fails "Time.mktime handles microseconds"
3
- fails "Time.mktime handles fractional microseconds as a Float"
4
- fails "Time.mktime handles fractional microseconds as a Rational"
5
- fails "Time.mktime ignores fractional seconds if a passed whole number of microseconds"
6
- fails "Time.mktime ignores fractional seconds if a passed fractional number of microseconds"
7
-
8
- fails "Time#strftime returns the fractional seconds digits, default is 9 digits (nanosecond) with %N"
9
- fails "Time#strftime with %N formats the nanoseconds of of the second with %N"
10
- fails "Time#strftime with %N formats the milliseconds of of the second with %3N"
11
- fails "Time#strftime with %N formats the microseconds of of the second with %6N"
12
- fails "Time#strftime with %N formats the nanoseconds of of the second with %9N"
13
- fails "Time#strftime with %N formats the picoseconds of of the second with %12N"
14
- fails "Time#strftime with %z formats a UTC time offset as '+0000'"
15
- fails "Time#strftime with %z formats a time with fixed positive offset as '+HHMM'"
2
+ fails "Time#+ accepts arguments that can be coerced into Rational"
3
+ fails "Time#+ adds a negative Float"
4
+ fails "Time#+ increments the time by the specified amount as rational numbers"
5
+ fails "Time#+ maintains microseconds precision"
6
+ fails "Time#+ maintains nanoseconds precision"
7
+ fails "Time#+ maintains precision"
8
+ fails "Time#+ maintains subseconds precision"
9
+ fails "Time#+ returns a time with the same fixed offset as self"
10
+ fails "Time#+ tracks microseconds"
11
+ fails "Time#+ tracks nanoseconds"
12
+ fails "Time#- accepts arguments that can be coerced into Rational"
13
+ fails "Time#- maintains microseconds precision"
14
+ fails "Time#- maintains nanoseconds precision"
15
+ fails "Time#- maintains precision"
16
+ fails "Time#- maintains subseconds precision"
17
+ fails "Time#- returns a time with nanoseconds precision between two time objects"
18
+ fails "Time#- returns a time with the same fixed offset as self"
19
+ fails "Time#- tracks microseconds"
20
+ fails "Time#- tracks nanoseconds"
21
+ fails "Time#<=> returns -1 if the first argument is a fraction of a microsecond before the second argument"
22
+ fails "Time#<=> returns -1 if the first argument is a point in time before the second argument (down to a microsecond)"
23
+ fails "Time#<=> returns 0 if time is the same as other, including fractional microseconds"
24
+ fails "Time#<=> returns 1 if the first argument is a fraction of a microsecond after the second argument"
25
+ fails "Time#<=> returns 1 if the first argument is a point in time after the second argument (down to a microsecond)"
26
+ fails "Time#day returns the day of the month (1..n) for a local Time"
27
+ fails "Time#day returns the day of the month for a Time with a fixed offset"
28
+ fails "Time#dst? dst? returns whether time is during daylight saving time"
29
+ fails "Time#dup returns a subclass instance"
30
+ fails "Time#eql? returns false if self and other have differing fractional microseconds"
31
+ fails "Time#eql? returns false if self and other have differing numbers of microseconds"
32
+ fails "Time#getgm returns a new time which is the utc representation of time"
33
+ fails "Time#getlocal raises ArgumentError if the argument represents a value greater than or equal to 86400 seconds"
34
+ fails "Time#getlocal raises ArgumentError if the argument represents a value less than or equal to -86400 seconds"
35
+ fails "Time#getlocal raises ArgumentError if the String argument is not of the form (+|-)HH:MM"
36
+ fails "Time#getlocal returns a new time which is the local representation of time"
37
+ fails "Time#getlocal returns a new time with the correct utc_offset according to the set timezone"
38
+ fails "Time#getlocal returns a Time with a UTC offset of the specified number of Rational seconds"
39
+ fails "Time#getlocal returns a Time with a UTC offset specified as +HH:MM"
40
+ fails "Time#getlocal returns a Time with a UTC offset specified as -HH:MM"
41
+ fails "Time#getlocal returns a Time with UTC offset specified as an Integer number of seconds"
42
+ fails "Time#getlocal with an argument that responds to #to_int coerces using #to_int"
43
+ fails "Time#getlocal with an argument that responds to #to_r coerces using #to_r"
44
+ fails "Time#getlocal with an argument that responds to #to_str coerces using #to_str"
45
+ fails "Time#getutc returns a new time which is the utc representation of time"
46
+ fails "Time#gmtime returns the utc representation of time"
47
+ fails "Time#gmtoff given negative offset returns a negative offset"
48
+ fails "Time#gmtoff given positive offset returns a positive offset"
49
+ fails "Time#gmtoff returns offset as Rational"
50
+ fails "Time#gmtoff returns the correct offset for Hawaii around daylight savings time change"
51
+ fails "Time#gmtoff returns the correct offset for New Zealand around daylight savings time change"
52
+ fails "Time#gmtoff returns the correct offset for US Eastern time zone around daylight savings time change"
53
+ fails "Time#gmtoff returns the offset in seconds between the timezone of time and UTC"
54
+ fails "Time#gmt_offset given negative offset returns a negative offset"
55
+ fails "Time#gmt_offset given positive offset returns a positive offset"
56
+ fails "Time#gmt_offset returns offset as Rational"
57
+ fails "Time#gmt_offset returns the correct offset for Hawaii around daylight savings time change"
58
+ fails "Time#gmt_offset returns the correct offset for New Zealand around daylight savings time change"
59
+ fails "Time#gmt_offset returns the correct offset for US Eastern time zone around daylight savings time change"
60
+ fails "Time#gmt_offset returns the offset in seconds between the timezone of time and UTC"
61
+ fails "Time#hash returns a Fixnum"
62
+ fails "Time#hour returns the hour of the day (0..23) for a local Time"
63
+ fails "Time#hour returns the hour of the day for a Time with a fixed offset"
64
+ fails "Time#isdst dst? returns whether time is during daylight saving time"
65
+ fails "Time#localtime changes the timezone according to the set one"
66
+ fails "Time#localtime converts self to local time, modifying the receiver"
67
+ fails "Time#localtime converts time to the UTC offset specified as an Integer number of seconds"
68
+ fails "Time#localtime raises ArgumentError if the argument represents a value greater than or equal to 86400 seconds"
69
+ fails "Time#localtime raises ArgumentError if the argument represents a value less than or equal to -86400 seconds"
70
+ fails "Time#localtime raises ArgumentError if the String argument is not of the form (+|-)HH:MM"
71
+ fails "Time#localtime returns a Time with a UTC offset of the specified number of Rational seconds"
72
+ fails "Time#localtime returns a Time with a UTC offset specified as +HH:MM"
73
+ fails "Time#localtime returns a Time with a UTC offset specified as -HH:MM"
74
+ fails "Time#localtime returns self"
75
+ fails "Time#localtime with an argument that responds to #to_int coerces using #to_int"
76
+ fails "Time#localtime with an argument that responds to #to_r coerces using #to_r"
77
+ fails "Time#localtime with an argument that responds to #to_str coerces using #to_str"
78
+ fails "Time#mday returns the day of the month (1..n) for a local Time"
79
+ fails "Time#mday returns the day of the month for a Time with a fixed offset"
80
+ fails "Time#min returns the minute of the hour (0..59) for a local Time"
81
+ fails "Time#min returns the minute of the hour for a Time with a fixed offset"
82
+ fails "Time#mon returns the four digit year for a Time with a fixed offset"
83
+ fails "Time#mon returns the month of the year for a local Time"
84
+ fails "Time#month returns the four digit year for a Time with a fixed offset"
85
+ fails "Time#month returns the month of the year for a local Time"
86
+ fails "Time#nsec returns 0 for a Time constructed with a whole number of seconds"
87
+ fails "Time#nsec returns the nanoseconds part of a Time constructed with a Float number of seconds"
88
+ fails "Time#nsec returns the nanoseconds part of a Time constructed with a Rational number of seconds"
89
+ fails "Time#nsec returns the nanoseconds part of a Time constructed with an Float number of microseconds"
90
+ fails "Time#nsec returns the nanoseconds part of a Time constructed with an Integer number of microseconds"
91
+ fails "Time#nsec returns the nanoseconds part of a Time constructed with an Rational number of microseconds"
92
+ fails "Time#strftime with %L formats the milliseconds of the second"
93
+ fails "Time#strftime with %z formats a local time with negative UTC offset as '-HHMM'"
94
+ fails "Time#strftime with %z formats a local time with positive UTC offset as '+HHMM'"
16
95
  fails "Time#strftime with %z formats a time with fixed negative offset as '-HHMM'"
17
96
  fails "Time#strftime with %z formats a time with fixed offset as '+/-HH:MM' with ':' specifier"
18
97
  fails "Time#strftime with %z formats a time with fixed offset as '+/-HH:MM:SS' with '::' specifier"
19
- fails "Time#strftime with %z rounds fixed offset to the nearest second"
20
- fails "Time#strftime with %L formats the milliseconds of of the second"
98
+ fails "Time#strftime with %z formats a time with fixed positive offset as '+HHMM'"
99
+ fails "Time#strftime with %z formats a UTC time offset as '+0000'"
100
+ fails "Time#subsec returns 0 as a Fixnum for a Time with a whole number of seconds"
101
+ fails "Time#subsec returns the fractional seconds as a Rational for a Time constructed with a Float number of seconds"
102
+ fails "Time#subsec returns the fractional seconds as a Rational for a Time constructed with a Rational number of seconds"
103
+ fails "Time#subsec returns the fractional seconds as a Rational for a Time constructed with an Float number of microseconds"
104
+ fails "Time#subsec returns the fractional seconds as a Rational for a Time constructed with an Integer number of microseconds"
105
+ fails "Time#subsec returns the fractional seconds as a Rational for a Time constructed with an Rational number of microseconds"
106
+ fails "Time#to_a returns a 10 element array representing the deconstructed time"
107
+ fails "Time#to_r returns a Rational even for a whole number of seconds"
108
+ fails "Time#to_r returns the a Rational representing seconds and subseconds since the epoch"
109
+ fails "Time#usec returns 0 for a Time constructed with an Rational number of microseconds < 1"
110
+ fails "Time#usec returns the microseconds for time created by Time#local"
111
+ fails "Time#usec returns the microseconds part of a Time constructed with a Rational number of seconds"
112
+ fails "Time#usec returns the microseconds part of a Time constructed with an Float number of microseconds > 1"
113
+ fails "Time#usec returns the microseconds part of a Time constructed with an Integer number of microseconds"
114
+ fails "Time#usec returns the microseconds part of a Time constructed with an Rational number of microseconds > 1"
115
+ fails "Time#utc returns the utc representation of time"
116
+ fails "Time#utc_offset given negative offset returns a negative offset"
117
+ fails "Time#utc_offset given positive offset returns a positive offset"
118
+ fails "Time#utc_offset returns offset as Rational"
119
+ fails "Time#utc_offset returns the correct offset for Hawaii around daylight savings time change"
120
+ fails "Time#utc_offset returns the correct offset for New Zealand around daylight savings time change"
121
+ fails "Time#utc_offset returns the correct offset for US Eastern time zone around daylight savings time change"
122
+ fails "Time#utc_offset returns the offset in seconds between the timezone of time and UTC"
123
+ fails "Time#wday returns an integer representing the day of the week, 0..6, with Sunday being 0"
124
+ fails "Time#year returns the four digit year for a local Time as an Integer"
125
+ fails "Time#year returns the four digit year for a Time with a fixed offset"
126
+ fails "Time#zone Encoding.default_internal is set doesn't raise errors for a Time with a fixed offset"
127
+ fails "Time#zone Encoding.default_internal is set returns the string with the default internal encoding"
128
+ fails "Time#zone returns nil for a Time with a fixed offset"
129
+ fails "Time#zone returns nil when getting the local time with a fixed offset"
130
+ fails "Time#zone returns the correct timezone for a local time"
131
+ fails "Time#zone returns the time zone used for time"
132
+ fails "Time#zone returns UTC when called on a UTC time"
133
+ fails "Time.at passed non-Time, non-Numeric with an argument that responds to #to_r coerces using #to_r"
134
+ fails "Time.at passed Numeric returns a subclass instance on a Time subclass"
135
+ fails "Time.at passed Time returns a subclass instance"
136
+ fails "Time.at passed [Integer, Numeric] returns a Time object representing the given number of seconds and Float microseconds since 1970-01-01 00:00:00 UTC"
137
+ fails "Time.at with a second argument that responds to #to_r coerces using #to_r"
138
+ fails "Time.gm handles fractional microseconds as a Float"
139
+ fails "Time.gm handles fractional microseconds as a Rational"
140
+ fails "Time.gm handles fractional seconds as a Rational"
141
+ fails "Time.gm handles microseconds"
142
+ fails "Time.gm ignores fractional seconds if a passed fractional number of microseconds"
143
+ fails "Time.gm ignores fractional seconds if a passed whole number of microseconds"
144
+ fails "Time.gm returns subclass instances"
145
+ fails "Time.local creates a time based on given C-style gmtime arguments, interpreted in the local time zone"
146
+ fails "Time.local creates a time based on given values, interpreted in the local time zone"
147
+ fails "Time.local creates the correct time just after dst change"
148
+ fails "Time.local creates the correct time just before dst change"
149
+ fails "Time.local handles fractional microseconds as a Float"
150
+ fails "Time.local handles fractional microseconds as a Rational"
151
+ fails "Time.local handles fractional seconds as a Rational"
152
+ fails "Time.local handles microseconds"
153
+ fails "Time.local ignores fractional seconds if a passed fractional number of microseconds"
154
+ fails "Time.local ignores fractional seconds if a passed whole number of microseconds"
155
+ fails "Time.local respects rare old timezones"
156
+ fails "Time.local returns subclass instances"
157
+ fails "Time.local timezone changes correctly adjusts the timezone change to 'CEST' on 'Europe/Amsterdam'"
158
+ fails "Time.local timezone changes correctly adjusts the timezone change to 'EET' on 'Europe/Istanbul'"
159
+ fails "Time.mktime creates a time based on given C-style gmtime arguments, interpreted in the local time zone"
160
+ fails "Time.mktime creates a time based on given values, interpreted in the local time zone"
161
+ fails "Time.mktime creates the correct time just after dst change"
162
+ fails "Time.mktime creates the correct time just before dst change"
163
+ fails "Time.mktime handles fractional microseconds as a Float"
164
+ fails "Time.mktime handles fractional microseconds as a Rational"
165
+ fails "Time.mktime handles fractional seconds as a Rational"
166
+ fails "Time.mktime handles microseconds"
167
+ fails "Time.mktime ignores fractional seconds if a passed fractional number of microseconds"
168
+ fails "Time.mktime ignores fractional seconds if a passed whole number of microseconds"
169
+ fails "Time.mktime respects rare old timezones"
170
+ fails "Time.mktime returns subclass instances"
171
+ fails "Time.mktime timezone changes correctly adjusts the timezone change to 'CEST' on 'Europe/Amsterdam'"
172
+ fails "Time.mktime timezone changes correctly adjusts the timezone change to 'EET' on 'Europe/Istanbul'"
173
+ fails "Time.new creates a subclass instance if called on a subclass"
174
+ fails "Time.new creates a time based on given values, interpreted in the local time zone"
175
+ fails "Time.new handles fractional seconds as a Rational"
176
+ fails "Time.new respects rare old timezones"
177
+ fails "Time.new returns subclass instances"
178
+ fails "Time.new timezone changes correctly adjusts the timezone change to 'CEST' on 'Europe/Amsterdam'"
179
+ fails "Time.new timezone changes correctly adjusts the timezone change to 'EET' on 'Europe/Istanbul'"
180
+ fails "Time.new with a utc_offset argument adds one hour if the offset minute value is greater than 59"
181
+ fails "Time.new with a utc_offset argument raises ArgumentError if the argument represents a value greater than or equal to 86400 seconds"
182
+ fails "Time.new with a utc_offset argument raises ArgumentError if the argument represents a value less than or equal to -86400 seconds"
183
+ fails "Time.new with a utc_offset argument raises ArgumentError if the hour value is greater than 23"
184
+ fails "Time.new with a utc_offset argument raises ArgumentError if the String argument is not of the form (+|-)HH:MM"
185
+ fails "Time.new with a utc_offset argument returns a local Time if the argument is nil"
186
+ fails "Time.new with a utc_offset argument returns a non-UTC time"
187
+ fails "Time.new with a utc_offset argument returns a Time with a UTC offset of the specified number of Integer seconds"
188
+ fails "Time.new with a utc_offset argument returns a Time with a UTC offset of the specified number of Rational seconds"
189
+ fails "Time.new with a utc_offset argument returns a Time with a UTC offset specified as +HH:MM"
190
+ fails "Time.new with a utc_offset argument returns a Time with a UTC offset specified as -HH:MM"
191
+ fails "Time.new with a utc_offset argument with an argument that responds to #to_int coerces using #to_int"
192
+ fails "Time.new with a utc_offset argument with an argument that responds to #to_r coerces using #to_r"
193
+ fails "Time.new with a utc_offset argument with an argument that responds to #to_str coerces using #to_str"
194
+ fails "Time.now creates a subclass instance if called on a subclass"
195
+ fails "Time.utc handles fractional microseconds as a Float"
196
+ fails "Time.utc handles fractional microseconds as a Rational"
197
+ fails "Time.utc handles fractional seconds as a Rational"
198
+ fails "Time.utc handles microseconds"
199
+ fails "Time.utc ignores fractional seconds if a passed fractional number of microseconds"
200
+ fails "Time.utc ignores fractional seconds if a passed whole number of microseconds"
201
+ fails "Time.utc returns subclass instances"
21
202
  end
data/spec/lib/cli_spec.rb CHANGED
@@ -115,15 +115,14 @@ describe Opal::CLI do
115
115
  end
116
116
 
117
117
  describe ':compile option' do
118
- let(:options) { {:compile => true, :evals => ['puts 5']} }
118
+ let(:options) { {:compile => true, :evals => ['puts 2342']} }
119
119
 
120
120
  it 'outputs the compiled javascript' do
121
- expect_output_of{ subject.run }.to include(".$puts(5)")
122
- expect_output_of{ subject.run }.not_to include("5\n")
121
+ expect_output_of{ subject.run }.to include(".$puts(2342)")
122
+ expect_output_of{ subject.run }.not_to include("2342\n")
123
123
  end
124
124
  end
125
125
 
126
-
127
126
  describe ':load_paths options' do
128
127
  let(:dir) { File.dirname(file) }
129
128
  let(:filename) { File.basename(file) }
@@ -133,6 +132,17 @@ describe Opal::CLI do
133
132
  end
134
133
  end
135
134
 
135
+ describe ':sexp option' do
136
+ let(:options) { {evals: ['puts 4'], sexp: true} }
137
+ it 'prints syntax expressions for the given code' do
138
+ expect_output_of{ subject.run }.to eq("(:call, nil, :puts, (:arglist, (:int, 4)))\n")
139
+ end
140
+ end
141
+
142
+
143
+
144
+ private
145
+
136
146
  def expect_output_of
137
147
  @output, _result = output_and_result_of { yield }
138
148
  expect(@output)
@@ -38,7 +38,15 @@ describe Opal::Compiler do
38
38
  expect_compiled("self.inspect").to include("$inspect()")
39
39
  expect_compiled("self.map { |a| a + 10 }").to include("$map")
40
40
  end
41
-
41
+
42
+ it "adds method missing stubs" do
43
+ expect_compiled("self.puts 'hello'").to include("Opal.add_stubs(['$puts'])")
44
+ end
45
+
46
+ it 'adds method missing stubs with operators' do
47
+ expect_compiled("class Foo; end; Foo.new > 5").to include("Opal.add_stubs(['$>', '$new'])")
48
+ end
49
+
42
50
  it "should compile constant lookups" do
43
51
  expect_compiled("Object").to include("Object")
44
52
  expect_compiled("Array").to include("Array")
@@ -154,6 +154,24 @@ describe 'Operator calls followed by parens' do
154
154
  end
155
155
  end
156
156
 
157
+ describe 'Calls that include a hash' do
158
+ it 'parses correctly when a hash followed by a block' do
159
+ parsed('foo(a => 2, &block)').should == [:call, nil, :foo, [:arglist, [:hash, [:call, nil, :a, [:arglist]], [:int, 2]],[:block_pass, [:call, nil, :block, [:arglist]]]]]
160
+ end
161
+
162
+ it 'parses correctly when only a hash is passed' do
163
+ parsed('foo(a => 2)').should == [:call, nil, :foo, [:arglist, [:hash, [:call, nil, :a, [:arglist]], [:int, 2]]]]
164
+ end
165
+
166
+ it 'parses correctly when ending in hash' do
167
+ parsed('foo(1, a => 2)').should == [:call, nil, :foo, [:arglist, [:int, 1], [:hash, [:call, nil, :a, [:arglist]], [:int, 2]]]]
168
+ end
169
+
170
+ it 'parses correctly with another parameter and hash followed by a block' do
171
+ parsed('foo(1, a => 2, &block)').should == [:call, nil, :foo, [:arglist, [:int, 1], [:hash, [:call, nil, :a, [:arglist]], [:int, 2]], [:block_pass, [:call, nil, :block, [:arglist]]]]]
172
+ end
173
+ end
174
+
157
175
  describe 'Calls with trailing comma' do
158
176
  it 'parses correctly' do
159
177
  parsed('foo(1,)').should == [:call, nil, :foo, [:arglist, [:int, 1]]]
@@ -14,14 +14,8 @@ describe "The '!' expression" do
14
14
  end
15
15
  end
16
16
 
17
- describe "The '!=' expression" do
18
- it "rewrites as !(lhs == rhs)" do
19
- parsed("1 != 2").should == [:call, [:call, [:int, 1], :==, [:arglist, [:int, 2]]], '!'.to_sym, [:arglist]]
20
- end
21
- end
22
-
23
17
  describe "The '!~' expression" do
24
- it "rewrites as !(lhs =~ rhs)" do
25
- parsed("1 !~ 2").should == [:not, [:call, [:int, 1], :=~, [:arglist, [:int, 2]]]]
18
+ it "does not rewrite as !(lhs =~ rhs)" do
19
+ parsed("1 !~ 2").should == [:call, [:int, 1], :!~, [:arglist, [:int, 2]]]
26
20
  end
27
21
  end
@@ -0,0 +1,24 @@
1
+ require 'lib/spec_helper'
2
+ require 'opal/sprockets'
3
+
4
+ describe Opal::Sprockets do
5
+ let(:env) { Sprockets::Environment.new }
6
+ before { Opal.paths.each { |path| env.append_path path } }
7
+
8
+ describe '.load_asset' do
9
+ it 'loads the main asset' do
10
+ code = described_class.load_asset('console', env)
11
+ expect(code).to include('Opal.load("console");')
12
+ end
13
+
14
+ it 'marks as loaded "opal" plus all non opal assets' do
15
+ code = described_class.load_asset('corelib/runtime', env)
16
+ expect(code).to include('Opal.loaded(["opal","corelib/runtime"]);')
17
+ end
18
+
19
+ it 'returns an empty string if the asset is not found' do
20
+ code = described_class.load_asset('foo', env)
21
+ expect(code).to eq('')
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,38 @@
1
+ describe "Array#&" do
2
+ it "relies on Ruby's #hash (not JavaScript's #toString) for identifying array items" do
3
+ a1 = [ 123, '123']
4
+ a2 = ['123', 123 ]
5
+ (a1 & a2).should == a1
6
+ (a2 & a1).should == a2
7
+
8
+ a1 = [ Time.at(1429521600.1), Time.at(1429521600.9) ]
9
+ a2 = [ Time.at(1429521600.9), Time.at(1429521600.1) ]
10
+ (a1 & a2).should == a1
11
+ (a2 & a1).should == a2
12
+
13
+ a1 = [ Object.new, Object.new ]
14
+ a2 = [ Object.new, Object.new ]
15
+ (a1 & a2).should == []
16
+ (a2 & a1).should == []
17
+
18
+ a1 = [ 1, 2, 3, '1', '2', '3']
19
+ a2 = ['1', '2', '3', 1, 2, 3 ]
20
+ (a1 & a2).should == a1
21
+ (a2 & a1).should == a2
22
+
23
+ a1 = [ [1, 2, 3], '1,2,3']
24
+ a2 = ['1,2,3', [1, 2, 3] ]
25
+ (a1 & a2).should == a1
26
+ (a2 & a1).should == a2
27
+
28
+ a1 = [ true, 'true']
29
+ a2 = ['true', true ]
30
+ (a1 & a2).should == a1
31
+ (a2 & a1).should == a2
32
+
33
+ a1 = [ false, 'false']
34
+ a2 = ['false', false ]
35
+ (a1 & a2).should == a1
36
+ (a2 & a1).should == a2
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ describe "Array#-" do
2
+ it "relies on Ruby's #hash (not JavaScript's #toString) for identifying array items" do
3
+ a1 = [ 123 ]
4
+ a2 = ['123']
5
+ (a1 - a2).should == a1
6
+ (a2 - a1).should == a2
7
+
8
+ a1 = [ Time.at(1429521600.1) ]
9
+ a2 = [ Time.at(1429521600.9) ]
10
+ (a1 - a2).should == a1
11
+ (a2 - a1).should == a2
12
+
13
+ a1 = [ Object.new ]
14
+ a2 = [ Object.new ]
15
+ (a1 - a2).should == a1
16
+ (a2 - a1).should == a2
17
+
18
+ a1 = [ 1, 2, 3 ]
19
+ a2 = ['1', '2', '3']
20
+ (a1 - a2).should == a1
21
+ (a2 - a1).should == a2
22
+
23
+ a1 = [ 1, 2, 3 ]
24
+ a2 = ['1,2,3']
25
+ (a1 - a2).should == a1
26
+ (a2 - a1).should == a2
27
+
28
+ a1 = [ true ]
29
+ a2 = ['true']
30
+ (a1 - a2).should == a1
31
+ (a2 - a1).should == a2
32
+
33
+ a1 = [ false ]
34
+ a2 = ['false']
35
+ (a1 - a2).should == a1
36
+ (a2 - a1).should == a2
37
+ end
38
+ end