mustermann19 0.3.1
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/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +10 -0
- data/.yardopts +1 -0
- data/Gemfile +2 -0
- data/LICENSE +22 -0
- data/README.md +1081 -0
- data/Rakefile +6 -0
- data/bench/capturing.rb +57 -0
- data/bench/regexp.rb +21 -0
- data/bench/simple_vs_sinatra.rb +23 -0
- data/bench/template_vs_addressable.rb +26 -0
- data/internals.md +64 -0
- data/lib/mustermann.rb +61 -0
- data/lib/mustermann/ast/compiler.rb +168 -0
- data/lib/mustermann/ast/expander.rb +134 -0
- data/lib/mustermann/ast/node.rb +160 -0
- data/lib/mustermann/ast/parser.rb +137 -0
- data/lib/mustermann/ast/pattern.rb +84 -0
- data/lib/mustermann/ast/transformer.rb +129 -0
- data/lib/mustermann/ast/translator.rb +108 -0
- data/lib/mustermann/ast/tree_renderer.rb +29 -0
- data/lib/mustermann/ast/validation.rb +43 -0
- data/lib/mustermann/caster.rb +117 -0
- data/lib/mustermann/equality_map.rb +48 -0
- data/lib/mustermann/error.rb +6 -0
- data/lib/mustermann/expander.rb +206 -0
- data/lib/mustermann/extension.rb +52 -0
- data/lib/mustermann/identity.rb +19 -0
- data/lib/mustermann/mapper.rb +98 -0
- data/lib/mustermann/pattern.rb +182 -0
- data/lib/mustermann/rails.rb +17 -0
- data/lib/mustermann/regexp_based.rb +30 -0
- data/lib/mustermann/regular.rb +26 -0
- data/lib/mustermann/router.rb +9 -0
- data/lib/mustermann/router/rack.rb +50 -0
- data/lib/mustermann/router/simple.rb +144 -0
- data/lib/mustermann/shell.rb +29 -0
- data/lib/mustermann/simple.rb +38 -0
- data/lib/mustermann/simple_match.rb +30 -0
- data/lib/mustermann/sinatra.rb +22 -0
- data/lib/mustermann/template.rb +48 -0
- data/lib/mustermann/to_pattern.rb +45 -0
- data/lib/mustermann/version.rb +3 -0
- data/mustermann.gemspec +31 -0
- data/spec/expander_spec.rb +105 -0
- data/spec/extension_spec.rb +296 -0
- data/spec/identity_spec.rb +83 -0
- data/spec/mapper_spec.rb +83 -0
- data/spec/mustermann_spec.rb +65 -0
- data/spec/pattern_spec.rb +49 -0
- data/spec/rails_spec.rb +522 -0
- data/spec/regexp_based_spec.rb +8 -0
- data/spec/regular_spec.rb +36 -0
- data/spec/router/rack_spec.rb +39 -0
- data/spec/router/simple_spec.rb +32 -0
- data/spec/shell_spec.rb +109 -0
- data/spec/simple_match_spec.rb +10 -0
- data/spec/simple_spec.rb +237 -0
- data/spec/sinatra_spec.rb +574 -0
- data/spec/support.rb +5 -0
- data/spec/support/coverage.rb +16 -0
- data/spec/support/env.rb +15 -0
- data/spec/support/expand_matcher.rb +27 -0
- data/spec/support/match_matcher.rb +39 -0
- data/spec/support/pattern.rb +39 -0
- data/spec/template_spec.rb +815 -0
- data/spec/to_pattern_spec.rb +20 -0
- metadata +301 -0
@@ -0,0 +1,296 @@
|
|
1
|
+
require 'support'
|
2
|
+
require 'mustermann/extension'
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'rack/test'
|
5
|
+
|
6
|
+
describe Mustermann::Extension do
|
7
|
+
include Rack::Test::Methods
|
8
|
+
|
9
|
+
subject :app do
|
10
|
+
Sinatra.new do
|
11
|
+
set :environment, :test
|
12
|
+
register Mustermann
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'sets up the extension' do
|
17
|
+
app.should be_a(Mustermann::Extension)
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'uses Sinatra-style patterns by default' do
|
21
|
+
before { app.get('/:slug(.:extension)?') { params[:slug] } }
|
22
|
+
example { get('/foo') .body.should be == 'foo' }
|
23
|
+
example { get('/foo.') .body.should be == 'foo.' }
|
24
|
+
example { get('/foo.bar') .body.should be == 'foo' }
|
25
|
+
example { get('/a%20b') .body.should be == 'a b' }
|
26
|
+
end
|
27
|
+
|
28
|
+
describe :except do
|
29
|
+
before { app.get('/auth/*', except: '/auth/login') { 'ok' } }
|
30
|
+
example { get('/auth/dunno').should be_ok }
|
31
|
+
example { get('/auth/login').should_not be_ok }
|
32
|
+
end
|
33
|
+
|
34
|
+
describe :capture do
|
35
|
+
context 'global' do
|
36
|
+
before do
|
37
|
+
app.set(:pattern, capture: { ext: %w[png jpg gif] })
|
38
|
+
app.get('/:slug(.:ext)?') { params[:slug] }
|
39
|
+
end
|
40
|
+
|
41
|
+
example { get('/foo.bar').body.should be == 'foo.bar' }
|
42
|
+
example { get('/foo.png').body.should be == 'foo' }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'route local' do
|
46
|
+
before do
|
47
|
+
app.set(:pattern, nil)
|
48
|
+
app.get('/:id', capture: /\d+/) { 'ok' }
|
49
|
+
end
|
50
|
+
|
51
|
+
example { get('/42').should be_ok }
|
52
|
+
example { get('/foo').should_not be_ok }
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'global and route local' do
|
56
|
+
context 'global is a hash' do
|
57
|
+
before do
|
58
|
+
app.set(:pattern, capture: { id: /\d+/ })
|
59
|
+
app.get('/:id(.:ext)?', capture: { ext: 'png' }) { ?a }
|
60
|
+
app.get('/:id', capture: { id: 'foo' }) { ?b }
|
61
|
+
app.get('/:id', capture: :alpha) { ?c }
|
62
|
+
end
|
63
|
+
|
64
|
+
example { get('/20') .body.should be == ?a }
|
65
|
+
example { get('/20.png') .body.should be == ?a }
|
66
|
+
example { get('/foo') .body.should be == ?b }
|
67
|
+
example { get('/bar') .body.should be == ?c }
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'global is not a hash' do
|
71
|
+
before do
|
72
|
+
app.set(:pattern, capture: /\d+/)
|
73
|
+
app.get('/:slug(.:ext)?', capture: { ext: 'png' }) { params[:slug] }
|
74
|
+
app.get('/:slug', capture: :alpha) { 'ok' }
|
75
|
+
end
|
76
|
+
|
77
|
+
example { get('/20.png').should be_ok }
|
78
|
+
example { get('/foo.png').should_not be_ok }
|
79
|
+
example { get('/foo').should be_ok }
|
80
|
+
|
81
|
+
example { get('/20.png') .body.should be == '20' }
|
82
|
+
example { get('/42') .body.should be == '42' }
|
83
|
+
example { get('/foo') .body.should be == 'ok' }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe :pattern do
|
89
|
+
describe :except do
|
90
|
+
before { app.get('/auth/*', pattern: { except: '/auth/login' }) { 'ok' } }
|
91
|
+
example { get('/auth/dunno').should be_ok }
|
92
|
+
example { get('/auth/login').should_not be_ok }
|
93
|
+
end
|
94
|
+
|
95
|
+
describe :capture do
|
96
|
+
context 'route local' do
|
97
|
+
before do
|
98
|
+
app.set(:pattern, nil)
|
99
|
+
app.get('/:id', pattern: { capture: /\d+/ }) { 'ok' }
|
100
|
+
end
|
101
|
+
|
102
|
+
example { get('/42').should be_ok }
|
103
|
+
example { get('/foo').should_not be_ok }
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'global and route local' do
|
107
|
+
context 'global is a hash' do
|
108
|
+
before do
|
109
|
+
app.set(:pattern, capture: { id: /\d+/ })
|
110
|
+
app.get('/:id(.:ext)?', pattern: { capture: { ext: 'png' }}) { ?a }
|
111
|
+
app.get('/:id', pattern: { capture: { id: 'foo' }}) { ?b }
|
112
|
+
app.get('/:id', pattern: { capture: :alpha }) { ?c }
|
113
|
+
end
|
114
|
+
|
115
|
+
example { get('/20') .body.should be == ?a }
|
116
|
+
example { get('/20.png') .body.should be == ?a }
|
117
|
+
example { get('/foo') .body.should be == ?b }
|
118
|
+
example { get('/bar') .body.should be == ?c }
|
119
|
+
end
|
120
|
+
|
121
|
+
context 'global is not a hash' do
|
122
|
+
before do
|
123
|
+
app.set(:pattern, capture: /\d+/)
|
124
|
+
app.get('/:slug(.:ext)?', pattern: { capture: { ext: 'png' }}) { params[:slug] }
|
125
|
+
app.get('/:slug', pattern: { capture: :alpha }) { 'ok' }
|
126
|
+
end
|
127
|
+
|
128
|
+
example { get('/20.png').should be_ok }
|
129
|
+
example { get('/foo.png').should_not be_ok }
|
130
|
+
example { get('/foo').should be_ok }
|
131
|
+
|
132
|
+
example { get('/20.png') .body.should be == '20' }
|
133
|
+
example { get('/42') .body.should be == '42' }
|
134
|
+
example { get('/foo') .body.should be == 'ok' }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
describe :greedy do
|
140
|
+
context 'default' do
|
141
|
+
before { app.get('/:name.:ext') { params[:name] }}
|
142
|
+
example { get('/foo.bar') .body.should be == 'foo' }
|
143
|
+
example { get('/foo.bar.baz') .body.should be == 'foo.bar' }
|
144
|
+
end
|
145
|
+
|
146
|
+
context 'enabled' do
|
147
|
+
before { app.get('/:name.:ext', pattern: { greedy: true }) { params[:name] }}
|
148
|
+
example { get('/foo.bar') .body.should be == 'foo' }
|
149
|
+
example { get('/foo.bar.baz') .body.should be == 'foo.bar' }
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'disabled' do
|
153
|
+
before { app.get('/:name.:ext', pattern: { greedy: false }) { params[:name] }}
|
154
|
+
example { get('/foo.bar') .body.should be == 'foo' }
|
155
|
+
example { get('/foo.bar.baz') .body.should be == 'foo' }
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'global' do
|
159
|
+
before do
|
160
|
+
app.set(:pattern, greedy: false)
|
161
|
+
app.get('/:name.:ext') { params[:name] }
|
162
|
+
end
|
163
|
+
|
164
|
+
example { get('/foo.bar') .body.should be == 'foo' }
|
165
|
+
example { get('/foo.bar.baz') .body.should be == 'foo' }
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe :space_matches_plus do
|
170
|
+
context 'default' do
|
171
|
+
before { app.get('/foo bar') { 'ok' }}
|
172
|
+
example { get('/foo%20bar') .should be_ok }
|
173
|
+
example { get('/foo+bar') .should be_ok }
|
174
|
+
end
|
175
|
+
|
176
|
+
context 'enabled' do
|
177
|
+
before { app.get('/foo bar', pattern: { space_matches_plus: true }) { 'ok' }}
|
178
|
+
example { get('/foo%20bar') .should be_ok }
|
179
|
+
example { get('/foo+bar') .should be_ok }
|
180
|
+
end
|
181
|
+
|
182
|
+
context 'disabled' do
|
183
|
+
before { app.get('/foo bar', pattern: { space_matches_plus: false }) { 'ok' }}
|
184
|
+
example { get('/foo%20bar') .should be_ok }
|
185
|
+
example { get('/foo+bar') .should_not be_ok }
|
186
|
+
end
|
187
|
+
|
188
|
+
context 'global' do
|
189
|
+
before do
|
190
|
+
app.set(:pattern, space_matches_plus: false)
|
191
|
+
app.get('/foo bar') { 'ok' }
|
192
|
+
end
|
193
|
+
|
194
|
+
example { get('/foo%20bar') .should be_ok }
|
195
|
+
example { get('/foo+bar') .should_not be_ok }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe :uri_decode do
|
200
|
+
context 'default' do
|
201
|
+
before { app.get('/&') { 'ok' }}
|
202
|
+
example { get('/&') .should be_ok }
|
203
|
+
example { get('/%26') .should be_ok }
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'enabled' do
|
207
|
+
before { app.get('/&', pattern: { uri_decode: true }) { 'ok' }}
|
208
|
+
example { get('/&') .should be_ok }
|
209
|
+
example { get('/%26') .should be_ok }
|
210
|
+
end
|
211
|
+
|
212
|
+
context 'disabled' do
|
213
|
+
before { app.get('/&', pattern: { uri_decode: false }) { 'ok' }}
|
214
|
+
example { get('/&') .should be_ok }
|
215
|
+
example { get('/%26') .should_not be_ok }
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'global' do
|
219
|
+
before do
|
220
|
+
app.set(:pattern, uri_decode: false)
|
221
|
+
app.get('/&') { 'ok' }
|
222
|
+
end
|
223
|
+
|
224
|
+
example { get('/&') .should be_ok }
|
225
|
+
example { get('/%26') .should_not be_ok }
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
describe :type do
|
231
|
+
describe :identity do
|
232
|
+
before do
|
233
|
+
app.set(:pattern, type: :identity)
|
234
|
+
app.get('/:foo') { 'ok' }
|
235
|
+
end
|
236
|
+
|
237
|
+
example { get('/:foo').should be_ok }
|
238
|
+
example { get('/foo').should_not be_ok }
|
239
|
+
end
|
240
|
+
|
241
|
+
describe :rails do
|
242
|
+
before do
|
243
|
+
app.set(:pattern, type: :rails)
|
244
|
+
app.get('/:slug(.:extension)') { params[:slug] }
|
245
|
+
end
|
246
|
+
|
247
|
+
example { get('/foo') .body.should be == 'foo' }
|
248
|
+
example { get('/foo.') .body.should be == 'foo.' }
|
249
|
+
example { get('/foo.bar') .body.should be == 'foo' }
|
250
|
+
example { get('/a%20b') .body.should be == 'a b' }
|
251
|
+
end
|
252
|
+
|
253
|
+
describe :shell do
|
254
|
+
before do
|
255
|
+
app.set(:pattern, type: :shell)
|
256
|
+
app.get('/{foo,bar}') { 'ok' }
|
257
|
+
end
|
258
|
+
|
259
|
+
example(nil, skip: true) { get('/foo').should be_ok }
|
260
|
+
example(nil, skip: true) { get('/bar').should be_ok }
|
261
|
+
end
|
262
|
+
|
263
|
+
describe :simple do
|
264
|
+
before do
|
265
|
+
app.set(:pattern, type: :simple)
|
266
|
+
app.get('/(a)') { 'ok' }
|
267
|
+
end
|
268
|
+
|
269
|
+
example { get('/(a)').should be_ok }
|
270
|
+
example { get('/a').should_not be_ok }
|
271
|
+
end
|
272
|
+
|
273
|
+
describe :simple do
|
274
|
+
before do
|
275
|
+
app.set(:pattern, type: :template)
|
276
|
+
app.get('/foo{/segments*}{.ext}') { "%p %p" % [params[:segments], params[:ext]] }
|
277
|
+
end
|
278
|
+
|
279
|
+
example { get('/foo/a.png').should be_ok }
|
280
|
+
example { get('/foo/a').should_not be_ok }
|
281
|
+
|
282
|
+
example { get('/foo/a.png').body.should be == '["a"] "png"' }
|
283
|
+
example { get('/foo/a/b.png').body.should be == '["a", "b"] "png"' }
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
context 'works with filters' do
|
288
|
+
before do
|
289
|
+
app.before('/auth/*', except: '/auth/login') { halt 'auth required' }
|
290
|
+
app.get('/auth/login') { 'please log in' }
|
291
|
+
end
|
292
|
+
|
293
|
+
example { get('/auth/dunno').body.should be == 'auth required' }
|
294
|
+
example { get('/auth/login').body.should be == 'please log in' }
|
295
|
+
end
|
296
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'support'
|
3
|
+
require 'mustermann/identity'
|
4
|
+
|
5
|
+
describe Mustermann::Identity do
|
6
|
+
extend Support::Pattern
|
7
|
+
|
8
|
+
pattern '' do
|
9
|
+
it { should match('') }
|
10
|
+
it { should_not match('/') }
|
11
|
+
end
|
12
|
+
|
13
|
+
pattern '/' do
|
14
|
+
it { should match('/') }
|
15
|
+
it { should_not match('/foo') }
|
16
|
+
|
17
|
+
example { pattern.params('/').should be == {} }
|
18
|
+
example { pattern.params('').should be_nil }
|
19
|
+
end
|
20
|
+
|
21
|
+
pattern '/foo' do
|
22
|
+
it { should match('/foo') }
|
23
|
+
it { should_not match('/bar') }
|
24
|
+
it { should_not match('/foo.bar') }
|
25
|
+
end
|
26
|
+
|
27
|
+
pattern '/foo/bar' do
|
28
|
+
it { should match('/foo/bar') }
|
29
|
+
it { should match('/foo%2Fbar') }
|
30
|
+
it { should match('/foo%2fbar') }
|
31
|
+
end
|
32
|
+
|
33
|
+
pattern '/:foo' do
|
34
|
+
it { should match('/:foo') }
|
35
|
+
it { should match('/%3Afoo') }
|
36
|
+
it { should_not match('/foo') }
|
37
|
+
it { should_not match('/foo?') }
|
38
|
+
it { should_not match('/foo/bar') }
|
39
|
+
it { should_not match('/') }
|
40
|
+
it { should_not match('/foo/') }
|
41
|
+
end
|
42
|
+
|
43
|
+
pattern '/föö' do
|
44
|
+
it { should match("/f%C3%B6%C3%B6") }
|
45
|
+
end
|
46
|
+
|
47
|
+
pattern '/test$/' do
|
48
|
+
it { should match('/test$/') }
|
49
|
+
end
|
50
|
+
|
51
|
+
pattern '/te+st/' do
|
52
|
+
it { should match('/te+st/') }
|
53
|
+
it { should_not match('/test/') }
|
54
|
+
it { should_not match('/teest/') }
|
55
|
+
end
|
56
|
+
|
57
|
+
pattern "/path with spaces" do
|
58
|
+
it { should match('/path%20with%20spaces') }
|
59
|
+
it { should_not match('/path%2Bwith%2Bspaces') }
|
60
|
+
it { should_not match('/path+with+spaces') }
|
61
|
+
end
|
62
|
+
|
63
|
+
pattern '/foo&bar' do
|
64
|
+
it { should match('/foo&bar') }
|
65
|
+
end
|
66
|
+
|
67
|
+
pattern '/test.bar' do
|
68
|
+
it { should match('/test.bar') }
|
69
|
+
it { should_not match('/test0bar') }
|
70
|
+
end
|
71
|
+
|
72
|
+
pattern '/foo/bar', uri_decode: false do
|
73
|
+
it { should match('/foo/bar') }
|
74
|
+
it { should_not match('/foo%2Fbar') }
|
75
|
+
it { should_not match('/foo%2fbar') }
|
76
|
+
end
|
77
|
+
|
78
|
+
pattern "/path with spaces", uri_decode: false do
|
79
|
+
it { should_not match('/path%20with%20spaces') }
|
80
|
+
it { should_not match('/path%2Bwith%2Bspaces') }
|
81
|
+
it { should_not match('/path+with+spaces') }
|
82
|
+
end
|
83
|
+
end
|
data/spec/mapper_spec.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'support'
|
2
|
+
require 'mustermann/mapper'
|
3
|
+
|
4
|
+
describe Mustermann::Mapper do
|
5
|
+
describe :initialize do
|
6
|
+
context 'accepts a block with no arguments, using the return value' do
|
7
|
+
subject(:mapper) { Mustermann::Mapper.new(additional_values: :raise) {{ "/foo" => "/bar" }}}
|
8
|
+
its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } }
|
9
|
+
example { mapper['/foo'].should be == '/bar' }
|
10
|
+
example { mapper['/fox'].should be == '/fox' }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'accepts a block with argument, passes instance to it' do
|
14
|
+
subject(:mapper) { Mustermann::Mapper.new(additional_values: :raise) { |m| m["/foo"] = "/bar" }}
|
15
|
+
its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } }
|
16
|
+
example { mapper['/foo'].should be == '/bar' }
|
17
|
+
example { mapper['/fox'].should be == '/fox' }
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'accepts mappings followed by options' do
|
21
|
+
subject(:mapper) { Mustermann::Mapper.new("/foo" => "/bar", additional_values: :raise) }
|
22
|
+
its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } }
|
23
|
+
example { mapper['/foo'].should be == '/bar' }
|
24
|
+
example { mapper['/fox'].should be == '/fox' }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'accepts options followed by mappings' do
|
28
|
+
subject(:mapper) { Mustermann::Mapper.new(additional_values: :raise, "/foo" => "/bar") }
|
29
|
+
its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } }
|
30
|
+
example { mapper['/foo'].should be == '/bar' }
|
31
|
+
example { mapper['/fox'].should be == '/fox' }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'allows specifying type' do
|
35
|
+
subject(:mapper) { Mustermann::Mapper.new(additional_values: :raise, type: :rails, "/foo" => "/bar") }
|
36
|
+
its(:to_h) { should be == { Mustermann.new("/foo", type: :rails) => Mustermann::Expander.new("/bar", type: :rails) } }
|
37
|
+
example { mapper['/foo'].should be == '/bar' }
|
38
|
+
example { mapper['/fox'].should be == '/fox' }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe :convert do
|
43
|
+
subject(:mapper) { Mustermann::Mapper.new }
|
44
|
+
|
45
|
+
context 'it maps params' do
|
46
|
+
before { mapper["/:a"] = "/:a.html" }
|
47
|
+
example { mapper["/foo"] .should be == "/foo.html" }
|
48
|
+
example { mapper["/foo/bar"] .should be == "/foo/bar" }
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'it supports named splats' do
|
52
|
+
before { mapper["/*a"] = "/*a.html" }
|
53
|
+
example { mapper["/foo"] .should be == "/foo.html" }
|
54
|
+
example { mapper["/foo/bar"] .should be == "/foo/bar.html" }
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'can map from patterns' do
|
58
|
+
before { mapper[Mustermann.new("/:a")] = "/:a.html" }
|
59
|
+
example { mapper["/foo"] .should be == "/foo.html" }
|
60
|
+
example { mapper["/foo/bar"] .should be == "/foo/bar" }
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'can map to patterns' do
|
64
|
+
before { mapper[Mustermann.new("/:a")] = Mustermann.new("/:a.html") }
|
65
|
+
example { mapper["/foo"] .should be == "/foo.html" }
|
66
|
+
example { mapper["/foo/bar"] .should be == "/foo/bar" }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'can map to expanders' do
|
70
|
+
before { mapper[Mustermann.new("/:a")] = Mustermann::Expander.new("/:a.html") }
|
71
|
+
example { mapper["/foo"] .should be == "/foo.html" }
|
72
|
+
example { mapper["/foo/bar"] .should be == "/foo/bar" }
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'can map to array' do
|
76
|
+
before { mapper["/:a"] = ["/:a.html", "/:a.:f"] }
|
77
|
+
example { mapper["/foo"] .should be == "/foo.html" }
|
78
|
+
example { mapper["/foo", "f" => 'x'] .should be == "/foo.x" }
|
79
|
+
example { mapper["/foo", f: 'x'] .should be == "/foo.x" }
|
80
|
+
example { mapper["/foo/bar"] .should be == "/foo/bar" }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|