renee-core 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,128 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Renee::Core::Application::Responding do
4
+ describe "#interpret_response" do
5
+ it "should render from a number" do
6
+ mock_app do
7
+ path('/') { halt 200 }
8
+ end
9
+ get '/'
10
+ assert_equal 200, response.status
11
+ assert_equal 'Status code 200', response.body
12
+ end
13
+
14
+ it "should render from a symbol" do
15
+ mock_app do
16
+ path('/') { halt :not_found }
17
+ end
18
+ get '/'
19
+ assert_equal 404, response.status
20
+ assert_equal 'Status code 404', response.body
21
+ end
22
+
23
+ it "should render from a string" do
24
+ mock_app do
25
+ path('/') { halt "hello!" }
26
+ end
27
+ get '/'
28
+ assert_equal 200, response.status
29
+ assert_equal 'hello!', response.body
30
+ end
31
+
32
+ it "should render from an array" do
33
+ mock_app do
34
+ path('/') { halt 500, "hello!" }
35
+ end
36
+ get '/'
37
+ assert_equal 500, response.status
38
+ assert_equal 'hello!', response.body
39
+ end
40
+
41
+ it "should render from an array with a symbol" do
42
+ mock_app do
43
+ path('/') { halt :payment_required, "hello!" }
44
+ end
45
+ get '/'
46
+ assert_equal 403, response.status
47
+ assert_equal 'hello!', response.body
48
+ end
49
+
50
+ it "should render a rack-sized array as a rack response" do
51
+ mock_app do
52
+ path('/') { halt [200, {'Content-Type' => 'text/plain'}, []] }
53
+ end
54
+ get '/'
55
+ assert_equal 200, response.status
56
+ end
57
+ end
58
+
59
+ describe "#respond" do
60
+ it "should allow respond! with response init arguments" do
61
+ mock_app do
62
+ get do
63
+ respond!("hello!", 403, "foo" => "bar")
64
+ end
65
+ end
66
+ get "/"
67
+ assert_equal 403, response.status
68
+ assert_equal "bar", response.headers["foo"]
69
+ assert_equal "hello!", response.body
70
+ end # respond!
71
+
72
+ it "should allow respond!" do
73
+ mock_app do
74
+ get do
75
+ respond! { status 403; headers :foo => "bar"; body "hello!" }
76
+ end
77
+ end
78
+ get "/"
79
+ assert_equal 403, response.status
80
+ assert_equal "bar", response.headers["foo"]
81
+ assert_equal "hello!", response.body
82
+ end # respond!
83
+
84
+ it "should allow respond" do
85
+ mock_app do
86
+ get do
87
+ halt(respond { status 403; headers :foo => "bar"; body "hello!" })
88
+ end
89
+ end
90
+ get "/"
91
+ assert_equal 403, response.status
92
+ assert_equal "bar", response.headers["foo"]
93
+ assert_equal "hello!", response.body
94
+ end # respond
95
+ end
96
+
97
+ describe "#redirect" do
98
+ it "should allow redirects" do
99
+ mock_app do
100
+ get { halt redirect('/hello') }
101
+ end
102
+
103
+ get '/'
104
+ assert_equal 302, response.status
105
+ assert_equal "/hello", response.headers['Location']
106
+ end
107
+
108
+ it "should accept custom status codes" do
109
+ mock_app do
110
+ get { halt redirect('/hello', 303) }
111
+ end
112
+
113
+ get '/'
114
+ assert_equal 303, response.status
115
+ assert_equal "/hello", response.headers['Location']
116
+ end
117
+
118
+ it "should allow redirect!" do
119
+ mock_app do
120
+ get { redirect!('/hello') }
121
+ end
122
+
123
+ get '/'
124
+ assert_equal 302, response.status
125
+ assert_equal "/hello", response.headers['Location']
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,422 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ describe Renee::Core::Application::Routing do
4
+
5
+ def renee_for(path, options = {}, &block)
6
+ Renee::Core.new(&block).call(Rack::MockRequest.env_for(path, options))
7
+ end
8
+
9
+ describe "with paths" do
10
+ it "generates a basic route" do
11
+ type = { 'Content-Type' => 'text/plain' }
12
+ mock_app do
13
+ path('/') { get { halt [200,type,['foo']] } }
14
+ path('bar') { put { halt [200,type,['bar']] } }
15
+
16
+ path '/foo' do
17
+ delete { halt [200,type,['hi']] }
18
+
19
+ path '/bar/har' do
20
+ get { halt [200,type,['foobar']] }
21
+ post { halt [200,type,['posted']] }
22
+ end
23
+
24
+ end
25
+ end
26
+ get '/'
27
+ assert_equal 200, response.status
28
+ assert_equal 'foo', response.body
29
+ put '/bar'
30
+ assert_equal 200, response.status
31
+ assert_equal 'bar', response.body
32
+ delete '/foo'
33
+ assert_equal 200, response.status
34
+ assert_equal 'hi', response.body
35
+ get '/foo/bar/har'
36
+ assert_equal 200, response.status
37
+ assert_equal 'foobar', response.body
38
+ post '/foo/bar/har'
39
+ assert_equal 200, response.status
40
+ assert_equal 'posted', response.body
41
+ end
42
+
43
+ it "accepts a query string" do
44
+ type = { 'Content-Type' => 'text/plain' }
45
+ mock_app do
46
+ path('test') { get { halt [200, type, [env['QUERY_STRING']]] } }
47
+
48
+ path 'foo' do
49
+ query_string 'bar' do
50
+ get { halt [200,type,['bar']] }
51
+ end
52
+
53
+ query_string 'foo=bar' do
54
+ post { halt [200,type,['foo']] }
55
+ end
56
+ end
57
+ end
58
+
59
+ get '/test?bar'
60
+ assert_equal 200, response.status
61
+ assert_equal 'bar', response.body
62
+ get '/foo?bar'
63
+ assert_equal 200, response.status
64
+ assert_equal 'bar', response.body
65
+ post '/foo?foo=bar'
66
+ assert_equal 200, response.status
67
+ assert_equal 'foo', response.body
68
+ end
69
+
70
+ it "accepts a set of query params (as hash)" do
71
+ mock_app do
72
+ path 'test' do
73
+ query :foo => "bar" do
74
+ halt 200
75
+ end
76
+ end
77
+ end
78
+
79
+ get '/test?foo=bar'
80
+ assert_equal 200, response.status
81
+ get '/test?foo=bar2'
82
+ assert_equal 404, response.status
83
+ end
84
+
85
+ it "accepts a set of query params (as an array)" do
86
+ mock_app do
87
+ path 'test' do
88
+ query :foo do |var|
89
+ case var
90
+ when 'bar' then halt 200
91
+ when 'bar2' then halt 500
92
+ end
93
+ end
94
+ end
95
+ end
96
+ get '/test?foo=bar'
97
+ assert_equal 200, response.status
98
+ get '/test?foo=bar2'
99
+ assert_equal 500, response.status
100
+ end
101
+
102
+ describe "with trailing slashes" do
103
+ it "should ignore trailing slashes normally" do
104
+ type = { 'Content-Type' => 'text/plain' }
105
+ mock_app do
106
+ path('test') { get { halt [200,type,['test']] } }
107
+ end
108
+
109
+ get '/test/'
110
+ assert_equal 200, response.status
111
+ assert_equal 'test', response.body
112
+ get '/test'
113
+ assert_equal 200, response.status
114
+ assert_equal 'test', response.body
115
+ end
116
+
117
+ it "should not ignore trailing slashes if told not to" do
118
+ type = { 'Content-Type' => 'text/plain' }
119
+ mock_app do
120
+ exact_path('test') { get { halt [200,type,['test']] } }
121
+ end
122
+ get '/test/'
123
+ assert_equal 404, response.status
124
+ get '/test'
125
+ assert_equal 200, response.status
126
+ assert_equal 'test', response.body
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "with variables" do
132
+
133
+ it "generates for path" do
134
+ type = { 'Content-Type' => 'text/plain' }
135
+ mock_app do
136
+ path 'test' do
137
+ variable do |id|
138
+ get { halt [200,type,[id]] }
139
+ end
140
+ end
141
+
142
+ path 'two' do
143
+ variable do |foo, bar|
144
+ get { halt [200, type,["#{foo}-#{bar}"]] }
145
+ end
146
+ end
147
+
148
+ path 'multi' do
149
+ variable do |foo, bar, lol|
150
+ post { halt [200, type,["#{foo}-#{bar}-#{lol}"]] }
151
+ end
152
+ end
153
+ end
154
+
155
+ get '/test/hello'
156
+ assert_equal 200, response.status
157
+ assert_equal 'hello', response.body
158
+ get '/two/1/2'
159
+ assert_equal 200, response.status
160
+ assert_equal '1-2', response.body
161
+ post '/multi/1/2/3'
162
+ assert_equal 200, response.status
163
+ assert_equal '1-2-3', response.body
164
+ end
165
+
166
+ it "generates nested paths" do
167
+ type = { 'Content-Type' => 'text/plain' }
168
+ mock_app do
169
+ path 'test' do
170
+ var do |id|
171
+ path 'moar' do
172
+ post { halt [200, type, [id]] }
173
+ end
174
+
175
+ path 'more' do
176
+ var do |foo, bar|
177
+ get { halt [200, type, ["#{foo}-#{bar}"]] }
178
+
179
+ path 'woo' do
180
+ get { halt [200, type, ["#{foo}-#{bar}-woo"]] }
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+
188
+ post '/test/world/moar'
189
+ assert_equal 200, response.status
190
+ assert_equal 'world', response.body
191
+ get '/test/world/more/1/2'
192
+ assert_equal 200, response.status
193
+ assert_equal '1-2', response.body
194
+ get '/test/world/more/1/2/woo'
195
+ assert_equal 200, response.status
196
+ assert_equal '1-2-woo', response.body
197
+ end
198
+
199
+ it "accepts an typcasts integers" do
200
+ type = { 'Content-Type' => 'text/plain' }
201
+ mock_app do
202
+ path 'add' do
203
+ variable :type => Integer do |a, b|
204
+ halt [200, type, ["#{a + b}"]]
205
+ end
206
+ end
207
+ end
208
+
209
+ get '/add/3/4'
210
+ assert_equal 200, response.status
211
+ assert_equal '7', response.body
212
+ end
213
+
214
+ it "accepts a regexp" do
215
+ type = { 'Content-Type' => 'text/plain' }
216
+ mock_app do
217
+ path 'add' do
218
+ variable /foo|bar/ do |a, b|
219
+ halt [200, type, ["#{a + b}"]]
220
+ end
221
+ end
222
+ end
223
+
224
+ get '/add/bar/foo'
225
+ assert_equal 200, response.status
226
+ assert_equal 'barfoo', response.body
227
+ end
228
+ end
229
+
230
+ describe "with remainder" do
231
+
232
+ it "matches the rest of the routes" do
233
+ type = { 'Content-Type' => 'text/plain' }
234
+ mock_app do
235
+ path 'test' do
236
+ get { halt [200,type,['test']] }
237
+
238
+ remainder do |rest|
239
+ post { halt [200, type, ["test-#{rest}"]] }
240
+ end
241
+ end
242
+
243
+ remainder do |rest|
244
+ halt [200, type, [rest]]
245
+ end
246
+ end
247
+
248
+ get '/a/b/c'
249
+ assert_equal 200, response.status
250
+ assert_equal '/a/b/c', response.body
251
+ post '/test/world/moar'
252
+ assert_equal 200, response.status
253
+ assert_equal 'test-/world/moar', response.body
254
+ end
255
+ end
256
+
257
+ describe "with extensions" do
258
+ it "should match an extension" do
259
+ type = { 'Content-Type' => 'text/plain' }
260
+ mock_app do
261
+ path '/test' do
262
+ extension 'html' do
263
+ halt [200, type, ['test html']]
264
+ end
265
+ extension 'json' do
266
+ halt [200, type, ['test json']]
267
+ end
268
+
269
+ no_extension do
270
+ halt [200, type, ['test nope']]
271
+ end
272
+ end
273
+
274
+ extension 'html' do
275
+ halt [200, type, ['test html']]
276
+ end
277
+ end
278
+ get '/test.html'
279
+ assert_equal 200, response.status
280
+ assert_equal 'test html', response.body
281
+ get '/test.json'
282
+ assert_equal 200, response.status
283
+ assert_equal 'test json', response.body
284
+ get '/test.xml'
285
+ assert_equal 404, response.status
286
+ end
287
+ end
288
+
289
+ describe "with part and part_var" do
290
+ it "should match a part" do
291
+ mock_app do
292
+ part '/test' do
293
+ part 'more' do
294
+ halt :ok
295
+ end
296
+ end
297
+ end
298
+ get '/testmore'
299
+ assert_equal 200, response.status
300
+ end
301
+
302
+ it "should match a part_var" do
303
+ mock_app do
304
+ part '/test' do
305
+ part 'more' do
306
+ part_var do |var|
307
+ path 'test' do
308
+ halt var
309
+ end
310
+ end
311
+ end
312
+ end
313
+ end
314
+ get '/testmorethisvar/test'
315
+ assert_equal 'thisvar', response.body
316
+ end
317
+
318
+ it "should match a part_var with Integer" do
319
+ mock_app do
320
+ part '/test' do
321
+ part 'more' do
322
+ part_var Integer do |var|
323
+ path 'test' do
324
+ halt var.to_s
325
+ end
326
+ end
327
+ end
328
+ end
329
+ end
330
+ get '/testmore123/test'
331
+ assert_equal '123', response.body
332
+ get '/testmore123a/test'
333
+ assert_equal 404, response.status
334
+ end
335
+ end
336
+
337
+ describe "multiple Renee's" do
338
+ it "should pass between them normally" do
339
+ type = { 'Content-Type' => 'text/plain' }
340
+ mock_app do
341
+ path 'test' do
342
+ halt run Renee::Core.new {
343
+ path 'time' do
344
+ halt halt [200,type,['test']]
345
+ end
346
+ }
347
+ end
348
+ end
349
+ get '/test/time'
350
+ assert_equal 200, response.status
351
+ assert_equal 'test', response.body
352
+ end
353
+
354
+ it "should support run! passing between" do
355
+ type = { 'Content-Type' => 'text/plain' }
356
+ mock_app do
357
+ path 'test' do
358
+ run! Renee::Core.new {
359
+ path 'time' do
360
+ halt halt [200,type,['test']]
361
+ end
362
+ }
363
+ end
364
+ end
365
+ get '/test/time'
366
+ assert_equal 200, response.status
367
+ assert_equal 'test', response.body
368
+ end
369
+ end
370
+
371
+ describe "#build" do
372
+ it "should allow building in-place rack apps" do
373
+ type = { 'Content-Type' => 'text/plain' }
374
+ mock_app do
375
+ path('test') do
376
+ halt build {
377
+ run proc {|env| [200, type, ['someone built me!']] }
378
+ }
379
+ end
380
+ end
381
+
382
+ get '/test'
383
+ assert_equal 200, response.status
384
+ assert_equal 'someone built me!', response.body
385
+ end
386
+ end
387
+
388
+ describe "#part and #part_var" do
389
+ it "should match parts and partial vars" do
390
+ mock_app do
391
+ part('test') {
392
+ part_var(Integer) { |id|
393
+ part('more') {
394
+ halt "the id is #{id}"
395
+ }
396
+ }
397
+ }
398
+ end
399
+ get '/test123more'
400
+ assert_equal 200, response.status
401
+ assert_equal 'the id is 123', response.body
402
+ end
403
+ end
404
+
405
+ describe "request methods" do
406
+ it "should allow request method routing when you're matching on /" do
407
+ type = { 'Content-Type' => 'text/plain' }
408
+ mock_app do
409
+ get { halt [200, type, ["hiya"]] }
410
+ end
411
+
412
+ get '/'
413
+ assert_equal 200, response.status
414
+ assert_equal 'hiya', response.body
415
+ end
416
+
417
+ it "should allow optional paths in the request method" do
418
+ blk = proc { get('/path') { halt [200, {}, "hiya"] } }
419
+ assert_equal [200, {}, "hiya"], renee_for('/path', &blk)
420
+ end
421
+ end
422
+ end
@@ -0,0 +1,4 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'renee-core'
3
+ # Load shared test helpers
4
+ require File.expand_path('../../../lib/test_helper', __FILE__)
@@ -0,0 +1,66 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.expand_path('../test_helper', __FILE__)
4
+
5
+ describe Renee::Core::URLGeneration do
6
+ it "should allow registration and generation of paths" do
7
+ r = Renee::Core.new
8
+ r.register(:test, '/test/time')
9
+ r.register(:test_var, '/test/:id')
10
+ assert_equal '/test/time', r.path(:test)
11
+ assert_equal '/test/123', r.path(:test_var, :id => 123)
12
+ assert_equal '/test/123', r.path(:test_var, 123)
13
+ end
14
+
15
+ it "should allow registration and generation of urls" do
16
+ r = Renee::Core.new
17
+ r.register(:test, 'http://localhost:8080/test/:time')
18
+ assert_equal 'http://localhost:8080/test/123', r.url(:test, 123)
19
+ assert_equal 'http://localhost:8080/test/654', r.url(:test, :time => '654')
20
+ end
21
+
22
+ it "should escape values when generating" do
23
+ r = Renee::Core.new
24
+ r.register(:test, '/:test')
25
+ assert_equal '/f%C3%B8%C3%B8', r.path(:test, "føø")
26
+ end
27
+
28
+ it "should encode extra values as query string params" do
29
+ r = Renee::Core.new
30
+ r.register(:test, '/:test')
31
+ assert_equal '/foo?bar=baz', r.path(:test, 'foo', :bar => :baz)
32
+ assert_equal '/foo?bar=baz', r.path(:test, :test => 'foo', :bar => :baz)
33
+ end
34
+
35
+ it "should allow default values" do
36
+ r = Renee::Core.new
37
+ r.register(:test, '/:test', :test => 'foo')
38
+ assert_equal '/foo', r.path(:test)
39
+ assert_equal '/baz', r.path(:test, :test => 'baz')
40
+ end
41
+
42
+ it "should include default vars as query string vars" do
43
+ r = Renee::Core.new
44
+ r.register(:test, '/:foo', :test => 'foo')
45
+ assert_equal '/foo?test=foo', r.path(:test, 'foo')
46
+ assert_equal '/foo?test=foo', r.path(:test, :foo => 'foo')
47
+ end
48
+
49
+ it "should allow #prefix calls for nesting common path parts" do
50
+ r = Renee::Core.new
51
+ r.prefix('/foo') do
52
+ r.register(:foo_bar, '/bar')
53
+ end
54
+ assert_equal '/foo/bar', r.path(:foo_bar)
55
+ end
56
+
57
+ it "should allow passing defaults and overriding them on a per-register basis" do
58
+ r = Renee::Core.new
59
+ r.prefix('/foo', :bar => 'baz') do
60
+ register(:foo_bar, '/bar', :bar => 'bam')
61
+ register(:foo_baz, '/baz')
62
+ end
63
+ assert_equal '/foo/bar?bar=bam', r.path(:foo_bar)
64
+ assert_equal '/foo/baz?bar=baz', r.path(:foo_baz)
65
+ end
66
+ end