sinatra-named-routes 0.0.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.
- data/.gitignore +18 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +57 -0
- data/Guardfile +9 -0
- data/README.md +3 -0
- data/Rakefile +1 -0
- data/lib/sinatra/named_routes.rb +103 -0
- data/lib/sinatra/version.rb +5 -0
- data/sinatra-named-routes.gemspec +22 -0
- data/spec/named_routes_spec.rb +149 -0
- data/spec/spec_helper.rb +10 -0
- metadata +67 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in sinatra-named-routes.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'sinatra-contrib'
|
8
|
+
gem 'rspec'
|
9
|
+
gem 'guard-rspec'
|
10
|
+
end
|
11
|
+
|
12
|
+
group :test do
|
13
|
+
gem 'simplecov', require: false
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
sinatra-named-routes (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: http://rubygems.org/
|
8
|
+
specs:
|
9
|
+
backports (2.3.0)
|
10
|
+
diff-lcs (1.1.3)
|
11
|
+
eventmachine (0.12.10)
|
12
|
+
guard (0.8.8)
|
13
|
+
thor (~> 0.14.6)
|
14
|
+
guard-rspec (0.5.2)
|
15
|
+
guard (>= 0.8.4)
|
16
|
+
multi_json (1.0.3)
|
17
|
+
rack (1.3.5)
|
18
|
+
rack-protection (1.1.4)
|
19
|
+
rack
|
20
|
+
rack-test (0.6.1)
|
21
|
+
rack (>= 1.0)
|
22
|
+
rspec (2.7.0)
|
23
|
+
rspec-core (~> 2.7.0)
|
24
|
+
rspec-expectations (~> 2.7.0)
|
25
|
+
rspec-mocks (~> 2.7.0)
|
26
|
+
rspec-core (2.7.1)
|
27
|
+
rspec-expectations (2.7.0)
|
28
|
+
diff-lcs (~> 1.1.2)
|
29
|
+
rspec-mocks (2.7.0)
|
30
|
+
simplecov (0.5.4)
|
31
|
+
multi_json (~> 1.0.3)
|
32
|
+
simplecov-html (~> 0.5.3)
|
33
|
+
simplecov-html (0.5.3)
|
34
|
+
sinatra (1.3.1)
|
35
|
+
rack (~> 1.3, >= 1.3.4)
|
36
|
+
rack-protection (~> 1.1, >= 1.1.2)
|
37
|
+
tilt (~> 1.3, >= 1.3.3)
|
38
|
+
sinatra-contrib (1.3.1)
|
39
|
+
backports (>= 2.0)
|
40
|
+
eventmachine
|
41
|
+
rack-protection
|
42
|
+
rack-test
|
43
|
+
sinatra (~> 1.3.0)
|
44
|
+
tilt (~> 1.3)
|
45
|
+
thor (0.14.6)
|
46
|
+
tilt (1.3.3)
|
47
|
+
|
48
|
+
PLATFORMS
|
49
|
+
ruby
|
50
|
+
|
51
|
+
DEPENDENCIES
|
52
|
+
guard-rspec
|
53
|
+
rspec
|
54
|
+
simplecov
|
55
|
+
sinatra
|
56
|
+
sinatra-contrib
|
57
|
+
sinatra-named-routes!
|
data/Guardfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :cli => '--color --format nested', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
end
|
9
|
+
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require_relative 'version'
|
2
|
+
|
3
|
+
module Sinatra
|
4
|
+
module NamedRoutes
|
5
|
+
@@routes = {}
|
6
|
+
|
7
|
+
#def uri(addr = nil, absolute = true, add_script_name = true, params = {})
|
8
|
+
def uri(*args)
|
9
|
+
path = args.shift if args.first.is_a? Symbol
|
10
|
+
params = args.pop if args.last.is_a? Array or args.last.is_a? Hash
|
11
|
+
|
12
|
+
if path
|
13
|
+
addr = get_path(path, params)
|
14
|
+
|
15
|
+
super(addr, *args)
|
16
|
+
else
|
17
|
+
super(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
alias :to :uri
|
23
|
+
alias :url :uri
|
24
|
+
|
25
|
+
def map(name, path)
|
26
|
+
route = {}
|
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
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
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
|
+
def route(verb, path, options={}, &block)
|
92
|
+
if path.is_a?(Symbol)
|
93
|
+
path = @@routes[path][:path]
|
94
|
+
end
|
95
|
+
|
96
|
+
super(verb, path, options, &block)
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.registered(app)
|
100
|
+
app.helpers NamedRoutes
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'sinatra/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'sinatra-named-routes'
|
7
|
+
s.version = Sinatra::NamedRoutes::VERSION
|
8
|
+
s.authors = ['Cristian Hampus']
|
9
|
+
s.email = ['contact@cristianhampus.se']
|
10
|
+
s.homepage = 'https://github.com/ckhampus/sinatra-named-routes'
|
11
|
+
s.summary = %q{Named Routes for Sinatra}
|
12
|
+
s.description = %q{Allows the use of named routes in Sinatra applications.}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'sinatra-named-routes'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_dependency 'sinatra'
|
22
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require_relative 'spec_helper'
|
2
|
+
|
3
|
+
describe Sinatra::NamedRoutes do
|
4
|
+
def helper_route(&block)
|
5
|
+
result = nil
|
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
|
18
|
+
|
19
|
+
mock_app do
|
20
|
+
register Sinatra::NamedRoutes
|
21
|
+
|
22
|
+
map(:hello, '/hello')
|
23
|
+
|
24
|
+
map(:path_named, '/hello/:name')
|
25
|
+
map(:path_multi_named, '/hello/:name.:format')
|
26
|
+
map(:path_splat, '/hello/*')
|
27
|
+
map(:path_multi_splat, '/hello/*.*')
|
28
|
+
map(:path_regexp, %r{/hello/([\w]+)})
|
29
|
+
map(:path_multi_regexp, %r{/hello/([\w]+).([\w]+)})
|
30
|
+
|
31
|
+
get('/') { 'hello' }
|
32
|
+
get(:hello) { 'hello world' }
|
33
|
+
get('/hello/:name') { |name| "hello #{name}" }
|
34
|
+
|
35
|
+
app = self
|
36
|
+
end
|
37
|
+
|
38
|
+
@helper_app = app
|
39
|
+
end
|
40
|
+
|
41
|
+
describe :helper_route do
|
42
|
+
it 'runs the block' do
|
43
|
+
ran = false
|
44
|
+
helper_route { ran = true }
|
45
|
+
ran.should be_true
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'returns the block result' do
|
49
|
+
helper_route { 42 }.should be == 42
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe :routing do
|
55
|
+
it 'does still allow normal routing' do
|
56
|
+
get('/').should be_ok
|
57
|
+
body.should be == 'hello'
|
58
|
+
|
59
|
+
get('/hello/cristian').should be_ok
|
60
|
+
body.should be == 'hello cristian'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'does still allow routing with symbols as paths' do
|
64
|
+
get('/hello').should be_ok
|
65
|
+
body.should be == 'hello world'
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
describe :path_helper do
|
71
|
+
|
72
|
+
it 'does not break normal behavior' do
|
73
|
+
helper_route do
|
74
|
+
url '/route_one', false
|
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
|
83
|
+
|
84
|
+
describe :named do
|
85
|
+
it 'returns the correct path if passed a hash with symbols as keys' do
|
86
|
+
helper_route do
|
87
|
+
url :path_multi_named, false, name: 'cristian', format: 'json'
|
88
|
+
end.should be == '/hello/cristian.json'
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns the correct path if passed a hash with strings as keys' do
|
92
|
+
helper_route do
|
93
|
+
url :path_multi_named, false, 'name' => 'cristian', 'format' => 'json'
|
94
|
+
end.should be == '/hello/cristian.json'
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'ignores keys that are left' do
|
98
|
+
helper_route do
|
99
|
+
url :path_multi_named, false, name: 'cristian', format: 'json', color: 'blue'
|
100
|
+
end.should be == '/hello/cristian.json'
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'throws an exception if required keys do not exist' do
|
104
|
+
expect do
|
105
|
+
helper_route do
|
106
|
+
url :path_multi_named, false, name: 'cristian', color: 'blue'
|
107
|
+
end
|
108
|
+
end.to raise_exception ArgumentError
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
describe :splat do
|
114
|
+
it 'returns the correct url for path with splats' do
|
115
|
+
helper_route do
|
116
|
+
url :path_multi_splat, false, ['cristian', 'json']
|
117
|
+
end.should be == '/hello/cristian.json'
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'throws exception if params does not match number of splats' do
|
121
|
+
expect do
|
122
|
+
helper_route do
|
123
|
+
url :path_multi_splat, false, ['cristian']
|
124
|
+
end
|
125
|
+
end.to raise_exception ArgumentError
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
describe :regular_expression do
|
131
|
+
it 'returns the correct url for path with regular expressions' do
|
132
|
+
helper_route do
|
133
|
+
url :path_multi_regexp, false, ['cristian', 'json']
|
134
|
+
end.should be == '/hello/cristian.json'
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'throws exception if params does not match number of captures' do
|
138
|
+
expect do
|
139
|
+
helper_route do
|
140
|
+
url :path_multi_regexp, false, ['cristian']
|
141
|
+
end
|
142
|
+
end.to raise_exception ArgumentError
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sinatra-named-routes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Cristian Hampus
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-13 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sinatra
|
16
|
+
requirement: &22756416 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *22756416
|
25
|
+
description: Allows the use of named routes in Sinatra applications.
|
26
|
+
email:
|
27
|
+
- contact@cristianhampus.se
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- Gemfile
|
34
|
+
- Gemfile.lock
|
35
|
+
- Guardfile
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- lib/sinatra/named_routes.rb
|
39
|
+
- lib/sinatra/version.rb
|
40
|
+
- sinatra-named-routes.gemspec
|
41
|
+
- spec/named_routes_spec.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
homepage: https://github.com/ckhampus/sinatra-named-routes
|
44
|
+
licenses: []
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project: sinatra-named-routes
|
63
|
+
rubygems_version: 1.7.2
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Named Routes for Sinatra
|
67
|
+
test_files: []
|