opal 1.0.3 → 1.1.1.rc1

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 (408) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +13 -12
  3. data/.gitattributes +1 -1
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/workflows/build.yml +90 -0
  6. data/.jshintrc +1 -1
  7. data/.overcommit.yml +35 -0
  8. data/.rubocop.yml +44 -7
  9. data/{.rubocop_todo.yml → .rubocop/todo.yml} +4 -5
  10. data/CHANGELOG.md +152 -1
  11. data/Gemfile +2 -3
  12. data/HACKING.md +2 -9
  13. data/LICENSE +1 -1
  14. data/README.md +21 -18
  15. data/UNRELEASED.md +4 -2
  16. data/benchmark-ips/bm_array_pop_1.rb +8 -0
  17. data/benchmark-ips/bm_array_shift.rb +7 -0
  18. data/benchmark-ips/bm_js_symbols_vs_strings.rb +7 -2
  19. data/benchmark-ips/class_shovel_vs_singleton_class.rb +16 -0
  20. data/bin/build-browser-source-map-support +4 -0
  21. data/bin/format-filters +54 -0
  22. data/bin/git-submodule-fast-install +49 -0
  23. data/bin/remove-filters +39 -0
  24. data/bin/setup +4 -0
  25. data/bin/yarn +11 -0
  26. data/docs/releasing.md +18 -0
  27. data/docs/roda-sprockets.md +86 -0
  28. data/docs/sinatra.md +5 -12
  29. data/examples/rack/Gemfile +1 -0
  30. data/examples/rack/app/application.rb +3 -0
  31. data/examples/rack/config.ru +5 -4
  32. data/exe/opal-repl +2 -83
  33. data/lib/opal/ast/builder.rb +1 -1
  34. data/lib/opal/builder.rb +2 -10
  35. data/lib/opal/builder_processors.rb +1 -1
  36. data/lib/opal/cli.rb +4 -1
  37. data/lib/opal/cli_options.rb +11 -3
  38. data/lib/opal/cli_runners.rb +27 -37
  39. data/lib/opal/cli_runners/applescript.rb +5 -44
  40. data/lib/opal/cli_runners/chrome.js +7 -35
  41. data/lib/opal/cli_runners/chrome.rb +75 -17
  42. data/lib/opal/cli_runners/compiler.rb +17 -0
  43. data/lib/opal/cli_runners/nashorn.rb +9 -43
  44. data/lib/opal/cli_runners/nodejs.rb +18 -47
  45. data/lib/opal/cli_runners/server.rb +18 -6
  46. data/lib/opal/cli_runners/source-map-support-browser.js +6449 -0
  47. data/lib/opal/cli_runners/source-map-support-node.js +3704 -0
  48. data/lib/opal/cli_runners/source-map-support.js +639 -0
  49. data/lib/opal/cli_runners/system_runner.rb +45 -0
  50. data/lib/opal/compiler.rb +57 -29
  51. data/lib/opal/config.rb +0 -5
  52. data/lib/opal/erb.rb +1 -1
  53. data/lib/opal/magic_comments.rb +34 -0
  54. data/lib/opal/nodes/args/arity_check.rb +2 -1
  55. data/lib/opal/nodes/base.rb +1 -1
  56. data/lib/opal/nodes/call.rb +1 -4
  57. data/lib/opal/nodes/def.rb +2 -0
  58. data/lib/opal/nodes/iter.rb +1 -1
  59. data/lib/opal/nodes/literal.rb +19 -14
  60. data/lib/opal/nodes/logic.rb +5 -80
  61. data/lib/opal/nodes/masgn.rb +2 -0
  62. data/lib/opal/nodes/rescue.rb +1 -1
  63. data/lib/opal/nodes/super.rb +24 -10
  64. data/lib/opal/nodes/top.rb +5 -4
  65. data/lib/opal/parser/with_c_lexer.rb +2 -1
  66. data/lib/opal/parser/with_ruby_lexer.rb +1 -1
  67. data/lib/opal/path_reader.rb +2 -2
  68. data/lib/opal/paths.rb +8 -5
  69. data/lib/opal/repl.rb +103 -0
  70. data/lib/opal/rewriter.rb +4 -0
  71. data/lib/opal/rewriters/for_rewriter.rb +1 -1
  72. data/lib/opal/rewriters/js_reserved_words.rb +7 -7
  73. data/lib/opal/rewriters/numblocks.rb +31 -0
  74. data/lib/opal/rewriters/returnable_logic.rb +33 -0
  75. data/lib/opal/util.rb +11 -48
  76. data/lib/opal/version.rb +1 -1
  77. data/opal.gemspec +26 -26
  78. data/opal/corelib/array.rb +160 -118
  79. data/opal/corelib/array/pack.rb +5 -3
  80. data/opal/corelib/basic_object.rb +4 -4
  81. data/opal/corelib/class.rb +2 -1
  82. data/opal/corelib/comparable.rb +49 -31
  83. data/opal/corelib/constants.rb +5 -5
  84. data/opal/corelib/enumerable.rb +108 -46
  85. data/opal/corelib/enumerator.rb +27 -12
  86. data/opal/corelib/file.rb +3 -1
  87. data/opal/corelib/hash.rb +6 -1
  88. data/opal/corelib/helpers.rb +8 -28
  89. data/opal/corelib/io.rb +12 -7
  90. data/opal/corelib/kernel.rb +45 -14
  91. data/opal/corelib/kernel/format.rb +3 -1
  92. data/opal/corelib/math.rb +8 -6
  93. data/opal/corelib/method.rb +8 -0
  94. data/opal/corelib/module.rb +17 -2
  95. data/opal/corelib/number.rb +3 -12
  96. data/opal/corelib/proc.rb +16 -0
  97. data/opal/corelib/random/mersenne_twister.rb +147 -0
  98. data/opal/corelib/range.rb +3 -13
  99. data/opal/corelib/regexp.rb +10 -6
  100. data/opal/corelib/runtime.js +208 -81
  101. data/opal/corelib/string.rb +55 -49
  102. data/opal/corelib/string/encoding.rb +109 -32
  103. data/opal/corelib/string/unpack.rb +2 -17
  104. data/opal/corelib/struct.rb +14 -1
  105. data/opal/corelib/time.rb +4 -0
  106. data/opal/opal.rb +1 -1
  107. data/opal/opal/mini.rb +1 -1
  108. data/package.json +16 -0
  109. data/spec/README.md +10 -0
  110. data/spec/filters/bugs/array.rb +76 -0
  111. data/spec/filters/bugs/base64.rb +10 -0
  112. data/spec/filters/bugs/basicobject.rb +12 -0
  113. data/spec/filters/bugs/bigdecimal.rb +248 -0
  114. data/spec/filters/bugs/class.rb +12 -0
  115. data/spec/filters/bugs/complex.rb +7 -0
  116. data/spec/filters/bugs/date.rb +104 -0
  117. data/spec/filters/bugs/encoding.rb +259 -0
  118. data/spec/filters/bugs/enumerable.rb +26 -0
  119. data/spec/filters/bugs/enumerator.rb +48 -0
  120. data/spec/filters/bugs/exception.rb +120 -0
  121. data/spec/filters/bugs/file.rb +48 -0
  122. data/spec/filters/bugs/float.rb +74 -0
  123. data/spec/filters/bugs/hash.rb +60 -0
  124. data/spec/filters/bugs/integer.rb +78 -0
  125. data/spec/filters/bugs/io.rb +9 -0
  126. data/spec/filters/bugs/kernel.rb +401 -0
  127. data/spec/filters/bugs/language.rb +451 -0
  128. data/spec/filters/bugs/marshal.rb +50 -0
  129. data/spec/filters/bugs/math.rb +4 -0
  130. data/spec/filters/bugs/method.rb +79 -0
  131. data/spec/filters/bugs/module.rb +281 -0
  132. data/spec/filters/bugs/nilclass.rb +4 -0
  133. data/spec/filters/bugs/numeric.rb +27 -0
  134. data/spec/filters/bugs/openstruct.rb +8 -0
  135. data/spec/filters/bugs/pack_unpack.rb +138 -0
  136. data/spec/filters/bugs/pathname.rb +9 -0
  137. data/spec/filters/bugs/proc.rb +80 -0
  138. data/spec/filters/bugs/random.rb +20 -0
  139. data/spec/filters/bugs/range.rb +139 -0
  140. data/spec/filters/bugs/rational.rb +12 -0
  141. data/spec/filters/bugs/regexp.rb +91 -0
  142. data/spec/filters/bugs/set.rb +51 -0
  143. data/spec/filters/bugs/singleton.rb +7 -0
  144. data/spec/filters/bugs/string.rb +341 -0
  145. data/spec/filters/bugs/stringscanner.rb +78 -0
  146. data/spec/filters/bugs/struct.rb +26 -0
  147. data/spec/filters/bugs/symbol.rb +7 -0
  148. data/spec/filters/bugs/time.rb +109 -0
  149. data/spec/filters/bugs/unboundmethod.rb +33 -0
  150. data/spec/filters/bugs/warnings.rb +30 -0
  151. data/spec/filters/unsupported/array.rb +168 -0
  152. data/spec/filters/unsupported/basicobject.rb +15 -0
  153. data/spec/filters/unsupported/bignum.rb +55 -0
  154. data/spec/filters/unsupported/class.rb +5 -0
  155. data/spec/filters/unsupported/delegator.rb +6 -0
  156. data/spec/filters/unsupported/enumerable.rb +12 -0
  157. data/spec/filters/unsupported/enumerator.rb +14 -0
  158. data/spec/filters/unsupported/file.rb +4 -0
  159. data/spec/filters/unsupported/fixnum.rb +15 -0
  160. data/spec/filters/unsupported/float.rb +47 -0
  161. data/spec/filters/unsupported/freeze.rb +259 -0
  162. data/spec/filters/unsupported/hash.rb +44 -0
  163. data/spec/filters/unsupported/integer.rb +101 -0
  164. data/spec/filters/unsupported/kernel.rb +35 -0
  165. data/spec/filters/unsupported/language.rb +25 -0
  166. data/spec/filters/unsupported/marshal.rb +44 -0
  167. data/spec/filters/unsupported/matchdata.rb +63 -0
  168. data/spec/filters/unsupported/math.rb +4 -0
  169. data/spec/filters/unsupported/pathname.rb +4 -0
  170. data/spec/filters/unsupported/privacy.rb +287 -0
  171. data/spec/filters/unsupported/proc.rb +4 -0
  172. data/spec/filters/unsupported/random.rb +5 -0
  173. data/spec/filters/unsupported/range.rb +8 -0
  174. data/spec/filters/unsupported/regexp.rb +70 -0
  175. data/spec/filters/unsupported/set.rb +5 -0
  176. data/spec/filters/unsupported/singleton.rb +7 -0
  177. data/spec/filters/unsupported/string.rb +687 -0
  178. data/spec/filters/unsupported/struct.rb +7 -0
  179. data/spec/filters/unsupported/symbol.rb +21 -0
  180. data/spec/filters/unsupported/taint.rb +162 -0
  181. data/spec/filters/unsupported/thread.rb +10 -0
  182. data/spec/filters/unsupported/time.rb +204 -0
  183. data/spec/filters/unsupported/usage_of_files.rb +262 -0
  184. data/spec/lib/builder_processors_spec.rb +44 -0
  185. data/spec/lib/builder_spec.rb +133 -0
  186. data/spec/lib/cli_runners/server_spec.rb +25 -0
  187. data/spec/lib/cli_runners_spec.rb +16 -0
  188. data/spec/lib/cli_spec.rb +256 -0
  189. data/spec/lib/compiler_spec.rb +693 -0
  190. data/spec/lib/config_spec.rb +112 -0
  191. data/spec/lib/dependency_resolver_spec.rb +43 -0
  192. data/spec/lib/deprecations_spec.rb +17 -0
  193. data/spec/lib/fixtures/complex_sprockets.js.rb.erb +4 -0
  194. data/spec/lib/fixtures/file_with_directives.js +2 -0
  195. data/spec/lib/fixtures/jst_file.js.jst +1 -0
  196. data/spec/lib/fixtures/no_requires.rb +1 -0
  197. data/spec/lib/fixtures/opal_file.rb +2 -0
  198. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  199. data/spec/lib/fixtures/required_file.js +1 -0
  200. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  201. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  202. data/spec/lib/fixtures/requires.rb +7 -0
  203. data/spec/lib/fixtures/source_location_test.rb +7 -0
  204. data/spec/lib/fixtures/source_map.rb +1 -0
  205. data/spec/lib/fixtures/source_map/subfolder/other_file.rb +1 -0
  206. data/spec/lib/fixtures/sprockets_file.js.rb +3 -0
  207. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  208. data/spec/lib/path_reader_spec.rb +47 -0
  209. data/spec/lib/paths_spec.rb +18 -0
  210. data/spec/lib/repl_spec.rb +28 -0
  211. data/spec/lib/rewriters/base_spec.rb +68 -0
  212. data/spec/lib/rewriters/binary_operator_assignment_spec.rb +153 -0
  213. data/spec/lib/rewriters/block_to_iter_spec.rb +28 -0
  214. data/spec/lib/rewriters/dot_js_syntax_spec.rb +108 -0
  215. data/spec/lib/rewriters/explicit_writer_return_spec.rb +186 -0
  216. data/spec/lib/rewriters/for_rewriter_spec.rb +92 -0
  217. data/spec/lib/rewriters/hashes/key_duplicates_rewriter_spec.rb +47 -0
  218. data/spec/lib/rewriters/js_reserved_words_spec.rb +119 -0
  219. data/spec/lib/rewriters/logical_operator_assignment_spec.rb +202 -0
  220. data/spec/lib/rewriters/opal_engine_check_spec.rb +84 -0
  221. data/spec/lib/rewriters/returnable_logic_spec.rb +52 -0
  222. data/spec/lib/rewriters/rubyspec/filters_rewriter_spec.rb +59 -0
  223. data/spec/lib/simple_server_spec.rb +56 -0
  224. data/spec/lib/source_map/file_spec.rb +67 -0
  225. data/spec/lib/source_map/index_spec.rb +80 -0
  226. data/spec/lib/spec_helper.rb +105 -0
  227. data/spec/mspec-opal/formatters.rb +197 -0
  228. data/spec/mspec-opal/runner.rb +172 -0
  229. data/spec/opal/compiler/irb_spec.rb +44 -0
  230. data/spec/opal/compiler/unicode_spec.rb +10 -0
  231. data/spec/opal/core/array/dup_spec.rb +23 -0
  232. data/spec/opal/core/array/intersection_spec.rb +38 -0
  233. data/spec/opal/core/array/minus_spec.rb +38 -0
  234. data/spec/opal/core/array/union_spec.rb +38 -0
  235. data/spec/opal/core/array/uniq_spec.rb +49 -0
  236. data/spec/opal/core/class/inherited_spec.rb +18 -0
  237. data/spec/opal/core/enumerable/all_break_spec.rb +5 -0
  238. data/spec/opal/core/enumerable/any_break_spec.rb +5 -0
  239. data/spec/opal/core/enumerable/collect_break_spec.rb +13 -0
  240. data/spec/opal/core/enumerable/count_break_spec.rb +5 -0
  241. data/spec/opal/core/enumerable/detect_break_spec.rb +5 -0
  242. data/spec/opal/core/enumerable/drop_while_break_spec.rb +5 -0
  243. data/spec/opal/core/enumerable/each_slice_break_spec.rb +6 -0
  244. data/spec/opal/core/enumerable/each_with_index_break_spec.rb +5 -0
  245. data/spec/opal/core/enumerable/each_with_object_break_spec.rb +5 -0
  246. data/spec/opal/core/enumerable/find_all_break_spec.rb +5 -0
  247. data/spec/opal/core/enumerable/find_index_break_spec.rb +5 -0
  248. data/spec/opal/core/enumerable/grep_break_spec.rb +5 -0
  249. data/spec/opal/core/enumerable/max_break_spec.rb +5 -0
  250. data/spec/opal/core/enumerable/max_by_break_spec.rb +5 -0
  251. data/spec/opal/core/enumerable/min_break_spec.rb +5 -0
  252. data/spec/opal/core/enumerable/min_by_break_spec.rb +5 -0
  253. data/spec/opal/core/enumerable/none_break_spec.rb +5 -0
  254. data/spec/opal/core/enumerable/one_break_spec.rb +5 -0
  255. data/spec/opal/core/enumerable/reduce_break_spec.rb +5 -0
  256. data/spec/opal/core/enumerable/take_while_break_spec.rb +5 -0
  257. data/spec/opal/core/enumerator/with_index_spec.rb +6 -0
  258. data/spec/opal/core/exception_spec.rb +8 -0
  259. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  260. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  261. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  262. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  263. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  264. data/spec/opal/core/fixtures/require_tree_files/nested/nested 1.rb +1 -0
  265. data/spec/opal/core/fixtures/require_tree_files/nested/nested 2.rb +1 -0
  266. data/spec/opal/core/fixtures/require_tree_files/other/other 1.rb +1 -0
  267. data/spec/opal/core/fixtures/require_tree_with_dot/file 1.rb +1 -0
  268. data/spec/opal/core/fixtures/require_tree_with_dot/file 2.rb +1 -0
  269. data/spec/opal/core/fixtures/require_tree_with_dot/file 3.rb +1 -0
  270. data/spec/opal/core/fixtures/require_tree_with_dot/index.rb +3 -0
  271. data/spec/opal/core/hash/internals_spec.rb +339 -0
  272. data/spec/opal/core/helpers_spec.rb +14 -0
  273. data/spec/opal/core/iterable_props_spec.rb +53 -0
  274. data/spec/opal/core/kernel/at_exit_spec.rb +70 -0
  275. data/spec/opal/core/kernel/freeze_spec.rb +15 -0
  276. data/spec/opal/core/kernel/instance_variables_spec.rb +110 -0
  277. data/spec/opal/core/kernel/methods_spec.rb +25 -0
  278. data/spec/opal/core/kernel/public_methods_spec.rb +25 -0
  279. data/spec/opal/core/kernel/require_tree_spec.rb +18 -0
  280. data/spec/opal/core/kernel/respond_to_spec.rb +15 -0
  281. data/spec/opal/core/language/DATA/characters_support_spec.rb +9 -0
  282. data/spec/opal/core/language/DATA/empty___END___spec.rb +7 -0
  283. data/spec/opal/core/language/DATA/multiple___END___spec.rb +10 -0
  284. data/spec/opal/core/language/arguments/mlhs_arg_spec.rb +18 -0
  285. data/spec/opal/core/language/keyword_arguments_spec.rb +9 -0
  286. data/spec/opal/core/language/numblocks_spec.rb +16 -0
  287. data/spec/opal/core/language/safe_navigator_spec.rb +7 -0
  288. data/spec/opal/core/language/while_spec.rb +31 -0
  289. data/spec/opal/core/language_spec.rb +29 -0
  290. data/spec/opal/core/marshal/dump_spec.rb +81 -0
  291. data/spec/opal/core/marshal/load_spec.rb +13 -0
  292. data/spec/opal/core/module_spec.rb +27 -0
  293. data/spec/opal/core/object_id_spec.rb +56 -0
  294. data/spec/opal/core/regexp/interpolation_spec.rb +40 -0
  295. data/spec/opal/core/regexp/match_spec.rb +78 -0
  296. data/spec/opal/core/runtime/bridged_classes_spec.rb +123 -0
  297. data/spec/opal/core/runtime/constants_spec.rb +16 -0
  298. data/spec/opal/core/runtime/eval_spec.rb +5 -0
  299. data/spec/opal/core/runtime/exit_spec.rb +29 -0
  300. data/spec/opal/core/runtime/is_a_spec.rb +48 -0
  301. data/spec/opal/core/runtime/loaded_spec.rb +20 -0
  302. data/spec/opal/core/runtime/main_methods_spec.rb +39 -0
  303. data/spec/opal/core/runtime/method_missing_spec.rb +68 -0
  304. data/spec/opal/core/runtime/rescue_spec.rb +37 -0
  305. data/spec/opal/core/runtime/string_spec.rb +25 -0
  306. data/spec/opal/core/runtime/truthy_spec.rb +61 -0
  307. data/spec/opal/core/runtime_spec.rb +58 -0
  308. data/spec/opal/core/string/each_byte_spec.rb +19 -0
  309. data/spec/opal/core/string/gsub_spec.rb +35 -0
  310. data/spec/opal/core/string/to_sym_spec.rb +9 -0
  311. data/spec/opal/core/string_spec.rb +28 -0
  312. data/spec/opal/core/struct/dup_spec.rb +11 -0
  313. data/spec/opal/core/time_spec.rb +68 -0
  314. data/spec/opal/stdlib/erb/erb_spec.rb +30 -0
  315. data/spec/opal/stdlib/erb/inline_block.opalerb +3 -0
  316. data/spec/opal/stdlib/erb/quoted.opalerb +1 -0
  317. data/spec/opal/stdlib/erb/simple.opalerb +1 -0
  318. data/spec/opal/stdlib/js_spec.rb +72 -0
  319. data/spec/opal/stdlib/json/ext_spec.rb +55 -0
  320. data/spec/opal/stdlib/json/parse_spec.rb +37 -0
  321. data/spec/opal/stdlib/logger/logger_spec.rb +308 -0
  322. data/spec/opal/stdlib/native/alias_native_spec.rb +27 -0
  323. data/spec/opal/stdlib/native/array_spec.rb +11 -0
  324. data/spec/opal/stdlib/native/date_spec.rb +12 -0
  325. data/spec/opal/stdlib/native/deprecated_include_spec.rb +8 -0
  326. data/spec/opal/stdlib/native/each_spec.rb +13 -0
  327. data/spec/opal/stdlib/native/element_reference_spec.rb +16 -0
  328. data/spec/opal/stdlib/native/exposure_spec.rb +33 -0
  329. data/spec/opal/stdlib/native/ext_spec.rb +19 -0
  330. data/spec/opal/stdlib/native/hash_spec.rb +67 -0
  331. data/spec/opal/stdlib/native/initialize_spec.rb +17 -0
  332. data/spec/opal/stdlib/native/method_missing_spec.rb +51 -0
  333. data/spec/opal/stdlib/native/native_alias_spec.rb +26 -0
  334. data/spec/opal/stdlib/native/native_class_spec.rb +18 -0
  335. data/spec/opal/stdlib/native/native_module_spec.rb +13 -0
  336. data/spec/opal/stdlib/native/native_reader_spec.rb +22 -0
  337. data/spec/opal/stdlib/native/native_writer_spec.rb +30 -0
  338. data/spec/opal/stdlib/native/new_spec.rb +92 -0
  339. data/spec/opal/stdlib/native/struct_spec.rb +12 -0
  340. data/spec/opal/stdlib/pp_spec.rb +5 -0
  341. data/spec/opal/stdlib/promise/always_spec.rb +49 -0
  342. data/spec/opal/stdlib/promise/error_spec.rb +15 -0
  343. data/spec/opal/stdlib/promise/rescue_spec.rb +53 -0
  344. data/spec/opal/stdlib/promise/then_spec.rb +79 -0
  345. data/spec/opal/stdlib/promise/trace_spec.rb +51 -0
  346. data/spec/opal/stdlib/promise/value_spec.rb +15 -0
  347. data/spec/opal/stdlib/promise/when_spec.rb +34 -0
  348. data/spec/opal/stdlib/source_map_spec.rb +8 -0
  349. data/spec/opal/stdlib/strscan/scan_spec.rb +11 -0
  350. data/spec/opal/stdlib/template/paths_spec.rb +10 -0
  351. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  352. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  353. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  354. data/spec/ruby_specs +183 -0
  355. data/spec/spec_helper.rb +31 -0
  356. data/spec/support/guard_platform.rb +4 -0
  357. data/spec/support/match_helpers.rb +57 -0
  358. data/spec/support/mspec_rspec_adapter.rb +33 -0
  359. data/spec/support/rewriters_helper.rb +54 -0
  360. data/spec/support/source_map_helper.rb +190 -0
  361. data/stdlib/base64.rb +2 -2
  362. data/stdlib/bigdecimal.rb +15 -3
  363. data/stdlib/bigdecimal/bignumber.js.rb +1 -1
  364. data/stdlib/bigdecimal/util.rb +148 -0
  365. data/stdlib/delegate.rb +8 -0
  366. data/stdlib/nodejs/fileutils.rb +1 -1
  367. data/stdlib/nodejs/kernel.rb +0 -13
  368. data/stdlib/nodejs/stacktrace.rb +4 -179
  369. data/stdlib/ostruct.rb +5 -0
  370. data/stdlib/pp.rb +586 -19
  371. data/stdlib/prettyprint.rb +556 -0
  372. data/stdlib/rbconfig/sizeof.rb +2 -0
  373. data/stdlib/securerandom.rb +32 -0
  374. data/stdlib/set.rb +36 -0
  375. data/stdlib/strscan.rb +15 -0
  376. data/tasks/benchmarking.rake +1 -1
  377. data/tasks/linting.rake +3 -5
  378. data/tasks/releasing.rake +2 -5
  379. data/tasks/testing.rake +16 -11
  380. data/tasks/testing/mspec_special_calls.rb +1 -19
  381. data/test/nodejs/fixtures/cat.png +0 -0
  382. data/test/nodejs/fixtures/hello.rb +1 -0
  383. data/test/nodejs/fixtures/iso88591.txt +1 -0
  384. data/test/nodejs/fixtures/utf8.txt +1 -0
  385. data/test/nodejs/fixtures/win1258.txt +1 -0
  386. data/test/nodejs/test_dir.rb +39 -0
  387. data/test/nodejs/test_env.rb +62 -0
  388. data/test/nodejs/test_error.rb +29 -0
  389. data/test/nodejs/test_file.rb +206 -0
  390. data/test/nodejs/test_file_encoding.rb +20 -0
  391. data/test/nodejs/test_io.rb +18 -0
  392. data/test/nodejs/test_opal_builder.rb +12 -0
  393. data/test/nodejs/test_pathname.rb +16 -0
  394. data/test/opal/cat.png +0 -0
  395. data/test/opal/http_server.rb +52 -0
  396. data/test/opal/test_base64.rb +115 -0
  397. data/test/opal/test_keyword.rb +590 -0
  398. data/test/opal/test_matrix.rb +661 -0
  399. data/test/opal/test_openuri.rb +53 -0
  400. data/test/opal/unsupported_and_bugs.rb +39 -0
  401. data/yarn.lock +1355 -0
  402. metadata +905 -40
  403. data/.travis.yml +0 -109
  404. data/appveyor.yml +0 -35
  405. data/lib/opal/nodes/runtime_helpers.rb +0 -51
  406. data/opal/corelib/random/MersenneTwister.js +0 -137
  407. data/opal/corelib/random/mersenne_twister.js.rb +0 -13
  408. data/stdlib/bigdecimal/kernel.rb +0 -5
data/spec/ruby_specs ADDED
@@ -0,0 +1,183 @@
1
+ ruby/core/array
2
+
3
+ ruby/core/array/pack/a_spec
4
+ !ruby/core/array/pack/at_spec
5
+ !ruby/core/array/pack/b_spec
6
+ ruby/core/array/pack/c_spec
7
+ !ruby/core/array/pack/comment_spec
8
+ !ruby/core/array/pack/d_spec
9
+ !ruby/core/array/pack/e_spec
10
+ !ruby/core/array/pack/empty_spec
11
+ !ruby/core/array/pack/f_spec
12
+ !ruby/core/array/pack/g_spec
13
+ !ruby/core/array/pack/h_spec
14
+ !ruby/core/array/pack/i_spec
15
+ !ruby/core/array/pack/j_spec
16
+ ruby/core/array/pack/l_spec
17
+ !ruby/core/array/pack/m_spec
18
+ !ruby/core/array/pack/n_spec
19
+ !ruby/core/array/pack/p_spec
20
+ !ruby/core/array/pack/percent_spec
21
+ !ruby/core/array/pack/q_spec
22
+ !ruby/core/array/pack/s_spec
23
+ ruby/core/array/pack/u_spec
24
+ !ruby/core/array/pack/v_spec
25
+ !ruby/core/array/pack/w_spec
26
+ !ruby/core/array/pack/x_spec
27
+ !ruby/core/array/pack/z_spec
28
+
29
+ ruby/core/basicobject
30
+ ruby/core/builtin_constants
31
+ ruby/core/class
32
+ ruby/core/comparable
33
+
34
+ ruby/core/complex
35
+ !ruby/core/complex/marshal_dump_spec
36
+
37
+ ruby/core/enumerable
38
+ ruby/core/enumerator
39
+
40
+ ruby/core/exception
41
+ !ruby/core/exception/load_error_spec
42
+
43
+ ruby/core/false
44
+ ruby/core/integer
45
+ ruby/core/file/basename_spec
46
+ ruby/core/file/dirname_spec
47
+ ruby/core/file/extname_spec
48
+ ruby/core/file/join_spec
49
+ ruby/core/file/expand_path_spec
50
+ ruby/core/file/absolute_path_spec
51
+ ruby/core/float
52
+ ruby/core/hash
53
+ ruby/core/integer
54
+
55
+ ruby/core/kernel
56
+ !ruby/core/kernel/abort_spec
57
+ !ruby/core/kernel/at_exit_spec
58
+ !ruby/core/kernel/backtick_spec
59
+ !ruby/core/kernel/binding_spec
60
+ !ruby/core/kernel/callcc_spec
61
+ !ruby/core/kernel/caller_locations_spec
62
+ !ruby/core/kernel/catch_spec
63
+ !ruby/core/kernel/chomp_spec
64
+ !ruby/core/kernel/chop_spec
65
+ !ruby/core/kernel/exec_spec
66
+ !ruby/core/kernel/exit_spec
67
+ !ruby/core/kernel/fork_spec
68
+ !ruby/core/kernel/gets_spec
69
+ !ruby/core/kernel/load_spec
70
+ !ruby/core/kernel/open_spec
71
+ !ruby/core/kernel/putc_spec
72
+ !ruby/core/kernel/readlines_spec
73
+ !ruby/core/kernel/readline_spec
74
+ !ruby/core/kernel/require_relative_spec
75
+ !ruby/core/kernel/require_spec
76
+ !ruby/core/kernel/select_spec
77
+ !ruby/core/kernel/set_trace_func_spec
78
+ !ruby/core/kernel/spawn_spec
79
+ !ruby/core/kernel/syscall_spec
80
+ !ruby/core/kernel/system_spec
81
+ !ruby/core/kernel/tainted_spec
82
+ !ruby/core/kernel/taint_spec
83
+ !ruby/core/kernel/test_spec
84
+ !ruby/core/kernel/throw_spec
85
+ !ruby/core/kernel/trace_var_spec
86
+ !ruby/core/kernel/trap_spec
87
+ !ruby/core/kernel/trust_spec
88
+ !ruby/core/kernel/untaint_spec
89
+ !ruby/core/kernel/untrace_var_spec
90
+ !ruby/core/kernel/untrusted_spec
91
+ !ruby/core/kernel/untrust_spec
92
+
93
+ ruby/core/matchdata
94
+ ruby/core/math
95
+
96
+ ruby/core/method
97
+
98
+ ruby/core/module
99
+ !ruby/core/module/autoload_spec
100
+
101
+ ruby/core/marshal/load_spec
102
+ ruby/core/marshal/dump_spec
103
+ ruby/core/marshal/major_version_spec
104
+ ruby/core/marshal/minor_version_spec
105
+
106
+ ruby/core/nil
107
+ ruby/core/numeric
108
+
109
+ ruby/core/proc
110
+
111
+ ruby/core/range
112
+ ruby/core/rational
113
+ ruby/core/regexp
114
+ ruby/core/random
115
+
116
+ ruby/core/string
117
+ !ruby/core/string/crypt_spec
118
+ !ruby/core/string/scrub_spec
119
+
120
+ ruby/core/string/unpack/a_spec
121
+ !ruby/core/string/unpack/at_spec
122
+ ruby/core/string/unpack/b_spec
123
+ ruby/core/string/unpack/c_spec
124
+ !ruby/core/string/unpack/comment_spec
125
+ !ruby/core/string/unpack/d_spec
126
+ !ruby/core/string/unpack/e_spec
127
+ !ruby/core/string/unpack/f_spec
128
+ !ruby/core/string/unpack/g_spec
129
+ ruby/core/string/unpack/h_spec
130
+ !ruby/core/string/unpack/i_spec
131
+ !ruby/core/string/unpack/j_spec
132
+ ruby/core/string/unpack/l_spec
133
+ ruby/core/string/unpack/m_spec
134
+ ruby/core/string/unpack/n_spec
135
+ !ruby/core/string/unpack/p_spec
136
+ !ruby/core/string/unpack/percent_spec
137
+ ruby/core/string/unpack/q_spec
138
+ ruby/core/string/unpack/s_spec
139
+ ruby/core/string/unpack/u_spec
140
+ ruby/core/string/unpack/v_spec
141
+ ruby/core/string/unpack/w_spec
142
+ !ruby/core/string/unpack/x_spec
143
+ ruby/core/string/unpack/z_spec
144
+
145
+ ruby/core/struct
146
+ ruby/core/symbol/to_proc_spec
147
+
148
+ ruby/core/time
149
+ !ruby/core/time/_dump_spec
150
+ !ruby/core/time/_load_spec
151
+
152
+ ruby/core/true
153
+ ruby/core/unboundmethod
154
+
155
+ ruby/language
156
+ !ruby/language/execution_spec
157
+ !ruby/language/safe_spec
158
+
159
+ ruby/library/base64
160
+ ruby/library/bigdecimal
161
+ !ruby/library/bigdecimal/util_spec
162
+ ruby/library/date
163
+ ruby/library/delegate/delegator/send_spec
164
+ ruby/library/erb/util/h_spec
165
+ ruby/library/erb/util/html_escape_spec
166
+ ruby/library/logger/severity_spec
167
+ ruby/library/observer
168
+
169
+ ruby/library/openstruct
170
+ !ruby/library/openstruct/frozen_spec
171
+ !ruby/library/openstruct/marshal_load_spec
172
+ !ruby/library/openstruct/marshal_dump_spec
173
+
174
+ ruby/library/pathname
175
+ !ruby/library/pathname/empty_spec
176
+ !ruby/library/pathname/glob_spec
177
+ ruby/library/pp
178
+ ruby/library/securerandom/hex_spec
179
+ ruby/library/set
180
+ ruby/library/singleton
181
+ ruby/library/stringio/each_line_spec
182
+ ruby/library/stringio/each_spec
183
+ ruby/library/stringscanner
@@ -0,0 +1,31 @@
1
+ require 'opal'
2
+ require 'set'
3
+ require 'opal/platform'
4
+ require 'opal-parser'
5
+ require 'mspec'
6
+ require 'mspec/version'
7
+ require 'support/mspec_rspec_adapter'
8
+ require 'support/guard_platform'
9
+ require 'mspec-opal/runner'
10
+
11
+ # Node v0.12 as well as Google Chrome/V8 42.0.2311.135 (64-bit)
12
+ # showed to need more tolerance (ruby spec default is 0.00003)
13
+ TOLERANCE = 0.00004
14
+
15
+ ENV['MSPEC_RUNNER'] = true
16
+
17
+ module Kernel
18
+ def opal_parse(str, file='(string)')
19
+ Opal::Parser.new.parse str, file
20
+ end
21
+
22
+ def eval_js(javascript)
23
+ `eval(javascript)`
24
+ end
25
+ end
26
+
27
+ # To make MSpec happy
28
+ require 'thread'
29
+
30
+ require 'mspec/utils/script' # Needed by DottedFormatter
31
+ require 'mspec-opal/formatters'
@@ -0,0 +1,4 @@
1
+ class PlatformGuard < SpecGuard
2
+ HOST_OS = ENV['OPAL_PLATFORM_NAME']
3
+ POINTER_SIZE = ENV['OPAL_POINTER_SIZE'] || WORD_SIZE
4
+ end
@@ -0,0 +1,57 @@
1
+ module MatchHelpers
2
+ class MatchMatcher
3
+ def initialize(expected)
4
+ fail "Expected #{expected} to be a Regexp!" unless expected.is_a?(Regexp)
5
+ @expected = expected
6
+ end
7
+
8
+ def matches?(actual)
9
+ @actual = actual
10
+ @expected.match(@actual)
11
+ end
12
+
13
+ def failure_message
14
+ ["Expected #{@actual.inspect} (#{@actual.class})",
15
+ "to match #{@expected}"]
16
+ end
17
+
18
+ def negative_failure_message
19
+ ["Expected #{@actual.inspect} (#{@actual.class})",
20
+ "not to match #{@expected}"]
21
+ end
22
+ end
23
+
24
+ class EndWithHelper
25
+ def initialize(expected)
26
+ @expected = expected
27
+ end
28
+
29
+ def matches?(actual)
30
+ @actual = actual
31
+ @actual.end_with?(@expected)
32
+ end
33
+
34
+ def failure_message
35
+ ["Expected #{@actual.inspect} (#{@actual.class})",
36
+ "to end with #{@expected}"]
37
+ end
38
+
39
+ def negative_failure_message
40
+ ["Expected #{@actual.inspect} (#{@actual.class})",
41
+ "not to end with #{@expected}"]
42
+ end
43
+ end
44
+ end
45
+
46
+ if !defined? RSpec
47
+ class Object
48
+ def match(expected)
49
+ MatchHelpers::MatchMatcher.new(expected)
50
+ end
51
+
52
+ def end_with(expected)
53
+ MatchHelpers::EndWithHelper.new(expected)
54
+ end
55
+ end
56
+ end
57
+
@@ -0,0 +1,33 @@
1
+ module MSpecRSpecAdapter
2
+ def expect(object)
3
+ MSpecRSpecAdapterShould.new(object)
4
+ end
5
+
6
+ def eq(expected)
7
+ MSpecRSpecAdapterEq.new(expected)
8
+ end
9
+
10
+ class MSpecRSpecAdapterEq < Struct.new(:object)
11
+ end
12
+
13
+ class MSpecRSpecAdapterShould < Struct.new(:object)
14
+ def to(expectation)
15
+ apply_expectation(:should, expectation)
16
+ end
17
+
18
+ def apply_expectation(type, expectation)
19
+ if MSpecRSpecAdapterEq === expectation
20
+ object.send(type) == expectation.object
21
+ else
22
+ object.send(type, expectation)
23
+ end
24
+ end
25
+
26
+ def not_to(expectation)
27
+ apply_expectation(:should_not, expectation)
28
+ end
29
+ alias to_not not_to
30
+ end
31
+ end
32
+
33
+ include MSpecRSpecAdapter unless defined? RSpec
@@ -0,0 +1,54 @@
1
+ module RewritersHelper
2
+ def s(type, *children)
3
+ ::Opal::AST::Node.new(type, children)
4
+ end
5
+
6
+ def rewritten(ast)
7
+ described_class.new.process(ast)
8
+ end
9
+
10
+ alias :rewrite :rewritten
11
+
12
+ def expect_rewritten(ast)
13
+ expect(rewritten(ast))
14
+ end
15
+
16
+ def expect_no_rewriting_for(ast)
17
+ expect_rewritten(ast).to eq(ast)
18
+ end
19
+
20
+ def parse(source)
21
+ buffer = Opal::Parser::SourceBuffer.new('(eval)')
22
+ buffer.source = source
23
+ parser = Opal::Parser.default_parser
24
+ parser.parse(buffer)
25
+ end
26
+
27
+ alias :ast_of :parse
28
+
29
+ def parse_without_rewriting(source)
30
+ buffer = Opal::Parser::SourceBuffer.new('(eval)')
31
+ buffer.source = source
32
+ parser = Parser::Ruby30.new
33
+ parser.parse(buffer)
34
+ end
35
+ end
36
+
37
+ RSpec.shared_examples 'it rewrites source-to-source' do |from_source, to_source|
38
+ it "rewrites source #{from_source} to source #{to_source}" do
39
+ initial = ast_of(from_source)
40
+ rewritten = self.rewritten(initial)
41
+ expected = ast_of(to_source)
42
+
43
+ expect(rewritten).to eq(expected)
44
+ end
45
+ end
46
+
47
+ RSpec.shared_examples 'it rewrites source-to-AST' do |from_source, to_ast|
48
+ it "rewrites source #{from_source} to AST #{to_ast}" do
49
+ initial = ast_of(from_source)
50
+ rewritten = self.rewritten(initial)
51
+
52
+ expect(rewritten).to eq(to_ast)
53
+ end
54
+ end
@@ -0,0 +1,190 @@
1
+ module SourceMapHelper
2
+ extend self
3
+
4
+ # Just for debugging purposes
5
+ def inspect_source(source)
6
+ puts source_with_lines(source)
7
+ end
8
+
9
+ # Just for debugging purposes
10
+ def source_with_lines(source)
11
+ source.split("\n", -1).map.with_index { |line, index| "#{(index).to_s.rjust(3)} | #{line}" }.join("\n")
12
+ end
13
+
14
+ def fragment(line: nil, column: nil, source_map_name: nil, code: '', sexp_type: nil)
15
+ double('Fragment', line: line, column: column, source_map_name: source_map_name, code: code, sexp_type: sexp_type)
16
+ end
17
+
18
+ SourcePosition = Struct.new(:line, :column, :file) do
19
+ def inspect
20
+ "#<SourcePosition line:#{line} column:#{column} file:#{file.inspect}>"
21
+ end
22
+ alias_method :to_s, :inspect
23
+
24
+ def in_source(source)
25
+ source.split("\n", -1)[line].to_s[column..-1]
26
+ end
27
+
28
+ def self.absolutize_mappings(relative_mappings)
29
+ reference_segment = [0, 0, 0, 0, 0]
30
+ relative_mappings.map do |relative_mapping|
31
+ # Reference: [generated_column, source_index, original_line, original_column, map_name_index]
32
+ reference_segment[0] = 0 # reset the generated_column at each new line
33
+
34
+ relative_mapping.map do |relative_segment|
35
+ segment = []
36
+
37
+ segment[0] = relative_segment[0].to_int + reference_segment[0].to_int
38
+ segment[1] = relative_segment[1].to_int + (reference_segment[1] || 0).to_int if relative_segment[1]
39
+ segment[2] = relative_segment[2].to_int + (reference_segment[2] || 0).to_int if relative_segment[2]
40
+ segment[3] = relative_segment[3].to_int + (reference_segment[3] || 0).to_int if relative_segment[3]
41
+ segment[4] = relative_segment[4].to_int + (reference_segment[4] || 0).to_int if relative_segment[4]
42
+
43
+ reference_segment = segment
44
+ segment
45
+ end
46
+ end
47
+ end
48
+
49
+ def find_section_in_map_index(index_map)
50
+ sections = index_map.to_h[:sections]
51
+ section, section_index = sections.each.with_index.find do |map, index|
52
+ next_map = sections[index + 1] or next true # if there's no next map the current one is good
53
+
54
+ (
55
+ line > map[:offset][:line] || (line == map[:offset][:line] && column >= map[:offset][:column])
56
+ ) && (
57
+ line < next_map[:offset][:line] || (line == next_map[:offset][:line] && column < map[:offset][:column])
58
+ )
59
+ end
60
+
61
+ next_section = sections[section_index + 1]
62
+
63
+ section or raise "no map found for #{inspect} among available sections: #{sections.map { |s| s[:offset] }}"
64
+ end
65
+
66
+ def mapped_with(map)
67
+ case map
68
+ when Opal::SourceMap::Index
69
+ offset_section = find_section_in_map_index(map)
70
+
71
+ offset = offset_section[:offset] || raise(offset_section.inspect)
72
+
73
+ offset_line = line - offset[:line]
74
+ offset_column = line.zero? ? (column - offset[:column]) : column
75
+ offset_position = self.class.new(offset_line, offset_column, offset_section[:map][:sources].first)
76
+
77
+ offset_position.mapped_with_file_map(offset_section[:map])
78
+
79
+ when Opal::SourceMap::File
80
+ mapped_with_file_map(map.to_h)
81
+
82
+ else raise "unknown map type: #{map.inspect}"
83
+ end
84
+ end
85
+
86
+ def mapped_with_file_map(map_to_h)
87
+ relative_mappings = Opal::SourceMap::VLQ.decode_mappings(map_to_h[:mappings])
88
+ absolute_mappings = SourcePosition.absolutize_mappings(relative_mappings)
89
+ mappings_line = absolute_mappings[line] or raise(
90
+ "can't find a mapping for #{inspect} in the available #{absolute_mappings.size} absolute mappings: #{absolute_mappings.inspect}"
91
+ )
92
+
93
+ # keep all segments with a column from the required position on
94
+ code_before_segment_strategy = -> segments {
95
+ segments.select do |segment|
96
+ segment[0] >= column
97
+ end.sort_by do |segment|
98
+ segment[0] - column # sort by the distance from the required position
99
+ end.first
100
+ }
101
+
102
+ code_after_segment_strategy = -> segments {
103
+ segments.select do |segment|
104
+ column >= segment[0]
105
+ end.sort_by do |segment|
106
+ column - segment[0] # sort by the distance from the required position
107
+ end.first
108
+ }
109
+
110
+ absolute_segments = absolute_mappings[line] or raise
111
+ matched_segment = code_before_segment_strategy[absolute_segments] || code_after_segment_strategy[absolute_segments]
112
+
113
+ raise "can't find a matching segment for #{inspect} in #{absolute_mappings[line]}" unless matched_segment
114
+
115
+ source_index = matched_segment[1]
116
+ original_source = map_to_h[:sources][source_index]
117
+ original_line = matched_segment[2]
118
+ original_column = matched_segment[3]
119
+
120
+ self.class.new(original_line, original_column, original_source)
121
+ end
122
+
123
+ def original_source(map)
124
+ map_to_h = map.to_h
125
+ matching_source = -> map_data { map_data[:sourcesContent].first if map_data[:sources] == [file] }
126
+ (map_to_h[:sections] || [{offset: {}, map: map_to_h}]).map { |section| matching_source[section[:map]] }.compact.first or
127
+ raise "can't find a source for #{file.inspect} in #{map_to_h.to_json}"
128
+ end
129
+
130
+ def self.find_code(code, source:)
131
+ line_contents, line = source.split("\n", -1).to_enum.with_index.find do |contents, index|
132
+ contents.include? code
133
+ end
134
+ return nil if line_contents.nil?
135
+ column = line_contents.index(code)
136
+ new(line, column)
137
+ end
138
+ end
139
+
140
+ RSpec::Matchers.define :be_at_line_and_column do |line, column, source:|
141
+ expected_position = SourcePosition.new(line, column)
142
+
143
+ match do |code|
144
+ actual_position = SourcePosition.find_code(code, source: source)
145
+ actual_position == expected_position
146
+ end
147
+
148
+ failure_message do |code|
149
+ actual_position = SourcePosition.find_code(code, source: source)
150
+ actual_code = expected_position.in_source(source)
151
+ "expected #{code.inspect} to be at #{expected_position}, " +
152
+ "instead #{actual_code.inspect} was found at the expected position, while code was found at #{actual_position}"
153
+ end
154
+ end
155
+
156
+ RSpec::Matchers.define :be_mapped_to_line_and_column do |line, column, source:, map:, file: nil|
157
+ expected_position = SourcePosition.new(line, column, file)
158
+
159
+ match do |code|
160
+ actual_position = SourcePosition.find_code(code, source: source).mapped_with(map)
161
+ actual_position == expected_position
162
+ end
163
+
164
+ failure_message do |code|
165
+ code_position = SourcePosition.find_code(code, source: source)
166
+ actual_position = code_position.mapped_with(map)
167
+
168
+ expected_source = expected_position.original_source(map)
169
+ expected_code = expected_position.in_source(expected_source)
170
+
171
+ actual_source = actual_position.original_source(map)
172
+ actual_code = actual_position.in_source(actual_source)
173
+
174
+ if Opal::SourceMap::Index === map
175
+ actual_section = actual_position.find_section_in_map_index(map)
176
+ expected_section = expected_position.find_section_in_map_index(map)
177
+ map.to_h[:sections].each { |s| p s[:offset] }
178
+ actual_offset = " (offset: #{actual_section[:offset]})"
179
+ expected_offset = " (offset: #{expected_section[:offset]})"
180
+ end
181
+
182
+ "expected #{code.inspect} at #{code_position.inspect} to be mapped to #{expected_position.inspect}" +
183
+ "\n\nEXPECTED #{expected_code.inspect} at #{expected_position}#{expected_offset}:\n"+
184
+ source_with_lines(expected_source) +
185
+ "\n\nACTUAL #{actual_code.inspect} at #{actual_position}#{actual_offset}:\n"+
186
+ source_with_lines(actual_source) +
187
+ "\n"
188
+ end
189
+ end
190
+ end