pendragon 0.5.0 → 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.
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