sanford 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,48 +7,55 @@ module Sanford
7
7
 
8
8
  ResponseArgs = Struct.new(:status, :data)
9
9
 
10
- attr_reader :handler_class, :request, :logger
11
-
12
10
  def self.included(klass)
13
- klass.class_eval{ extend ClassMethods }
11
+ klass.class_eval do
12
+ extend ClassMethods
13
+ include InstanceMethods
14
+ end
14
15
  end
15
16
 
16
- def initialize(handler_class, request, logger = nil)
17
- @handler_class, @request = handler_class, request
18
- @logger = logger || Sanford.config.logger
19
- @handler = @handler_class.new(self)
20
- self.init
21
- end
17
+ module InstanceMethods
22
18
 
23
- def init
24
- self.init!
25
- end
19
+ attr_reader :handler_class, :request, :logger
26
20
 
27
- def init!
28
- end
21
+ def initialize(handler_class, request, logger = nil)
22
+ @handler_class, @request = handler_class, request
23
+ @logger = logger || Sanford.config.logger
24
+ @handler = @handler_class.new(self)
25
+ self.init
26
+ end
29
27
 
30
- def run
31
- response_args = catch_halt{ self.run!(@handler) }
32
- Sanford::Protocol::Response.new(response_args.status, response_args.data)
33
- end
28
+ def init
29
+ self.init!
30
+ end
34
31
 
35
- def run!
36
- raise NotImplementedError
37
- end
32
+ def init!
33
+ end
38
34
 
39
- # It's best to keep what `halt` and `catch_halt` return in the same format.
40
- # Currently this is a `ResponseArgs` object. This is so no matter how the
41
- # block returns (either by throwing or running normally), you get the same
42
- # thing kind of object.
35
+ def run
36
+ response_args = catch_halt{ self.run!(@handler) }
37
+ Sanford::Protocol::Response.new(response_args.status, response_args.data)
38
+ end
43
39
 
44
- def halt(status, options = nil)
45
- options = OpenStruct.new(options || {})
46
- response_status = [ status, options.message ]
47
- throw :halt, ResponseArgs.new(response_status, options.data)
48
- end
40
+ def run!
41
+ raise NotImplementedError
42
+ end
43
+
44
+ # It's best to keep what `halt` and `catch_halt` return in the same format.
45
+ # Currently this is a `ResponseArgs` object. This is so no matter how the
46
+ # block returns (either by throwing or running normally), you get the same
47
+ # thing kind of object.
48
+
49
+ def halt(status, options = nil)
50
+ options = OpenStruct.new(options || {})
51
+ response_status = [ status, options.message ]
52
+ throw :halt, ResponseArgs.new(response_status, options.data)
53
+ end
54
+
55
+ def catch_halt(&block)
56
+ catch(:halt){ ResponseArgs.new(*block.call) }
57
+ end
49
58
 
50
- def catch_halt(&block)
51
- catch(:halt){ ResponseArgs.new(*block.call) }
52
59
  end
53
60
 
54
61
  module ClassMethods
@@ -9,6 +9,7 @@ module Sanford
9
9
 
10
10
  class Server
11
11
  include DatTCP::Server
12
+
12
13
  attr_reader :sanford_host, :sanford_host_data, :sanford_host_options
13
14
 
14
15
  def initialize(host, options = nil)
@@ -1,6 +1,3 @@
1
- require 'sanford-protocol'
2
- require 'sanford/runner'
3
-
4
1
  module Sanford
5
2
 
6
3
  module ServiceHandler
@@ -18,58 +15,60 @@ module Sanford
18
15
  def self.included(klass)
19
16
  klass.class_eval do
20
17
  extend ClassMethods
18
+ include InstanceMethods
21
19
  end
22
20
  end
23
21
 
24
- def initialize(runner)
25
- @sanford_runner = runner
26
- end
22
+ module InstanceMethods
27
23
 
28
- def init
29
- self.run_callback 'before_init'
30
- self.init!
31
- self.run_callback 'after_init'
32
- end
24
+ def initialize(runner)
25
+ @sanford_runner = runner
26
+ end
33
27
 
34
- def init!
35
- end
28
+ def init
29
+ self.run_callback 'before_init'
30
+ self.init!
31
+ self.run_callback 'after_init'
32
+ end
36
33
 
37
- def run
38
- self.run_callback 'before_run'
39
- data = self.run!
40
- self.run_callback 'after_run'
41
- [ 200, data ]
42
- end
34
+ def init!
35
+ end
43
36
 
44
- def run!
45
- raise NotImplementedError
46
- end
37
+ def run
38
+ self.run_callback 'before_run'
39
+ data = self.run!
40
+ self.run_callback 'after_run'
41
+ [ 200, data ]
42
+ end
47
43
 
48
- def inspect
49
- reference = '0x0%x' % (self.object_id << 1)
50
- "#<#{self.class}:#{reference} @request=#{self.request.inspect}>"
51
- end
44
+ def run!
45
+ raise NotImplementedError
46
+ end
52
47
 
53
- protected
48
+ def inspect
49
+ reference = '0x0%x' % (self.object_id << 1)
50
+ "#<#{self.class}:#{reference} @request=#{self.request.inspect}>"
51
+ end
54
52
 
55
- def before_init; end
56
- def after_init; end
57
- def before_run; end
58
- def after_run; end
53
+ protected
59
54
 
60
- # Helpers
55
+ # Helpers
61
56
 
62
- def run_handler(handler_class, params = nil)
63
- handler_class.run(params || {}, self.logger)
64
- end
57
+ def run_handler(handler_class, params = nil)
58
+ handler_class.run(params || {}, self.logger)
59
+ end
60
+
61
+ def halt(*args); @sanford_runner.halt(*args); end
62
+ def request; @sanford_runner.request; end
63
+ def params; self.request.params; end
64
+ def logger; @sanford_runner.logger; end
65
65
 
66
- def halt(*args); @sanford_runner.halt(*args); end
67
- def request; @sanford_runner.request; end
68
- def params; self.request.params; end
69
- def logger; @sanford_runner.logger; end
66
+ def run_callback(callback)
67
+ (self.class.send("#{callback}_callbacks") || []).each do |callback|
68
+ self.instance_eval(&callback)
69
+ end
70
+ end
70
71
 
71
- def run_callback(callback)
72
- self.send(callback.to_s)
73
72
  end
74
73
 
75
74
  module ClassMethods
@@ -78,6 +77,20 @@ module Sanford
78
77
  Sanford.config.runner.run(self, params || {}, logger)
79
78
  end
80
79
 
80
+ def before_init_callbacks; @before_init_callbacks ||= []; end
81
+ def after_init_callbacks; @after_init_callbacks ||= []; end
82
+ def before_run_callbacks; @before_run_callbacks ||= []; end
83
+ def after_run_callbacks; @after_run_callbacks ||= []; end
84
+
85
+ def before_init(&block); self.before_init_callbacks << block; end
86
+ def after_init(&block); self.after_init_callbacks << block; end
87
+ def before_run(&block); self.before_run_callbacks << block; end
88
+ def after_run(&block); self.after_run_callbacks << block; end
89
+ def prepend_before_init(&block); self.before_init_callbacks.unshift(block); end
90
+ def prepend_after_init(&block); self.after_init_callbacks.unshift(block); end
91
+ def prepend_before_run(&block); self.before_run_callbacks.unshift(block); end
92
+ def prepend_after_run(&block); self.after_run_callbacks.unshift(block); end
93
+
81
94
  end
82
95
 
83
96
  end
@@ -0,0 +1,19 @@
1
+ require 'sanford/test_runner'
2
+
3
+ module Sanford
4
+
5
+ module TestHelpers
6
+
7
+ module_function
8
+
9
+ def test_runner(handler_class, args = nil)
10
+ TestRunner.new(handler_class, args)
11
+ end
12
+
13
+ def test_handler(handler_class, args = nil)
14
+ test_runner(handler_class, args).handler
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -1,14 +1,24 @@
1
1
  require 'sanford-protocol'
2
-
3
2
  require 'sanford/runner'
3
+ require 'sanford/service_handler'
4
4
 
5
5
  module Sanford
6
6
 
7
+ InvalidServiceHandlerError = Class.new(RuntimeError)
8
+
7
9
  class TestRunner
8
10
  include Sanford::Runner
9
11
 
10
12
  attr_reader :handler, :response
11
13
 
14
+ def initialize(handler_class, *args)
15
+ if !handler_class.include?(Sanford::ServiceHandler)
16
+ raise InvalidServiceHandlerError, "#{handler_class.inspect} is not a"\
17
+ " Sanford::ServiceHandler"
18
+ end
19
+ super
20
+ end
21
+
12
22
  def init!
13
23
  if !@request.kind_of?(Sanford::Protocol::Request)
14
24
  @request = test_request(@request)
@@ -21,28 +31,23 @@ module Sanford
21
31
  # want to `run` at all.
22
32
 
23
33
  def run
24
- @response ||= build_response catch_halt{ @handler.run }
34
+ @response ||= build_response(catch_halt{ @handler.run }).tap do |response|
35
+ # attempt to serialize (and then throw away) the response data
36
+ # this will error on the developer if BSON can't serialize their response
37
+ Sanford::Protocol::BsonBody.new.encode(response.to_hash)
38
+ end
25
39
  end
26
40
 
27
41
  protected
28
42
 
29
43
  def test_request(params)
30
- Sanford::Protocol::Request.new('name', params)
44
+ Sanford::Protocol::Request.new('name', params || {})
31
45
  end
32
46
 
33
47
  def build_response(response_args)
34
48
  Sanford::Protocol::Response.new(response_args.status, response_args.data) if response_args
35
49
  end
36
50
 
37
- module Helpers
38
- module_function
39
-
40
- def test_runner(handler_class, params = nil, logger = nil)
41
- TestRunner.new(handler_class, params || {}, logger)
42
- end
43
-
44
- end
45
-
46
51
  end
47
52
 
48
53
  end
@@ -1,3 +1,3 @@
1
1
  module Sanford
2
- VERSION = "0.8.0"
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/sanford.rb CHANGED
@@ -13,14 +13,6 @@ ENV['SANFORD_SERVICES_FILE'] ||= 'config/services'
13
13
 
14
14
  module Sanford
15
15
 
16
- def self.register(host)
17
- @hosts.add(host)
18
- end
19
-
20
- def self.hosts
21
- @hosts
22
- end
23
-
24
16
  def self.config
25
17
  Sanford::Config
26
18
  end
@@ -35,6 +27,14 @@ module Sanford
35
27
  require self.config.services_file
36
28
  end
37
29
 
30
+ def self.register(host)
31
+ @hosts.add(host)
32
+ end
33
+
34
+ def self.hosts
35
+ @hosts
36
+ end
37
+
38
38
  module Config
39
39
  include NsOptions::Proxy
40
40
  option :services_file, Pathname, :default => ENV['SANFORD_SERVICES_FILE']
@@ -48,12 +48,22 @@ module Sanford
48
48
  @set = Set.new(values)
49
49
  end
50
50
 
51
+ def method_missing(method, *args, &block)
52
+ @set.send(method, *args, &block)
53
+ end
54
+
55
+ def respond_to?(method)
56
+ super || @set.respond_to?(method)
57
+ end
58
+
51
59
  # We want class names to take precedence over a configured name, so that if
52
60
  # a user specifies a specific class, they always get it
53
61
  def find(name)
54
- self.find_by_class_name(name) || self.find_by_name(name)
62
+ find_by_class_name(name) || find_by_name(name)
55
63
  end
56
64
 
65
+ private
66
+
57
67
  def find_by_class_name(class_name)
58
68
  @set.detect{|host_class| host_class.to_s == class_name.to_s }
59
69
  end
@@ -62,14 +72,6 @@ module Sanford
62
72
  @set.detect{|host_class| host_class.name == name.to_s }
63
73
  end
64
74
 
65
- def method_missing(method, *args, &block)
66
- @set.send(method, *args, &block)
67
- end
68
-
69
- def respond_to?(method)
70
- super || @set.respond_to?(method)
71
- end
72
-
73
75
  end
74
76
 
75
77
  end
data/sanford.gemspec CHANGED
@@ -18,10 +18,10 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
19
  gem.require_paths = ["lib"]
20
20
 
21
- gem.add_dependency("dat-tcp", ["~>0.4"])
22
- gem.add_dependency("ns-options", ["~>1.0"])
23
- gem.add_dependency("sanford-protocol", ["~>0.6"])
21
+ gem.add_dependency("dat-tcp", ["~> 0.4"])
22
+ gem.add_dependency("ns-options", ["~> 1.1"])
23
+ gem.add_dependency("sanford-protocol", ["~> 0.7"])
24
24
 
25
- gem.add_development_dependency("assert", ["~>2.3"])
26
- gem.add_development_dependency("assert-mocha", ["~>1.0"])
25
+ gem.add_development_dependency("assert", ["~> 2.10"])
26
+ gem.add_development_dependency("assert-mocha", ["~> 1.1"])
27
27
  end
@@ -1,71 +1,80 @@
1
- class TestServiceHandler
1
+ class BasicServiceHandler
2
2
  include Sanford::ServiceHandler
3
3
 
4
+ def run!
5
+ { 'name' => 'Joe Test', 'email' => "joe.test@example.com" }
6
+ end
7
+
4
8
  end
5
9
 
6
- class BasicServiceHandler
10
+ class SerializeErrorServiceHandler
7
11
  include Sanford::ServiceHandler
8
12
 
13
+ # return data that fails BSON serialization
14
+ # BSON errors if it is sent date/datetime values
9
15
  def run!
10
- { 'name' => 'Joe Test', 'email' => "joe.test@example.com" }
16
+ { 'date' => Date.today,
17
+ 'datetime' => DateTime.now
18
+ }
11
19
  end
12
20
 
13
21
  end
14
22
 
15
- class FlagServiceHandler
16
- include Sanford::ServiceHandler
23
+ module CallbackServiceHandler
17
24
 
18
- attr_reader :before_init_called, :init_bang_called, :after_init_called,
19
- :before_run_called, :run_bang_called, :after_run_called
25
+ def self.included(receiver)
26
+ receiver.class_eval do
27
+ attr_reader :before_init_called, :init_bang_called, :after_init_called
28
+ attr_reader :before_run_called, :run_bang_called, :after_run_called
29
+ attr_reader :second_before_init_called, :second_after_run_called
20
30
 
21
- def before_init
22
- @before_init_called = true
23
- end
31
+ before_init do
32
+ @before_init_called = true
33
+ end
34
+ before_init do
35
+ @second_before_init_called = true
36
+ end
24
37
 
25
- def init!
26
- @init_bang_called = true
27
- end
38
+ after_init do
39
+ @after_init_called = true
40
+ end
41
+
42
+ before_run do
43
+ @before_run_called = true
44
+ end
45
+
46
+ after_run do
47
+ @after_run_called = true
48
+ end
49
+ after_run do
50
+ @second_after_run_called = true
51
+ end
52
+
53
+ end
28
54
 
29
- def after_init
30
- @after_init_called = true
31
55
  end
32
56
 
33
- def before_run
34
- @before_run_called = true
57
+ def init!
58
+ @init_bang_called = true
35
59
  end
36
60
 
37
61
  def run!
38
62
  @run_bang_called = true
39
63
  end
40
64
 
41
- def after_run
42
- @after_run_called = true
43
- end
44
-
45
65
  end
46
66
 
47
- class RunOtherHandler
67
+ class FlagServiceHandler
48
68
  include Sanford::ServiceHandler
69
+ include CallbackServiceHandler
49
70
 
50
- def run!
51
- response = run_handler(HaltServiceHandler, 'code' => 200, 'data' => 'RunOtherHandler')
52
- response.data
53
- end
54
71
  end
55
72
 
56
- class HaltServiceHandler
73
+ class HaltingBehaviorServiceHandler
57
74
  include Sanford::ServiceHandler
75
+ include CallbackServiceHandler
58
76
 
59
- def run!
60
- halt params['code'], :message => params['message'], :data => params['data']
61
- end
62
-
63
- end
64
-
65
- class HaltingBehaviorServiceHandler < FlagServiceHandler
66
-
67
- def before_init
68
- super
77
+ before_init do
69
78
  halt_when('before_init')
70
79
  end
71
80
 
@@ -74,13 +83,11 @@ class HaltingBehaviorServiceHandler < FlagServiceHandler
74
83
  halt_when('init!')
75
84
  end
76
85
 
77
- def after_init
78
- super
86
+ after_init do
79
87
  halt_when('after_init')
80
88
  end
81
89
 
82
- def before_run
83
- super
90
+ before_run do
84
91
  halt_when('before_run')
85
92
  end
86
93
 
@@ -89,8 +96,7 @@ class HaltingBehaviorServiceHandler < FlagServiceHandler
89
96
  halt_when('run!')
90
97
  end
91
98
 
92
- def after_run
93
- super
99
+ after_run do
94
100
  halt_when('after_run')
95
101
  end
96
102
 
@@ -110,3 +116,23 @@ class HaltingBehaviorServiceHandler < FlagServiceHandler
110
116
  end
111
117
 
112
118
  end
119
+
120
+ class RunOtherHandler
121
+ include Sanford::ServiceHandler
122
+
123
+ def run!
124
+ response = run_handler(HaltServiceHandler, 'code' => 200, 'data' => 'RunOtherHandler')
125
+ response.data
126
+ end
127
+ end
128
+
129
+ class HaltServiceHandler
130
+ include Sanford::ServiceHandler
131
+
132
+ def run!
133
+ halt params['code'], :message => params['message'], :data => params['data']
134
+ end
135
+
136
+ end
137
+
138
+ class InvalidServiceHandler; end
@@ -26,7 +26,7 @@ class TestHost
26
26
 
27
27
  service_handler_ns 'TestHost'
28
28
 
29
- service 'echo', 'Echo'
29
+ service :echo, 'Echo'
30
30
  service 'bad', 'Bad'
31
31
  service 'multiply', 'Multiply'
32
32
  service 'halt_it', '::TestHost::HaltIt'
@@ -76,7 +76,7 @@ class TestHost
76
76
  class Authorized
77
77
  include Sanford::ServiceHandler
78
78
 
79
- def before_run
79
+ before_run do
80
80
  halt 401, :message => "Not authorized"
81
81
  end
82
82
 
@@ -1,4 +1,4 @@
1
- require 'sanford-protocol/test/fake_socket'
1
+ require 'sanford-protocol/fake_socket'
2
2
 
3
3
  class SimpleClient
4
4
 
@@ -56,7 +56,7 @@ class SimpleClient
56
56
  protected
57
57
 
58
58
  def call_using_fake_socket(method, *args)
59
- self.call(Sanford::Protocol::Test::FakeSocket.send(method, *args).in)
59
+ self.call(Sanford::Protocol::FakeSocket.send(method, *args).in)
60
60
  end
61
61
 
62
62
  end
@@ -1,5 +1,5 @@
1
1
  require 'assert'
2
- require 'sanford-protocol/test/fake_socket'
2
+ require 'sanford-protocol/fake_socket'
3
3
 
4
4
  # These tests are intended as a high level test against Sanford's server. They
5
5
  # use fake and real connections to test how Sanford behaves.
@@ -197,7 +197,7 @@ class RequestHandlingTests < Assert::Context
197
197
  :keep_alive => true
198
198
  })
199
199
  @server.on_run
200
- @socket = Sanford::Protocol::Test::FakeSocket.new
200
+ @socket = Sanford::Protocol::FakeSocket.new
201
201
  @fake_connection = FakeProtocolConnection.new(@socket)
202
202
  Sanford::Protocol::Connection.stubs(:new).with(@socket).returns(@fake_connection)
203
203
  end