mustermann-contrib 1.0.0.beta2 → 1.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +23 -0
  3. data/README.md +11 -95
  4. data/lib/mustermann/cake.rb +1 -0
  5. data/lib/mustermann/express.rb +1 -0
  6. data/lib/mustermann/file_utils.rb +1 -0
  7. data/lib/mustermann/file_utils/glob_pattern.rb +1 -0
  8. data/lib/mustermann/flask.rb +1 -0
  9. data/lib/mustermann/pyramid.rb +1 -0
  10. data/lib/mustermann/rails.rb +1 -0
  11. data/lib/mustermann/shell.rb +1 -0
  12. data/lib/mustermann/simple.rb +1 -0
  13. data/lib/mustermann/string_scanner.rb +1 -0
  14. data/lib/mustermann/template.rb +1 -0
  15. data/lib/mustermann/versions.rb +2 -1
  16. data/lib/mustermann/visualizer.rb +5 -4
  17. data/lib/mustermann/visualizer/highlight.rb +9 -8
  18. data/lib/mustermann/visualizer/highlighter.rb +1 -0
  19. data/lib/mustermann/visualizer/highlighter/ad_hoc.rb +2 -1
  20. data/lib/mustermann/visualizer/highlighter/ast.rb +1 -0
  21. data/lib/mustermann/visualizer/highlighter/composite.rb +2 -1
  22. data/lib/mustermann/visualizer/highlighter/dummy.rb +2 -1
  23. data/lib/mustermann/visualizer/highlighter/regular.rb +2 -1
  24. data/lib/mustermann/visualizer/pattern_extension.rb +2 -1
  25. data/lib/mustermann/visualizer/renderer/ansi.rb +1 -0
  26. data/lib/mustermann/visualizer/renderer/generic.rb +1 -0
  27. data/lib/mustermann/visualizer/renderer/hansi_template.rb +1 -0
  28. data/lib/mustermann/visualizer/renderer/html.rb +1 -0
  29. data/lib/mustermann/visualizer/renderer/sexp.rb +1 -0
  30. data/lib/mustermann/visualizer/tree.rb +2 -1
  31. data/lib/mustermann/visualizer/tree_renderer.rb +2 -1
  32. data/mustermann-contrib.gemspec +1 -1
  33. data/spec/cake_spec.rb +1 -0
  34. data/spec/express_spec.rb +1 -0
  35. data/spec/file_utils_spec.rb +1 -0
  36. data/spec/flask_spec.rb +1 -0
  37. data/spec/flask_subclass_spec.rb +2 -1
  38. data/spec/pattern_extension_spec.rb +1 -0
  39. data/spec/pyramid_spec.rb +1 -0
  40. data/spec/rails_spec.rb +1 -0
  41. data/spec/shell_spec.rb +1 -0
  42. data/spec/simple_spec.rb +1 -0
  43. data/spec/string_scanner_spec.rb +1 -0
  44. data/spec/template_spec.rb +1 -0
  45. metadata +8 -10
  46. data/lib/mustermann/grape.rb +0 -35
  47. data/spec/grape_spec.rb +0 -747
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Mustermann
2
3
  module Visualizer
3
4
  # Mixin that will be added to {Mustermann::Pattern}.
@@ -65,4 +66,4 @@ module Mustermann
65
66
  end
66
67
  end
67
68
  end
68
- end
69
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Mustermann
2
3
  module Visualizer
3
4
  # @!visibility private
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module Mustermann
2
3
  module Visualizer
3
4
  # @!visibility private
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mustermann/visualizer/renderer/generic'
2
3
 
3
4
  module Mustermann
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mustermann/visualizer/renderer/generic'
2
3
  require 'cgi'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mustermann/visualizer/renderer/generic'
2
3
 
3
4
  module Mustermann
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'hansi'
2
3
 
3
4
  module Mustermann
@@ -60,4 +61,4 @@ module Mustermann
60
61
  private :ljust, :deansi, :length
61
62
  end
62
63
  end
63
- end
64
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'mustermann/visualizer/tree'
2
3
  require 'mustermann/ast/translator'
3
4
  require 'hansi'
@@ -75,4 +76,4 @@ module Mustermann
75
76
  translate(Object) { }
76
77
  end
77
78
  end
78
- end
79
+ end
@@ -5,7 +5,7 @@ Gem::Specification.new do |s|
5
5
  s.name = "mustermann-contrib"
6
6
  s.version = Mustermann::VERSION
7
7
  s.authors = ["Konstantin Haase", "Zachary Scott"]
8
- s.email = "mail@zzak.io"
8
+ s.email = "sinatrarb@googlegroups.com"
9
9
  s.homepage = "https://github.com/sinatra/mustermann"
10
10
  s.summary = %q{Collection of extensions for Mustermann}
11
11
  s.description = %q{Adds many plugins to Mustermman}
data/spec/cake_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/cake'
3
4
 
data/spec/express_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/express'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/file_utils'
3
4
 
data/spec/flask_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/flask'
3
4
 
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/flask'
3
4
 
4
5
  FlaskSubclass ||= Class.new(Mustermann::Flask)
5
- FlaskSubclass.register_converter(:foo) {}
6
+ FlaskSubclass.register_converter(:foo) {}
6
7
 
7
8
  describe FlaskSubclass do
8
9
  extend Support::Pattern
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/visualizer'
3
4
  require 'pp'
data/spec/pyramid_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/pyramid'
3
4
 
data/spec/rails_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/rails'
3
4
 
data/spec/shell_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/shell'
3
4
 
data/spec/simple_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/simple'
3
4
  require 'mustermann/visualizer'
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/string_scanner'
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'support'
2
3
  require 'mustermann/template'
3
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mustermann-contrib
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta2
4
+ version: 1.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: 2016-08-22 00:00:00.000000000 Z
12
+ date: 2017-03-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mustermann
@@ -17,14 +17,14 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 1.0.0.beta2
20
+ version: 1.0.0
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 1.0.0.beta2
27
+ version: 1.0.0
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: hansi
30
30
  requirement: !ruby/object:Gem::Requirement
@@ -40,11 +40,12 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: 0.2.0
42
42
  description: Adds many plugins to Mustermman
43
- email: mail@zzak.io
43
+ email: sinatrarb@googlegroups.com
44
44
  executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - LICENSE
48
49
  - README.md
49
50
  - examples/highlighting.rb
50
51
  - highlighting.png
@@ -55,7 +56,6 @@ files:
55
56
  - lib/mustermann/file_utils/glob_pattern.rb
56
57
  - lib/mustermann/fileutils.rb
57
58
  - lib/mustermann/flask.rb
58
- - lib/mustermann/grape.rb
59
59
  - lib/mustermann/pyramid.rb
60
60
  - lib/mustermann/rails.rb
61
61
  - lib/mustermann/shell.rb
@@ -87,7 +87,6 @@ files:
87
87
  - spec/file_utils_spec.rb
88
88
  - spec/flask_spec.rb
89
89
  - spec/flask_subclass_spec.rb
90
- - spec/grape_spec.rb
91
90
  - spec/pattern_extension_spec.rb
92
91
  - spec/pyramid_spec.rb
93
92
  - spec/rails_spec.rb
@@ -113,9 +112,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
112
  version: 2.2.0
114
113
  required_rubygems_version: !ruby/object:Gem::Requirement
115
114
  requirements:
116
- - - ">"
115
+ - - ">="
117
116
  - !ruby/object:Gem::Version
118
- version: 1.3.1
117
+ version: '0'
119
118
  requirements: []
120
119
  rubyforge_project:
121
120
  rubygems_version: 2.5.1
@@ -123,4 +122,3 @@ signing_key:
123
122
  specification_version: 4
124
123
  summary: Collection of extensions for Mustermann
125
124
  test_files: []
126
- has_rdoc:
@@ -1,35 +0,0 @@
1
- require 'mustermann'
2
- require 'mustermann/ast/pattern'
3
-
4
- module Mustermann
5
- # Grape style pattern implementation.
6
- #
7
- # @example
8
- # Mustermann.new('/:foo', type: :grape) === '/bar' # => true
9
- #
10
- # @see Mustermann::Pattern
11
- # @see file:README.md#grape Syntax description in the README
12
- class Grape < AST::Pattern
13
- register :grape
14
-
15
- on(nil, ??, ?)) { |c| unexpected(c) }
16
-
17
- on(?*) { |c| scan(/\w+/) ? node(:named_splat, buffer.matched) : node(:splat) }
18
- on(?:) { |c| node(:capture, constraint: "[^/\\?#\.]") { scan(/\w+/) } }
19
- on(?\\) { |c| node(:char, expect(/./)) }
20
- on(?() { |c| node(:optional, node(:group) { read unless scan(?)) }) }
21
- on(?|) { |c| node(:or) }
22
-
23
- on ?{ do |char|
24
- type = scan(?+) ? :named_splat : :capture
25
- name = expect(/[\w\.]+/)
26
- type = :splat if type == :named_splat and name == 'splat'
27
- expect(?})
28
- node(type, name)
29
- end
30
-
31
- suffix ?? do |char, element|
32
- node(:optional, element)
33
- end
34
- end
35
- end
data/spec/grape_spec.rb DELETED
@@ -1,747 +0,0 @@
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('/%0Afoo') .capturing foo: '%0Afoo' }
45
- it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' }
46
-
47
- it { should_not match('/foo.bar') }
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_not match('/foo.bar/bar.foo') }
63
- it { should_not match('/user@example.com/name') }
64
- it { should_not match('/10.1/te.st') }
65
- it { should_not match('/10.1.2/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
-
271
- it { should_not match('/pony正..jpg') }
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_not match('/foo.foo@bar') }
287
- it { should_not match('/foo@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_not match('/pony.png.jpg') }
299
- it { should_not match('/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_not match('/10/te.st') }
318
- end
319
-
320
- pattern '/10.1/:id' do
321
- it { should match('/10.1/test') .capturing id: 'test' }
322
- it { should_not match('/10.1/te.st') }
323
- end
324
-
325
- pattern '/:foo.:bar/:id' do
326
- it { should_not match('/10.1/te.st') }
327
- it { should_not match('/10.1.2/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_not match('/a.b/c') }
334
- it { should_not match('/a.b/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_not match('/pony.png.jpg') }
558
- it { should_not match('/pony.jpg.png') }
559
- it { should_not match('/pony.gif') }
560
- it { should_not match('/pony.') }
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.tar.gz') .capturing file: 'pony', ext: '.tar.gz' }
569
- it { should_not match('/pony.png.jpg') }
570
- it { should_not match('/pony.jpg.png') }
571
- it { should_not match('/pony.gif') }
572
- it { should_not match('/pony.') }
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_not match('/pony.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