sanford 0.15.1 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -2
- data/bench/config.sanford +11 -4
- data/bench/report.rb +1 -1
- data/bench/report.txt +37 -31
- data/lib/sanford/connection_handler.rb +0 -5
- data/lib/sanford/runner.rb +34 -28
- data/lib/sanford/sanford_runner.rb +5 -12
- data/lib/sanford/server.rb +57 -117
- data/lib/sanford/server_data.rb +13 -9
- data/lib/sanford/service_handler.rb +50 -23
- data/lib/sanford/test_runner.rb +30 -26
- data/lib/sanford/version.rb +1 -1
- data/lib/sanford/worker.rb +106 -0
- data/sanford.gemspec +2 -1
- data/test/support/app_server.rb +7 -4
- data/test/system/server_tests.rb +7 -3
- data/test/system/service_handler_tests.rb +1 -2
- data/test/unit/connection_handler_tests.rb +0 -16
- data/test/unit/runner_tests.rb +152 -41
- data/test/unit/sanford_runner_tests.rb +105 -63
- data/test/unit/server_data_tests.rb +34 -25
- data/test/unit/server_tests.rb +132 -210
- data/test/unit/service_handler_tests.rb +137 -64
- data/test/unit/test_runner_tests.rb +40 -101
- data/test/unit/worker_tests.rb +185 -0
- metadata +32 -15
- data/lib/sanford/test_helpers.rb +0 -19
- /data/{LICENSE.txt → LICENSE} +0 -0
@@ -1,12 +1,13 @@
|
|
1
|
+
require 'much-plugin'
|
2
|
+
|
1
3
|
module Sanford
|
2
4
|
|
3
5
|
module ServiceHandler
|
6
|
+
include MuchPlugin
|
4
7
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
include InstanceMethods
|
9
|
-
end
|
8
|
+
plugin_included do
|
9
|
+
extend ClassMethods
|
10
|
+
include InstanceMethods
|
10
11
|
end
|
11
12
|
|
12
13
|
module InstanceMethods
|
@@ -15,24 +16,29 @@ module Sanford
|
|
15
16
|
@sanford_runner = runner
|
16
17
|
end
|
17
18
|
|
18
|
-
def
|
19
|
-
|
19
|
+
def sanford_init
|
20
|
+
self.sanford_run_callback 'before_init'
|
20
21
|
self.init!
|
21
|
-
|
22
|
+
self.sanford_run_callback 'after_init'
|
22
23
|
end
|
23
24
|
|
24
25
|
def init!
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
-
|
28
|
+
def sanford_run
|
29
|
+
self.sanford_run_callback 'before_run'
|
29
30
|
data = self.run!
|
30
|
-
|
31
|
-
[
|
31
|
+
self.sanford_run_callback 'after_run'
|
32
|
+
[200, data]
|
32
33
|
end
|
33
34
|
|
34
35
|
def run!
|
35
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
def sanford_run_callback(callback)
|
39
|
+
(self.class.send("#{callback}_callbacks") || []).each do |callback|
|
40
|
+
self.instance_eval(&callback)
|
41
|
+
end
|
36
42
|
end
|
37
43
|
|
38
44
|
def inspect
|
@@ -40,21 +46,26 @@ module Sanford
|
|
40
46
|
"#<#{self.class}:#{reference} @request=#{request.inspect}>"
|
41
47
|
end
|
42
48
|
|
49
|
+
def ==(other_handler)
|
50
|
+
self.class == other_handler.class
|
51
|
+
end
|
52
|
+
|
43
53
|
private
|
44
54
|
|
45
55
|
# Helpers
|
46
56
|
|
47
|
-
|
48
|
-
def
|
49
|
-
def request; @sanford_runner.request; end
|
50
|
-
def params; @sanford_runner.params; end
|
51
|
-
def logger; @sanford_runner.logger; end
|
57
|
+
# utils
|
58
|
+
def logger; @sanford_runner.logger; end
|
52
59
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
60
|
+
# request
|
61
|
+
def request; @sanford_runner.request; end
|
62
|
+
def params; @sanford_runner.params; end
|
63
|
+
|
64
|
+
# response
|
65
|
+
def status(*args); @sanford_runner.status(*args); end
|
66
|
+
def data(*args); @sanford_runner.data(*args); end
|
67
|
+
def halt(*args); @sanford_runner.halt(*args); end
|
68
|
+
def render(*args); @sanford_runner.render(*args); end
|
58
69
|
|
59
70
|
end
|
60
71
|
|
@@ -83,6 +94,22 @@ module Sanford
|
|
83
94
|
|
84
95
|
end
|
85
96
|
|
97
|
+
module TestHelpers
|
98
|
+
|
99
|
+
def self.included(klass)
|
100
|
+
require 'sanford/test_runner'
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_runner(handler_class, args = nil)
|
104
|
+
TestRunner.new(handler_class, args)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_handler(handler_class, args = nil)
|
108
|
+
test_runner(handler_class, args).handler
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
86
113
|
end
|
87
114
|
|
88
115
|
end
|
data/lib/sanford/test_runner.rb
CHANGED
@@ -8,53 +8,57 @@ module Sanford
|
|
8
8
|
|
9
9
|
class TestRunner < Runner
|
10
10
|
|
11
|
-
attr_reader :response
|
12
|
-
|
13
11
|
def initialize(handler_class, args = nil)
|
14
12
|
if !handler_class.include?(Sanford::ServiceHandler)
|
15
|
-
raise InvalidServiceHandlerError, "#{handler_class.inspect} is not a"\
|
16
|
-
"
|
13
|
+
raise InvalidServiceHandlerError, "#{handler_class.inspect} is not a " \
|
14
|
+
"Sanford::ServiceHandler"
|
17
15
|
end
|
18
16
|
|
19
|
-
|
17
|
+
a = (args || {}).dup
|
20
18
|
super(handler_class, {
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
19
|
+
:logger => a.delete(:logger),
|
20
|
+
:router => a.delete(:router),
|
21
|
+
:template_source => a.delete(:template_source),
|
22
|
+
:request => a.delete(:request),
|
23
|
+
:params => normalize_params(a.delete(:params) || {})
|
26
24
|
})
|
27
|
-
|
25
|
+
a.each{ |key, value| @handler.send("#{key}=", value) }
|
28
26
|
|
29
|
-
|
30
|
-
|
27
|
+
@halted = false
|
28
|
+
catch(:halt){ self.handler.sanford_init }
|
31
29
|
end
|
32
30
|
|
33
|
-
|
34
|
-
# the `TestRunner` behave similar to the `SanfordRunner`, i.e. `halt` in
|
35
|
-
# `init` stops processing where `halt` is called.
|
31
|
+
def halted?; @halted; end
|
36
32
|
|
37
33
|
def run
|
38
|
-
|
34
|
+
catch(:halt){ self.handler.sanford_run } if !self.halted?
|
35
|
+
self.to_response
|
36
|
+
end
|
37
|
+
|
38
|
+
# attempt to encode (and then throw away) the response
|
39
|
+
# this will error on the developer if it can't encode their response
|
40
|
+
def to_response
|
41
|
+
super.tap do |response|
|
42
|
+
Sanford::Protocol.msg_body.encode(response.to_hash) if response
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# helpers
|
47
|
+
|
48
|
+
def halt(*args)
|
49
|
+
@halted = true
|
50
|
+
super
|
39
51
|
end
|
40
52
|
|
41
53
|
private
|
42
54
|
|
43
|
-
#
|
55
|
+
# stringify and encode/decode to ensure params are valid and are
|
44
56
|
# in the format they would normally be when a handler is built and run.
|
45
57
|
def normalize_params(params)
|
46
58
|
p = Sanford::Protocol::StringifyParams.new(params)
|
47
59
|
Sanford::Protocol.msg_body.decode(Sanford::Protocol.msg_body.encode(p))
|
48
60
|
end
|
49
61
|
|
50
|
-
def build_and_serialize_response(&block)
|
51
|
-
build_response(&block).tap do |response|
|
52
|
-
# attempt to serialize (and then throw away) the response data
|
53
|
-
# this will error on the developer if it can't serialize their response
|
54
|
-
Sanford::Protocol.msg_body.encode(response.to_hash) if response
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
62
|
end
|
59
63
|
|
60
64
|
end
|
data/lib/sanford/version.rb
CHANGED
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'much-plugin'
|
2
|
+
require 'dat-tcp/worker'
|
3
|
+
require 'sanford/connection_handler'
|
4
|
+
require 'sanford/server_data'
|
5
|
+
|
6
|
+
module Sanford
|
7
|
+
|
8
|
+
module Worker
|
9
|
+
include MuchPlugin
|
10
|
+
|
11
|
+
plugin_included do
|
12
|
+
include DatTCP::Worker
|
13
|
+
include InstanceMethods
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
|
19
|
+
def work!(client_socket)
|
20
|
+
connection = Connection.new(client_socket)
|
21
|
+
return if sanford_keep_alive_connection?(connection)
|
22
|
+
Sanford::ConnectionHandler.new(params[:sanford_server_data], connection).run
|
23
|
+
ensure
|
24
|
+
connection.close rescue false
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def sanford_keep_alive_connection?(connection)
|
30
|
+
params[:sanford_server_data].receives_keep_alive && connection.peek_data.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class Connection
|
36
|
+
DEFAULT_TIMEOUT = 1
|
37
|
+
|
38
|
+
attr_reader :timeout
|
39
|
+
|
40
|
+
def initialize(socket)
|
41
|
+
@socket = socket
|
42
|
+
@connection = Sanford::Protocol::Connection.new(@socket)
|
43
|
+
@timeout = (ENV['SANFORD_TIMEOUT'] || DEFAULT_TIMEOUT).to_f
|
44
|
+
end
|
45
|
+
|
46
|
+
def write_data(data)
|
47
|
+
TCPCork.apply(@socket)
|
48
|
+
@connection.write data
|
49
|
+
TCPCork.remove(@socket)
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_data; @connection.read(@timeout); end
|
53
|
+
def peek_data; @connection.peek(@timeout); end
|
54
|
+
def close; @connection.close; end
|
55
|
+
def close_write; @connection.close_write; end
|
56
|
+
end
|
57
|
+
|
58
|
+
module TCPCork
|
59
|
+
# On Linux, use TCP_CORK to better control how the TCP stack
|
60
|
+
# packetizes our stream. This improves both latency and throughput.
|
61
|
+
# TCP_CORK disables Nagle's algorithm, which is ideal for sporadic
|
62
|
+
# traffic (like Telnet) but is less optimal for HTTP. Sanford is similar
|
63
|
+
# to HTTP, it doesn't receive sporadic packets, it has all its data
|
64
|
+
# come in at once.
|
65
|
+
# For more information: http://baus.net/on-tcp_cork
|
66
|
+
|
67
|
+
if RUBY_PLATFORM =~ /linux/
|
68
|
+
# 3 == TCP_CORK
|
69
|
+
def self.apply(socket)
|
70
|
+
socket.setsockopt(::Socket::IPPROTO_TCP, 3, true)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.remove(socket)
|
74
|
+
socket.setsockopt(::Socket::IPPROTO_TCP, 3, false)
|
75
|
+
end
|
76
|
+
else
|
77
|
+
def self.apply(socket); end
|
78
|
+
def self.remove(socket); end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
module TestHelpers
|
83
|
+
include MuchPlugin
|
84
|
+
|
85
|
+
plugin_included do
|
86
|
+
include DatTCP::Worker::TestHelpers
|
87
|
+
include InstanceMethods
|
88
|
+
end
|
89
|
+
|
90
|
+
module InstanceMethods
|
91
|
+
|
92
|
+
def test_runner(worker_class, options = nil)
|
93
|
+
options ||= {}
|
94
|
+
options[:params] = {
|
95
|
+
:sanford_server_data => Sanford::ServerData.new,
|
96
|
+
}.merge(options[:params] || {})
|
97
|
+
super(worker_class, options)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
data/sanford.gemspec
CHANGED
@@ -18,7 +18,8 @@ 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.
|
21
|
+
gem.add_dependency("dat-tcp", ["~> 0.8"])
|
22
|
+
gem.add_dependency("much-plugin", ["~> 0.1"])
|
22
23
|
gem.add_dependency("ns-options", ["~> 1.1"])
|
23
24
|
gem.add_dependency("sanford-protocol", ["~> 0.11"])
|
24
25
|
|
data/test/support/app_server.rb
CHANGED
@@ -6,6 +6,9 @@ if !defined?(ROOT_PATH)
|
|
6
6
|
ROOT_PATH = Pathname.new(File.expand_path('../../..', __FILE__))
|
7
7
|
end
|
8
8
|
|
9
|
+
LOGGER = Logger.new(ROOT_PATH.join('log/app_server.log').to_s)
|
10
|
+
LOGGER.datetime_format = "" # turn off the datetime in the logs
|
11
|
+
|
9
12
|
class AppERBEngine < Sanford::TemplateEngine
|
10
13
|
RenderScope = Struct.new(:view)
|
11
14
|
|
@@ -26,7 +29,7 @@ class AppServer
|
|
26
29
|
|
27
30
|
receives_keep_alive true
|
28
31
|
|
29
|
-
logger
|
32
|
+
logger LOGGER
|
30
33
|
verbose_logging true
|
31
34
|
|
32
35
|
router do
|
@@ -62,7 +65,7 @@ module AppHandlers
|
|
62
65
|
include Sanford::ServiceHandler
|
63
66
|
|
64
67
|
def run!
|
65
|
-
params['message']
|
68
|
+
data(params['message'])
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
@@ -78,7 +81,7 @@ module AppHandlers
|
|
78
81
|
include Sanford::ServiceHandler
|
79
82
|
|
80
83
|
def run!
|
81
|
-
Class.new
|
84
|
+
data(Class.new)
|
82
85
|
end
|
83
86
|
end
|
84
87
|
|
@@ -121,7 +124,7 @@ module AppHandlers
|
|
121
124
|
|
122
125
|
def run!
|
123
126
|
halt(200, :message => "in run") if params['when'] == 'run'
|
124
|
-
false
|
127
|
+
data(false)
|
125
128
|
end
|
126
129
|
|
127
130
|
after_run do
|
data/test/system/server_tests.rb
CHANGED
@@ -284,7 +284,7 @@ module Sanford::Server
|
|
284
284
|
|
285
285
|
assert_equal 200, subject.code
|
286
286
|
assert_equal 'in after run', subject.status.message
|
287
|
-
|
287
|
+
assert_false subject.data
|
288
288
|
end
|
289
289
|
|
290
290
|
should "allow halting in an after callback" do
|
@@ -293,7 +293,7 @@ module Sanford::Server
|
|
293
293
|
|
294
294
|
assert_equal 200, subject.code
|
295
295
|
assert_equal 'in after', subject.status.message
|
296
|
-
|
296
|
+
assert_false subject.data
|
297
297
|
end
|
298
298
|
|
299
299
|
end
|
@@ -320,7 +320,11 @@ module Sanford::Server
|
|
320
320
|
setup do
|
321
321
|
# get our current ip address, need something different than 0.0.0.0 and
|
322
322
|
# 127.0.0.1 to bind to
|
323
|
-
ENV['SANFORD_IP']
|
323
|
+
ENV['SANFORD_IP'] = Socket.getaddrinfo(
|
324
|
+
Socket.gethostname,
|
325
|
+
80,
|
326
|
+
Socket::AF_INET
|
327
|
+
).first[3]
|
324
328
|
ENV['SANFORD_PORT'] = (AppServer.port + 1).to_s
|
325
329
|
|
326
330
|
@server = AppServer.new
|
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'assert'
|
2
2
|
require 'sanford/service_handler'
|
3
3
|
|
4
|
-
require 'sanford/test_helpers'
|
5
4
|
require 'test/support/app_server'
|
6
5
|
|
7
6
|
module Sanford::ServiceHandler
|
8
7
|
|
9
8
|
class SystemTests < Assert::Context
|
10
|
-
include Sanford::TestHelpers
|
9
|
+
include Sanford::ServiceHandler::TestHelpers
|
11
10
|
|
12
11
|
desc "Sanford::ServiceHandler"
|
13
12
|
|
@@ -142,22 +142,6 @@ class Sanford::ConnectionHandler
|
|
142
142
|
|
143
143
|
end
|
144
144
|
|
145
|
-
class RunWithExceptionWhileDebuggingTests < InitTests
|
146
|
-
desc "and run with a route that throws an exception in debug mode"
|
147
|
-
setup do
|
148
|
-
ENV['SANFORD_DEBUG'] = '1'
|
149
|
-
Assert.stub(@route, :run){ raise @exception }
|
150
|
-
end
|
151
|
-
teardown do
|
152
|
-
ENV.delete('SANFORD_DEBUG')
|
153
|
-
end
|
154
|
-
|
155
|
-
should "raise the exception" do
|
156
|
-
assert_raises(@exception.class){ @connection_handler.run }
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
145
|
class RunWithVerboseLoggingTests < UnitTests
|
162
146
|
desc "run with verbose logging"
|
163
147
|
setup do
|
data/test/unit/runner_tests.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'assert'
|
2
2
|
require 'sanford/runner'
|
3
3
|
|
4
|
+
require 'sanford-protocol'
|
4
5
|
require 'sanford/logger'
|
5
6
|
require 'sanford/router'
|
6
7
|
require 'sanford/template_source'
|
@@ -12,23 +13,35 @@ class Sanford::Runner
|
|
12
13
|
desc "Sanford::Runner"
|
13
14
|
setup do
|
14
15
|
@handler_class = TestServiceHandler
|
15
|
-
@runner_class
|
16
|
+
@runner_class = Sanford::Runner
|
16
17
|
end
|
17
18
|
subject{ @runner_class }
|
18
19
|
|
20
|
+
should "know its default status code " do
|
21
|
+
assert_equal 200, subject::DEFAULT_STATUS_CODE
|
22
|
+
end
|
23
|
+
|
24
|
+
should "know its default status msg " do
|
25
|
+
assert_equal nil, subject::DEFAULT_STATUS_MSG
|
26
|
+
end
|
27
|
+
|
28
|
+
should "know its default data" do
|
29
|
+
assert_equal nil, subject::DEFAULT_DATA
|
30
|
+
end
|
31
|
+
|
19
32
|
end
|
20
33
|
|
21
34
|
class InitTests < UnitTests
|
22
35
|
desc "when init"
|
23
36
|
setup do
|
24
|
-
|
25
|
-
@runner = @runner_class.new(@handler_class, :template_source => source)
|
37
|
+
@runner = @runner_class.new(@handler_class)
|
26
38
|
end
|
27
39
|
subject{ @runner }
|
28
40
|
|
29
41
|
should have_readers :handler_class, :handler
|
30
|
-
should have_readers :
|
31
|
-
should
|
42
|
+
should have_readers :logger, :router, :template_source
|
43
|
+
should have_readers :request, :params
|
44
|
+
should have_imeths :run, :to_response
|
32
45
|
should have_imeths :halt
|
33
46
|
|
34
47
|
should "know its handler class and handler" do
|
@@ -36,68 +49,166 @@ class Sanford::Runner
|
|
36
49
|
assert_instance_of @handler_class, subject.handler
|
37
50
|
end
|
38
51
|
|
39
|
-
should "default its
|
52
|
+
should "default its attrs" do
|
40
53
|
runner = @runner_class.new(@handler_class)
|
41
|
-
assert_nil runner.request
|
42
|
-
assert_equal ::Hash.new, runner.params
|
43
54
|
assert_kind_of Sanford::NullLogger, runner.logger
|
44
55
|
assert_kind_of Sanford::Router, runner.router
|
45
56
|
assert_kind_of Sanford::NullTemplateSource, runner.template_source
|
57
|
+
|
58
|
+
assert_nil runner.request
|
59
|
+
|
60
|
+
assert_equal({}, subject.params)
|
61
|
+
end
|
62
|
+
|
63
|
+
should "know its attrs" do
|
64
|
+
args = {
|
65
|
+
:logger => 'a-logger',
|
66
|
+
:router => 'a-router',
|
67
|
+
:template_source => 'a-source',
|
68
|
+
:request => 'a-request',
|
69
|
+
:params => {}
|
70
|
+
}
|
71
|
+
|
72
|
+
runner = @runner_class.new(@handler_class, args)
|
73
|
+
|
74
|
+
assert_equal args[:logger], runner.logger
|
75
|
+
assert_equal args[:router], runner.router
|
76
|
+
assert_equal args[:template_source], runner.template_source
|
77
|
+
assert_equal args[:request], runner.request
|
78
|
+
assert_equal args[:params], runner.params
|
46
79
|
end
|
47
80
|
|
48
81
|
should "not implement its run method" do
|
49
82
|
assert_raises(NotImplementedError){ subject.run }
|
50
83
|
end
|
51
84
|
|
52
|
-
should "
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
85
|
+
should "know its `to_response` representation" do
|
86
|
+
exp = Sanford::Protocol::Response.new(
|
87
|
+
[subject.class::DEFAULT_STATUS_CODE, subject.class::DEFAULT_STATUS_MSG],
|
88
|
+
subject.class::DEFAULT_DATA
|
89
|
+
)
|
90
|
+
assert_equal exp, subject.to_response
|
91
|
+
|
92
|
+
code, msg, data = Factory.integer, Factory.string, Factory.text
|
93
|
+
subject.status(code, :message => msg)
|
94
|
+
subject.data(data)
|
95
|
+
exp = Sanford::Protocol::Response.new([code, msg], data)
|
96
|
+
assert_equal exp, subject.to_response
|
57
97
|
end
|
58
98
|
|
59
|
-
should "
|
60
|
-
|
61
|
-
|
62
|
-
|
99
|
+
should "know and set its response status" do
|
100
|
+
assert_equal [nil, nil], subject.status
|
101
|
+
|
102
|
+
code, msg = Factory.integer, Factory.string
|
103
|
+
subject.status(code, :message => msg)
|
104
|
+
assert_equal [code, msg], subject.status
|
63
105
|
end
|
64
106
|
|
65
|
-
should "
|
66
|
-
|
67
|
-
message = Factory.string
|
68
|
-
data = Factory.string
|
107
|
+
should "know and set its response data" do
|
108
|
+
assert_nil subject.data
|
69
109
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
110
|
+
exp = Factory.text
|
111
|
+
subject.data exp
|
112
|
+
assert_equal exp, subject.data
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
class HaltTests < InitTests
|
118
|
+
desc "the `halt` method"
|
119
|
+
setup do
|
120
|
+
@code = Factory.integer
|
121
|
+
@message = Factory.string
|
122
|
+
@data = Factory.string
|
123
|
+
end
|
124
|
+
|
125
|
+
should "set response attrs and halt execution" do
|
126
|
+
runner = runner_halted_with()
|
127
|
+
assert_nil runner.status.first
|
128
|
+
assert_nil runner.status.last
|
129
|
+
assert_nil runner.data
|
130
|
+
|
131
|
+
runner = runner_halted_with(@code)
|
132
|
+
assert_equal @code, runner.status.first
|
133
|
+
assert_nil runner.status.last
|
134
|
+
assert_nil runner.data
|
135
|
+
|
136
|
+
runner = runner_halted_with(:message => @message)
|
137
|
+
assert_nil runner.status.first
|
138
|
+
assert_equal @message, runner.status.last
|
139
|
+
assert_nil runner.data
|
140
|
+
|
141
|
+
runner = runner_halted_with(:data => @data)
|
142
|
+
assert_nil runner.status.first
|
143
|
+
assert_nil runner.status.last
|
144
|
+
assert_equal @data, runner.data
|
145
|
+
|
146
|
+
runner = runner_halted_with(@code, :message => @message)
|
147
|
+
assert_equal @code, runner.status.first
|
148
|
+
assert_equal @message, runner.status.last
|
149
|
+
assert_nil runner.data
|
150
|
+
|
151
|
+
runner = runner_halted_with(@code, :data => @data)
|
152
|
+
assert_equal @code, runner.status.first
|
153
|
+
assert_nil runner.status.last
|
154
|
+
assert_equal @data, runner.data
|
155
|
+
|
156
|
+
runner = runner_halted_with({
|
157
|
+
:message => @message,
|
158
|
+
:data => @data
|
159
|
+
})
|
160
|
+
assert_nil runner.status.first
|
161
|
+
assert_equal @message, runner.status.last
|
162
|
+
assert_equal @data, runner.data
|
163
|
+
|
164
|
+
runner = runner_halted_with(@code, {
|
165
|
+
:message => @message,
|
166
|
+
:data => @data
|
167
|
+
})
|
168
|
+
assert_equal @code, runner.status.first
|
169
|
+
assert_equal @message, runner.status.last
|
170
|
+
assert_equal @data, runner.data
|
76
171
|
end
|
77
172
|
|
78
|
-
|
79
|
-
code = Factory.integer
|
80
|
-
message = Factory.string
|
81
|
-
data = Factory.string
|
173
|
+
private
|
82
174
|
|
83
|
-
|
84
|
-
|
175
|
+
def runner_halted_with(*halt_args)
|
176
|
+
@runner_class.new(@handler_class).tap do |runner|
|
177
|
+
catch(:halt){ runner.halt(*halt_args) }
|
85
178
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
class RenderTests < InitTests
|
184
|
+
desc "the `render` method"
|
185
|
+
setup do
|
186
|
+
@template_name = Factory.path
|
187
|
+
@locals = { Factory.string => Factory.string }
|
188
|
+
data = @data = Factory.text
|
189
|
+
@render_called_with = nil
|
190
|
+
@source = @runner.template_source
|
191
|
+
Assert.stub(@source, :render){ |*args| @render_called_with = args; data }
|
192
|
+
end
|
193
|
+
|
194
|
+
should "call to the template source's render method and set the return value as data" do
|
195
|
+
subject.render(@template_name, @locals)
|
196
|
+
exp = [@template_name, subject.handler, @locals]
|
197
|
+
assert_equal exp, @render_called_with
|
198
|
+
assert_equal @data, subject.data
|
199
|
+
end
|
200
|
+
|
201
|
+
should "default the locals if none given" do
|
202
|
+
subject.render(@template_name)
|
203
|
+
exp = [@template_name, subject.handler, {}]
|
204
|
+
assert_equal exp, @render_called_with
|
89
205
|
end
|
90
206
|
|
91
207
|
end
|
92
208
|
|
93
209
|
class TestServiceHandler
|
94
210
|
include Sanford::ServiceHandler
|
95
|
-
end
|
96
211
|
|
97
|
-
class FakeTemplateSource
|
98
|
-
def render(path, service_handler, locals)
|
99
|
-
[path.to_s, service_handler.class.to_s, locals]
|
100
|
-
end
|
101
212
|
end
|
102
213
|
|
103
214
|
end
|