joshbuddy-usher 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +0 -1
- data/VERSION.yml +1 -1
- data/lib/usher.rb +62 -9
- data/lib/usher/exceptions.rb +2 -2
- data/lib/usher/node.rb +1 -1
- data/lib/usher/route/splitter.rb +1 -1
- data/spec/recognize_spec.rb +15 -0
- metadata +3 -3
data/Rakefile
CHANGED
@@ -7,7 +7,6 @@ begin
|
|
7
7
|
s.description = s.summary = "A general purpose routing library"
|
8
8
|
s.email = "joshbuddy@gmail.com"
|
9
9
|
s.homepage = "http://github.com/joshbuddy/usher"
|
10
|
-
s.description = "TODO"
|
11
10
|
s.authors = ["Joshua Hull"]
|
12
11
|
s.files = FileList["[A-Z]*", "{lib,spec,rails}/**/*"]
|
13
12
|
s.add_dependency 'joshbuddy-fuzzy_hash'
|
data/VERSION.yml
CHANGED
data/lib/usher.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
$:.unshift File.dirname(__FILE__)
|
2
2
|
|
3
|
-
require 'strscan'
|
4
|
-
require 'set'
|
5
3
|
require 'usher/node'
|
6
4
|
require 'usher/route'
|
7
5
|
require 'usher/grapher'
|
@@ -12,15 +10,24 @@ class Usher
|
|
12
10
|
attr_reader :tree, :named_routes, :route_count, :routes
|
13
11
|
|
14
12
|
SymbolArraySorter = proc {|a,b| a.hash <=> b.hash}
|
15
|
-
|
13
|
+
|
14
|
+
# Returns whether the route set is empty
|
15
|
+
#
|
16
|
+
# set = Usher.new
|
17
|
+
# set.empty? => true
|
18
|
+
# set.add_route('/test')
|
19
|
+
# set.empty? => false
|
16
20
|
def empty?
|
17
21
|
@route_count.zero?
|
18
22
|
end
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
# Resets the route set back to its initial state
|
25
|
+
#
|
26
|
+
# set = Usher.new
|
27
|
+
# set.add_route('/test')
|
28
|
+
# set.empty? => false
|
29
|
+
# set.reset!
|
30
|
+
# set.empty? => true
|
24
31
|
def reset!
|
25
32
|
@tree = Node.root(self)
|
26
33
|
@named_routes = {}
|
@@ -30,19 +37,60 @@ class Usher
|
|
30
37
|
end
|
31
38
|
alias clear! reset!
|
32
39
|
|
33
|
-
|
34
|
-
|
40
|
+
# Creates a route set
|
41
|
+
def initialize
|
35
42
|
reset!
|
36
43
|
end
|
37
44
|
|
45
|
+
# Adds a route referencable by +name+. Sett add_route for format +path+ and +options+.
|
46
|
+
#
|
47
|
+
# set = Usher.new
|
48
|
+
# set.add_named_route(:test_route, '/test')
|
38
49
|
def add_named_route(name, path, options = {})
|
39
50
|
add_route(path, options).name(name)
|
40
51
|
end
|
41
52
|
|
53
|
+
# Attaches a +route+ to a +name+
|
54
|
+
#
|
55
|
+
# set = Usher.new
|
56
|
+
# route = set.add_route('/test')
|
57
|
+
# set.name(:test, route)
|
42
58
|
def name(name, route)
|
43
59
|
@named_routes[name] = route.primary_path
|
44
60
|
end
|
45
61
|
|
62
|
+
# Creates a route from +path+ and +options+
|
63
|
+
#
|
64
|
+
# <tt>+path+</tt>::
|
65
|
+
# A path consists a mix of dynamic and static parts delimited by <tt>/</tt>
|
66
|
+
#
|
67
|
+
# *Dynamic*
|
68
|
+
#
|
69
|
+
# Dynamic parts are prefixed with either :, *. :variable matches only one part of the path, whereas *variable can match one or
|
70
|
+
# more parts. Example:
|
71
|
+
# <b>/path/:variable/path</b> would match
|
72
|
+
#
|
73
|
+
# * /path/test/path
|
74
|
+
# * /path/something_else/path
|
75
|
+
# * /path/one_more/path
|
76
|
+
#
|
77
|
+
# In the above examples, 'test', 'something_else' and 'one_more' respectively would be bound to the key :variable.
|
78
|
+
# However, /path/test/one_more/path would not be matched.
|
79
|
+
#
|
80
|
+
# Example:
|
81
|
+
# <b>/path/*variable/path</b> would match
|
82
|
+
#
|
83
|
+
# * /path/one/two/three/path
|
84
|
+
# * /path/four/five/path
|
85
|
+
#
|
86
|
+
# In the above examples, ['one', 'two', 'three'] and ['four', 'five'] respectively would be bound to the key :variable.
|
87
|
+
#
|
88
|
+
# <tt>+options+</tt>::
|
89
|
+
# --
|
90
|
+
# * :transformers - Transforms a variable before it gets to the conditions and requirements. Takes either a +proc+ or a +symbol+. If its a +symbol+, calls the method on the incoming parameter. If its a +proc+, its called with the variable.
|
91
|
+
# * :requirements - After transformation, tests the condition using ===. If it returns false, it raises an +Usher::ValidationException+
|
92
|
+
# * :conditions - Accepts any of the following +:protocol+, +:domain+, +:port+, +:query_string+, +:remote_ip+, +:user_agent+, +:referer+ and +:method+. This can be either a +string+ or a +regexp+.
|
93
|
+
#
|
46
94
|
def add_route(path, options = {})
|
47
95
|
transformers = options.delete(:transformers) || {}
|
48
96
|
conditions = options.delete(:conditions) || {}
|
@@ -63,6 +111,11 @@ class Usher
|
|
63
111
|
route
|
64
112
|
end
|
65
113
|
|
114
|
+
# Recognizes a +request+ and returns +nil+ or an Usher::Route::Path
|
115
|
+
#
|
116
|
+
# set = Usher.new
|
117
|
+
# route = set.add_route('/test')
|
118
|
+
# set.name(:test, route)
|
66
119
|
def recognize(request)
|
67
120
|
@tree.find(request)
|
68
121
|
end
|
data/lib/usher/exceptions.rb
CHANGED
data/lib/usher/node.rb
CHANGED
@@ -127,7 +127,7 @@ class Usher
|
|
127
127
|
when Symbol
|
128
128
|
part = part.send(t)
|
129
129
|
end
|
130
|
-
raise "#{part} does not conform to #{next_part.value.validator}" if next_part.value.validator && (not next_part.value.validator === part)
|
130
|
+
raise ValidationException.new("#{part} does not conform to #{next_part.value.validator}") if next_part.value.validator && (not next_part.value.validator === part)
|
131
131
|
case next_part.value.type
|
132
132
|
when :*
|
133
133
|
params << [next_part.value.name, []]
|
data/lib/usher/route/splitter.rb
CHANGED
data/spec/recognize_spec.rb
CHANGED
@@ -30,6 +30,21 @@ describe "Usher route recognition" do
|
|
30
30
|
target_route.paths.include?(route_set.recognize(build_request({:method => 'get', :path => '/sample', :domain => 'admin.host.com'})).first).should == true
|
31
31
|
end
|
32
32
|
|
33
|
+
it "should recognize a format-style variable" do
|
34
|
+
target_route = route_set.add_route('/sample.:format', :controller => 'sample', :action => 'action')
|
35
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == [target_route.paths.first, [[:format , 'html']]]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should recognize a format-style literal" do
|
39
|
+
target_route = route_set.add_route(':action.html', :controller => 'sample', :action => 'action')
|
40
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == [target_route.paths.first, [[:action , 'sample']]]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should recognize a format-style variable along side another variable" do
|
44
|
+
target_route = route_set.add_route(':action.:format', :controller => 'sample', :action => 'action')
|
45
|
+
route_set.recognize(build_request({:method => 'get', :path => '/sample.html', :domain => 'admin.host.com'})).should == [target_route.paths.first, [[:action , 'sample'], [:format, 'html']]]
|
46
|
+
end
|
47
|
+
|
33
48
|
it "should recognize a specific route when several http-style restrictions are used" do
|
34
49
|
target_route_http_admin = route_set.add_route('/sample', :controller => 'sample', :action => 'action', :conditions => {:protocol => 'http', :domain => 'admin.spec.com'})
|
35
50
|
target_route_http_www = route_set.add_route('/sample', :controller => 'sample', :action => 'action', :conditions => {:protocol => 'http', :domain => 'www.spec.com'})
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: joshbuddy-usher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joshua Hull
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-03-
|
12
|
+
date: 2009-03-27 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,7 +22,7 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
-
description:
|
25
|
+
description: A general purpose routing library
|
26
26
|
email: joshbuddy@gmail.com
|
27
27
|
executables: []
|
28
28
|
|