Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fixed dummy_server so functional tests work; run dummy_server on anot…

…her port to avoid conflict; updated TODO
  • Loading branch information...
commit 04abddfd84369e91b0489e9541746640ae717f3b 1 parent ef87ce5
@ericgj authored
View
14 .autotest
@@ -6,17 +6,17 @@ Autotest.add_hook :initialize do |at|
at.testlib = 'minitest/spec'
# Note only unit tests are autotest'ed here
- at.add_mapping(/^spec\/unit\/.*_spec\.rb$/) do |filename, _|
+ at.add_mapping(/^spec\/unit\/.*\.rb$/) do |filename, _|
filename
end
# To include functional and integration tests, uncomment these lines
-# at.add_mapping(/^spec\/functional\/.*\.rb$/) do |filename, _|
-# filename
-# end
-# at.add_mapping(/^spec\/integration\/.*\.rb$/) do |filename, _|
-# filename
-# end
+ at.add_mapping(/^spec\/functional\/.*\.rb$/) do |filename, _|
+ filename
+ end
+ at.add_mapping(/^spec\/integration\/.*\.rb$/) do |filename, _|
+ filename
+ end
end
View
3  TODO.markdown
@@ -1,8 +1,5 @@
## Oct 7
-1. Spec Route
-2. Spec Response class
-3. Fix dummy_server for functional tests
4. Add App functional tests for register, notify, and callbacks
5. Add integration tests for App register, notify, and callbacks
View
2  lib/em_gntp.rb
@@ -5,5 +5,7 @@
Bundler.setup :default
require 'lib/em_gntp/marshal'
require 'lib/em_gntp/client'
+require 'lib/em_gntp/response'
+require 'lib/em_gntp/route'
require 'lib/em_gntp/notification'
require 'lib/em_gntp/app'
View
2  lib/em_gntp/response.rb
@@ -12,7 +12,7 @@ class Response < Struct.new(:status,
include EM_GNTP::Marshal::Response
extend Forwardable
- def_delegator :[], :@raw
+ def_delegator :@raw, :[]
def initialize(resp)
@raw = resp
View
5 lib/em_gntp/route.rb
@@ -4,6 +4,7 @@ class Route
class << self
def parse action, path
+ path ||= ''
parts = path.split('/')[0..2].map {|p| p == '*' ? nil : p}
[action] + Array.new(3).fill {|i| parts[i] }
end
@@ -28,9 +29,9 @@ def matches?(*args)
end
- # sort nil parts after named parts
+ # sort nil parts after named parts (unless named parts begin with ~)
def <=>(other)
- pattern.map {|it| it || '_'} <=> other.pattern.map {|it| it || '_'}
+ pattern.map {|it| it || '~'} <=> other.pattern.map {|it| it || '~'}
end
end
View
4 spec/functional/app_notify_spec.rb
@@ -7,7 +7,7 @@
before do
@p_svr = DummyServerHelper.fork_server(:notify => '-OK')
EM_GNTP::Client.response_class = MarshalHelper.dummy_response_class
- @subject = EM_GNTP::App.new('test')
+ @subject = EM_GNTP::App.new('test', :port => DummyServerHelper::DEFAULT_PORT)
end
after do
@@ -39,7 +39,7 @@
before do
@p_svr = DummyServerHelper.fork_server(:notify => '-OK')
EM_GNTP::Client.response_class = MarshalHelper.dummy_response_class
- @subject = EM_GNTP::App.new('test')
+ @subject = EM_GNTP::App.new('test', :port => DummyServerHelper::DEFAULT_PORT)
end
after do
View
4 spec/functional/app_register_spec.rb
@@ -7,7 +7,7 @@
before do
@p_svr = DummyServerHelper.fork_server(:register => '-OK')
EM_GNTP::Client.response_class = MarshalHelper.dummy_response_class
- @subject = EM_GNTP::App.new('test')
+ @subject = EM_GNTP::App.new('test',:port => DummyServerHelper::DEFAULT_PORT)
end
after do
@@ -40,7 +40,7 @@
before do
@p_svr = DummyServerHelper.fork_server(:register => '-OK')
EM_GNTP::Client.response_class = MarshalHelper.dummy_response_class
- @subject = EM_GNTP::App.new('test')
+ @subject = EM_GNTP::App.new('test',:port => DummyServerHelper::DEFAULT_PORT)
end
after do
View
48 spec/functional/client_spec.rb
@@ -12,15 +12,15 @@
'request_method' => 'REGISTER',
'encryption_id' => 'NONE'
}
- @input_hdrs = {'application_name' => 'SurfWriter',
- 'application_icon' => 'http://www.site.org/image.jpg'
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
+ 'Application-Icon' => 'http://www.site.org/image.jpg'
}
@input_notifs = { 'Download Complete' => {
- 'notification_display_name' => 'Download completed',
- 'notification_enabled' => 'True',
- 'x_language' => 'English',
- 'x_timezone' => 'PST'
+ 'Notification-Display-Name' => 'Download completed',
+ 'Notification-Enabled' => 'True',
+ 'X-Language' => 'English',
+ 'X-Timezone' => 'PST'
}
}
@@ -41,7 +41,7 @@
callback_count = 0
EM.run {
puts "Client sending request"
- connect = EM_GNTP::Client.register(@input)
+ connect = EM_GNTP::Client.register(@input, 'localhost', DummyServerHelper::DEFAULT_PORT)
connect.each_ok_response do |resp|
puts "Client received OK response"
@@ -82,15 +82,15 @@
'request_method' => 'REGISTER',
'encryption_id' => 'NONE'
}
- @input_hdrs = {'application_name' => 'SurfWriter',
- 'application_icon' => 'http://www.site.org/image.jpg'
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
+ 'Application-Icon' => 'http://www.site.org/image.jpg'
}
@input_notifs = { 'Download Complete' => {
- 'notification_display_name' => 'Download completed',
- 'notification_enabled' => 'True',
- 'x_language' => 'English',
- 'x_timezone' => 'PST'
+ 'Notification-Display_name' => 'Download completed',
+ 'Notification-Enabled' => 'True',
+ 'X-Language' => 'English',
+ 'X-Timezone' => 'PST'
}
}
@@ -111,7 +111,7 @@
callback_count = 0
EM.run {
puts "Client sending request"
- connect = EM_GNTP::Client.register(@input)
+ connect = EM_GNTP::Client.register(@input, 'localhost', DummyServerHelper::DEFAULT_PORT)
connect.each_ok_response do |resp|
puts "Client received OK response"
@@ -161,10 +161,10 @@
'request_method' => 'NOTIFY',
'encryption_id' => 'NONE'
}
- @input_hdrs = {'application_name' => 'SurfWriter',
- 'notification_id' => '999',
- 'notification_callback_context' => 'default',
- 'notification_callback_context_type' => 'confirm'
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
+ 'Notification-ID' => '999',
+ 'Notification-Callback-Context' => 'default',
+ 'Notification-Callback-Context-Type' => 'confirm'
}
@input = MarshalHelper.dummy_request(
@@ -178,7 +178,7 @@
EM.run {
puts "Client sending request"
- connect = EM_GNTP::Client.register(@input)
+ connect = EM_GNTP::Client.register(@input, 'localhost', DummyServerHelper::DEFAULT_PORT)
connect.each_ok_response do |resp|
puts "Client received OK response"
@@ -234,10 +234,10 @@
'request_method' => 'NOTIFY',
'encryption_id' => 'NONE'
}
- @input_hdrs = {'application_name' => 'SurfWriter',
- 'notification_id' => '999',
- 'notification_callback_context' => 'default',
- 'notification_callback_context_type' => 'confirm'
+ @input_hdrs = {'Application-Name' => 'SurfWriter',
+ 'Notification-ID' => '999',
+ 'Notification-Callback-Context' => 'default',
+ 'Notification-Callback-Context-Type' => 'confirm'
}
@input = MarshalHelper.dummy_request(
@@ -251,7 +251,7 @@
EM.run {
puts "Client sending request"
- connect = EM_GNTP::Client.register(@input)
+ connect = EM_GNTP::Client.register(@input, 'localhost', DummyServerHelper::DEFAULT_PORT)
connect.each_ok_response do |resp|
puts "Client received OK response"
View
57 spec/shared/dummy_server.rb
@@ -6,7 +6,7 @@ class Server < EM::Connection
include EM_GNTP::Constants
DEFAULT_HOST = 'localhost'
- DEFAULT_PORT = 23053
+ DEFAULT_PORT = 23052 # note one off to avoid port conflict
DEFAULT_RESPONSES = { :register => ['-OK', 0],
:notify => ['-OK', 0],
@@ -54,10 +54,10 @@ def post_init
def receive_data data
@buffer.extract(data).each do |line|
- #puts "#{line.inspect}"
+ update_message_state!(line)
@lines << line
- receive_message @lines.join("\r\n") + "\r\n" if eof?
end
+ receive_message @lines.join("\r\n") + "\r\n" if eof?
end
protected
@@ -66,10 +66,29 @@ def reset_state
@buffer = BufferedTokenizer.new("\r\n")
@lines = []
@response = nil
+ @sections_left = 0
+ end
+
+ # Horribly kludgy but that's GNTP for you...
+ def update_message_state!(line)
+ if line[/^\s*Notifications-Count\s*:\s*(\d+)/i]
+ @sections_left += $1.to_i
+ end
+ if line[/^.+:\s*x-growl-resource:/i]
+ @sections_left += 1
+ end
+ if line.empty?
+ @sections_left -= 1
+ end
+ #puts line
+ #puts "Note: #{@sections_left} more sections"
end
def eof?
- @lines[-2..-1] == ['','']
+ if @lines[-1].empty? && @sections_left > 0
+ puts "SERVER: CRLFCRLF received, but expecting #{@sections_left} more sections"
+ end
+ @lines[-1].empty? && @sections_left <= 0
end
def receive_message message
@@ -102,7 +121,7 @@ def prepare_responses_for(req)
canned_responses[:callback][0],
canned_responses[:callback][1]
) \
- if req['headers']['notification_callback_context']
+ if req['headers']['Notification-Callback-Context']
end
end
@@ -110,10 +129,10 @@ def prepare_responses_for(req)
def prepare_register_response_for(req, meth, err)
env, hdrs = req[ENVIRONMENT_KEY], req[HEADERS_KEY]
out = []
- out << "#{env[underscorize(GNTP_PROTOCOL_KEY)]}" +
- "/#{env[underscorize(GNTP_VERSION_KEY)]} "+
+ out << "#{env[(GNTP_PROTOCOL_KEY)]}" +
+ "/#{env[(GNTP_VERSION_KEY)]} "+
"#{meth} "+
- "#{env[underscorize(GNTP_ENCRYPTION_ID_KEY)]}"
+ "#{env[(GNTP_ENCRYPTION_ID_KEY)]}"
out << "#{GNTP_RESPONSE_ACTION_KEY}: #{GNTP_REGISTER_METHOD}"
if meth == GNTP_ERROR_RESPONSE
out << "#{GNTP_ERROR_CODE_KEY}: #{err}"
@@ -129,12 +148,12 @@ def prepare_register_response_for(req, meth, err)
def prepare_notify_response_for(req, meth, err)
env, hdrs = req[ENVIRONMENT_KEY], req[HEADERS_KEY]
out = []
- out << "#{env[underscorize(GNTP_PROTOCOL_KEY)]}" +
- "/#{env[underscorize(GNTP_VERSION_KEY)]} "+
+ out << "#{env[(GNTP_PROTOCOL_KEY)]}" +
+ "/#{env[(GNTP_VERSION_KEY)]} "+
"#{meth} "+
- "#{env[underscorize(GNTP_ENCRYPTION_ID_KEY)]}"
+ "#{env[(GNTP_ENCRYPTION_ID_KEY)]}"
out << "#{GNTP_RESPONSE_ACTION_KEY}: #{GNTP_NOTIFY_METHOD}"
- out << "#{GNTP_NOTIFICATION_ID_KEY}: #{hdrs[underscorize(GNTP_NOTIFICATION_ID_KEY)]}"
+ out << "#{GNTP_NOTIFICATION_ID_KEY}: #{hdrs[(GNTP_NOTIFICATION_ID_KEY)]}"
if meth == GNTP_ERROR_RESPONSE
out << "#{GNTP_ERROR_CODE_KEY}: #{err}"
out << "Error-Description: An error occurred"
@@ -158,16 +177,16 @@ def schedule_callback_response_for(req, rslt, secs)
def callback_response_for(req, rslt)
env, hdrs = req[ENVIRONMENT_KEY], req[HEADERS_KEY]
out = []
- out << "#{env[underscorize(GNTP_PROTOCOL_KEY)]}" +
- "/#{env[underscorize(GNTP_VERSION_KEY)]} "+
+ out << "#{env[(GNTP_PROTOCOL_KEY)]}" +
+ "/#{env[(GNTP_VERSION_KEY)]} "+
"#{GNTP_CALLBACK_RESPONSE} "+
- "#{env[underscorize(GNTP_ENCRYPTION_ID_KEY)]}"
- out << "#{GNTP_APPLICATION_NAME_KEY}: #{hdrs[underscorize(GNTP_APPLICATION_NAME_KEY)]}"
- out << "#{GNTP_NOTIFICATION_ID_KEY}: #{hdrs[underscorize(GNTP_NOTIFICATION_ID_KEY)]}"
+ "#{env[(GNTP_ENCRYPTION_ID_KEY)]}"
+ out << "#{GNTP_APPLICATION_NAME_KEY}: #{hdrs[(GNTP_APPLICATION_NAME_KEY)]}"
+ out << "#{GNTP_NOTIFICATION_ID_KEY}: #{hdrs[(GNTP_NOTIFICATION_ID_KEY)]}"
out << "#{GNTP_NOTIFICATION_CALLBACK_RESULT_KEY}: #{rslt}"
out << "#{GNTP_NOTIFICATION_CALLBACK_TIMESTAMP_KEY}: #{Time.now.strftime('%Y-%m-%d %H:%M:%SZ')}"
- out << "#{GNTP_NOTIFICATION_CALLBACK_CONTEXT_KEY}: #{hdrs[underscorize(GNTP_NOTIFICATION_CALLBACK_CONTEXT_KEY)]}"
- out << "#{GNTP_NOTIFICATION_CALLBACK_CONTEXT_TYPE_KEY}: #{hdrs[underscorize(GNTP_NOTIFICATION_CALLBACK_CONTEXT_TYPE_KEY)]}"
+ out << "#{GNTP_NOTIFICATION_CALLBACK_CONTEXT_KEY}: #{hdrs[(GNTP_NOTIFICATION_CALLBACK_CONTEXT_KEY)]}"
+ out << "#{GNTP_NOTIFICATION_CALLBACK_CONTEXT_TYPE_KEY}: #{hdrs[(GNTP_NOTIFICATION_CALLBACK_CONTEXT_TYPE_KEY)]}"
out << nil
out << nil
out << nil
View
4 spec/shared/dummy_server_helper.rb
@@ -1,6 +1,8 @@
module DummyServerHelper
-
+
+ DEFAULT_PORT = EM_GNTP::Dummy::Server::DEFAULT_PORT
+
def self.fork_server(opts = {})
fork {
puts '-------------- server process fork ------------------'
View
5 spec/shared/marshal_helper.rb
@@ -29,7 +29,10 @@ def initialize(input = [])
def self.dummy_request(env = {}, hdrs = {}, notifs = {})
klass = dummy_request_class
- klass.new({'environment' => env, 'headers' => hdrs, 'notifications' => notifs})
+ klass.new({'environment' => env,
+ 'headers' => hdrs,
+ 'notifications' => notifs
+ })
end
View
3  spec/unit/response_spec.rb
@@ -2,5 +2,6 @@
describe 'EM_GNTP::Response.load' do
-
+ it 'should have some tests' do end
+
end
View
92 spec/unit/route_spec.rb
@@ -0,0 +1,92 @@
+require File.join(File.dirname(__FILE__),'..','spec_helper')
+
+describe 'EM_GNTP::Route.parse' do
+
+ it 'should parse nil path' do
+ @subject = EM_GNTP::Route.parse 'action', nil
+ @subject.must_equal ['action', nil, nil, nil]
+ end
+
+ it 'should parse empty path' do
+ @subject = EM_GNTP::Route.parse 'action', ''
+ @subject.must_equal ['action', nil, nil, nil]
+ end
+
+ it 'should parse action and path' do
+ @subject = EM_GNTP::Route.parse 'action', 'name/context/type'
+ @subject.must_equal ['action', 'name', 'context', 'type']
+ end
+
+ it 'should parse * in path' do
+ @subject = EM_GNTP::Route.parse 'action', 'name/*/type'
+ @subject.must_equal ['action', 'name', nil, 'type']
+ end
+
+ it 'should parse * at start of path' do
+ @subject = EM_GNTP::Route.parse 'action', '*/context/type'
+ @subject.must_equal ['action', nil, 'context', 'type']
+ end
+
+ it 'should parse * at end of path' do
+ @subject = EM_GNTP::Route.parse 'action', 'name/context/*'
+ @subject.must_equal ['action', 'name', 'context', nil]
+ end
+
+ it 'should parse multiple *' do
+ @subject = EM_GNTP::Route.parse 'action', 'name/*/*'
+ @subject.must_equal ['action', 'name', nil, nil]
+ end
+
+ it 'should parse path with less than 3 parts' do
+ @subject = EM_GNTP::Route.parse 'action', 'name/context'
+ @subject.must_equal ['action', 'name', 'context', nil]
+ end
+
+ it 'should parse path with greater than 3 parts' do
+ @subject = EM_GNTP::Route.parse 'action', 'name/context/type/extra'
+ @subject.must_equal ['action', 'name', 'context', 'type']
+ end
+
+end
+
+describe 'EM_GNTP::Route.matches?' do
+
+ it 'should match identical pattern' do
+ @pattern = ['action', 'name', 'context', 'type']
+ EM_GNTP::Route.matches?(@pattern, ['action', 'name', 'context', 'type'])
+ end
+
+ it 'should match nil part of pattern' do
+ @pattern = ['action', 'name', nil, 'type']
+ EM_GNTP::Route.matches?(@pattern, ['action', 'name', 'context', 'type'])
+ end
+
+ it 'should match multiple nil parts of pattern' do
+ @pattern = [nil, 'name', nil, 'type']
+ EM_GNTP::Route.matches?(@pattern, ['action', 'name', 'context', 'type'])
+ end
+
+end
+
+describe 'EM_GNTP::Route#<=>' do
+
+ it 'should sort by standard array sort if no nil parts in pattern' do
+ subject = [ s1 = EM_GNTP::Route.new('action', 'b/c/d'),
+ s2 = EM_GNTP::Route.new('bacon', 'a/b/c'),
+ s3 = EM_GNTP::Route.new('action', 'a/b/c')
+ ]
+ subject.sort.must_equal [s3, s1, s2]
+ end
+
+ it 'should sort nil parts after non-nil parts in pattern' do
+ subject = [ s1 = EM_GNTP::Route.new('action', 'b/c/d'),
+ s2 = EM_GNTP::Route.new('bacon', 'a/b/c'),
+ s3 = EM_GNTP::Route.new('action', 'a/b/c'),
+ s4 = EM_GNTP::Route.new('action', '*/b/c'),
+ s5 = EM_GNTP::Route.new('action', 'a/*/c'),
+ s6 = EM_GNTP::Route.new('action', 'b/c/*')
+ ]
+ subject.sort.must_equal [s3, s5, s1, s6, s4, s2]
+ end
+
+end
Please sign in to comment.
Something went wrong with that request. Please try again.