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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 914465eff1ee8117a07da6fd8f8e9619885003d2
4
- data.tar.gz: dec0c29b856f107c142018b068e978012de160c9
3
+ metadata.gz: cd0edab5d92da0e54a220b00f8f7d494b4db1e3b
4
+ data.tar.gz: 543fc628f35ff975c0a24812ea09a3fa6d21c8b1
5
5
  SHA512:
6
- metadata.gz: 9defb1e67cef1b199bc9b556467a17c56e9fa94a97421a5fbcc6b519fd9039d4ba55e9f9d02f7c2bb4ead6a1cb954e12052fbc59c7697b5a59db52e72691da68
7
- data.tar.gz: 97473aaab4ccbfbbc7e8ab6147935107c45fd9852463abe53a8285f3e1bbccc32163298fee0c6e97060aa0377d67f42d80f428585a1f8b14dc9df874cddfb699
6
+ metadata.gz: 2bc2a1c2b90272591d3b1c3c1447f2f1502636ac741406bb3b2fa3ae2e106fae188876147e4235857a7f9ff6b5cbe900b3da9f561bc6d65fc5f695b9c117add6
7
+ data.tar.gz: d65be58e80f6ba365a8d11a5523426e83bca18929417874e199a072e13c1509bba27720e9e9775cd9314cf9db8f00aa111b090a077743b0ab153e3725b358015
@@ -4,8 +4,10 @@ install:
4
4
  - gem update --system
5
5
  - bundle update
6
6
  rvm:
7
- - 2.0.0
8
- - 2.1.0
7
+ - 2.1.10
8
+ - 2.2.6
9
+ - 2.3.3
10
+ - 2.4.0-preview3
9
11
  - jruby
10
12
  - rbx
11
13
  notifications:
data/Gemfile CHANGED
@@ -1,3 +1,10 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ gem 'rake'
4
+ gem 'rack-test'
5
+ gem 'test-unit'
6
+ gem 'mocha'
7
+ gem 'sinatra'
8
+ gem 'yard'
9
+ gem 'modulla'
3
10
  gemspec
@@ -1,104 +1,48 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- pendragon (0.6.1)
5
- mustermann19 (~> 0.3.0)
4
+ pendragon (0.6.2)
5
+ mustermann
6
6
  rack (>= 1.3.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (4.1.6)
12
- i18n (~> 0.6, >= 0.6.9)
13
- json (~> 1.7, >= 1.7.7)
14
- minitest (~> 5.1)
15
- thread_safe (~> 0.1)
16
- tzinfo (~> 1.1)
17
- enumerable-lazy (0.0.1)
18
- haml (4.0.5)
19
- tilt
20
- http_router (0.11.1)
21
- rack (>= 1.0.0)
22
- url_mount (~> 0.2.1)
23
- i18n (0.6.11)
24
- json (1.8.1)
25
- json (1.8.1-java)
26
- mail (2.5.4)
27
- mime-types (~> 1.16)
28
- treetop (~> 1.4.8)
29
11
  metaclass (0.0.4)
30
- mime-types (1.25.1)
31
- minitest (5.4.2)
32
12
  mocha (1.1.0)
33
13
  metaclass (~> 0.0.1)
34
- moneta (0.7.20)
35
- mustermann19 (0.3.1)
36
- enumerable-lazy
37
- padrino (0.12.4)
38
- padrino-admin (= 0.12.4)
39
- padrino-cache (= 0.12.4)
40
- padrino-core (= 0.12.4)
41
- padrino-gen (= 0.12.4)
42
- padrino-helpers (= 0.12.4)
43
- padrino-mailer (= 0.12.4)
44
- padrino-support (= 0.12.4)
45
- padrino-admin (0.12.4)
46
- padrino-core (= 0.12.4)
47
- padrino-helpers (= 0.12.4)
48
- padrino-cache (0.12.4)
49
- moneta (~> 0.7.0)
50
- padrino-core (= 0.12.4)
51
- padrino-helpers (= 0.12.4)
52
- padrino-core (0.12.4)
53
- activesupport (>= 3.1)
54
- http_router (~> 0.11.0)
55
- padrino-support (= 0.12.4)
56
- rack-protection (>= 1.5.0)
57
- sinatra (~> 1.4.2)
58
- thor (~> 0.18)
59
- padrino-gen (0.12.4)
60
- bundler (~> 1.0)
61
- padrino-core (= 0.12.4)
62
- padrino-helpers (0.12.4)
63
- i18n (~> 0.6, >= 0.6.7)
64
- padrino-support (= 0.12.4)
65
- tilt (~> 1.4.1)
66
- padrino-mailer (0.12.4)
67
- mail (~> 2.5.3)
68
- padrino-core (= 0.12.4)
69
- padrino-support (0.12.4)
70
- activesupport (>= 3.1)
71
- polyglot (0.3.5)
72
- rack (1.5.2)
14
+ modulla (0.1.1)
15
+ mustermann (0.4.0)
16
+ tool (~> 0.2)
17
+ power_assert (0.3.0)
18
+ rack (1.5.5)
73
19
  rack-protection (1.5.3)
74
20
  rack
75
- rack-test (0.6.2)
21
+ rack-test (0.6.3)
76
22
  rack (>= 1.0)
77
- rake (10.3.2)
78
- sinatra (1.4.5)
79
- rack (~> 1.4)
23
+ rake (11.3.0)
24
+ sinatra (1.4.7)
25
+ rack (~> 1.5)
80
26
  rack-protection (~> 1.4)
81
- tilt (~> 1.3, >= 1.3.4)
82
- thor (0.19.1)
83
- thread_safe (0.3.4)
84
- thread_safe (0.3.4-java)
85
- tilt (1.4.1)
86
- treetop (1.4.15)
87
- polyglot
88
- polyglot (>= 0.3.1)
89
- tzinfo (1.2.2)
90
- thread_safe (~> 0.1)
91
- url_mount (0.2.1)
92
- rack
27
+ tilt (>= 1.3, < 3)
28
+ test-unit (3.2.1)
29
+ power_assert
30
+ tilt (2.0.5)
31
+ tool (0.2.3)
32
+ yard (0.9.5)
93
33
 
94
34
  PLATFORMS
95
- java
96
35
  ruby
97
36
 
98
37
  DEPENDENCIES
99
- haml
100
- mocha (>= 0.10.0)
101
- padrino (~> 0.12.2)
38
+ mocha
39
+ modulla
102
40
  pendragon!
103
- rack-test (>= 0.5.0)
104
- rake (>= 0.8.7)
41
+ rack-test
42
+ rake
43
+ sinatra
44
+ test-unit
45
+ yard
46
+
47
+ BUNDLED WITH
48
+ 1.12.5
data/README.md CHANGED
@@ -2,268 +2,145 @@
2
2
 
3
3
  [![Build Status](https://travis-ci.org/namusyaka/pendragon.svg?branch=master)](https://travis-ci.org/namusyaka/pendragon) [![Gem Version](https://badge.fury.io/rb/pendragon.svg)](http://badge.fury.io/rb/pendragon)
4
4
 
5
- Pendragon provides an HTTP router for use in Rack and Padrino.
6
- As a Rack application, it makes it easy to define complicated routing.
7
- As a Padrino plugin, your application uses Pendragon instead of http_router.
8
- Therefore, some bugs of http_router will be fixed.
5
+ Pendragon provides an HTTP router and its toolkit for use in Rack. As a Rack application, it makes it easy to define complicated routing.
6
+ Algorithms of the router are used in [Padrino](https://github.com/padrino/padrino-framework) and [Grape](https://github.com/ruby-grape/grape), it's fast, flexible and robust.
7
+
8
+ *If you want to use in Ruby-1.9, you can do it by using [mustermann19](https://github.com/namusyaka/mustermann19).*
9
9
 
10
- *If you want to use in Ruby1.9, you can do it by using [mustermann/1.9-support branch](https://github.com/rkh/mustermann/tree/1.9-support).*
11
10
 
12
11
  ```ruby
13
12
  Pendragon.new do
14
- get("/"){ "hello world" }
15
- get("/foo/:bar", name: :foo) do |params|
16
- "foo is #{params[:bar]}"
13
+ get('/') { [200, {}, ['hello world']] }
14
+ namespace :users do
15
+ get('/', to: -> { [200, {}, ['User page index']] })
16
+ get('/:id', to: -> (id) { [200, {}, [id]] })
17
+ get('/:id/comments') { |id| [200, {}, [User.find_by(id: id).comments.to_json]] }
17
18
  end
18
19
  end
19
20
  ```
20
21
 
21
- ## Installation
22
-
23
- Depends on [rack](https://github.com/rack/rack) and [mustermann](https://github.com/rkh/mustermann).
22
+ ## Router Patterns
24
23
 
25
- `gem install pendragon`
26
-
27
- ## Usage
24
+ |Type |Description |Note |
25
+ |---|---|---|
26
+ |[liner](https://github.com/namusyaka/pendragon/blob/master/lib/pendragon/liner.rb) |Linear search, Optimized Mustermann patterns | |
27
+ |[realism](https://github.com/namusyaka/pendragon/blob/master/lib/pendragon/realism.rb) |First route is detected by union regexps (Actually, O(1) in ruby level), routes since the first time will be retected by linear search | this algorithm is using in Grape |
28
+ |[radix](https://github.com/namusyaka/pendragon-radix) |Radix Tree, not using Mustermann and regexp| requires C++11 |
28
29
 
29
- ### Configuration
30
-
31
- |name |types |default|description |
32
- |:---------------|:------|:------|:-------------------------|
33
- |enable_compiler |boolean|false|The performance will be improved. However, it will increase the first load time.|
34
- |auto_rack_format|boolean|true|If disable this param, the block of route should return the response of valid rack format.|
35
- |lock |boolean|false|If you enable this option, all requests to synchronize on a mutex lock|
30
+ ## Installation
36
31
 
37
- #### `enable_compiler`
32
+ Add this line to your application's Gemfile:
38
33
 
39
34
  ```ruby
40
- # Performance will be improved!
41
- Pendragon.new do |config|
42
- config.enable_compiler = true
43
- end
35
+ gem 'pendragon'
44
36
  ```
45
37
 
46
- *The compiler mode was inspired by [rack-multiplexer](https://github.com/r7kamura/rack-multiplexer). Thank you!*
38
+ And then execute:
47
39
 
48
- #### `auto_rack_format`
40
+ $ bundle
49
41
 
50
- ```ruby
51
- # Enable the param (default)
52
- Pendragon.new do
53
- get("/"){ "hey" }
54
- end
42
+ Or install it yourself as:
55
43
 
56
- pendragon = Pendragon.new do |config|
57
- config.auto_rack_format = false
58
- end
59
- # Disable the param
60
- pendragon.get("/"){ [200, {"Content-Type" => "text/html;charset=utf-8"}, ["hey"]] }
61
- ```
44
+ $ gem install pendragon
62
45
 
63
- #### `lock`
64
46
 
65
- ```ruby
66
- pendragon = Pendragon.new do |config|
67
- config.lock = true
68
- end
69
- ```
47
+ ## Usage
70
48
 
71
- If you use pendragon in threaded environment, you should enable this option to avoid compiling all routes again and again.
49
+ ### Selects router pattern
72
50
 
73
- #### Deprecated
51
+ You can select router pattern as following code.
74
52
 
75
53
  ```ruby
76
- # Global configuration style is deprecated since 0.5.0
77
- Pendragon.configure do |config|
78
- config.enable_compiler = true
79
- end
54
+ # Gets Linear router class by passing type in `Pendragon.[]`
55
+ Pendragon[:linear] #=> Pendragon::Linear
80
56
 
81
- # Please use new syntax.
82
- pendragon = Pendragon.new do |config|
83
- config.enable_compiler = true
84
- end
57
+ # Specify :type to construction of Pendragon.
58
+ Pendragon.new(type: :linear) { ... }
85
59
  ```
86
60
 
87
- ### Register a route
61
+ ### Registers a route
88
62
 
89
63
  It has some methods to register a route. For example, `#get`, `#post` and `#delete` are so.
90
64
  This section introduces all those methods.
91
65
 
92
- #### `add(verb, path, option, &block)`
66
+ #### `route(method, path, **options, &block)`
67
+
93
68
 
94
69
  The method is the basis of the registration method of all.
95
70
  In comparison with other registration methods, one argument is increased.
96
71
 
97
72
  ```ruby
98
73
  Pendragon.new do
99
- # The two approach have the same meaning.
100
- add(:get, "/"){ "hello world" }
101
- get("/"){ "hello world" }
74
+ route('GET', ?/){ [200, {}, ['hello']] }
102
75
  end
103
76
  ```
104
77
 
105
- #### `get(path, option, &block)`, `post`, `delete`, `put` and `head`
78
+ #### `get(path, **options, &block)`, `post`, `delete`, `put` and `head`
106
79
 
107
- Basically the usage is the same with `#add`.
108
- You may as well use those methods instead of `#add` because those methods are easy to understand.
80
+ Basically the usage is the same with `#route`.
81
+ You may as well use those methods instead of `#route` because those methods are easy to understand.
109
82
 
110
83
  ```ruby
111
84
  Pendragon.new do
112
- get("/"){ "hello world" }
113
- post("/"){ "hello world" }
114
- delete("/"){ "hello world" }
115
- put("/"){ "hello world" }
116
- head("/"){ "hello world" }
85
+ get (?/) { [200, {}, ['hello']] }
86
+ post (?/) { [200, {}, ['hello']] }
87
+ delete(?/) { [200, {}, ['hello']] }
88
+ put (?/) { [200, {}, ['hello']] }
89
+ head (?/) { [200, {}, ['hello']] }
117
90
  end
118
91
  ```
119
92
 
120
- ##### Path
121
-
122
- The path must be an instance of String (this must be complied with the Mustermann::Sinatra's rule) or Regexp.
123
-
124
- ##### Route options
125
-
126
- |name|types |description |
127
- |:----|:------|:-------------------------|
128
- |name |symbol |specify the name of route for `Pendragon::Router#path` method.|
129
- |order|integer|specify the order for the prioritized routes.|
130
- |capture|hash|specify the capture for matching condition. [more information here](https://github.com/rkh/mustermann)|
131
- |status|integer|specify the status code of response|
132
- |header|hash|specify the header of response|
133
-
134
- ##### Block Parameters
135
-
136
- The block is allowed to pass a parameter.
137
- It will be an instance of Hash.
138
-
139
- ```ruby
140
- pendragon = Pendragon.new do
141
- get("/:id/:foo/:bar"){|params| params.inspect }
142
- end
143
-
144
- request = Rack::MockRequest.env_for("/123/hey/ho")
145
- pendragon.recognize(request).first.call #=> '{id: "123", foo: "hey", bar: "ho"}'
146
- ```
147
-
148
- ### Recognize the route
149
-
150
- The route registered can be recognized by several methods.
151
-
152
- #### `recognize(request)`
153
-
154
- This method returns all the routes that match the conditions.
155
- The format of returns will be such as `[[Pendragon::Route, params], ...]`.
156
- The request must be an instance of `Rack::Request` or Hash created by `Rack::MockRequest.env_for`.
93
+ ### Mounts Rack Application
157
94
 
158
- ```ruby
159
- pendragon = Pendragon.new
160
- index = pendragon.get("/"){ "hello world" }
161
- foo = pendragon.get("/foo/:bar"){ "foo is bar" }
162
-
163
- mock_request = Rack::MockRequest.env_for("/")
164
- route, params = pendragon.recognize(mock_request).first
165
-
166
- route.path == index.path #=> true
167
- params #=> {}
95
+ You can easily mount your rack application onto Pendragon.
168
96
 
169
- mock_request = Rack::MockRequest.env_for("/foo/baz")
170
- route, params = pendragon.recognize(mock_request).first
171
-
172
- route.path == foo.path #=> true
173
- params #=> {bar: "baz"}
174
- ```
175
-
176
- #### `recognize_path(path_info)`
177
-
178
- Recognizes a route from `path_info`.
179
- The method uses `#recognize`, but return value is not same with it.
180
- Maybe this is useful if you set the name to the route.
97
+ *Please note that pendragon distinguishes between processing Proc and Rack Application.*
181
98
 
182
99
  ```ruby
183
- pendragon = Pendragon.new do
184
- get("/", name: :index){ "hello world" }
185
- get("/:id", name: :foo){ "fooooo" }
100
+ class RackApp
101
+ def call(env)
102
+ puts env #=> rack default env
103
+ [200, {}, ['hello']]
104
+ end
186
105
  end
187
106
 
188
- pendragon.recognize_path("/") #=> [:index, {}]
189
- pendragon.recognize_path("/hey") #=> [:foo, {id: "hey"}]
190
- ```
191
-
192
- #### `path(name, *args)`
193
-
194
- Recognizes a route from route's name, and expands the path from parameters.
195
- If you pass a name that does not exist, Pendragon raises `InvalidRouteException`.
196
- The parameters that is not required to expand will be treated as query.
197
-
198
- ```ruby
199
- pendragon = Pendragon.new do
200
- get("/", name: :index){ "hello world" }
201
- get("/:id", name: :foo){ "fooooo" }
107
+ Pendragon.new do
108
+ get '/ids/:id', to: -> (id) { p id } # Block parameters are available
109
+ get '/rack/:id', to: RackApp.new # RackApp#call will be called, `id` is not passed and `env` is passed instead.
202
110
  end
203
-
204
- pendragon.path(:index) #=> "/"
205
- pendragon.path(:foo, id: "123") #=> "/123"
206
- pendragon.path(:foo, id: "123", bar: "hey") #=> "/123?bar=hey"
207
111
  ```
208
112
 
209
- ### Prioritized Routes
113
+ ### Halt
210
114
 
211
- Pendragon supports for respecting route order.
212
- If you want to use this, you should pass the `:order` option to the registration method.
115
+ You can halt to processing by calling `throw :halt` inside your route.
213
116
 
214
117
  ```ruby
215
- pendragon = Pendragon.new do
216
- get("/", order: 1){ "two" }
217
- get("/", order: 0){ "one" }
218
- get("/", order: 2){ "three" }
118
+ Pendragon.new do
119
+ get ?/ do
120
+ throw :halt, [404, {}, ['not found']]
121
+ [200, {}, ['failed to halt']]
122
+ end
219
123
  end
220
-
221
- request = Rack::MockRequest.env_for("/")
222
- pendragon.recognize(request).map{|route, _| route.call } #=> ["one", "two", "three"]
223
124
  ```
224
125
 
225
- ### Passing
126
+ ### Cascading
226
127
 
227
- A route can punt processing to the next matching route using `throw :pass`
128
+ A route can punt to the next matching route by using `X-Cascade` header.
228
129
 
229
130
  ```ruby
230
131
  pendragon = Pendragon.new do
231
- foo = nil
232
- get("/"){ foo = "yay"; throw :pass }
233
- get("/"){ foo }
234
- end
235
-
236
- request = Rack::MockRequest.env_for("/")
237
- pendragon.call(request) #=> [200, {"Content-Type"=>"text/html;charset=utf-8"}, ["yay"]]
238
- ```
239
-
240
- ### With Padrino
241
-
242
- Add `register Pendragon::Padrino` to your padrino application.
243
- Of course, Pendragon has compatibility with Padrino Routing.
244
-
245
-
246
- ```ruby
247
- require 'pendragon/padrino'
248
-
249
- class App < Padrino::Application
250
- register Pendragon::Padrino
251
-
252
- # Also, your app's performance will be improved by using compiler mode.
253
- set :pendragon, enable_compiler: true
254
-
255
- get :index do
256
- "hello pendragon!"
257
- end
258
-
259
- get :users, :map => "/users/:user_id/", :user_id => /\d+/ do |user_id|
260
- params.inspect
132
+ foo = 1
133
+ get ?/ do
134
+ [200, { 'X-Cascade' => 'pass' }, ['']]
261
135
  end
262
136
 
263
- get :user_items, :map => "/users/:user_id/:item_id", :user_id => /\d+/, :item_id => /[1-9]+/ do |user_id, item_id|
264
- "Show #{user_id} and #{item_id}"
137
+ get ?/ do
138
+ [200, {}, ['goal!']]
265
139
  end
266
140
  end
141
+
142
+ env = Rack::MockRequest.env_for(?/)
143
+ pendragon.call(env) #=> [200, {}, ['goal!']]
267
144
  ```
268
145
 
269
146
  ## Contributing