renee 0.4.0.pre1 → 0.4.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +11 -8
- data/README.md +50 -1
- data/Rakefile +14 -104
- data/config.ru +5 -0
- data/examples/blog/config.ru +1 -0
- data/lib/renee.rb +3 -2
- data/lib/renee/render.rb +1 -1
- data/lib/renee/url_generation.rb +66 -45
- data/lib/renee/version.rb +1 -1
- data/plan.txt +1 -5
- data/renee.gemspec +3 -3
- data/site/public/css/app.css +47 -26
- data/site/views/extending.md +66 -0
- data/site/views/index.md +14 -4
- data/site/views/routing.md +0 -38
- data/site/views/variable-types.md +2 -2
- data/test/{renee/blog_test.rb → blog_test.rb} +0 -0
- data/test/{renee-render/render_test.rb → render_test.rb} +0 -0
- data/test/renee-url-generation/test_helper.rb +1 -1
- data/test/{renee-session/session_test.rb → session_test.rb} +2 -2
- data/test/renee/test_helper.rb b/data/test/test_helper → copy.rb +0 -0
- data/test/test_helper.rb +8 -1
- data/test/{renee-url-generation/url_generation_test.rb → url_generation_test.rb} +2 -2
- metadata +47 -77
- data/Gemfile-renee +0 -8
- data/Gemfile-renee-core +0 -8
- data/Gemfile-renee-render +0 -9
- data/Gemfile-renee-session +0 -9
- data/Gemfile-renee-url-generation +0 -8
- data/README-renee-core.md +0 -242
- data/README-renee-render.md +0 -38
- data/README-renee-session.md +0 -3
- data/README-renee-url-generation.md +0 -3
- data/lib/renee/core.rb +0 -98
- data/lib/renee/core/chaining.rb +0 -66
- data/lib/renee/core/env_accessors.rb +0 -72
- data/lib/renee/core/exceptions.rb +0 -15
- data/lib/renee/core/matcher.rb +0 -61
- data/lib/renee/core/plugins.rb +0 -31
- data/lib/renee/core/rack_interaction.rb +0 -50
- data/lib/renee/core/request_context.rb +0 -56
- data/lib/renee/core/responding.rb +0 -112
- data/lib/renee/core/response.rb +0 -78
- data/lib/renee/core/routing.rb +0 -319
- data/lib/renee/core/transform.rb +0 -18
- data/renee-core.gemspec +0 -26
- data/renee-render.gemspec +0 -30
- data/renee-session.gemspec +0 -28
- data/renee-url-generation.gemspec +0 -24
- data/test.watchr +0 -61
- data/test/renee-core/chaining_test.rb +0 -33
- data/test/renee-core/env_accessors_test.rb +0 -43
- data/test/renee-core/include_test.rb +0 -14
- data/test/renee-core/request_context_test.rb +0 -70
- data/test/renee-core/responding_test.rb +0 -128
- data/test/renee-core/routing_test.rb +0 -443
- data/test/renee-core/test_helper.rb +0 -4
- data/test/renee-core/variable_type_test.rb +0 -57
data/test.watchr
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
ENV["WATCHR"] = "1"
|
2
|
-
system 'clear'
|
3
|
-
|
4
|
-
def growl(message)
|
5
|
-
growlnotify = `which growlnotify`.chomp
|
6
|
-
if not growlnotify.empty?
|
7
|
-
title = "Watchr Test Results"
|
8
|
-
image = message.include?('0 failures, 0 errors') ? "~/.watchr_images/passed.png" : "~/.watchr_images/failed.png"
|
9
|
-
options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
|
10
|
-
system %(#{growlnotify} #{options} &)
|
11
|
-
else
|
12
|
-
puts message
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def run(cmd)
|
17
|
-
puts(cmd); `#{cmd}`
|
18
|
-
end
|
19
|
-
|
20
|
-
def run_test_file(file)
|
21
|
-
system('clear')
|
22
|
-
result = run(%Q(ruby -I"lib:test" -rubygems #{file}))
|
23
|
-
growl result.split("\n").last rescue nil
|
24
|
-
puts result
|
25
|
-
end
|
26
|
-
|
27
|
-
def run_all_tests
|
28
|
-
system('clear')
|
29
|
-
result = run "rake test"
|
30
|
-
growl result.split("\n").last rescue nil
|
31
|
-
puts result
|
32
|
-
end
|
33
|
-
|
34
|
-
def related_test_files(path)
|
35
|
-
Dir['test/**/*.rb'].select { |file| file =~ /#{File.basename(path).split(".").first}_test.rb/ }
|
36
|
-
end
|
37
|
-
|
38
|
-
watch('.*/test/test_helper\.rb') { run_all_tests }
|
39
|
-
watch('.*/test/(.*).*_test\.rb') { |m| run_test_file(m[0]) }
|
40
|
-
watch('.*/lib/(.*)\.rb') { |m| related_test_files(m[0]).map {|tf| run_test_file(tf) } }
|
41
|
-
|
42
|
-
# Ctrl-\
|
43
|
-
Signal.trap 'QUIT' do
|
44
|
-
puts " --- Running all tests ---\n\n"
|
45
|
-
run_all_tests
|
46
|
-
end
|
47
|
-
|
48
|
-
@interrupted = false
|
49
|
-
|
50
|
-
# Ctrl-C
|
51
|
-
Signal.trap 'INT' do
|
52
|
-
if @interrupted then
|
53
|
-
@wants_to_quit = true
|
54
|
-
abort("\n")
|
55
|
-
else
|
56
|
-
puts "Interrupt a second time to quit"
|
57
|
-
@interrupted = true
|
58
|
-
Kernel.sleep 1.5
|
59
|
-
run_all_tests
|
60
|
-
end
|
61
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
describe "Route chaining" do
|
4
|
-
|
5
|
-
it "should chaining" do
|
6
|
-
type = { 'Content-Type' => 'text/plain' }
|
7
|
-
mock_app do
|
8
|
-
path('/').get { halt [200,type,['foo']] }
|
9
|
-
continue_routing.path('bar').put { halt [200,type,['bar']] }
|
10
|
-
continue_routing.path('bar').var.put { |id| halt [200,type,[id]] }
|
11
|
-
continue_routing.path('bar').var.get.halt { |id| "wow, nice to meet you " }
|
12
|
-
end
|
13
|
-
get '/'
|
14
|
-
assert_equal 200, response.status
|
15
|
-
assert_equal 'foo', response.body
|
16
|
-
put '/bar'
|
17
|
-
assert_equal 200, response.status
|
18
|
-
assert_equal 'bar', response.body
|
19
|
-
put '/bar/asd'
|
20
|
-
assert_equal 200, response.status
|
21
|
-
assert_equal 'asd', response.body
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should chain and halt with a non-routing method" do
|
25
|
-
type = { 'Content-Type' => 'text/plain' }
|
26
|
-
mock_app do
|
27
|
-
path('/').get.halt "hi"
|
28
|
-
end
|
29
|
-
get '/'
|
30
|
-
assert_equal 200, response.status
|
31
|
-
assert_equal 'hi', response.body
|
32
|
-
end
|
33
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
require File.expand_path('../test_helper', __FILE__)
|
4
|
-
|
5
|
-
describe Renee::Core::EnvAccessors do
|
6
|
-
it "should allow accessing the env" do
|
7
|
-
@app = Renee.core {
|
8
|
-
self.test = 'hello'
|
9
|
-
path('test').get do
|
10
|
-
halt "test is #{test}"
|
11
|
-
end
|
12
|
-
}.setup {
|
13
|
-
env_accessor :test
|
14
|
-
}
|
15
|
-
get '/test'
|
16
|
-
assert_equal 200, response.status
|
17
|
-
assert_equal 'test is hello', response.body
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should raise when you try to access weird env keys" do
|
21
|
-
assert_raises(Renee::Core::EnvAccessors::InvalidEnvNameError) {
|
22
|
-
@app = Renee.core {
|
23
|
-
self.test_test = 'hello'
|
24
|
-
}.setup {
|
25
|
-
env_accessor "test.test"
|
26
|
-
}
|
27
|
-
}
|
28
|
-
end
|
29
|
-
|
30
|
-
it "should allow weird env keys if you map them" do
|
31
|
-
@app = Renee.core {
|
32
|
-
self.test_test = 'hello'
|
33
|
-
path('test').get do
|
34
|
-
halt "test is #{test_test}"
|
35
|
-
end
|
36
|
-
}.setup {
|
37
|
-
env_accessor "test.test" => :test_test
|
38
|
-
}
|
39
|
-
get '/test'
|
40
|
-
assert_equal 200, response.status
|
41
|
-
assert_equal 'test is hello', response.body
|
42
|
-
end
|
43
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
describe "Route::Settings#include" do
|
4
|
-
it "should allow the inclusion of arbitrary modules" do
|
5
|
-
type = { 'Content-Type' => 'text/plain' }
|
6
|
-
@app = Renee.core {
|
7
|
-
halt :ok if respond_to?(:hi)
|
8
|
-
}.setup {
|
9
|
-
include Module.new { def hi; end }
|
10
|
-
}
|
11
|
-
get '/'
|
12
|
-
assert_equal 200, response.status
|
13
|
-
end
|
14
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
class AddHelloThereMiddleware
|
4
|
-
def initialize(app)
|
5
|
-
@app = app
|
6
|
-
end
|
7
|
-
|
8
|
-
def call(env)
|
9
|
-
if env['hello']
|
10
|
-
env['hello'] << "there"
|
11
|
-
else
|
12
|
-
env['hello'] = 'hello'
|
13
|
-
end
|
14
|
-
@app.call(env)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class AddWhatsThatMiddleware
|
19
|
-
def initialize(app)
|
20
|
-
@app = app
|
21
|
-
end
|
22
|
-
|
23
|
-
def call(env)
|
24
|
-
if env['hello']
|
25
|
-
env['hello'] << "that"
|
26
|
-
else
|
27
|
-
env['hello'] = 'whats'
|
28
|
-
end
|
29
|
-
@app.call(env)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "Route::Core::RequestContext#use" do
|
34
|
-
it "should allow the inclusion of arbitrary middlewares" do
|
35
|
-
type = { 'Content-Type' => 'text/plain' }
|
36
|
-
@app = Renee.core {
|
37
|
-
halt env['hello']
|
38
|
-
}.setup {
|
39
|
-
use AddHelloThereMiddleware
|
40
|
-
}
|
41
|
-
get '/'
|
42
|
-
assert_equal 200, response.status
|
43
|
-
assert_equal 'hello', response.body
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should call middlewares in sequence (1)" do
|
47
|
-
type = { 'Content-Type' => 'text/plain' }
|
48
|
-
@app = Renee.core {
|
49
|
-
halt env['hello']
|
50
|
-
}.setup {
|
51
|
-
use AddHelloThereMiddleware
|
52
|
-
use AddWhatsThatMiddleware
|
53
|
-
}
|
54
|
-
get '/'
|
55
|
-
assert_equal 200, response.status
|
56
|
-
assert_equal 'hellothat', response.body
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should call middlewares in sequence (2)" do
|
60
|
-
@app = Renee.core {
|
61
|
-
halt env['hello']
|
62
|
-
}.setup {
|
63
|
-
use AddWhatsThatMiddleware
|
64
|
-
use AddHelloThereMiddleware
|
65
|
-
}
|
66
|
-
get '/'
|
67
|
-
assert_equal 200, response.status
|
68
|
-
assert_equal 'whatsthere', response.body
|
69
|
-
end
|
70
|
-
end
|
@@ -1,128 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
describe Renee::Core::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
|
@@ -1,443 +0,0 @@
|
|
1
|
-
require File.expand_path('../test_helper', __FILE__)
|
2
|
-
|
3
|
-
describe Renee::Core::Routing do
|
4
|
-
|
5
|
-
def renee_for(path, options = {}, &block)
|
6
|
-
Renee.core(&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
|
-
describe "with trailing slashes" do
|
44
|
-
it "should ignore trailing slashes normally" do
|
45
|
-
type = { 'Content-Type' => 'text/plain' }
|
46
|
-
mock_app do
|
47
|
-
path('test') { get { halt [200,type,['test']] } }
|
48
|
-
end
|
49
|
-
|
50
|
-
get '/test/'
|
51
|
-
assert_equal 200, response.status
|
52
|
-
assert_equal 'test', response.body
|
53
|
-
get '/test'
|
54
|
-
assert_equal 200, response.status
|
55
|
-
assert_equal 'test', response.body
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should not ignore trailing slashes if told not to" do
|
59
|
-
type = { 'Content-Type' => 'text/plain' }
|
60
|
-
mock_app do
|
61
|
-
path('test').empty { get { halt [200,type,['test']] } }
|
62
|
-
end
|
63
|
-
get '/test/'
|
64
|
-
assert_equal 404, response.status
|
65
|
-
get '/test'
|
66
|
-
assert_equal 200, response.status
|
67
|
-
assert_equal 'test', response.body
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe "with variables" do
|
73
|
-
|
74
|
-
it "generates for path" do
|
75
|
-
type = { 'Content-Type' => 'text/plain' }
|
76
|
-
mock_app do
|
77
|
-
path 'test' do
|
78
|
-
variable do |id|
|
79
|
-
get { halt [200,type,[id]] }
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
path 'two' do
|
84
|
-
var.var do |foo, bar|
|
85
|
-
get { halt [200, type,["#{foo}-#{bar}"]] }
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
path 'multi' do
|
90
|
-
multi_var(3) do |foo, bar, lol|
|
91
|
-
post { halt [200, type,["#{foo}-#{bar}-#{lol}"]] }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
get '/test/hello'
|
97
|
-
assert_equal 200, response.status
|
98
|
-
assert_equal 'hello', response.body
|
99
|
-
get '/two/1/2'
|
100
|
-
assert_equal 200, response.status
|
101
|
-
assert_equal '1-2', response.body
|
102
|
-
post '/multi/1/2/3'
|
103
|
-
assert_equal 200, response.status
|
104
|
-
assert_equal '1-2-3', response.body
|
105
|
-
end
|
106
|
-
|
107
|
-
it "generates nested paths" do
|
108
|
-
type = { 'Content-Type' => 'text/plain' }
|
109
|
-
mock_app do
|
110
|
-
path 'test' do
|
111
|
-
var do |id|
|
112
|
-
path 'moar' do
|
113
|
-
post { halt [200, type, [id]] }
|
114
|
-
end
|
115
|
-
|
116
|
-
path 'more' do
|
117
|
-
var.var do |foo, bar|
|
118
|
-
get { halt [200, type, ["#{foo}-#{bar}"]] }
|
119
|
-
|
120
|
-
path 'woo' do
|
121
|
-
get { halt [200, type, ["#{foo}-#{bar}-woo"]] }
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
post '/test/world/moar'
|
130
|
-
assert_equal 200, response.status
|
131
|
-
assert_equal 'world', response.body
|
132
|
-
get '/test/world/more/1/2'
|
133
|
-
assert_equal 200, response.status
|
134
|
-
assert_equal '1-2', response.body
|
135
|
-
get '/test/world/more/1/2/woo'
|
136
|
-
assert_equal 200, response.status
|
137
|
-
assert_equal '1-2-woo', response.body
|
138
|
-
end
|
139
|
-
|
140
|
-
it "accepts an typcasts integers" do
|
141
|
-
type = { 'Content-Type' => 'text/plain' }
|
142
|
-
mock_app do
|
143
|
-
path 'add' do
|
144
|
-
var(:integer).var(:integer) do |a, b|
|
145
|
-
halt [200, type, ["#{a + b}"]]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
get '/add/3/4'
|
151
|
-
assert_equal 200, response.status
|
152
|
-
assert_equal '7', response.body
|
153
|
-
end
|
154
|
-
|
155
|
-
it "can take an optional variable" do
|
156
|
-
type = { 'Content-Type' => 'text/plain' }
|
157
|
-
mock_app do
|
158
|
-
path 'add' do
|
159
|
-
var(:integer).optional(:integer) do |a, b|
|
160
|
-
b ||= a
|
161
|
-
halt [200, type, ["#{a + b}"]]
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
get '/add/3/4'
|
167
|
-
assert_equal 200, response.status
|
168
|
-
assert_equal '7', response.body
|
169
|
-
get '/add/3'
|
170
|
-
assert_equal 200, response.status
|
171
|
-
assert_equal '6', response.body
|
172
|
-
end
|
173
|
-
|
174
|
-
it "allows arbitrary ranges of values" do
|
175
|
-
type = { 'Content-Type' => 'text/plain' }
|
176
|
-
mock_app do
|
177
|
-
path 'add' do
|
178
|
-
multi_var(2..5, :integer).get do |numbers|
|
179
|
-
halt [200, type, ["Add up to #{numbers.inject(numbers.shift) {|m, i| m += i}}"]]
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
get '/add/3/4'
|
185
|
-
assert_equal 200, response.status
|
186
|
-
assert_equal 'Add up to 7', response.body
|
187
|
-
get '/add/3/4/6/7'
|
188
|
-
assert_equal 200, response.status
|
189
|
-
assert_equal 'Add up to 20', response.body
|
190
|
-
get '/add/3/4/6/7/8/10/2'
|
191
|
-
assert_equal 404, response.status
|
192
|
-
end
|
193
|
-
|
194
|
-
it "accepts allows repeating vars" do
|
195
|
-
type = { 'Content-Type' => 'text/plain' }
|
196
|
-
mock_app do
|
197
|
-
path 'add' do
|
198
|
-
glob :integer do |numbers|
|
199
|
-
halt [200, type, ["Add up to #{numbers.inject(numbers.shift) {|m, i| m += i}}"]]
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
get '/add/3/4'
|
205
|
-
assert_equal 200, response.status
|
206
|
-
assert_equal 'Add up to 7', response.body
|
207
|
-
get '/add/3/4/6/7'
|
208
|
-
assert_equal 200, response.status
|
209
|
-
assert_equal 'Add up to 20', response.body
|
210
|
-
end
|
211
|
-
|
212
|
-
it "accepts a regexp" do
|
213
|
-
type = { 'Content-Type' => 'text/plain' }
|
214
|
-
mock_app do
|
215
|
-
path 'add' do
|
216
|
-
var(/foo|bar/).var(/foo|bar/) do |a, b|
|
217
|
-
halt [200, type, ["#{a + b}"]]
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
get '/add/bar/foo'
|
223
|
-
assert_equal 200, response.status
|
224
|
-
assert_equal 'barfoo', response.body
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
describe "with remainder" do
|
229
|
-
|
230
|
-
it "matches the rest of the routes" do
|
231
|
-
type = { 'Content-Type' => 'text/plain' }
|
232
|
-
mock_app do
|
233
|
-
path 'test' do
|
234
|
-
get { halt [200,type,['test']] }
|
235
|
-
|
236
|
-
remainder do |rest|
|
237
|
-
post { halt [200, type, ["test-#{rest}"]] }
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
remainder do |rest|
|
242
|
-
halt [200, type, [rest]]
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
get '/a/b/c'
|
247
|
-
assert_equal 200, response.status
|
248
|
-
assert_equal '/a/b/c', response.body
|
249
|
-
post '/test/world/moar'
|
250
|
-
assert_equal 200, response.status
|
251
|
-
assert_equal 'test-/world/moar', response.body
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
describe "with extensions" do
|
256
|
-
it "should match an extension" do
|
257
|
-
type = { 'Content-Type' => 'text/plain' }
|
258
|
-
mock_app do
|
259
|
-
path('/test').get do
|
260
|
-
case extension
|
261
|
-
when 'html' then halt [200, type, ['test html']]
|
262
|
-
when 'json' then halt [200, type, ['test json']]
|
263
|
-
when nil then halt [200, type, ['test nope']]
|
264
|
-
else halt [406, type, ['unknown']]
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
extension 'html' do
|
269
|
-
halt [200, type, ['test html']]
|
270
|
-
end
|
271
|
-
end
|
272
|
-
get '/test.html'
|
273
|
-
assert_equal 200, response.status
|
274
|
-
assert_equal 'test html', response.body
|
275
|
-
get '/test.json'
|
276
|
-
assert_equal 200, response.status
|
277
|
-
assert_equal 'test json', response.body
|
278
|
-
get '/test.xml'
|
279
|
-
assert_equal 406, response.status
|
280
|
-
end
|
281
|
-
|
282
|
-
it "should match an extension when there is a non-specific variable before" do
|
283
|
-
mock_app do
|
284
|
-
var do |id|
|
285
|
-
case extension
|
286
|
-
when 'html' then halt "html #{id}"
|
287
|
-
when 'xml' then halt "xml #{id}"
|
288
|
-
when nil then halt "none #{id}"
|
289
|
-
end
|
290
|
-
end
|
291
|
-
end
|
292
|
-
get '/var.html'
|
293
|
-
assert_equal 200, response.status
|
294
|
-
assert_equal 'html var', response.body
|
295
|
-
get '/var.xml'
|
296
|
-
assert_equal 200, response.status
|
297
|
-
assert_equal 'xml var', response.body
|
298
|
-
get '/var'
|
299
|
-
assert_equal 200, response.status
|
300
|
-
assert_equal 'none var', response.body
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
describe "with part and part_var" do
|
305
|
-
it "should match a part" do
|
306
|
-
mock_app do
|
307
|
-
part '/test' do
|
308
|
-
part 'more' do
|
309
|
-
halt :ok
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
get '/testmore'
|
314
|
-
assert_equal 200, response.status
|
315
|
-
end
|
316
|
-
|
317
|
-
it "should match a part_var" do
|
318
|
-
mock_app do
|
319
|
-
part '/test' do
|
320
|
-
part 'more' do
|
321
|
-
part_var do |var|
|
322
|
-
path 'test' do
|
323
|
-
halt var
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
end
|
328
|
-
end
|
329
|
-
get '/testmorethisvar/test'
|
330
|
-
assert_equal 'thisvar', response.body
|
331
|
-
end
|
332
|
-
|
333
|
-
it "should match a part_var with Integer" do
|
334
|
-
mock_app do
|
335
|
-
part '/test' do
|
336
|
-
part 'more' do
|
337
|
-
part_var :integer do |var|
|
338
|
-
path 'test' do
|
339
|
-
halt var.to_s
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|
343
|
-
end
|
344
|
-
end
|
345
|
-
get '/testmore123/test'
|
346
|
-
assert_equal '123', response.body
|
347
|
-
get '/testmore123a/test'
|
348
|
-
assert_equal 404, response.status
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
describe "multiple Renee's" do
|
353
|
-
it "should pass between them normally" do
|
354
|
-
type = { 'Content-Type' => 'text/plain' }
|
355
|
-
mock_app do
|
356
|
-
path 'test' do
|
357
|
-
halt run Renee.core {
|
358
|
-
path 'time' do
|
359
|
-
halt halt [200,type,['test']]
|
360
|
-
end
|
361
|
-
}
|
362
|
-
end
|
363
|
-
end
|
364
|
-
get '/test/time'
|
365
|
-
assert_equal 200, response.status
|
366
|
-
assert_equal 'test', response.body
|
367
|
-
end
|
368
|
-
|
369
|
-
it "should support run! passing between" do
|
370
|
-
type = { 'Content-Type' => 'text/plain' }
|
371
|
-
mock_app do
|
372
|
-
path 'test' do
|
373
|
-
run! Renee.core {
|
374
|
-
path 'time' do
|
375
|
-
halt halt [200,type,['test']]
|
376
|
-
end
|
377
|
-
}
|
378
|
-
end
|
379
|
-
end
|
380
|
-
get '/test/time'
|
381
|
-
assert_equal 200, response.status
|
382
|
-
assert_equal 'test', response.body
|
383
|
-
end
|
384
|
-
end
|
385
|
-
|
386
|
-
describe "#build" do
|
387
|
-
it "should allow building in-place rack apps" do
|
388
|
-
type = { 'Content-Type' => 'text/plain' }
|
389
|
-
mock_app do
|
390
|
-
path('test') do
|
391
|
-
halt build {
|
392
|
-
run proc {|env| [200, type, ['someone built me!']] }
|
393
|
-
}
|
394
|
-
end
|
395
|
-
end
|
396
|
-
|
397
|
-
get '/test'
|
398
|
-
assert_equal 200, response.status
|
399
|
-
assert_equal 'someone built me!', response.body
|
400
|
-
end
|
401
|
-
end
|
402
|
-
|
403
|
-
describe "#part and #part_var" do
|
404
|
-
it "should match parts and partial vars" do
|
405
|
-
mock_app do
|
406
|
-
part('test') {
|
407
|
-
part_var(:integer) { |id|
|
408
|
-
part('more') {
|
409
|
-
halt "the id is #{id}"
|
410
|
-
}
|
411
|
-
}
|
412
|
-
}
|
413
|
-
end
|
414
|
-
get '/test123more'
|
415
|
-
assert_equal 200, response.status
|
416
|
-
assert_equal 'the id is 123', response.body
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
describe "request methods" do
|
421
|
-
it "should allow request method routing when you're matching on /" do
|
422
|
-
type = { 'Content-Type' => 'text/plain' }
|
423
|
-
mock_app do
|
424
|
-
get { halt [200, type, ["hiya"]] }
|
425
|
-
end
|
426
|
-
|
427
|
-
get '/'
|
428
|
-
assert_equal 200, response.status
|
429
|
-
assert_equal 'hiya', response.body
|
430
|
-
end
|
431
|
-
|
432
|
-
it "should raise if you fail to halt" do
|
433
|
-
type = { 'Content-Type' => 'text/plain' }
|
434
|
-
mock_app do
|
435
|
-
get { }
|
436
|
-
halt :ok
|
437
|
-
end
|
438
|
-
|
439
|
-
get '/'
|
440
|
-
assert_equal 404, response.status
|
441
|
-
end
|
442
|
-
end
|
443
|
-
end
|