sanford 0.8.0 → 0.9.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.
@@ -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