opal 0.6.3 → 0.7.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.spectator +2 -0
  4. data/.spectator-mspec +3 -0
  5. data/.travis.yml +8 -11
  6. data/CHANGELOG.md +33 -0
  7. data/CONTRIBUTING.md +8 -43
  8. data/Gemfile +15 -4
  9. data/Guardfile +77 -0
  10. data/README.md +15 -9
  11. data/Rakefile +36 -12
  12. data/benchmarks/operators.rb +11 -0
  13. data/bin/opal +10 -13
  14. data/bin/opal-build +4 -4
  15. data/bin/opal-mspec +10 -0
  16. data/bin/opal-repl +4 -3
  17. data/examples/sinatra/Gemfile +1 -1
  18. data/examples/sinatra/config.ru +3 -3
  19. data/lib/mspec/opal/main.rb.erb +2 -2
  20. data/lib/mspec/opal/rake_task.rb +31 -24
  21. data/lib/mspec/opal/runner.rb +18 -1
  22. data/lib/mspec/opal/sprockets.js +17 -0
  23. data/lib/opal.rb +1 -34
  24. data/lib/opal/builder.rb +92 -58
  25. data/lib/opal/builder_processors.rb +165 -0
  26. data/lib/opal/cli.rb +85 -144
  27. data/lib/opal/cli_options.rb +136 -90
  28. data/lib/opal/cli_runners.rb +10 -0
  29. data/lib/opal/cli_runners/nodejs.rb +56 -0
  30. data/lib/opal/cli_runners/phantom.js +35 -0
  31. data/lib/opal/cli_runners/phantomjs.rb +28 -0
  32. data/lib/opal/cli_runners/server.rb +54 -0
  33. data/lib/opal/compiler.rb +35 -16
  34. data/lib/opal/erb.rb +29 -15
  35. data/lib/opal/hike_path_finder.rb +18 -0
  36. data/lib/opal/nodes.rb +1 -0
  37. data/lib/opal/nodes/call.rb +107 -26
  38. data/lib/opal/nodes/call_special.rb +31 -6
  39. data/lib/opal/nodes/class.rb +2 -2
  40. data/lib/opal/nodes/constants.rb +5 -20
  41. data/lib/opal/nodes/def.rb +4 -4
  42. data/lib/opal/nodes/defined.rb +3 -3
  43. data/lib/opal/nodes/definitions.rb +1 -1
  44. data/lib/opal/nodes/for.rb +35 -0
  45. data/lib/opal/nodes/helpers.rb +2 -2
  46. data/lib/opal/nodes/iter.rb +3 -3
  47. data/lib/opal/nodes/literal.rb +10 -2
  48. data/lib/opal/nodes/masgn.rb +2 -2
  49. data/lib/opal/nodes/module.rb +2 -2
  50. data/lib/opal/nodes/scope.rb +1 -0
  51. data/lib/opal/nodes/singleton_class.rb +2 -2
  52. data/lib/opal/nodes/super.rb +2 -2
  53. data/lib/opal/nodes/top.rb +30 -3
  54. data/lib/opal/parser.rb +15 -1
  55. data/lib/opal/parser/grammar.rb +2571 -2452
  56. data/lib/opal/parser/grammar.y +37 -5
  57. data/lib/opal/parser/keywords.rb +2 -0
  58. data/lib/opal/parser/lexer.rb +21 -11
  59. data/lib/opal/path_reader.rb +28 -0
  60. data/lib/opal/paths.rb +38 -0
  61. data/lib/opal/source_map.rb +32 -15
  62. data/lib/opal/sprockets/environment.rb +9 -2
  63. data/lib/opal/sprockets/erb.rb +1 -2
  64. data/lib/opal/sprockets/path_reader.rb +34 -0
  65. data/lib/opal/sprockets/processor.rb +40 -39
  66. data/lib/opal/sprockets/server.rb +47 -33
  67. data/lib/opal/version.rb +1 -1
  68. data/opal.gemspec +10 -5
  69. data/opal/README.md +6 -0
  70. data/opal/corelib/array.rb +36 -4
  71. data/opal/corelib/array/inheritance.rb +6 -6
  72. data/opal/corelib/basic_object.rb +9 -9
  73. data/opal/corelib/boolean.rb +1 -1
  74. data/opal/corelib/class.rb +12 -12
  75. data/opal/corelib/dir.rb +20 -0
  76. data/opal/corelib/enumerable.rb +42 -42
  77. data/opal/corelib/enumerator.rb +1 -1
  78. data/opal/corelib/error.rb +2 -2
  79. data/opal/corelib/file.rb +56 -0
  80. data/opal/corelib/hash.rb +5 -5
  81. data/opal/corelib/helpers.rb +3 -3
  82. data/opal/corelib/io.rb +13 -10
  83. data/opal/corelib/kernel.rb +44 -68
  84. data/opal/corelib/method.rb +1 -1
  85. data/opal/corelib/module.rb +89 -114
  86. data/opal/corelib/nil_class.rb +1 -1
  87. data/opal/corelib/numeric.rb +27 -23
  88. data/opal/corelib/proc.rb +5 -5
  89. data/opal/corelib/range.rb +8 -4
  90. data/opal/corelib/regexp.rb +5 -5
  91. data/opal/corelib/runtime.js +589 -272
  92. data/opal/corelib/string.rb +52 -37
  93. data/opal/corelib/string/inheritance.rb +5 -5
  94. data/opal/corelib/time.rb +102 -52
  95. data/opal/corelib/variables.rb +3 -3
  96. data/opal/opal.rb +2 -0
  97. data/package.json +9 -0
  98. data/spec/filters/bugs/array.rb +0 -6
  99. data/spec/filters/bugs/language.rb +4 -0
  100. data/spec/filters/bugs/numeric.rb +7 -6
  101. data/spec/filters/bugs/opal.rb +2 -0
  102. data/spec/filters/bugs/regexp.rb +4 -0
  103. data/spec/filters/bugs/string.rb +0 -7
  104. data/spec/filters/bugs/stringscanner.rb +4 -1
  105. data/spec/filters/unsupported/private_methods.rb +2 -0
  106. data/spec/lib/builder_processors_spec.rb +27 -0
  107. data/spec/lib/builder_spec.rb +66 -0
  108. data/spec/{cli → lib}/cli_spec.rb +60 -5
  109. data/spec/{cli → lib}/compiler_spec.rb +66 -5
  110. data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
  111. data/spec/lib/fixtures/no_requires.rb +1 -0
  112. data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
  113. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  114. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  115. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  116. data/spec/lib/fixtures/requires.rb +7 -0
  117. data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
  118. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  119. data/spec/lib/hike_path_finder_spec.rb +23 -0
  120. data/spec/{cli → lib}/lexer_spec.rb +1 -1
  121. data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
  122. data/spec/{cli → lib}/parser/and_spec.rb +1 -1
  123. data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
  124. data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
  125. data/spec/{cli → lib}/parser/block_spec.rb +1 -1
  126. data/spec/{cli → lib}/parser/break_spec.rb +1 -1
  127. data/spec/{cli → lib}/parser/call_spec.rb +1 -1
  128. data/spec/{cli → lib}/parser/class_spec.rb +1 -1
  129. data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
  130. data/spec/{cli → lib}/parser/def_spec.rb +1 -1
  131. data/spec/{cli → lib}/parser/if_spec.rb +1 -1
  132. data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
  133. data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
  134. data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
  135. data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
  136. data/spec/{cli → lib}/parser/module_spec.rb +1 -1
  137. data/spec/{cli → lib}/parser/not_spec.rb +1 -1
  138. data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
  139. data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
  140. data/spec/{cli → lib}/parser/or_spec.rb +1 -1
  141. data/spec/{cli → lib}/parser/return_spec.rb +1 -1
  142. data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
  143. data/spec/{cli → lib}/parser/string_spec.rb +8 -1
  144. data/spec/{cli → lib}/parser/super_spec.rb +1 -1
  145. data/spec/lib/parser/unary_spec.rb +48 -0
  146. data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
  147. data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
  148. data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
  149. data/spec/{cli → lib}/parser/while_spec.rb +1 -1
  150. data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
  151. data/spec/lib/path_reader_spec.rb +24 -0
  152. data/spec/lib/shared/path_finder_shared.rb +19 -0
  153. data/spec/lib/shared/path_reader_shared.rb +31 -0
  154. data/spec/lib/spec_helper.rb +9 -0
  155. data/spec/lib/sprockets/environment_spec.rb +30 -0
  156. data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
  157. data/spec/lib/sprockets/path_reader_spec.rb +25 -0
  158. data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
  159. data/spec/lib/sprockets/server_spec.rb +20 -0
  160. data/spec/opal/compiler/irb_spec.rb +11 -11
  161. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  162. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  163. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  164. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  165. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  166. data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
  167. data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
  168. data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
  169. data/spec/opal/core/source_map_spec.rb +2 -2
  170. data/spec/opal/core/string_spec.rb +11 -0
  171. data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
  172. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  173. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  174. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  175. data/spec/rubyspecs +54 -11
  176. data/spec/spec_helper.rb +18 -3
  177. data/spec/support/mspec_rspec_adapter.rb +33 -0
  178. data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
  179. data/stdlib/README.md +3 -0
  180. data/stdlib/benchmark.rb +10 -0
  181. data/stdlib/date.rb +2 -2
  182. data/stdlib/dir.rb +1 -5
  183. data/stdlib/file.rb +1 -7
  184. data/stdlib/json.rb +10 -1
  185. data/stdlib/native.rb +5 -5
  186. data/stdlib/nodejs.rb +5 -0
  187. data/stdlib/nodejs/dir.rb +13 -0
  188. data/stdlib/nodejs/file.rb +98 -0
  189. data/stdlib/nodejs/fileutils.rb +26 -0
  190. data/stdlib/nodejs/io.rb +2 -0
  191. data/stdlib/nodejs/irb.rb +45 -0
  192. data/stdlib/nodejs/process.rb +16 -0
  193. data/stdlib/nodejs/require.rb +32 -0
  194. data/stdlib/nodejs/rubygems.rb +68 -0
  195. data/stdlib/nodejs/runtime.rb +25 -0
  196. data/stdlib/nodejs/yaml.rb +11 -0
  197. data/stdlib/opal-parser.rb +1 -2
  198. data/stdlib/opal-source-maps.rb +2 -0
  199. data/stdlib/phantomjs.rb +8 -0
  200. data/stdlib/process.rb +10 -0
  201. data/stdlib/promise.rb +12 -4
  202. data/stdlib/set.rb +27 -0
  203. data/stdlib/source_map.rb +5 -63
  204. data/stdlib/source_map/map.rb +220 -0
  205. data/stdlib/source_map/mapping.rb +26 -0
  206. data/stdlib/source_map/offset.rb +88 -0
  207. data/stdlib/source_map/version.rb +3 -0
  208. data/stdlib/source_map/vlq.rb +77 -101
  209. data/stdlib/sourcemap.rb +1 -0
  210. data/stdlib/strscan.rb +7 -1
  211. data/stdlib/template.rb +1 -1
  212. data/stdlib/thread.rb +147 -7
  213. metadata +238 -104
  214. data/lib/mspec/opal/mspec_fixes.rb +0 -87
  215. data/spec/cli/sprockets/environment_spec.rb +0 -14
  216. data/spec/filters/bugs/symbol.rb +0 -5
  217. data/spec/opal/core/kernel/warn_spec.rb +0 -83
  218. data/spec/opal/core/language/numbers_spec.rb +0 -60
  219. data/stdlib/opal-source-maps.js.erb +0 -2
  220. data/stdlib/source_map/generator.rb +0 -251
  221. data/stdlib/source_map/parser.rb +0 -102
@@ -1,9 +1,9 @@
1
1
  # regexp matches
2
2
  $& = $~ = $` = $' = nil
3
3
 
4
- # stub library path
5
- $: = []
6
- $" = []
4
+ # requires
5
+ $LOADED_FEATURES = $" = `Opal.loaded_features`
6
+ $LOAD_PATH = $: = []
7
7
 
8
8
  # split lines
9
9
  $/ = "\n"
data/opal/opal.rb CHANGED
@@ -28,3 +28,5 @@ require 'corelib/struct'
28
28
  require 'corelib/io'
29
29
  require 'corelib/main'
30
30
  require 'corelib/variables'
31
+ require 'corelib/dir'
32
+ require 'corelib/file'
data/package.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "dependencies": {
3
+ "glob": "latest",
4
+ "js-yaml": "latest"
5
+ },
6
+ "devDependencies": {
7
+ "doxx": "latest"
8
+ }
9
+ }
@@ -213,13 +213,7 @@ opal_filter "Array" do
213
213
  fails "Array#partition returns two arrays"
214
214
  fails "Array#partition does not return subclass instances on Array subclasses"
215
215
 
216
- fails "Array#| does not call to_ary on array subclasses"
217
- fails "Array#| does not return subclass instances for Array subclasses"
218
216
  fails "Array#| acts as if using an intermediate hash to collect values"
219
- fails "Array#| tries to convert the passed argument to an Array using #to_ary"
220
- fails "Array#| creates an array with elements in order they are first encountered"
221
- fails "Array#| creates an array with no duplicates"
222
- fails "Array#| returns an array of elements that appear in either array (union)"
223
217
 
224
218
  # recursive arrays
225
219
  fails "Array#join raises an ArgumentError when the Array is recursive"
@@ -320,6 +320,7 @@ opal_filter "language" do
320
320
  fails "The super keyword raises an error error when super method does not exist"
321
321
  fails "The super keyword calls the correct method when the superclass argument list is different from the subclass"
322
322
  fails "The super keyword respects the original module a method is aliased from"
323
+ fails "The super keyword raises a RuntimeError when called with implicit arguments from a method defined with define_method"
323
324
 
324
325
  fails "The until modifier with begin .. end block restart the current iteration without reevaluting condition with redo"
325
326
  fails "The until modifier with begin .. end block skips to end of body with next"
@@ -408,4 +409,7 @@ opal_filter "language" do
408
409
  fails "The defined? keyword for super for a method taking no arguments returns nil from a block in a #define_method when no superclass method exists"
409
410
  fails "The defined? keyword for super for a method taking arguments returns nil from a #define_method when no superclass method exists"
410
411
  fails "The defined? keyword for super for a method taking arguments returns nil from a block in a #define_method when no superclass method exists"
412
+
413
+ fails "The __FILE__ pseudo-variable equals the absolute path of a file loaded by an absolute path" # we can't clear $LOADED_FEATURES, should be treated as readonly
414
+ fails "The __FILE__ pseudo-variable equals the absolute path of a file loaded by a relative path" # we can't clear $LOADED_FEATURES, should be treated as readonly
411
415
  end
@@ -6,14 +6,15 @@ opal_filter "Fixnum bugs" do
6
6
  fails "Fixnum#zero? returns true if self is 0"
7
7
  end
8
8
 
9
- opal_filter "Fixnum#<< doesn't handle non-integers" do
10
- fails "Fixnum#<< with n << m raises a TypeError when passed a String"
11
- fails "Fixnum#<< with n << m raises a TypeError when passed nil"
12
- fails "Fixnum#<< with n << m raises a TypeError when #to_int does not return an Integer"
9
+ opal_filter "Fixnum#<< doesn't handle Bignum and large number checks" do
13
10
  fails "Fixnum#<< with n << m returns a Bignum == fixnum_min() * 2 when fixnum_min() << 1 and n < 0"
14
11
  fails "Fixnum#<< with n << m returns a Bignum == fixnum_max() * 2 when fixnum_max() << 1 and n > 0"
15
12
  fails "Fixnum#<< with n << m returns 0 when m < 0 and m is a Bignum"
16
13
  fails "Fixnum#<< with n << m returns 0 when m < 0 and m == p where 2**p > n >= 2**(p-1)"
17
- fails "Fixnum#<< with n << m returns n shifted right m bits when n < 0, m < 0"
18
- fails "Fixnum#<< with n << m returns n shifted right m bits when n > 0, m < 0"
14
+ end
15
+
16
+ opal_filter "Fixnum#>> doesn't handle Bignum" do
17
+ fails "Fixnum#>> with n >> m returns a Bignum == fixnum_max() * 2 when fixnum_max() >> -1 and n > 0"
18
+ fails "Fixnum#>> with n >> m returns a Bignum == fixnum_min() * 2 when fixnum_min() >> -1 and n < 0"
19
+ fails "Fixnum#>> with n >> m returns 0 when m is a Bignum"
19
20
  end
@@ -9,4 +9,6 @@ opal_filter "Opal bugs" do
9
9
  fails "String#index with Regexp supports \\G which matches at the given start offset"
10
10
  fails "String#index with Regexp starts the search at the given offset"
11
11
  fails "String#index with Regexp returns the index of the first match of regexp"
12
+
13
+ fails "Kernel#warn requires multiple arguments"
12
14
  end
@@ -1,7 +1,11 @@
1
1
  opal_filter "RegExp" do
2
+ fails "Regexp#eql? is true if self and other have the same character set code"
3
+ fails "Regexp#== is true if self and other have the same character set code"
2
4
  fails "Regexp#~ matches against the contents of $_"
3
5
  fails "Regexp#match uses the start as a character offset"
4
6
  fails "Regexp#match matches the input at a given position"
5
7
  fails "Regexp#match with [string, position] when given a positive position matches the input at a given position"
6
8
  fails "Regexp#match with [string, position] when given a negative position matches the input at a given position"
9
+ fails "MatchData#regexp returns the pattern used in the match"
10
+ fails "MatchData#values_at when passed a Range returns an array of the matching value"
7
11
  end
@@ -192,14 +192,7 @@ opal_filter "String" do
192
192
  fails "String#sub with pattern, replacement replaces \\' with everything after the current match"
193
193
  fails "String#sub with pattern, replacement replaces \\+ with the last paren that actually matched"
194
194
  fails "String#sub with pattern, replacement treats \\+ as an empty string if there was no captures"
195
- fails "String#sub with pattern, replacement maps \\\\ in replacement to \\"
196
- fails "String#sub with pattern, replacement tries to convert pattern to a string using to_str"
197
- fails "String#sub with pattern, replacement tries to convert pattern to a string using to_str"
198
- fails "String#sub with pattern, replacement raises a TypeError when pattern can't be converted to a string"
199
- fails "String#sub with pattern, replacement raises a TypeError when replacement can't be converted to a string"
200
195
  fails "String#sub with pattern, replacement sets $~ to MatchData of match and nil when there's none"
201
- fails "String#sub with pattern, replacement replaces \\1 with 1"
202
- fails "String#sub with pattern, replacement replaces \\\\1 with \\1"
203
196
  fails "String#sub with pattern and block sets $~ for access from the block"
204
197
  fails "String#sub with pattern and block sets $~ to MatchData of last match and nil when there's none for access from outside"
205
198
  fails "String#sub with pattern and block doesn't raise a RuntimeError if the string is modified while substituting"
@@ -2,7 +2,7 @@ opal_filter "StringScanner" do
2
2
  fails "StringScanner#[] calls to_int on the given index"
3
3
  fails "StringScanner#[] raises a TypeError if the given index is nil"
4
4
  fails "StringScanner#[] raises a TypeError when a Range is as argument"
5
- fails "StringScanner#[] raises a TypeError when a String is as argument"
5
+ fails "StringScanner#[] raises a TypeError when a String is as argument"
6
6
 
7
7
  fails "StringScanner#get_byte is not multi-byte character sensitive"
8
8
 
@@ -16,4 +16,7 @@ opal_filter "StringScanner" do
16
16
 
17
17
  fails "StringScanner#scan returns the matched string for a multi byte string"
18
18
  fails "StringScanner#scan raises a TypeError if pattern isn't a Regexp"
19
+
20
+ fails "StringScanner#pos= can poin position that greater than string length for multibyte string"
21
+ fails "StringScanner#pos= positions from the end if the argument is negative for multibyte string"
19
22
  end
@@ -39,4 +39,6 @@ opal_filter "Private methods" do
39
39
  fails "Class#initialize is private"
40
40
 
41
41
  fails "Math#atanh is a private instance method"
42
+
43
+ fails "Kernel#warn is a private method"
42
44
  end
@@ -0,0 +1,27 @@
1
+ require 'lib/spec_helper'
2
+ require 'opal/builder_processors'
3
+
4
+ describe Opal::Builder::RubyProcessor do
5
+ it 'compiles ruby to js' do
6
+ processor = described_class.new('puts 5', '-e')
7
+ expect(processor.to_s).to include('$puts(5)')
8
+ end
9
+
10
+ describe ':requirable option' do
11
+ it 'is respected' do
12
+ processor = described_class.new('puts 5', '-e', requirable: true)
13
+ expect(processor.to_s).to include('Opal.modules[')
14
+ end
15
+
16
+ it 'defaults to "false"' do
17
+ processor = described_class.new('puts 5', '-e')
18
+ expect(processor.to_s).not_to include('Opal.modules[')
19
+ end
20
+ end
21
+
22
+ it 'fills required_trees' do
23
+ processor = described_class.new('require_tree "./pippo"', '-e')
24
+ expect(processor.required_trees).to eq(['pippo'])
25
+ end
26
+ end
27
+
@@ -0,0 +1,66 @@
1
+ require 'lib/spec_helper'
2
+ require 'opal/builder'
3
+ require 'lib/shared/path_reader_shared'
4
+
5
+ describe Opal::Builder do
6
+ subject(:builder) { described_class.new(options) }
7
+ let(:options) { {} }
8
+
9
+ it 'compiles opal' do
10
+ expect(builder.build('opal').to_s).to match('(Opal);')
11
+ end
12
+
13
+ it 'respect #require_tree calls' do
14
+ begin
15
+ Opal.append_path(File.expand_path('..', __FILE__))
16
+ expect(builder.build('fixtures/require_tree_test').to_s).to include('Opal.modules["fixtures/required_tree_test/required_file1"]')
17
+ ensure
18
+ Opal.instance_variable_set('@paths', nil)
19
+ end
20
+ end
21
+
22
+ describe ':stubs' do
23
+ let(:options) { {stubs: ['foo']} }
24
+
25
+ it 'compiles them as empty files' do
26
+ source = 'require "foo"'
27
+ expect(builder.default_processor).to receive('new').with(source, anything, anything).once.and_call_original
28
+ expect(builder.default_processor).to receive('new').with('', anything, anything).once.and_call_original
29
+
30
+ builder.build_str(source, 'bar.rb')
31
+ end
32
+ end
33
+
34
+ describe ':prerequired' do
35
+ let(:options) { {prerequired: ['foo']} }
36
+
37
+ it 'compiles them as empty files' do
38
+ source = 'require "foo"'
39
+ builder.build_str(source, 'bar.rb')
40
+ end
41
+ end
42
+
43
+ describe ':preload' do
44
+ let(:options) { {preload: ['base64']} }
45
+
46
+ it 'compiles them as empty files' do
47
+ source = 'puts 5'
48
+ expect(builder.default_processor).to receive('new').with(anything, 'base64', anything).once.and_call_original
49
+ expect(builder.default_processor).to receive('new').with(source, anything, anything).once.and_call_original
50
+
51
+ builder.build_str(source, 'bar.rb')
52
+ end
53
+ end
54
+
55
+ describe 'requiring a native .js file' do
56
+ it 'can be required without specifying extension' do
57
+ builder.build_str('require "corelib/runtime"', 'foo')
58
+ expect(builder.to_s).to start_with('(function(undefined)')
59
+ end
60
+
61
+ it 'can be required specifying extension' do
62
+ builder.build_str('require "corelib/runtime.js"', 'foo')
63
+ expect(builder.to_s).to start_with('(function(undefined)')
64
+ end
65
+ end
66
+ end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../spec_helper', __FILE__)
1
+ require 'lib/spec_helper'
2
2
  require 'opal/cli'
3
3
  require 'stringio'
4
4
 
@@ -9,7 +9,7 @@ describe Opal::CLI do
9
9
  subject(:cli) { described_class.new(options) }
10
10
 
11
11
  context 'with a file' do
12
- let(:options) { {:filename => file} }
12
+ let(:options) { {:file => File.open(file)} }
13
13
 
14
14
  it 'runs the file' do
15
15
  expect_output_of{ subject.run }.to eq("hi from opal!\n")
@@ -58,6 +58,56 @@ describe Opal::CLI do
58
58
  end
59
59
  end
60
60
 
61
+ describe ':gems options' do
62
+ context 'with a Gem name' do
63
+ let(:dir) { File.dirname(file) }
64
+ let(:filename) { File.basename(file) }
65
+ let(:gem_name) { 'mspec' }
66
+ let(:options) { {:gems => [gem_name], :evals => ['']} }
67
+
68
+ it "adds the gem's lib paths to Opal.path" do
69
+ cli.run
70
+
71
+ spec = Gem::Specification.find_by_name(gem_name)
72
+ spec.require_paths.each do |require_path|
73
+ require_path = File.join(spec.gem_dir, require_path)
74
+ expect(Opal.paths).to include(require_path)
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ describe ':stubs options' do
81
+ context 'with a stubbed file' do
82
+ let(:dir) { File.dirname(file) }
83
+ let(:filename) { File.basename(file) }
84
+ let(:stub_name) { 'an_unparsable_lib' }
85
+ let(:options) { {:stubs => [stub_name], :evals => ["require #{stub_name.inspect}"]} }
86
+
87
+ it "adds the gem's lib paths to Opal.path" do
88
+ expect_output_of{ subject.run }.to eq('')
89
+ end
90
+ end
91
+ end
92
+
93
+ describe ':verbose option' do
94
+ let(:options) { {:verbose => true, :evals => ['']} }
95
+
96
+ it 'sets the verbose flag (currently unused)' do
97
+ expect(cli.verbose).to eq(true)
98
+ end
99
+ end
100
+
101
+ describe ':compile option' do
102
+ let(:options) { {:compile => true, :evals => ['puts 5']} }
103
+
104
+ it 'outputs the compiled javascript' do
105
+ expect_output_of{ subject.run }.to include(".$puts(5)")
106
+ expect_output_of{ subject.run }.not_to include("5\n")
107
+ end
108
+ end
109
+
110
+
61
111
  describe ':load_paths options' do
62
112
  let(:dir) { File.dirname(file) }
63
113
  let(:filename) { File.basename(file) }
@@ -68,11 +118,16 @@ describe Opal::CLI do
68
118
  end
69
119
 
70
120
  def expect_output_of
121
+ @output, _result = output_and_result_of { yield }
122
+ expect(@output)
123
+ end
124
+
125
+ def output_and_result_of
71
126
  stdout = described_class.stdout
72
127
  described_class.stdout = fake_stdout
73
- yield
74
- @output = fake_stdout.tap(&:rewind).read
75
- expect(@output)
128
+ result = yield
129
+ output = fake_stdout.tap(&:rewind).read
130
+ return output, result
76
131
  ensure
77
132
  described_class.stdout = stdout
78
133
  end
@@ -1,6 +1,25 @@
1
- require File.expand_path('../spec_helper', __FILE__)
1
+ require 'lib/spec_helper'
2
2
 
3
3
  describe Opal::Compiler do
4
+ describe 'requiring' do
5
+ it 'calls #require' do
6
+ expect_compiled("require 'pippo'").to include('self.$require("pippo")')
7
+ end
8
+ end
9
+
10
+ describe 'requirable' do
11
+ it 'executes the file' do
12
+ expect_compiled("").to include('(function($opal) {')
13
+ expect_compiled("").to end_with("})(Opal);\n")
14
+ end
15
+
16
+ it 'puts the compiled into "Opal.modules"' do
17
+ options = { :requirable => true, :file => "pippo" }
18
+ expect_compiled("", options).to include('Opal.modules["pippo"] = function($opal) {')
19
+ expect_compiled("", options).to end_with("};\n")
20
+ end
21
+ end
22
+
4
23
  it "should compile simple ruby values" do
5
24
  expect_compiled("3.142").to include("return 3.142")
6
25
  expect_compiled("123e1").to include("return 1230")
@@ -21,8 +40,8 @@ describe Opal::Compiler do
21
40
  end
22
41
 
23
42
  it "should compile constant lookups" do
24
- expect_compiled("Object").to include("scope.Object")
25
- expect_compiled("Array").to include("scope.Array")
43
+ expect_compiled("Object").to include("Object")
44
+ expect_compiled("Array").to include("Array")
26
45
  end
27
46
 
28
47
  describe "class names" do
@@ -130,7 +149,49 @@ describe Opal::Compiler do
130
149
  end
131
150
  end
132
151
 
133
- def expect_compiled(source)
134
- expect(Opal::Compiler.new.compile source)
152
+ describe 'pre-processing require-ish methods' do
153
+ describe '#require' do
154
+ it 'parses and resolve #require argument' do
155
+ compiler = compiler_for(%Q{require "#{__FILE__}"})
156
+ expect(compiler.requires).to eq([__FILE__])
157
+ end
158
+ end
159
+
160
+ describe '#autoload' do
161
+ it 'ignores autoload outside of context class' do
162
+ compiler = compiler_for(%Q{autoload Whatever, "#{__FILE__}"})
163
+ expect(compiler.requires).to eq([])
164
+ end
165
+
166
+ it 'parses and resolve second #autoload arguments' do
167
+ compiler = compiler_for(%Q{class Foo; autoload Whatever, "#{__FILE__}"; end})
168
+ expect(compiler.requires).to eq([__FILE__])
169
+ end
170
+ end
171
+
172
+ describe '#require_relative' do
173
+ it 'parses and resolve #require_relative argument' do
174
+ compiler = compiler_for(%Q{require_relative "./#{File.basename(__FILE__)}"}, file: __FILE__)
175
+ expect(compiler.requires).to eq([__FILE__])
176
+ end
177
+ end
178
+
179
+ describe '#require_tree' do
180
+ require 'pathname'
181
+ let(:file) { Pathname(__FILE__).join('../fixtures/require_tree_test.rb') }
182
+
183
+ it 'parses and resolve #require argument' do
184
+ compiler = compiler_for(file.read)
185
+ expect(compiler.required_trees).to eq(['../fixtures/required_tree_test'])
186
+ end
187
+ end
188
+ end
189
+
190
+ def expect_compiled(*args)
191
+ expect(Opal::Compiler.new(*args).compile)
192
+ end
193
+
194
+ def compiler_for(*args)
195
+ Opal::Compiler.new(*args).tap(&:compile)
135
196
  end
136
197
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../spec_helper.rb', __FILE__)
1
+ require 'lib/spec_helper'
2
2
 
3
3
  describe Opal::Nodes::CallNode::DependencyResolver do
4
4
  let(:compiler) { double(:compiler, :dynamic_require_severity => :none) }
@@ -0,0 +1 @@
1
+ puts 'hi there'
File without changes
@@ -0,0 +1,3 @@
1
+ require_tree '../fixtures/required_tree_test'
2
+
3
+ puts 5