mustang 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/README.md +11 -1
  2. data/Rakefile +1 -1
  3. data/TODO.md +2 -1
  4. data/ext/v8/extconf.rb +3 -1
  5. data/ext/v8/v8_array.cpp +2 -0
  6. data/ext/v8/v8_context.cpp +32 -5
  7. data/ext/v8/v8_date.cpp +1 -0
  8. data/ext/v8/v8_external.cpp +1 -0
  9. data/ext/v8/v8_function.cpp +3 -0
  10. data/ext/v8/v8_integer.cpp +1 -0
  11. data/ext/v8/v8_macros.h +6 -0
  12. data/ext/v8/v8_main.cpp +3 -1
  13. data/ext/v8/v8_number.cpp +1 -0
  14. data/ext/v8/v8_object.cpp +2 -0
  15. data/ext/v8/v8_regexp.cpp +1 -0
  16. data/ext/v8/v8_string.cpp +1 -0
  17. data/ext/v8/v8_value.cpp +2 -0
  18. data/lib/mustang.rb +20 -27
  19. data/lib/mustang/context.rb +0 -26
  20. data/lib/{core_ext → mustang/core_ext}/class.rb +1 -1
  21. data/lib/{core_ext → mustang/core_ext}/object.rb +2 -4
  22. data/lib/{core_ext → mustang/core_ext}/symbol.rb +0 -0
  23. data/lib/{support → mustang/support}/delegated.rb +0 -0
  24. data/lib/mustang/v8/array.rb +21 -0
  25. data/lib/mustang/v8/context.rb +15 -0
  26. data/lib/mustang/v8/date.rb +20 -0
  27. data/lib/mustang/v8/error.rb +17 -0
  28. data/lib/mustang/v8/external.rb +16 -0
  29. data/lib/mustang/v8/function.rb +13 -0
  30. data/lib/mustang/v8/integer.rb +16 -0
  31. data/lib/mustang/v8/number.rb +16 -0
  32. data/lib/mustang/v8/object.rb +66 -0
  33. data/lib/mustang/v8/regexp.rb +23 -0
  34. data/lib/mustang/v8/string.rb +27 -0
  35. data/mustang.gemspec +1 -1
  36. data/spec/{core_ext → mustang/core_ext}/class_spec.rb +3 -3
  37. data/spec/{core_ext → mustang/core_ext}/object_spec.rb +3 -3
  38. data/spec/{core_ext → mustang/core_ext}/symbol_spec.rb +1 -1
  39. data/spec/{v8 → mustang/v8}/array_spec.rb +12 -5
  40. data/spec/{v8 → mustang/v8}/cast_spec.rb +10 -10
  41. data/spec/{v8 → mustang/v8}/context_spec.rb +52 -6
  42. data/spec/{v8 → mustang/v8}/data_spec.rb +4 -4
  43. data/spec/{v8 → mustang/v8}/date_spec.rb +12 -5
  44. data/spec/{v8 → mustang/v8}/empty_spec.rb +4 -4
  45. data/spec/{v8 → mustang/v8}/errors_spec.rb +9 -9
  46. data/spec/{v8 → mustang/v8}/external_spec.rb +14 -7
  47. data/spec/{v8 → mustang/v8}/function_spec.rb +20 -13
  48. data/spec/{v8 → mustang/v8}/integer_spec.rb +13 -6
  49. data/spec/{v8 → mustang/v8}/main_spec.rb +2 -2
  50. data/spec/{v8 → mustang/v8}/null_spec.rb +4 -4
  51. data/spec/{v8 → mustang/v8}/number_spec.rb +5 -5
  52. data/spec/{v8 → mustang/v8}/object_spec.rb +13 -6
  53. data/spec/mustang/v8/primitive_spec.rb +9 -0
  54. data/spec/{v8 → mustang/v8}/regexp_spec.rb +12 -5
  55. data/spec/{v8 → mustang/v8}/string_spec.rb +12 -5
  56. data/spec/{v8 → mustang/v8}/undefined_spec.rb +4 -4
  57. data/spec/mustang/v8/value_spec.rb +222 -0
  58. data/spec/spec_helper.rb +1 -1
  59. metadata +91 -62
  60. data/lib/v8/array.rb +0 -21
  61. data/lib/v8/context.rb +0 -13
  62. data/lib/v8/date.rb +0 -20
  63. data/lib/v8/error.rb +0 -15
  64. data/lib/v8/external.rb +0 -16
  65. data/lib/v8/function.rb +0 -11
  66. data/lib/v8/integer.rb +0 -16
  67. data/lib/v8/number.rb +0 -16
  68. data/lib/v8/object.rb +0 -66
  69. data/lib/v8/regexp.rb +0 -23
  70. data/lib/v8/string.rb +0 -27
  71. data/spec/v8/primitive_spec.rb +0 -9
  72. data/spec/v8/value_spec.rb +0 -215
@@ -0,0 +1,17 @@
1
+ module Mustang
2
+ module V8
3
+ class Error
4
+ def inspect
5
+ "#{name}: #{message}"
6
+ end
7
+
8
+ def to_s
9
+ message
10
+ end
11
+
12
+ def name
13
+ self.class.name.delete("Mustang::V8::")
14
+ end
15
+ end # Error
16
+ end # V8
17
+ end # Mustang
@@ -0,0 +1,16 @@
1
+ module Mustang
2
+ module V8
3
+ class External
4
+ include Comparable
5
+ include Delegated
6
+
7
+ def <=>(other)
8
+ to_obj <=> other
9
+ end
10
+
11
+ def delegate
12
+ to_obj
13
+ end
14
+ end # External
15
+ end # V8
16
+ end # Mustang
@@ -0,0 +1,13 @@
1
+ module Mustang
2
+ module V8
3
+ class Function
4
+ def call(*args, &block)
5
+ call_on(@receiver, *args, &block);
6
+ end
7
+
8
+ def to_proc
9
+ origin.to_proc if origin
10
+ end
11
+ end # Function
12
+ end # V8
13
+ end # Mustang
@@ -0,0 +1,16 @@
1
+ module Mustang
2
+ module V8
3
+ class Integer
4
+ include Comparable
5
+ include Delegated
6
+
7
+ def <=>(other)
8
+ to_i <=> other
9
+ end
10
+
11
+ def delegate
12
+ to_i
13
+ end
14
+ end # Integer
15
+ end # V8
16
+ end # Mustang
@@ -0,0 +1,16 @@
1
+ module Mustang
2
+ module V8
3
+ class Number
4
+ include Comparable
5
+ include Delegated
6
+
7
+ def <=>(other)
8
+ to_f <=> other
9
+ end
10
+
11
+ def delegate
12
+ to_f
13
+ end
14
+ end # Number
15
+ end # V8
16
+ end # Mustang
@@ -0,0 +1,66 @@
1
+ module Mustang
2
+ module V8
3
+ class Object
4
+ # We have to extend native <tt>.new</tt> method with full support for reflection
5
+ # of ruby objects.
6
+ class << self
7
+ alias_method :native_new, :new
8
+
9
+ def new(*args, &block)
10
+ res = native_new(*args)
11
+ res.send(:reflect_from, args.first)
12
+ end
13
+ end
14
+
15
+ def respond_to?(meth) # :nodoc:
16
+ !self[meth].undefined? or super
17
+ end
18
+
19
+ def method_missing(meth, *args, &block) # :nodoc:
20
+ if respond_to?(meth)
21
+ property = self[meth]
22
+ if property.is_a?(Function)
23
+ return property.call_on(self, *args, &block)
24
+ else
25
+ return property
26
+ end
27
+ end
28
+ super
29
+ end
30
+
31
+ include Comparable
32
+ include Enumerable
33
+ include Delegated
34
+
35
+ def to_hash
36
+ Hash[*keys.map {|key| [key.to_s, get(key)] }.flatten(1)]
37
+ end
38
+
39
+ def <=>(other)
40
+ to_hash <=> other
41
+ end
42
+
43
+ def each(*args, &block)
44
+ to_hash.each(*args, &block)
45
+ end
46
+
47
+ def delegate
48
+ to_hash
49
+ end
50
+
51
+ private
52
+
53
+ def reflect_from(obj) # :nodoc:
54
+ if !obj.nil? and !obj.v8? and !obj.is_a?(Hash)
55
+ obj.class.declared_methods.each { |meth|
56
+ if func_name = meth.to_sym.to_js_func_name
57
+ func = set(func_name, obj.method(meth))
58
+ func.bind(obj)
59
+ end
60
+ }
61
+ end
62
+ self
63
+ end
64
+ end # Object
65
+ end # V8
66
+ end # Mustang
@@ -0,0 +1,23 @@
1
+ module Mustang
2
+ module V8
3
+ class Regexp
4
+ include Delegated
5
+
6
+ def ==(other)
7
+ to_regexp == other
8
+ end
9
+
10
+ def ===(other)
11
+ to_regexp == other
12
+ end
13
+
14
+ def delegate
15
+ to_regexp
16
+ end
17
+
18
+ def to_regexp
19
+ ::Regexp.new(source, options)
20
+ end
21
+ end # Regexp
22
+ end # V8
23
+ end # Mustang
@@ -0,0 +1,27 @@
1
+ module Mustang
2
+ module V8
3
+ class String
4
+ # On ruby 1.9+ we have to force UTF-8 encoding here...
5
+ if RUBY_VERSION > "1.9"
6
+ alias_method :native_to_utf8, :to_utf8
7
+
8
+ def to_utf8
9
+ native_to_utf8.force_encoding("UTF-8")
10
+ end
11
+ end
12
+
13
+ alias_method :to_s, :to_utf8
14
+
15
+ include Comparable
16
+ include Delegated
17
+
18
+ def <=>(other)
19
+ to_s <=> other
20
+ end
21
+
22
+ def delegate
23
+ to_s
24
+ end
25
+ end # String
26
+ end # V8
27
+ end # Mustang
@@ -3,7 +3,7 @@
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "mustang"
5
5
  s.summary = "Awesome V8 JavaScript engine embedded into the Ruby's shiny body"
6
- s.version = "0.1.1"
6
+ s.version = "0.2.0"
7
7
  s.authors = ["Chris Kowalik", "Cubox"]
8
8
  s.description = "Ruby proxy library for Google V8 Javascript engine."
9
9
  s.homepage = "http://github.com/nu7hatch/mustang"
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe Class do
4
4
  describe "#declared_methods" do
@@ -12,8 +12,8 @@ describe Class do
12
12
  attr_reader :bar
13
13
  end
14
14
 
15
- First.declared_methods.should == [:foo, :foo=, :to_s]
16
- Second.declared_methods.should == [:bar, :foo, :foo=, :to_s]
15
+ First.declared_methods.should =~ [:foo, :foo=, :to_s]
16
+ Second.declared_methods.should =~ [:bar, :foo, :foo=, :to_s]
17
17
  end
18
18
  end
19
19
  end
@@ -1,10 +1,10 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe Object do
4
4
  setup_context
5
5
 
6
6
  it "includes V8::Cast module" do
7
- Object.included_modules.should include(V8::Cast)
7
+ Object.included_modules.should include(Mustang::V8::Cast)
8
8
  end
9
9
 
10
10
  describe "#v8?" do
@@ -13,7 +13,7 @@ describe Object do
13
13
  end
14
14
 
15
15
  it "returns true when object is reflection from v8" do
16
- V8::Integer.new(1).should be_v8
16
+ Mustang::V8::Integer.new(1).should be_v8
17
17
  end
18
18
  end
19
19
  end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe Class do
4
4
  describe "#to_js_func_name" do
@@ -1,14 +1,21 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
- describe V8::Array do
4
- subject { V8::Array }
3
+ describe Mustang::V8::Array do
4
+ subject { Mustang::V8::Array }
5
5
  setup_context
6
6
 
7
- it "inherits V8::Object" do
8
- subject.new(1,2,3).should be_kind_of(V8::Object)
7
+ it "inherits Mustang::V8::Object" do
8
+ subject.new(1,2,3).should be_kind_of(Mustang::V8::Object)
9
9
  end
10
10
 
11
11
  describe ".new" do
12
+ context "when no context entered" do
13
+ it "should raise error" do
14
+ Mustang::V8::Context.exit_all!
15
+ expect { subject.new(1,2,3) }.to raise_error(RuntimeError, "can't create V8 object without entering into context")
16
+ end
17
+ end
18
+
12
19
  context "when no params given" do
13
20
  it "creates empty array" do
14
21
  ary = subject.new
@@ -1,15 +1,15 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
- describe V8::Cast do
3
+ describe Mustang::V8::Cast do
4
4
  setup_context
5
5
 
6
6
  describe "#to_v8" do
7
7
  it "converts current object to v8 compilant" do
8
- [1,2,3].to_v8.should be_kind_of(V8::Array)
9
- 1.to_v8.should be_kind_of(V8::Integer)
10
- "foo".to_v8.should be_kind_of(V8::String)
11
- (1.5).to_v8.should be_kind_of(V8::Number)
12
- {:foo => 1}.to_v8.should be_kind_of(V8::Object)
8
+ [1,2,3].to_v8.should be_kind_of(Mustang::V8::Array)
9
+ 1.to_v8.should be_kind_of(Mustang::V8::Integer)
10
+ "foo".to_v8.should be_kind_of(Mustang::V8::String)
11
+ (1.5).to_v8.should be_kind_of(Mustang::V8::Number)
12
+ {:foo => 1}.to_v8.should be_kind_of(Mustang::V8::Object)
13
13
  end
14
14
  end
15
15
  end
@@ -20,13 +20,13 @@ describe "Typecasting" do
20
20
  context "from js to ruby" do
21
21
  it "converts null properly" do
22
22
  null = cxt.eval("null", "<eval>")
23
- null.should == V8::Null
23
+ null.should == Mustang::V8::Null
24
24
  null.should be_null
25
25
  end
26
26
 
27
27
  it "converts undefined value to nil" do
28
28
  undefined = cxt.eval("undefined", "<eval>")
29
- undefined.should == V8::Undefined
29
+ undefined.should == Mustang::V8::Undefined
30
30
  undefined.should be_undefined
31
31
  end
32
32
 
@@ -56,7 +56,7 @@ describe "Typecasting" do
56
56
  obj = cxt.eval("var o = {foo: 1, bar: 2, func: function() { return 1 }}; o", "<eval>")
57
57
  obj[:foo].should == 1
58
58
  obj[:bar].should == 2
59
- obj[:func].should be_kind_of(V8::Function)
59
+ obj[:func].should be_kind_of(Mustang::V8::Function)
60
60
  end
61
61
 
62
62
  it "converts regexps properly" do
@@ -1,6 +1,13 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Mustang::V8::Context do
4
+ describe ".new" do
5
+ it "creates new context and enters it" do
6
+ cxt = Mustang::V8::Context.new
7
+ cxt.should be_entered
8
+ end
9
+ end
2
10
 
3
- describe V8::Context do
4
11
  describe "#evaluate" do
5
12
  it "evaluates given javascript source" do
6
13
  subject.evaluate("var a = 'foo'; a;", "<eval>").should == 'foo'
@@ -8,7 +15,7 @@ describe V8::Context do
8
15
 
9
16
  it "returns result converted to ruby object" do
10
17
  result = subject.evaluate("'foo'", "<eval>")
11
- result.should be_kind_of(V8::String)
18
+ result.should be_kind_of(Mustang::V8::String)
12
19
  result.to_s.should == 'foo'
13
20
  end
14
21
 
@@ -45,16 +52,17 @@ describe V8::Context do
45
52
 
46
53
  describe "#global" do
47
54
  it "returns the global object for current context" do
48
- subject.global.should be_kind_of(V8::Object)
55
+ subject.global.should be_kind_of(Mustang::V8::Object)
49
56
  end
50
57
  end
51
58
 
52
59
  describe "#enter" do
53
- subject { V8::Context.new }
60
+ subject { Mustang::V8::Context.new }
54
61
 
55
62
  context "when block given" do
56
63
  it "enters to context evaluates passed block, and exits after execution" do
57
64
  entered = false
65
+ subject.exit
58
66
  subject.enter { |cxt| entered = cxt.entered? }
59
67
  entered.should be_true
60
68
  subject.should_not be_entered
@@ -63,7 +71,8 @@ describe V8::Context do
63
71
 
64
72
  context "when no block given" do
65
73
  it "enters to context" do
66
- subject.enter.should be_true
74
+ subject.exit
75
+ subject.enter.should be
67
76
  subject.should be_entered
68
77
  end
69
78
  end
@@ -75,4 +84,41 @@ describe V8::Context do
75
84
  subject.should_not be_entered
76
85
  end
77
86
  end
87
+
88
+ describe ".exit_all!" do
89
+ it "exits from all curretnly entered contexts" do
90
+ cxts = []
91
+ cxts << Mustang::V8::Context.new
92
+ cxts << Mustang::V8::Context.new
93
+ cxts << Mustang::V8::Context.new
94
+ cxts.each { |cxt| cxt.enter }
95
+ Mustang::V8::Context.exit_all!
96
+ cxts.each { |cxt| cxt.should_not be_entered }
97
+ end
98
+ end
99
+
100
+ describe ".current" do
101
+ context "when there is entered context" do
102
+ it "returns currently entered context" do
103
+ pending "not implemented"
104
+ cxt = Mustang::V8::Context.new
105
+ cxt.enter
106
+ Mustang::V8::Context.current.should == cxt
107
+ end
108
+ end
109
+
110
+ context "when there is no context entered" do
111
+ it "returns nil" do
112
+ pending "not implemented"
113
+ Mustang::V8::Context.exit_all!
114
+ Mustang::V8::Context.current.should_not be
115
+ end
116
+ end
117
+
118
+ it "is aliased with #entered" do
119
+ pending "not implemented"
120
+ Mustang::V8::Context.new.enter
121
+ Mustang::V8::Context.entered.should == Mustang::V8::Context.current
122
+ end
123
+ end
78
124
  end
@@ -1,6 +1,6 @@
1
- require File.dirname(__FILE__) + '/../spec_helper'
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
- describe V8::Data do
3
+ describe Mustang::V8::Data do
4
4
  setup_context
5
5
 
6
6
  describe "#error?" do
@@ -29,11 +29,11 @@ describe V8::Data do
29
29
 
30
30
  describe "#value?" do
31
31
  it "returns true when data is kind of value" do
32
- V8::Integer.new(1).should be_value
32
+ Mustang::V8::Integer.new(1).should be_value
33
33
  end
34
34
 
35
35
  it "returns false when data is not kind of value" do
36
- V8::Undefined.should_not be_value
36
+ Mustang::V8::Undefined.should_not be_value
37
37
  end
38
38
  end
39
39
  end