joshbuddy-usher 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION.yml +2 -2
- data/lib/usher.rb +5 -3
- data/lib/usher/exceptions.rb +1 -3
- data/lib/usher/node.rb +2 -9
- data/lib/usher/route.rb +1 -2
- data/lib/usher/{route/splitter.rb → splitter.rb} +45 -39
- data/spec/split_spec.rb +14 -6
- metadata +3 -3
data/VERSION.yml
CHANGED
data/lib/usher.rb
CHANGED
@@ -4,10 +4,11 @@ require 'usher/node'
|
|
4
4
|
require 'usher/route'
|
5
5
|
require 'usher/grapher'
|
6
6
|
require 'usher/interface'
|
7
|
+
require 'usher/splitter'
|
7
8
|
require 'usher/exceptions'
|
8
9
|
|
9
10
|
class Usher
|
10
|
-
attr_reader :tree, :named_routes, :route_count, :routes
|
11
|
+
attr_reader :tree, :named_routes, :route_count, :routes, :splitter
|
11
12
|
|
12
13
|
SymbolArraySorter = proc {|a,b| a.hash <=> b.hash} #:nodoc:
|
13
14
|
|
@@ -38,7 +39,8 @@ class Usher
|
|
38
39
|
alias clear! reset!
|
39
40
|
|
40
41
|
# Creates a route set
|
41
|
-
def initialize
|
42
|
+
def initialize(delimiter = '/')
|
43
|
+
@splitter = Splitter.delimiter(delimiter)
|
42
44
|
reset!
|
43
45
|
end
|
44
46
|
|
@@ -130,7 +132,7 @@ class Usher
|
|
130
132
|
# route = set.add_route('/test')
|
131
133
|
# set.recognize(Request.new('/test')).path.route == route => true
|
132
134
|
def recognize(request)
|
133
|
-
@tree.find(request)
|
135
|
+
@tree.find(request, @splitter.url_split(request.path))
|
134
136
|
end
|
135
137
|
|
136
138
|
# Recognizes a set of +parameters+ and gets the closest matching Usher::Route::Path or +nil+ if no route exists.
|
data/lib/usher/exceptions.rb
CHANGED
data/lib/usher/node.rb
CHANGED
@@ -21,14 +21,7 @@ class Usher
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def depth
|
24
|
-
|
25
|
-
@depth = 0
|
26
|
-
p = self
|
27
|
-
while (p = p.parent) && p.is_a?(Node)
|
28
|
-
@depth += 1
|
29
|
-
end
|
30
|
-
end
|
31
|
-
@depth
|
24
|
+
@depth ||= @parent && @parent.is_a?(Node) ? @parent.depth + 1 : 0
|
32
25
|
end
|
33
26
|
|
34
27
|
def self.root(route_set)
|
@@ -103,7 +96,7 @@ class Usher
|
|
103
96
|
route
|
104
97
|
end
|
105
98
|
|
106
|
-
def find(request, path
|
99
|
+
def find(request, path, params = [])
|
107
100
|
part = path.shift unless path.size.zero?
|
108
101
|
|
109
102
|
if @exclusive_type
|
data/lib/usher/route.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
$:.unshift File.dirname(__FILE__)
|
2
2
|
|
3
3
|
require 'route/path'
|
4
|
-
require 'route/splitter'
|
5
4
|
require 'route/variable'
|
6
5
|
require 'route/request_method'
|
7
6
|
|
@@ -15,7 +14,7 @@ class Usher
|
|
15
14
|
@requirements = options.delete(:requirements)
|
16
15
|
@conditions = options.delete(:conditions)
|
17
16
|
@transformers = options.delete(:transformers)
|
18
|
-
@paths =
|
17
|
+
@paths = @router.splitter.split(@original_path, @requirements, @transformers).collect {|path| Path.new(self, path)}
|
19
18
|
@primary_path = @paths.first
|
20
19
|
end
|
21
20
|
|
@@ -1,47 +1,53 @@
|
|
1
1
|
require 'strscan'
|
2
2
|
|
3
3
|
class Usher
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
class Splitter
|
5
|
+
|
6
|
+
def self.delimiter(delimiter = '/')
|
7
|
+
SplitterInstance.new(
|
8
|
+
delimiter,
|
9
|
+
Regexp.new('((:|\*||\.:|\.)[0-9A-Za-z\$\-_\+!\*\',]+|' + Regexp.quote(delimiter) + '|\(|\)|\|)'),
|
10
|
+
Regexp.new(Regexp.quote(delimiter) + '|\.?[0-9A-Za-z\$\-_\+!\*\',]+')
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :paths
|
15
|
+
|
16
|
+
class SplitterInstance
|
11
17
|
|
12
|
-
def initialize(
|
13
|
-
@
|
14
|
-
@
|
15
|
-
@
|
18
|
+
def initialize(delimiter, split_regex, url_split_regex)
|
19
|
+
@delimiter = delimiter
|
20
|
+
@split_regex = split_regex
|
21
|
+
@url_split_regex = url_split_regex
|
16
22
|
end
|
17
|
-
|
18
|
-
def
|
23
|
+
|
24
|
+
def url_split(path)
|
19
25
|
parts = []
|
20
26
|
ss = StringScanner.new(path)
|
21
27
|
while !ss.eos?
|
22
|
-
if part = ss.scan(
|
23
|
-
parts << part unless part ==
|
28
|
+
if part = ss.scan(@url_split_regex)
|
29
|
+
parts << part unless part == @delimiter
|
24
30
|
end
|
25
31
|
end if path && !path.empty?
|
26
32
|
parts
|
27
33
|
end
|
28
|
-
|
29
|
-
def
|
34
|
+
|
35
|
+
def split(path, requirements = {}, transformers = {})
|
30
36
|
parts = Group.new(:all, nil)
|
31
37
|
ss = StringScanner.new(path)
|
32
38
|
current_group = parts
|
33
39
|
while !ss.eos?
|
34
|
-
part = ss.scan(
|
40
|
+
part = ss.scan(@split_regex)
|
35
41
|
case part[0]
|
36
42
|
when ?*, ?:, ?.
|
37
43
|
type = (part[1] == ?: ? part.slice!(0,2) : part.slice!(0).chr).to_sym
|
38
|
-
current_group << Variable.new(type, part, :validator => requirements[part.to_sym], :transformer => transformers[part.to_sym])
|
44
|
+
current_group << Usher::Route::Variable.new(type, part, :validator => requirements[part.to_sym], :transformer => transformers[part.to_sym])
|
39
45
|
when ?(
|
40
46
|
new_group = Group.new(:any, current_group)
|
41
47
|
current_group << new_group
|
42
48
|
current_group = new_group
|
43
|
-
when ?)
|
44
|
-
current_group = current_group.parent
|
49
|
+
when ?)
|
50
|
+
current_group = current_group.parent.type == :one ? current_group.parent.parent : current_group.parent
|
45
51
|
when ?|
|
46
52
|
unless current_group.parent.type == :one
|
47
53
|
detached_group = current_group.parent.pop
|
@@ -53,16 +59,16 @@ class Usher
|
|
53
59
|
end
|
54
60
|
current_group.parent << Group.new(:all, current_group.parent)
|
55
61
|
current_group = current_group.parent.last
|
56
|
-
when
|
62
|
+
when @delimiter[0]
|
57
63
|
else
|
58
64
|
current_group << part
|
59
65
|
end
|
60
66
|
end unless !path || path.empty?
|
61
|
-
parts
|
67
|
+
calc_paths(parts)
|
62
68
|
end
|
63
|
-
|
69
|
+
|
64
70
|
private
|
65
|
-
|
71
|
+
|
66
72
|
def cartesian_product!(lval, rval)
|
67
73
|
product = []
|
68
74
|
(lval.size * rval.size).times do |index|
|
@@ -73,7 +79,7 @@ class Usher
|
|
73
79
|
end
|
74
80
|
lval.replace(product)
|
75
81
|
end
|
76
|
-
|
82
|
+
|
77
83
|
def calc_paths(parts)
|
78
84
|
if parts.is_a?(Group)
|
79
85
|
paths = [[]]
|
@@ -97,23 +103,23 @@ class Usher
|
|
97
103
|
else
|
98
104
|
[[parts]]
|
99
105
|
end
|
100
|
-
|
106
|
+
|
101
107
|
end
|
108
|
+
end
|
109
|
+
|
110
|
+
class Group < Array
|
111
|
+
attr_accessor :type
|
112
|
+
attr_accessor :parent
|
102
113
|
|
103
|
-
|
104
|
-
|
105
|
-
attr_accessor :parent
|
106
|
-
|
107
|
-
def inspect
|
108
|
-
"#{type}->#{super}"
|
109
|
-
end
|
110
|
-
|
111
|
-
def initialize(type, parent)
|
112
|
-
@type = type
|
113
|
-
@parent = parent
|
114
|
-
end
|
114
|
+
def inspect
|
115
|
+
"#{type}->#{super}"
|
115
116
|
end
|
116
117
|
|
118
|
+
def initialize(type, parent)
|
119
|
+
@type = type
|
120
|
+
@parent = parent
|
121
|
+
end
|
117
122
|
end
|
123
|
+
|
118
124
|
end
|
119
125
|
end
|
data/spec/split_spec.rb
CHANGED
@@ -4,25 +4,33 @@ describe "Usher route tokenizing" do
|
|
4
4
|
|
5
5
|
|
6
6
|
it "should split / delimited routes" do
|
7
|
-
Usher::
|
7
|
+
Usher::Splitter.delimiter('/').split('/test/this/split').should == [['test', 'this', 'split']]
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should split on ' ' delimited routes as well" do
|
11
|
+
Usher::Splitter.delimiter(' ').split('test this split').should == [['test', 'this', 'split']]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should split on ' ' delimited routes for more complex routes as well" do
|
15
|
+
Usher::Splitter.delimiter(' ').split('(test|this) split').should == [['test', 'split'], ['this', 'split']]
|
8
16
|
end
|
9
17
|
|
10
18
|
it "should group optional parts with brackets" do
|
11
|
-
Usher::
|
19
|
+
Usher::Splitter.delimiter('/').split('/test/this(/split)').should == [
|
12
20
|
['test', 'this'],
|
13
21
|
['test', 'this', 'split']
|
14
22
|
]
|
15
23
|
end
|
16
24
|
|
17
25
|
it "should group exclusive optional parts with brackets and pipes" do
|
18
|
-
Usher::
|
26
|
+
Usher::Splitter.delimiter('/').split('/test/this(/split|/split2)').should == [
|
19
27
|
['test', 'this', 'split'],
|
20
28
|
['test', 'this', 'split2']
|
21
29
|
]
|
22
30
|
end
|
23
31
|
|
24
32
|
it "should group exclusive optional-optional parts with brackets and pipes" do
|
25
|
-
Usher::
|
33
|
+
Usher::Splitter.delimiter('/').split('/test/this((/split|/split2))').should == [
|
26
34
|
['test', 'this'],
|
27
35
|
['test', 'this', 'split'],
|
28
36
|
['test', 'this', 'split2']
|
@@ -30,7 +38,7 @@ describe "Usher route tokenizing" do
|
|
30
38
|
end
|
31
39
|
|
32
40
|
it "should group optional parts with brackets (for non overlapping groups)" do
|
33
|
-
Usher::
|
41
|
+
Usher::Splitter.delimiter('/').split('/test/this(/split)(/split2)') == [
|
34
42
|
["test", "this"],
|
35
43
|
["test", "this", "split"],
|
36
44
|
["test", "this", "split2"],
|
@@ -39,7 +47,7 @@ describe "Usher route tokenizing" do
|
|
39
47
|
end
|
40
48
|
|
41
49
|
it "should group nested-optional parts with brackets" do
|
42
|
-
Usher::
|
50
|
+
Usher::Splitter.delimiter('/').split('/test/this(/split(.:format))') == [
|
43
51
|
["test", "this"],
|
44
52
|
["test", "this", "split"],
|
45
53
|
["test", "this", "split", Usher::Route::Variable.new(:'.:', :format)]
|
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.
|
4
|
+
version: 0.3.0
|
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-04-
|
12
|
+
date: 2009-04-03 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -53,9 +53,9 @@ files:
|
|
53
53
|
- lib/usher/route
|
54
54
|
- lib/usher/route/path.rb
|
55
55
|
- lib/usher/route/request_method.rb
|
56
|
-
- lib/usher/route/splitter.rb
|
57
56
|
- lib/usher/route/variable.rb
|
58
57
|
- lib/usher/route.rb
|
58
|
+
- lib/usher/splitter.rb
|
59
59
|
- lib/usher.rb
|
60
60
|
- spec/generate_spec.rb
|
61
61
|
- spec/grapher_spec.rb
|