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.
@@ -1,4 +1,4 @@
1
1
  ---
2
- :minor: 2
3
- :patch: 2
4
2
  :major: 0
3
+ :minor: 3
4
+ :patch: 0
@@ -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.
@@ -1,7 +1,5 @@
1
1
  class Usher
2
2
  class UnrecognizedException < RuntimeError; end
3
- class ValidationException < RuntimeError
4
-
5
- end
3
+ class ValidationException < RuntimeError; end
6
4
  class MissingParameterException < RuntimeError; end
7
5
  end
@@ -21,14 +21,7 @@ class Usher
21
21
  end
22
22
 
23
23
  def depth
24
- unless @depth
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 = Route::Splitter.url_split(request.path), params = [])
99
+ def find(request, path, params = [])
107
100
  part = path.shift unless path.size.zero?
108
101
 
109
102
  if @exclusive_type
@@ -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 = Splitter.new(@original_path, @requirements, @transformers).paths.collect {|path| Path.new(self, path)}
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 Route
5
- class Splitter
6
-
7
- ScanRegex = /((:|\*||\.:|\.)[0-9A-Za-z\$\-_\+!\*',]+|\/|\(|\)|\|)/
8
- UrlScanRegex = /\/|\.?[0-9A-Za-z\$\-_\+!\*',]+/
9
-
10
- attr_reader :paths
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(path, requirements = {}, transformers = {})
13
- @parts = Splitter.split(path, requirements, transformers)
14
- @paths = calc_paths(@parts)
15
- @paths
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 self.url_split(path)
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(UrlScanRegex)
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 self.split(path, requirements = {}, transformers = {})
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(ScanRegex)
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
- class Group < Array
104
- attr_accessor :type
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
@@ -4,25 +4,33 @@ describe "Usher route tokenizing" do
4
4
 
5
5
 
6
6
  it "should split / delimited routes" do
7
- Usher::Route::Splitter.new('/test/this/split').paths.first.should == ['test', 'this', 'split']
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::Route::Splitter.new('/test/this(/split)').paths.should == [
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::Route::Splitter.new('/test/this(/split|/split2)').paths.should == [
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::Route::Splitter.new('/test/this((/split|/split2))').paths.should == [
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::Route::Splitter.new('/test/this(/split)(/split2)').paths == [
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::Route::Splitter.new('/test/this(/split(.:format))').paths == [
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.2.2
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-02 00:00:00 -07:00
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