joshbuddy-usher 0.2.2 → 0.3.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/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
|