opal 0.8.1 → 0.9.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -2,8 +2,8 @@
2
2
 
3
3
  To configure a gem to run in Opal the gem will need a couple of things:
4
4
 
5
- 1. The opal gem running on a server (so the ruby code can get compiled to .js.)
6
- 2. The opal search path has to know to look for your gem when it is required.
5
+ 1. The opal gem running on a server (so the ruby code can get compiled to JavaScript).
6
+ 2. The Opal search path has to know to look for your gem when it is required.
7
7
 
8
8
  This is done by having the following 2 lines in your outermost .rb file:
9
9
 
data/docs/faq.md CHANGED
@@ -6,7 +6,7 @@ To try and keep ruby relevant in a world where client-side apps are making javas
6
6
 
7
7
  ### How compatible is Opal?
8
8
 
9
- We run opal against [rubyspec](https://github.com/rubyspec/rubyspec) as our primary testing setup. We try to make Opal as compatible as possible, whilst also taking into account restrictions of Javascript when applicable. Opal supports the majority of ruby syntax features, as well as a very large part of the corelib implementation. We support method\_missing, modules, classes, instance\_exec, blocks, procs and lots lots more. Opal can compile and run Rspec unmodified, as well as self hosting the compiler at runtime.
9
+ We run opal against [rubyspec](https://github.com/rubyspec/rubyspec) as our primary testing setup. We try to make Opal as compatible as possible, whilst also taking into account restrictions of JavaScript when applicable. Opal supports the majority of ruby syntax features, as well as a very large part of the corelib implementation. We support method\_missing, modules, classes, instance\_exec, blocks, procs and lots lots more. Opal can compile and run Rspec unmodified, as well as self hosting the compiler at runtime.
10
10
 
11
11
  ### What version of ruby does Opal target?
12
12
 
@@ -14,4 +14,4 @@ We are running tests under ruby 2.0.0 conditions, but are mostly compatible with
14
14
 
15
15
  ### Why doesn't Opal support mutable strings?
16
16
 
17
- All strings in Opal are immutable because ruby strings just get compiled direclty into javascript strings, which are immutable. Wrapping ruby strings as a custom Javascript object would add a lot of overhead as well as making interaction between ruby and javascript libraries more difficult.
17
+ All strings in Opal are immutable because ruby strings just get compiled direclty into javascript strings, which are immutable. Wrapping ruby strings as a custom JavaScript object would add a lot of overhead as well as making interaction between ruby and javascript libraries more difficult.
@@ -25,6 +25,23 @@ Opal.compile("[1, 2, 3].each { |a| puts a }")
25
25
  # => "(function() { ... })()"
26
26
  ```
27
27
 
28
- `opal` includes sprockets support to sprockets for compiling ruby (and erb) assets, and treating them as first class javascript citizens. It works in a similar way to coffeescript, where javascript files can simply require ruby sources, and ruby sources can require javascript and other ruby files.
28
+ `opal` includes sprockets support for compiling Ruby (and ERB) assets, and treating them as first class JavaScript citizens. It works in a similar way to CoffeeScript, where JavaScript files can simply require Ruby sources, and Ruby sources can require JavaScript and other Ruby files.
29
+
30
+ This relies on the Opal load path. Any gem containing opal code registers that directory to the Opal load path. Opal will then use all Opal load paths when running sprockets instances. For rails applications, `opal-rails` does this automatically. For building a simple application, we have to do this manually.
31
+
32
+
33
+ ### Adding lookup paths
34
+
35
+ Opal uses a load path which works with sprockets to create a set of locations which opal can require files
36
+ from. If you want to add a directory to this load path, you can add it to the global environment.
37
+
38
+ In the `Opal` module, a property `paths` is used to hold the load paths which
39
+ `Opal` uses to require files from. You can add a directory to this:
40
+
41
+ ```ruby
42
+ Opal.append_path '../my_lib'
43
+ ```
44
+
45
+ Now, any ruby files in this directory can be discovered.
46
+
29
47
 
30
- This relies on the opal load path. Any gem containing opal code registers that directory to the opal load path. opal will then use all opal load paths when running sprockets instances. For rails applications, opal-rails does this automatically. For building a simple application, we have to do this manually.
data/docs/jquery.md CHANGED
@@ -42,11 +42,11 @@ require 'opal-jquery'
42
42
  alert "Hello from jquery + opal"
43
43
  ```
44
44
 
45
- > **Note**: this file requires two important dependencies, `jquery` and `opal-jquery`.
46
- > You need to bring your own `jquery.js` file as the gem does not include one. If
47
- > you are using the asset pipeline with rails, then this should be available
48
- > already, otherwise download a copy and place it into `app/` or whichever directory
49
- > you are compiling assets from. You can alternatively require a zepto instance.
45
+ NOTE: this file requires two important dependencies, `jquery` and `opal-jquery`.
46
+ You need to bring your own `jquery.js` file as the gem does not include one. If
47
+ you are using the asset pipeline with rails, then this should be available
48
+ already, otherwise download a copy and place it into `app/` or whichever directory
49
+ you are compiling assets from. You can alternatively require a zepto instance.
50
50
 
51
51
  The `#alert` method is provided by `opal-jquery`. If the message displays, then
52
52
  `jquery` support should be working.
@@ -0,0 +1,53 @@
1
+ # Parsing Ruby from JavaScript with `opal-parser`
2
+
3
+ Generally is best to precompile Ruby source files to JavaScript server-side but sometimes may become useful to be able to compile Ruby to JavaScript directly from JS.
4
+
5
+ Opal is able to compile its – pure Ruby – compiler to JavaScript (how cool is that!). The whole compiler chain is available in the `stdlib` as `opal-parser`.
6
+
7
+ ```ruby
8
+ require 'opal-parser'
9
+ ```
10
+
11
+
12
+ ## Features
13
+
14
+ ### `Kernel#eval`
15
+
16
+ `opal-parser` provides a partial implementation of `Kernel#eval` that only support the first parameter (String) and refuse any passed `binding`, `lineno` or `filename`.
17
+
18
+ Example:
19
+
20
+ ```ruby
21
+ require 'opal-parser'
22
+ eval "puts 'hello world!'"
23
+ ```
24
+
25
+
26
+ ### `Kernel#require_remote`
27
+
28
+ Will fetch a remote URL (by means of a sync `XMLHttpRequest`) and evaluate its contents as Ruby code.
29
+
30
+ Example:
31
+
32
+ ```ruby
33
+ require 'opal-parser'
34
+ require_remote 'http://pastie.org/pastes/10444960/text'
35
+ HelloWorld.new.say_hello!
36
+ ```
37
+
38
+
39
+ ### `Opal.compile()` and `Opal.eval()` (JavaScript)
40
+
41
+ After requiring `opal-parser` both `Opal.compile()` and `Opal.eval()` functions are added to the JavaScript API.
42
+
43
+ `Opal.compile(string, options)` (JavaScript) will forward the call to `Opal.compile` (Ruby) converting options from a plain JS object to a Ruby Hash.
44
+ `Opal.eval(string)` will compile the given code to JavaScript and then pass it to the [native `eval()` function][eval].
45
+
46
+
47
+ ### Support for `<script type="text/ruby">`
48
+
49
+ When `opal-parser` is required it will search the page for any `<script>` tag with type `text/ruby`.
50
+ If an `src` attribute is present will fetch and eval the file with `Kernel#require_remote` otherwise it will get the script tags contents and eval them with `Kernel#eval`.
51
+
52
+
53
+ [eval]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
@@ -12,11 +12,11 @@ Encodings only have a very small implementation inside Opal.
12
12
 
13
13
  #### Threads ####
14
14
 
15
- Javascript does not have a native `Thread` implementation, so they are not present inside Opal. There is a placeholder `Thread` class just to provide some small level of compatibility with libraries that expect it. It does not have any function.
15
+ JavaScript does not have a native `Thread` implementation, so they are not present inside Opal. There is a placeholder `Thread` class just to provide some small level of compatibility with libraries that expect it. It does not have any function.
16
16
 
17
17
  #### Frozen Objects ####
18
18
 
19
- Opal does not currently support frozen objects, but has placeholder methods to prevent other libraries breaking when expecting these methods. Opal could support frozen objects in the future once a similar implementation becomes available across Javascript runtimes.
19
+ Opal does not currently support frozen objects, but has placeholder methods to prevent other libraries breaking when expecting these methods. Opal could support frozen objects in the future once a similar implementation becomes available across JavaScript runtimes.
20
20
 
21
21
  #### `method_added` and `method_removed` hooks ####
22
22
 
data/docs/upgrading.md ADDED
@@ -0,0 +1,22 @@
1
+ # Upgrading from v0.8 to v0.9
2
+
3
+ ## `Opal::Processor.load_asset_code` deprecated
4
+
5
+ `Opal::Processor.load_asset_code(sprockets, name)` has been deprecated in favor of `Opal::Sprockets.load_asset(name, sprockets)`.
6
+
7
+ ## `$console.log` instead of `pp`
8
+
9
+ Previously `pp` would have forwarded the object to JS own `console.log` but now just prints calling `.inspect` on it similarly to what `p` does.
10
+
11
+ ```ruby
12
+ require 'pp'
13
+ pp a: 1, b: {c: 3}
14
+ ```
15
+
16
+ Now:
17
+
18
+ ```ruby
19
+ require 'console'
20
+ $console.log a: 1, b: {c: 3}
21
+ ```
22
+
@@ -70,3 +70,18 @@ Run `bundle exec rackup` and visit the page `http://localhost:9292` in any
70
70
  browser. Observe the console to see the printed statement.
71
71
 
72
72
  You can just change `app/application.rb` and refresh the page to see any changes.
73
+
74
+
75
+ ## Using an existing `sprockets` instance
76
+
77
+ We only need to append Opal paths to the existing sprockets instance.
78
+
79
+ ```ruby
80
+ require 'sprockets'
81
+ environment = Sprockets::Environment.new
82
+
83
+ require 'opal'
84
+ Opal.paths.each do |path|
85
+ environment.append_path path
86
+ end
87
+ ```
@@ -1,7 +1,20 @@
1
1
  require 'bundler'
2
2
  Bundler.require
3
3
 
4
+ # Instructions: bundle in this directory
5
+ # then run bundle exec rackup to start the server
6
+ # and browse to localhost:9292
7
+
8
+ # a very small application that just tries to authenticate a user and fails
9
+ # it just writes to the console in the browser (no visible html)
10
+
11
+ # with gems like opal-jquery or opal-browser you could manipulate the dom directly
12
+
4
13
  run Opal::Server.new { |s|
14
+ # the name of the ruby file to load. To use more files they must be required from here (see app)
5
15
  s.main = 'application'
16
+ # the directory where the code is (add to opal load path )
6
17
  s.append_path 'app'
18
+ # need to set the index explicitly for opal server to pick it up
19
+ s.index_path = 'index.html.erb'
7
20
  }
@@ -7,6 +7,7 @@ opal = Opal::Server.new {|s|
7
7
  }
8
8
 
9
9
  sprockets = opal.sprockets
10
+ prefix = '/assets'
10
11
  maps_prefix = '/__OPAL_SOURCE_MAPS__'
11
12
  maps_app = Opal::SourceMapServer.new(sprockets, maps_prefix)
12
13
 
@@ -17,19 +18,17 @@ map maps_prefix do
17
18
  run maps_app
18
19
  end
19
20
 
20
- map '/assets' do
21
+ map prefix do
21
22
  run sprockets
22
23
  end
23
24
 
24
25
  get '/' do
25
- opal_boot_code = Opal::Processor.load_asset_code(sprockets, 'application')
26
-
27
26
  <<-HTML
28
27
  <!doctype html>
29
28
  <html>
30
29
  <head>
31
- <script src="/assets/application.js"></script>
32
- <script>#{opal_boot_code}</script>
30
+ <meta charset="utf-8">
31
+ #{::Opal::Sprockets.javascript_include_tag('application', sprockets: sprockets, prefix: prefix, debug: true)}
33
32
  </head>
34
33
  </html>
35
34
  HTML
@@ -5,6 +5,7 @@ class OSpecFilter
5
5
 
6
6
  def initialize
7
7
  @filters = Set.new
8
+ @seen = Set.new
8
9
  end
9
10
 
10
11
  def register
@@ -12,6 +13,7 @@ class OSpecFilter
12
13
  end
13
14
 
14
15
  def ===(description)
16
+ @seen << description
15
17
  @filters.include? description
16
18
  end
17
19
 
@@ -22,12 +24,58 @@ class OSpecFilter
22
24
  def fails(description)
23
25
  @filters << description
24
26
  end
27
+
28
+ def unused_filters_message(list: false)
29
+ unused = @filters - @seen
30
+ return if unused.size == 0
31
+
32
+ if list
33
+ puts
34
+ puts "Unused filters:"
35
+ unused.each {|u| puts "- #{u}"}
36
+ puts
37
+ else
38
+ warn "\nThere are #{unused.size} unused filters, re-run with ENV['LIST_UNUSED_FILTERS'] = true to list them\n\n"
39
+ end
40
+ end
25
41
  end
26
42
 
27
43
  class Object
28
44
  def opal_filter(description, &block)
29
45
  OSpecFilter.main.register_filters(description, block)
30
46
  end
47
+
48
+ # Copyed from MSpec, with changes.
49
+ def with_timezone(name, offset = nil, daylight_saving_zone = "")
50
+ zone = name.dup
51
+
52
+ if offset
53
+ # TZ convention is backwards
54
+ offset = -offset
55
+
56
+ zone += offset.to_s
57
+ zone += ":00:00"
58
+ end
59
+ zone += daylight_saving_zone
60
+
61
+ # WAS:
62
+ #
63
+ # old = ENV["TZ"]
64
+ # ENV["TZ"] = zone
65
+ #
66
+ # begin
67
+ # yield
68
+ # ensure
69
+ # ENV["TZ"] = old
70
+ # end
71
+ #
72
+ if ENV["TZ"] == zone
73
+ yield
74
+ else
75
+ 1.should == 1 # MSpec will get mad if the example has no expectations.
76
+ warn "Skipped spec for TZ=#{zone} as it's not supported"
77
+ end
78
+ end
31
79
  end
32
80
 
33
81
  class BrowserFormatter
@@ -171,10 +219,6 @@ class NodeJSFormatter < BrowserFormatter
171
219
  end
172
220
  end
173
221
 
174
- def finish_with_code(code)
175
- `global.OPAL_SPEC_CODE = code;`
176
- end
177
-
178
222
  def finish_with_code(code)
179
223
  puts "\n\n"
180
224
  exit(code)
@@ -227,9 +271,10 @@ class OSpecRunner
227
271
  MSpec.actions :start
228
272
  end
229
273
 
230
- def bm!(repeat)
274
+ def bm!(repeat, bm_filepath)
231
275
  `self.bm = {}`
232
- MSpec.repeat = repeat;
276
+ `self.bm_filepath = bm_filepath`
277
+ MSpec.repeat = repeat
233
278
  MSpec.register :before, self
234
279
  MSpec.register :after, self
235
280
  end
@@ -252,17 +297,15 @@ class OSpecRunner
252
297
 
253
298
  def did_finish
254
299
  %x{
255
- var obj = self.bm, key, val, json, file;
300
+ var obj = self.bm, key, val, report = '';
256
301
  if (obj) {
257
302
  for (key in obj) {
258
303
  if (obj.hasOwnProperty(key)) {
259
304
  val = obj[key];
260
- obj[key] = val.stopped - val.started;
305
+ report += key.replace(/\s/g, '_') + ' ' + ((val.stopped - val.started) / 1000) + '\n';
261
306
  }
262
307
  }
263
- json = JSON.stringify(obj, null, ' ');
264
- file = #{Time.now.strftime('tmp/bm_%Y-%m-%d_%H-%M-%S-%L.json')};
265
- #{File.open(`file`, 'w') {|f| f.write(`json`)}}
308
+ require('fs').writeFileSync(self.bm_filepath, report);
266
309
  }
267
310
  }
268
311
  MSpec.actions :finish
data/lib/opal.rb CHANGED
@@ -6,6 +6,6 @@ require 'opal/paths'
6
6
  require 'opal/version'
7
7
 
8
8
  # Opal is a ruby to javascript compiler, with a runtime for running
9
- # in any javascript environment.
9
+ # in any JavaScript environment.
10
10
  module Opal
11
11
  end
data/lib/opal/builder.rb CHANGED
@@ -143,7 +143,7 @@ module Opal
143
143
  def process_requires(filename, requires, options)
144
144
  requires.map { |r| process_require(r, options) }
145
145
  rescue MissingRequire => error
146
- raise error, "A file required by #{filename.inspect} wasn't found.\n#{error.message}"
146
+ raise error, "A file required by #{filename.inspect} wasn't found.\n#{error.message}", error.backtrace
147
147
  end
148
148
 
149
149
  def already_processed
@@ -62,7 +62,7 @@ module Opal
62
62
  end
63
63
 
64
64
  def mark_as_required(filename)
65
- "Opal.mark_as_loaded(Opal.normalize_loadable_path(#{filename.to_s.inspect}));"
65
+ "Opal.loaded([#{filename.to_s.inspect}]);"
66
66
  end
67
67
  end
68
68
 
data/lib/opal/cli.rb CHANGED
@@ -105,12 +105,8 @@ module Opal
105
105
  builder.build(local_require)
106
106
  end
107
107
 
108
- if evals.any?
109
- builder.build_str(evals.join("\n"), '-e')
110
- else
111
- if file and (filename != '-' or evals.empty?)
112
- builder.build_str(file.read, filename)
113
- end
108
+ evals_or_file do |contents, filename|
109
+ builder.build_str(contents, filename)
114
110
  end
115
111
 
116
112
  builder.build_str 'Kernel.exit', '(exit)' unless no_exit
@@ -127,14 +123,10 @@ module Opal
127
123
  end
128
124
 
129
125
  def show_sexp
130
- if evals.any?
131
- sexp = Opal::Parser.new.parse(evals.join("\n"), '-e')
132
- else
133
- if file and (file.path != '-' or evals.empty?)
134
- sexp = Opal::Parser.new.parse(file.read, file.path)
135
- end
126
+ evals_or_file do |contents, filename|
127
+ sexp = Opal::Parser.new.parse(contents, filename)
128
+ puts sexp.inspect
136
129
  end
137
- puts sexp.inspect
138
130
  end
139
131
 
140
132
  def map
@@ -154,6 +146,18 @@ module Opal
154
146
  ]
155
147
  end
156
148
 
149
+ # Internal: Yelds a string of source code and the proper filename for either
150
+ # evals, stdin or a filepath.
151
+ def evals_or_file
152
+ if evals.any?
153
+ yield evals.join("\n"), '-e'
154
+ else
155
+ if file and (filename != '-' or evals.empty?)
156
+ yield file.read, filename
157
+ end
158
+ end
159
+ end
160
+
157
161
  def puts(*args)
158
162
  output.puts(*args)
159
163
  end
@@ -119,7 +119,7 @@ module Opal
119
119
  dynamic_require_levels = %w[error warning ignore]
120
120
  on('-D', '--dynamic-require LEVEL', dynamic_require_levels,
121
121
  'Set level of dynamic require severity.',
122
- "(deafult: error, values: #{dynamic_require_levels.join(', ')})") do |level|
122
+ "(default: error, values: #{dynamic_require_levels.join(', ')})") do |level|
123
123
  options[:dynamic_require_severity] = level.to_sym
124
124
  end
125
125