pendragon 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96b558eec1e2524045fcd153be5bca8bb159ffdd
4
- data.tar.gz: b2411809a3ccb47d6d9a46c162c9611b9bddffbf
3
+ metadata.gz: 50f2cc54ef1c804fa05b8de3a47d6bf731e86f8f
4
+ data.tar.gz: 90c08c4129ae507b429d35487ff7824a37ad424e
5
5
  SHA512:
6
- metadata.gz: 7152a62fffeb920032d0ee6699183c662e18aa138567e638506fd8d6158d53aa47884b9b971c3ceadaa693380204c5b9f8c3d037891be37cdf01c5a4801f47bb
7
- data.tar.gz: 8a7dcf1502c0b4b9febec24efd7f96aff8f0f644d492a44f0883cd7b0da562014ccf6c089f07d5f351c67b98dc4cb1267d9f96c37d672801a66ce5df5f9c7158
6
+ metadata.gz: cf8e88346a526a08c48e63db31f861d4b401754bcaea842e0ac0ce6446e241a0cf51b87d2c61ff6f1dcbf29c4e10d975a078fa31f9413881b578c60845a53a41
7
+ data.tar.gz: 070bc4ce928f628ba6f22260e42f05087ee96caccba81c0084a3ccf5fe7491cfa94aebaf7f695a539ef26c9a86944313e0674dd23c9240e255fa23b05bc5e922
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pendragon (0.4.0)
4
+ pendragon (0.5.1)
5
5
  mustermann (= 0.2.0)
6
6
  rack (>= 1.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (4.1.1)
11
+ activesupport (4.1.4)
12
12
  i18n (~> 0.6, >= 0.6.9)
13
13
  json (~> 1.7, >= 1.7.7)
14
14
  minitest (~> 5.1)
@@ -19,20 +19,53 @@ GEM
19
19
  http_router (0.11.1)
20
20
  rack (>= 1.0.0)
21
21
  url_mount (~> 0.2.1)
22
- i18n (0.6.9)
22
+ i18n (0.6.11)
23
23
  json (1.8.1)
24
+ mail (2.5.4)
25
+ mime-types (~> 1.16)
26
+ treetop (~> 1.4.8)
24
27
  metaclass (0.0.4)
25
- minitest (5.3.4)
28
+ mime-types (1.25.1)
29
+ minitest (5.4.0)
26
30
  mocha (1.1.0)
27
31
  metaclass (~> 0.0.1)
32
+ moneta (0.7.20)
28
33
  mustermann (0.2.0)
29
- padrino-core (0.12.0.rc3)
34
+ padrino (0.12.2)
35
+ padrino-admin (= 0.12.2)
36
+ padrino-cache (= 0.12.2)
37
+ padrino-core (= 0.12.2)
38
+ padrino-gen (= 0.12.2)
39
+ padrino-helpers (= 0.12.2)
40
+ padrino-mailer (= 0.12.2)
41
+ padrino-support (= 0.12.2)
42
+ padrino-admin (0.12.2)
43
+ padrino-core (= 0.12.2)
44
+ padrino-helpers (= 0.12.2)
45
+ padrino-cache (0.12.2)
46
+ moneta (~> 0.7.0)
47
+ padrino-core (= 0.12.2)
48
+ padrino-helpers (= 0.12.2)
49
+ padrino-core (0.12.2)
30
50
  activesupport (>= 3.1)
31
51
  http_router (~> 0.11.0)
52
+ padrino-support (= 0.12.2)
32
53
  rack-protection (>= 1.5.0)
33
54
  sinatra (~> 1.4.2)
34
- thor (~> 0.17.0)
55
+ thor (~> 0.18.0)
56
+ padrino-gen (0.12.2)
57
+ bundler (~> 1.0)
58
+ padrino-core (= 0.12.2)
59
+ padrino-helpers (0.12.2)
60
+ i18n (~> 0.6, >= 0.6.7)
61
+ padrino-support (= 0.12.2)
35
62
  tilt (~> 1.4.1)
63
+ padrino-mailer (0.12.2)
64
+ mail (~> 2.5.3)
65
+ padrino-core (= 0.12.2)
66
+ padrino-support (0.12.2)
67
+ activesupport (>= 3.1)
68
+ polyglot (0.3.5)
36
69
  rack (1.5.2)
37
70
  rack-protection (1.5.3)
38
71
  rack
@@ -43,10 +76,13 @@ GEM
43
76
  rack (~> 1.4)
44
77
  rack-protection (~> 1.4)
45
78
  tilt (~> 1.3, >= 1.3.4)
46
- thor (0.17.0)
47
- thread_safe (0.3.3)
79
+ thor (0.18.1)
80
+ thread_safe (0.3.4)
48
81
  tilt (1.4.1)
49
- tzinfo (1.1.0)
82
+ treetop (1.4.15)
83
+ polyglot
84
+ polyglot (>= 0.3.1)
85
+ tzinfo (1.2.1)
50
86
  thread_safe (~> 0.1)
51
87
  url_mount (0.2.1)
52
88
  rack
@@ -57,7 +93,7 @@ PLATFORMS
57
93
  DEPENDENCIES
58
94
  haml
59
95
  mocha (>= 0.10.0)
60
- padrino-core (= 0.12.0.rc3)
96
+ padrino (~> 0.12.2)
61
97
  pendragon!
62
98
  rack-test (>= 0.5.0)
63
99
  rake (>= 0.8.7)
data/README.md CHANGED
@@ -73,7 +73,7 @@ pendragon = Pendragon.new do |config|
73
73
  end
74
74
  ```
75
75
 
76
- ### Register the route
76
+ ### Register a route
77
77
 
78
78
  It has some methods to register a route. For example, `#get`, `#post` and `#delete` are so.
79
79
  This section introduces all those methods.
@@ -1,7 +1,10 @@
1
1
  module Pendragon
2
+ # A class for configuration of Pendragon
3
+ # @!visibility private
2
4
  class Configuration
3
-
4
- # Define the accessor as boolean method
5
+ # Defines an accessor as boolean method
6
+ # @example
7
+ # attr_boolean_accessor :accessor_name
5
8
  def self.attr_boolean_accessor(*keys)
6
9
  keys.each do |key|
7
10
  attr_accessor key
@@ -15,8 +18,9 @@ module Pendragon
15
18
  # @see Pendragon::Router#compile
16
19
  attr_boolean_accessor :enable_compiler
17
20
 
18
- # Automatically convert response into Rack format.
21
+ # Automatically converts response into Rack format.
19
22
  # Default value is `true`.
23
+ # @see Pendragon::Router#invoke
20
24
  attr_boolean_accessor :auto_rack_format
21
25
 
22
26
  # Constructs an instance of Pendragon::Configuration
@@ -1,11 +1,23 @@
1
1
  require 'pendragon/engine/recognizer'
2
2
 
3
3
  module Pendragon
4
+ # One of the engine classes for recognizing routes
5
+ # This engine will perform better than the recognizer engine
6
+ #
7
+ # @example
8
+ # Pendragon.new do |config|
9
+ # config.enable_compiler = true
10
+ # end
11
+ #
12
+ # @!visibility private
4
13
  class Compiler < Recognizer
5
- def initialize(routes)
6
- @routes = routes
7
- end
8
-
14
+ # Concatenates all routes, recognizes routes matched with pattern, and returns them
15
+ # @overload call
16
+ # @param [Rack::Request] request
17
+ # @raise [Pendragon::BadRequest] raised if request is bad request
18
+ # @raise [Pendragon::NotFound] raised if cannot find routes that match with pattern
19
+ # @raise [Pendragon::MethodNotAllowed] raised if routes can be find and do not match with verb
20
+ # @return [Array] The return value will be something like [Pendragon::Route, Hash]
9
21
  def call(request)
10
22
  compile! unless compiled?
11
23
  pattern, verb, params = parse_request(request)
@@ -17,8 +29,7 @@ module Pendragon
17
29
  candidacies.map{|route| [route, params_for(route, pattern, params)]}
18
30
  end
19
31
 
20
- private
21
-
32
+ # @!visibility private
22
33
  def compile!
23
34
  return if compiled?
24
35
  @regexps = @routes.map.with_index do |route, index|
@@ -30,6 +41,7 @@ module Pendragon
30
41
  @regexps = compile(@regexps)
31
42
  end
32
43
 
44
+ # @!visibility private
33
45
  def compile(regexps, paths = [])
34
46
  return paths if regexps.length.zero?
35
47
  paths << Regexp.union(regexps)
@@ -37,14 +49,16 @@ module Pendragon
37
49
  compile(regexps, paths)
38
50
  end
39
51
 
52
+ # @!visibility private
40
53
  def compiled?
41
54
  !!@regexps
42
55
  end
43
56
 
57
+ # @!visibility private
44
58
  def match_with(pattern)
45
59
  offset = 0
46
60
  conditions = [pattern]
47
- conditions << pattern[0..-2] if pattern != "/" && pattern.end_with?("/")
61
+ conditions << pattern[0..-2] if pattern != Matcher::PATH_DELIMITER && pattern.end_with?(Matcher::PATH_DELIMITER)
48
62
  loop.with_object([]) do |_, candidacies|
49
63
  return candidacies unless conditions.any?{|x| @regexps[offset] === x }
50
64
  route = @routes[offset..-1].detect{|route| Regexp.last_match("_#{route.index}") }
@@ -52,5 +66,7 @@ module Pendragon
52
66
  offset = route.index + 1
53
67
  end
54
68
  end
69
+
70
+ private :compile!, :compile, :compiled?, :match_with
55
71
  end
56
72
  end
@@ -1,17 +1,29 @@
1
1
  module Pendragon
2
+ # One of the engine classes for recognizing routes
3
+ # @!visibility private
2
4
  class Recognizer
5
+ # The keys for rack headers
6
+ PATH_INFO = "PATH_INFO".freeze
7
+ REQUEST_METHOD = "REQUEST_METHOD".freeze
8
+
9
+ # Constructs an instance of Pendragon::Recognizer
10
+ # @param [Array<Pendragon::Route>] routes
3
11
  def initialize(routes)
4
12
  @routes = routes
5
13
  end
6
14
 
15
+ # Recognized routes, and returns them
16
+ # @param [Rack::Request] request
17
+ # @raise [Pendragon::BadRequest] raised if request is bad request
18
+ # @raise [Pendragon::NotFound] raised if cannot find routes that match with pattern
19
+ # @raise [Pendragon::MethodNotAllowed] raised if routes can be find and do not match with verb
20
+ # @return [Array] The return value will be something like [Pendragon::Route, Hash]
7
21
  def call(request)
8
22
  pattern, verb, params = parse_request(request)
9
23
  raise_exception(400) unless valid_verb?(verb)
10
24
  fetch(pattern, verb){|route| [route, params_for(route, pattern, params)] }
11
25
  end
12
26
 
13
- private
14
-
15
27
  # @!visibility private
16
28
  def params_for(route, pattern, params)
17
29
  route.params(pattern, params)
@@ -19,7 +31,7 @@ module Pendragon
19
31
 
20
32
  # @!visibility private
21
33
  def valid_verb?(verb)
22
- Pendragon::HTTP_VERBS.include?(verb.downcase.to_sym)
34
+ Pendragon::HTTP_VERBS.include?(verb)
23
35
  end
24
36
 
25
37
  # @!visibility private
@@ -34,17 +46,9 @@ module Pendragon
34
46
  # @!visibility private
35
47
  def parse_request(request)
36
48
  if request.is_a?(Hash)
37
- [request['PATH_INFO'], request['REQUEST_METHOD'].downcase.to_sym, {}]
49
+ [request[PATH_INFO], request[REQUEST_METHOD].upcase, {}]
38
50
  else
39
- [request.path_info, request.request_method.downcase.to_sym, parse_request_params(request.params)]
40
- end
41
- end
42
-
43
- # @!visibility private
44
- def parse_request_params(params)
45
- params.inject({}) do |result, entry|
46
- result[entry[0].to_sym] = entry[1]
47
- result
51
+ [request.path_info, request.request_method.upcase, request.params]
48
52
  end
49
53
  end
50
54
 
@@ -61,5 +65,7 @@ module Pendragon
61
65
  end
62
66
  }.(error_code)
63
67
  end
68
+
69
+ private :params_for, :valid_verb?, :fetch, :parse_request, :raise_exception
64
70
  end
65
71
  end
@@ -0,0 +1,71 @@
1
+ module Pendragon
2
+ # Raises the exception if routes that matches the condition do not exist
3
+ InvalidRouteException = Class.new(ArgumentError)
4
+
5
+ # A base class for error responses
6
+ # ResponseError#status and ResponseError#body must be implemented by subclass
7
+ class ResponseError < StandardError
8
+ def initialize(*args)
9
+ @args = args
10
+ end
11
+
12
+ def call
13
+ [status, headers, Array(body)]
14
+ end
15
+
16
+ def status
17
+ raise NotImplementedError, "`status` must be implemented by subclass"
18
+ end
19
+
20
+ def body
21
+ raise NotImplementedError, "`body` must be implemented by subclass"
22
+ end
23
+
24
+ def headers
25
+ @headers ||= { "Content-Type" => "text/plain" }
26
+ end
27
+ end
28
+
29
+ # A class for BadRequest response
30
+ class BadRequest < ResponseError
31
+ def status
32
+ @status ||= 400
33
+ end
34
+
35
+ def body
36
+ @body ||= "Bad Request"
37
+ end
38
+ end
39
+
40
+ # A class for NotFound response
41
+ class NotFound < ResponseError
42
+ def status
43
+ @status ||= 404
44
+ end
45
+
46
+ def body
47
+ @body ||= "Not Found"
48
+ end
49
+ end
50
+
51
+ # A class for MethodNotAllowed response
52
+ class MethodNotAllowed < ResponseError
53
+ ALLOW = "Allow".freeze
54
+ COMMA = ", ".freeze
55
+
56
+ def status
57
+ @status ||= 405
58
+ end
59
+
60
+ def body
61
+ @body ||= "Method Not Allowed"
62
+ end
63
+
64
+ def headers
65
+ @headers ||= begin
66
+ super_headers = super
67
+ super_headers.merge!(ALLOW => @args.shift.map{|verb| verb.upcase } * COMMA)
68
+ end
69
+ end
70
+ end
71
+ end
@@ -1,40 +1,49 @@
1
1
  require 'mustermann/sinatra'
2
2
 
3
3
  module Pendragon
4
+ # A class for path matching
5
+ #
6
+ # @example
7
+ # matcher = Pendragon::Matcher.new("/category/:id", capture: {id: /\d+/})
8
+ # matcher.match("/category/1234") #=> #<MatchData "/category/1234" id:"1234">
9
+ #
10
+ # @!visibility private
4
11
  class Matcher
12
+ # A character of path delimiter
13
+ PATH_DELIMITER = "/".freeze
14
+
15
+ # A prefix character of query string
16
+ QUERY_PREFIX = "?".freeze
17
+
18
+ # A character of query string delimiter
19
+ QUERY_DELIMITER = "&".freeze
20
+
21
+ # Constructs a new instance of Pendragon::Matcher
5
22
  # @param [String] path The path is string or regexp.
6
23
  # @option options [Hash] :capture Set capture for path pattern.
7
24
  # @option options [Hash] :default_values Set default_values for path pattern.
8
- #
9
25
  # @return [Pendragon::Matcher]
10
- #
11
26
  def initialize(path, options = {})
12
- @path = path.is_a?(String) && path.empty? ? "/" : path
27
+ @path = path.is_a?(String) && path.empty? ? PATH_DELIMITER : path
13
28
  @capture = options.delete(:capture)
14
29
  @default_values = options.delete(:default_values)
15
30
  end
16
31
 
17
- # Do the matching.
18
- #
32
+ # Does the matching.
19
33
  # @param [String] pattern The pattern is actual path (path_info etc).
20
- #
21
34
  # @return [MatchData] If the pattern matched this route, return a MatchData.
22
35
  # @return [Nil] If the pattern doesn't matched this route, return a nil.
23
- #
24
36
  def match(pattern)
25
- pattern = pattern[0..-2] if mustermann? and pattern != "/" and pattern.end_with?("/")
37
+ pattern = pattern[0..-2] if mustermann? and pattern != PATH_DELIMITER and pattern.end_with?(PATH_DELIMITER)
26
38
  handler.match(pattern)
27
39
  end
28
40
 
29
- # Expands the path with params.
30
- #
41
+ # Expands a path with params.
31
42
  # @param [Hash] params The params for path pattern.
32
- #
33
43
  # @example
34
- # matcher = Pendragon::Matcher.new("/foo/:bar")
35
- # matcher.expand(:bar => 123) #=> "/foo/123"
36
- # matcher.expand(:bar => "bar", :baz => "test") #=> "/foo/bar?baz=test"
37
- #
44
+ # matcher = Pendragon::Matcher.new("/foo/:bar")
45
+ # matcher.expand(:bar => 123) #=> "/foo/123"
46
+ # matcher.expand(:bar => "bar", :baz => "test") #=> "/foo/bar?baz=test"
38
47
  # @return [String] A expaneded path.
39
48
  def expand(params)
40
49
  params = params.dup
@@ -44,15 +53,17 @@ module Pendragon
44
53
  end
45
54
  params.merge!(@default_values) if @default_values.is_a?(Hash)
46
55
  expanded_path = handler.expand(params)
47
- expanded_path = expanded_path + "?" + query.map{|k,v| "#{k}=#{v}" }.join("&") unless query.empty?
56
+ expanded_path = expanded_path + QUERY_PREFIX + query.map{|k,v| "#{k}=#{v}" }.join(QUERY_DELIMITER) unless query.empty?
48
57
  expanded_path
49
58
  end
50
59
 
60
+ # Returns whether the handler is Mustermann
51
61
  # @return [Boolean] This matcher's handler is mustermann ?
52
62
  def mustermann?
53
63
  handler.instance_of?(Mustermann::Sinatra)
54
64
  end
55
65
 
66
+ # Returns the handler
56
67
  # @return [Mustermann::Sinatra] Returns a Mustermann::Sinatra when @path is string.
57
68
  # @return [Regexp] Returns a regexp when @path is regexp.
58
69
  def handler
@@ -65,14 +76,16 @@ module Pendragon
65
76
  end
66
77
  end
67
78
 
79
+ # Converts the handler into String
68
80
  # @return [String] Returns a converted handler.
69
81
  def to_s
70
82
  handler.to_s
71
83
  end
72
84
 
85
+ # Returns all named captures
73
86
  # @return [Array] Returns a named captures.
74
87
  def names
75
- handler.names.map(&:to_sym)
88
+ handler.names
76
89
  end
77
90
  end
78
91
  end
@@ -3,7 +3,7 @@ require 'pendragon/route'
3
3
  module Pendragon
4
4
  module Padrino
5
5
  class Route < ::Pendragon::Route
6
- attr_accessor :action, :cache, :cache_key, :cache_expires_in, :parent,
6
+ attr_accessor :action, :cache, :cache_key, :cache_expires, :parent,
7
7
  :use_layout, :controller, :user_agent, :path_for_generation
8
8
 
9
9
  def before_filters(&block)
@@ -1,4 +1,10 @@
1
1
  module Pendragon
2
+ # A class for defining the route
3
+ #
4
+ # @example
5
+ # route = Pendragon::Route.new("/:id", "GET", capture: id: /\d+/){|params| params[:id].to_s }
6
+ # route.match("/1234") #=> #<MatchData "/category/1234" id:"1234">
7
+ # route.arity
2
8
  class Route
3
9
 
4
10
  # The accessors are useful to access from Pendragon::Router
@@ -14,37 +20,59 @@ module Pendragon
14
20
  attr_writer :router
15
21
 
16
22
  # Constructs a new instance of Pendragon::Route
23
+ # @param [String, Regexp] path The path of route
24
+ # @param [String, Symbol] verb The verb of route
25
+ # @param [Hash] options The options hash
17
26
  def initialize(path, verb, options = {}, &block)
18
27
  @block = block if block_given?
19
- @path, @verb = path, verb
28
+ @path, @verb = path, verb.to_s.upcase
20
29
  @capture = {}
21
30
  @order = 0
22
31
  merge_with_options!(options)
23
32
  end
24
33
 
34
+ # Returns an instance of Pendragon::Matcherthat is associated with the route
35
+ # @return [Pendragon::Matcher]
25
36
  def matcher
26
37
  @matcher ||= Matcher.new(@path, :capture => @capture,
27
38
  :default_values => options[:default_values])
28
39
  end
29
40
 
41
+ # Returns arity of route block
42
+ # @return [Fixnum]
30
43
  def arity
31
44
  @block.arity
32
45
  end
33
46
 
47
+ # Calls the route block with arguments
48
+ # @param [Array] args The arguments are passed to the route block
34
49
  def call(*args)
35
50
  @block.call(*args)
36
51
  end
37
52
 
53
+ # Matches a pattern with the route matcher
54
+ # @param [String] pattern The pattern will be matched with route matcher
55
+ # @return (see Pendragon::Matcher#match)
38
56
  def match(pattern)
39
57
  matcher.match(pattern)
40
58
  end
41
59
 
60
+ # Associates the block with the route, and increments current order of the router
61
+ # @yield The route block
42
62
  def to(&block)
43
63
  @block = block if block_given?
44
64
  @order = @router.current
45
65
  @router.increment_order!
46
66
  end
47
67
 
68
+ # Expands a path using parameters
69
+ # @param [Array] args
70
+ # @example
71
+ # pendragon = Pendragon.new
72
+ # route = pendragon.get("/category/:name"){}
73
+ # route.path(name: "Doraemon") #=> "/category/Doraemon"
74
+ # route.path(name: "Doraemon", hey: "Hey") #=> "/category/Doraemon?hey=Hey"
75
+ # @return [String] The expanded path
48
76
  def path(*args)
49
77
  return @path if args.empty?
50
78
  params = args[0]
@@ -52,21 +80,28 @@ module Pendragon
52
80
  matcher.expand(params) if matcher.mustermann?
53
81
  end
54
82
 
83
+ # Matches a pattern with the route matcher, and then returns the route params
84
+ # @param [String] pattern The pattern will be matched with the matcher
85
+ # @param [Hash] parameters The parameters are base of the route params
86
+ # @example
87
+ # pendragon = Pendragon.new
88
+ # route = pendragon.get("/category/:name"){}
89
+ # route.params("/category/Doraemon") #=> {:name=>"Doraemon"}
90
+ # route.params("/category/Doraemon", hey: "Hey") #=> {:name=>"Doraemon", :hey=>"Hey"}
91
+ # @return [Hash] The params for use in routing engines
55
92
  def params(pattern, parameters = {})
56
- match_data, params = match(pattern), {}
93
+ match_data, params = match(pattern), indifferent_hash
57
94
  if match_data.names.empty?
58
95
  params.merge!(:captures => match_data.captures) unless match_data.captures.empty?
59
96
  params
60
97
  else
61
- params = matcher.handler.params(pattern, :captures => match_data) || params
62
- symbolize(params).merge(parameters){|key, old, new| old || new }
98
+ params_from_matcher = matcher.handler.params(pattern, :captures => match_data)
99
+ params.merge!(params_from_matcher) if params_from_matcher
100
+ params.merge(parameters){|key, old, new| old || new }
63
101
  end
64
102
  end
65
103
 
66
- def symbolize(parameters)
67
- parameters.inject({}){|result, (key, val)| result[key.to_sym] = val; result }
68
- end
69
-
104
+ # @!visibility private
70
105
  def merge_with_options!(options)
71
106
  @options = {} unless @options
72
107
  options.each_pair do |key, value|
@@ -74,10 +109,16 @@ module Pendragon
74
109
  end
75
110
  end
76
111
 
112
+ # @!visibility private
77
113
  def accessor?(key)
78
114
  respond_to?("#{key}=") && respond_to?(key)
79
115
  end
80
116
 
81
- private :symbolize, :merge_with_options!, :accessor?
117
+ # @!visibility private
118
+ def indifferent_hash
119
+ Hash.new{|hash, key| hash[key.to_s] if key.instance_of?(Symbol) }
120
+ end
121
+
122
+ private :merge_with_options!, :accessor?, :indifferent_hash
82
123
  end
83
124
  end
@@ -1,13 +1,23 @@
1
1
  require 'pendragon/route'
2
2
  require 'pendragon/matcher'
3
- require 'pendragon/error_handler'
3
+ require 'pendragon/error'
4
4
  require 'pendragon/configuration'
5
5
  require 'pendragon/engine/compiler'
6
6
  require 'rack'
7
7
 
8
8
  module Pendragon
9
+ # A class for the router
10
+ #
11
+ # @example Construct with a block which has no argument
12
+ # router = Pendragon do
13
+ # get("/"){ "hello world" }
14
+ # end
15
+ #
16
+ # @example Construct with a block which has an argument
17
+ # router = Pendragon.new do |config|
18
+ # config.enable_compiler = true
19
+ # end
9
20
  class Router
10
-
11
21
  # The accessors are useful to access from Pendragon::Route
12
22
  attr_accessor :current, :routes
13
23
 
@@ -47,6 +57,10 @@ module Pendragon
47
57
  $!.call
48
58
  end
49
59
 
60
+ # Calls a route, and build return value of the router
61
+ # @param [Pendragon::Route] route The route matched with the condition of request
62
+ # @param [Hash] params The params will be passed with the route
63
+ # @return [Array<Fixnum, Hash, Array>] The return value of the route block
50
64
  def invoke(route, params)
51
65
  response = route.arity != 0 ? route.call(params) : route.call
52
66
  return response unless configuration.auto_rack_format?
@@ -110,10 +124,10 @@ module Pendragon
110
124
  # @return [Array]
111
125
  def recognize_path(path_info)
112
126
  route, params = recognize(Rack::MockRequest.env_for(path_info)).first
113
- [route.name, params]
127
+ [route.name, params.inject({}){|hash, (key, value)| hash[key.to_sym] = value; hash }]
114
128
  end
115
129
 
116
- # Returns a expanded path matched with the conditions as arguments
130
+ # Returns an expanded path matched with the conditions as arguments
117
131
  # @return [String, Regexp]
118
132
  # @example
119
133
  # router = Pendragon.new
@@ -126,12 +140,12 @@ module Pendragon
126
140
  end
127
141
  end
128
142
 
143
+ # Returns Pendragon configuration
144
+ # @return [Pendragon::Configuration]
129
145
  def configuration
130
146
  @configuration || Pendragon.configuration
131
147
  end
132
148
 
133
- private
134
-
135
149
  # @!visibility private
136
150
  # @example
137
151
  # extract_with_name(:index) do |route, params|
@@ -146,8 +160,8 @@ module Pendragon
146
160
  if !args.empty? and matcher.mustermann?
147
161
  matcher_names = matcher.names
148
162
  params_for_expand = Hash[matcher_names.map{|matcher_name|
149
- [matcher_name.to_sym, (params[matcher_name.to_sym] || args.shift)]}]
150
- params_for_expand.merge!(Hash[params.select{|k, v| !matcher_names.include?(name.to_sym) }])
163
+ [matcher_name.to_sym, (params[matcher_name] || args.shift)]}]
164
+ params_for_expand.merge!(Hash[params.select{|k, v| !matcher_names.include?(name) }])
151
165
  args = saved_args.dup
152
166
  else
153
167
  params_for_expand = params.dup
@@ -156,5 +170,7 @@ module Pendragon
156
170
  end
157
171
  raise InvalidRouteException
158
172
  end
173
+
174
+ private :extract_with_name
159
175
  end
160
176
  end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Pendragon
3
- VERSION = '0.5.0'
3
+ VERSION = '0.5.1'
4
4
  end
data/lib/pendragon.rb CHANGED
@@ -3,7 +3,7 @@ require 'pendragon/router'
3
3
  module Pendragon
4
4
 
5
5
  # Allow the verbs of these.
6
- HTTP_VERBS = [:get, :post, :delete, :put, :head]
6
+ HTTP_VERBS = %w[GET POST PUT PATCH DELETE HEAD OPTIONS LINK UNLINK].freeze
7
7
 
8
8
  class << self
9
9
  # A new instance of Pendragon::Router
@@ -38,8 +38,7 @@ module Pendragon
38
38
  @configuration = nil
39
39
  end
40
40
 
41
- private
42
-
41
+ # @!visibility private
43
42
  def configuration_warning(method)
44
43
  warn <<-WARN
45
44
  Pendragon.#{method} is deprecated because it isn't thread-safe.
@@ -50,5 +49,7 @@ Pendragon.new do |config|
50
49
  end
51
50
  WARN
52
51
  end
52
+
53
+ private :configuration_warning
53
54
  end
54
55
  end
data/pendragon.gemspec CHANGED
@@ -16,5 +16,5 @@ Gem::Specification.new "pendragon", Pendragon::VERSION do |s|
16
16
  s.add_development_dependency "rack-test", ">= 0.5.0"
17
17
  s.add_development_dependency "mocha", ">= 0.10.0"
18
18
  s.add_development_dependency "haml"
19
- s.add_development_dependency "padrino-core", "= 0.12.0.rc3"
19
+ s.add_development_dependency "padrino", "~> 0.12.2"
20
20
  end
data/test/helper.rb CHANGED
@@ -7,6 +7,7 @@ require 'minitest/autorun'
7
7
  require 'minitest/spec'
8
8
  require 'mocha/setup'
9
9
  require 'padrino-core'
10
+ require 'padrino/rendering'
10
11
  require 'rack'
11
12
  require 'rack/test'
12
13
 
data/test/padrino_test.rb CHANGED
@@ -6,7 +6,6 @@ class FooError < RuntimeError; end
6
6
 
7
7
  describe "Pendragon::Padrino" do
8
8
  setup do
9
- Padrino::Application.send(:register, Padrino::Rendering)
10
9
  Padrino::Application.send(:register, Pendragon::Padrino)
11
10
  Padrino::Rendering::DEFAULT_RENDERING_OPTIONS[:strict_format] = false
12
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pendragon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - namusyaka
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-26 00:00:00.000000000 Z
11
+ date: 2014-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -95,19 +95,19 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: padrino-core
98
+ name: padrino
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '='
101
+ - - ~>
102
102
  - !ruby/object:Gem::Version
103
- version: 0.12.0.rc3
103
+ version: 0.12.2
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '='
108
+ - - ~>
109
109
  - !ruby/object:Gem::Version
110
- version: 0.12.0.rc3
110
+ version: 0.12.2
111
111
  description: Provides an HTTP router for use in Rack and Padrino.
112
112
  email: namusyaka@gmail.com
113
113
  executables: []
@@ -124,7 +124,7 @@ files:
124
124
  - lib/pendragon/configuration.rb
125
125
  - lib/pendragon/engine/compiler.rb
126
126
  - lib/pendragon/engine/recognizer.rb
127
- - lib/pendragon/error_handler.rb
127
+ - lib/pendragon/error.rb
128
128
  - lib/pendragon/matcher.rb
129
129
  - lib/pendragon/padrino.rb
130
130
  - lib/pendragon/padrino/ext/class_methods.rb
@@ -1,47 +0,0 @@
1
- module Pendragon
2
- class ErrorHandler < StandardError
3
- def call
4
- response = []
5
- response << (settings[:status] || default_response[0])
6
- response << (settings[:headers] || default_response[1])
7
- response << Array(settings[:body] || default_response[2])
8
- end
9
-
10
- def settings
11
- self.class.settings
12
- end
13
-
14
- class << self
15
- def set(key, value)
16
- settings[key] = value
17
- end
18
-
19
- def settings
20
- @settings ||= {}
21
- end
22
- end
23
-
24
- private
25
-
26
- def default_response
27
- @default_response ||= [404, {'Content-Type' => 'text/html'}, ["Not Found"]]
28
- end
29
- end
30
-
31
- NotFound = Class.new(ErrorHandler)
32
- InvalidRouteException = Class.new(ArgumentError)
33
-
34
- class MethodNotAllowed < ErrorHandler
35
- set :status, 405
36
- set :body, "Method Not Allowed"
37
-
38
- def initialize(verbs)
39
- default_response[1].merge!("Allow" => verbs.map{|verb| verb.upcase } * ", ")
40
- end
41
- end
42
-
43
- class BadRequest < ErrorHandler
44
- set :status, 400
45
- set :body, "Bad Request"
46
- end
47
- end