hobbit 0.5.0 → 0.6.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.
- checksums.yaml +4 -4
- data/.travis.yml +5 -1
- data/CHANGELOG.md +13 -0
- data/README.md +6 -60
- data/Rakefile +2 -2
- data/hobbit.gemspec +4 -3
- data/lib/hobbit.rb +1 -0
- data/lib/hobbit/base.rb +15 -17
- data/lib/hobbit/request.rb +10 -0
- data/lib/hobbit/version.rb +1 -1
- data/test/base_test.rb +239 -0
- data/test/helper.rb +25 -0
- data/test/request_test.rb +17 -0
- data/test/response_test.rb +129 -0
- data/test/version_test.rb +7 -0
- metadata +31 -14
- data/spec/base_spec.rb +0 -262
- data/spec/minitest_helper.rb +0 -22
- data/spec/response_spec.rb +0 -101
- data/spec/version_spec.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8fea5a3ee747290419ad304a7468743ae765533
|
4
|
+
data.tar.gz: 4eb29b6427502b999924fd293dcc88d93e3204aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 182223ff3e7dbc5fad224842851803d2fb6c72ee88077fbe790a733edfef827d712845c33162a8291d82168b8e380fe928e9031a9c0190f5ce898352c8ede349
|
7
|
+
data.tar.gz: 10ad33ce30a2a7bb9edd21737c33defbb6dd3d0db14e769064c8cb74258ff270b1ef03a6071d1ac0b60da222cb32d8771091b7c43d62cbe831d7d34a9475d146
|
data/.travis.yml
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
---
|
2
2
|
rvm:
|
3
3
|
- 2.0.0
|
4
|
-
- 2.1.
|
4
|
+
- 2.1.2
|
5
5
|
- ruby-head
|
6
|
+
addons:
|
7
|
+
code_climate:
|
8
|
+
repo_token:
|
9
|
+
secure: "bogVqPmJ2KlI2XK3Ln9Ki8vG08WTvKbKfvYm4ErD1A+2t3vg61utFKxJS8R3P5QKuDDIIX98eQC7r+gPeGEYwT+tDDFMnBsGQZcaeXJCYZQ3qLN36GpnPmpeZ3tTZwop5aT1AmMCF0IllDWYCjcWzeEZan23Eqt5YOyzTGAnr4g="
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
# 0.6.0
|
2
|
+
|
3
|
+
* Change the implementation of `Hobbit::Base#halt`. This new implementation is
|
4
|
+
more rack compliant.
|
5
|
+
* Test hobbit with [oktobertest](https://github.com/patriciomacadden/oktobertest)
|
6
|
+
instead of minitest (Because reasons!).
|
7
|
+
|
8
|
+
# 0.5.1 (Unreleased)
|
9
|
+
|
10
|
+
* A class is an object too, so allow to `run` classes.
|
11
|
+
* Add `Hobbit::Request`, which sets the path info to `/` if its empty (instead
|
12
|
+
of doing that on the call method).
|
13
|
+
|
1
14
|
# 0.5.0
|
2
15
|
|
3
16
|
* Refactor `Hobbit::Base#halt`. It now sets the status, merges the headers and
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Hobbit [](https://travis-ci.org/patriciomacadden/hobbit) [](https://codeclimate.com/github/patriciomacadden/hobbit) [](https://codeclimate.com/github/patriciomacadden/hobbit) [](https://gemnasium.com/patriciomacadden/hobbit) [](http://badge.fury.io/rb/hobbit)
|
2
2
|
|
3
3
|
A minimalistic microframework built on top of [Rack](http://rack.github.io/).
|
4
4
|
|
@@ -63,7 +63,7 @@ Create a `config.ru` file:
|
|
63
63
|
```ruby
|
64
64
|
require './app'
|
65
65
|
|
66
|
-
run App.new
|
66
|
+
run App.new # or just `run App`
|
67
67
|
```
|
68
68
|
|
69
69
|
Run it with `rackup`:
|
@@ -115,7 +115,7 @@ end
|
|
115
115
|
When a route gets called you have this methods available:
|
116
116
|
|
117
117
|
* `env`: The Rack environment.
|
118
|
-
* `request`: a `
|
118
|
+
* `request`: a `Hobbit::Request` instance.
|
119
119
|
* `response`: a `Hobbit::Response` instance.
|
120
120
|
|
121
121
|
And any other method defined in your application.
|
@@ -176,44 +176,7 @@ end
|
|
176
176
|
|
177
177
|
#### Halting
|
178
178
|
|
179
|
-
To immediately stop a request within route you can use `halt`.
|
180
|
-
specify a status:
|
181
|
-
|
182
|
-
```ruby
|
183
|
-
require 'hobbit'
|
184
|
-
|
185
|
-
class App < Hobbit::Base
|
186
|
-
use Rack::Session::Cookie, secret: SecureRandom.hex(64)
|
187
|
-
|
188
|
-
def session
|
189
|
-
env['rack.session']
|
190
|
-
end
|
191
|
-
|
192
|
-
get '/' do
|
193
|
-
halt 401 unless session['user_id']
|
194
|
-
end
|
195
|
-
end
|
196
|
-
```
|
197
|
-
|
198
|
-
Or body:
|
199
|
-
|
200
|
-
```ruby
|
201
|
-
require 'hobbit'
|
202
|
-
|
203
|
-
class App < Hobbit::Base
|
204
|
-
use Rack::Session::Cookie, secret: SecureRandom.hex(64)
|
205
|
-
|
206
|
-
def session
|
207
|
-
env['rack.session']
|
208
|
-
end
|
209
|
-
|
210
|
-
get '/' do
|
211
|
-
halt 401, 'This will be the body' unless session['user_id']
|
212
|
-
end
|
213
|
-
end
|
214
|
-
```
|
215
|
-
|
216
|
-
Or headers:
|
179
|
+
To immediately stop a request within route you can use `halt`.
|
217
180
|
|
218
181
|
```ruby
|
219
182
|
require 'hobbit'
|
@@ -226,25 +189,8 @@ class App < Hobbit::Base
|
|
226
189
|
end
|
227
190
|
|
228
191
|
get '/' do
|
229
|
-
|
230
|
-
|
231
|
-
end
|
232
|
-
```
|
233
|
-
|
234
|
-
Or both:
|
235
|
-
|
236
|
-
``` ruby
|
237
|
-
require 'hobbit'
|
238
|
-
|
239
|
-
class App < Hobbit::Base
|
240
|
-
use Rack::Session::Cookie, secret: SecureRandom.hex(64)
|
241
|
-
|
242
|
-
def session
|
243
|
-
env['rack.session']
|
244
|
-
end
|
245
|
-
|
246
|
-
get '/' do
|
247
|
-
halt 401, { 'Content-Type' => 'text/html; charset=utf-8' }, 'Woops'
|
192
|
+
response.status = 401
|
193
|
+
halt response.finish
|
248
194
|
end
|
249
195
|
end
|
250
196
|
```
|
data/Rakefile
CHANGED
data/hobbit.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ['patriciomacadden@gmail.com']
|
11
11
|
spec.description = %q{A minimalistic microframework built on top of rack}
|
12
12
|
spec.summary = %q{A minimalistic microframework built on top of rack}
|
13
|
-
spec.homepage = ''
|
13
|
+
spec.homepage = 'https://github.com/patriciomacadden/hobbit'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
@@ -19,8 +19,9 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
-
spec.add_development_dependency '
|
23
|
-
spec.add_development_dependency '
|
22
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
23
|
+
spec.add_development_dependency 'oktobertest'
|
24
|
+
spec.add_development_dependency 'oktobertest-contrib'
|
24
25
|
spec.add_development_dependency 'rack-test'
|
25
26
|
spec.add_development_dependency 'rake'
|
26
27
|
|
data/lib/hobbit.rb
CHANGED
data/lib/hobbit/base.rb
CHANGED
@@ -17,6 +17,10 @@ module Hobbit
|
|
17
17
|
stack
|
18
18
|
end
|
19
19
|
|
20
|
+
def call(env)
|
21
|
+
new.call env
|
22
|
+
end
|
23
|
+
|
20
24
|
def routes
|
21
25
|
@routes ||= Hash.new { |hash, key| hash[key] = [] }
|
22
26
|
end
|
@@ -43,38 +47,32 @@ module Hobbit
|
|
43
47
|
attr_reader :env, :request, :response
|
44
48
|
|
45
49
|
def call(env)
|
46
|
-
dup._call
|
50
|
+
dup._call env
|
47
51
|
end
|
48
52
|
|
49
53
|
def _call(env)
|
50
|
-
env['PATH_INFO'] = '/' if env['PATH_INFO'].empty?
|
51
54
|
@env = env
|
52
|
-
@request =
|
55
|
+
@request = Hobbit::Request.new @env
|
53
56
|
@response = Hobbit::Response.new
|
54
|
-
route_eval
|
55
|
-
@response.finish
|
57
|
+
catch(:halt) { route_eval }
|
56
58
|
end
|
57
59
|
|
58
|
-
def halt(
|
59
|
-
response.status = res.detect { |s| s.is_a? Fixnum } || 200
|
60
|
-
response.headers.merge! res.detect { |h| h.is_a? Hash } || {}
|
61
|
-
response.write res.detect { |b| b.is_a? String } || ''
|
62
|
-
|
60
|
+
def halt(response)
|
63
61
|
throw :halt, response
|
64
62
|
end
|
65
63
|
|
66
64
|
private
|
67
65
|
|
68
66
|
def route_eval
|
69
|
-
|
70
|
-
if route = find_route
|
71
|
-
response.write instance_eval(&route[:block])
|
72
|
-
else
|
73
|
-
halt 404
|
74
|
-
end
|
67
|
+
route = find_route
|
75
68
|
|
76
|
-
|
69
|
+
if route
|
70
|
+
response.write instance_eval(&route[:block])
|
71
|
+
else
|
72
|
+
response.status = 404
|
77
73
|
end
|
74
|
+
|
75
|
+
response.finish
|
78
76
|
end
|
79
77
|
|
80
78
|
def find_route
|
data/lib/hobbit/version.rb
CHANGED
data/test/base_test.rb
ADDED
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
scope Hobbit::Base do
|
4
|
+
setup do
|
5
|
+
mock_app do
|
6
|
+
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
7
|
+
class_eval "#{verb.downcase}('/') { '#{verb}' }"
|
8
|
+
class_eval "#{verb.downcase}('/route.json') { '#{verb} /route.json' }"
|
9
|
+
class_eval "#{verb.downcase}('/route/:id.json') { request.params[:id] }"
|
10
|
+
class_eval "#{verb.downcase}('/:name') { request.params[:name] }"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
16
|
+
scope "::#{verb.downcase}" do
|
17
|
+
test 'adds a route to @routes' do
|
18
|
+
route = app.to_app.class.routes[verb].first
|
19
|
+
assert_equal '/', route[:path]
|
20
|
+
end
|
21
|
+
|
22
|
+
test 'extracts the extra_params' do
|
23
|
+
route = app.to_app.class.routes[verb].last
|
24
|
+
assert_equal [:name], route[:extra_params]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
scope '::map' do
|
30
|
+
setup do
|
31
|
+
mock_app do
|
32
|
+
map '/map' do
|
33
|
+
run Proc.new { |env| [200, {}, ['from map']] }
|
34
|
+
end
|
35
|
+
|
36
|
+
get('/') { 'hello world' }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
test 'mounts an application to the rack stack' do
|
41
|
+
get '/map'
|
42
|
+
assert_equal 'from map', last_response.body
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
scope '::new' do
|
47
|
+
test 'returns an instance of Rack::Builder' do
|
48
|
+
assert_kind_of Rack::Builder, app
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
scope '::call' do
|
53
|
+
test 'creates a new instance and sends the call message' do
|
54
|
+
a = Class.new(Hobbit::Base) do
|
55
|
+
get '/' do
|
56
|
+
'hello world'
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
env = { 'PATH_INFO' => '/', 'REQUEST_METHOD' => 'GET' }
|
61
|
+
status, headers, body = a.call env
|
62
|
+
assert_equal ['hello world'], body
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
scope '::routes' do
|
67
|
+
test 'returns a Hash' do
|
68
|
+
assert_kind_of Hash, app.to_app.class.routes
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
scope '::stack' do
|
73
|
+
test 'returns an instance of Rack::Builder' do
|
74
|
+
assert_kind_of Rack::Builder, app.to_app.class.stack
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
scope '::use' do
|
79
|
+
setup do
|
80
|
+
mock_app do
|
81
|
+
middleware = Class.new do
|
82
|
+
def initialize(app = nil)
|
83
|
+
@app = app
|
84
|
+
end
|
85
|
+
|
86
|
+
def call(env)
|
87
|
+
request = Rack::Request.new(env)
|
88
|
+
@app.call(env) unless request.path_info == '/use'
|
89
|
+
[200, {}, 'from use']
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
use middleware
|
94
|
+
|
95
|
+
get('/') { 'hello world' }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
test 'adds a middleware to the rack stack' do
|
100
|
+
get '/use'
|
101
|
+
assert_equal 'from use', last_response.body
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
scope '::compile_route' do
|
106
|
+
def block
|
107
|
+
Proc.new { |env| [200, {}, []] }
|
108
|
+
end
|
109
|
+
|
110
|
+
test 'compiles /' do
|
111
|
+
path = '/'
|
112
|
+
route = Hobbit::Base.send :compile_route, path, &block
|
113
|
+
assert_equal block.call({}), route[:block].call({})
|
114
|
+
assert_equal /^\/$/.to_s, route[:compiled_path].to_s
|
115
|
+
assert_equal [], route[:extra_params]
|
116
|
+
assert_equal path, route[:path]
|
117
|
+
end
|
118
|
+
|
119
|
+
test 'compiles with .' do
|
120
|
+
path = '/route.json'
|
121
|
+
route = Hobbit::Base.send :compile_route, path, &block
|
122
|
+
assert_equal block.call({}), route[:block].call({})
|
123
|
+
assert_equal /^\/route.json$/.to_s, route[:compiled_path].to_s
|
124
|
+
assert_equal [], route[:extra_params]
|
125
|
+
assert_equal path, route[:path]
|
126
|
+
end
|
127
|
+
|
128
|
+
test 'compiles with -' do
|
129
|
+
path = '/hello-world'
|
130
|
+
route = Hobbit::Base.send :compile_route, path, &block
|
131
|
+
assert_equal block.call({}), route[:block].call({})
|
132
|
+
assert_equal /^\/hello-world$/.to_s, route[:compiled_path].to_s
|
133
|
+
assert_equal [], route[:extra_params]
|
134
|
+
assert_equal path, route[:path]
|
135
|
+
end
|
136
|
+
|
137
|
+
test 'compiles with params' do
|
138
|
+
path = '/hello/:name'
|
139
|
+
route = Hobbit::Base.send :compile_route, path, &block
|
140
|
+
assert_equal block.call({}), route[:block].call({})
|
141
|
+
assert_equal /^\/hello\/([^\/?#]+)$/.to_s, route[:compiled_path].to_s
|
142
|
+
assert_equal [:name], route[:extra_params]
|
143
|
+
assert_equal path, route[:path]
|
144
|
+
|
145
|
+
path = '/say/:something/to/:someone'
|
146
|
+
route = Hobbit::Base.send :compile_route, path, &block
|
147
|
+
assert_equal block.call({}), route[:block].call({})
|
148
|
+
assert_equal /^\/say\/([^\/?#]+)\/to\/([^\/?#]+)$/.to_s, route[:compiled_path].to_s
|
149
|
+
assert_equal [:something, :someone], route[:extra_params]
|
150
|
+
assert_equal path, route[:path]
|
151
|
+
end
|
152
|
+
|
153
|
+
test 'compiles with . and params' do
|
154
|
+
path = '/route/:id.json'
|
155
|
+
route = Hobbit::Base.send :compile_route, path, &block
|
156
|
+
assert_equal block.call({}), route[:block].call({})
|
157
|
+
assert_equal /^\/route\/([^\/?#]+).json$/.to_s, route[:compiled_path].to_s
|
158
|
+
assert_equal [:id], route[:extra_params]
|
159
|
+
assert_equal path, route[:path]
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
scope '#call' do
|
164
|
+
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
165
|
+
scope 'when the request matches a route' do
|
166
|
+
test "matches #{verb} ''" do
|
167
|
+
send verb.downcase, ''
|
168
|
+
assert last_response.ok?
|
169
|
+
assert_equal verb, last_response.body
|
170
|
+
end
|
171
|
+
|
172
|
+
test 'matches #{verb} /' do
|
173
|
+
send verb.downcase, '/'
|
174
|
+
assert last_response.ok?
|
175
|
+
assert_equal verb, last_response.body
|
176
|
+
end
|
177
|
+
|
178
|
+
test 'matches #{verb} /route.json' do
|
179
|
+
send verb.downcase, '/route.json'
|
180
|
+
assert last_response.ok?
|
181
|
+
assert_equal "#{verb} /route.json", last_response.body
|
182
|
+
end
|
183
|
+
|
184
|
+
test 'matches #{verb} /route/:id.json' do
|
185
|
+
send verb.downcase, '/route/1.json'
|
186
|
+
assert last_response.ok?
|
187
|
+
assert_equal '1', last_response.body
|
188
|
+
end
|
189
|
+
|
190
|
+
test 'matches #{verb} /:name' do
|
191
|
+
send verb.downcase, '/hobbit'
|
192
|
+
assert last_response.ok?
|
193
|
+
assert_equal 'hobbit', last_response.body
|
194
|
+
|
195
|
+
send verb.downcase, '/hello-hobbit'
|
196
|
+
assert last_response.ok?
|
197
|
+
assert_equal 'hello-hobbit', last_response.body
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
scope 'when the request not matches a route' do
|
202
|
+
test 'responds with 404 status code' do
|
203
|
+
send verb.downcase, '/not/found'
|
204
|
+
assert last_response.not_found?
|
205
|
+
assert_equal '', last_response.body
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
scope '#halt' do
|
212
|
+
setup do
|
213
|
+
mock_app do
|
214
|
+
get '/halt' do
|
215
|
+
response.status = 501
|
216
|
+
halt response.finish
|
217
|
+
end
|
218
|
+
|
219
|
+
get '/halt_finished' do
|
220
|
+
halt [404, {}, ['Not found']]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
test 'halts the execution with a response' do
|
226
|
+
get '/halt'
|
227
|
+
assert_status 501
|
228
|
+
end
|
229
|
+
|
230
|
+
test 'halts the execution with a finished response' do
|
231
|
+
get '/halt_finished'
|
232
|
+
assert_status 404
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
test 'responds to call' do
|
237
|
+
assert app.to_app.respond_to? :call
|
238
|
+
end
|
239
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'codeclimate-test-reporter'
|
4
|
+
CodeClimate::TestReporter.start
|
5
|
+
|
6
|
+
require 'oktobertest'
|
7
|
+
require 'oktobertest/contrib'
|
8
|
+
require 'rack'
|
9
|
+
require 'rack/test'
|
10
|
+
|
11
|
+
require 'hobbit'
|
12
|
+
|
13
|
+
module Oktobertest
|
14
|
+
class Test
|
15
|
+
include Rack::Test::Methods
|
16
|
+
|
17
|
+
def mock_app(&block)
|
18
|
+
@app = Class.new(Hobbit::Base, &block).new
|
19
|
+
end
|
20
|
+
|
21
|
+
def app
|
22
|
+
@app
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
scope Hobbit::Request do
|
4
|
+
scope '#initialize' do
|
5
|
+
test "sets the path info to / if it's empty" do
|
6
|
+
env = { 'PATH_INFO' => '', 'REQUEST_METHOD' => 'GET' }
|
7
|
+
request = Hobbit::Request.new env
|
8
|
+
assert_equal '/', request.path_info
|
9
|
+
end
|
10
|
+
|
11
|
+
test "doesn't change the path info if it's not empty" do
|
12
|
+
env = { 'PATH_INFO' => '/hello_world', 'REQUEST_METHOD' => 'GET' }
|
13
|
+
request = Hobbit::Request.new env
|
14
|
+
assert_equal '/hello_world', request.path_info
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
scope Hobbit::Response do
|
4
|
+
scope '#initialize' do
|
5
|
+
def default_headers
|
6
|
+
{ 'Content-Type' => 'text/html; charset=utf-8' }
|
7
|
+
end
|
8
|
+
|
9
|
+
test 'sets the body, status and headers with no arguments given' do
|
10
|
+
response = Hobbit::Response.new
|
11
|
+
assert_equal 200, response.status
|
12
|
+
assert_equal default_headers, response.headers
|
13
|
+
assert_equal [], response.body
|
14
|
+
end
|
15
|
+
|
16
|
+
test 'sets the body, status and headers with arguments given' do
|
17
|
+
status, headers, body = 200, { 'Content-Type' => 'application/json' }, ['{"name": "Hobbit"}']
|
18
|
+
response = Hobbit::Response.new body, status, headers
|
19
|
+
assert_equal status, response.status
|
20
|
+
assert_equal headers, response.headers
|
21
|
+
assert_equal body, response.body
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'sets the body if the body is a string' do
|
25
|
+
response = Hobbit::Response.new 'hello world'
|
26
|
+
assert 200, response.status
|
27
|
+
assert default_headers, response.headers
|
28
|
+
assert ['hello world'], response.body
|
29
|
+
end
|
30
|
+
|
31
|
+
test 'raises a TypeError if body does not respond to :to_str or :each' do
|
32
|
+
assert_raises TypeError do
|
33
|
+
Hobbit::Response.new 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
scope '#[]' do
|
39
|
+
def response
|
40
|
+
Hobbit::Response.new
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'responds to #[]' do
|
44
|
+
assert response.respond_to? :[]
|
45
|
+
end
|
46
|
+
|
47
|
+
test 'returns a header' do
|
48
|
+
assert_equal 'text/html; charset=utf-8', response['Content-Type']
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
scope '#[]=' do
|
53
|
+
def response
|
54
|
+
Hobbit::Response.new
|
55
|
+
end
|
56
|
+
|
57
|
+
test 'responds to #[]=' do
|
58
|
+
assert response.respond_to? :[]=
|
59
|
+
end
|
60
|
+
|
61
|
+
test 'sets a header' do
|
62
|
+
content_type = 'text/html; charset=utf-8'
|
63
|
+
response['Content-Type'] = content_type
|
64
|
+
assert_equal content_type, response['Content-Type']
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
scope '#finish' do
|
69
|
+
def status
|
70
|
+
200
|
71
|
+
end
|
72
|
+
|
73
|
+
def headers
|
74
|
+
{ 'Content-Type' => 'application/json', 'Content-Length' => '18' }
|
75
|
+
end
|
76
|
+
|
77
|
+
def body
|
78
|
+
['{"name": "Hobbit"}']
|
79
|
+
end
|
80
|
+
|
81
|
+
test 'returns a 3 elements array with status, headers and body' do
|
82
|
+
response = Hobbit::Response.new body, status, headers
|
83
|
+
assert_equal [status, headers, body], response.finish
|
84
|
+
end
|
85
|
+
|
86
|
+
test 'calculates the Content-Length of the body' do
|
87
|
+
response = Hobbit::Response.new body, status, headers
|
88
|
+
s, h, b = response.finish
|
89
|
+
assert_includes h, 'Content-Length'
|
90
|
+
assert_equal '18', h['Content-Length']
|
91
|
+
end
|
92
|
+
|
93
|
+
test 'calculates the Content-Length of the body, even if the body is empty' do
|
94
|
+
response = Hobbit::Response.new
|
95
|
+
s, h, b = response.finish
|
96
|
+
assert_includes h, 'Content-Length'
|
97
|
+
assert_equal '0', h['Content-Length']
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
scope '#redirect' do
|
102
|
+
def response
|
103
|
+
@response ||= Hobbit::Response.new
|
104
|
+
end
|
105
|
+
|
106
|
+
test 'sets the Location header and the status code' do
|
107
|
+
response.redirect '/hello'
|
108
|
+
assert_equal '/hello', response.headers['Location']
|
109
|
+
assert_equal 302, response.status
|
110
|
+
end
|
111
|
+
|
112
|
+
test 'sets the Location header and the status code if given' do
|
113
|
+
response.redirect '/hello', 301
|
114
|
+
assert_equal '/hello', response.headers['Location']
|
115
|
+
assert_equal 301, response.status
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
scope '#write' do
|
120
|
+
def response
|
121
|
+
@response ||= Hobbit::Response.new
|
122
|
+
end
|
123
|
+
|
124
|
+
test 'appends the argument to the body of the response' do
|
125
|
+
response.write 'hello world'
|
126
|
+
assert_equal ['hello world'], response.body
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hobbit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patricio Mac Adden
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: codeclimate-test-reporter
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,21 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: oktobertest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: oktobertest-contrib
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - ">="
|
@@ -111,13 +125,15 @@ files:
|
|
111
125
|
- hobbit.gemspec
|
112
126
|
- lib/hobbit.rb
|
113
127
|
- lib/hobbit/base.rb
|
128
|
+
- lib/hobbit/request.rb
|
114
129
|
- lib/hobbit/response.rb
|
115
130
|
- lib/hobbit/version.rb
|
116
|
-
-
|
117
|
-
-
|
118
|
-
-
|
119
|
-
-
|
120
|
-
|
131
|
+
- test/base_test.rb
|
132
|
+
- test/helper.rb
|
133
|
+
- test/request_test.rb
|
134
|
+
- test/response_test.rb
|
135
|
+
- test/version_test.rb
|
136
|
+
homepage: https://github.com/patriciomacadden/hobbit
|
121
137
|
licenses:
|
122
138
|
- MIT
|
123
139
|
metadata: {}
|
@@ -137,12 +153,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
153
|
version: '0'
|
138
154
|
requirements: []
|
139
155
|
rubyforge_project:
|
140
|
-
rubygems_version: 2.2.
|
156
|
+
rubygems_version: 2.2.2
|
141
157
|
signing_key:
|
142
158
|
specification_version: 4
|
143
159
|
summary: A minimalistic microframework built on top of rack
|
144
160
|
test_files:
|
145
|
-
-
|
146
|
-
-
|
147
|
-
-
|
148
|
-
-
|
161
|
+
- test/base_test.rb
|
162
|
+
- test/helper.rb
|
163
|
+
- test/request_test.rb
|
164
|
+
- test/response_test.rb
|
165
|
+
- test/version_test.rb
|
data/spec/base_spec.rb
DELETED
@@ -1,262 +0,0 @@
|
|
1
|
-
require 'minitest_helper'
|
2
|
-
|
3
|
-
describe Hobbit::Base do
|
4
|
-
include Hobbit::Mock
|
5
|
-
include Rack::Test::Methods
|
6
|
-
|
7
|
-
def app
|
8
|
-
@app
|
9
|
-
end
|
10
|
-
|
11
|
-
before do
|
12
|
-
mock_app do
|
13
|
-
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
14
|
-
class_eval "#{verb.downcase}('/') { '#{verb}' }"
|
15
|
-
class_eval "#{verb.downcase}('/route.json') { '#{verb} /route.json' }"
|
16
|
-
class_eval "#{verb.downcase}('/route/:id.json') { request.params[:id] }"
|
17
|
-
class_eval "#{verb.downcase}('/:name') { request.params[:name] }"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
23
|
-
str = <<EOS
|
24
|
-
describe "::#{verb.downcase}" do
|
25
|
-
it 'must add a route to @routes' do
|
26
|
-
route = app.to_app.class.routes['#{verb}'].first
|
27
|
-
route[:path].must_equal '/'
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'must extract the extra_params' do
|
31
|
-
route = app.to_app.class.routes['#{verb}'].last
|
32
|
-
route[:extra_params].must_equal [:name]
|
33
|
-
end
|
34
|
-
end
|
35
|
-
EOS
|
36
|
-
class_eval str
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '::map' do
|
40
|
-
before do
|
41
|
-
mock_app do
|
42
|
-
map '/map' do
|
43
|
-
run Proc.new { |env| [200, {}, ['from map']] }
|
44
|
-
end
|
45
|
-
|
46
|
-
get('/') { 'hello world' }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'must mount a application to the rack stack' do
|
51
|
-
get '/map'
|
52
|
-
last_response.body.must_equal 'from map'
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe '::new' do
|
57
|
-
it 'should return an instance of Rack::Builder' do
|
58
|
-
app.must_be_kind_of Rack::Builder
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
describe '::routes' do
|
63
|
-
it 'must return a Hash' do
|
64
|
-
app.to_app.class.routes.must_be_kind_of Hash
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe '::stack' do
|
69
|
-
it 'must return an instance of Rack::Builder' do
|
70
|
-
app.to_app.class.stack.must_be_kind_of Rack::Builder
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
describe '::use' do
|
75
|
-
before do
|
76
|
-
mock_app do
|
77
|
-
middleware = Class.new do
|
78
|
-
def initialize(app = nil)
|
79
|
-
@app = app
|
80
|
-
end
|
81
|
-
|
82
|
-
def call(env)
|
83
|
-
request = Rack::Request.new(env)
|
84
|
-
@app.call(env) unless request.path_info == '/use'
|
85
|
-
[200, {}, 'from use']
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
use middleware
|
90
|
-
|
91
|
-
get('/') { 'hello world' }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'must add a middleware to the rack stack' do
|
96
|
-
get '/use'
|
97
|
-
last_response.body.must_equal 'from use'
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe '::compile_route' do
|
102
|
-
let(:block) { block = Proc.new { |env| [200, {}, []] } }
|
103
|
-
|
104
|
-
it 'must compile /' do
|
105
|
-
path = '/'
|
106
|
-
route = Hobbit::Base.send :compile_route, path, &block
|
107
|
-
route[:block].call({}).must_equal block.call({})
|
108
|
-
route[:compiled_path].to_s.must_equal /^\/$/.to_s
|
109
|
-
route[:extra_params].must_equal []
|
110
|
-
route[:path].must_equal path
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'must compile with .' do
|
114
|
-
path = '/route.json'
|
115
|
-
route = Hobbit::Base.send :compile_route, path, &block
|
116
|
-
route[:block].call({}).must_equal block.call({})
|
117
|
-
route[:compiled_path].to_s.must_equal /^\/route.json$/.to_s
|
118
|
-
route[:extra_params].must_equal []
|
119
|
-
route[:path].must_equal path
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'must compile with -' do
|
123
|
-
path = '/hello-world'
|
124
|
-
route = Hobbit::Base.send :compile_route, path, &block
|
125
|
-
route[:block].call({}).must_equal block.call({})
|
126
|
-
route[:compiled_path].to_s.must_equal /^\/hello-world$/.to_s
|
127
|
-
route[:extra_params].must_equal []
|
128
|
-
route[:path].must_equal path
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'must compile with params' do
|
132
|
-
path = '/hello/:name'
|
133
|
-
route = Hobbit::Base.send :compile_route, path, &block
|
134
|
-
route[:block].call({}).must_equal block.call({})
|
135
|
-
route[:compiled_path].to_s.must_equal /^\/hello\/([^\/?#]+)$/.to_s
|
136
|
-
route[:extra_params].must_equal [:name]
|
137
|
-
route[:path].must_equal path
|
138
|
-
|
139
|
-
path = '/say/:something/to/:someone'
|
140
|
-
route = Hobbit::Base.send :compile_route, path, &block
|
141
|
-
route[:block].call({}).must_equal block.call({})
|
142
|
-
route[:compiled_path].to_s.must_equal /^\/say\/([^\/?#]+)\/to\/([^\/?#]+)$/.to_s
|
143
|
-
route[:extra_params].must_equal [:something, :someone]
|
144
|
-
route[:path].must_equal path
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'must compile with . and params' do
|
148
|
-
path = '/route/:id.json'
|
149
|
-
route = Hobbit::Base.send :compile_route, path, &block
|
150
|
-
route[:block].call({}).must_equal block.call({})
|
151
|
-
route[:compiled_path].to_s.must_equal /^\/route\/([^\/?#]+).json$/.to_s
|
152
|
-
route[:extra_params].must_equal [:id]
|
153
|
-
route[:path].must_equal path
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
describe '#call' do
|
158
|
-
%w(DELETE GET HEAD OPTIONS PATCH POST PUT).each do |verb|
|
159
|
-
str = <<EOS
|
160
|
-
describe 'when the request matches a route' do
|
161
|
-
it 'must match #{verb} ""' do
|
162
|
-
#{verb.downcase} ''
|
163
|
-
last_response.must_be :ok?
|
164
|
-
last_response.body.must_equal '#{verb}'
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'must match #{verb} /' do
|
168
|
-
#{verb.downcase} '/'
|
169
|
-
last_response.must_be :ok?
|
170
|
-
last_response.body.must_equal '#{verb}'
|
171
|
-
end
|
172
|
-
|
173
|
-
it 'must match #{verb} /route.json' do
|
174
|
-
#{verb.downcase} '/route.json'
|
175
|
-
last_response.must_be :ok?
|
176
|
-
last_response.body.must_equal '#{verb} /route.json'
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'must match #{verb} /route/:id.json' do
|
180
|
-
#{verb.downcase} '/route/1.json'
|
181
|
-
last_response.must_be :ok?
|
182
|
-
last_response.body.must_equal '1'
|
183
|
-
end
|
184
|
-
|
185
|
-
it 'must match #{verb} /:name' do
|
186
|
-
#{verb.downcase} '/hobbit'
|
187
|
-
last_response.must_be :ok?
|
188
|
-
last_response.body.must_equal 'hobbit'
|
189
|
-
|
190
|
-
#{verb.downcase} '/hello-hobbit'
|
191
|
-
last_response.must_be :ok?
|
192
|
-
last_response.body.must_equal 'hello-hobbit'
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
describe 'when the request not matches a route' do
|
197
|
-
it 'must respond with 404 status code' do
|
198
|
-
#{verb.downcase} '/not/found'
|
199
|
-
last_response.must_be :not_found?
|
200
|
-
last_response.body.must_equal ''
|
201
|
-
end
|
202
|
-
end
|
203
|
-
EOS
|
204
|
-
class_eval str
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
describe '#halt' do
|
209
|
-
before do
|
210
|
-
mock_app do
|
211
|
-
get '/halt_fixnum' do
|
212
|
-
halt 501
|
213
|
-
response.write 'Hello world'
|
214
|
-
end
|
215
|
-
|
216
|
-
get '/halt_string' do
|
217
|
-
halt 'Halt!'
|
218
|
-
end
|
219
|
-
|
220
|
-
get '/halt_hash' do
|
221
|
-
halt({ header: 'OK' })
|
222
|
-
end
|
223
|
-
|
224
|
-
get '/halt_combined' do
|
225
|
-
halt 404, 'Not Found'
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'returns the response given to halt function' do
|
231
|
-
get '/halt_fixnum'
|
232
|
-
last_response.body.must_equal ''
|
233
|
-
last_response.headers.must_equal({ 'Content-Type' => 'text/html; charset=utf-8', 'Content-Length' => '0' })
|
234
|
-
last_response.status.must_equal 501
|
235
|
-
end
|
236
|
-
|
237
|
-
it 'accepts body' do
|
238
|
-
get '/halt_string'
|
239
|
-
last_response.body.must_equal 'Halt!'
|
240
|
-
last_response.headers.must_equal({ 'Content-Type' => 'text/html; charset=utf-8', 'Content-Length' => '5' })
|
241
|
-
last_response.status.must_equal 200
|
242
|
-
end
|
243
|
-
|
244
|
-
it 'accepts headers' do
|
245
|
-
get '/halt_hash'
|
246
|
-
last_response.body.must_equal ''
|
247
|
-
last_response.headers.must_equal({ 'Content-Type' => 'text/html; charset=utf-8', 'Content-Length' => '0', header: 'OK' })
|
248
|
-
last_response.status.must_equal 200
|
249
|
-
end
|
250
|
-
|
251
|
-
it 'accepts combinations' do
|
252
|
-
get '/halt_combined'
|
253
|
-
last_response.body.must_equal 'Not Found'
|
254
|
-
last_response.headers.must_equal({ 'Content-Type' => 'text/html; charset=utf-8', 'Content-Length' => '9' })
|
255
|
-
last_response.status.must_equal 404
|
256
|
-
end
|
257
|
-
end
|
258
|
-
|
259
|
-
it 'must respond to call' do
|
260
|
-
app.to_app.must_respond_to :call
|
261
|
-
end
|
262
|
-
end
|
data/spec/minitest_helper.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
ENV['RACK_ENV'] ||= 'test'
|
2
|
-
|
3
|
-
require 'bundler'
|
4
|
-
Bundler.require :default, ENV['RACK_ENV'].to_sym
|
5
|
-
|
6
|
-
require 'coveralls'
|
7
|
-
Coveralls.wear!
|
8
|
-
|
9
|
-
require 'minitest/autorun'
|
10
|
-
require 'rack'
|
11
|
-
require 'rack/test'
|
12
|
-
|
13
|
-
require 'hobbit'
|
14
|
-
|
15
|
-
module Hobbit
|
16
|
-
module Mock
|
17
|
-
def mock_app(&block)
|
18
|
-
app = Class.new Hobbit::Base, &block
|
19
|
-
@app = app.new
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/spec/response_spec.rb
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
require 'minitest_helper'
|
2
|
-
|
3
|
-
describe Hobbit::Response do
|
4
|
-
describe '#initialize' do
|
5
|
-
it 'must set the body, status and headers with no arguments given' do
|
6
|
-
default_headers = { 'Content-Type' => 'text/html; charset=utf-8' }
|
7
|
-
response = Hobbit::Response.new
|
8
|
-
response.status.must_equal 200
|
9
|
-
response.headers.must_equal default_headers
|
10
|
-
response.body.must_equal []
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'must set the body, status and headers with arguments given' do
|
14
|
-
status, headers, body = 200, { 'Content-Type' => 'application/json' }, ['{"name": "Hobbit"}']
|
15
|
-
response = Hobbit::Response.new body, status, headers
|
16
|
-
response.status.must_equal status
|
17
|
-
response.headers.must_equal headers
|
18
|
-
response.body.must_equal body
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'must raise a TypeError if body does not respond to :to_str or :each' do
|
22
|
-
proc { Hobbit::Response.new 1 }.must_raise TypeError
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '#[]' do
|
27
|
-
let(:response) { Hobbit::Response.new }
|
28
|
-
|
29
|
-
it 'must respond to #[]' do
|
30
|
-
response.must_respond_to :[]
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'must return a header' do
|
34
|
-
response['Content-Type'].must_equal 'text/html; charset=utf-8'
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe '#[]=' do
|
39
|
-
let(:response) { Hobbit::Response.new }
|
40
|
-
|
41
|
-
it 'must respond to #[]=' do
|
42
|
-
response.must_respond_to :[]=
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'must set a header' do
|
46
|
-
content_type = 'text/html; charset=utf-8'
|
47
|
-
response['Content-Type'] = content_type
|
48
|
-
response['Content-Type'].must_equal content_type
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
describe '#finish' do
|
53
|
-
let(:status) { 200 }
|
54
|
-
let(:headers) { { 'Content-Type' => 'application/json' } }
|
55
|
-
let(:body) { ['{"name": "Hobbit"}'] }
|
56
|
-
|
57
|
-
it 'must return a 3 elements array with status, headers and body' do
|
58
|
-
response = Hobbit::Response.new body, status, headers
|
59
|
-
response.finish.must_equal [status, headers, body]
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'must calculate the Content-Length of the body' do
|
63
|
-
response = Hobbit::Response.new body, status, headers
|
64
|
-
s, h, b = response.finish
|
65
|
-
h.must_include 'Content-Length'
|
66
|
-
h['Content-Length'].must_equal '18'
|
67
|
-
end
|
68
|
-
|
69
|
-
it 'must calculate the Content-Length of the body, even if the body is empty' do
|
70
|
-
response = Hobbit::Response.new
|
71
|
-
s, h, b = response.finish
|
72
|
-
h.must_include 'Content-Length'
|
73
|
-
h['Content-Length'].must_equal '0'
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
describe '#redirect' do
|
78
|
-
let(:response) { Hobbit::Response.new }
|
79
|
-
|
80
|
-
it 'must set the Location header and the status code' do
|
81
|
-
response.redirect '/hello'
|
82
|
-
response.headers['Location'].must_equal '/hello'
|
83
|
-
response.status.must_equal 302
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'must set the Location header and the status code if given' do
|
87
|
-
response.redirect '/hello', 301
|
88
|
-
response.headers['Location'].must_equal '/hello'
|
89
|
-
response.status.must_equal 301
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
describe '#write' do
|
94
|
-
let(:response) { Hobbit::Response.new }
|
95
|
-
|
96
|
-
it 'must append the argument to the body of the response' do
|
97
|
-
response.write 'hello world'
|
98
|
-
response.body.must_equal ['hello world']
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|