mustermann 1.1.1 → 3.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/expander.rb +4 -2
- data/lib/mustermann/ast/node.rb +3 -3
- data/lib/mustermann/ast/translator.rb +1 -1
- data/lib/mustermann/extension.rb +1 -48
- data/lib/mustermann/version.rb +1 -1
- data/lib/mustermann.rb +2 -3
- data/mustermann.gemspec +1 -2
- data/spec/mustermann_spec.rb +2 -5
- metadata +7 -10
- 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: ea330a8bf09165e676628df2668f0afa5d8fd32372bb7b07ed6a286cf274f74c
|
4
|
+
data.tar.gz: 58b0252ef3ba1d5bd06b3dceab50c06ba011d98b9e2bc54c6caa314443fa722b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9e8638a1cb73cf39256c6cb422d4d1a4601a2d9348aba8361d31083103e0495a843d595b579f08d2614ba1b665b41959a79eaffd869348551a2cb558c1cf1ea
|
7
|
+
data.tar.gz: 5b569063e6dd7d3beb3bdd983d4f5c30a9d12ce7b5e06d0f1f215e56004ba678011df824d26a94d5dc136d957c7835e5bcc38081cbbda2d838cfe78b3ca00ec7
|
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
|
|
@@ -12,11 +12,11 @@ module Mustermann
|
|
12
12
|
class Expander < Translator
|
13
13
|
raises ExpandError
|
14
14
|
|
15
|
-
translate
|
15
|
+
translate(Array, &-> (*args) do
|
16
16
|
inject(t.pattern) do |pattern, element|
|
17
17
|
t.add_to(pattern, t(element, *args))
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end.ruby2_keywords)
|
20
20
|
|
21
21
|
translate :capture do |**options|
|
22
22
|
t.for_capture(node, **options)
|
@@ -124,6 +124,8 @@ module Mustermann
|
|
124
124
|
# @see Mustermann::AST::Translator#expand
|
125
125
|
# @!visibility private
|
126
126
|
ruby2_keywords def escape(string, *args)
|
127
|
+
return super unless string.respond_to?(:=~)
|
128
|
+
|
127
129
|
# URI::Parser is pretty slow, let's not send every string to it, even if it's unnecessary
|
128
130
|
string =~ /\A\w*\Z/ ? string : super
|
129
131
|
end
|
data/lib/mustermann/ast/node.rb
CHANGED
@@ -35,8 +35,8 @@ module Mustermann
|
|
35
35
|
# Helper for creating a new instance and calling #parse on it.
|
36
36
|
# @return [Mustermann::AST::Node]
|
37
37
|
# @!visibility private
|
38
|
-
def self.parse(
|
39
|
-
new(
|
38
|
+
def self.parse(payload = nil, **options, &block)
|
39
|
+
new(payload, **options).tap { |n| n.parse(&block) }
|
40
40
|
end
|
41
41
|
|
42
42
|
# @!visibility private
|
@@ -108,7 +108,7 @@ module Mustermann
|
|
108
108
|
# @see Mustermann::AST::Node#parse
|
109
109
|
# @!visibility private
|
110
110
|
def parse
|
111
|
-
self.payload ||=
|
111
|
+
self.payload ||= String.new
|
112
112
|
super
|
113
113
|
end
|
114
114
|
|
@@ -120,7 +120,7 @@ module Mustermann
|
|
120
120
|
# @!visibility private
|
121
121
|
def escape(char, parser: URI::DEFAULT_PARSER, escape: parser.regexp[:UNSAFE], also_escape: nil)
|
122
122
|
escape = Regexp.union(also_escape, escape) if also_escape
|
123
|
-
char =~ escape ? parser.escape(char, Regexp.union(*escape)) : char
|
123
|
+
char.to_s =~ escape ? parser.escape(char, Regexp.union(*escape)) : char
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
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
@@ -75,8 +75,8 @@ module Mustermann
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
-
@mutex
|
79
|
-
@types
|
78
|
+
@mutex = Mutex.new
|
79
|
+
@types = {}
|
80
80
|
|
81
81
|
# Maps a type to its factory.
|
82
82
|
#
|
@@ -120,7 +120,6 @@ module Mustermann
|
|
120
120
|
def self.extend_object(object)
|
121
121
|
return super unless defined? ::Sinatra::Base and object.is_a? Class and object < ::Sinatra::Base
|
122
122
|
require 'mustermann/extension'
|
123
|
-
object.register Extension
|
124
123
|
end
|
125
124
|
end
|
126
125
|
|
data/mustermann.gemspec
CHANGED
@@ -10,10 +10,9 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.summary = %q{Your personal string matching expert.}
|
11
11
|
s.description = %q{A library implementing patterns that behave like regular expressions.}
|
12
12
|
s.license = 'MIT'
|
13
|
-
s.required_ruby_version = '>= 2.
|
13
|
+
s.required_ruby_version = '>= 2.6.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,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mustermann
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Konstantin Haase
|
8
8
|
- Zachary Scott
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-07-24 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
|
@@ -90,7 +89,7 @@ homepage: https://github.com/sinatra/mustermann
|
|
90
89
|
licenses:
|
91
90
|
- MIT
|
92
91
|
metadata: {}
|
93
|
-
post_install_message:
|
92
|
+
post_install_message:
|
94
93
|
rdoc_options: []
|
95
94
|
require_paths:
|
96
95
|
- lib
|
@@ -98,16 +97,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
98
97
|
requirements:
|
99
98
|
- - ">="
|
100
99
|
- !ruby/object:Gem::Version
|
101
|
-
version: 2.
|
100
|
+
version: 2.6.0
|
102
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
102
|
requirements:
|
104
103
|
- - ">="
|
105
104
|
- !ruby/object:Gem::Version
|
106
105
|
version: '0'
|
107
106
|
requirements: []
|
108
|
-
|
109
|
-
|
110
|
-
signing_key:
|
107
|
+
rubygems_version: 3.0.3.1
|
108
|
+
signing_key:
|
111
109
|
specification_version: 4
|
112
110
|
summary: Your personal string matching expert.
|
113
111
|
test_files:
|
@@ -116,7 +114,6 @@ test_files:
|
|
116
114
|
- spec/concat_spec.rb
|
117
115
|
- spec/equality_map_spec.rb
|
118
116
|
- spec/expander_spec.rb
|
119
|
-
- spec/extension_spec.rb
|
120
117
|
- spec/identity_spec.rb
|
121
118
|
- spec/mapper_spec.rb
|
122
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
|