sinatra-contrib 2.0.0.rc1 → 2.0.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +2 -1
- data/lib/sinatra/decompile.rb +5 -0
- data/lib/sinatra/runner.rb +155 -0
- data/lib/sinatra/webdav.rb +93 -0
- data/sinatra-contrib.gemspec +5 -199
- metadata +13 -175
- data/spec/capture_spec.rb +0 -100
- data/spec/config_file/key_value.yml +0 -7
- data/spec/config_file/key_value.yml.erb +0 -6
- data/spec/config_file/key_value_override.yml +0 -2
- data/spec/config_file/missing_env.yml +0 -4
- data/spec/config_file/with_envs.yml +0 -7
- data/spec/config_file/with_nested_envs.yml +0 -11
- data/spec/config_file_spec.rb +0 -76
- data/spec/content_for/different_key.erb +0 -1
- data/spec/content_for/different_key.erubis +0 -1
- data/spec/content_for/different_key.haml +0 -2
- data/spec/content_for/different_key.slim +0 -2
- data/spec/content_for/footer.erb +0 -3
- data/spec/content_for/footer.erubis +0 -3
- data/spec/content_for/footer.haml +0 -2
- data/spec/content_for/footer.slim +0 -2
- data/spec/content_for/layout.erb +0 -1
- data/spec/content_for/layout.erubis +0 -1
- data/spec/content_for/layout.haml +0 -1
- data/spec/content_for/layout.slim +0 -1
- data/spec/content_for/multiple_blocks.erb +0 -4
- data/spec/content_for/multiple_blocks.erubis +0 -4
- data/spec/content_for/multiple_blocks.haml +0 -8
- data/spec/content_for/multiple_blocks.slim +0 -8
- data/spec/content_for/multiple_yields.erb +0 -3
- data/spec/content_for/multiple_yields.erubis +0 -3
- data/spec/content_for/multiple_yields.haml +0 -3
- data/spec/content_for/multiple_yields.slim +0 -3
- data/spec/content_for/passes_values.erb +0 -1
- data/spec/content_for/passes_values.erubis +0 -1
- data/spec/content_for/passes_values.haml +0 -1
- data/spec/content_for/passes_values.slim +0 -1
- data/spec/content_for/same_key.erb +0 -1
- data/spec/content_for/same_key.erubis +0 -1
- data/spec/content_for/same_key.haml +0 -2
- data/spec/content_for/same_key.slim +0 -2
- data/spec/content_for/takes_values.erb +0 -1
- data/spec/content_for/takes_values.erubis +0 -1
- data/spec/content_for/takes_values.haml +0 -3
- data/spec/content_for/takes_values.slim +0 -3
- data/spec/content_for_spec.rb +0 -241
- data/spec/cookies_spec.rb +0 -826
- data/spec/custom_logger_spec.rb +0 -43
- data/spec/extension_spec.rb +0 -32
- data/spec/json_spec.rb +0 -115
- data/spec/link_header_spec.rb +0 -99
- data/spec/multi_route_spec.rb +0 -59
- data/spec/namespace/foo.erb +0 -1
- data/spec/namespace/nested/foo.erb +0 -1
- data/spec/namespace_spec.rb +0 -791
- data/spec/okjson.rb +0 -581
- data/spec/reloader/app.rb.erb +0 -40
- data/spec/reloader_spec.rb +0 -465
- data/spec/required_params_spec.rb +0 -68
- data/spec/respond_with/bar.erb +0 -1
- data/spec/respond_with/bar.json.erb +0 -1
- data/spec/respond_with/baz.yajl +0 -1
- data/spec/respond_with/foo.html.erb +0 -1
- data/spec/respond_with/not_html.sass +0 -2
- data/spec/respond_with_spec.rb +0 -317
- data/spec/spec_helper.rb +0 -7
- data/spec/streaming_spec.rb +0 -415
data/spec/custom_logger_spec.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'sinatra/custom_logger'
|
3
|
-
|
4
|
-
describe Sinatra::CustomLogger do
|
5
|
-
before do
|
6
|
-
rack_logger = @rack_logger = double
|
7
|
-
mock_app do
|
8
|
-
helpers Sinatra::CustomLogger
|
9
|
-
|
10
|
-
before do
|
11
|
-
env['rack.logger'] = rack_logger
|
12
|
-
end
|
13
|
-
|
14
|
-
get '/' do
|
15
|
-
logger.info 'Logged message'
|
16
|
-
'Response'
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe '#logger' do
|
22
|
-
it 'falls back to request.logger' do
|
23
|
-
expect(@rack_logger).to receive(:info).with('Logged message')
|
24
|
-
get '/'
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'logger setting is set' do
|
28
|
-
before do
|
29
|
-
custom_logger = @custom_logger = double
|
30
|
-
@app.class_eval do
|
31
|
-
configure do
|
32
|
-
set :logger, custom_logger
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'calls custom logger' do
|
38
|
-
expect(@custom_logger).to receive(:info).with('Logged message')
|
39
|
-
get '/'
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
data/spec/extension_spec.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Sinatra::Extension do
|
4
|
-
module ExampleExtension
|
5
|
-
extend Sinatra::Extension
|
6
|
-
|
7
|
-
set :foo, :bar
|
8
|
-
settings.set :bar, :blah
|
9
|
-
|
10
|
-
configure :test, :production do
|
11
|
-
set :reload_stuff, false
|
12
|
-
end
|
13
|
-
|
14
|
-
configure :development do
|
15
|
-
set :reload_stuff, true
|
16
|
-
end
|
17
|
-
|
18
|
-
get '/' do
|
19
|
-
"from extension, yay"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
before { mock_app { register ExampleExtension }}
|
24
|
-
|
25
|
-
it('allows using set') { expect(settings.foo).to eq(:bar) }
|
26
|
-
it('implements configure') { expect(settings.reload_stuff).to be false }
|
27
|
-
|
28
|
-
it 'allows defing routes' do
|
29
|
-
expect(get('/')).to be_ok
|
30
|
-
expect(body).to eq("from extension, yay")
|
31
|
-
end
|
32
|
-
end
|
data/spec/json_spec.rb
DELETED
@@ -1,115 +0,0 @@
|
|
1
|
-
require 'multi_json'
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'okjson'
|
5
|
-
|
6
|
-
shared_examples_for "a json encoder" do |lib, const|
|
7
|
-
before do
|
8
|
-
begin
|
9
|
-
require lib if lib
|
10
|
-
@encoder = eval(const)
|
11
|
-
rescue LoadError
|
12
|
-
skip "unable to load #{lib}"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
it "allows setting :encoder to #{const}" do
|
17
|
-
enc = @encoder
|
18
|
-
mock_app { get('/') { json({'foo' => 'bar'}, :encoder => enc) }}
|
19
|
-
results_in 'foo' => 'bar'
|
20
|
-
end
|
21
|
-
|
22
|
-
it "allows setting settings.json_encoder to #{const}" do
|
23
|
-
enc = @encoder
|
24
|
-
mock_app do
|
25
|
-
set :json_encoder, enc
|
26
|
-
get('/') { json 'foo' => 'bar' }
|
27
|
-
end
|
28
|
-
results_in 'foo' => 'bar'
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe Sinatra::JSON do
|
33
|
-
def mock_app(&block)
|
34
|
-
super do
|
35
|
-
class_eval(&block)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def results_in(obj)
|
40
|
-
expect(OkJson.decode(get('/').body)).to eq(obj)
|
41
|
-
end
|
42
|
-
|
43
|
-
it "encodes objects to json out of the box" do
|
44
|
-
mock_app { get('/') { json :foo => [1, 'bar', nil] } }
|
45
|
-
results_in 'foo' => [1, 'bar', nil]
|
46
|
-
end
|
47
|
-
|
48
|
-
it "sets the content type to 'application/json'" do
|
49
|
-
mock_app { get('/') { json({}) } }
|
50
|
-
expect(get('/')["Content-Type"]).to include("application/json")
|
51
|
-
end
|
52
|
-
|
53
|
-
it "allows overriding content type with :content_type" do
|
54
|
-
mock_app { get('/') { json({}, :content_type => "foo/bar") } }
|
55
|
-
expect(get('/')["Content-Type"]).to eq("foo/bar")
|
56
|
-
end
|
57
|
-
|
58
|
-
it "accepts shorthands for :content_type" do
|
59
|
-
mock_app { get('/') { json({}, :content_type => :js) } }
|
60
|
-
expect(get('/')["Content-Type"]).to eq("application/javascript;charset=utf-8")
|
61
|
-
end
|
62
|
-
|
63
|
-
it 'calls generate on :encoder if available' do
|
64
|
-
enc = Object.new
|
65
|
-
def enc.generate(obj) obj.inspect end
|
66
|
-
mock_app { get('/') { json(42, :encoder => enc) }}
|
67
|
-
expect(get('/').body).to eq('42')
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'calls encode on :encoder if available' do
|
71
|
-
enc = Object.new
|
72
|
-
def enc.encode(obj) obj.inspect end
|
73
|
-
mock_app { get('/') { json(42, :encoder => enc) }}
|
74
|
-
expect(get('/').body).to eq('42')
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'sends :encoder as method call if it is a Symbol' do
|
78
|
-
mock_app { get('/') { json(42, :encoder => :inspect) }}
|
79
|
-
expect(get('/').body).to eq('42')
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'calls generate on settings.json_encoder if available' do
|
83
|
-
enc = Object.new
|
84
|
-
def enc.generate(obj) obj.inspect end
|
85
|
-
mock_app do
|
86
|
-
set :json_encoder, enc
|
87
|
-
get('/') { json 42 }
|
88
|
-
end
|
89
|
-
expect(get('/').body).to eq('42')
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'calls encode on settings.json_encode if available' do
|
93
|
-
enc = Object.new
|
94
|
-
def enc.encode(obj) obj.inspect end
|
95
|
-
mock_app do
|
96
|
-
set :json_encoder, enc
|
97
|
-
get('/') { json 42 }
|
98
|
-
end
|
99
|
-
expect(get('/').body).to eq('42')
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'sends settings.json_encode as method call if it is a Symbol' do
|
103
|
-
mock_app do
|
104
|
-
set :json_encoder, :inspect
|
105
|
-
get('/') { json 42 }
|
106
|
-
end
|
107
|
-
expect(get('/').body).to eq('42')
|
108
|
-
end
|
109
|
-
|
110
|
-
describe('Yajl') { it_should_behave_like "a json encoder", "yajl", "Yajl::Encoder" } unless defined? JRUBY_VERSION
|
111
|
-
describe('JSON') { it_should_behave_like "a json encoder", "json", "::JSON" }
|
112
|
-
describe('OkJson') { it_should_behave_like "a json encoder", nil, "OkJson" }
|
113
|
-
describe('to_json') { it_should_behave_like "a json encoder", "json", ":to_json" }
|
114
|
-
describe('without') { it_should_behave_like "a json encoder", nil, "Sinatra::JSON" }
|
115
|
-
end
|
data/spec/link_header_spec.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Sinatra::LinkHeader do
|
4
|
-
before do
|
5
|
-
mock_app do
|
6
|
-
helpers Sinatra::LinkHeader
|
7
|
-
before('/') { link 'something', :rel => 'from-filter', :foo => :bar }
|
8
|
-
|
9
|
-
get '/' do
|
10
|
-
link :something, 'booyah'
|
11
|
-
end
|
12
|
-
|
13
|
-
get '/style' do
|
14
|
-
stylesheet '/style.css'
|
15
|
-
end
|
16
|
-
|
17
|
-
get '/prefetch' do
|
18
|
-
prefetch '/foo'
|
19
|
-
end
|
20
|
-
|
21
|
-
get '/link_headers' do
|
22
|
-
response['Link'] = "<foo> ;bar=\"baz\""
|
23
|
-
stylesheet '/style.css'
|
24
|
-
prefetch '/foo'
|
25
|
-
link_headers
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe :link do
|
31
|
-
it "sets link headers" do
|
32
|
-
get '/'
|
33
|
-
expect(headers['Link'].lines).to include('<booyah>; rel="something"')
|
34
|
-
end
|
35
|
-
|
36
|
-
it "returns link html tags" do
|
37
|
-
get '/'
|
38
|
-
expect(body).to eq('<link href="booyah" rel="something" />')
|
39
|
-
end
|
40
|
-
|
41
|
-
it "takes an options hash" do
|
42
|
-
get '/'
|
43
|
-
elements = ["<something>", "foo=\"bar\"", "rel=\"from-filter\""]
|
44
|
-
expect(headers['Link'].split(",\n").first.strip.split('; ').sort).to eq(elements)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
describe :stylesheet do
|
49
|
-
it 'sets link headers' do
|
50
|
-
get '/style'
|
51
|
-
expect(headers['Link']).to match(%r{^</style\.css>;})
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'sets type to text/css' do
|
55
|
-
get '/style'
|
56
|
-
expect(headers['Link']).to include('type="text/css"')
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'sets rel to stylesheet' do
|
60
|
-
get '/style'
|
61
|
-
expect(headers['Link']).to include('rel="stylesheet"')
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'returns html tag' do
|
65
|
-
get '/style'
|
66
|
-
expect(body).to match(%r{^<link href="/style\.css"})
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe :prefetch do
|
71
|
-
it 'sets link headers' do
|
72
|
-
get '/prefetch'
|
73
|
-
expect(headers['Link']).to match(%r{^</foo>;})
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'sets rel to prefetch' do
|
77
|
-
get '/prefetch'
|
78
|
-
expect(headers['Link']).to include('rel="prefetch"')
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'returns html tag' do
|
82
|
-
get '/prefetch'
|
83
|
-
expect(body).to eq('<link href="/foo" rel="prefetch" />')
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe :link_headers do
|
88
|
-
it 'generates html for all link headers' do
|
89
|
-
get '/link_headers'
|
90
|
-
expect(body).to include('<link href="/foo" rel="prefetch" />')
|
91
|
-
expect(body).to include('<link href="/style.css" ')
|
92
|
-
end
|
93
|
-
|
94
|
-
it "respects Link headers not generated on its own" do
|
95
|
-
get '/link_headers'
|
96
|
-
expect(body).to include('<link href="foo" bar="baz" />')
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
data/spec/multi_route_spec.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Sinatra::MultiRoute do
|
4
|
-
|
5
|
-
it 'does not break normal routing' do
|
6
|
-
mock_app do
|
7
|
-
register Sinatra::MultiRoute
|
8
|
-
get('/') { 'normal' }
|
9
|
-
end
|
10
|
-
|
11
|
-
expect(get('/')).to be_ok
|
12
|
-
expect(body).to eq('normal')
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'supports multiple routes' do
|
16
|
-
mock_app do
|
17
|
-
register Sinatra::MultiRoute
|
18
|
-
get('/foo', '/bar') { 'paths' }
|
19
|
-
end
|
20
|
-
|
21
|
-
expect(get('/foo')).to be_ok
|
22
|
-
expect(body).to eq('paths')
|
23
|
-
expect(get('/bar')).to be_ok
|
24
|
-
expect(body).to eq('paths')
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'triggers conditions' do
|
28
|
-
count = 0
|
29
|
-
mock_app do
|
30
|
-
register Sinatra::MultiRoute
|
31
|
-
set(:some_condition) { |_| count += 1 }
|
32
|
-
get('/foo', '/bar', :some_condition => true) { 'paths' }
|
33
|
-
end
|
34
|
-
|
35
|
-
expect(count).to eq(4)
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'supports multiple verbs' do
|
39
|
-
mock_app do
|
40
|
-
register Sinatra::MultiRoute
|
41
|
-
route('PUT', 'POST', '/') { 'verb' }
|
42
|
-
end
|
43
|
-
|
44
|
-
expect(post('/')).to be_ok
|
45
|
-
expect(body).to eq('verb')
|
46
|
-
expect(put('/')).to be_ok
|
47
|
-
expect(body).to eq('verb')
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'takes symbols as verbs' do
|
51
|
-
mock_app do
|
52
|
-
register Sinatra::MultiRoute
|
53
|
-
route(:get, '/baz') { 'symbol as verb' }
|
54
|
-
end
|
55
|
-
|
56
|
-
expect(get('/baz')).to be_ok
|
57
|
-
expect(body).to eq('symbol as verb')
|
58
|
-
end
|
59
|
-
end
|
data/spec/namespace/foo.erb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
hi
|
@@ -1 +0,0 @@
|
|
1
|
-
ho
|
data/spec/namespace_spec.rb
DELETED
@@ -1,791 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Sinatra::Namespace do
|
4
|
-
verbs = [:get, :head, :post, :put, :delete, :options, :patch]
|
5
|
-
|
6
|
-
def mock_app(&block)
|
7
|
-
super do
|
8
|
-
register Sinatra::Namespace
|
9
|
-
class_eval(&block)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def namespace(*args, &block)
|
14
|
-
mock_app { namespace(*args, &block) }
|
15
|
-
end
|
16
|
-
|
17
|
-
verbs.each do |verb|
|
18
|
-
describe "HTTP #{verb.to_s.upcase}" do
|
19
|
-
|
20
|
-
it 'prefixes the path with the namespace' do
|
21
|
-
namespace('/foo') { send(verb, '/bar') { 'baz' }}
|
22
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
23
|
-
expect(body).to eq('baz') unless verb == :head
|
24
|
-
expect(send(verb, '/foo/baz')).not_to be_ok
|
25
|
-
end
|
26
|
-
|
27
|
-
describe 'redirect_to' do
|
28
|
-
it 'redirect within namespace' do
|
29
|
-
namespace('/foo') { send(verb, '/bar') { redirect_to '/foo_bar' }}
|
30
|
-
expect(send(verb, '/foo/bar')).to be_redirect
|
31
|
-
expect(send(verb, '/foo/bar').location).to include("/foo/foo_bar")
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'when namespace is a string' do
|
36
|
-
it 'accepts routes with no path' do
|
37
|
-
namespace('/foo') { send(verb) { 'bar' } }
|
38
|
-
expect(send(verb, '/foo')).to be_ok
|
39
|
-
expect(body).to eq('bar') unless verb == :head
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'accepts the path as a named parameter' do
|
43
|
-
namespace('/foo') { send(verb, '/:bar') { params[:bar] }}
|
44
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
45
|
-
expect(body).to eq('bar') unless verb == :head
|
46
|
-
expect(send(verb, '/foo/baz')).to be_ok
|
47
|
-
expect(body).to eq('baz') unless verb == :head
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'accepts the path as a regular expression' do
|
51
|
-
namespace('/foo') { send(verb, /\/\d\d/) { 'bar' }}
|
52
|
-
expect(send(verb, '/foo/12')).to be_ok
|
53
|
-
expect(body).to eq 'bar' unless verb == :head
|
54
|
-
expect(send(verb, '/foo/123')).not_to be_ok
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'when namespace is a named parameter' do
|
59
|
-
it 'accepts routes with no path' do
|
60
|
-
namespace('/:foo') { send(verb) { 'bar' } }
|
61
|
-
expect(send(verb, '/foo')).to be_ok
|
62
|
-
expect(body).to eq('bar') unless verb == :head
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'sets the parameter correctly' do
|
66
|
-
namespace('/:foo') { send(verb, '/bar') { params[:foo] }}
|
67
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
68
|
-
expect(body).to eq('foo') unless verb == :head
|
69
|
-
expect(send(verb, '/fox/bar')).to be_ok
|
70
|
-
expect(body).to eq('fox') unless verb == :head
|
71
|
-
expect(send(verb, '/foo/baz')).not_to be_ok
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'accepts the path as a named parameter' do
|
75
|
-
namespace('/:foo') { send(verb, '/:bar') { params[:bar] }}
|
76
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
77
|
-
expect(body).to eq('bar') unless verb == :head
|
78
|
-
expect(send(verb, '/foo/baz')).to be_ok
|
79
|
-
expect(body).to eq('baz') unless verb == :head
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'accepts the path as regular expression' do
|
83
|
-
namespace('/:foo') { send(verb, %r{/bar}) { params[:foo] }}
|
84
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
85
|
-
expect(body).to eq('foo') unless verb == :head
|
86
|
-
expect(send(verb, '/fox/bar')).to be_ok
|
87
|
-
expect(body).to eq('fox') unless verb == :head
|
88
|
-
expect(send(verb, '/foo/baz')).not_to be_ok
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'when namespace is a regular expression' do
|
93
|
-
it 'accepts routes with no path' do
|
94
|
-
namespace(%r{/foo}) { send(verb) { 'bar' } }
|
95
|
-
expect(send(verb, '/foo')).to be_ok
|
96
|
-
expect(body).to eq('bar') unless verb == :head
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'accepts the path as a named parameter' do
|
100
|
-
namespace(%r{/foo}) { send(verb, '/:bar') { params[:bar] }}
|
101
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
102
|
-
expect(body).to eq('bar') unless verb == :head
|
103
|
-
expect(send(verb, '/foo/baz')).to be_ok
|
104
|
-
expect(body).to eq('baz') unless verb == :head
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'accepts the path as a regular expression' do
|
108
|
-
namespace(/\/\d\d/) { send(verb, /\/\d\d/) { 'foo' }}
|
109
|
-
expect(send(verb, '/23/12')).to be_ok
|
110
|
-
expect(body).to eq('foo') unless verb == :head
|
111
|
-
expect(send(verb, '/123/12')).not_to be_ok
|
112
|
-
end
|
113
|
-
|
114
|
-
describe "before/after filters" do
|
115
|
-
it 'trigger before filter' do
|
116
|
-
ran = false
|
117
|
-
namespace(/\/foo\/([^\/&?]+)\/bar\/([^\/&?]+)\//) { before { ran = true };}
|
118
|
-
|
119
|
-
send(verb, '/bar/')
|
120
|
-
expect(ran).to eq(false)
|
121
|
-
|
122
|
-
send(verb, '/foo/1/bar/1/')
|
123
|
-
expect(ran).to eq(true)
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'trigger after filter' do
|
127
|
-
ran = false
|
128
|
-
namespace(/\/foo\/([^\/&?]+)\/bar\/([^\/&?]+)\//) { after { ran = true };}
|
129
|
-
|
130
|
-
send(verb, '/bar/')
|
131
|
-
expect(ran).to eq(false)
|
132
|
-
|
133
|
-
send(verb, '/foo/1/bar/1/')
|
134
|
-
expect(ran).to eq(true)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
describe 'helpers' do
|
139
|
-
it 'are defined using the helpers method' do
|
140
|
-
namespace /\/foo\/([^\/&?]+)\/bar\/([^\/&?]+)\// do
|
141
|
-
helpers do
|
142
|
-
def foo
|
143
|
-
'foo'
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
send verb, '' do
|
148
|
-
foo.to_s
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
expect(send(verb, '/foo/1/bar/1/')).to be_ok
|
153
|
-
expect(body).to eq('foo') unless verb == :head
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
context 'when namespace is a splat' do
|
159
|
-
it 'accepts the path as a splat' do
|
160
|
-
namespace('/*') { send(verb, '/*') { params[:splat].join ' - ' }}
|
161
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
162
|
-
expect(body).to eq('foo - bar') unless verb == :head
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
describe 'before-filters' do
|
167
|
-
specify 'are triggered' do
|
168
|
-
ran = false
|
169
|
-
namespace('/foo') { before { ran = true }}
|
170
|
-
send(verb, '/foo')
|
171
|
-
expect(ran).to be true
|
172
|
-
end
|
173
|
-
|
174
|
-
specify 'are not triggered for a different namespace' do
|
175
|
-
ran = false
|
176
|
-
namespace('/foo') { before { ran = true }}
|
177
|
-
send(verb, '/fox')
|
178
|
-
expect(ran).to be false
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe 'after-filters' do
|
183
|
-
specify 'are triggered' do
|
184
|
-
ran = false
|
185
|
-
namespace('/foo') { after { ran = true }}
|
186
|
-
send(verb, '/foo')
|
187
|
-
expect(ran).to be true
|
188
|
-
end
|
189
|
-
|
190
|
-
specify 'are not triggered for a different namespace' do
|
191
|
-
ran = false
|
192
|
-
namespace('/foo') { after { ran = true }}
|
193
|
-
send(verb, '/fox')
|
194
|
-
expect(ran).to be false
|
195
|
-
end
|
196
|
-
end
|
197
|
-
|
198
|
-
describe 'conditions' do
|
199
|
-
context 'when the namespace has no prefix' do
|
200
|
-
specify 'are accepted in the namespace' do
|
201
|
-
mock_app do
|
202
|
-
namespace(:host_name => 'example.com') { send(verb) { 'yes' }}
|
203
|
-
send(verb, '/') { 'no' }
|
204
|
-
end
|
205
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com')
|
206
|
-
expect(last_response).to be_ok
|
207
|
-
expect(body).to eq('yes') unless verb == :head
|
208
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.org')
|
209
|
-
expect(last_response).to be_ok
|
210
|
-
expect(body).to eq('no') unless verb == :head
|
211
|
-
end
|
212
|
-
|
213
|
-
specify 'are accepted in the route definition' do
|
214
|
-
namespace :host_name => 'example.com' do
|
215
|
-
send(verb, '/foo', :provides => :txt) { 'ok' }
|
216
|
-
end
|
217
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')).to be_ok
|
218
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')).not_to be_ok
|
219
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')).not_to be_ok
|
220
|
-
end
|
221
|
-
|
222
|
-
specify 'are accepted in the before-filter' do
|
223
|
-
ran = false
|
224
|
-
namespace :provides => :txt do
|
225
|
-
before('/foo', :host_name => 'example.com') { ran = true }
|
226
|
-
send(verb, '/*') { 'ok' }
|
227
|
-
end
|
228
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
229
|
-
expect(ran).to be false
|
230
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
231
|
-
expect(ran).to be false
|
232
|
-
send(verb, '/bar', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
233
|
-
expect(ran).to be false
|
234
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
235
|
-
expect(ran).to be true
|
236
|
-
end
|
237
|
-
|
238
|
-
specify 'are accepted in the after-filter' do
|
239
|
-
ran = false
|
240
|
-
namespace :provides => :txt do
|
241
|
-
after('/foo', :host_name => 'example.com') { ran = true }
|
242
|
-
send(verb, '/*') { 'ok' }
|
243
|
-
end
|
244
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
245
|
-
expect(ran).to be false
|
246
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
247
|
-
expect(ran).to be false
|
248
|
-
send(verb, '/bar', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
249
|
-
expect(ran).to be false
|
250
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
251
|
-
expect(ran).to be true
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
context 'when the namespace is a string' do
|
256
|
-
specify 'are accepted in the namespace' do
|
257
|
-
namespace '/foo', :host_name => 'example.com' do
|
258
|
-
send(verb) { 'ok' }
|
259
|
-
end
|
260
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')).to be_ok
|
261
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')).not_to be_ok
|
262
|
-
end
|
263
|
-
|
264
|
-
specify 'are accepted in the before-filter' do
|
265
|
-
namespace '/foo' do
|
266
|
-
before(:host_name => 'example.com') { @yes = 'yes' }
|
267
|
-
send(verb) { @yes || 'no' }
|
268
|
-
end
|
269
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')
|
270
|
-
expect(last_response).to be_ok
|
271
|
-
expect(body).to eq('yes') unless verb == :head
|
272
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')
|
273
|
-
expect(last_response).to be_ok
|
274
|
-
expect(body).to eq('no') unless verb == :head
|
275
|
-
end
|
276
|
-
|
277
|
-
specify 'are accepted in the after-filter' do
|
278
|
-
ran = false
|
279
|
-
namespace '/foo' do
|
280
|
-
before(:host_name => 'example.com') { ran = true }
|
281
|
-
send(verb) { 'ok' }
|
282
|
-
end
|
283
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')
|
284
|
-
expect(ran).to be false
|
285
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')
|
286
|
-
expect(ran).to be true
|
287
|
-
end
|
288
|
-
|
289
|
-
specify 'are accepted in the route definition' do
|
290
|
-
namespace '/foo' do
|
291
|
-
send(verb, :host_name => 'example.com') { 'ok' }
|
292
|
-
end
|
293
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')).to be_ok
|
294
|
-
expect(send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')).not_to be_ok
|
295
|
-
end
|
296
|
-
|
297
|
-
context 'when the namespace has a condition' do
|
298
|
-
specify 'are accepted in the before-filter' do
|
299
|
-
ran = false
|
300
|
-
namespace '/', :provides => :txt do
|
301
|
-
before(:host_name => 'example.com') { ran = true }
|
302
|
-
send(verb) { 'ok' }
|
303
|
-
end
|
304
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
305
|
-
expect(ran).to be false
|
306
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
307
|
-
expect(ran).to be false
|
308
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
309
|
-
expect(ran).to be true
|
310
|
-
end
|
311
|
-
|
312
|
-
specify 'are accepted in the filters' do
|
313
|
-
ran = false
|
314
|
-
namespace '/f', :provides => :txt do
|
315
|
-
before('oo', :host_name => 'example.com') { ran = true }
|
316
|
-
send(verb, '/*') { 'ok' }
|
317
|
-
end
|
318
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
319
|
-
expect(ran).to be false
|
320
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
321
|
-
expect(ran).to be false
|
322
|
-
send(verb, '/far', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
323
|
-
expect(ran).to be false
|
324
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
325
|
-
expect(ran).to be true
|
326
|
-
end
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end
|
330
|
-
|
331
|
-
describe 'helpers' do
|
332
|
-
it 'are defined using the helpers method' do
|
333
|
-
namespace '/foo' do
|
334
|
-
helpers do
|
335
|
-
def magic
|
336
|
-
42
|
337
|
-
end
|
338
|
-
end
|
339
|
-
|
340
|
-
send verb, '/bar' do
|
341
|
-
magic.to_s
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
346
|
-
expect(body).to eq('42') unless verb == :head
|
347
|
-
end
|
348
|
-
|
349
|
-
it 'can be defined as normal methods' do
|
350
|
-
namespace '/foo' do
|
351
|
-
def magic
|
352
|
-
42
|
353
|
-
end
|
354
|
-
|
355
|
-
send verb, '/bar' do
|
356
|
-
magic.to_s
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
361
|
-
expect(body).to eq('42') unless verb == :head
|
362
|
-
end
|
363
|
-
|
364
|
-
it 'can be defined using module mixins' do
|
365
|
-
mixin = Module.new do
|
366
|
-
def magic
|
367
|
-
42
|
368
|
-
end
|
369
|
-
end
|
370
|
-
|
371
|
-
namespace '/foo' do
|
372
|
-
helpers mixin
|
373
|
-
send verb, '/bar' do
|
374
|
-
magic.to_s
|
375
|
-
end
|
376
|
-
end
|
377
|
-
|
378
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
379
|
-
expect(body).to eq('42') unless verb == :head
|
380
|
-
end
|
381
|
-
|
382
|
-
specify 'are unavailable outside the namespace where they are defined' do
|
383
|
-
mock_app do
|
384
|
-
namespace '/foo' do
|
385
|
-
def magic
|
386
|
-
42
|
387
|
-
end
|
388
|
-
|
389
|
-
send verb, '/bar' do
|
390
|
-
magic.to_s
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
send verb, '/' do
|
395
|
-
magic.to_s
|
396
|
-
end
|
397
|
-
end
|
398
|
-
|
399
|
-
expect { send verb, '/' }.to raise_error(NameError)
|
400
|
-
end
|
401
|
-
|
402
|
-
specify 'are unavailable outside the namespace that they are mixed into' do
|
403
|
-
mixin = Module.new do
|
404
|
-
def magic
|
405
|
-
42
|
406
|
-
end
|
407
|
-
end
|
408
|
-
|
409
|
-
mock_app do
|
410
|
-
namespace '/foo' do
|
411
|
-
helpers mixin
|
412
|
-
send verb, '/bar' do
|
413
|
-
magic.to_s
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
send verb, '/' do
|
418
|
-
magic.to_s
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
expect { send verb, '/' }.to raise_error(NameError)
|
423
|
-
end
|
424
|
-
|
425
|
-
specify 'are available to nested namespaces' do
|
426
|
-
mock_app do
|
427
|
-
helpers do
|
428
|
-
def magic
|
429
|
-
42
|
430
|
-
end
|
431
|
-
end
|
432
|
-
|
433
|
-
namespace '/foo' do
|
434
|
-
send verb, '/bar' do
|
435
|
-
magic.to_s
|
436
|
-
end
|
437
|
-
end
|
438
|
-
end
|
439
|
-
|
440
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
441
|
-
expect(body).to eq('42') unless verb == :head
|
442
|
-
end
|
443
|
-
|
444
|
-
specify 'can call super from nested definitions' do
|
445
|
-
mock_app do
|
446
|
-
helpers do
|
447
|
-
def magic
|
448
|
-
42
|
449
|
-
end
|
450
|
-
end
|
451
|
-
|
452
|
-
namespace '/foo' do
|
453
|
-
def magic
|
454
|
-
super - 19
|
455
|
-
end
|
456
|
-
|
457
|
-
send verb, '/bar' do
|
458
|
-
magic.to_s
|
459
|
-
end
|
460
|
-
end
|
461
|
-
end
|
462
|
-
|
463
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
464
|
-
expect(body).to eq('23') unless verb == :head
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
describe 'nesting' do
|
469
|
-
it 'routes to nested namespaces' do
|
470
|
-
namespace '/foo' do
|
471
|
-
namespace '/bar' do
|
472
|
-
send(verb, '/baz') { 'OKAY!!11!'}
|
473
|
-
end
|
474
|
-
end
|
475
|
-
|
476
|
-
expect(send(verb, '/foo/bar/baz')).to be_ok
|
477
|
-
expect(body).to eq('OKAY!!11!') unless verb == :head
|
478
|
-
end
|
479
|
-
|
480
|
-
it 'exposes helpers to nested namespaces' do
|
481
|
-
namespace '/foo' do
|
482
|
-
helpers do
|
483
|
-
def magic
|
484
|
-
42
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
namespace '/bar' do
|
489
|
-
send verb, '/baz' do
|
490
|
-
magic.to_s
|
491
|
-
end
|
492
|
-
end
|
493
|
-
end
|
494
|
-
|
495
|
-
expect(send(verb, '/foo/bar/baz')).to be_ok
|
496
|
-
expect(body).to eq('42') unless verb == :head
|
497
|
-
end
|
498
|
-
|
499
|
-
specify 'does not provide access to nested helper methods' do
|
500
|
-
namespace '/foo' do
|
501
|
-
namespace '/bar' do
|
502
|
-
def magic
|
503
|
-
42
|
504
|
-
end
|
505
|
-
|
506
|
-
send verb, '/baz' do
|
507
|
-
magic.to_s
|
508
|
-
end
|
509
|
-
end
|
510
|
-
|
511
|
-
send verb do
|
512
|
-
magic.to_s
|
513
|
-
end
|
514
|
-
end
|
515
|
-
|
516
|
-
expect { send verb, '/foo' }.to raise_error(NameError)
|
517
|
-
end
|
518
|
-
|
519
|
-
it 'accepts a nested namespace as a named parameter' do
|
520
|
-
namespace('/:a') { namespace('/:b') { send(verb) { params[:a] }}}
|
521
|
-
expect(send(verb, '/foo/bar')).to be_ok
|
522
|
-
expect(body).to eq('foo') unless verb == :head
|
523
|
-
end
|
524
|
-
end
|
525
|
-
|
526
|
-
describe 'error handling' do
|
527
|
-
it 'can be customized using the not_found block' do
|
528
|
-
namespace('/de') do
|
529
|
-
not_found { 'nicht gefunden' }
|
530
|
-
end
|
531
|
-
expect(send(verb, '/foo').status).to eq 404
|
532
|
-
expect(last_response.body).not_to eq 'nicht gefunden' unless verb == :head
|
533
|
-
expect(get('/en/foo').status).to eq 404
|
534
|
-
expect(last_response.body).not_to eq 'nicht gefunden' unless verb == :head
|
535
|
-
expect(get('/de/foo').status).to eq 404
|
536
|
-
expect(last_response.body).to eq 'nicht gefunden' unless verb == :head
|
537
|
-
end
|
538
|
-
|
539
|
-
it 'can be customized for specific error codes' do
|
540
|
-
namespace('/de') do
|
541
|
-
error(404) { 'nicht gefunden' }
|
542
|
-
end
|
543
|
-
expect(send(verb, '/foo').status).to eq 404
|
544
|
-
expect(last_response.body).not_to eq 'nicht gefunden' unless verb == :head
|
545
|
-
expect(get('/en/foo').status).to eq 404
|
546
|
-
expect(last_response.body).not_to eq 'nicht gefunden' unless verb == :head
|
547
|
-
expect(get('/de/foo').status).to eq 404
|
548
|
-
expect(last_response.body).to eq 'nicht gefunden' unless verb == :head
|
549
|
-
end
|
550
|
-
|
551
|
-
it 'falls back to the handler defined in the base app' do
|
552
|
-
mock_app do
|
553
|
-
error(404) { 'not found...' }
|
554
|
-
namespace('/en') do
|
555
|
-
end
|
556
|
-
namespace('/de') do
|
557
|
-
error(404) { 'nicht gefunden' }
|
558
|
-
end
|
559
|
-
end
|
560
|
-
expect(send(verb, '/foo').status).to eq 404
|
561
|
-
expect(last_response.body).to eq 'not found...' unless verb == :head
|
562
|
-
expect(get('/en/foo').status).to eq 404
|
563
|
-
expect(last_response.body).to eq 'not found...' unless verb == :head
|
564
|
-
expect(get('/de/foo').status).to eq 404
|
565
|
-
expect(last_response.body).to eq 'nicht gefunden' unless verb == :head
|
566
|
-
end
|
567
|
-
|
568
|
-
it 'can be customized for specific Exception classes' do
|
569
|
-
mock_app do
|
570
|
-
class AError < StandardError; end
|
571
|
-
class BError < AError; end
|
572
|
-
|
573
|
-
error(AError) do
|
574
|
-
body('auth failed')
|
575
|
-
401
|
576
|
-
end
|
577
|
-
|
578
|
-
namespace('/en') do
|
579
|
-
get '/foo' do
|
580
|
-
raise BError
|
581
|
-
end
|
582
|
-
end
|
583
|
-
|
584
|
-
namespace('/de') do
|
585
|
-
error(AError) do
|
586
|
-
body('methode nicht erlaubt')
|
587
|
-
406
|
588
|
-
end
|
589
|
-
|
590
|
-
get '/foo' do
|
591
|
-
raise BError
|
592
|
-
end
|
593
|
-
end
|
594
|
-
end
|
595
|
-
expect(get('/en/foo').status).to eq 401
|
596
|
-
expect(last_response.body).to eq 'auth failed' unless verb == :head
|
597
|
-
expect(get('/de/foo').status).to eq 406
|
598
|
-
expect(last_response.body).to eq 'methode nicht erlaubt' unless verb == :head
|
599
|
-
end
|
600
|
-
|
601
|
-
it "allows custom error handlers when namespace is declared as /en/:id. Issue #119" do
|
602
|
-
mock_app {
|
603
|
-
class CError < StandardError;
|
604
|
-
end
|
605
|
-
|
606
|
-
error { raise "should not come here" }
|
607
|
-
|
608
|
-
namespace('/en/:id') do
|
609
|
-
error(CError) { 201 }
|
610
|
-
get '/?' do
|
611
|
-
raise CError
|
612
|
-
end
|
613
|
-
end
|
614
|
-
}
|
615
|
-
|
616
|
-
expect(get('/en/1').status).to eq(201)
|
617
|
-
end
|
618
|
-
end
|
619
|
-
|
620
|
-
unless verb == :head
|
621
|
-
describe 'templates' do
|
622
|
-
specify 'default to the base app\'s template' do
|
623
|
-
mock_app do
|
624
|
-
template(:foo) { 'hi' }
|
625
|
-
send(verb, '/') { erb :foo }
|
626
|
-
namespace '/foo' do
|
627
|
-
send(verb) { erb :foo }
|
628
|
-
end
|
629
|
-
end
|
630
|
-
|
631
|
-
expect(send(verb, '/').body).to eq 'hi'
|
632
|
-
expect(send(verb, '/foo').body).to eq 'hi'
|
633
|
-
end
|
634
|
-
|
635
|
-
specify 'can be nested' do
|
636
|
-
mock_app do
|
637
|
-
template(:foo) { 'hi' }
|
638
|
-
send(verb, '/') { erb :foo }
|
639
|
-
namespace '/foo' do
|
640
|
-
template(:foo) { 'ho' }
|
641
|
-
send(verb) { erb :foo }
|
642
|
-
end
|
643
|
-
end
|
644
|
-
|
645
|
-
expect(send(verb, '/').body).to eq 'hi'
|
646
|
-
expect(send(verb, '/foo').body).to eq 'ho'
|
647
|
-
end
|
648
|
-
|
649
|
-
specify 'can use a custom views directory' do
|
650
|
-
mock_app do
|
651
|
-
set :views, File.expand_path('../namespace', __FILE__)
|
652
|
-
send(verb, '/') { erb :foo }
|
653
|
-
namespace('/foo') do
|
654
|
-
set :views, File.expand_path('../namespace/nested', __FILE__)
|
655
|
-
send(verb) { erb :foo }
|
656
|
-
end
|
657
|
-
end
|
658
|
-
|
659
|
-
expect(send(verb, '/').body).to eq "hi\n"
|
660
|
-
expect(send(verb, '/foo').body).to eq "ho\n"
|
661
|
-
end
|
662
|
-
|
663
|
-
specify 'default to the base app\'s layout' do
|
664
|
-
mock_app do
|
665
|
-
layout { 'he said: <%= yield %>' }
|
666
|
-
template(:foo) { 'hi' }
|
667
|
-
send(verb, '/') { erb :foo }
|
668
|
-
namespace '/foo' do
|
669
|
-
template(:foo) { 'ho' }
|
670
|
-
send(verb) { erb :foo }
|
671
|
-
end
|
672
|
-
end
|
673
|
-
|
674
|
-
expect(send(verb, '/').body).to eq 'he said: hi'
|
675
|
-
expect(send(verb, '/foo').body).to eq 'he said: ho'
|
676
|
-
end
|
677
|
-
|
678
|
-
specify 'can define nested layouts' do
|
679
|
-
mock_app do
|
680
|
-
layout { 'Hello <%= yield %>!' }
|
681
|
-
template(:foo) { 'World' }
|
682
|
-
send(verb, '/') { erb :foo }
|
683
|
-
namespace '/foo' do
|
684
|
-
layout { 'Hi <%= yield %>!' }
|
685
|
-
send(verb) { erb :foo }
|
686
|
-
end
|
687
|
-
end
|
688
|
-
|
689
|
-
expect(send(verb, '/').body).to eq 'Hello World!'
|
690
|
-
expect(send(verb, '/foo').body).to eq 'Hi World!'
|
691
|
-
end
|
692
|
-
end
|
693
|
-
end
|
694
|
-
|
695
|
-
describe 'extensions' do
|
696
|
-
specify 'provide read access to settings' do
|
697
|
-
value = nil
|
698
|
-
mock_app do
|
699
|
-
set :foo, 42
|
700
|
-
namespace '/foo' do
|
701
|
-
value = foo
|
702
|
-
end
|
703
|
-
end
|
704
|
-
expect(value).to eq 42
|
705
|
-
end
|
706
|
-
|
707
|
-
specify 'can be registered within a namespace' do
|
708
|
-
a = b = nil
|
709
|
-
extension = Module.new { define_method(:views) { 'CUSTOM!!!' } }
|
710
|
-
mock_app do
|
711
|
-
namespace '/' do
|
712
|
-
register extension
|
713
|
-
a = views
|
714
|
-
end
|
715
|
-
b = views
|
716
|
-
end
|
717
|
-
expect(a).to eq 'CUSTOM!!!'
|
718
|
-
expect(b).not_to eq 'CUSTOM!!!'
|
719
|
-
end
|
720
|
-
|
721
|
-
specify 'trigger the route_added hook' do
|
722
|
-
route = nil
|
723
|
-
extension = Module.new
|
724
|
-
extension.singleton_class.class_eval do
|
725
|
-
define_method(:route_added) { |*r| route = r }
|
726
|
-
end
|
727
|
-
mock_app do
|
728
|
-
namespace '/f' do
|
729
|
-
register extension
|
730
|
-
get('oo') { }
|
731
|
-
end
|
732
|
-
get('/bar') { }
|
733
|
-
end
|
734
|
-
expect(route[1]).to eq(Mustermann.new '/foo')
|
735
|
-
end
|
736
|
-
|
737
|
-
specify 'prevent app-global settings from being changed' do
|
738
|
-
expect { namespace('/') { set :foo, :bar }}.to raise_error(ArgumentError)
|
739
|
-
end
|
740
|
-
end
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
describe 'settings' do
|
745
|
-
it 'provides access to top-level settings' do
|
746
|
-
mock_app do
|
747
|
-
set :foo, 'ok'
|
748
|
-
|
749
|
-
namespace '/foo' do
|
750
|
-
get '/bar' do
|
751
|
-
settings.foo
|
752
|
-
end
|
753
|
-
end
|
754
|
-
end
|
755
|
-
|
756
|
-
expect(get('/foo/bar').status).to eq(200)
|
757
|
-
expect(last_response.body).to eq('ok')
|
758
|
-
end
|
759
|
-
|
760
|
-
it 'uses some repro' do
|
761
|
-
mock_app do
|
762
|
-
set :foo, 42
|
763
|
-
|
764
|
-
namespace '/foo' do
|
765
|
-
get '/bar' do
|
766
|
-
#settings.respond_to?(:foo).to_s
|
767
|
-
settings.foo.to_s
|
768
|
-
end
|
769
|
-
end
|
770
|
-
end
|
771
|
-
|
772
|
-
expect(get('/foo/bar').status).to eq(200)
|
773
|
-
expect(last_response.body).to eq('42')
|
774
|
-
end
|
775
|
-
|
776
|
-
it 'allows checking setting existence with respond_to?' do
|
777
|
-
mock_app do
|
778
|
-
set :foo, 42
|
779
|
-
|
780
|
-
namespace '/foo' do
|
781
|
-
get '/bar' do
|
782
|
-
settings.respond_to?(:foo).to_s
|
783
|
-
end
|
784
|
-
end
|
785
|
-
end
|
786
|
-
|
787
|
-
expect(get('/foo/bar').status).to eq(200)
|
788
|
-
expect(last_response.body).to eq('true')
|
789
|
-
end
|
790
|
-
end
|
791
|
-
end
|