usher 0.4.8 → 0.5.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/README.rdoc +12 -1
- data/Rakefile +5 -29
- data/VERSION.yml +2 -2
- data/lib/usher.rb +126 -37
- data/lib/usher/grapher.rb +5 -4
- data/lib/usher/interface.rb +12 -5
- data/lib/usher/interface/email_interface.rb +1 -1
- data/lib/usher/interface/rack_interface.rb +31 -13
- data/lib/usher/interface/rails2_2_interface.rb +3 -4
- data/lib/usher/interface/rails2_3_interface.rb +3 -4
- data/lib/usher/interface/rails3_interface.rb +57 -0
- data/lib/usher/node.rb +121 -73
- data/lib/usher/route.rb +45 -11
- data/lib/usher/route/path.rb +50 -11
- data/lib/usher/route/util.rb +65 -0
- data/lib/usher/route/variable.rb +22 -11
- data/lib/usher/splitter.rb +4 -141
- data/lib/usher/util.rb +6 -0
- data/lib/usher/util/generate.rb +129 -0
- data/lib/usher/util/parser.rb +145 -0
- data/spec/private/email/recognize_spec.rb +2 -4
- data/spec/private/generate_spec.rb +86 -32
- data/spec/private/grapher_spec.rb +5 -6
- data/spec/private/parser_spec.rb +75 -0
- data/spec/private/path_spec.rb +35 -4
- data/spec/private/rack/dispatch_spec.rb +100 -15
- data/spec/private/recognize_spec.rb +88 -50
- data/spec/spec_helper.rb +22 -0
- metadata +13 -7
- data/lib/usher/generate.rb +0 -131
- data/spec/private/split_spec.rb +0 -76
data/lib/usher/generate.rb
DELETED
@@ -1,131 +0,0 @@
|
|
1
|
-
require 'rack'
|
2
|
-
|
3
|
-
unless Rack::Utils.respond_to?(:uri_escape)
|
4
|
-
module Rack
|
5
|
-
|
6
|
-
module Utils
|
7
|
-
|
8
|
-
def uri_escape(s)
|
9
|
-
s.to_s.gsub(/([^:\/?\[\]\-_~\.!\$&'\(\)\*\+,;=@a-zA-Z0-9]+)/n) {
|
10
|
-
'%'<<$1.unpack('H2'*$1.size).join('%').upcase
|
11
|
-
}.tr(' ', '+')
|
12
|
-
end
|
13
|
-
module_function :uri_escape
|
14
|
-
|
15
|
-
def uri_unescape(s)
|
16
|
-
gsub(/((?:%[0-9a-fA-F]{2})+)/n){
|
17
|
-
[$1.delete('%')].pack('H*')
|
18
|
-
}
|
19
|
-
end
|
20
|
-
module_function :uri_unescape
|
21
|
-
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class Usher
|
27
|
-
class Generators
|
28
|
-
|
29
|
-
class URL
|
30
|
-
|
31
|
-
def initialize(usher)
|
32
|
-
@usher = usher
|
33
|
-
end
|
34
|
-
|
35
|
-
def generate_full(routing_lookup, request, params = nil)
|
36
|
-
path = path_for_routing_lookup(routing_lookup, params)
|
37
|
-
result = generate_start(path, request)
|
38
|
-
result << generate_path(path, params)
|
39
|
-
end
|
40
|
-
|
41
|
-
def generate(routing_lookup, params = nil)
|
42
|
-
generate_path(path_for_routing_lookup(routing_lookup, params), params)
|
43
|
-
end
|
44
|
-
|
45
|
-
def generate_start(path, request)
|
46
|
-
result = (path.route.generate_with && path.route.generate_with.scheme || request.scheme).dup
|
47
|
-
result << '://'
|
48
|
-
result << (path.route.generate_with && path.route.generate_with.host) ? path.route.generate_with.host : request.host
|
49
|
-
port = path.route.generate_with && path.route.generate_with.port || request.port
|
50
|
-
if result[4] == ?s
|
51
|
-
result << ':' << port.to_s if port != 443
|
52
|
-
else
|
53
|
-
result << ':' << port.to_s if port != 80
|
54
|
-
end
|
55
|
-
result
|
56
|
-
end
|
57
|
-
|
58
|
-
def path_for_routing_lookup(routing_lookup, params)
|
59
|
-
path = case routing_lookup
|
60
|
-
when Symbol
|
61
|
-
route = @usher.named_routes[routing_lookup]
|
62
|
-
params.is_a?(Hash) ? route.find_matching_path(params) : route.paths.first
|
63
|
-
when Route
|
64
|
-
params.is_a?(Hash) ? routing_lookup.find_matching_path(params) : routing_lookup.paths.first
|
65
|
-
when nil
|
66
|
-
params.is_a?(Hash) ? @usher.path_for_options(params) : raise
|
67
|
-
when Route::Path
|
68
|
-
routing_lookup
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
# Generates a completed URL based on a +route+ or set of optional +params+
|
73
|
-
#
|
74
|
-
# set = Usher.new
|
75
|
-
# route = set.add_named_route(:test_route, '/:controller/:action')
|
76
|
-
# set.generate_url(nil, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
77
|
-
# set.generate_url(:test_route, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
78
|
-
# set.generate_url(route.primary_path, {:controller => 'c', :action => 'a'}) == '/c/a' => true
|
79
|
-
def generate_path(path, params = nil)
|
80
|
-
raise UnrecognizedException.new unless path
|
81
|
-
|
82
|
-
params = Array(params) if params.is_a?(String)
|
83
|
-
if params.is_a?(Array)
|
84
|
-
given_size = params.size
|
85
|
-
extra_params = params.last.is_a?(Hash) ? params.pop : nil
|
86
|
-
params = Hash[*path.dynamic_parts.inject([]){|a, dynamic_part| a.concat([dynamic_part.name, params.shift || raise(MissingParameterException.new("got #{given_size}, expected #{path.dynamic_parts.size} parameters"))]); a}]
|
87
|
-
params.merge!(extra_params) if extra_params
|
88
|
-
end
|
89
|
-
|
90
|
-
result = ''
|
91
|
-
path.parts.each do |part|
|
92
|
-
case part
|
93
|
-
when Route::Variable
|
94
|
-
value = (params && params.delete(part.name)) || part.default_value || raise(MissingParameterException.new)
|
95
|
-
case part.type
|
96
|
-
when :*
|
97
|
-
value.each_with_index do |current_value, index|
|
98
|
-
current_value = current_value.to_s unless current_value.is_a?(String)
|
99
|
-
part.valid!(current_value)
|
100
|
-
result << current_value
|
101
|
-
result << '/' if index != value.size - 1
|
102
|
-
end
|
103
|
-
when :':'
|
104
|
-
value = value.to_s unless value.is_a?(String)
|
105
|
-
part.valid!(value)
|
106
|
-
result << value
|
107
|
-
end
|
108
|
-
else
|
109
|
-
result << part
|
110
|
-
end
|
111
|
-
end
|
112
|
-
result = Rack::Utils.uri_escape(result)
|
113
|
-
|
114
|
-
if params && !params.empty?
|
115
|
-
has_query = result[??]
|
116
|
-
params.each do |k,v|
|
117
|
-
case v
|
118
|
-
when Array
|
119
|
-
v.each do |v_part|
|
120
|
-
result << (has_query ? '&' : has_query = true && '?') << Rack::Utils.escape("#{k.to_s}[]") << '=' << Rack::Utils.escape(v_part.to_s)
|
121
|
-
end
|
122
|
-
else
|
123
|
-
result << (has_query ? '&' : has_query = true && '?') << Rack::Utils.escape(k.to_s) << '=' << Rack::Utils.escape(v.to_s)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
result
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
data/spec/private/split_spec.rb
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
require 'lib/usher'
|
2
|
-
|
3
|
-
describe "Usher route tokenizing" do
|
4
|
-
|
5
|
-
|
6
|
-
it "should split / delimited routes" do
|
7
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this/split').should == [['/', 'test', '/','this', '/', 'split']]
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should split / delimited routes with a regex in it" do
|
11
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').
|
12
|
-
split('/test/{this}/split').should == [['/', 'test', '/', /this/, '/', 'split']]
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should split on ' ' delimited routes as well" do
|
16
|
-
Usher::Splitter.for_delimiters([' '], '[0-9A-Za-z\$\-_\+!\*\',]+').split('test this split').should == [['test', ' ', 'this', ' ', 'split']]
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should split on email delimiters as well" do
|
20
|
-
Usher::Splitter.for_delimiters(['@', '+', '-', '.'], '[a-zA-Z0-9]+').split('one+more.12345-09876-alphanum3ric5@domain.com').should == [["one", '+', "more", ".", "12345", '-', "09876", '-', "alphanum3ric5", "@", "domain", ".", "com"]]
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should split on ' ' delimited routes for more complex routes as well" do
|
24
|
-
Usher::Splitter.for_delimiters([' '], '[0-9A-Za-z\$\-_\+!\*\',]+').split('(test|this) split').should == [['test', ' ', 'split'], ['this', ' ', 'split']]
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should group optional parts with brackets" do
|
28
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split)').should == [
|
29
|
-
['/', 'test', '/', 'this'],
|
30
|
-
['/', 'test', '/', 'this', '/', 'split']
|
31
|
-
]
|
32
|
-
end
|
33
|
-
|
34
|
-
it "should group exclusive optional parts with brackets and pipes" do
|
35
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split|/split2)').should == [
|
36
|
-
['/', 'test', '/', 'this','/', 'split'],
|
37
|
-
['/', 'test', '/', 'this','/', 'split2']
|
38
|
-
]
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should group exclusive optional-optional parts with brackets and pipes" do
|
42
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this((/split|/split2))').should == [
|
43
|
-
['/', 'test','/', 'this'],
|
44
|
-
['/', 'test','/', 'this', '/', 'split'],
|
45
|
-
['/', 'test','/', 'this', '/', 'split2']
|
46
|
-
]
|
47
|
-
end
|
48
|
-
|
49
|
-
it "should group optional parts with brackets (for non overlapping groups)" do
|
50
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split)(/split2)') == [
|
51
|
-
['/', "test", '/', "this"],
|
52
|
-
['/', "test", '/', "this", '/', "split"],
|
53
|
-
['/', "test", '/', "this", '/', "split2"],
|
54
|
-
['/', "test", '/', "this", '/', "split", '/', "split2"]
|
55
|
-
]
|
56
|
-
end
|
57
|
-
|
58
|
-
it "should group nested-optional parts with brackets" do
|
59
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split(.:format))') == [
|
60
|
-
['/', "test", '/', "this"],
|
61
|
-
['/', "test", '/', "this", '/', "split"],
|
62
|
-
['/', "test", '/', "this", '/', "split", '.', Usher::Route::Variable.new(:':', :format)]
|
63
|
-
]
|
64
|
-
end
|
65
|
-
|
66
|
-
it "should to_s all different variable types" do
|
67
|
-
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/:split/*splitter').first.collect{|v| v.to_s} ==
|
68
|
-
[ ':split', '*splitter' ]
|
69
|
-
end
|
70
|
-
|
71
|
-
it "should == variable types" do
|
72
|
-
parts = Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/:split/:split').first
|
73
|
-
parts[1].should == parts[3]
|
74
|
-
end
|
75
|
-
|
76
|
-
end
|