amf_socket 0.2.0 → 0.3.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.
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