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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 944ab35171d45442e32e96a5587753f37ed50f0d
4
- data.tar.gz: c1e65e014055647553c5eaf4e9c055f8cb43afe5
3
+ metadata.gz: f8fea5a3ee747290419ad304a7468743ae765533
4
+ data.tar.gz: 4eb29b6427502b999924fd293dcc88d93e3204aa
5
5
  SHA512:
6
- metadata.gz: 6b5d57ba581c5676c1670f8eb6cece3d7442cf0a9d286d8848dc7726b806a493217c0ed8de6133da3c8596156e40f08e23bef60cab889c2915b1dd36972bd362
7
- data.tar.gz: 995bf2aeb75e3a5f6116aad7715d5d4cffd92f84d0bd1cc58c9a36593ee604c678487f313f8912aae68b66a80a60db18c15951743391f9e28322a3848a914095
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.0
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 [![Build Status](https://travis-ci.org/patriciomacadden/hobbit.png?branch=master)](https://travis-ci.org/patriciomacadden/hobbit) [![Code Climate](https://codeclimate.com/github/patriciomacadden/hobbit.png)](https://codeclimate.com/github/patriciomacadden/hobbit) [![Coverage Status](https://coveralls.io/repos/patriciomacadden/hobbit/badge.png?branch=master)](https://coveralls.io/r/patriciomacadden/hobbit) [![Dependency Status](https://gemnasium.com/patriciomacadden/hobbit.png)](https://gemnasium.com/patriciomacadden/hobbit) [![Gem Version](https://badge.fury.io/rb/hobbit.png)](http://badge.fury.io/rb/hobbit)
1
+ # Hobbit [![Build Status](http://img.shields.io/travis/patriciomacadden/hobbit.svg)](https://travis-ci.org/patriciomacadden/hobbit) [![Code Climate](http://img.shields.io/codeclimate/github/patriciomacadden/hobbit.svg)](https://codeclimate.com/github/patriciomacadden/hobbit) [![Code Climate Coverage](http://img.shields.io/codeclimate/coverage/github/patriciomacadden/hobbit.svg)](https://codeclimate.com/github/patriciomacadden/hobbit) [![Dependency Status](http://img.shields.io/gemnasium/patriciomacadden/hobbit.svg)](https://gemnasium.com/patriciomacadden/hobbit) [![Gem Version](http://img.shields.io/gem/v/hobbit.svg)](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 `Rack::Request` instance.
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`. You can also
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
- halt 401, { 'Content-Type' => 'text/html; charset=utf-8' }
230
- end
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
@@ -2,8 +2,8 @@ require 'bundler/gem_tasks'
2
2
  require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new do |t|
5
- t.libs << 'spec'
6
- t.pattern = 'spec/**/*_spec.rb'
5
+ t.libs << 'test'
6
+ t.pattern = 'test/**/*_test.rb'
7
7
  end
8
8
 
9
9
  task default: :test
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 'coveralls'
23
- spec.add_development_dependency 'minitest'
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
@@ -1,3 +1,4 @@
1
1
  require 'hobbit/base'
2
+ require 'hobbit/request'
2
3
  require 'hobbit/response'
3
4
  require 'hobbit/version'
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(env)
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 = Rack::Request.new(@env)
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(*res)
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
- catch :halt do
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
- response
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
@@ -0,0 +1,10 @@
1
+ require 'rack/request'
2
+
3
+ module Hobbit
4
+ class Request < Rack::Request
5
+ def initialize(env)
6
+ env['PATH_INFO'] = '/' if env['PATH_INFO'].empty?
7
+ super
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Hobbit
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
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
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ scope Hobbit::VERSION do
4
+ test "it's defined" do
5
+ assert defined? Hobbit::VERSION
6
+ end
7
+ 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.5.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-03-06 00:00:00.000000000 Z
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: coveralls
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: minitest
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
- - spec/base_spec.rb
117
- - spec/minitest_helper.rb
118
- - spec/response_spec.rb
119
- - spec/version_spec.rb
120
- homepage: ''
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.0
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
- - spec/base_spec.rb
146
- - spec/minitest_helper.rb
147
- - spec/response_spec.rb
148
- - spec/version_spec.rb
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
@@ -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
@@ -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
data/spec/version_spec.rb DELETED
@@ -1,7 +0,0 @@
1
- require 'minitest_helper'
2
-
3
- describe Hobbit::VERSION do
4
- it 'wont be nil' do
5
- Hobbit::VERSION.wont_be_nil
6
- end
7
- end