sinatra-named-routes 0.0.1 → 0.1.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.
- data/.travis.yml +1 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +21 -17
- data/README.md +2 -2
- data/Rakefile +4 -0
- data/lib/sinatra/named_routes.rb +27 -78
- data/lib/sinatra/route_parser.rb +164 -0
- data/lib/sinatra/version.rb +1 -1
- data/spec/named_routes_spec.rb +64 -106
- data/spec/route_parser_spec.rb +72 -0
- metadata +12 -6
data/.travis.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm: 1.9.2
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -2,6 +2,7 @@ PATH
|
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
4
|
sinatra-named-routes (0.0.1)
|
5
|
+
sinatra
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: http://rubygems.org/
|
@@ -9,31 +10,34 @@ GEM
|
|
9
10
|
backports (2.3.0)
|
10
11
|
diff-lcs (1.1.3)
|
11
12
|
eventmachine (0.12.10)
|
12
|
-
|
13
|
+
ffi (1.0.11)
|
14
|
+
guard (1.0.0)
|
15
|
+
ffi (>= 0.5.0)
|
13
16
|
thor (~> 0.14.6)
|
14
|
-
guard-rspec (0.
|
15
|
-
guard (>= 0.
|
16
|
-
multi_json (1.0.
|
17
|
-
rack (1.
|
18
|
-
rack-protection (1.
|
17
|
+
guard-rspec (0.6.0)
|
18
|
+
guard (>= 0.10.0)
|
19
|
+
multi_json (1.0.4)
|
20
|
+
rack (1.4.1)
|
21
|
+
rack-protection (1.2.0)
|
19
22
|
rack
|
20
23
|
rack-test (0.6.1)
|
21
24
|
rack (>= 1.0)
|
22
|
-
|
23
|
-
|
24
|
-
rspec-
|
25
|
-
rspec-
|
26
|
-
|
27
|
-
rspec-
|
25
|
+
rake (0.9.2.2)
|
26
|
+
rspec (2.8.0)
|
27
|
+
rspec-core (~> 2.8.0)
|
28
|
+
rspec-expectations (~> 2.8.0)
|
29
|
+
rspec-mocks (~> 2.8.0)
|
30
|
+
rspec-core (2.8.0)
|
31
|
+
rspec-expectations (2.8.0)
|
28
32
|
diff-lcs (~> 1.1.2)
|
29
|
-
rspec-mocks (2.
|
33
|
+
rspec-mocks (2.8.0)
|
30
34
|
simplecov (0.5.4)
|
31
35
|
multi_json (~> 1.0.3)
|
32
36
|
simplecov-html (~> 0.5.3)
|
33
37
|
simplecov-html (0.5.3)
|
34
|
-
sinatra (1.3.
|
35
|
-
rack (~> 1.3, >= 1.3.
|
36
|
-
rack-protection (~> 1.
|
38
|
+
sinatra (1.3.2)
|
39
|
+
rack (~> 1.3, >= 1.3.6)
|
40
|
+
rack-protection (~> 1.2)
|
37
41
|
tilt (~> 1.3, >= 1.3.3)
|
38
42
|
sinatra-contrib (1.3.1)
|
39
43
|
backports (>= 2.0)
|
@@ -50,8 +54,8 @@ PLATFORMS
|
|
50
54
|
|
51
55
|
DEPENDENCIES
|
52
56
|
guard-rspec
|
57
|
+
rake
|
53
58
|
rspec
|
54
59
|
simplecov
|
55
|
-
sinatra
|
56
60
|
sinatra-contrib
|
57
61
|
sinatra-named-routes!
|
data/README.md
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
# Sinatra Named Routes
|
2
|
-
|
1
|
+
# Sinatra Named Routes [](http://travis-ci.org/ckhampus/sinatra-named-routes)
|
2
|
+
|
3
3
|
This gem allows the use of named routes in Sinatra applications.
|
data/Rakefile
CHANGED
data/lib/sinatra/named_routes.rb
CHANGED
@@ -1,103 +1,52 @@
|
|
1
|
-
|
1
|
+
require File.join(File.dirname(__FILE__), 'version')
|
2
|
+
require File.join(File.dirname(__FILE__), 'route_parser')
|
2
3
|
|
3
4
|
module Sinatra
|
4
5
|
module NamedRoutes
|
5
|
-
|
6
|
+
module Helpers
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# def uri(addr = nil, absolute = true, add_script_name = true, params = {})
|
9
|
+
def uri(*args)
|
10
|
+
path = args.shift if args.first.is_a? Symbol
|
11
|
+
params = args.pop if args.last.is_a? Array or args.last.is_a? Hash
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
if path
|
14
|
+
addr = NamedRoutes.get_path(path, params)
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
super(addr, *args)
|
17
|
+
else
|
18
|
+
super(*args)
|
19
|
+
end
|
19
20
|
|
21
|
+
end
|
22
|
+
alias :to :uri
|
23
|
+
alias :url :uri
|
20
24
|
end
|
21
25
|
|
22
|
-
alias :to :uri
|
23
|
-
alias :url :uri
|
24
|
-
|
25
26
|
def map(name, path)
|
26
|
-
|
27
|
-
route[:path] = path
|
28
|
-
|
29
|
-
if path.is_a? String
|
30
|
-
named = path.scan(/(?<=:)[^\.\/]*/).map { |item| item.to_sym }
|
31
|
-
splat = path.scan(/\*/)
|
32
|
-
|
33
|
-
params = { named: named, splat: splat }
|
34
|
-
elsif path.is_a? Regexp
|
35
|
-
regexp = path.source.scan(/\([^\)]*\)/)
|
36
|
-
|
37
|
-
params = { regexp: regexp }
|
38
|
-
end
|
39
|
-
|
40
|
-
route[:params] = params
|
41
|
-
|
42
|
-
@@routes[name] = route
|
27
|
+
NamedRoutes.routes[name] = Route.new path
|
43
28
|
end
|
44
29
|
|
45
30
|
private
|
46
31
|
|
47
|
-
def get_path(name, params = {})
|
48
|
-
route = @@routes[name]
|
49
|
-
|
50
|
-
path = route[:path]
|
51
|
-
|
52
|
-
if params.is_a? Hash
|
53
|
-
|
54
|
-
# Turn string keys into symbols
|
55
|
-
params = params.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
|
56
|
-
|
57
|
-
if path.is_a? String
|
58
|
-
route[:params][:named].each do |key|
|
59
|
-
if params.has_key? key
|
60
|
-
path = path.sub(key.inspect, params[key])
|
61
|
-
else
|
62
|
-
raise ArgumentError.new
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
elsif params.is_a? Array
|
67
|
-
if path.is_a? String
|
68
|
-
if route[:params][:splat].length != params.length
|
69
|
-
raise ArgumentError.new
|
70
|
-
end
|
71
|
-
|
72
|
-
params.each do |value|
|
73
|
-
path = path.sub('*', value)
|
74
|
-
end
|
75
|
-
elsif path.is_a? Regexp
|
76
|
-
if route[:params][:regexp].length != params.length
|
77
|
-
raise ArgumentError.new
|
78
|
-
end
|
79
|
-
|
80
|
-
path = path.source
|
81
|
-
|
82
|
-
params.each_index do |index|
|
83
|
-
path = path.sub(route[:params][:regexp][index], params[index])
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
path
|
89
|
-
end
|
90
|
-
|
91
32
|
def route(verb, path, options={}, &block)
|
92
33
|
if path.is_a?(Symbol)
|
93
|
-
path =
|
34
|
+
path = NamedRoutes.routes[path].source
|
94
35
|
end
|
95
36
|
|
96
37
|
super(verb, path, options, &block)
|
97
38
|
end
|
98
39
|
|
40
|
+
def self.get_path(name, params = {})
|
41
|
+
NamedRoutes.routes[name].build params
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.routes
|
45
|
+
@@routes ||= {}
|
46
|
+
end
|
47
|
+
|
99
48
|
def self.registered(app)
|
100
|
-
app.helpers NamedRoutes
|
49
|
+
app.helpers NamedRoutes::Helpers
|
101
50
|
end
|
102
51
|
end
|
103
52
|
end
|
@@ -0,0 +1,164 @@
|
|
1
|
+
class Route
|
2
|
+
attr_reader :source
|
3
|
+
|
4
|
+
def initialize(route)
|
5
|
+
route = route.source if route.is_a? Regexp
|
6
|
+
|
7
|
+
@source = route
|
8
|
+
@input = StringScanner.new(route)
|
9
|
+
@output = []
|
10
|
+
|
11
|
+
parse
|
12
|
+
end
|
13
|
+
|
14
|
+
# Public: Build URL with parameters.
|
15
|
+
#
|
16
|
+
# params - The hash or array of parameters to pass to URL.
|
17
|
+
#
|
18
|
+
# Returns the URL as a String.
|
19
|
+
def build(params = {})
|
20
|
+
path = []
|
21
|
+
params = {} if params.nil?
|
22
|
+
|
23
|
+
@output.each_index do |index|
|
24
|
+
item = @output[index]
|
25
|
+
next_item = @output.fetch(index + 1, nil)
|
26
|
+
|
27
|
+
case item[:token]
|
28
|
+
when :slash
|
29
|
+
@trailing_slash = item[:optional]
|
30
|
+
path << '/'
|
31
|
+
when :dot
|
32
|
+
@trailing_dot = item[:optional]
|
33
|
+
path << '.'
|
34
|
+
when :splat
|
35
|
+
if params.is_a? Hash
|
36
|
+
raise ArgumentError, 'No parameters passed.' if params[:splat].empty?
|
37
|
+
path << params[:splat].shift
|
38
|
+
else
|
39
|
+
raise ArgumentError, 'No enough parameters passed.' if params.empty?
|
40
|
+
path << params.shift
|
41
|
+
end
|
42
|
+
when :path
|
43
|
+
path << item[:value]
|
44
|
+
when :named_param
|
45
|
+
item_key = item[:value]
|
46
|
+
|
47
|
+
if params.has_key? item_key
|
48
|
+
path << params.delete(item_key)
|
49
|
+
else
|
50
|
+
raise ArgumentError, "No value passed for '#{item_key.to_s}'" unless item[:optional]
|
51
|
+
end
|
52
|
+
when :regexp
|
53
|
+
name = /#{item[:value]}/.names
|
54
|
+
|
55
|
+
if name.any?
|
56
|
+
name = name.first.to_sym
|
57
|
+
|
58
|
+
if params.has_key? name
|
59
|
+
path << params.delete(name)
|
60
|
+
else
|
61
|
+
raise ArgumentError, "No value passed for '#{name.to_s}'" unless item[:optional]
|
62
|
+
end
|
63
|
+
else
|
64
|
+
if params.is_a? Hash
|
65
|
+
raise ArgumentError, 'No enough parameters passed.' if params[:captures].empty? and !item[:optional]
|
66
|
+
path << params[:captures].shift
|
67
|
+
else
|
68
|
+
raise ArgumentError, 'No enough parameters passed.' if params.empty?
|
69
|
+
path << params.shift
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
path = path.join
|
76
|
+
|
77
|
+
if @trailing_dot
|
78
|
+
path = path.chomp '.'
|
79
|
+
end
|
80
|
+
|
81
|
+
if @trailing_slash
|
82
|
+
path = path.chomp '/'
|
83
|
+
end
|
84
|
+
|
85
|
+
path
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def is_optional?
|
91
|
+
@output.last[:optional] = @input.scan(/\?/) ? true : false
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse
|
95
|
+
while token = parse_slash || parse_path || parse_named_param ||
|
96
|
+
parse_dot || parse_splat || parse_regexp
|
97
|
+
@output << token
|
98
|
+
is_optional?
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def parse_slash
|
103
|
+
if @input.scan(/\//)
|
104
|
+
{
|
105
|
+
:token => :slash
|
106
|
+
}
|
107
|
+
else
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def parse_dot
|
113
|
+
if @input.scan(/\./)
|
114
|
+
{
|
115
|
+
:token => :dot
|
116
|
+
}
|
117
|
+
else
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def parse_splat
|
123
|
+
if @input.scan(/\*/)
|
124
|
+
{
|
125
|
+
:token => :splat
|
126
|
+
}
|
127
|
+
else
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def parse_path
|
133
|
+
if @input.scan(/\w+/)
|
134
|
+
{
|
135
|
+
:token => :path,
|
136
|
+
:value => @input.matched
|
137
|
+
}
|
138
|
+
else
|
139
|
+
nil
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def parse_named_param
|
144
|
+
if @input.scan(/:[^\W]*/)
|
145
|
+
{
|
146
|
+
:token => :named_param,
|
147
|
+
:value => @input.matched.sub(':', '').to_sym
|
148
|
+
}
|
149
|
+
else
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def parse_regexp
|
155
|
+
if @input.scan(/\([^\)]*\)/)
|
156
|
+
{
|
157
|
+
:token => :regexp,
|
158
|
+
:value => @input.matched
|
159
|
+
}
|
160
|
+
else
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
data/lib/sinatra/version.rb
CHANGED
data/spec/named_routes_spec.rb
CHANGED
@@ -1,147 +1,105 @@
|
|
1
|
-
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
2
|
|
3
3
|
describe Sinatra::NamedRoutes do
|
4
4
|
def helper_route(&block)
|
5
|
-
|
6
|
-
@helper_app.get('/helper_route') do
|
7
|
-
result = instance_eval(&block)
|
8
|
-
'ok'
|
9
|
-
end
|
10
|
-
get '/helper_route'
|
11
|
-
last_response.should be_ok
|
12
|
-
body.should be == 'ok'
|
13
|
-
result
|
14
|
-
end
|
15
|
-
|
16
|
-
before do
|
17
|
-
app = nil
|
5
|
+
time = Time.now.usec
|
18
6
|
|
19
7
|
mock_app do
|
20
8
|
register Sinatra::NamedRoutes
|
21
9
|
|
22
|
-
map(:
|
23
|
-
|
24
|
-
map(:
|
25
|
-
map(:
|
26
|
-
map(:
|
27
|
-
map(:path_multi_splat, '/hello/*.*')
|
28
|
-
map(:path_regexp, %r{/hello/([\w]+)})
|
29
|
-
map(:path_multi_regexp, %r{/hello/([\w]+).([\w]+)})
|
10
|
+
map(:path_named_params, '/hello/:name.:format')
|
11
|
+
map(:path_splats, '/hello/*.*')
|
12
|
+
map(:path_regexp, %r{/hello/([\w]+).([\w]+)})
|
13
|
+
map(:path_named_captures, %r{/hello/(?<person>[^/?#]+)})
|
14
|
+
map(:path_optional_named_captures, %r{/page(?<format>.[^/?#]+)?})
|
30
15
|
|
31
|
-
get
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
app = self
|
16
|
+
get "/#{time}" do
|
17
|
+
instance_eval(&block)
|
18
|
+
end
|
36
19
|
end
|
37
20
|
|
38
|
-
|
21
|
+
get "/#{time}"
|
39
22
|
end
|
40
23
|
|
41
|
-
describe :
|
42
|
-
it '
|
43
|
-
|
44
|
-
|
45
|
-
ran.should be_true
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'returns the block result' do
|
49
|
-
helper_route { 42 }.should be == 42
|
50
|
-
end
|
24
|
+
describe :routing do
|
25
|
+
it 'does allow routing with symbols as paths' do
|
26
|
+
mock_app do
|
27
|
+
register Sinatra::NamedRoutes
|
51
28
|
|
52
|
-
|
29
|
+
map :test, '/test'
|
53
30
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
31
|
+
get :test do
|
32
|
+
'symbols work'
|
33
|
+
end
|
34
|
+
end
|
58
35
|
|
59
|
-
get('/
|
60
|
-
body.should be == '
|
36
|
+
get('/test').should be_ok
|
37
|
+
body.should be == 'symbols work'
|
61
38
|
end
|
62
39
|
|
63
|
-
it 'does
|
64
|
-
|
65
|
-
|
40
|
+
it 'does not break normal routing' do
|
41
|
+
mock_app do
|
42
|
+
register Sinatra::NamedRoutes
|
43
|
+
|
44
|
+
get '/normal' do
|
45
|
+
'still works'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
get('/normal').should be_ok
|
50
|
+
body.should be == 'still works'
|
66
51
|
end
|
67
52
|
|
68
53
|
end
|
69
54
|
|
70
55
|
describe :path_helper do
|
71
56
|
|
72
|
-
it 'does not break normal behavior' do
|
73
|
-
|
74
|
-
|
75
|
-
end.should be == '/route_one'
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'ignores params if path is not a symbol' do
|
79
|
-
helper_route do
|
80
|
-
url '/route_one', false, name: 'cristian'
|
81
|
-
end.should be == '/route_one'
|
82
|
-
end
|
57
|
+
it 'does not break normal helper behavior' do
|
58
|
+
mock_app do
|
59
|
+
register Sinatra::NamedRoutes
|
83
60
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
url :path_multi_named, false, name: 'cristian', format: 'json'
|
88
|
-
end.should be == '/hello/cristian.json'
|
61
|
+
get '/' do
|
62
|
+
url '/route', false
|
63
|
+
end
|
89
64
|
end
|
90
65
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end.should be == '/hello/cristian.json'
|
95
|
-
end
|
66
|
+
get('/').should be_ok
|
67
|
+
body.should be == '/route'
|
68
|
+
end
|
96
69
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end.should be == '/hello/cristian.json'
|
101
|
-
end
|
70
|
+
it 'ignores params if path is not a symbol' do
|
71
|
+
mock_app do
|
72
|
+
register Sinatra::NamedRoutes
|
102
73
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
url :path_multi_named, false, name: 'cristian', color: 'blue'
|
107
|
-
end
|
108
|
-
end.to raise_exception ArgumentError
|
74
|
+
get '/' do
|
75
|
+
url '/route', false, :name => 'cristian'
|
76
|
+
end
|
109
77
|
end
|
110
78
|
|
79
|
+
get('/').should be_ok
|
80
|
+
body.should be == '/route'
|
111
81
|
end
|
112
82
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
url :path_multi_splat, false, ['cristian', 'json']
|
117
|
-
end.should be == '/hello/cristian.json'
|
118
|
-
end
|
83
|
+
it 'returns the correct urls' do
|
84
|
+
mock_app do
|
85
|
+
register Sinatra::NamedRoutes
|
119
86
|
|
120
|
-
|
121
|
-
expect do
|
122
|
-
helper_route do
|
123
|
-
url :path_multi_splat, false, ['cristian']
|
124
|
-
end
|
125
|
-
end.to raise_exception ArgumentError
|
126
|
-
end
|
87
|
+
map :path, '/hello/?:person?'
|
127
88
|
|
128
|
-
|
89
|
+
get '/test1' do
|
90
|
+
url :path, false, :person => 'cristian'
|
91
|
+
end
|
129
92
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
url :path_multi_regexp, false, ['cristian', 'json']
|
134
|
-
end.should be == '/hello/cristian.json'
|
93
|
+
get '/test2' do
|
94
|
+
url :path, false
|
95
|
+
end
|
135
96
|
end
|
136
97
|
|
137
|
-
|
138
|
-
|
139
|
-
helper_route do
|
140
|
-
url :path_multi_regexp, false, ['cristian']
|
141
|
-
end
|
142
|
-
end.to raise_exception ArgumentError
|
143
|
-
end
|
98
|
+
get('/test1').should be_ok
|
99
|
+
body.should be == '/hello/cristian'
|
144
100
|
|
101
|
+
get('/test2').should be_ok
|
102
|
+
body.should be == '/hello'
|
145
103
|
end
|
146
104
|
|
147
105
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe Route do
|
4
|
+
it 'supports named parameters' do
|
5
|
+
route = Route.new('/hello/:person.:format')
|
6
|
+
url = route.build :person => 'cristian', :format => 'json'
|
7
|
+
url.should eql '/hello/cristian.json'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'throws exception if required named params are missing' do
|
11
|
+
expect do
|
12
|
+
route = Route.new('/hello/:person.:format')
|
13
|
+
url = route.build :person => 'cristian'
|
14
|
+
end.to raise_exception ArgumentError
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'supports splats' do
|
18
|
+
route = Route.new('/hello/*.*')
|
19
|
+
url = route.build ['cristian', 'json']
|
20
|
+
url.should eql '/hello/cristian.json'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'throws exception if required splats are missing' do
|
24
|
+
expect do
|
25
|
+
route = Route.new('/hello/*.*')
|
26
|
+
url = route.build ['cristian']
|
27
|
+
end.to raise_exception ArgumentError
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'supports splats mixed wih named parameters' do
|
31
|
+
route = Route.new('/hello/:person.*')
|
32
|
+
url = route.build :person => 'cristian', :splat => ['json']
|
33
|
+
url.should eql '/hello/cristian.json'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'supports regular expressions' do
|
37
|
+
route = Route.new(%r{/hello/([\w]+).([\w]+)})
|
38
|
+
url = route.build ['cristian', 'html']
|
39
|
+
url.should eql '/hello/cristian.html'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'supports optional regular expressions mixed with named params' do
|
43
|
+
route = Route.new(%r{/hello/:lang/([\w]+).?([\w]+)?})
|
44
|
+
url = route.build :lang => 'en', :captures => ['cristian', 'html']
|
45
|
+
url.should eql '/hello/en/cristian.html'
|
46
|
+
|
47
|
+
url = route.build :lang => 'en', :captures => ['cristian']
|
48
|
+
url.should eql '/hello/en/cristian'
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'supports named capture groups' do
|
52
|
+
next if RUBY_VERSION < '1.9'
|
53
|
+
|
54
|
+
route = Route.new(%r{/hello/(?<person>[^/?#]+)})
|
55
|
+
url = route.build :person => 'cristian'
|
56
|
+
url.should eql '/hello/cristian'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'supports optional named capture groups' do
|
60
|
+
next if RUBY_VERSION < '1.9'
|
61
|
+
|
62
|
+
route = Route.new(%r{/page(?<format>.[^/?#]+)?})
|
63
|
+
url = route.build
|
64
|
+
url.should eql '/page'
|
65
|
+
|
66
|
+
url = route.build :format => '.html'
|
67
|
+
url.should eql '/page.html'
|
68
|
+
|
69
|
+
url = route.build :format => '.xml'
|
70
|
+
url.should eql '/page.xml'
|
71
|
+
end
|
72
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sinatra-named-routes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-02-11 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sinatra
|
16
|
-
requirement: &
|
16
|
+
requirement: &70197364991660 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70197364991660
|
25
25
|
description: Allows the use of named routes in Sinatra applications.
|
26
26
|
email:
|
27
27
|
- contact@cristianhampus.se
|
@@ -30,15 +30,18 @@ extensions: []
|
|
30
30
|
extra_rdoc_files: []
|
31
31
|
files:
|
32
32
|
- .gitignore
|
33
|
+
- .travis.yml
|
33
34
|
- Gemfile
|
34
35
|
- Gemfile.lock
|
35
36
|
- Guardfile
|
36
37
|
- README.md
|
37
38
|
- Rakefile
|
38
39
|
- lib/sinatra/named_routes.rb
|
40
|
+
- lib/sinatra/route_parser.rb
|
39
41
|
- lib/sinatra/version.rb
|
40
42
|
- sinatra-named-routes.gemspec
|
41
43
|
- spec/named_routes_spec.rb
|
44
|
+
- spec/route_parser_spec.rb
|
42
45
|
- spec/spec_helper.rb
|
43
46
|
homepage: https://github.com/ckhampus/sinatra-named-routes
|
44
47
|
licenses: []
|
@@ -60,8 +63,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
63
|
version: '0'
|
61
64
|
requirements: []
|
62
65
|
rubyforge_project: sinatra-named-routes
|
63
|
-
rubygems_version: 1.
|
66
|
+
rubygems_version: 1.8.15
|
64
67
|
signing_key:
|
65
68
|
specification_version: 3
|
66
69
|
summary: Named Routes for Sinatra
|
67
|
-
test_files:
|
70
|
+
test_files:
|
71
|
+
- spec/named_routes_spec.rb
|
72
|
+
- spec/route_parser_spec.rb
|
73
|
+
- spec/spec_helper.rb
|