pendragon 0.6.2 → 1.0.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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -2
- data/Gemfile +7 -0
- data/Gemfile.lock +27 -83
- data/README.md +69 -192
- data/Rakefile +3 -18
- data/benchmark.rb +31 -0
- data/lib/pendragon.rb +60 -44
- data/lib/pendragon/constants.rb +27 -0
- data/lib/pendragon/errors.rb +72 -0
- data/lib/pendragon/linear.rb +9 -0
- data/lib/pendragon/realism.rb +49 -0
- data/lib/pendragon/router.rb +295 -142
- data/lib/pendragon/version.rb +1 -1
- data/pendragon.gemspec +1 -6
- data/test/helper.rb +9 -84
- data/test/router/test_linear.rb +6 -0
- data/test/router/test_realism.rb +6 -0
- data/test/supports/shared_examples_for_routing.rb +277 -0
- data/test/test_router.rb +40 -0
- metadata +22 -101
- data/lib/pendragon/configuration.rb +0 -42
- data/lib/pendragon/engine/compiler.rb +0 -74
- data/lib/pendragon/engine/recognizer.rb +0 -72
- data/lib/pendragon/error.rb +0 -71
- data/lib/pendragon/matcher.rb +0 -93
- data/lib/pendragon/padrino.rb +0 -15
- data/lib/pendragon/padrino/ext/class_methods.rb +0 -318
- data/lib/pendragon/padrino/ext/instance_methods.rb +0 -63
- data/lib/pendragon/padrino/route.rb +0 -50
- data/lib/pendragon/padrino/router.rb +0 -34
- data/lib/pendragon/route.rb +0 -124
- data/test/compile_helper.rb +0 -3
- data/test/padrino_test.rb +0 -2113
- data/test/pendragon_configuration.rb +0 -32
- data/test/pendragon_test.rb +0 -229
metadata
CHANGED
@@ -1,145 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pendragon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- namusyaka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-11-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 1.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: mustermann
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.3.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 0.3.0
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rake
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '>='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.8.7
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 0.8.7
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rack-test
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.5.0
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 0.5.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: mocha
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - '>='
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: 0.10.0
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - '>='
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: 0.10.0
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: haml
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - '>='
|
31
|
+
- - ">="
|
88
32
|
- !ruby/object:Gem::Version
|
89
33
|
version: '0'
|
90
|
-
type: :
|
34
|
+
type: :runtime
|
91
35
|
prerelease: false
|
92
36
|
version_requirements: !ruby/object:Gem::Requirement
|
93
37
|
requirements:
|
94
|
-
- -
|
38
|
+
- - ">="
|
95
39
|
- !ruby/object:Gem::Version
|
96
40
|
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: padrino
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ~>
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: 0.12.2
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ~>
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: 0.12.2
|
111
41
|
description: Provides an HTTP router for use in Rack and Padrino.
|
112
42
|
email: namusyaka@gmail.com
|
113
43
|
executables: []
|
114
44
|
extensions: []
|
115
45
|
extra_rdoc_files: []
|
116
46
|
files:
|
117
|
-
- .travis.yml
|
47
|
+
- ".travis.yml"
|
118
48
|
- Gemfile
|
119
49
|
- Gemfile.lock
|
120
50
|
- README.md
|
121
51
|
- Rakefile
|
52
|
+
- benchmark.rb
|
122
53
|
- config.ru
|
123
54
|
- lib/pendragon.rb
|
124
|
-
- lib/pendragon/
|
125
|
-
- lib/pendragon/
|
126
|
-
- lib/pendragon/
|
127
|
-
- lib/pendragon/
|
128
|
-
- lib/pendragon/matcher.rb
|
129
|
-
- lib/pendragon/padrino.rb
|
130
|
-
- lib/pendragon/padrino/ext/class_methods.rb
|
131
|
-
- lib/pendragon/padrino/ext/instance_methods.rb
|
132
|
-
- lib/pendragon/padrino/route.rb
|
133
|
-
- lib/pendragon/padrino/router.rb
|
134
|
-
- lib/pendragon/route.rb
|
55
|
+
- lib/pendragon/constants.rb
|
56
|
+
- lib/pendragon/errors.rb
|
57
|
+
- lib/pendragon/linear.rb
|
58
|
+
- lib/pendragon/realism.rb
|
135
59
|
- lib/pendragon/router.rb
|
136
60
|
- lib/pendragon/version.rb
|
137
61
|
- pendragon.gemspec
|
138
|
-
- test/compile_helper.rb
|
139
62
|
- test/helper.rb
|
140
|
-
- test/
|
141
|
-
- test/
|
142
|
-
- test/
|
63
|
+
- test/router/test_linear.rb
|
64
|
+
- test/router/test_realism.rb
|
65
|
+
- test/supports/shared_examples_for_routing.rb
|
66
|
+
- test/test_router.rb
|
143
67
|
homepage: https://github.com/namusyaka/pendragon
|
144
68
|
licenses:
|
145
69
|
- MIT
|
@@ -150,21 +74,18 @@ require_paths:
|
|
150
74
|
- lib
|
151
75
|
required_ruby_version: !ruby/object:Gem::Requirement
|
152
76
|
requirements:
|
153
|
-
- -
|
77
|
+
- - ">="
|
154
78
|
- !ruby/object:Gem::Version
|
155
79
|
version: '0'
|
156
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
81
|
requirements:
|
158
|
-
- -
|
82
|
+
- - ">="
|
159
83
|
- !ruby/object:Gem::Version
|
160
84
|
version: '0'
|
161
85
|
requirements: []
|
162
86
|
rubyforge_project:
|
163
|
-
rubygems_version: 2.
|
87
|
+
rubygems_version: 2.5.1
|
164
88
|
signing_key:
|
165
89
|
specification_version: 4
|
166
90
|
summary: Provides an HTTP router for use in Rack and Padrino.
|
167
|
-
test_files:
|
168
|
-
- test/padrino_test.rb
|
169
|
-
- test/pendragon_test.rb
|
170
|
-
has_rdoc:
|
91
|
+
test_files: []
|
@@ -1,42 +0,0 @@
|
|
1
|
-
module Pendragon
|
2
|
-
# A class for configuration of Pendragon
|
3
|
-
# @!visibility private
|
4
|
-
class Configuration
|
5
|
-
# Defines an accessor as boolean method
|
6
|
-
# @example
|
7
|
-
# attr_boolean_accessor :accessor_name
|
8
|
-
def self.attr_boolean_accessor(*keys)
|
9
|
-
keys.each do |key|
|
10
|
-
attr_accessor key
|
11
|
-
define_method("#{key}?"){ !!__send__(key) }
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# Enables to compile the routes
|
16
|
-
# Improve the performance by using this option,
|
17
|
-
# but some features will not work correctly.
|
18
|
-
# @see Pendragon::Router#compile
|
19
|
-
attr_boolean_accessor :enable_compiler
|
20
|
-
|
21
|
-
# Automatically converts response into Rack format.
|
22
|
-
# Default value is `true`.
|
23
|
-
# @see Pendragon::Router#invoke
|
24
|
-
attr_boolean_accessor :auto_rack_format
|
25
|
-
|
26
|
-
# Enables to lock for threaded environment.
|
27
|
-
# If you enable this option, all requests to synchronize on a mutex lock
|
28
|
-
attr_boolean_accessor :lock
|
29
|
-
|
30
|
-
# Constructs an instance of Pendragon::Configuration
|
31
|
-
def initialize
|
32
|
-
@enable_compiler = false
|
33
|
-
@auto_rack_format = true
|
34
|
-
@lock = false
|
35
|
-
end
|
36
|
-
|
37
|
-
# Returns an instance variable
|
38
|
-
def [](variable_name)
|
39
|
-
instance_variable_get("@#{variable_name}")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'pendragon/engine/recognizer'
|
2
|
-
|
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
|
13
|
-
class Compiler < Recognizer
|
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], ..]
|
21
|
-
def call(request)
|
22
|
-
compile! unless compiled?
|
23
|
-
pattern, verb, params = parse_request(request)
|
24
|
-
pattern = pattern.encode(Encoding.default_external)
|
25
|
-
raise_exception(400) unless valid_verb?(verb)
|
26
|
-
candidacies = match_with(pattern)
|
27
|
-
raise_exception(404) if candidacies.empty?
|
28
|
-
candidacies, allows = candidacies.partition{|route| route.verb == verb }
|
29
|
-
raise_exception(405, verbs: allows.map(&:verb)) if candidacies.empty?
|
30
|
-
candidacies.map{|route| [route, params_for(route, pattern, params)]}
|
31
|
-
end
|
32
|
-
|
33
|
-
# @!visibility private
|
34
|
-
def compile!
|
35
|
-
return if compiled?
|
36
|
-
@regexps = @routes.map.with_index do |route, index|
|
37
|
-
regexp = route.matcher.handler
|
38
|
-
regexp = regexp.to_regexp if route.matcher.mustermann?
|
39
|
-
route.index = index
|
40
|
-
/(?<_#{index}>#{regexp})/
|
41
|
-
end
|
42
|
-
@regexps = compile(@regexps)
|
43
|
-
@compiled = true
|
44
|
-
end
|
45
|
-
|
46
|
-
# @!visibility private
|
47
|
-
def compile(regexps, paths = [])
|
48
|
-
return paths if regexps.length.zero?
|
49
|
-
paths << Regexp.union(regexps)
|
50
|
-
regexps.shift
|
51
|
-
compile(regexps, paths)
|
52
|
-
end
|
53
|
-
|
54
|
-
# @!visibility private
|
55
|
-
def compiled?
|
56
|
-
!!@compiled
|
57
|
-
end
|
58
|
-
|
59
|
-
# @!visibility private
|
60
|
-
def match_with(pattern)
|
61
|
-
offset = 0
|
62
|
-
conditions = [pattern]
|
63
|
-
conditions << pattern[0..-2] if pattern != Matcher::PATH_DELIMITER && pattern.end_with?(Matcher::PATH_DELIMITER)
|
64
|
-
loop.with_object([]) do |_, candidacies|
|
65
|
-
return candidacies unless conditions.any?{|x| @regexps[offset] === x }
|
66
|
-
route = @routes[offset..-1].detect{|route| Regexp.last_match["_#{route.index}"] }
|
67
|
-
candidacies << route
|
68
|
-
offset = route.index + 1
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
private :compile!, :compile, :compiled?, :match_with
|
73
|
-
end
|
74
|
-
end
|
@@ -1,72 +0,0 @@
|
|
1
|
-
module Pendragon
|
2
|
-
# One of the engine classes for recognizing routes
|
3
|
-
# @!visibility private
|
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
|
11
|
-
def initialize(routes)
|
12
|
-
@routes = routes
|
13
|
-
end
|
14
|
-
|
15
|
-
# Recognizes 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]
|
21
|
-
def call(request)
|
22
|
-
pattern, verb, params = parse_request(request)
|
23
|
-
pattern = pattern.encode(Encoding.default_external)
|
24
|
-
raise_exception(400) unless valid_verb?(verb)
|
25
|
-
fetch(pattern, verb){|route| [route, params_for(route, pattern, params)] }
|
26
|
-
end
|
27
|
-
|
28
|
-
# @!visibility private
|
29
|
-
def params_for(route, pattern, params)
|
30
|
-
route.params(pattern, params)
|
31
|
-
end
|
32
|
-
|
33
|
-
# @!visibility private
|
34
|
-
def valid_verb?(verb)
|
35
|
-
Pendragon::HTTP_VERBS.include?(verb)
|
36
|
-
end
|
37
|
-
|
38
|
-
# @!visibility private
|
39
|
-
def fetch(pattern, verb)
|
40
|
-
_routes = @routes.select{|route| route.match(pattern) }
|
41
|
-
raise_exception(404) if _routes.empty?
|
42
|
-
result = _routes.map{|route| yield(route) if verb == route.verb }.compact
|
43
|
-
raise_exception(405, :verbs => _routes.map(&:verb)) if result.empty?
|
44
|
-
result
|
45
|
-
end
|
46
|
-
|
47
|
-
# @!visibility private
|
48
|
-
def parse_request(request)
|
49
|
-
if request.is_a?(Hash)
|
50
|
-
[request[PATH_INFO], request[REQUEST_METHOD].upcase, {}]
|
51
|
-
else
|
52
|
-
[request.path_info, request.request_method.upcase, request.params]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# @!visibility private
|
57
|
-
def raise_exception(error_code, options = {})
|
58
|
-
raise ->(error_code) {
|
59
|
-
case error_code
|
60
|
-
when 400
|
61
|
-
BadRequest
|
62
|
-
when 404
|
63
|
-
NotFound
|
64
|
-
when 405
|
65
|
-
MethodNotAllowed.new(options[:verbs])
|
66
|
-
end
|
67
|
-
}.(error_code)
|
68
|
-
end
|
69
|
-
|
70
|
-
private :params_for, :valid_verb?, :fetch, :parse_request, :raise_exception
|
71
|
-
end
|
72
|
-
end
|
data/lib/pendragon/error.rb
DELETED
@@ -1,71 +0,0 @@
|
|
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
|