opal 0.3.37 → 0.3.38

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 (51) hide show
  1. data/CHANGELOG.md +11 -0
  2. data/Gemfile +0 -8
  3. data/README.md +7 -6
  4. data/bin/opal +18 -10
  5. data/config.ru +8 -21
  6. data/lib/assets/javascripts/opal-parser.js.erb +3 -60
  7. data/lib/assets/javascripts/opal/array.rb +87 -43
  8. data/lib/assets/javascripts/opal/basic_object.rb +4 -0
  9. data/lib/assets/javascripts/opal/boolean.rb +5 -3
  10. data/lib/assets/javascripts/opal/class.rb +19 -4
  11. data/lib/assets/javascripts/opal/comparable.rb +1 -1
  12. data/lib/assets/javascripts/opal/enumerable.rb +32 -0
  13. data/lib/assets/javascripts/opal/error.rb +1 -1
  14. data/lib/assets/javascripts/opal/hash.rb +166 -103
  15. data/lib/assets/javascripts/opal/json.rb +3 -2
  16. data/lib/assets/javascripts/opal/kernel.rb +9 -1
  17. data/lib/assets/javascripts/opal/native.rb +29 -0
  18. data/lib/assets/javascripts/opal/nil_class.rb +9 -1
  19. data/lib/assets/javascripts/opal/numeric.rb +6 -4
  20. data/lib/assets/javascripts/opal/parser.js +57 -0
  21. data/lib/assets/javascripts/opal/proc.rb +5 -5
  22. data/lib/assets/javascripts/opal/regexp.rb +1 -1
  23. data/lib/assets/javascripts/opal/runtime.js +13 -0
  24. data/lib/assets/javascripts/opal/string.rb +14 -3
  25. data/lib/assets/javascripts/opal/time.rb +1 -1
  26. data/lib/opal.rb +1 -1
  27. data/lib/opal/parser.rb +39 -13
  28. data/lib/opal/processor.rb +13 -2
  29. data/lib/opal/version.rb +1 -1
  30. data/opal.gemspec +3 -0
  31. data/spec/core/array/fill_spec.rb +26 -0
  32. data/spec/core/array/try_convert_spec.rb +15 -0
  33. data/spec/core/enumerable/each_slice_spec.rb +24 -0
  34. data/spec/core/enumerable/group_by_spec.rb +16 -0
  35. data/spec/core/module/const_get_spec.rb +34 -0
  36. data/spec/core/module/undef_method_spec.rb +67 -0
  37. data/spec/core/nil/to_h_spec.rb +10 -0
  38. data/spec/core/proc/element_reference_spec.rb +21 -0
  39. data/spec/{core → core_ext}/array/to_json_spec.rb +0 -0
  40. data/spec/core_ext/method_missing_spec.rb +43 -0
  41. data/spec/core_ext/native/fixtures/classes.rb +5 -0
  42. data/spec/core_ext/native/initialize_spec.rb +8 -0
  43. data/spec/core_ext/native/method_missing_spec.rb +7 -0
  44. data/spec/core_ext/native/to_native_spec.rb +7 -0
  45. data/spec/grammar/parser_spec.rb +1 -1
  46. data/spec/language/super_spec.rb +20 -0
  47. data/spec/language/variables_spec.rb +69 -0
  48. data/spec/spec_helper.rb +9 -5
  49. metadata +66 -8
  50. data/lib/assets/javascripts/opal/core.rb +0 -36
  51. data/spec/autorun.rb +0 -3
@@ -9,6 +9,14 @@ module Opal
9
9
  true
10
10
  end
11
11
 
12
+ class << self
13
+ attr_accessor :method_missing_enabled
14
+ attr_accessor :optimized_operators_enabled
15
+ end
16
+
17
+ self.method_missing_enabled = true
18
+ self.optimized_operators_enabled = true
19
+
12
20
  def initialize_engine
13
21
  require_template_library 'opal'
14
22
  end
@@ -18,8 +26,11 @@ module Opal
18
26
  end
19
27
 
20
28
  def evaluate(context, locals, &block)
21
- parser = Opal::Parser.new
22
- result = parser.parse data
29
+ options = { :method_missing => self.class.method_missing_enabled,
30
+ :optimized_operators => self.class.optimized_operators_enabled }
31
+
32
+ parser = Opal::Parser.new
33
+ result = parser.parse data, options
23
34
 
24
35
  parser.requires.each { |r| context.require_asset r }
25
36
  result
data/lib/opal/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Opal
2
- VERSION = '0.3.37'
2
+ VERSION = '0.3.38'
3
3
  end
data/opal.gemspec CHANGED
@@ -16,4 +16,7 @@ Gem::Specification.new do |s|
16
16
  s.require_paths = ['lib']
17
17
 
18
18
  s.add_runtime_dependency 'sprockets'
19
+
20
+ s.add_development_dependency 'opal-spec', '~> 0.2.10'
21
+ s.add_development_dependency 'racc'
19
22
  end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe "Array#fill" do
4
+ it "returns self" do
5
+ ary = [1, 2, 3]
6
+ ary.fill(:a).should equal(ary)
7
+ end
8
+
9
+ it "is destructive" do
10
+ ary = [1, 2, 3]
11
+ ary.fill(:a)
12
+ ary.should == [:a, :a, :a]
13
+ end
14
+
15
+ it "replaces all elements in the array with the filler if not given an index nor a length" do
16
+ ary = ['a', 'b', 'c', 'duh']
17
+ ary.fill(8).should == [8, 8, 8, 8]
18
+
19
+ str = "x"
20
+ ary.fill(str).should == [str, str, str, str]
21
+ end
22
+
23
+ it "replaces all elements with the value of block (index given to block)" do
24
+ [nil, nil, nil, nil].fill { |i| i * 2 }.should == [0, 2, 4, 6]
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ ruby_version_is "1.9" do
5
+ describe "Array.try_convert" do
6
+ it "returns the argument if it's a Array" do
7
+ x = Array.new
8
+ Array.try_convert(x).should equal(x)
9
+ end
10
+
11
+ it "returns nil when the argument does not respond to #to_ary" do
12
+ Array.try_convert(Object.new).should be_nil
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+
3
+ describe "Enumerable#each_slice" do
4
+ before :each do
5
+ @enum = EnumerableSpecs::Numerous.new(7,6,5,4,3,2,1)
6
+ @sliced = [[7,6,5],[4,3,2],[1]]
7
+ end
8
+
9
+ it "passes element groups to the block" do
10
+ acc = []
11
+ @enum.each_slice(3) { |g| acc << g }.should be_nil
12
+ acc.should == @sliced
13
+ end
14
+
15
+ it "works when n is >= full length" do
16
+ full = @enum.to_a
17
+ acc = []
18
+ @enum.each_slice(full.length) { |g| acc << g }
19
+ acc.should == [full]
20
+ acc = []
21
+ @enum.each_slice(full.length + 1) { |g| acc << g }
22
+ acc.should == [full]
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ describe "Enumerable#group_by" do
2
+ it "returns a hash with values grouped according to the block" do
3
+ grouped = [:foo, :bar, :baz].group_by { |word| word[0, 1].to_sym }
4
+ grouped.should == { :f => [:foo], :b => [:bar, :baz] }
5
+ end
6
+
7
+ it "returns an empty hash for empty enumerables" do
8
+ [].group_by { |x| x }.should == {}
9
+ end
10
+
11
+ it "allows nil as a valid key" do
12
+ grouped = [[nil, :foo], [nil, :baz], [42, 100]].group_by { |arr| arr.first }
13
+ grouped[nil].should == [[nil, :foo], [nil, :baz]]
14
+ grouped[42].should == [[42, 100]]
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../../../fixtures/constants', __FILE__)
3
+
4
+ CS_CONST1 = :const1
5
+
6
+ module ConstGetSpecs
7
+ FOO = 100
8
+
9
+ module Bar
10
+ BAR = 200
11
+
12
+ module Baz
13
+ BAZ = 300
14
+ end
15
+ end
16
+ end
17
+
18
+ describe "Module#const_get" do
19
+ it "accepts a String or Symbol name" do
20
+ Object.const_get(:CS_CONST1).should == :const1
21
+ Object.const_get("CS_CONST1").should == :const1
22
+ end
23
+
24
+ it "raises a NameError if no constant is defined in the search path" do
25
+ lambda { Object.const_get :CS_CONSTX_BAD }.should raise_error(NameError)
26
+ end
27
+
28
+ it "searches parent scopes of classes and modules" do
29
+ ConstGetSpecs::Bar::Baz.const_get(:BAZ).should eq(300)
30
+ ConstGetSpecs::Bar::Baz.const_get(:BAR).should eq(200)
31
+ ConstGetSpecs::Bar::Baz.const_get(:FOO).should eq(100)
32
+ ConstGetSpecs::Bar::Baz.const_get(:Bar).should eq(ConstGetSpecs::Bar)
33
+ end
34
+ end
@@ -0,0 +1,67 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+ require File.expand_path('../fixtures/classes', __FILE__)
3
+
4
+ module ModuleSpecs
5
+ class NoInheritance
6
+ def method_to_undef() 1 end
7
+ def another_method_to_undef() 1 end
8
+ end
9
+
10
+ class Parent
11
+ def method_to_undef() 1 end
12
+ def another_method_to_undef() 1 end
13
+ end
14
+
15
+ class Child < Parent
16
+ end
17
+
18
+ class Ancestor
19
+ def method_to_undef() 1 end
20
+ def another_method_to_undef() 1 end
21
+ end
22
+
23
+ class Descendant < Ancestor
24
+ end
25
+ end
26
+
27
+ describe "Module#undef_method with symbol" do
28
+ it "removes a method defined in a class" do
29
+ x = ModuleSpecs::NoInheritance.new
30
+
31
+ x.method_to_undef.should == 1
32
+
33
+ ModuleSpecs::NoInheritance.send :undef_method, :method_to_undef
34
+
35
+ lambda { x.method_to_undef }.should raise_error(NoMethodError)
36
+ end
37
+
38
+ it "removes a method defined in a super class" do
39
+ child = ModuleSpecs::Child.new
40
+ child.method_to_undef.should == 1
41
+
42
+ ModuleSpecs::Child.send :undef_method, :method_to_undef
43
+
44
+ lambda { child.method_to_undef }.should raise_error(NoMethodError)
45
+ end
46
+ end
47
+
48
+ describe "Module#undef_method with string" do
49
+ it "removes a method defined in a class" do
50
+ x = ModuleSpecs::NoInheritance.new
51
+
52
+ x.another_method_to_undef.should == 1
53
+
54
+ ModuleSpecs::NoInheritance.send :undef_method, 'another_method_to_undef'
55
+
56
+ lambda { x.another_method_to_undef }.should raise_error(NoMethodError)
57
+ end
58
+
59
+ it "removes a method defined in a super class" do
60
+ child = ModuleSpecs::Child.new
61
+ child.another_method_to_undef.should == 1
62
+
63
+ ModuleSpecs::Child.send :undef_method, 'another_method_to_undef'
64
+
65
+ lambda { child.another_method_to_undef }.should raise_error(NoMethodError)
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path('../../../spec_helper', __FILE__)
2
+
3
+ ruby_version_is "2.0" do
4
+ describe "NilClass#to_h" do
5
+ it "returns an empty hash" do
6
+ nil.to_h.should == {}
7
+ nil.to_h.default.should == nil
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,21 @@
1
+ describe "Proc#[]" do
2
+ it "invokes self" do
3
+ Proc.new { "test!" }[].should == "test!"
4
+ lambda { "test!" }[].should == "test!"
5
+ proc { "test!" }[].should == "test!"
6
+ end
7
+
8
+ it "sets self's parameters to the given values" do
9
+ Proc.new { |a, b| a + b }[1, 2].should == 3
10
+ Proc.new { |*args| args }[1, 2, 3, 4].should == [1, 2, 3, 4]
11
+ Proc.new { |_, *args| args }[1, 2, 3].should == [2, 3]
12
+
13
+ lambda { |a, b| a + b }[1, 2].should == 3
14
+ lambda { |*args| args }[1, 2, 3, 4].should == [1, 2, 3, 4]
15
+ lambda { |_, *args| args }[1, 2, 3].should == [2, 3]
16
+
17
+ proc { |a, b| a + b }[1, 2].should == 3
18
+ proc { |*args| args }[1, 2, 3, 4].should == [1, 2, 3, 4]
19
+ proc { |_, *args| args }[1, 2, 3].should == [2, 3]
20
+ end
21
+ end
File without changes
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ module MethodMissingSpecs
4
+ class A
5
+ def method_missing(mid, *args)
6
+ [mid, args]
7
+ end
8
+ end
9
+
10
+ class B
11
+ def method_missing(mid, *args, &block)
12
+ [mid, block]
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "method_missing" do
18
+ before do
19
+ @obj = MethodMissingSpecs::A.new
20
+ end
21
+
22
+ it "should pass the missing method name as first argument" do
23
+ @obj.foo.should eq([:foo, []])
24
+ end
25
+
26
+ it "should correctly pass arguments to method_missing" do
27
+ @obj.bar(1, 2, 3).should eq([:bar, [1, 2, 3]])
28
+ end
29
+
30
+ it "should pass blocks to method_missing" do
31
+ obj = MethodMissingSpecs::B.new
32
+ proc = proc { 1 }
33
+ obj.baz(1, 2, &proc).should eq([:baz, proc])
34
+ end
35
+ end
36
+
37
+ describe "BasicObject#method_missing" do
38
+ it "raises an error for the missing method" do
39
+ lambda {
40
+ BasicObject.new.foo_bar_baz
41
+ }.should raise_error(Exception)
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ require "opal/native"
2
+
3
+ class NativeSpecs
4
+ include Native
5
+ end
@@ -0,0 +1,8 @@
1
+ require "spec_helper"
2
+
3
+ describe "Native#initialize" do
4
+ it "raises an error when passed null or undefined" do
5
+ lambda { NativeSpecs.new(`null`) }.should raise_error(Exception)
6
+ lambda { NativeSpecs.new(`undefined`) }.should raise_error(Exception)
7
+ end
8
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe "Native#method_missing" do
4
+ it "forwards methods to wrapped object as native function calls" do
5
+ NativeSpecs.new("adam").toUpperCase.should eq("ADAM")
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require "spec_helper"
2
+
3
+ describe "Native#to_native" do
4
+ it "returns the wrapped object" do
5
+ NativeSpecs.new(:foo).to_native.should eq(:foo)
6
+ end
7
+ end
@@ -22,7 +22,7 @@ describe "Opal::Parser" do
22
22
  it "should parse constant lookups" do
23
23
  opal_eval("Object").should == Object
24
24
  opal_eval("Array").should == Array
25
- opal_eval("OpalSpec::ExampleGroup").should == OpalSpec::ExampleGroup
25
+ opal_eval("Spec::ExampleGroup").should == Spec::ExampleGroup
26
26
  end
27
27
 
28
28
  it "should parse class and module definitions" do
@@ -43,9 +43,29 @@ describe "The super keyword" do
43
43
  it "calls the superclass when initial method is define_method'd" do
44
44
  Super::S7.new.here.should == :good
45
45
  end
46
+
47
+ describe "with no arguments or parens" do
48
+ it "should pass all given arguments in current method to super" do
49
+ Super::NoArgs::B.new.foo(1, 4, 9).should eq([1, 4, 9, 42])
50
+ end
51
+ end
46
52
  end
47
53
 
48
54
  module Super
55
+ module NoArgs
56
+ class A
57
+ def foo(a, b, c)
58
+ [a, b, c]
59
+ end
60
+ end
61
+
62
+ class B < A
63
+ def foo(a, b, c)
64
+ super << 42
65
+ end
66
+ end
67
+ end
68
+
49
69
  module S1
50
70
  class A
51
71
  def foo(a)
@@ -23,6 +23,75 @@ describe "Basic assignment" do
23
23
  a = *[[]]; a.should == [[]]
24
24
  a = *[1,2]; a.should == [1,2]
25
25
  end
26
+
27
+ it "sets unavailable values to nil" do
28
+ ary = []
29
+ a, b, c = ary
30
+
31
+ a.should be_nil
32
+ b.should be_nil
33
+ c.should be_nil
34
+ end
35
+
36
+ it "sets the splat to an empty Array if there are no more values" do
37
+ ary = []
38
+ a, b, *c = ary
39
+
40
+ a.should be_nil
41
+ b.should be_nil
42
+ c.should == []
43
+ end
44
+
45
+ it "allows multiple values to be assigned" do
46
+ a,b,*c = nil; [a,b,c].should == [nil, nil, []]
47
+ a,b,*c = 1; [a,b,c].should == [1, nil, []]
48
+ a,b,*c = []; [a,b,c].should == [nil, nil, []]
49
+ a,b,*c = [1]; [a,b,c].should == [1, nil, []]
50
+ a,b,*c = [nil]; [a,b,c].should == [nil, nil, []]
51
+ a,b,*c = [[]]; [a,b,c].should == [[], nil, []]
52
+ a,b,*c = [1,2]; [a,b,c].should == [1,2,[]]
53
+
54
+ a,b,*c = *nil; [a,b,c].should == [nil, nil, []]
55
+ a,b,*c = *[]; [a,b,c].should == [nil, nil, []]
56
+ a,b,*c = *[nil]; [a,b,c].should == [nil, nil, []]
57
+ a,b,*c = *[[]]; [a,b,c].should == [[], nil, []]
58
+ a,b,*c = *[1,2]; [a,b,c].should == [1,2,[]]
59
+ end
60
+
61
+ it "allows assignment through lambda" do
62
+ f = lambda {|r,*l| r.should == []; l.should == [1]}
63
+ f.call([], *[1])
64
+
65
+ f = lambda{|x| x}
66
+ f.call(42).should == 42
67
+ f.call([42]).should == [42]
68
+ f.call([[42]]).should == [[42]]
69
+ f.call([42,55]).should == [42,55]
70
+
71
+ f = lambda{|*x| x}
72
+ f.call(42).should == [42]
73
+ f.call([42]).should == [[42]]
74
+ f.call([[42]]).should == [[[42]]]
75
+ f.call([42,55]).should == [[42,55]]
76
+ f.call(42,55).should == [42,55]
77
+ end
78
+
79
+ it "allows chained assignment" do
80
+ (a = 1 + b = 2 + c = 4 + d = 8).should == 15
81
+ d.should == 8
82
+ c.should == 12
83
+ b.should == 14
84
+ a.should == 15
85
+ end
86
+ end
87
+
88
+ describe "Assignment using expansion" do
89
+ ruby_version_is "1.9" do
90
+ it "succeeds without conversion" do
91
+ *x = (1..7).to_a
92
+ x.should == [1, 2, 3, 4, 5, 6, 7]
93
+ end
94
+ end
26
95
  end
27
96
 
28
97
  describe "Assigning multiple values" do