renee-core 0.4.0.pre1 → 0.4.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +6 -0
- data/Gemfile +12 -0
- data/MIT-LICENSE.txt +7 -0
- data/README.md +242 -0
- data/Rakefile +24 -0
- data/lib/renee/core/chaining.rb +0 -1
- data/lib/renee/core/rack_interaction.rb +4 -4
- data/lib/renee/core/responding.rb +57 -20
- data/lib/renee/core/routing.rb +68 -41
- data/lib/renee/core/transform.rb +58 -0
- data/lib/renee/core/version.rb +5 -0
- data/lib/renee/core.rb +70 -22
- data/renee-core.gemspec +26 -0
- data/test/{renee-core/chaining_test.rb → chaining_test.rb} +0 -1
- data/test/{renee-core/include_test.rb → include_test.rb} +0 -0
- data/test/{renee-core/request_context_test.rb → request_context_test.rb} +0 -0
- data/test/{renee-core/responding_test.rb → responding_test.rb} +31 -1
- data/test/{renee-core/routing_test.rb → routing_test.rb} +0 -0
- data/test/test_helper.rb +2 -0
- data/test/{renee-core/variable_type_test.rb → variable_type_test.rb} +1 -1
- metadata +35 -35
- data/lib/renee/core/env_accessors.rb +0 -72
- data/lib/renee/core/matcher.rb +0 -61
- data/lib/renee/core/request_context.rb +0 -56
- data/lib/renee/core/response.rb +0 -78
- data/test/renee-core/env_accessors_test.rb +0 -43
- data/test/renee-core/test_helper.rb +0 -4
data/lib/renee/core/routing.rb
CHANGED
@@ -40,11 +40,11 @@ module Renee
|
|
40
40
|
# end
|
41
41
|
#
|
42
42
|
# @api public
|
43
|
-
def path(p
|
44
|
-
if
|
43
|
+
def path(p)
|
44
|
+
if block_given?
|
45
45
|
p = p[1, p.size] if p[0] == ?/
|
46
46
|
extension_part = detected_extension ? "|\\.#{Regexp.quote(detected_extension)}" : ""
|
47
|
-
part(/^\/#{Regexp.quote(p)}(?=\/|$#{extension_part})
|
47
|
+
part(/^\/#{Regexp.quote(p)}(?=\/|$#{extension_part})/) { yield }
|
48
48
|
else
|
49
49
|
create_chain_proxy(:path, p)
|
50
50
|
end
|
@@ -87,14 +87,17 @@ module Renee
|
|
87
87
|
# GET /test/hey/there #=> [200, {}, 'hey-there']
|
88
88
|
#
|
89
89
|
# @api public
|
90
|
-
def variable(
|
91
|
-
|
90
|
+
def variable(*types)
|
91
|
+
block_given? ?
|
92
|
+
complex_variable(types, '/', types.empty? ? 1 : types.size) { |*a| yield *a } :
|
93
|
+
create_chain_proxy(:variable, *types)
|
92
94
|
end
|
93
95
|
alias_method :var, :variable
|
94
96
|
chainable :variable, :var
|
95
97
|
|
96
|
-
def optional_variable(type = nil
|
97
|
-
|
98
|
+
def optional_variable(type = nil)
|
99
|
+
block_given? ?
|
100
|
+
complex_variable(type, '/', 0..1) { |vars| yield vars.first } : create_chain_proxy(:variable, type)
|
98
101
|
end
|
99
102
|
alias_method :optional, :optional_variable
|
100
103
|
chainable :optional, :optional_variable
|
@@ -102,8 +105,10 @@ module Renee
|
|
102
105
|
# Same as variable except you can match multiple variables with the same type.
|
103
106
|
# @param [Range, Integer] count The number of parameters to capture.
|
104
107
|
# @param [Symbol] type The type to use for match.
|
105
|
-
def multi_variable(count, type = nil
|
106
|
-
|
108
|
+
def multi_variable(count, type = nil)
|
109
|
+
block_given? ?
|
110
|
+
complex_variable(type, '/', count) { |mv| yield mv } :
|
111
|
+
create_chain_proxy(:multi_variable, count, type)
|
107
112
|
end
|
108
113
|
alias_method :multi_var, :multi_variable
|
109
114
|
alias_method :mvar, :multi_variable
|
@@ -111,8 +116,10 @@ module Renee
|
|
111
116
|
|
112
117
|
# Same as variable except it matches indefinitely.
|
113
118
|
# @param [Symbol] type The type to use for match.
|
114
|
-
def repeating_variable(type = nil
|
115
|
-
|
119
|
+
def repeating_variable(type = nil)
|
120
|
+
block_given? ?
|
121
|
+
complex_variable(type, '/', nil) { |mv| yield mv } :
|
122
|
+
create_chain_proxy(:repeating_variable, type)
|
116
123
|
end
|
117
124
|
alias_method :glob, :repeating_variable
|
118
125
|
chainable :repeating_variable, :glob
|
@@ -120,8 +127,10 @@ module Renee
|
|
120
127
|
# Match parts off the path as variables without a leading slash.
|
121
128
|
# @see #variable
|
122
129
|
# @api public
|
123
|
-
def partial_variable(type = nil
|
124
|
-
|
130
|
+
def partial_variable(type = nil)
|
131
|
+
block_given? ?
|
132
|
+
complex_variable(type, nil, 1) { |v| yield v } :
|
133
|
+
create_chain_proxy(:partial_variable, type)
|
125
134
|
end
|
126
135
|
alias_method :part_var, :partial_variable
|
127
136
|
chainable :partial_variable, :part_var
|
@@ -143,8 +152,8 @@ module Renee
|
|
143
152
|
# no_extension { |path| halt [200, {}, path] }
|
144
153
|
#
|
145
154
|
# @api public
|
146
|
-
def no_extension
|
147
|
-
|
155
|
+
def no_extension
|
156
|
+
yield unless detected_extension
|
148
157
|
end
|
149
158
|
|
150
159
|
# Match any remaining path.
|
@@ -153,8 +162,10 @@ module Renee
|
|
153
162
|
# remainder { |path| halt [200, {}, path] }
|
154
163
|
#
|
155
164
|
# @api public
|
156
|
-
def remainder
|
157
|
-
|
165
|
+
def remainder
|
166
|
+
block_given? ?
|
167
|
+
with_path_part(env['PATH_INFO']) { |var| yield var } :
|
168
|
+
create_chain_proxy(:remainder)
|
158
169
|
end
|
159
170
|
alias_method :catchall, :remainder
|
160
171
|
chainable :remainder, :catchall
|
@@ -165,8 +176,8 @@ module Renee
|
|
165
176
|
# get { halt [200, {}, "hello world"] }
|
166
177
|
#
|
167
178
|
# @api public
|
168
|
-
def get
|
169
|
-
|
179
|
+
def get
|
180
|
+
block_given? ? request_method('GET') { yield } : create_chain_proxy(:get)
|
170
181
|
end
|
171
182
|
chainable :get
|
172
183
|
|
@@ -176,8 +187,8 @@ module Renee
|
|
176
187
|
# post { halt [200, {}, "hello world"] }
|
177
188
|
#
|
178
189
|
# @api public
|
179
|
-
def post
|
180
|
-
|
190
|
+
def post
|
191
|
+
block_given? ? request_method('POST') { yield } : create_chain_proxy(:get)
|
181
192
|
end
|
182
193
|
chainable :post
|
183
194
|
|
@@ -187,19 +198,30 @@ module Renee
|
|
187
198
|
# put { halt [200, {}, "hello world"] }
|
188
199
|
#
|
189
200
|
# @api public
|
190
|
-
def put
|
191
|
-
|
201
|
+
def put
|
202
|
+
block_given? ? request_method('PUT') { yield } : create_chain_proxy(:get)
|
192
203
|
end
|
193
204
|
chainable :put
|
194
205
|
|
206
|
+
# Respond to a PATCH request and yield the block.
|
207
|
+
#
|
208
|
+
# @example
|
209
|
+
# put { halt [200, {}, "hello world"] }
|
210
|
+
#
|
211
|
+
# @api public
|
212
|
+
def patch
|
213
|
+
block_given? ? request_method('PATCH') { yield } : create_chain_proxy(:get)
|
214
|
+
end
|
215
|
+
chainable :patch
|
216
|
+
|
195
217
|
# Respond to a DELETE request and yield the block.
|
196
218
|
#
|
197
219
|
# @example
|
198
220
|
# delete { halt [200, {}, "hello world"] }
|
199
221
|
#
|
200
222
|
# @api public
|
201
|
-
def delete
|
202
|
-
|
223
|
+
def delete
|
224
|
+
block_given? ? request_method('DELETE') { yield } : create_chain_proxy(:get)
|
203
225
|
end
|
204
226
|
chainable :delete
|
205
227
|
|
@@ -209,9 +231,9 @@ module Renee
|
|
209
231
|
# complete { halt [200, {}, "hello world"] }
|
210
232
|
#
|
211
233
|
# @api public
|
212
|
-
def complete
|
213
|
-
if
|
214
|
-
with_path_part(env['PATH_INFO']) {
|
234
|
+
def complete
|
235
|
+
if block_given?
|
236
|
+
with_path_part(env['PATH_INFO']) { yield } if complete?
|
215
237
|
else
|
216
238
|
create_chain_proxy(:complete)
|
217
239
|
end
|
@@ -227,7 +249,8 @@ module Renee
|
|
227
249
|
#
|
228
250
|
# @api public
|
229
251
|
def complete?
|
230
|
-
(detected_extension and env['PATH_INFO'] =~ /^\/?(\.#{Regexp.quote(detected_extension)}\/?)?$/) ||
|
252
|
+
(detected_extension and env['PATH_INFO'] =~ /^\/?(\.#{Regexp.quote(detected_extension)}\/?)?$/) ||
|
253
|
+
(detected_extension.nil? and env['PATH_INFO'] =~ /^\/?$/)
|
231
254
|
end
|
232
255
|
|
233
256
|
# Match only when the path is ''.
|
@@ -236,10 +259,10 @@ module Renee
|
|
236
259
|
# empty { halt [200, {}, "hello world"] }
|
237
260
|
#
|
238
261
|
# @api public
|
239
|
-
def empty
|
240
|
-
if
|
262
|
+
def empty
|
263
|
+
if block_given?
|
241
264
|
if env['PATH_INFO'] == ''
|
242
|
-
with_path_part(env['PATH_INFO']) {
|
265
|
+
with_path_part(env['PATH_INFO']) { yield }
|
243
266
|
end
|
244
267
|
else
|
245
268
|
create_chain_proxy(:empty)
|
@@ -249,11 +272,10 @@ module Renee
|
|
249
272
|
|
250
273
|
private
|
251
274
|
def complex_variable(type, prefix, count)
|
252
|
-
matcher = variable_matcher_for_type(type)
|
253
275
|
path = env['PATH_INFO'].dup
|
254
276
|
vals = []
|
255
|
-
|
256
|
-
|
277
|
+
variable_matching_loop(count) do |idx|
|
278
|
+
matcher = variable_matcher_for_type(type.respond_to?(:at) ? type.at(idx) : type)
|
257
279
|
path.start_with?(prefix) ? path.slice!(0, prefix.size) : break if prefix
|
258
280
|
if match = matcher[path]
|
259
281
|
path.slice!(0, match.first.size)
|
@@ -272,9 +294,9 @@ module Renee
|
|
272
294
|
|
273
295
|
def variable_matching_loop(count)
|
274
296
|
case count
|
275
|
-
when Range then count.max.times { break unless yield }
|
276
|
-
when nil then loop { break unless yield }
|
277
|
-
else count.times { break unless yield }
|
297
|
+
when Range then count.max.times { |i| break unless yield i }
|
298
|
+
when nil then i = 0; loop { break unless yield i; i+= 1 }
|
299
|
+
else count.times { |i| break unless yield i }
|
278
300
|
end
|
279
301
|
end
|
280
302
|
|
@@ -304,14 +326,19 @@ module Renee
|
|
304
326
|
script_part = env['PATH_INFO'][0, part.size]
|
305
327
|
env['PATH_INFO'] = env['PATH_INFO'].slice(part.size, env['PATH_INFO'].size)
|
306
328
|
env['SCRIPT_NAME'] += script_part
|
329
|
+
@requested_http_methods.clear
|
307
330
|
yield script_part
|
308
331
|
raise NotMatchedError
|
309
332
|
end
|
310
333
|
|
311
334
|
def request_method(method)
|
312
|
-
if
|
313
|
-
|
314
|
-
|
335
|
+
if complete?
|
336
|
+
if env['REQUEST_METHOD'] == method
|
337
|
+
yield
|
338
|
+
raise NotMatchedError
|
339
|
+
else
|
340
|
+
@requested_http_methods << method
|
341
|
+
end
|
315
342
|
end
|
316
343
|
end
|
317
344
|
end
|
data/lib/renee/core/transform.rb
CHANGED
@@ -13,6 +13,64 @@ module Renee
|
|
13
13
|
m.first == value ? m.last : nil
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
# Class used for variable matching.
|
18
|
+
class Matcher
|
19
|
+
attr_accessor :name
|
20
|
+
|
21
|
+
# @param [Regexp] matcher The regexp matcher to determine what is part of the variable.
|
22
|
+
def initialize(matcher)
|
23
|
+
@matcher = matcher
|
24
|
+
end
|
25
|
+
|
26
|
+
# Used to specific the error handler if the matcher doesn't match anything. By default, there is no error handler.
|
27
|
+
# @yield The block to be executed it fails to match.
|
28
|
+
def on_error(&blk)
|
29
|
+
@error_handler = blk
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# Used to transform the value matched.
|
34
|
+
# @yield TODO
|
35
|
+
def on_transform(&blk)
|
36
|
+
@transform_handler = blk
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
# Convienence method to creating halting error handler.
|
41
|
+
# @param [Symbol, Integer] error_code The HTTP code to halt with.
|
42
|
+
# @see #interpret_response
|
43
|
+
def halt_on_error!(error_code = :bad_request)
|
44
|
+
on_error { halt error_code }
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# Matcher for string
|
49
|
+
# @param [String] val The value to attempt to match on.
|
50
|
+
# @raise [ClientError] If the match fails to match and there is an error handler defined.
|
51
|
+
def [](val)
|
52
|
+
match = nil
|
53
|
+
case @matcher
|
54
|
+
when Array
|
55
|
+
match = nil
|
56
|
+
@matcher.find { |m| match = m[val] }
|
57
|
+
else
|
58
|
+
if match = /^#{@matcher.to_s}/.match(val)
|
59
|
+
match = [match[0]]
|
60
|
+
match << @transform_handler.call(match.first) if @transform_handler
|
61
|
+
match
|
62
|
+
end
|
63
|
+
end
|
64
|
+
if match
|
65
|
+
match
|
66
|
+
elsif @error_handler
|
67
|
+
raise ClientError.new("There was an error interpreting the value #{val.inspect} for #{name.inspect}", &@error_handler)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Matcher for Integers
|
73
|
+
IntegerMatcher = Matcher.new(/\d+/).on_transform{|v| Integer(v)}
|
16
74
|
end
|
17
75
|
end
|
18
76
|
end
|
data/lib/renee/core.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
1
|
require 'rack'
|
2
2
|
|
3
|
-
require 'renee/version'
|
4
|
-
require 'renee/core/
|
3
|
+
require 'renee/core/version'
|
4
|
+
require 'renee/core/transform'
|
5
5
|
require 'renee/core/chaining'
|
6
|
-
require 'renee/core/response'
|
7
6
|
require 'renee/core/exceptions'
|
8
7
|
require 'renee/core/rack_interaction'
|
9
|
-
require 'renee/core/request_context'
|
10
|
-
require 'renee/core/transform'
|
11
8
|
require 'renee/core/routing'
|
12
9
|
require 'renee/core/responding'
|
13
|
-
require 'renee/core/env_accessors'
|
14
10
|
require 'renee/core/plugins'
|
15
11
|
|
16
12
|
# Top-level Renee constant
|
17
13
|
module Renee
|
18
14
|
# @example
|
19
15
|
# Renee.core { path('/hello') { halt :ok } }
|
20
|
-
def self.core(&
|
16
|
+
def self.core(&app)
|
21
17
|
cls = Class.new(Renee::Core)
|
22
|
-
cls.
|
18
|
+
cls.run(&app) if app
|
23
19
|
cls
|
24
20
|
end
|
25
21
|
|
@@ -27,12 +23,12 @@ module Renee
|
|
27
23
|
# For convience you can also used a method named #Renee
|
28
24
|
# for decalaring new instances.
|
29
25
|
class Core
|
30
|
-
# Current version of Renee::Core
|
31
|
-
VERSION = Renee::VERSION
|
32
|
-
|
33
26
|
# Error raised if routing fails. Use #continue_routing to continue routing.
|
34
27
|
NotMatchedError = Class.new(RuntimeError)
|
35
28
|
|
29
|
+
# Error raised if respond! or respond is used and no body is set.
|
30
|
+
NoResponseSetError = Class.new(RuntimeError)
|
31
|
+
|
36
32
|
# Class methods that are included in new instances of {Core}
|
37
33
|
module ClassMethods
|
38
34
|
include Plugins
|
@@ -46,12 +42,22 @@ module Renee
|
|
46
42
|
new.call(env)
|
47
43
|
end
|
48
44
|
|
45
|
+
# Specify a middleware to use before calling your application.
|
46
|
+
def use(mw, *args, &blk)
|
47
|
+
middlewares << [mw, args, blk]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Retreive the list of currently available middlewares.
|
51
|
+
def middlewares
|
52
|
+
@middlewares ||= []
|
53
|
+
end
|
54
|
+
|
49
55
|
# Allows you to set the #application_block on your class.
|
50
56
|
# @yield The application block
|
51
|
-
def
|
57
|
+
def run(&app)
|
52
58
|
@application_block = app
|
53
59
|
setup do
|
54
|
-
register_variable_type :integer, IntegerMatcher
|
60
|
+
register_variable_type :integer, Transform::IntegerMatcher
|
55
61
|
register_variable_type :int, :integer
|
56
62
|
end
|
57
63
|
end
|
@@ -73,26 +79,68 @@ module Renee
|
|
73
79
|
# @return [Renee::Core::Matcher] A matcher
|
74
80
|
def register_variable_type(name, matcher)
|
75
81
|
matcher = case matcher
|
76
|
-
when Matcher then matcher
|
77
|
-
when Array
|
78
|
-
when Symbol
|
79
|
-
else
|
82
|
+
when Transform::Matcher then matcher
|
83
|
+
when Array then Transform::Matcher.new(matcher.map{|m| variable_types[m]})
|
84
|
+
when Symbol then variable_types[matcher]
|
85
|
+
else Transform::Matcher.new(matcher)
|
80
86
|
end
|
81
87
|
matcher.name = name
|
82
88
|
variable_types[name] = matcher
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
92
|
+
attr_reader :env, :request, :detected_extension
|
93
|
+
|
94
|
+
# Provides a rack interface compliant call method.
|
95
|
+
# @param[Hash] env The rack environment.
|
96
|
+
def call(e)
|
97
|
+
initialize_plugins
|
98
|
+
idx = 0
|
99
|
+
next_app = proc do |env|
|
100
|
+
if idx == self.class.middlewares.size
|
101
|
+
@requested_http_methods = []
|
102
|
+
@env, @request = env, Rack::Request.new(env)
|
103
|
+
@detected_extension = env['PATH_INFO'][/\.([^\.\/]+)$/, 1]
|
104
|
+
# TODO clear template cache in development? `template_cache.clear`
|
105
|
+
out = catch(:halt) do
|
106
|
+
begin
|
107
|
+
self.class.before_blocks.each { |b| instance_eval(&b) }
|
108
|
+
instance_eval(&self.class.application_block)
|
109
|
+
raise NotMatchedError
|
110
|
+
rescue ClientError => e
|
111
|
+
e.response ? instance_eval(&e.response) : halt("There was an error with your request", 400)
|
112
|
+
rescue NotMatchedError => e
|
113
|
+
unless @requested_http_methods.empty?
|
114
|
+
throw :halt,
|
115
|
+
Rack::Response.new(
|
116
|
+
"Method #{request.request_method} unsupported, use #{@requested_http_methods.join(", ")} instead", 405,
|
117
|
+
{'Allow' => @requested_http_methods.join(", ")}).finish
|
118
|
+
end
|
119
|
+
end
|
120
|
+
Rack::Response.new("Not found", 404).finish
|
121
|
+
end
|
122
|
+
self.class.after_blocks.each { |a| out = instance_exec(out, &a) }
|
123
|
+
out
|
124
|
+
else
|
125
|
+
middleware = self.class.middlewares[idx]
|
126
|
+
idx += 1
|
127
|
+
middleware[0].new(next_app, *middleware[1], &middleware[2]).call(env)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
next_app[e]
|
131
|
+
end # call
|
132
|
+
|
133
|
+
def initialize_plugins
|
134
|
+
self.class.init_blocks.each { |init_block| self.class.class_eval(&init_block) }
|
135
|
+
self.class.send(:define_method, :initialize_plugins) { }
|
136
|
+
end
|
137
|
+
|
86
138
|
include Chaining
|
87
|
-
include RequestContext
|
88
139
|
include Routing
|
89
140
|
include Responding
|
90
141
|
include RackInteraction
|
91
142
|
include Transform
|
92
|
-
include EnvAccessors
|
93
143
|
|
94
|
-
|
95
|
-
include ClassMethods
|
96
|
-
end
|
144
|
+
extend ClassMethods
|
97
145
|
end
|
98
146
|
end
|
data/renee-core.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "renee/core/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "renee-core"
|
7
|
+
s.version = Renee::Core::VERSION
|
8
|
+
s.authors = ["Josh Hull", "Nathan Esquenazi", "Arthur Chiu"]
|
9
|
+
s.email = ["joshbuddy@gmail.com", "nesquena@gmail.com", "mr.arthur.chiu@gmail.com"]
|
10
|
+
s.homepage = "http://reneerb.com"
|
11
|
+
s.summary = %q{The super-friendly rack helpers}
|
12
|
+
s.description = %q{The super-friendly rack helpers.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "renee-core"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- test`.split("\n") + ["test/test_helper.rb"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_runtime_dependency 'rack', ">= 1.3.0"
|
21
|
+
|
22
|
+
s.add_development_dependency 'minitest', "~> 2.11.1"
|
23
|
+
s.add_development_dependency 'bundler'
|
24
|
+
s.add_development_dependency "rack-test", ">= 0.5.0"
|
25
|
+
s.add_development_dependency "rake"
|
26
|
+
end
|
File without changes
|
File without changes
|
@@ -20,6 +20,27 @@ describe Renee::Core::Responding do
|
|
20
20
|
assert_equal 'Status code 404', response.body
|
21
21
|
end
|
22
22
|
|
23
|
+
it "should respond with a 404 if the path isn't matched" do
|
24
|
+
mock_app do
|
25
|
+
path('hello') do
|
26
|
+
halt :ok
|
27
|
+
end
|
28
|
+
end
|
29
|
+
get '/'
|
30
|
+
assert_equal 404, response.status
|
31
|
+
assert_equal 'Not found', response.body
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should respond with a 405 if the path is matched but the request method isn't" do
|
35
|
+
mock_app do
|
36
|
+
get {}
|
37
|
+
post {}
|
38
|
+
end
|
39
|
+
put '/'
|
40
|
+
assert_equal 405, response.status
|
41
|
+
assert_equal 'GET, POST', response.headers['Allow']
|
42
|
+
end
|
43
|
+
|
23
44
|
it "should render from a string" do
|
24
45
|
mock_app do
|
25
46
|
path('/') { halt "hello!" }
|
@@ -43,7 +64,7 @@ describe Renee::Core::Responding do
|
|
43
64
|
path('/') { halt :payment_required, "hello!" }
|
44
65
|
end
|
45
66
|
get '/'
|
46
|
-
assert_equal
|
67
|
+
assert_equal 402, response.status
|
47
68
|
assert_equal 'hello!', response.body
|
48
69
|
end
|
49
70
|
|
@@ -92,6 +113,15 @@ describe Renee::Core::Responding do
|
|
92
113
|
assert_equal "bar", response.headers["foo"]
|
93
114
|
assert_equal "hello!", response.body
|
94
115
|
end # respond
|
116
|
+
|
117
|
+
it "should raise a NoResponseSetError if you respond without any values" do
|
118
|
+
mock_app do
|
119
|
+
get do
|
120
|
+
respond!
|
121
|
+
end
|
122
|
+
end
|
123
|
+
assert_raises(Renee::Core::NoResponseSetError) { get('/') }
|
124
|
+
end # respond
|
95
125
|
end
|
96
126
|
|
97
127
|
describe "#redirect" do
|
File without changes
|
data/test/test_helper.rb
CHANGED
@@ -19,7 +19,7 @@ describe Renee::Core::Matcher do
|
|
19
19
|
halt i.inspect
|
20
20
|
end
|
21
21
|
}.setup {
|
22
|
-
register_variable_type(:symbol, /[a-z_]+/).on_transform{|v| v.to_sym}.
|
22
|
+
register_variable_type(:symbol, /[a-z_]+/).on_transform{|v| v.to_sym}.halt_on_error!
|
23
23
|
}
|
24
24
|
get '/123'
|
25
25
|
assert_equal 400, response.status
|