amf_socket 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- amf_socket (0.2.0)
4
+ amf_socket (0.3.0)
5
5
  RocketAMF (>= 0.2.1)
6
6
  eventmachine (>= 0.12.10)
7
7
 
@@ -9,10 +9,51 @@ GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
11
  RocketAMF (0.2.1)
12
+ columnize (0.3.6)
13
+ debugger (1.2.0)
14
+ columnize (>= 0.3.1)
15
+ debugger-linecache (~> 1.1.1)
16
+ debugger-ruby_core_source (~> 1.1.3)
17
+ debugger-linecache (1.1.2)
18
+ debugger-ruby_core_source (>= 1.1.1)
19
+ debugger-ruby_core_source (1.1.3)
20
+ diff-lcs (1.1.3)
12
21
  eventmachine (0.12.10)
22
+ ffi (1.1.5)
23
+ growl (1.0.3)
24
+ guard (1.3.2)
25
+ listen (>= 0.4.2)
26
+ thor (>= 0.14.6)
27
+ guard-rspec (1.2.1)
28
+ guard (>= 1.1)
29
+ listen (0.4.7)
30
+ rb-fchange (~> 0.0.5)
31
+ rb-fsevent (~> 0.9.1)
32
+ rb-inotify (~> 0.8.8)
33
+ rake (0.9.2.2)
34
+ rb-fchange (0.0.5)
35
+ ffi
36
+ rb-fsevent (0.9.1)
37
+ rb-inotify (0.8.8)
38
+ ffi (>= 0.5.0)
39
+ rspec (2.11.0)
40
+ rspec-core (~> 2.11.0)
41
+ rspec-expectations (~> 2.11.0)
42
+ rspec-mocks (~> 2.11.0)
43
+ rspec-core (2.11.1)
44
+ rspec-expectations (2.11.2)
45
+ diff-lcs (~> 1.1.3)
46
+ rspec-mocks (2.11.2)
47
+ thor (0.16.0)
13
48
 
14
49
  PLATFORMS
15
50
  ruby
16
51
 
17
52
  DEPENDENCIES
18
53
  amf_socket!
54
+ debugger (= 1.2.0)
55
+ growl (= 1.0.3)
56
+ guard (= 1.3.2)
57
+ guard-rspec (= 1.2.1)
58
+ rake (= 0.9.2.2)
59
+ rspec (= 2.11.0)
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard :rspec, :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| r = "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/Rakefile CHANGED
@@ -3,11 +3,6 @@
3
3
  require 'rubygems'
4
4
  require 'bundler/gem_tasks'
5
5
 
6
- begin
7
- require 'debugger'
8
- rescue Exception
9
- end
10
-
11
6
  begin
12
7
  Bundler.setup(:default, :development)
13
8
  rescue Bundler::BundlerError => e
@@ -16,6 +11,8 @@ rescue Bundler::BundlerError => e
16
11
  exit e.status_code
17
12
  end
18
13
 
14
+ require 'debugger'
15
+
19
16
  task :environment do
20
17
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
21
18
  require 'amf_socket'
@@ -30,6 +27,14 @@ task :console => :environment do
30
27
  IRB.start
31
28
  end
32
29
 
30
+ desc 'Run all specs'
31
+ task :spec do
32
+ puts 'Running rspec:'
33
+ system 'rspec spec'
34
+ end
35
+
36
+ task :default => :spec
37
+
33
38
  desc 'Start a test server'
34
39
  task :harness => :environment do
35
40
  EM.run do
data/amf_socket.gemspec CHANGED
@@ -17,4 +17,11 @@ Gem::Specification.new do |gem|
17
17
 
18
18
  gem.add_dependency('eventmachine', ['>= 0.12.10'])
19
19
  gem.add_dependency('RocketAMF', ['>= 0.2.1'])
20
+
21
+ gem.add_development_dependency('rake', ['= 0.9.2.2'])
22
+ gem.add_development_dependency('rspec', ['= 2.11.0'])
23
+ gem.add_development_dependency('guard', ['= 1.3.2'])
24
+ gem.add_development_dependency('guard-rspec', ['= 1.2.1'])
25
+ gem.add_development_dependency('growl', ['= 1.0.3'])
26
+ gem.add_development_dependency('debugger', ['= 1.2.0'])
20
27
  end
@@ -1,14 +1,20 @@
1
1
  class AmfSocket::AmfRpcConnection < AmfSocket::AmfConnection
2
+ PING_INTERVAL = 5 # Seconds.
3
+
4
+ attr_reader :latency
5
+
2
6
  def send_request(command, params = {}, &block)
3
7
  request = AmfSocket::RpcRequest.new(command, params)
4
8
  block.call(request)
5
9
  @sent_requests[request.message_id] = request
6
10
  send_object(request.to_hash)
11
+ request.send(:sent)
7
12
  end
8
13
 
9
14
  def send_message(command, params = {})
10
15
  message = AmfSocket::RpcMessage.new(command, params)
11
16
  send_object(message.to_hash)
17
+ message.send(:sent)
12
18
  end
13
19
 
14
20
  #
@@ -17,7 +23,11 @@ class AmfSocket::AmfRpcConnection < AmfSocket::AmfConnection
17
23
 
18
24
  def post_init
19
25
  super
26
+
20
27
  @sent_requests = {}
28
+ @next_ping = Time.now.utc
29
+
30
+ AmfSocket.heartbeat.add(self)
21
31
  end
22
32
 
23
33
  def receive_object(object)
@@ -42,6 +52,8 @@ class AmfSocket::AmfRpcConnection < AmfSocket::AmfConnection
42
52
  end
43
53
 
44
54
  def unbind
55
+ AmfSocket.heartbeat.remove(self)
56
+
45
57
  @sent_requests.each do |message_id, request|
46
58
  if request.failed_callback.is_a?(Proc)
47
59
  request.failed_callback.call('disconnected')
@@ -66,13 +78,59 @@ class AmfSocket::AmfRpcConnection < AmfSocket::AmfConnection
66
78
 
67
79
  def receive_response(response_object)
68
80
  raise AmfSocket::InvalidObject unless (message_id = response_object[:response][:messageId])
69
- raise AmfSocket::InvalidObject unless (request = @sent_requests[message_id])
81
+
82
+ return unless (request = @sent_requests[message_id]) # Ignore timed out requests.
70
83
 
71
84
  response = AmfSocket::RpcResponse.new(request, response_object)
72
85
  @sent_requests.delete(message_id)
73
86
 
74
- if request.succeeded_callback.is_a?(Proc)
75
- request.succeeded_callback.call(response)
87
+ AmfSocket.try do
88
+ if request.succeeded_callback.is_a?(Proc)
89
+ request.succeeded_callback.call(response)
90
+ end
91
+ end
92
+ end
93
+
94
+ def heartbeat
95
+ timeout_requests
96
+ ping
97
+ end
98
+
99
+ #
100
+ # Private Methods.
101
+ #
102
+
103
+ private
104
+
105
+ def timeout_requests
106
+ @sent_requests.each do |message_id, request|
107
+ if request.timed_out?
108
+ AmfSocket.try do
109
+ if request.failed_callback.is_a?(Proc)
110
+ request.failed_callback.call('timed_out')
111
+ end
112
+ end
113
+
114
+ @sent_requests.delete(message_id)
115
+ end
116
+ end
117
+ end
118
+
119
+ def ping
120
+ return if @next_ping > Time.now.utc
121
+
122
+ send_request('amf_socket_ping', :time => Time.now.utc, :latency => @latency.to_f) do |request|
123
+ @next_ping = Time.now.utc + PING_INTERVAL
124
+
125
+ request.timeout = 10
126
+
127
+ request.succeeded do |response|
128
+ @latency = Time.now.utc - request.sent_at
129
+ end
130
+
131
+ request.failed do |reason|
132
+ close_connection if reason == 'timed_out'
133
+ end
76
134
  end
77
135
  end
78
136
  end
@@ -0,0 +1,51 @@
1
+ class AmfSocket::Heartbeat
2
+ INTERVAL = 1 # Seconds.
3
+
4
+ def initialize
5
+ @objects = Set.new
6
+ start unless AmfSocket.test_mode?
7
+ end
8
+
9
+ def start
10
+ return false unless @timer.nil?
11
+
12
+ @timer = EM::PeriodicTimer.new(INTERVAL, method(:timer_handler))
13
+
14
+ return true
15
+ end
16
+
17
+ def stop
18
+ return false unless @timer
19
+
20
+ @timer.cancel
21
+ @timer = nil
22
+
23
+ return true
24
+ end
25
+
26
+ def add(object)
27
+ return false if @objects.include?(object)
28
+
29
+ @objects.add(object)
30
+
31
+ return true
32
+ end
33
+
34
+ def remove(object)
35
+ return false unless @objects.include?(object)
36
+
37
+ @objects.delete(object)
38
+
39
+ return true
40
+ end
41
+
42
+ private
43
+
44
+ def timer_handler
45
+ @objects.each do |object|
46
+ AmfSocket.try do
47
+ object.send(:heartbeat) if object.respond_to?(:heartbeat, true)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -2,6 +2,7 @@ class AmfSocket::RpcMessage
2
2
  attr_reader :message_id
3
3
  attr_reader :command
4
4
  attr_reader :params
5
+ attr_reader :sent_at
5
6
 
6
7
  def initialize(command, params = {})
7
8
  raise AmfSocket::InvalidArg.new('Command must be a String.') unless command.is_a?(String)
@@ -23,4 +24,10 @@ class AmfSocket::RpcMessage
23
24
 
24
25
  return object
25
26
  end
27
+
28
+ private
29
+
30
+ def sent
31
+ @sent_at = Time.now.utc
32
+ end
26
33
  end
@@ -33,6 +33,8 @@ class AmfSocket::RpcReceivedRequest
33
33
 
34
34
  @connection.send_object(object)
35
35
 
36
+ @state = :replied
37
+
36
38
  return true
37
39
  end
38
40
 
@@ -1,12 +1,15 @@
1
1
  class AmfSocket::RpcRequest
2
- attr_reader :state # Valid states: :initialized, :sent, :responded.
2
+ attr_reader :state # Valid states: :initialized, :sent, :responded, :failed.
3
3
  attr_reader :message_id
4
4
  attr_reader :command
5
5
  attr_reader :params
6
+ attr_reader :sent_at
7
+ attr_reader :timeout_at
6
8
 
7
9
  attr_accessor :succeeded_callback
8
10
  attr_accessor :failed_callback
9
- attr_accessor :timeout
11
+
12
+ TIMEOUT = 30 # Seconds.
10
13
 
11
14
  def initialize(command, params = {})
12
15
  raise AmfSocket::InvalidArg.new('Command must be a String.') unless command.is_a?(String)
@@ -16,13 +19,18 @@ class AmfSocket::RpcRequest
16
19
  @params = params
17
20
  @state = :initialized
18
21
  @message_id = SecureRandom.hex
22
+ @timeout = TIMEOUT
19
23
  end
20
24
 
21
25
  def succeeded(&block)
26
+ require_state(:initialized)
27
+
22
28
  @succeeded_callback = block
23
29
  end
24
30
 
25
31
  def failed(&block)
32
+ require_state(:initialized)
33
+
26
34
  @failed_callback = block
27
35
  end
28
36
 
@@ -37,4 +45,32 @@ class AmfSocket::RpcRequest
37
45
 
38
46
  return object
39
47
  end
48
+
49
+ def timeout=(seconds)
50
+ require_state(:initialized)
51
+
52
+ @timeout = seconds
53
+ end
54
+
55
+ def timeout
56
+ return @timeout
57
+ end
58
+
59
+ def timed_out?
60
+ return Time.now.utc >= @timeout_at
61
+ end
62
+
63
+ private
64
+
65
+ def sent
66
+ require_state(:initialized)
67
+
68
+ @state = :sent
69
+ @sent_at = Time.now.utc
70
+ @timeout_at = @sent_at + timeout
71
+ end
72
+
73
+ def require_state(s)
74
+ raise 'Invalid state' unless @state == s
75
+ end
40
76
  end
@@ -1,3 +1,3 @@
1
1
  module AmfSocket
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/amf_socket.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require 'eventmachine'
2
2
  require 'rocketamf'
3
3
  require 'securerandom'
4
+ require 'thread'
4
5
 
5
6
  module AmfSocket; end
6
7
 
@@ -14,3 +15,34 @@ require 'amf_socket/rpc_received_request'
14
15
  require 'amf_socket/rpc_received_message'
15
16
  require 'amf_socket/serializer'
16
17
  require 'amf_socket/exceptions'
18
+ require 'amf_socket/heartbeat'
19
+
20
+ module AmfSocket
21
+ def self.heartbeat
22
+ @heartbeat ||= AmfSocket::Heartbeat.new
23
+ end
24
+
25
+ def self.exception_handler=(handler)
26
+ @exception_handler = handler
27
+ end
28
+
29
+ def self.exception_handler
30
+ return @exception_handler
31
+ end
32
+
33
+ def self.try(&block)
34
+ begin
35
+ block.call
36
+ rescue Exception => e
37
+ @exception_handler.call(e) if @exception_handler
38
+ end
39
+ end
40
+
41
+ def self.enable_test_mode
42
+ @test_mode = true
43
+ end
44
+
45
+ def self.test_mode?
46
+ return !!@test_mode
47
+ end
48
+ end
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::AmfConnection do
4
+ it 'should use use the amf serializer' do
5
+ conn = AmfSocket::AmfConnection.new(nil)
6
+ conn.serializer.should == AmfSocket::Serializer
7
+ end
8
+ end
@@ -0,0 +1,196 @@
1
+ require 'spec_helper'
2
+
3
+ class AmfRpcConnTestable < AmfSocket::AmfRpcConnection
4
+ attr_accessor :sent_requests
5
+ attr_accessor :sent_objects
6
+ attr_accessor :received_requests
7
+ attr_accessor :received_messages
8
+
9
+ def self.new
10
+ allocate.instance_eval do
11
+ initialize
12
+ post_init
13
+ self
14
+ end
15
+ end
16
+
17
+ def initialize
18
+ @sent_objects = []
19
+ @received_requests = []
20
+ @received_messages = []
21
+ end
22
+
23
+ def send_object(object)
24
+ @sent_objects << object
25
+ end
26
+
27
+ def receive_request(request)
28
+ @received_requests << request
29
+ end
30
+
31
+ def receive_message(message)
32
+ @received_messages << message
33
+ end
34
+ end
35
+
36
+ describe AmfSocket::AmfRpcConnection do
37
+ context 'when sending requests' do
38
+ before(:each) do
39
+ @conn = AmfRpcConnTestable.new
40
+ @command = 'hello'
41
+ @params = { :foo => 'bar' }
42
+ @request = AmfSocket::RpcRequest.new(@command, @params)
43
+ @flag = false
44
+ @block = proc do |request|
45
+ @flag = true
46
+ @block_arg = request
47
+ end
48
+
49
+ AmfSocket::RpcRequest.should_receive(:new).with(@command, @params).and_return(@request)
50
+
51
+ @conn.send_request(@command, @params) { |request| @block.call(request) }
52
+ end
53
+
54
+ it 'should send the request as a simple hash object' do
55
+ @conn.sent_objects.first.should == @request.to_hash
56
+ end
57
+
58
+ it 'should execute the block and pass it a request object' do
59
+ @flag.should == true
60
+ @block_arg.class.should == AmfSocket::RpcRequest
61
+ end
62
+
63
+ it 'should register the request in order to handle the response' do
64
+ @conn.sent_requests.first[0].should == @request.message_id
65
+ @conn.sent_requests.first[1].should == @request
66
+ end
67
+ end
68
+
69
+ context 'when sending messages' do
70
+ before(:each) do
71
+ @conn = AmfRpcConnTestable.new
72
+ @command = 'hello'
73
+ @params = { :foo => 'bar' }
74
+ @message = AmfSocket::RpcMessage.new(@command, @params)
75
+
76
+ AmfSocket::RpcMessage.should_receive(:new).with(@command, @params).and_return(@message)
77
+
78
+ @conn.send_message(@command, @params)
79
+ end
80
+
81
+ it 'should send the message as a simple hash object' do
82
+ @conn.sent_objects.first.should == @message.to_hash
83
+ end
84
+ end
85
+
86
+ context 'when receiving objects' do
87
+ before(:each) do
88
+ @conn = AmfRpcConnTestable.new
89
+ end
90
+
91
+ it 'should handle received requests' do
92
+ object = {
93
+ :type => 'rpcRequest',
94
+ :request => {
95
+ :messageId => '123',
96
+ :command => 'hello',
97
+ :params => {
98
+ :foo => 'bar'
99
+ }
100
+ }
101
+ }
102
+
103
+ @conn.receive_object(object)
104
+
105
+ @conn.received_requests.length.should == 1
106
+
107
+ request = @conn.received_requests.first
108
+
109
+ request.class.should == AmfSocket::RpcReceivedRequest
110
+ request.message_id.should == '123'
111
+ request.command.should == 'hello'
112
+ request.params.should == { :foo => 'bar' }
113
+ request.connection.should == @conn
114
+ end
115
+
116
+ it 'should handle recevied messages' do
117
+ object = {
118
+ :type => 'rpcMessage',
119
+ :message => {
120
+ :messageId => '123',
121
+ :command => 'hello',
122
+ :params => {
123
+ :foo => 'bar'
124
+ }
125
+ }
126
+ }
127
+
128
+ @conn.receive_object(object)
129
+
130
+ @conn.received_messages.length.should == 1
131
+
132
+ message = @conn.received_messages.first
133
+
134
+ message.class.should == AmfSocket::RpcReceivedMessage
135
+ message.message_id.should == '123'
136
+ message.command.should == 'hello'
137
+ message.params.should == { :foo => 'bar' }
138
+ message.connection.should == @conn
139
+ end
140
+
141
+ it 'should handle responses for sent requests' do
142
+ flag = false
143
+ req = nil
144
+ res = nil
145
+
146
+ @conn.send_request('hello', :foo => 'bar') do |request|
147
+ req = request
148
+
149
+ request.succeeded do |response|
150
+ flag = true
151
+ res = response
152
+ end
153
+ end
154
+
155
+ object = {
156
+ :type => 'rpcResponse',
157
+ :response => {
158
+ :messageId => req.message_id,
159
+ :result => 'happy ending'
160
+ }
161
+ }
162
+
163
+ @conn.receive_object(object)
164
+
165
+ flag.should == true
166
+ res.result.should == 'happy ending'
167
+ end
168
+ end
169
+
170
+ context 'when a socket gets disconnected' do
171
+ before(:each) do
172
+ @conn = AmfRpcConnTestable.new
173
+ end
174
+
175
+ it 'should trigger failure on app pending requests' do
176
+ flag = false
177
+ req = nil
178
+ reas = nil
179
+
180
+ @conn.send_request('hello', :foo => 'bar') do |request|
181
+ req = request
182
+
183
+ request.failed do |reason|
184
+ flag = true
185
+ reas = reason
186
+ end
187
+ end
188
+
189
+ @conn.unbind
190
+
191
+ flag.should == true
192
+ reas.should == 'disconnected'
193
+ @conn.sent_requests.length.should == 0
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::Heartbeat do
4
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::RpcMessage do
4
+ it 'should construct properly' do
5
+ SecureRandom.should_receive(:hex).and_return('random id')
6
+
7
+ message = AmfSocket::RpcMessage.new('hello', :foo => 'bar')
8
+
9
+ message.message_id.should == 'random id'
10
+ message.command.should == 'hello'
11
+ message.params.should == { :foo => 'bar' }
12
+ end
13
+
14
+ it 'should convert to a hash' do
15
+ message = AmfSocket::RpcMessage.new('hello', :foo => 'bar')
16
+
17
+ expected = {
18
+ :type => 'rpcMessage',
19
+ :message => {
20
+ :messageId => message.message_id,
21
+ :command => 'hello',
22
+ :params => { :foo => 'bar'
23
+ }
24
+ }
25
+ }
26
+
27
+ message.to_hash.should == expected
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::RpcReceivedMessage do
4
+ it 'should construct properly' do
5
+ object = {
6
+ :type => 'rpcMessage',
7
+ :message => {
8
+ :messageId => 'random id',
9
+ :command => 'hello',
10
+ :params => {
11
+ :foo => 'bar'
12
+ }
13
+ }
14
+ }
15
+
16
+ conn = stub
17
+
18
+ message = AmfSocket::RpcReceivedMessage.new(object, conn)
19
+
20
+ message.connection.should == conn
21
+ message.message_id.should == 'random id'
22
+ message.command.should == 'hello'
23
+ message.params.should == { :foo => 'bar' }
24
+ end
25
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::RpcReceivedRequest do
4
+ before(:each) do
5
+ @object = {
6
+ :type => 'rpcRequest',
7
+ :request => {
8
+ :messageId => 'random id',
9
+ :command => 'hello',
10
+ :params => {
11
+ :foo => 'bar'
12
+ }
13
+ }
14
+ }
15
+
16
+ @conn = stub
17
+
18
+ @request = AmfSocket::RpcReceivedRequest.new(@object, @conn)
19
+ end
20
+
21
+ it 'should construct properly' do
22
+ @request.state.should == :initialized
23
+ @request.connection.should == @conn
24
+ @request.message_id.should == 'random id'
25
+ @request.command.should == 'hello'
26
+ @request.params.should == { :foo => 'bar' }
27
+ end
28
+
29
+ it 'should reply properly' do
30
+ @conn.should_receive(:send_object).exactly(:once)
31
+ @request.reply('foo bar').should == true
32
+ @request.state.should == :replied
33
+ @request.reply('foo bar again').should == false
34
+ end
35
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::RpcRequest do
4
+ it 'should construct properly' do
5
+ SecureRandom.should_receive(:hex).and_return('random id')
6
+
7
+ request = AmfSocket::RpcRequest.new('hello', :foo => 'bar')
8
+
9
+ request.message_id.should == 'random id'
10
+ request.command.should == 'hello'
11
+ request.params.should == { :foo => 'bar' }
12
+ end
13
+
14
+ it 'should convert to a hash' do
15
+ request = AmfSocket::RpcRequest.new('hello', :foo => 'bar')
16
+
17
+ expected = {
18
+ :type=> 'rpcRequest',
19
+ :request => {
20
+ :messageId => request.message_id,
21
+ :command => 'hello',
22
+ :params=> { :foo => 'bar'
23
+ }
24
+ }
25
+ }
26
+
27
+ request.to_hash.should == expected
28
+ end
29
+
30
+ it 'should store the succeeded callback' do
31
+ request = AmfSocket::RpcRequest.new('hello', :foo => 'bar')
32
+
33
+ flag = false
34
+
35
+ request.succeeded { flag = true }
36
+ request.succeeded_callback.call
37
+
38
+ flag.should == true
39
+ end
40
+
41
+ it 'should store the failed callback' do
42
+ request = AmfSocket::RpcRequest.new('hello', :foo => 'bar')
43
+
44
+ flag = false
45
+
46
+ request.failed { flag = true }
47
+ request.failed_callback.call
48
+
49
+ flag.should == true
50
+ end
51
+
52
+ it 'should convert to a hash' do
53
+ message = AmfSocket::RpcRequest.new('hello', :foo => 'bar')
54
+
55
+ expected = {
56
+ :type => 'rpcRequest',
57
+ :request => {
58
+ :messageId => message.message_id,
59
+ :command => 'hello',
60
+ :params => { :foo => 'bar'
61
+ }
62
+ }
63
+ }
64
+
65
+ message.to_hash.should == expected
66
+ end
67
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::RpcResponse do
4
+ it 'should construct properly' do
5
+ request = stub
6
+
7
+ response_object = {
8
+ :type => 'rpcResponse',
9
+ :response => {
10
+ :messageId => 'random id',
11
+ :result => 'foobar'
12
+ }
13
+ }
14
+
15
+ response = AmfSocket::RpcResponse.new(request, response_object)
16
+
17
+ response.request.should == request
18
+ response.result.should == 'foobar'
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe AmfSocket::Serializer do
4
+ it 'should dump an object to AMF format' do
5
+ AmfSocket::Serializer.dump({ :foo => 'bar' }).should == "\n\v\x01\afoo\x06\abar\x01"
6
+ end
7
+
8
+ it 'should load an object from AMF format' do
9
+ AmfSocket::Serializer.load("\n\v\x01\afoo\x06\abar\x01").should == { :foo => 'bar' }
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe AmfSocket do
4
+ it 'should make sure 5 == 5' do
5
+ 5.should == 5
6
+ end
7
+ end
@@ -0,0 +1,30 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rubygems'
5
+ require 'bundler'
6
+ require 'debugger'
7
+
8
+ begin
9
+ Bundler.setup(:default, :development)
10
+ rescue Bundler::BundlerError => e
11
+ $stderr.puts(e.message)
12
+ $stderr.puts("Run `bundle install` to install missing gems")
13
+ exit e.status_code
14
+ end
15
+
16
+ require 'benchmark'
17
+ require 'amf_socket'
18
+
19
+ AmfSocket.enable_test_mode
20
+
21
+ AmfSocket.exception_handler do |ue|
22
+ puts "UNHANDLED EXCEPTION #{ue.class} (#{ue.message.chomp})\n#{ue.backtrace.join("\n")}\n--"
23
+ end
24
+
25
+ # Requires supporting files with custom matchers and macros, etc,
26
+ # in ./support/ and its subdirectories.
27
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
28
+
29
+ RSpec.configure do |config|
30
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: amf_socket
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-25 00:00:00.000000000 Z
12
+ date: 2012-09-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -43,6 +43,102 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: 0.2.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.2.2
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.2.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 2.11.0
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 2.11.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: guard
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 1.3.2
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.2
94
+ - !ruby/object:Gem::Dependency
95
+ name: guard-rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.2.1
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.2.1
110
+ - !ruby/object:Gem::Dependency
111
+ name: growl
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 1.0.3
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 1.0.3
126
+ - !ruby/object:Gem::Dependency
127
+ name: debugger
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - '='
132
+ - !ruby/object:Gem::Version
133
+ version: 1.2.0
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - '='
140
+ - !ruby/object:Gem::Version
141
+ version: 1.2.0
46
142
  description: Ruby implementation of AMF Socket (https://github.com/chadrem/amf_socket)
47
143
  email:
48
144
  - chad@remesch.com
@@ -51,8 +147,10 @@ extensions: []
51
147
  extra_rdoc_files: []
52
148
  files:
53
149
  - .gitignore
150
+ - .rspec
54
151
  - Gemfile
55
152
  - Gemfile.lock
153
+ - Guardfile
56
154
  - LICENSE.txt
57
155
  - README.md
58
156
  - Rakefile
@@ -61,6 +159,7 @@ files:
61
159
  - lib/amf_socket/amf_connection.rb
62
160
  - lib/amf_socket/amf_rpc_connection.rb
63
161
  - lib/amf_socket/exceptions.rb
162
+ - lib/amf_socket/heartbeat.rb
64
163
  - lib/amf_socket/rpc_message.rb
65
164
  - lib/amf_socket/rpc_received_message.rb
66
165
  - lib/amf_socket/rpc_received_request.rb
@@ -68,6 +167,17 @@ files:
68
167
  - lib/amf_socket/rpc_response.rb
69
168
  - lib/amf_socket/serializer.rb
70
169
  - lib/amf_socket/version.rb
170
+ - spec/amf_socket/amf_connection_spec.rb
171
+ - spec/amf_socket/amf_rpc_connection_spec.rb
172
+ - spec/amf_socket/heartbeat_spec.rb
173
+ - spec/amf_socket/rpc_message_spec.rb
174
+ - spec/amf_socket/rpc_received_message_spec.rb
175
+ - spec/amf_socket/rpc_received_request_spec.rb
176
+ - spec/amf_socket/rpc_request_spec.rb
177
+ - spec/amf_socket/rpc_response_spec.rb
178
+ - spec/amf_socket/serializer_spec.rb
179
+ - spec/amf_socket_spec.rb
180
+ - spec/spec_helper.rb
71
181
  homepage: https://github.com/chadrem/observation
72
182
  licenses: []
73
183
  post_install_message:
@@ -82,7 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
82
192
  version: '0'
83
193
  segments:
84
194
  - 0
85
- hash: -337065738793524363
195
+ hash: -2517453312073385127
86
196
  required_rubygems_version: !ruby/object:Gem::Requirement
87
197
  none: false
88
198
  requirements:
@@ -91,7 +201,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
201
  version: '0'
92
202
  segments:
93
203
  - 0
94
- hash: -337065738793524363
204
+ hash: -2517453312073385127
95
205
  requirements: []
96
206
  rubyforge_project:
97
207
  rubygems_version: 1.8.24
@@ -99,4 +209,15 @@ signing_key:
99
209
  specification_version: 3
100
210
  summary: AMF Socket is a bi-directional RPC system for Adobe Flash (Actionscript)
101
211
  programs.
102
- test_files: []
212
+ test_files:
213
+ - spec/amf_socket/amf_connection_spec.rb
214
+ - spec/amf_socket/amf_rpc_connection_spec.rb
215
+ - spec/amf_socket/heartbeat_spec.rb
216
+ - spec/amf_socket/rpc_message_spec.rb
217
+ - spec/amf_socket/rpc_received_message_spec.rb
218
+ - spec/amf_socket/rpc_received_request_spec.rb
219
+ - spec/amf_socket/rpc_request_spec.rb
220
+ - spec/amf_socket/rpc_response_spec.rb
221
+ - spec/amf_socket/serializer_spec.rb
222
+ - spec/amf_socket_spec.rb
223
+ - spec/spec_helper.rb