mustermann19 0.4.0 → 0.4.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.
- checksums.yaml +4 -4
- data/README.md +11 -0
- data/lib/mustermann/grape.rb +34 -0
- data/lib/mustermann/version.rb +1 -1
- data/spec/grape_spec.rb +747 -0
- metadata +59 -55
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b657d781342db968ae5f3aa2870ae038b2dcbe6d
|
4
|
+
data.tar.gz: 7e3f3769de07852525cf560cc1b053f31ff90be9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82059db05fce899ea10ec6d729d4411a7d5073052c66dba13710df0f17a7472fc79d0345225f1b760bd9cf16c3d4e32d822502fe8271e2efd78bac449d7acbcc
|
7
|
+
data.tar.gz: ddab562925edbfe2f4fe85af92d7e86945077965b6407cce6960796945fad76234b1c158dca4dd06442fd3dc66f805fef532005f8007613d1251dc652832985e
|
data/README.md
CHANGED
@@ -1007,6 +1007,17 @@ This comes with a few trade-offs:
|
|
1007
1007
|
[`uri_decode`](#-available-options--uri_decode),
|
1008
1008
|
[`ignore_unknown_options`](#-available-options--ignore_unknown_options).
|
1009
1009
|
|
1010
|
+
<a name="-pattern-details-grape"></a>
|
1011
|
+
### `grape`
|
1012
|
+
|
1013
|
+
**Supported options:**
|
1014
|
+
[`capture`](#-available-options--capture),
|
1015
|
+
[`except`](#-available-options--except),
|
1016
|
+
[`greedy`](#-available-options--greedy),
|
1017
|
+
[`space_matches_plus`](#-available-options--space_matches_plus),
|
1018
|
+
[`uri_decode`](#-available-options--uri_decode),
|
1019
|
+
[`ignore_unknown_options`](#-available-options--ignore_unknown_options).
|
1020
|
+
|
1010
1021
|
<a name="-pattern-details-rails"></a>
|
1011
1022
|
### `rails`
|
1012
1023
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'mustermann/ast/pattern'
|
2
|
+
|
3
|
+
module Mustermann
|
4
|
+
# Grape style pattern implementation.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# Mustermann.new('/:foo', type: :grape) === '/bar' # => true
|
8
|
+
#
|
9
|
+
# @see Mustermann::Pattern
|
10
|
+
# @see file:README.md#grape Syntax description in the README
|
11
|
+
class Grape < AST::Pattern
|
12
|
+
register :grape
|
13
|
+
|
14
|
+
on(nil, ??, ?)) { |c| unexpected(c) }
|
15
|
+
|
16
|
+
on(?*) { |c| scan(/\w+/) ? node(:named_splat, buffer.matched) : node(:splat) }
|
17
|
+
on(?:) { |c| node(:capture) { scan(/\w+/) } }
|
18
|
+
on(?\\) { |c| node(:char, expect(/./)) }
|
19
|
+
on(?() { |c| node(:optional, node(:group) { read unless scan(?)) }) }
|
20
|
+
on(?|) { |c| node(:or) }
|
21
|
+
|
22
|
+
on ?{ do |char|
|
23
|
+
type = scan(?+) ? :named_splat : :capture
|
24
|
+
name = expect(/[\w\.]+/)
|
25
|
+
type = :splat if type == :named_splat and name == 'splat'
|
26
|
+
expect(?})
|
27
|
+
node(type, name)
|
28
|
+
end
|
29
|
+
|
30
|
+
suffix ?? do |char, element|
|
31
|
+
node(:optional, element)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/mustermann/version.rb
CHANGED
data/spec/grape_spec.rb
ADDED
@@ -0,0 +1,747 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'support'
|
3
|
+
require 'mustermann/grape'
|
4
|
+
|
5
|
+
describe Mustermann::Grape do
|
6
|
+
extend Support::Pattern
|
7
|
+
|
8
|
+
pattern '' do
|
9
|
+
it { should match('') }
|
10
|
+
it { should_not match('/') }
|
11
|
+
|
12
|
+
it { should generate_template('') }
|
13
|
+
|
14
|
+
it { should respond_to(:expand) }
|
15
|
+
it { should respond_to(:to_templates) }
|
16
|
+
end
|
17
|
+
|
18
|
+
pattern '/' do
|
19
|
+
it { should match('/') }
|
20
|
+
it { should_not match('/foo') }
|
21
|
+
end
|
22
|
+
|
23
|
+
pattern '/foo' do
|
24
|
+
it { should match('/foo') }
|
25
|
+
it { should_not match('/bar') }
|
26
|
+
it { should_not match('/foo.bar') }
|
27
|
+
end
|
28
|
+
|
29
|
+
pattern '/foo/bar' do
|
30
|
+
it { should match('/foo/bar') }
|
31
|
+
it { should_not match('/foo%2Fbar') }
|
32
|
+
it { should_not match('/foo%2fbar') }
|
33
|
+
end
|
34
|
+
|
35
|
+
pattern '/foo\/bar' do
|
36
|
+
it { should match('/foo/bar') }
|
37
|
+
it { should match('/foo%2Fbar') }
|
38
|
+
it { should match('/foo%2fbar') }
|
39
|
+
end
|
40
|
+
|
41
|
+
pattern '/:foo' do
|
42
|
+
it { should match('/foo') .capturing foo: 'foo' }
|
43
|
+
it { should match('/bar') .capturing foo: 'bar' }
|
44
|
+
it { should match('/foo.bar') .capturing foo: 'foo.bar' }
|
45
|
+
it { should match('/%0Afoo') .capturing foo: '%0Afoo' }
|
46
|
+
it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' }
|
47
|
+
|
48
|
+
it { should_not match('/foo?') }
|
49
|
+
it { should_not match('/foo/bar') }
|
50
|
+
it { should_not match('/') }
|
51
|
+
it { should_not match('/foo/') }
|
52
|
+
|
53
|
+
it { should generate_template('/{foo}') }
|
54
|
+
end
|
55
|
+
|
56
|
+
pattern '/föö' do
|
57
|
+
it { should match("/f%C3%B6%C3%B6") }
|
58
|
+
end
|
59
|
+
|
60
|
+
pattern "/:foo/:bar" do
|
61
|
+
it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
|
62
|
+
it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' }
|
63
|
+
it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' }
|
64
|
+
it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' }
|
65
|
+
it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' }
|
66
|
+
|
67
|
+
it { should_not match('/foo%2Fbar') }
|
68
|
+
it { should_not match('/foo%2fbar') }
|
69
|
+
|
70
|
+
example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} }
|
71
|
+
example { pattern.params('').should be_nil }
|
72
|
+
|
73
|
+
it { should generate_template('/{foo}/{bar}') }
|
74
|
+
end
|
75
|
+
|
76
|
+
pattern "/{foo}/{bar}" do
|
77
|
+
it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
|
78
|
+
it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' }
|
79
|
+
it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' }
|
80
|
+
it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' }
|
81
|
+
it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' }
|
82
|
+
|
83
|
+
it { should_not match('/foo%2Fbar') }
|
84
|
+
it { should_not match('/foo%2fbar') }
|
85
|
+
|
86
|
+
example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} }
|
87
|
+
example { pattern.params('').should be_nil }
|
88
|
+
|
89
|
+
it { should generate_template('/{foo}/{bar}') }
|
90
|
+
end
|
91
|
+
|
92
|
+
pattern '/hello/:person' do
|
93
|
+
it { should match('/hello/Frank').capturing person: 'Frank' }
|
94
|
+
it { should generate_template('/hello/{person}') }
|
95
|
+
end
|
96
|
+
|
97
|
+
pattern '/hello/{person}' do
|
98
|
+
it { should match('/hello/Frank').capturing person: 'Frank' }
|
99
|
+
it { should generate_template('/hello/{person}') }
|
100
|
+
end
|
101
|
+
|
102
|
+
pattern '/?:foo?/?:bar?' do
|
103
|
+
it { should match('/hello/world') .capturing foo: 'hello', bar: 'world' }
|
104
|
+
it { should match('/hello') .capturing foo: 'hello', bar: nil }
|
105
|
+
it { should match('/') .capturing foo: nil, bar: nil }
|
106
|
+
it { should match('') .capturing foo: nil, bar: nil }
|
107
|
+
|
108
|
+
it { should expand(foo: 'hello') .to('/hello/') }
|
109
|
+
it { should expand(foo: 'hello', bar: 'world') .to('/hello/world') }
|
110
|
+
it { should expand(bar: 'world') .to('//world') }
|
111
|
+
it { should expand .to('//') }
|
112
|
+
it { should_not expand(baz: '') }
|
113
|
+
|
114
|
+
it { should_not match('/hello/world/') }
|
115
|
+
it { should generate_templates("", "/", "//", "//{bar}", "/{bar}", "/{foo}", "/{foo}/", "/{foo}/{bar}", "/{foo}{bar}", "{bar}", "{foo}", "{foo}/", "{foo}/{bar}", "{foo}{bar}") }
|
116
|
+
end
|
117
|
+
|
118
|
+
pattern '/:foo_bar' do
|
119
|
+
it { should match('/hello').capturing foo_bar: 'hello' }
|
120
|
+
it { should generate_template('/{foo_bar}') }
|
121
|
+
end
|
122
|
+
|
123
|
+
pattern '/{foo.bar}' do
|
124
|
+
it { should match('/hello').capturing :"foo.bar" => 'hello' }
|
125
|
+
it { should generate_template('/{foo.bar}') }
|
126
|
+
end
|
127
|
+
|
128
|
+
pattern '/*' do
|
129
|
+
it { should match('/') .capturing splat: '' }
|
130
|
+
it { should match('/foo') .capturing splat: 'foo' }
|
131
|
+
it { should match('/foo/bar') .capturing splat: 'foo/bar' }
|
132
|
+
it { should generate_template('/{+splat}') }
|
133
|
+
|
134
|
+
example { pattern.params('/foo').should be == {"splat" => ["foo"]} }
|
135
|
+
end
|
136
|
+
|
137
|
+
pattern '/{+splat}' do
|
138
|
+
it { should match('/') .capturing splat: '' }
|
139
|
+
it { should match('/foo') .capturing splat: 'foo' }
|
140
|
+
it { should match('/foo/bar') .capturing splat: 'foo/bar' }
|
141
|
+
it { should generate_template('/{+splat}') }
|
142
|
+
|
143
|
+
example { pattern.params('/foo').should be == {"splat" => ["foo"]} }
|
144
|
+
end
|
145
|
+
|
146
|
+
pattern '/*foo' do
|
147
|
+
it { should match('/') .capturing foo: '' }
|
148
|
+
it { should match('/foo') .capturing foo: 'foo' }
|
149
|
+
it { should match('/foo/bar') .capturing foo: 'foo/bar' }
|
150
|
+
it { should generate_template('/{+foo}') }
|
151
|
+
|
152
|
+
example { pattern.params('/foo') .should be == {"foo" => "foo" } }
|
153
|
+
example { pattern.params('/foo/bar') .should be == {"foo" => "foo/bar" } }
|
154
|
+
end
|
155
|
+
|
156
|
+
pattern '/{+foo}' do
|
157
|
+
it { should match('/') .capturing foo: '' }
|
158
|
+
it { should match('/foo') .capturing foo: 'foo' }
|
159
|
+
it { should match('/foo/bar') .capturing foo: 'foo/bar' }
|
160
|
+
it { should generate_template('/{+foo}') }
|
161
|
+
|
162
|
+
example { pattern.params('/foo') .should be == {"foo" => "foo" } }
|
163
|
+
example { pattern.params('/foo/bar') .should be == {"foo" => "foo/bar" } }
|
164
|
+
end
|
165
|
+
|
166
|
+
pattern '/*foo/*bar' do
|
167
|
+
it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
|
168
|
+
it { should generate_template('/{+foo}/{+bar}') }
|
169
|
+
end
|
170
|
+
|
171
|
+
pattern '/{+foo}/{+bar}' do
|
172
|
+
it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' }
|
173
|
+
it { should generate_template('/{+foo}/{+bar}') }
|
174
|
+
end
|
175
|
+
|
176
|
+
pattern '/:foo/*' do
|
177
|
+
it { should match("/foo/bar/baz") .capturing foo: 'foo', splat: 'bar/baz' }
|
178
|
+
it { should match("/foo/") .capturing foo: 'foo', splat: '' }
|
179
|
+
it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' }
|
180
|
+
it { should_not match('/foo') }
|
181
|
+
it { should generate_template('/{foo}/{+splat}') }
|
182
|
+
|
183
|
+
example { pattern.params('/bar/foo').should be == {"splat" => ["foo"], "foo" => "bar"} }
|
184
|
+
example { pattern.params('/bar/foo/f%20o').should be == {"splat" => ["foo/f o"], "foo" => "bar"} }
|
185
|
+
end
|
186
|
+
|
187
|
+
pattern '/{foo}/*' do
|
188
|
+
it { should match("/foo/bar/baz") .capturing foo: 'foo', splat: 'bar/baz' }
|
189
|
+
it { should match("/foo/") .capturing foo: 'foo', splat: '' }
|
190
|
+
it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' }
|
191
|
+
it { should_not match('/foo') }
|
192
|
+
it { should generate_template('/{foo}/{+splat}') }
|
193
|
+
|
194
|
+
example { pattern.params('/bar/foo').should be == {"splat" => ["foo"], "foo" => "bar"} }
|
195
|
+
example { pattern.params('/bar/foo/f%20o').should be == {"splat" => ["foo/f o"], "foo" => "bar"} }
|
196
|
+
end
|
197
|
+
|
198
|
+
pattern '/test$/' do
|
199
|
+
it { should match('/test$/') }
|
200
|
+
end
|
201
|
+
|
202
|
+
pattern '/te+st/' do
|
203
|
+
it { should match('/te+st/') }
|
204
|
+
it { should_not match('/test/') }
|
205
|
+
it { should_not match('/teest/') }
|
206
|
+
end
|
207
|
+
|
208
|
+
pattern "/path with spaces" do
|
209
|
+
it { should match('/path%20with%20spaces') }
|
210
|
+
it { should match('/path%2Bwith%2Bspaces') }
|
211
|
+
it { should match('/path+with+spaces') }
|
212
|
+
|
213
|
+
it { should generate_template('/path%20with%20spaces') }
|
214
|
+
end
|
215
|
+
|
216
|
+
pattern '/foo&bar' do
|
217
|
+
it { should match('/foo&bar') }
|
218
|
+
end
|
219
|
+
|
220
|
+
pattern '/foo\{bar' do
|
221
|
+
it { should match('/foo%7Bbar') }
|
222
|
+
end
|
223
|
+
|
224
|
+
pattern '/*/:foo/*/*' do
|
225
|
+
it { should match('/bar/foo/bling/baz/boom') }
|
226
|
+
|
227
|
+
it "should capture all splat parts" do
|
228
|
+
match = pattern.match('/bar/foo/bling/baz/boom')
|
229
|
+
match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom']
|
230
|
+
match.names.should be == ['splat', 'foo']
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'should map to proper params' do
|
234
|
+
pattern.params('/bar/foo/bling/baz/boom').should be == {
|
235
|
+
"foo" => "foo", "splat" => ['bar', 'bling', 'baz/boom']
|
236
|
+
}
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
pattern '/{+splat}/{foo}/{+splat}/{+splat}' do
|
241
|
+
it { should match('/bar/foo/bling/baz/boom') }
|
242
|
+
|
243
|
+
it "should capture all splat parts" do
|
244
|
+
match = pattern.match('/bar/foo/bling/baz/boom')
|
245
|
+
match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom']
|
246
|
+
match.names.should be == ['splat', 'foo']
|
247
|
+
end
|
248
|
+
|
249
|
+
it 'should map to proper params' do
|
250
|
+
pattern.params('/bar/foo/bling/baz/boom').should be == {
|
251
|
+
"foo" => "foo", "splat" => ['bar', 'bling', 'baz/boom']
|
252
|
+
}
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
pattern '/test.bar' do
|
257
|
+
it { should match('/test.bar') }
|
258
|
+
it { should_not match('/test0bar') }
|
259
|
+
end
|
260
|
+
|
261
|
+
pattern '/:file.:ext' do
|
262
|
+
it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
|
263
|
+
it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
|
264
|
+
it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
|
265
|
+
|
266
|
+
it { should match('/pony%E6%AD%A3%2Ejpg') .capturing file: 'pony%E6%AD%A3', ext: 'jpg' }
|
267
|
+
it { should match('/pony%e6%ad%a3%2ejpg') .capturing file: 'pony%e6%ad%a3', ext: 'jpg' }
|
268
|
+
it { should match('/pony正%2Ejpg') .capturing file: 'pony正', ext: 'jpg' }
|
269
|
+
it { should match('/pony正%2ejpg') .capturing file: 'pony正', ext: 'jpg' }
|
270
|
+
it { should match('/pony正..jpg') .capturing file: 'pony正.', ext: 'jpg' }
|
271
|
+
|
272
|
+
it { should_not match('/.jpg') }
|
273
|
+
end
|
274
|
+
|
275
|
+
pattern '/(:a)x?' do
|
276
|
+
it { should match('/a') .capturing a: 'a' }
|
277
|
+
it { should match('/xa') .capturing a: 'xa' }
|
278
|
+
it { should match('/axa') .capturing a: 'axa' }
|
279
|
+
|
280
|
+
it { should generate_template('/{a}x') }
|
281
|
+
it { should generate_template('/{a}') }
|
282
|
+
end
|
283
|
+
|
284
|
+
pattern '/:user(@:host)?' do
|
285
|
+
it { should match('/foo@bar') .capturing user: 'foo', host: 'bar' }
|
286
|
+
it { should match('/foo.foo@bar') .capturing user: 'foo.foo', host: 'bar' }
|
287
|
+
it { should match('/foo@bar.bar') .capturing user: 'foo', host: 'bar.bar' }
|
288
|
+
|
289
|
+
it { should generate_template('/{user}') }
|
290
|
+
it { should generate_template('/{user}@{host}') }
|
291
|
+
end
|
292
|
+
|
293
|
+
pattern '/:file(.:ext)?' do
|
294
|
+
it { should match('/pony') .capturing file: 'pony', ext: nil }
|
295
|
+
it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
|
296
|
+
it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
|
297
|
+
it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
|
298
|
+
it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' }
|
299
|
+
it { should match('/pony.') .capturing file: 'pony.' }
|
300
|
+
it { should_not match('/.jpg') }
|
301
|
+
|
302
|
+
it { should generate_template('/{file}') }
|
303
|
+
it { should generate_template('/{file}.{ext}') }
|
304
|
+
it { should_not generate_template('/{file}.') }
|
305
|
+
end
|
306
|
+
|
307
|
+
pattern '/:id/test.bar' do
|
308
|
+
it { should match('/3/test.bar') .capturing id: '3' }
|
309
|
+
it { should match('/2/test.bar') .capturing id: '2' }
|
310
|
+
it { should match('/2E/test.bar') .capturing id: '2E' }
|
311
|
+
it { should match('/2e/test.bar') .capturing id: '2e' }
|
312
|
+
it { should match('/%2E/test.bar') .capturing id: '%2E' }
|
313
|
+
end
|
314
|
+
|
315
|
+
pattern '/10/:id' do
|
316
|
+
it { should match('/10/test') .capturing id: 'test' }
|
317
|
+
it { should match('/10/te.st') .capturing id: 'te.st' }
|
318
|
+
end
|
319
|
+
|
320
|
+
pattern '/10.1/:id' do
|
321
|
+
it { should match('/10.1/test') .capturing id: 'test' }
|
322
|
+
it { should match('/10.1/te.st') .capturing id: 'te.st' }
|
323
|
+
end
|
324
|
+
|
325
|
+
pattern '/:foo.:bar/:id' do
|
326
|
+
it { should match('/10.1/te.st') .capturing foo: "10", bar: "1", id: "te.st" }
|
327
|
+
it { should match('/10.1.2/te.st') .capturing foo: "10.1", bar: "2", id: "te.st" }
|
328
|
+
end
|
329
|
+
|
330
|
+
pattern '/:a/:b.?:c?' do
|
331
|
+
it { should match('/a/b') .capturing a: 'a', b: 'b', c: nil }
|
332
|
+
it { should match('/a/b.c') .capturing a: 'a', b: 'b', c: 'c' }
|
333
|
+
it { should match('/a.b/c') .capturing a: 'a.b', b: 'c', c: nil }
|
334
|
+
it { should match('/a.b/c.d') .capturing a: 'a.b', b: 'c', c: 'd' }
|
335
|
+
it { should_not match('/a.b/c.d/e') }
|
336
|
+
end
|
337
|
+
|
338
|
+
pattern '/:a(foo:b)?' do
|
339
|
+
it { should match('/barfoobar') .capturing a: 'bar', b: 'bar' }
|
340
|
+
it { should match('/barfoobarfoobar') .capturing a: 'barfoobar', b: 'bar' }
|
341
|
+
it { should match('/bar') .capturing a: 'bar', b: nil }
|
342
|
+
it { should_not match('/') }
|
343
|
+
end
|
344
|
+
|
345
|
+
pattern '/foo?' do
|
346
|
+
it { should match('/fo') }
|
347
|
+
it { should match('/foo') }
|
348
|
+
it { should_not match('') }
|
349
|
+
it { should_not match('/') }
|
350
|
+
it { should_not match('/f') }
|
351
|
+
it { should_not match('/fooo') }
|
352
|
+
end
|
353
|
+
|
354
|
+
pattern '/foo\?' do
|
355
|
+
it { should match('/foo?') }
|
356
|
+
it { should_not match('/foo\?') }
|
357
|
+
it { should_not match('/fo') }
|
358
|
+
it { should_not match('/foo') }
|
359
|
+
it { should_not match('') }
|
360
|
+
it { should_not match('/') }
|
361
|
+
it { should_not match('/f') }
|
362
|
+
it { should_not match('/fooo') }
|
363
|
+
end
|
364
|
+
|
365
|
+
pattern '/foo\\\?' do
|
366
|
+
it { should match('/foo%5c') }
|
367
|
+
it { should match('/foo') }
|
368
|
+
it { should_not match('/foo\?') }
|
369
|
+
it { should_not match('/fo') }
|
370
|
+
it { should_not match('') }
|
371
|
+
it { should_not match('/') }
|
372
|
+
it { should_not match('/f') }
|
373
|
+
it { should_not match('/fooo') }
|
374
|
+
end
|
375
|
+
|
376
|
+
pattern '/\(' do
|
377
|
+
it { should match('/(') }
|
378
|
+
end
|
379
|
+
|
380
|
+
pattern '/\(?' do
|
381
|
+
it { should match('/(') }
|
382
|
+
it { should match('/') }
|
383
|
+
end
|
384
|
+
|
385
|
+
pattern '/(\()?' do
|
386
|
+
it { should match('/(') }
|
387
|
+
it { should match('/') }
|
388
|
+
end
|
389
|
+
|
390
|
+
pattern '/(\(\))?' do
|
391
|
+
it { should match('/') }
|
392
|
+
it { should match('/()') }
|
393
|
+
it { should_not match('/(') }
|
394
|
+
end
|
395
|
+
|
396
|
+
pattern '/\(\)?' do
|
397
|
+
it { should match('/(') }
|
398
|
+
it { should match('/()') }
|
399
|
+
it { should_not match('/') }
|
400
|
+
end
|
401
|
+
|
402
|
+
pattern '/\*' do
|
403
|
+
it { should match('/*') }
|
404
|
+
it { should_not match('/a') }
|
405
|
+
end
|
406
|
+
|
407
|
+
pattern '/\*/*' do
|
408
|
+
it { should match('/*/b/c') }
|
409
|
+
it { should_not match('/a/b/c') }
|
410
|
+
end
|
411
|
+
|
412
|
+
pattern '/\:foo' do
|
413
|
+
it { should match('/:foo') }
|
414
|
+
it { should_not match('/foo') }
|
415
|
+
end
|
416
|
+
|
417
|
+
pattern '/:fOO' do
|
418
|
+
it { should match('/a').capturing fOO: 'a' }
|
419
|
+
end
|
420
|
+
|
421
|
+
pattern '/:_X' do
|
422
|
+
it { should match('/a').capturing _X: 'a' }
|
423
|
+
end
|
424
|
+
|
425
|
+
pattern '/:f00' do
|
426
|
+
it { should match('/a').capturing f00: 'a' }
|
427
|
+
end
|
428
|
+
|
429
|
+
pattern '/:foo(/:bar)?/:baz?' do
|
430
|
+
it { should match('/foo/bar/baz').capturing foo: 'foo', bar: 'bar', baz: 'baz' }
|
431
|
+
end
|
432
|
+
|
433
|
+
pattern "/(foo|bar)" do
|
434
|
+
it { should match("/foo") }
|
435
|
+
it { should match("/bar") }
|
436
|
+
end
|
437
|
+
|
438
|
+
pattern "/(foo\\|bar)" do
|
439
|
+
it { should match "/foo%7Cbar" }
|
440
|
+
it { should generate_template "/foo%7Cbar" }
|
441
|
+
|
442
|
+
it { should_not match("/foo") }
|
443
|
+
it { should_not match("/bar") }
|
444
|
+
|
445
|
+
it { should_not generate_template('/foo') }
|
446
|
+
it { should_not generate_template('/bar') }
|
447
|
+
end
|
448
|
+
|
449
|
+
pattern "/(:a/:b|:c)" do
|
450
|
+
it { should match("/foo") .capturing c: 'foo' }
|
451
|
+
it { should match("/foo/bar") .capturing a: 'foo', b: 'bar' }
|
452
|
+
|
453
|
+
it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') }
|
454
|
+
it { should expand(c: 'foo') .to('/foo') }
|
455
|
+
it { should_not expand(a: 'foo', b: 'bar', c: 'baz') }
|
456
|
+
end
|
457
|
+
|
458
|
+
pattern "/:a/:b|:c" do
|
459
|
+
it { should match("foo") .capturing c: 'foo' }
|
460
|
+
it { should match("/foo/bar") .capturing a: 'foo', b: 'bar' }
|
461
|
+
|
462
|
+
it { should generate_template('/{a}/{b}') }
|
463
|
+
it { should generate_template('{c}') }
|
464
|
+
|
465
|
+
it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') }
|
466
|
+
it { should expand(c: 'foo') .to('foo') }
|
467
|
+
it { should_not expand(a: 'foo', b: 'bar', c: 'baz') }
|
468
|
+
end
|
469
|
+
|
470
|
+
pattern '/:foo', capture: /\d+/ do
|
471
|
+
it { should match('/1') .capturing foo: '1' }
|
472
|
+
it { should match('/123') .capturing foo: '123' }
|
473
|
+
|
474
|
+
it { should_not match('/') }
|
475
|
+
it { should_not match('/foo') }
|
476
|
+
end
|
477
|
+
|
478
|
+
pattern '/:foo', capture: /\d+/ do
|
479
|
+
it { should match('/1') .capturing foo: '1' }
|
480
|
+
it { should match('/123') .capturing foo: '123' }
|
481
|
+
|
482
|
+
it { should_not match('/') }
|
483
|
+
it { should_not match('/foo') }
|
484
|
+
end
|
485
|
+
|
486
|
+
pattern '/:foo', capture: '1' do
|
487
|
+
it { should match('/1').capturing foo: '1' }
|
488
|
+
|
489
|
+
it { should_not match('/') }
|
490
|
+
it { should_not match('/foo') }
|
491
|
+
it { should_not match('/123') }
|
492
|
+
end
|
493
|
+
|
494
|
+
pattern '/:foo', capture: 'a.b' do
|
495
|
+
it { should match('/a.b') .capturing foo: 'a.b' }
|
496
|
+
it { should match('/a%2Eb') .capturing foo: 'a%2Eb' }
|
497
|
+
it { should match('/a%2eb') .capturing foo: 'a%2eb' }
|
498
|
+
|
499
|
+
it { should_not match('/ab') }
|
500
|
+
it { should_not match('/afb') }
|
501
|
+
it { should_not match('/a1b') }
|
502
|
+
it { should_not match('/a.bc') }
|
503
|
+
end
|
504
|
+
|
505
|
+
pattern '/:foo(/:bar)?', capture: :alpha do
|
506
|
+
it { should match('/abc') .capturing foo: 'abc', bar: nil }
|
507
|
+
it { should match('/a/b') .capturing foo: 'a', bar: 'b' }
|
508
|
+
it { should match('/a') .capturing foo: 'a', bar: nil }
|
509
|
+
|
510
|
+
it { should_not match('/1/2') }
|
511
|
+
it { should_not match('/a/2') }
|
512
|
+
it { should_not match('/1/b') }
|
513
|
+
it { should_not match('/1') }
|
514
|
+
it { should_not match('/1/') }
|
515
|
+
it { should_not match('/a/') }
|
516
|
+
it { should_not match('//a') }
|
517
|
+
end
|
518
|
+
|
519
|
+
pattern '/:foo', capture: ['foo', 'bar', /\d+/] do
|
520
|
+
it { should match('/1') .capturing foo: '1' }
|
521
|
+
it { should match('/123') .capturing foo: '123' }
|
522
|
+
it { should match('/foo') .capturing foo: 'foo' }
|
523
|
+
it { should match('/bar') .capturing foo: 'bar' }
|
524
|
+
|
525
|
+
it { should_not match('/') }
|
526
|
+
it { should_not match('/baz') }
|
527
|
+
it { should_not match('/foo1') }
|
528
|
+
end
|
529
|
+
|
530
|
+
pattern '/:foo:bar:baz', capture: { foo: :alpha, bar: /\d+/ } do
|
531
|
+
it { should match('/ab123xy-1') .capturing foo: 'ab', bar: '123', baz: 'xy-1' }
|
532
|
+
it { should match('/ab123') .capturing foo: 'ab', bar: '12', baz: '3' }
|
533
|
+
it { should_not match('/123abcxy-1') }
|
534
|
+
it { should_not match('/abcxy-1') }
|
535
|
+
it { should_not match('/abc1') }
|
536
|
+
end
|
537
|
+
|
538
|
+
pattern '/:foo', capture: { foo: ['foo', 'bar', /\d+/] } do
|
539
|
+
it { should match('/1') .capturing foo: '1' }
|
540
|
+
it { should match('/123') .capturing foo: '123' }
|
541
|
+
it { should match('/foo') .capturing foo: 'foo' }
|
542
|
+
it { should match('/bar') .capturing foo: 'bar' }
|
543
|
+
|
544
|
+
it { should_not match('/') }
|
545
|
+
it { should_not match('/baz') }
|
546
|
+
it { should_not match('/foo1') }
|
547
|
+
end
|
548
|
+
|
549
|
+
pattern '/:file(.:ext)?', capture: { ext: ['jpg', 'png'] } do
|
550
|
+
it { should match('/pony') .capturing file: 'pony', ext: nil }
|
551
|
+
it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
|
552
|
+
it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' }
|
553
|
+
it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' }
|
554
|
+
it { should match('/pony.png') .capturing file: 'pony', ext: 'png' }
|
555
|
+
it { should match('/pony%2Epng') .capturing file: 'pony', ext: 'png' }
|
556
|
+
it { should match('/pony%2epng') .capturing file: 'pony', ext: 'png' }
|
557
|
+
it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' }
|
558
|
+
it { should match('/pony.jpg.png') .capturing file: 'pony.jpg', ext: 'png' }
|
559
|
+
it { should match('/pony.gif') .capturing file: 'pony.gif', ext: nil }
|
560
|
+
it { should match('/pony.') .capturing file: 'pony.', ext: nil }
|
561
|
+
it { should_not match('.jpg') }
|
562
|
+
end
|
563
|
+
|
564
|
+
pattern '/:file:ext?', capture: { ext: ['.jpg', '.png', '.tar.gz'] } do
|
565
|
+
it { should match('/pony') .capturing file: 'pony', ext: nil }
|
566
|
+
it { should match('/pony.jpg') .capturing file: 'pony', ext: '.jpg' }
|
567
|
+
it { should match('/pony.png') .capturing file: 'pony', ext: '.png' }
|
568
|
+
it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: '.jpg' }
|
569
|
+
it { should match('/pony.jpg.png') .capturing file: 'pony.jpg', ext: '.png' }
|
570
|
+
it { should match('/pony.tar.gz') .capturing file: 'pony', ext: '.tar.gz' }
|
571
|
+
it { should match('/pony.gif') .capturing file: 'pony.gif', ext: nil }
|
572
|
+
it { should match('/pony.') .capturing file: 'pony.', ext: nil }
|
573
|
+
it { should_not match('/.jpg') }
|
574
|
+
end
|
575
|
+
|
576
|
+
pattern '/:a(@:b)?', capture: { b: /\d+/ } do
|
577
|
+
it { should match('/a') .capturing a: 'a', b: nil }
|
578
|
+
it { should match('/a@1') .capturing a: 'a', b: '1' }
|
579
|
+
it { should match('/a@b') .capturing a: 'a@b', b: nil }
|
580
|
+
it { should match('/a@1@2') .capturing a: 'a@1', b: '2' }
|
581
|
+
end
|
582
|
+
|
583
|
+
pattern '/(:a)b?', greedy: false do
|
584
|
+
it { should match('/ab').capturing a: 'a' }
|
585
|
+
end
|
586
|
+
|
587
|
+
pattern '/:file(.:ext)?', greedy: false do
|
588
|
+
it { should match('/pony') .capturing file: 'pony', ext: nil }
|
589
|
+
it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' }
|
590
|
+
it { should match('/pony.png.jpg') .capturing file: 'pony', ext: 'png.jpg' }
|
591
|
+
end
|
592
|
+
|
593
|
+
pattern '/auth/*', except: '/auth/login' do
|
594
|
+
it { should match('/auth/admin') }
|
595
|
+
it { should match('/auth/foobar') }
|
596
|
+
it { should_not match('/auth/login') }
|
597
|
+
end
|
598
|
+
|
599
|
+
pattern '/:foo/:bar', except: '/:bar/20' do
|
600
|
+
it { should match('/foo/bar').capturing foo: 'foo', bar: 'bar' }
|
601
|
+
it { should_not match('/20/20') }
|
602
|
+
end
|
603
|
+
|
604
|
+
pattern '/foo?', uri_decode: false do
|
605
|
+
it { should match('/foo') }
|
606
|
+
it { should match('/fo') }
|
607
|
+
it { should_not match('/foo?') }
|
608
|
+
end
|
609
|
+
|
610
|
+
pattern '/foo/bar', uri_decode: false do
|
611
|
+
it { should match('/foo/bar') }
|
612
|
+
it { should_not match('/foo%2Fbar') }
|
613
|
+
it { should_not match('/foo%2fbar') }
|
614
|
+
end
|
615
|
+
|
616
|
+
pattern "/path with spaces", uri_decode: false do
|
617
|
+
it { should match('/path with spaces') }
|
618
|
+
it { should_not match('/path%20with%20spaces') }
|
619
|
+
it { should_not match('/path%2Bwith%2Bspaces') }
|
620
|
+
it { should_not match('/path+with+spaces') }
|
621
|
+
end
|
622
|
+
|
623
|
+
pattern "/path with spaces", space_matches_plus: false do
|
624
|
+
it { should match('/path%20with%20spaces') }
|
625
|
+
it { should_not match('/path%2Bwith%2Bspaces') }
|
626
|
+
it { should_not match('/path+with+spaces') }
|
627
|
+
end
|
628
|
+
|
629
|
+
context 'invalid syntax' do
|
630
|
+
example 'unexpected closing parenthesis' do
|
631
|
+
expect { Mustermann::Grape.new('foo)bar') }.
|
632
|
+
to raise_error(Mustermann::ParseError, 'unexpected ) while parsing "foo)bar"')
|
633
|
+
end
|
634
|
+
|
635
|
+
example 'missing closing parenthesis' do
|
636
|
+
expect { Mustermann::Grape.new('foo(bar') }.
|
637
|
+
to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar"')
|
638
|
+
end
|
639
|
+
|
640
|
+
example 'missing unescaped closing parenthesis' do
|
641
|
+
expect { Mustermann::Grape.new('foo(bar\)') }.
|
642
|
+
to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar\\\\)"')
|
643
|
+
end
|
644
|
+
|
645
|
+
example '? at beginning of route' do
|
646
|
+
expect { Mustermann::Grape.new('?foobar') }.
|
647
|
+
to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "?foobar"')
|
648
|
+
end
|
649
|
+
|
650
|
+
example 'double ?' do
|
651
|
+
expect { Mustermann::Grape.new('foo??bar') }.
|
652
|
+
to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "foo??bar"')
|
653
|
+
end
|
654
|
+
|
655
|
+
example 'dangling escape' do
|
656
|
+
expect { Mustermann::Grape.new('foo\\') }.
|
657
|
+
to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo\\\\"')
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
context 'invalid capture names' do
|
662
|
+
example 'empty name' do
|
663
|
+
expect { Mustermann::Grape.new('/:/') }.
|
664
|
+
to raise_error(Mustermann::CompileError, "capture name can't be empty: \"/:/\"")
|
665
|
+
end
|
666
|
+
|
667
|
+
example 'named splat' do
|
668
|
+
expect { Mustermann::Grape.new('/:splat/') }.
|
669
|
+
to raise_error(Mustermann::CompileError, "capture name can't be splat: \"/:splat/\"")
|
670
|
+
end
|
671
|
+
|
672
|
+
example 'named captures' do
|
673
|
+
expect { Mustermann::Grape.new('/:captures/') }.
|
674
|
+
to raise_error(Mustermann::CompileError, "capture name can't be captures: \"/:captures/\"")
|
675
|
+
end
|
676
|
+
|
677
|
+
example 'with capital letter' do
|
678
|
+
expect { Mustermann::Grape.new('/:Foo/') }.
|
679
|
+
to raise_error(Mustermann::CompileError, "capture name must start with underscore or lower case letter: \"/:Foo/\"")
|
680
|
+
end
|
681
|
+
|
682
|
+
example 'with integer' do
|
683
|
+
expect { Mustermann::Grape.new('/:1a/') }.
|
684
|
+
to raise_error(Mustermann::CompileError, "capture name must start with underscore or lower case letter: \"/:1a/\"")
|
685
|
+
end
|
686
|
+
|
687
|
+
example 'same name twice' do
|
688
|
+
expect { Mustermann::Grape.new('/:foo(/:bar)?/:bar?') }.
|
689
|
+
to raise_error(Mustermann::CompileError, "can't use the same capture name twice: \"/:foo(/:bar)?/:bar?\"")
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
context 'Regexp compatibility' do
|
694
|
+
describe :=== do
|
695
|
+
example('non-matching') { Mustermann::Grape.new("/") .should_not be === '/foo' }
|
696
|
+
example('matching') { Mustermann::Grape.new("/:foo") .should be === '/foo' }
|
697
|
+
end
|
698
|
+
|
699
|
+
describe :=~ do
|
700
|
+
example('non-matching') { Mustermann::Grape.new("/") .should_not be =~ '/foo' }
|
701
|
+
example('matching') { Mustermann::Grape.new("/:foo") .should be =~ '/foo' }
|
702
|
+
|
703
|
+
context 'String#=~' do
|
704
|
+
example('non-matching') { "/foo".should_not be =~ Mustermann::Grape.new("/") }
|
705
|
+
example('matching') { "/foo".should be =~ Mustermann::Grape.new("/:foo") }
|
706
|
+
end
|
707
|
+
end
|
708
|
+
|
709
|
+
describe :to_regexp do
|
710
|
+
example('empty pattern') { Mustermann::Grape.new('').to_regexp.should be == /\A(?-mix:)\Z/ }
|
711
|
+
|
712
|
+
context 'Regexp.try_convert' do
|
713
|
+
example('empty pattern') { Regexp.try_convert(Mustermann::Grape.new('')).should be == /\A(?-mix:)\Z/ }
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|
717
|
+
|
718
|
+
context 'Proc compatibility' do
|
719
|
+
describe :to_proc do
|
720
|
+
example { Mustermann::Grape.new("/").to_proc.should be_a(Proc) }
|
721
|
+
example('non-matching') { Mustermann::Grape.new("/") .to_proc.call('/foo').should be == false }
|
722
|
+
example('matching') { Mustermann::Grape.new("/:foo") .to_proc.call('/foo').should be == true }
|
723
|
+
end
|
724
|
+
end
|
725
|
+
|
726
|
+
context "peeking" do
|
727
|
+
subject(:pattern) { Mustermann::Grape.new(":name") }
|
728
|
+
|
729
|
+
describe :peek_size do
|
730
|
+
example { pattern.peek_size("foo bar/blah") .should be == "foo bar".size }
|
731
|
+
example { pattern.peek_size("foo%20bar/blah") .should be == "foo%20bar".size }
|
732
|
+
example { pattern.peek_size("/foo bar") .should be_nil }
|
733
|
+
end
|
734
|
+
|
735
|
+
describe :peek_match do
|
736
|
+
example { pattern.peek_match("foo bar/blah") .to_s .should be == "foo bar" }
|
737
|
+
example { pattern.peek_match("foo%20bar/blah") .to_s .should be == "foo%20bar" }
|
738
|
+
example { pattern.peek_match("/foo bar") .should be_nil }
|
739
|
+
end
|
740
|
+
|
741
|
+
describe :peek_params do
|
742
|
+
example { pattern.peek_params("foo bar/blah") .should be == [{"name" => "foo bar"}, "foo bar".size] }
|
743
|
+
example { pattern.peek_params("foo%20bar/blah") .should be == [{"name" => "foo bar"}, "foo%20bar".size] }
|
744
|
+
example { pattern.peek_params("/foo bar") .should be_nil }
|
745
|
+
end
|
746
|
+
end
|
747
|
+
end
|
metadata
CHANGED
@@ -1,167 +1,168 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mustermann19
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Haase
|
8
8
|
- namusyaka
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-02-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
+
name: enumerable-lazy
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- -
|
18
|
+
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
20
|
version: '0'
|
20
|
-
name: enumerable-lazy
|
21
|
-
prerelease: false
|
22
21
|
type: :runtime
|
22
|
+
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
+
name: rspec
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- -
|
32
|
+
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '0'
|
34
|
-
name: rspec
|
35
|
-
prerelease: false
|
36
35
|
type: :development
|
36
|
+
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec-its
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
|
-
- -
|
46
|
+
- - ">="
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '0'
|
48
|
-
name: rspec-its
|
49
|
-
prerelease: false
|
50
49
|
type: :development
|
50
|
+
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
|
-
- -
|
53
|
+
- - ">="
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '0'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
|
+
name: addressable
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
58
59
|
requirements:
|
59
|
-
- -
|
60
|
+
- - ">="
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '0'
|
62
|
-
name: addressable
|
63
|
-
prerelease: false
|
64
63
|
type: :development
|
64
|
+
prerelease: false
|
65
65
|
version_requirements: !ruby/object:Gem::Requirement
|
66
66
|
requirements:
|
67
|
-
- -
|
67
|
+
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '0'
|
70
70
|
- !ruby/object:Gem::Dependency
|
71
|
+
name: sinatra
|
71
72
|
requirement: !ruby/object:Gem::Requirement
|
72
73
|
requirements:
|
73
|
-
- - ~>
|
74
|
+
- - "~>"
|
74
75
|
- !ruby/object:Gem::Version
|
75
76
|
version: '1.4'
|
76
|
-
name: sinatra
|
77
|
-
prerelease: false
|
78
77
|
type: :development
|
78
|
+
prerelease: false
|
79
79
|
version_requirements: !ruby/object:Gem::Requirement
|
80
80
|
requirements:
|
81
|
-
- - ~>
|
81
|
+
- - "~>"
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '1.4'
|
84
84
|
- !ruby/object:Gem::Dependency
|
85
|
+
name: rack-test
|
85
86
|
requirement: !ruby/object:Gem::Requirement
|
86
87
|
requirements:
|
87
|
-
- -
|
88
|
+
- - ">="
|
88
89
|
- !ruby/object:Gem::Version
|
89
90
|
version: '0'
|
90
|
-
name: rack-test
|
91
|
-
prerelease: false
|
92
91
|
type: :development
|
92
|
+
prerelease: false
|
93
93
|
version_requirements: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
|
-
- -
|
95
|
+
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
- !ruby/object:Gem::Dependency
|
99
|
+
name: rake
|
99
100
|
requirement: !ruby/object:Gem::Requirement
|
100
101
|
requirements:
|
101
|
-
- -
|
102
|
+
- - ">="
|
102
103
|
- !ruby/object:Gem::Version
|
103
104
|
version: '0'
|
104
|
-
name: rake
|
105
|
-
prerelease: false
|
106
105
|
type: :development
|
106
|
+
prerelease: false
|
107
107
|
version_requirements: !ruby/object:Gem::Requirement
|
108
108
|
requirements:
|
109
|
-
- -
|
109
|
+
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
111
|
version: '0'
|
112
112
|
- !ruby/object:Gem::Dependency
|
113
|
+
name: yard
|
113
114
|
requirement: !ruby/object:Gem::Requirement
|
114
115
|
requirements:
|
115
|
-
- -
|
116
|
+
- - ">="
|
116
117
|
- !ruby/object:Gem::Version
|
117
118
|
version: '0'
|
118
|
-
name: yard
|
119
|
-
prerelease: false
|
120
119
|
type: :development
|
120
|
+
prerelease: false
|
121
121
|
version_requirements: !ruby/object:Gem::Requirement
|
122
122
|
requirements:
|
123
|
-
- -
|
123
|
+
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
- !ruby/object:Gem::Dependency
|
127
|
+
name: simplecov
|
127
128
|
requirement: !ruby/object:Gem::Requirement
|
128
129
|
requirements:
|
129
|
-
- -
|
130
|
+
- - ">="
|
130
131
|
- !ruby/object:Gem::Version
|
131
132
|
version: '0'
|
132
|
-
name: simplecov
|
133
|
-
prerelease: false
|
134
133
|
type: :development
|
134
|
+
prerelease: false
|
135
135
|
version_requirements: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- -
|
137
|
+
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
140
|
- !ruby/object:Gem::Dependency
|
141
|
+
name: coveralls
|
141
142
|
requirement: !ruby/object:Gem::Requirement
|
142
143
|
requirements:
|
143
|
-
- -
|
144
|
+
- - ">="
|
144
145
|
- !ruby/object:Gem::Version
|
145
146
|
version: '0'
|
146
|
-
name: coveralls
|
147
|
-
prerelease: false
|
148
147
|
type: :development
|
148
|
+
prerelease: false
|
149
149
|
version_requirements: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
|
-
- -
|
151
|
+
- - ">="
|
152
152
|
- !ruby/object:Gem::Version
|
153
153
|
version: '0'
|
154
|
-
description: library implementing patterns that behave like regular expressions for
|
154
|
+
description: library implementing patterns that behave like regular expressions for
|
155
|
+
use in Ruby 1.9
|
155
156
|
email: namusyaka@gmail.com
|
156
157
|
executables: []
|
157
158
|
extensions: []
|
158
159
|
extra_rdoc_files:
|
159
160
|
- README.md
|
160
161
|
files:
|
161
|
-
- .gitignore
|
162
|
-
- .rspec
|
163
|
-
- .travis.yml
|
164
|
-
- .yardopts
|
162
|
+
- ".gitignore"
|
163
|
+
- ".rspec"
|
164
|
+
- ".travis.yml"
|
165
|
+
- ".yardopts"
|
165
166
|
- Gemfile
|
166
167
|
- LICENSE
|
167
168
|
- README.md
|
@@ -191,6 +192,7 @@ files:
|
|
191
192
|
- lib/mustermann/express.rb
|
192
193
|
- lib/mustermann/extension.rb
|
193
194
|
- lib/mustermann/flask.rb
|
195
|
+
- lib/mustermann/grape.rb
|
194
196
|
- lib/mustermann/identity.rb
|
195
197
|
- lib/mustermann/mapper.rb
|
196
198
|
- lib/mustermann/pattern.rb
|
@@ -223,6 +225,7 @@ files:
|
|
223
225
|
- spec/extension_spec.rb
|
224
226
|
- spec/flask_spec.rb
|
225
227
|
- spec/flask_subclass_spec.rb
|
228
|
+
- spec/grape_spec.rb
|
226
229
|
- spec/identity_spec.rb
|
227
230
|
- spec/mapper_spec.rb
|
228
231
|
- spec/mustermann_spec.rb
|
@@ -252,24 +255,24 @@ homepage: https://github.com/namusyaka/mustermann
|
|
252
255
|
licenses:
|
253
256
|
- MIT
|
254
257
|
metadata: {}
|
255
|
-
post_install_message:
|
258
|
+
post_install_message:
|
256
259
|
rdoc_options: []
|
257
260
|
require_paths:
|
258
261
|
- lib
|
259
262
|
required_ruby_version: !ruby/object:Gem::Requirement
|
260
263
|
requirements:
|
261
|
-
- -
|
264
|
+
- - ">="
|
262
265
|
- !ruby/object:Gem::Version
|
263
266
|
version: 1.9.2
|
264
267
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
265
268
|
requirements:
|
266
|
-
- -
|
269
|
+
- - ">="
|
267
270
|
- !ruby/object:Gem::Version
|
268
271
|
version: '0'
|
269
272
|
requirements: []
|
270
|
-
rubyforge_project:
|
271
|
-
rubygems_version: 2.1
|
272
|
-
signing_key:
|
273
|
+
rubyforge_project:
|
274
|
+
rubygems_version: 2.5.1
|
275
|
+
signing_key:
|
273
276
|
specification_version: 4
|
274
277
|
summary: use patterns like regular expressions
|
275
278
|
test_files:
|
@@ -280,6 +283,7 @@ test_files:
|
|
280
283
|
- spec/extension_spec.rb
|
281
284
|
- spec/flask_spec.rb
|
282
285
|
- spec/flask_subclass_spec.rb
|
286
|
+
- spec/grape_spec.rb
|
283
287
|
- spec/identity_spec.rb
|
284
288
|
- spec/mapper_spec.rb
|
285
289
|
- spec/mustermann_spec.rb
|
@@ -305,4 +309,4 @@ test_files:
|
|
305
309
|
- spec/support/scan_matcher.rb
|
306
310
|
- spec/template_spec.rb
|
307
311
|
- spec/to_pattern_spec.rb
|
308
|
-
has_rdoc:
|
312
|
+
has_rdoc:
|