sanford 0.15.1 → 0.16.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/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
|