oscardelben-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/MIT-LICENSE +21 -0
- data/README.rdoc +30 -0
- data/lib/building.rb +27 -0
- data/lib/recognition.rb +94 -0
- data/lib/routes.rb +36 -0
- data/lib/store.rb +13 -0
- data/spec/spec/routes_spec.rb +91 -0
- data/spec/spec_helper.rb +1 -0
- metadata +61 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) Oscar Del Ben <info@oscardelben.com>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
= Routes
|
2
|
+
== A routes library for ruby
|
3
|
+
|
4
|
+
USAGE:
|
5
|
+
|
6
|
+
Routes::Building.draw do
|
7
|
+
map '/posts', :controller => 'posts', :action => 'index'
|
8
|
+
map '/posts/:id', :controller => 'posts'
|
9
|
+
map '/controller/:action', {}
|
10
|
+
map '/:controller/:action/:id', {}
|
11
|
+
map '/cool', lambda { |path| "This is #{path}" }
|
12
|
+
map /.*/, :action => 'anything'
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
Routes::Recognition.new('/posts').recognize # => { :controller => 'posts', :action => 'index' }
|
17
|
+
|
18
|
+
Routes::Recognition.new('/posts/1').recognize # => { :controller => 'posts', :id => '1' }
|
19
|
+
|
20
|
+
Routes::Recognition.new('/controller/new').recognize # => { :action => 'new' }
|
21
|
+
|
22
|
+
Routes::Recognition.new('/posts/show/1').recognize # => { :controller => 'posts', :action => 'show', :id => '1' }
|
23
|
+
|
24
|
+
Routes::Recognition.new('/something').recognize # => { :action => 'anything' }
|
25
|
+
|
26
|
+
Routes::Recognition.new('/cool').recognize # => "This is /cool"
|
27
|
+
|
28
|
+
|
29
|
+
CONTRIBUTIONS
|
30
|
+
I'm open to contributions and suggestions. Drop me an email at info@oscardelben.com
|
data/lib/building.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
module Routes
|
2
|
+
class Building
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def map(route, action={})
|
7
|
+
Routes::Store.routes << [normalize_route(route), action]
|
8
|
+
end
|
9
|
+
|
10
|
+
def draw(&block)
|
11
|
+
class_eval(&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def normalize_route(route)
|
17
|
+
if route.is_a? String
|
18
|
+
route = "/#{route}" unless route[0] == ?/
|
19
|
+
route = "#{route}/" unless route[-1] == ?/
|
20
|
+
end
|
21
|
+
route
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/recognition.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
module Routes
|
2
|
+
class Recognition
|
3
|
+
|
4
|
+
attr_accessor :path, :result, :route_pattern
|
5
|
+
|
6
|
+
def initialize(path)
|
7
|
+
@path = path
|
8
|
+
@result = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def recognize
|
12
|
+
Routes::Store.routes.each do |route|
|
13
|
+
@route_pattern = route[0]
|
14
|
+
@result = route[1]
|
15
|
+
|
16
|
+
filter_route!
|
17
|
+
|
18
|
+
return give_back_result if @result
|
19
|
+
end
|
20
|
+
|
21
|
+
# Nothing matched
|
22
|
+
give_back_result
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def segments_from_string(path)
|
28
|
+
path[1..-1].split('/')
|
29
|
+
end
|
30
|
+
|
31
|
+
def give_back_result
|
32
|
+
if result.respond_to?(:call)
|
33
|
+
result.call(path)
|
34
|
+
else
|
35
|
+
result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_result(key, value)
|
40
|
+
@result.merge!(key => value)
|
41
|
+
end
|
42
|
+
|
43
|
+
def route_segments
|
44
|
+
segments_from_string(route_pattern)
|
45
|
+
end
|
46
|
+
|
47
|
+
def path_segments
|
48
|
+
segments_from_string(path)
|
49
|
+
end
|
50
|
+
|
51
|
+
def filter_route!
|
52
|
+
if route_pattern.is_a? String
|
53
|
+
match_with_string
|
54
|
+
elsif route_pattern.respond_to?(:match)
|
55
|
+
match_with_regexp
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def match_with_string
|
60
|
+
if compatible_segments?
|
61
|
+
match_segments
|
62
|
+
else
|
63
|
+
@result = nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def match_with_regexp
|
68
|
+
if route_pattern =~ path
|
69
|
+
return give_back_result
|
70
|
+
else
|
71
|
+
result = nil
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# TODO: path_segments is calculated 2 times
|
76
|
+
def compatible_segments?
|
77
|
+
route_segments.size == path_segments.size
|
78
|
+
end
|
79
|
+
|
80
|
+
def match_segments
|
81
|
+
path_segments.each_with_index do |path_segment, index|
|
82
|
+
route_segment = route_segments[index]
|
83
|
+
|
84
|
+
if route_segment[0] == ?:
|
85
|
+
update_result(eval(route_segment), path_segment)
|
86
|
+
elsif path_segment != route_segment
|
87
|
+
@result = nil
|
88
|
+
break
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
data/lib/routes.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009 Oscar Del Ben <info@oscardelben.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
|
25
|
+
path = File.expand_path(File.dirname(__FILE__))
|
26
|
+
$:.unshift(path) unless $:.include?(path)
|
27
|
+
|
28
|
+
module Routes
|
29
|
+
|
30
|
+
autoload :Building, "building"
|
31
|
+
autoload :Recognition, "recognition"
|
32
|
+
autoload :Store, "store"
|
33
|
+
|
34
|
+
VERSION = [0,1]
|
35
|
+
|
36
|
+
end
|
data/lib/store.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'spec_helper')
|
2
|
+
|
3
|
+
describe Routes do
|
4
|
+
context 'storing new routes' do
|
5
|
+
|
6
|
+
before(:each) do
|
7
|
+
Routes::Store.routes = []
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should have an empty routes list on new" do
|
11
|
+
Routes::Store.routes.should == []
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be able to add a new route with the map method" do
|
15
|
+
Routes::Building.map('/foo', 'some action')
|
16
|
+
Routes::Store.routes.should == [['/foo/', 'some action']]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should consider the order of routes with the map method" do
|
20
|
+
Routes::Building.map('/first', 'first action')
|
21
|
+
Routes::Building.map('/second', 'second action')
|
22
|
+
Routes::Store.routes.should == [['/first/', 'first action'], ['/second/', 'second action']]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should append / at the start of path if needed" do
|
26
|
+
Routes::Building.map('foo/', nil)
|
27
|
+
Routes::Store.routes.should == [['/foo/', nil]]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should append / at the end of path if needed" do
|
31
|
+
Routes::Building.map('/foo', nil)
|
32
|
+
Routes::Store.routes.should == [['/foo/', nil]]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should be able to storea bunch of routes with the draw method" do
|
36
|
+
proc = lambda { |path| "You are visiting #{path}" }
|
37
|
+
regex = /pos.*/
|
38
|
+
|
39
|
+
Routes::Building.draw do
|
40
|
+
map '/first', 'something'
|
41
|
+
map '/second', :controller => 'foo', :action => 'bar'
|
42
|
+
map '/third', proc
|
43
|
+
map regex, 'something else'
|
44
|
+
end
|
45
|
+
|
46
|
+
Routes::Store.routes.should == [
|
47
|
+
['/first/', 'something'],
|
48
|
+
['/second/', { :controller => 'foo', :action => 'bar' }],
|
49
|
+
['/third/', proc],
|
50
|
+
[regex, 'something else']
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'routes recognition' do
|
58
|
+
|
59
|
+
before(:each) do
|
60
|
+
Routes::Store.routes = []
|
61
|
+
|
62
|
+
Routes::Building.draw do
|
63
|
+
map '/posts', :controller => 'posts', :action => 'index'
|
64
|
+
map '/posts/:id', :controller => 'posts'
|
65
|
+
map '/controller/:action', {}
|
66
|
+
map '/:controller/:action/:id', {}
|
67
|
+
map '/cool', lambda { |path| "This is #{path}" }
|
68
|
+
map /.*/, :action => 'anything'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should find route" do
|
73
|
+
Routes::Recognition.new('/posts').recognize.should == { :controller => 'posts', :action => 'index' }
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should find route with symbols as parameters" do
|
77
|
+
Routes::Recognition.new('/posts/1').recognize.should == { :controller => 'posts', :id => '1' }
|
78
|
+
Routes::Recognition.new('/controller/new').recognize.should == { :action => 'new' }
|
79
|
+
Routes::Recognition.new('/posts/show/1').recognize.should == { :controller => 'posts', :action => 'show', :id => '1' }
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should find route with regular expression" do
|
83
|
+
Routes::Recognition.new('/something').recognize.should == { :action => 'anything' }
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should directly execute lambda routes" do
|
87
|
+
Routes::Recognition.new('/cool').recognize.should == "This is /cool"
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'routes')
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oscardelben-routes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Oscar Del Ben
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-05-18 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A routes library for ruby.
|
17
|
+
email: info@oscardelben.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- lib/building.rb
|
26
|
+
- lib/recognition.rb
|
27
|
+
- lib/routes.rb
|
28
|
+
- lib/store.rb
|
29
|
+
- MIT-LICENSE
|
30
|
+
- README.rdoc
|
31
|
+
- spec/spec/routes_spec.rb
|
32
|
+
- spec/spec_helper.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: http://github.com/oscardelben/routes
|
35
|
+
post_install_message:
|
36
|
+
rdoc_options:
|
37
|
+
- --inline-source
|
38
|
+
- --charset=UTF-8
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
version:
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
requirements: []
|
54
|
+
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 1.2.0
|
57
|
+
signing_key:
|
58
|
+
specification_version: 2
|
59
|
+
summary: A routes library for ruby.
|
60
|
+
test_files: []
|
61
|
+
|