mustermann 1.1.2 → 2.0.0
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/README.md +1 -24
- data/lib/mustermann/ast/translator.rb +1 -0
- data/lib/mustermann/extension.rb +1 -48
- data/lib/mustermann/version.rb +1 -1
- data/lib/mustermann.rb +0 -1
- data/mustermann.gemspec +0 -1
- data/spec/mustermann_spec.rb +2 -5
- metadata +3 -5
- data/spec/extension_spec.rb +0 -297
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0181b5f440930f6c4e8308e8e11f5cd0513dc4245a37c69fe06d7a3448e3d48
|
4
|
+
data.tar.gz: 467aed81ed5b287a53c29fe7a43eacf375ce4f973b0b9b85d3400ab8c3bb9d80
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8aa6339c6cd99bf69519e1b5be4afcbce878379f66a3fda3c8996b0020941296dccbf9cb51c9a03989e2561ca27709225a9dbadaa9da6d81476522c0a2845fd7
|
7
|
+
data.tar.gz: c6171a83ab906b0568516d26475531221196d130ad42b75e766a4200d252c5042fdcb6061a7b9a60980edefdd89e85d46aa1bcbba0cffaa01c66972f669409fc
|
data/README.md
CHANGED
@@ -377,30 +377,7 @@ mapper['/foo/bar'] # => "/foo/bar"
|
|
377
377
|
<a name="-sinatra-integration"></a>
|
378
378
|
## Sinatra Integration
|
379
379
|
|
380
|
-
|
381
|
-
|
382
|
-
``` ruby
|
383
|
-
require 'sinatra'
|
384
|
-
require 'mustermann'
|
385
|
-
|
386
|
-
get Mustermann.new('/:foo') do
|
387
|
-
params[:foo]
|
388
|
-
end
|
389
|
-
```
|
390
|
-
|
391
|
-
In fact, since using this with Sinatra is the main use case, it comes with a build-in extension for **Sinatra 1.x**.
|
392
|
-
|
393
|
-
``` ruby
|
394
|
-
require 'sinatra'
|
395
|
-
require 'mustermann'
|
396
|
-
|
397
|
-
register Mustermann
|
398
|
-
|
399
|
-
# this will use Mustermann rather than the built-in pattern matching
|
400
|
-
get '/:slug(.ext)?' do
|
401
|
-
params[:slug]
|
402
|
-
end
|
403
|
-
```
|
380
|
+
Mustermann is used in Sinatra by default since version 2.0, for previous versions an [extension](https://github.com/sinatra/mustermann-sinatra-extension) is available.
|
404
381
|
|
405
382
|
### Configuration
|
406
383
|
|
data/lib/mustermann/extension.rb
CHANGED
@@ -1,50 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'sinatra/version'
|
3
|
-
fail "no need to load the Mustermann extension for #{::Sinatra::VERSION}" if ::Sinatra::VERSION >= '2.0.0'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
module Mustermann
|
8
|
-
# Sinatra 1.x extension switching default pattern parsing over to Mustermann.
|
9
|
-
#
|
10
|
-
# @example With classic Sinatra application
|
11
|
-
# require 'sinatra'
|
12
|
-
# require 'mustermann'
|
13
|
-
#
|
14
|
-
# register Mustermann
|
15
|
-
# get('/:id', capture: /\d+/) { ... }
|
16
|
-
#
|
17
|
-
# @example With modular Sinatra application
|
18
|
-
# require 'sinatra/base'
|
19
|
-
# require 'mustermann'
|
20
|
-
#
|
21
|
-
# class MyApp < Sinatra::Base
|
22
|
-
# register Mustermann
|
23
|
-
# get('/:id', capture: /\d+/) { ... }
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @see file:README.md#Sinatra_Integration "Sinatra Integration" in the README
|
27
|
-
module Extension
|
28
|
-
def compile!(verb, path, block, except: nil, capture: nil, pattern: { }, **options)
|
29
|
-
if path.respond_to? :to_str
|
30
|
-
pattern[:except] = except if except
|
31
|
-
pattern[:capture] = capture if capture
|
32
|
-
|
33
|
-
if settings.respond_to? :pattern and settings.pattern?
|
34
|
-
pattern.merge! settings.pattern do |key, local, global|
|
35
|
-
next local unless local.is_a? Hash
|
36
|
-
next global.merge(local) if global.is_a? Hash
|
37
|
-
Hash.new(global).merge! local
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
path = Mustermann.new(path, **pattern)
|
42
|
-
condition { params.merge! path.params(captures: Array(params[:captures]), offset: -1) }
|
43
|
-
end
|
44
|
-
|
45
|
-
super(verb, path, block, options)
|
46
|
-
end
|
47
|
-
|
48
|
-
private :compile!
|
49
|
-
end
|
50
|
-
end
|
3
|
+
fail "Mustermann extension for Sinatra has been extracted into its own gem. More information at https://github.com/sinatra/mustermann-sinatra-extension"
|
data/lib/mustermann/version.rb
CHANGED
data/lib/mustermann.rb
CHANGED
data/mustermann.gemspec
CHANGED
@@ -13,7 +13,6 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.required_ruby_version = '>= 2.2.0'
|
14
14
|
s.files = `git ls-files`.split("\n")
|
15
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
16
|
|
18
17
|
s.add_runtime_dependency('ruby2_keywords', '~> 0.0.1')
|
19
18
|
end
|
data/spec/mustermann_spec.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'support'
|
3
3
|
require 'mustermann'
|
4
|
-
require 'mustermann/extension'
|
5
4
|
require 'sinatra/base'
|
6
5
|
|
7
6
|
describe Mustermann do
|
@@ -70,11 +69,9 @@ describe Mustermann do
|
|
70
69
|
describe :extend_object do
|
71
70
|
context 'special behavior for Sinatra only' do
|
72
71
|
example { Object .new.extend(Mustermann).should be_a(Mustermann) }
|
73
|
-
example { Object .new.extend(Mustermann).should_not be_a(Mustermann::Extension) }
|
74
72
|
example { Class .new.extend(Mustermann).should be_a(Mustermann) }
|
75
|
-
|
76
|
-
example { Sinatra
|
77
|
-
example { Sinatra .new.extend(Mustermann).should be_a(Mustermann::Extension) }
|
73
|
+
|
74
|
+
example { expect { Sinatra.new.extend(Mustermann) }.to raise_error(RuntimeError, "Mustermann extension for Sinatra has been extracted into its own gem. More information at https://github.com/sinatra/mustermann-sinatra-extension") }
|
78
75
|
end
|
79
76
|
end
|
80
77
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mustermann
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Haase
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-07-
|
12
|
+
date: 2022-07-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ruby2_keywords
|
@@ -76,7 +76,6 @@ files:
|
|
76
76
|
- spec/concat_spec.rb
|
77
77
|
- spec/equality_map_spec.rb
|
78
78
|
- spec/expander_spec.rb
|
79
|
-
- spec/extension_spec.rb
|
80
79
|
- spec/identity_spec.rb
|
81
80
|
- spec/mapper_spec.rb
|
82
81
|
- spec/mustermann_spec.rb
|
@@ -105,7 +104,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
104
|
- !ruby/object:Gem::Version
|
106
105
|
version: '0'
|
107
106
|
requirements: []
|
108
|
-
rubygems_version: 3.2.
|
107
|
+
rubygems_version: 3.2.22
|
109
108
|
signing_key:
|
110
109
|
specification_version: 4
|
111
110
|
summary: Your personal string matching expert.
|
@@ -115,7 +114,6 @@ test_files:
|
|
115
114
|
- spec/concat_spec.rb
|
116
115
|
- spec/equality_map_spec.rb
|
117
116
|
- spec/expander_spec.rb
|
118
|
-
- spec/extension_spec.rb
|
119
117
|
- spec/identity_spec.rb
|
120
118
|
- spec/mapper_spec.rb
|
121
119
|
- spec/mustermann_spec.rb
|
data/spec/extension_spec.rb
DELETED
@@ -1,297 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'support'
|
3
|
-
require 'mustermann/extension'
|
4
|
-
require 'sinatra/base'
|
5
|
-
require 'rack/test'
|
6
|
-
|
7
|
-
describe Mustermann::Extension do
|
8
|
-
include Rack::Test::Methods
|
9
|
-
|
10
|
-
subject :app do
|
11
|
-
Sinatra.new do
|
12
|
-
set :environment, :test
|
13
|
-
register Mustermann
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'sets up the extension' do
|
18
|
-
app.should be_a(Mustermann::Extension)
|
19
|
-
end
|
20
|
-
|
21
|
-
context 'uses Sinatra-style patterns by default' do
|
22
|
-
before { app.get('/:slug(.:extension)?') { params[:slug] } }
|
23
|
-
example { get('/foo') .body.should be == 'foo' }
|
24
|
-
example { get('/foo.') .body.should be == 'foo.' }
|
25
|
-
example { get('/foo.bar') .body.should be == 'foo' }
|
26
|
-
example { get('/a%20b') .body.should be == 'a b' }
|
27
|
-
end
|
28
|
-
|
29
|
-
describe :except do
|
30
|
-
before { app.get('/auth/*', except: '/auth/login') { 'ok' } }
|
31
|
-
example { get('/auth/dunno').should be_ok }
|
32
|
-
example { get('/auth/login').should_not be_ok }
|
33
|
-
end
|
34
|
-
|
35
|
-
describe :capture do
|
36
|
-
context 'global' do
|
37
|
-
before do
|
38
|
-
app.set(:pattern, capture: { ext: %w[png jpg gif] })
|
39
|
-
app.get('/:slug(.:ext)?') { params[:slug] }
|
40
|
-
end
|
41
|
-
|
42
|
-
example { get('/foo.bar').body.should be == 'foo.bar' }
|
43
|
-
example { get('/foo.png').body.should be == 'foo' }
|
44
|
-
end
|
45
|
-
|
46
|
-
context 'route local' do
|
47
|
-
before do
|
48
|
-
app.set(:pattern, nil)
|
49
|
-
app.get('/:id', capture: /\d+/) { 'ok' }
|
50
|
-
end
|
51
|
-
|
52
|
-
example { get('/42').should be_ok }
|
53
|
-
example { get('/foo').should_not be_ok }
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'global and route local' do
|
57
|
-
context 'global is a hash' do
|
58
|
-
before do
|
59
|
-
app.set(:pattern, capture: { id: /\d+/ })
|
60
|
-
app.get('/:id(.:ext)?', capture: { ext: 'png' }) { ?a }
|
61
|
-
app.get('/:id', capture: { id: 'foo' }) { ?b }
|
62
|
-
app.get('/:id', capture: :alpha) { ?c }
|
63
|
-
end
|
64
|
-
|
65
|
-
example { get('/20') .body.should be == ?a }
|
66
|
-
example { get('/20.png') .body.should be == ?a }
|
67
|
-
example { get('/foo') .body.should be == ?b }
|
68
|
-
example { get('/bar') .body.should be == ?c }
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'global is not a hash' do
|
72
|
-
before do
|
73
|
-
app.set(:pattern, capture: /\d+/)
|
74
|
-
app.get('/:slug(.:ext)?', capture: { ext: 'png' }) { params[:slug] }
|
75
|
-
app.get('/:slug', capture: :alpha) { 'ok' }
|
76
|
-
end
|
77
|
-
|
78
|
-
example { get('/20.png').should be_ok }
|
79
|
-
example { get('/foo.png').should_not be_ok }
|
80
|
-
example { get('/foo').should be_ok }
|
81
|
-
|
82
|
-
example { get('/20.png') .body.should be == '20' }
|
83
|
-
example { get('/42') .body.should be == '42' }
|
84
|
-
example { get('/foo') .body.should be == 'ok' }
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
describe :pattern do
|
90
|
-
describe :except do
|
91
|
-
before { app.get('/auth/*', pattern: { except: '/auth/login' }) { 'ok' } }
|
92
|
-
example { get('/auth/dunno').should be_ok }
|
93
|
-
example { get('/auth/login').should_not be_ok }
|
94
|
-
end
|
95
|
-
|
96
|
-
describe :capture do
|
97
|
-
context 'route local' do
|
98
|
-
before do
|
99
|
-
app.set(:pattern, nil)
|
100
|
-
app.get('/:id', pattern: { capture: /\d+/ }) { 'ok' }
|
101
|
-
end
|
102
|
-
|
103
|
-
example { get('/42').should be_ok }
|
104
|
-
example { get('/foo').should_not be_ok }
|
105
|
-
end
|
106
|
-
|
107
|
-
context 'global and route local' do
|
108
|
-
context 'global is a hash' do
|
109
|
-
before do
|
110
|
-
app.set(:pattern, capture: { id: /\d+/ })
|
111
|
-
app.get('/:id(.:ext)?', pattern: { capture: { ext: 'png' }}) { ?a }
|
112
|
-
app.get('/:id', pattern: { capture: { id: 'foo' }}) { ?b }
|
113
|
-
app.get('/:id', pattern: { capture: :alpha }) { ?c }
|
114
|
-
end
|
115
|
-
|
116
|
-
example { get('/20') .body.should be == ?a }
|
117
|
-
example { get('/20.png') .body.should be == ?a }
|
118
|
-
example { get('/foo') .body.should be == ?b }
|
119
|
-
example { get('/bar') .body.should be == ?c }
|
120
|
-
end
|
121
|
-
|
122
|
-
context 'global is not a hash' do
|
123
|
-
before do
|
124
|
-
app.set(:pattern, capture: /\d+/)
|
125
|
-
app.get('/:slug(.:ext)?', pattern: { capture: { ext: 'png' }}) { params[:slug] }
|
126
|
-
app.get('/:slug', pattern: { capture: :alpha }) { 'ok' }
|
127
|
-
end
|
128
|
-
|
129
|
-
example { get('/20.png').should be_ok }
|
130
|
-
example { get('/foo.png').should_not be_ok }
|
131
|
-
example { get('/foo').should be_ok }
|
132
|
-
|
133
|
-
example { get('/20.png') .body.should be == '20' }
|
134
|
-
example { get('/42') .body.should be == '42' }
|
135
|
-
example { get('/foo') .body.should be == 'ok' }
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
describe :greedy do
|
141
|
-
context 'default' do
|
142
|
-
before { app.get('/:name.:ext') { params[:name] }}
|
143
|
-
example { get('/foo.bar') .body.should be == 'foo' }
|
144
|
-
example { get('/foo.bar.baz') .body.should be == 'foo.bar' }
|
145
|
-
end
|
146
|
-
|
147
|
-
context 'enabled' do
|
148
|
-
before { app.get('/:name.:ext', pattern: { greedy: true }) { params[:name] }}
|
149
|
-
example { get('/foo.bar') .body.should be == 'foo' }
|
150
|
-
example { get('/foo.bar.baz') .body.should be == 'foo.bar' }
|
151
|
-
end
|
152
|
-
|
153
|
-
context 'disabled' do
|
154
|
-
before { app.get('/:name.:ext', pattern: { greedy: false }) { params[:name] }}
|
155
|
-
example { get('/foo.bar') .body.should be == 'foo' }
|
156
|
-
example { get('/foo.bar.baz') .body.should be == 'foo' }
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'global' do
|
160
|
-
before do
|
161
|
-
app.set(:pattern, greedy: false)
|
162
|
-
app.get('/:name.:ext') { params[:name] }
|
163
|
-
end
|
164
|
-
|
165
|
-
example { get('/foo.bar') .body.should be == 'foo' }
|
166
|
-
example { get('/foo.bar.baz') .body.should be == 'foo' }
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
describe :space_matches_plus do
|
171
|
-
context 'default' do
|
172
|
-
before { app.get('/foo bar') { 'ok' }}
|
173
|
-
example { get('/foo%20bar') .should be_ok }
|
174
|
-
example { get('/foo+bar') .should be_ok }
|
175
|
-
end
|
176
|
-
|
177
|
-
context 'enabled' do
|
178
|
-
before { app.get('/foo bar', pattern: { space_matches_plus: true }) { 'ok' }}
|
179
|
-
example { get('/foo%20bar') .should be_ok }
|
180
|
-
example { get('/foo+bar') .should be_ok }
|
181
|
-
end
|
182
|
-
|
183
|
-
context 'disabled' do
|
184
|
-
before { app.get('/foo bar', pattern: { space_matches_plus: false }) { 'ok' }}
|
185
|
-
example { get('/foo%20bar') .should be_ok }
|
186
|
-
example { get('/foo+bar') .should_not be_ok }
|
187
|
-
end
|
188
|
-
|
189
|
-
context 'global' do
|
190
|
-
before do
|
191
|
-
app.set(:pattern, space_matches_plus: false)
|
192
|
-
app.get('/foo bar') { 'ok' }
|
193
|
-
end
|
194
|
-
|
195
|
-
example { get('/foo%20bar') .should be_ok }
|
196
|
-
example { get('/foo+bar') .should_not be_ok }
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
describe :uri_decode do
|
201
|
-
context 'default' do
|
202
|
-
before { app.get('/&') { 'ok' }}
|
203
|
-
example { get('/&') .should be_ok }
|
204
|
-
example { get('/%26') .should be_ok }
|
205
|
-
end
|
206
|
-
|
207
|
-
context 'enabled' do
|
208
|
-
before { app.get('/&', pattern: { uri_decode: true }) { 'ok' }}
|
209
|
-
example { get('/&') .should be_ok }
|
210
|
-
example { get('/%26') .should be_ok }
|
211
|
-
end
|
212
|
-
|
213
|
-
context 'disabled' do
|
214
|
-
before { app.get('/&', pattern: { uri_decode: false }) { 'ok' }}
|
215
|
-
example { get('/&') .should be_ok }
|
216
|
-
example { get('/%26') .should_not be_ok }
|
217
|
-
end
|
218
|
-
|
219
|
-
context 'global' do
|
220
|
-
before do
|
221
|
-
app.set(:pattern, uri_decode: false)
|
222
|
-
app.get('/&') { 'ok' }
|
223
|
-
end
|
224
|
-
|
225
|
-
example { get('/&') .should be_ok }
|
226
|
-
example { get('/%26') .should_not be_ok }
|
227
|
-
end
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe :type do
|
232
|
-
describe :identity do
|
233
|
-
before do
|
234
|
-
app.set(:pattern, type: :identity)
|
235
|
-
app.get('/:foo') { 'ok' }
|
236
|
-
end
|
237
|
-
|
238
|
-
example { get('/:foo').should be_ok }
|
239
|
-
example { get('/foo').should_not be_ok }
|
240
|
-
end
|
241
|
-
|
242
|
-
describe :rails do
|
243
|
-
before do
|
244
|
-
app.set(:pattern, type: :rails)
|
245
|
-
app.get('/:slug(.:extension)') { params[:slug] }
|
246
|
-
end
|
247
|
-
|
248
|
-
example { get('/foo') .body.should be == 'foo' }
|
249
|
-
example { get('/foo.') .body.should be == 'foo.' }
|
250
|
-
example { get('/foo.bar') .body.should be == 'foo' }
|
251
|
-
example { get('/a%20b') .body.should be == 'a b' }
|
252
|
-
end
|
253
|
-
|
254
|
-
describe :shell do
|
255
|
-
before do
|
256
|
-
app.set(:pattern, type: :shell)
|
257
|
-
app.get('/{foo,bar}') { 'ok' }
|
258
|
-
end
|
259
|
-
|
260
|
-
example { get('/foo').should be_ok }
|
261
|
-
example { get('/bar').should be_ok }
|
262
|
-
end
|
263
|
-
|
264
|
-
describe :simple do
|
265
|
-
before do
|
266
|
-
app.set(:pattern, type: :simple)
|
267
|
-
app.get('/(a)') { 'ok' }
|
268
|
-
end
|
269
|
-
|
270
|
-
example { get('/(a)').should be_ok }
|
271
|
-
example { get('/a').should_not be_ok }
|
272
|
-
end
|
273
|
-
|
274
|
-
describe :simple do
|
275
|
-
before do
|
276
|
-
app.set(:pattern, type: :template)
|
277
|
-
app.get('/foo{/segments*}{.ext}') { "%p %p" % [params[:segments], params[:ext]] }
|
278
|
-
end
|
279
|
-
|
280
|
-
example { get('/foo/a.png').should be_ok }
|
281
|
-
example { get('/foo/a').should_not be_ok }
|
282
|
-
|
283
|
-
example { get('/foo/a.png').body.should be == '["a"] "png"' }
|
284
|
-
example { get('/foo/a/b.png').body.should be == '["a", "b"] "png"' }
|
285
|
-
end
|
286
|
-
end
|
287
|
-
|
288
|
-
context 'works with filters' do
|
289
|
-
before do
|
290
|
-
app.before('/auth/*', except: '/auth/login') { halt 'auth required' }
|
291
|
-
app.get('/auth/login') { 'please log in' }
|
292
|
-
end
|
293
|
-
|
294
|
-
example { get('/auth/dunno').body.should be == 'auth required' }
|
295
|
-
example { get('/auth/login').body.should be == 'please log in' }
|
296
|
-
end
|
297
|
-
end
|