mustang 0.1.1 → 0.2.0

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 (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