joshbuddy-usher 0.4.1 → 0.4.2
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 +20 -2
- data/VERSION.yml +1 -1
- data/lib/usher/interface/email_interface.rb +31 -0
- data/lib/usher/interface.rb +4 -0
- data/lib/usher/node.rb +7 -4
- data/lib/usher/route/variable.rb +3 -2
- data/lib/usher/splitter.rb +5 -6
- data/lib/usher.rb +35 -9
- data/spec/private/email/recognize_spec.rb +40 -0
- data/spec/private/split_spec.rb +16 -12
- metadata +5 -2
data/README.rdoc
CHANGED
@@ -43,9 +43,25 @@ However, <tt>/path/test/one_more/path</tt> would not be matched.
|
|
43
43
|
|
44
44
|
In the above examples, ['one', 'two', 'three'] and ['four', 'five'] respectively would be bound to the key :variable.
|
45
45
|
|
46
|
+
As well, variables can have a regex matcher.
|
47
|
+
|
48
|
+
<b>Example:</b>
|
49
|
+
<tt>/product/{:id,\d+}</tt> would match
|
50
|
+
|
51
|
+
* <tt>/product/123</tt>
|
52
|
+
* <tt>/product/4521</tt>
|
53
|
+
|
54
|
+
But not
|
55
|
+
* <tt>/product/AE-35</tt>
|
56
|
+
|
57
|
+
As well, the same logic applies for * variables as well, where only parts matchable by the supplied regex will
|
58
|
+
actually be bound to the variable
|
59
|
+
|
46
60
|
==== Static
|
47
61
|
|
48
62
|
Static parts of literal character sequences. For instance, <tt>/path/something.html</tt> would match only the same path.
|
63
|
+
As well, static parts can have a regex pattern in them as well, such as <tt>/path/something.{html|xml}</tt> which would match only
|
64
|
+
<tt>/path/something.html</tt> and <tt>/path/something.xml</tt>
|
49
65
|
|
50
66
|
==== Optional sections
|
51
67
|
|
@@ -53,12 +69,14 @@ Sections of a route can be marked as optional by surrounding it with brackets. F
|
|
53
69
|
|
54
70
|
==== One and only one sections
|
55
71
|
|
56
|
-
Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes.
|
72
|
+
Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes.
|
73
|
+
For instance, the path, <tt>/path/something(.xml|.html)</tt> would only match <tt>/path/something.xml</tt> and
|
74
|
+
<tt>/path/something.html</tt>. Generally its more efficent to use one and only sections over using regex.
|
57
75
|
|
58
76
|
=== +options+
|
59
77
|
* +transformers+ - Transforms a variable before it gets to the 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.
|
60
78
|
* +requirements+ - After transformation, tests the condition using ===. If it returns false, it raises an <tt>Usher::ValidationException</tt>
|
61
|
-
* +conditions+ - Accepts any of the
|
79
|
+
* +conditions+ - Accepts any of the +request_methods+ specificied in the construction of Usher. This can be either a <tt>string</tt> or a regular expression.
|
62
80
|
* Any other key is interpreted as a requirement for the variable of its name.
|
63
81
|
|
64
82
|
== Rails
|
data/VERSION.yml
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'rack_interface/route'
|
4
|
+
|
5
|
+
class Usher
|
6
|
+
module Interface
|
7
|
+
class EmailInterface
|
8
|
+
|
9
|
+
def initialize(&blk)
|
10
|
+
@routes = Usher.new(:delimiters => ['@', '-', '.'], :valid_regex => '[\+a-zA-Z0-9]+', :globs_capture_separators => true)
|
11
|
+
instance_eval(&blk) if blk
|
12
|
+
end
|
13
|
+
|
14
|
+
def for(path, &block)
|
15
|
+
@routes.add_route(path).to(block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def reset!
|
19
|
+
@routes.reset!
|
20
|
+
end
|
21
|
+
|
22
|
+
def act(email)
|
23
|
+
response = @routes.recognize(email, email)
|
24
|
+
if response.path
|
25
|
+
response.path.route.params.first.call(response.params.inject({}){|h,(k,v)| h[k]=v.to_s; h })
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/usher/interface.rb
CHANGED
@@ -5,6 +5,7 @@ class Usher
|
|
5
5
|
autoload :Rails2Interface, 'interface/rails2_interface'
|
6
6
|
autoload :MerbInterface, 'interface/merb_interface'
|
7
7
|
autoload :RackInterface, 'interface/rack_interface'
|
8
|
+
autoload :EmailInterface, 'interface/email_interface'
|
8
9
|
|
9
10
|
def self.for(type, &blk)
|
10
11
|
case type
|
@@ -14,7 +15,10 @@ class Usher
|
|
14
15
|
MerbInterface.new(&blk)
|
15
16
|
when :rack
|
16
17
|
RackInterface.new(&blk)
|
18
|
+
when :email
|
19
|
+
EmailInterface.new(&blk)
|
17
20
|
end
|
21
|
+
|
18
22
|
end
|
19
23
|
|
20
24
|
|
data/lib/usher/node.rb
CHANGED
@@ -9,7 +9,7 @@ class Usher
|
|
9
9
|
Response = Struct.new(:path, :params)
|
10
10
|
|
11
11
|
attr_reader :lookup
|
12
|
-
attr_accessor :terminates, :exclusive_type, :parent, :value, :request_methods
|
12
|
+
attr_accessor :terminates, :exclusive_type, :parent, :value, :request_methods, :globs_capture_separators
|
13
13
|
|
14
14
|
def initialize(parent, value)
|
15
15
|
@parent = parent
|
@@ -26,9 +26,10 @@ class Usher
|
|
26
26
|
@depth ||= @parent && @parent.is_a?(Node) ? @parent.depth + 1 : 0
|
27
27
|
end
|
28
28
|
|
29
|
-
def self.root(route_set, request_methods)
|
29
|
+
def self.root(route_set, request_methods, globs_capture_separators)
|
30
30
|
root = self.new(route_set, nil)
|
31
31
|
root.request_methods = request_methods
|
32
|
+
root.globs_capture_separators = globs_capture_separators
|
32
33
|
root
|
33
34
|
end
|
34
35
|
|
@@ -69,6 +70,8 @@ class Usher
|
|
69
70
|
current_node.lookup[nil] ||= Node.new(current_node, Route::RequestMethod.new(current_node.exclusive_type, nil))
|
70
71
|
end
|
71
72
|
else
|
73
|
+
key.globs_capture_separators = globs_capture_separators if key.is_a?(Route::Variable)
|
74
|
+
|
72
75
|
if !key.is_a?(Route::Variable)
|
73
76
|
current_node.upgrade_lookup if key.is_a?(Regexp)
|
74
77
|
current_node.lookup[key] ||= Node.new(current_node, key)
|
@@ -116,7 +119,7 @@ class Usher
|
|
116
119
|
path.unshift(next_part.parent.value) if next_part.parent.value.is_a?(Symbol)
|
117
120
|
break
|
118
121
|
else
|
119
|
-
unless part.is_a?(Symbol)
|
122
|
+
unless part.is_a?(Symbol) && !next_part.value.globs_capture_separators
|
120
123
|
part = next_part.value.transform!(part)
|
121
124
|
next_part.value.valid!(part)
|
122
125
|
params.last.last << part
|
@@ -152,7 +155,7 @@ class Usher
|
|
152
155
|
path.unshift(next_part.parent.value) if next_part.parent.value.is_a?(Symbol)
|
153
156
|
next_part.find(request, path, params)
|
154
157
|
else
|
155
|
-
unless part.is_a?(Symbol)
|
158
|
+
unless part.is_a?(Symbol) && !next_part.value.globs_capture_separators
|
156
159
|
part = next_part.value.transform!(part)
|
157
160
|
next_part.value.valid!(part)
|
158
161
|
params.last.last << part
|
data/lib/usher/route/variable.rb
CHANGED
@@ -2,14 +2,15 @@ class Usher
|
|
2
2
|
class Route
|
3
3
|
class Variable
|
4
4
|
attr_reader :type, :name, :validator, :transformer, :regex_matcher
|
5
|
-
attr_accessor :look_ahead
|
5
|
+
attr_accessor :look_ahead, :globs_capture_separators
|
6
6
|
|
7
|
-
def initialize(type, name, validator = nil, transformer = nil, regex_matcher = nil)
|
7
|
+
def initialize(type, name, validator = nil, transformer = nil, regex_matcher = nil, globs_capture_separators = false)
|
8
8
|
@type = type
|
9
9
|
@name = :"#{name}"
|
10
10
|
@validator = validator
|
11
11
|
@transformer = transformer
|
12
12
|
@regex_matcher = regex_matcher
|
13
|
+
@globs_capture_separators = globs_capture_separators
|
13
14
|
end
|
14
15
|
|
15
16
|
def to_s
|
data/lib/usher/splitter.rb
CHANGED
@@ -3,13 +3,12 @@ require 'strscan'
|
|
3
3
|
class Usher
|
4
4
|
class Splitter
|
5
5
|
|
6
|
-
def self.for_delimiters(delimiters)
|
6
|
+
def self.for_delimiters(delimiters, valid_regex)
|
7
7
|
delimiters_regex = delimiters.collect{|d| Regexp.quote(d)} * '|'
|
8
|
-
|
9
8
|
SplitterInstance.new(
|
10
9
|
delimiters,
|
11
|
-
Regexp.new('((:|\*)?
|
12
|
-
Regexp.new(delimiters_regex + '|
|
10
|
+
Regexp.new('((:|\*)?' + valid_regex + '|' + delimiters_regex + '|\(|\)|\||\{)'),
|
11
|
+
Regexp.new(delimiters_regex + '|' + valid_regex)
|
13
12
|
)
|
14
13
|
end
|
15
14
|
|
@@ -51,7 +50,7 @@ class Usher
|
|
51
50
|
type = part.slice!(0).chr.to_sym
|
52
51
|
current_group << Usher::Route::Variable.new(type, part, requirements && requirements[part.to_sym], transformers && transformers[part.to_sym])
|
53
52
|
when ?{
|
54
|
-
pattern = ''
|
53
|
+
pattern = '^'
|
55
54
|
count = 1
|
56
55
|
variable = ss.scan(/[:\*]([^,]+),/)
|
57
56
|
until count.zero?
|
@@ -64,7 +63,7 @@ class Usher
|
|
64
63
|
end
|
65
64
|
pattern << regex_part
|
66
65
|
end
|
67
|
-
pattern
|
66
|
+
pattern[pattern.size - 1] = ?$
|
68
67
|
regex = Regexp.new(pattern)
|
69
68
|
if variable
|
70
69
|
variable_type = variable.slice!(0).chr.to_sym
|
data/lib/usher.rb
CHANGED
@@ -31,7 +31,7 @@ class Usher
|
|
31
31
|
# set.reset!
|
32
32
|
# set.empty? => true
|
33
33
|
def reset!
|
34
|
-
@tree = Node.root(self, @request_methods)
|
34
|
+
@tree = Node.root(self, @request_methods, @globs_capture_separators)
|
35
35
|
@named_routes = {}
|
36
36
|
@routes = []
|
37
37
|
@route_count = 0
|
@@ -39,16 +39,24 @@ class Usher
|
|
39
39
|
end
|
40
40
|
alias clear! reset!
|
41
41
|
|
42
|
-
# Creates a route set, with
|
42
|
+
# Creates a route set, with options
|
43
43
|
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
44
|
+
# <tt>:globs_capture_separators</tt>: +true+ or +false+. (default +false+) Specifies whether glob matching will also include separators
|
45
|
+
# that are matched.
|
46
|
+
#
|
47
|
+
# <tt>:delimiters</tt>: Array of Strings. (default <tt>['/', '.']</tt>). Delimiters used in path separation. Array must be single character strings.
|
48
|
+
#
|
49
|
+
# <tt>:valid_regex</tt>: String. (default <tt>'[0-9A-Za-z\$\-_\+!\*\',]+'</tt>). String that can be interpolated into regex to match
|
50
|
+
# valid character sequences within path.
|
51
|
+
#
|
52
|
+
# <tt>:request_methods</tt>: Array of Symbols. (default <tt>[:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]</tt>)
|
53
|
+
# Array of methods called against the request object for the purposes of matching route requirements.
|
48
54
|
def initialize(options = nil)
|
49
|
-
@
|
55
|
+
@globs_capture_separators = options && options.key?(:globs_capture_separators) ? options.delete(:globs_capture_separators) : false
|
56
|
+
@delimiters = options && options.delete(:delimiters) || ['/', '.']
|
57
|
+
@valid_regex = options && options.delete(:valid_regex) || '[0-9A-Za-z\$\-_\+!\*\',]+'
|
50
58
|
@request_methods = options && options.delete(:request_methods) || [:protocol, :domain, :port, :query_string, :remote_ip, :user_agent, :referer, :method, :subdomains]
|
51
|
-
@splitter = Splitter.for_delimiters(@delimiters)
|
59
|
+
@splitter = Splitter.for_delimiters(@delimiters, @valid_regex)
|
52
60
|
reset!
|
53
61
|
end
|
54
62
|
|
@@ -96,9 +104,25 @@ class Usher
|
|
96
104
|
#
|
97
105
|
# In the above examples, ['one', 'two', 'three'] and ['four', 'five'] respectively would be bound to the key :variable.
|
98
106
|
#
|
107
|
+
# As well, variables can have a regex matcher.
|
108
|
+
#
|
109
|
+
# <b>Example:</b>
|
110
|
+
# <tt>/product/{:id,\d+}</tt> would match
|
111
|
+
#
|
112
|
+
# * <tt>/product/123</tt>
|
113
|
+
# * <tt>/product/4521</tt>
|
114
|
+
#
|
115
|
+
# But not
|
116
|
+
# * <tt>/product/AE-35</tt>
|
117
|
+
#
|
118
|
+
# As well, the same logic applies for * variables as well, where only parts matchable by the supplied regex will
|
119
|
+
# actually be bound to the variable
|
120
|
+
#
|
99
121
|
# ==== Static
|
100
122
|
#
|
101
123
|
# Static parts of literal character sequences. For instance, <tt>/path/something.html</tt> would match only the same path.
|
124
|
+
# As well, static parts can have a regex pattern in them as well, such as <tt>/path/something.{html|xml}</tt> which would match only
|
125
|
+
# <tt>/path/something.html</tt> and <tt>/path/something.xml</tt>
|
102
126
|
#
|
103
127
|
# ==== Optional sections
|
104
128
|
#
|
@@ -106,7 +130,9 @@ class Usher
|
|
106
130
|
#
|
107
131
|
# ==== One and only one sections
|
108
132
|
#
|
109
|
-
# Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes.
|
133
|
+
# Sections of a route can be marked as "one and only one" by surrounding it with brackets and separating parts of the route with pipes.
|
134
|
+
# For instance, the path, <tt>/path/something(.xml|.html)</tt> would only match <tt>/path/something.xml</tt> and
|
135
|
+
# <tt>/path/something.html</tt>. Generally its more efficent to use one and only sections over using regex.
|
110
136
|
#
|
111
137
|
# === +options+
|
112
138
|
# * +transformers+ - Transforms a variable before it gets to the 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.
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'lib/usher'
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
def build_email_mock(email)
|
6
|
+
request = mock "Request"
|
7
|
+
request.should_receive(:email).any_number_of_times.and_return(email)
|
8
|
+
request
|
9
|
+
end
|
10
|
+
|
11
|
+
SampleController = Object.new
|
12
|
+
|
13
|
+
describe "Usher (for email) route recognition" do
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@route_set = Usher::Interface.for(:email)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should recognize a simple request" do
|
20
|
+
receiver = mock('receiver')
|
21
|
+
receiver.should_receive(:action).with({}).exactly(1)
|
22
|
+
@route_set.for('joshbuddy@gmail.com') { |params| receiver.action(params) }
|
23
|
+
@route_set.act('joshbuddy@gmail.com')
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should recognize a wildcard domain" do
|
27
|
+
receiver = mock('receiver')
|
28
|
+
receiver.should_receive(:action).with({:domain => 'gmail.com'}).exactly(1)
|
29
|
+
@route_set.for('joshbuddy@*domain') { |params| receiver.action(params) }
|
30
|
+
@route_set.act('joshbuddy@gmail.com')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should recognize a complex email" do
|
34
|
+
receiver = mock('receiver')
|
35
|
+
receiver.should_receive(:action).with({:subject => 'sub+ect', :id => '123', :sid => '456', :tok => 'sdqwe123ae', :domain => 'mydomain.org'}).exactly(1)
|
36
|
+
@route_set.for(':subject.{:id,^\d+$}-{:sid,^\d+$}-{:tok,^\w+$}@*domain') { |params| receiver.action(params) }
|
37
|
+
@route_set.act('sub+ect.123-456-sdqwe123ae@mydomain.org')
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/spec/private/split_spec.rb
CHANGED
@@ -4,38 +4,42 @@ describe "Usher route tokenizing" do
|
|
4
4
|
|
5
5
|
|
6
6
|
it "should split / delimited routes" do
|
7
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this/split').should == [[:/, 'test', :/,'this', :/, 'split']]
|
7
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this/split').should == [[:/, 'test', :/,'this', :/, 'split']]
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should split / delimited routes with a regex in it" do
|
11
|
-
Usher::Splitter.for_delimiters(['/', '.']).
|
12
|
-
split('/test/{this}/split').should == [[:/, 'test', :/,
|
11
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').
|
12
|
+
split('/test/{this}/split').should == [[:/, 'test', :/, /^this$/, :/, 'split']]
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should split on ' ' delimited routes as well" do
|
16
|
-
Usher::Splitter.for_delimiters([' ']).split('test this split').should == [['test', :' ', 'this', :' ', 'split']]
|
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"]]
|
17
21
|
end
|
18
22
|
|
19
23
|
it "should split on ' ' delimited routes for more complex routes as well" do
|
20
|
-
Usher::Splitter.for_delimiters([' ']).split('(test|this) split').should == [['test', :' ', 'split'], ['this', :' ', 'split']]
|
24
|
+
Usher::Splitter.for_delimiters([' '], '[0-9A-Za-z\$\-_\+!\*\',]+').split('(test|this) split').should == [['test', :' ', 'split'], ['this', :' ', 'split']]
|
21
25
|
end
|
22
26
|
|
23
27
|
it "should group optional parts with brackets" do
|
24
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split)').should == [
|
28
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split)').should == [
|
25
29
|
[:/, 'test', :/, 'this'],
|
26
30
|
[:/, 'test', :/, 'this', :/, 'split']
|
27
31
|
]
|
28
32
|
end
|
29
33
|
|
30
34
|
it "should group exclusive optional parts with brackets and pipes" do
|
31
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split|/split2)').should == [
|
35
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split|/split2)').should == [
|
32
36
|
[:/, 'test', :/, 'this',:/, 'split'],
|
33
37
|
[:/, 'test', :/, 'this',:/, 'split2']
|
34
38
|
]
|
35
39
|
end
|
36
40
|
|
37
41
|
it "should group exclusive optional-optional parts with brackets and pipes" do
|
38
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this((/split|/split2))').should == [
|
42
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this((/split|/split2))').should == [
|
39
43
|
[:/, 'test',:/, 'this'],
|
40
44
|
[:/, 'test',:/, 'this', :/, 'split'],
|
41
45
|
[:/, 'test',:/, 'this', :/, 'split2']
|
@@ -43,7 +47,7 @@ describe "Usher route tokenizing" do
|
|
43
47
|
end
|
44
48
|
|
45
49
|
it "should group optional parts with brackets (for non overlapping groups)" do
|
46
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split)(/split2)') == [
|
50
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split)(/split2)') == [
|
47
51
|
[:/, "test", :/, "this"],
|
48
52
|
[:/, "test", :/, "this", :/, "split"],
|
49
53
|
[:/, "test", :/, "this", :/, "split2"],
|
@@ -52,7 +56,7 @@ describe "Usher route tokenizing" do
|
|
52
56
|
end
|
53
57
|
|
54
58
|
it "should group nested-optional parts with brackets" do
|
55
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/test/this(/split(.:format))') == [
|
59
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/test/this(/split(.:format))') == [
|
56
60
|
[:/, "test", :/, "this"],
|
57
61
|
[:/, "test", :/, "this", :/, "split"],
|
58
62
|
[:/, "test", :/, "this", :/, "split", :'.', Usher::Route::Variable.new(:':', :format)]
|
@@ -60,12 +64,12 @@ describe "Usher route tokenizing" do
|
|
60
64
|
end
|
61
65
|
|
62
66
|
it "should to_s all different variable types" do
|
63
|
-
Usher::Splitter.for_delimiters(['/', '.']).split('/:split/*splitter').first.collect{|v| v.to_s} ==
|
67
|
+
Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/:split/*splitter').first.collect{|v| v.to_s} ==
|
64
68
|
[ ':split', '*splitter' ]
|
65
69
|
end
|
66
70
|
|
67
71
|
it "should == variable types" do
|
68
|
-
parts = Usher::Splitter.for_delimiters(['/', '.']).split('/:split/:split').first
|
72
|
+
parts = Usher::Splitter.for_delimiters(['/', '.'], '[0-9A-Za-z\$\-_\+!\*\',]+').split('/:split/:split').first
|
69
73
|
parts[1].should == parts[3]
|
70
74
|
end
|
71
75
|
|
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.
|
4
|
+
version: 0.4.2
|
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-05-
|
12
|
+
date: 2009-05-11 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -40,6 +40,7 @@ files:
|
|
40
40
|
- lib/usher/exceptions.rb
|
41
41
|
- lib/usher/grapher.rb
|
42
42
|
- lib/usher/interface
|
43
|
+
- lib/usher/interface/email_interface.rb
|
43
44
|
- lib/usher/interface/merb_interface.rb
|
44
45
|
- lib/usher/interface/rack_interface
|
45
46
|
- lib/usher/interface/rack_interface/mapper.rb
|
@@ -58,6 +59,8 @@ files:
|
|
58
59
|
- lib/usher/splitter.rb
|
59
60
|
- lib/usher.rb
|
60
61
|
- spec/private
|
62
|
+
- spec/private/email
|
63
|
+
- spec/private/email/recognize_spec.rb
|
61
64
|
- spec/private/generate_spec.rb
|
62
65
|
- spec/private/grapher_spec.rb
|
63
66
|
- spec/private/path_spec.rb
|