lotus-router 0.1.0 → 0.1.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: ff45eb9a0d8db10815f562e9d5af4e5cf2649b7a
4
- data.tar.gz: 3a6e353ac3840fc2bab5a0324ec50294493efa20
3
+ metadata.gz: 7ded3effb55d8697f3a45666539825d205771161
4
+ data.tar.gz: ac9b49d12b41b64e694998e4c663895f81279921
5
5
  SHA512:
6
- metadata.gz: 5aba74771a3578cb3654a687b428e9fdca6bbdc2cc186dc1777ff28b9862a4a9f50d7daa9de80fbfc191bcf67ca3ab35eabfdcdbffedfb9d0043aa62601d8b72
7
- data.tar.gz: e0d18ad2c7e1cdb275a58871a321cd635b383c1c6308635cfeab29bfe5859e62eeeab0c728414ba118601787855a3b3e01fc602120ddf0c45304af63b20d84e4
6
+ metadata.gz: 1542eba77ef0f590dd88f9abe472760f09e14375796867dd031bd360bf2e19b4056c8b89c03b32bb45542a23616f6c502df2382a8dc19441b16b5eb0dc657223
7
+ data.tar.gz: ea54e84f9c8507fd70d0c5c3e7f946930444d612dfc89012215d56a7ab55518658599dd0707dbb4da2358f1904d2717b27165f1ce9f77c9f40fdfc1626adb44e
data/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ ## v0.1.1
2
+ ### Jun 23, 2014
3
+
4
+ 6f0ea8b 2014-06-12 **Luca Guidi** Introduced Lotus::Router#mount
5
+ 8457e1c 2014-06-08 **Luca Guidi** Use composition over inheritance for Lotus::Routing::Resource::Options
6
+ 9426099 2014-05-13 **Luca Guidi** Let specify a pattern for Lotus::Routing::EndpointResolver
7
+ 340ce17 2014-05-10 **Luca Guidi** Enable Ruby 2.1.2 on Travis CI
8
+ 42b83b8 2014-02-24 **Luca Guidi** Added support for Ruby 2.1.1
9
+ 6a5daf9 2014-02-15 **Luca Guidi** Make Lotus::Routing::Endpoint::EndpointNotFound to inherit from StandardError, instead of Exception. This make it compatible with Rack::ShowExceptions.
10
+
11
+ ## v0.1.0
12
+ ### Jan 23, 2014
13
+
14
+ 594e332 2014-01-23 **Luca Guidi** Added support for OPTIONS HTTP verb
15
+ 10af04b 2014-01-17 **Luca Guidi** Added Lotus::Routing::EndpointNotFound when a lazy endpoint can't be found
16
+ 72165e5 2014-01-17 **Luca Guidi** Make action separator customizable via Lotus::Router options.
17
+ ca7ea8d 2014-01-17 **Luca Guidi** Catch http_router exceptions and re-raise them with names under Lotus::Routing. This helps to have a stable public API.
18
+ 3d678e3 2014-01-16 **Luca Guidi** Lotus::Router now encapsulates Lotus::Routing::HttpRouter, instead of directly inherit from HttpRouter. This will protect our public API against HttpRouter changes.
19
+ 8e8f7f9 2014-01-16 **Luca Guidi** Lotus::Routing::Resource::CollectionAction use configurable controller and action name separator over the hardcoded value
20
+ 0bc8e54 2014-01-10 **Luca Guidi** Implemented Lotus::Routing::Namespace#resource
21
+ e134e5c 2014-01-08 **Luca Guidi** Simplify Lotus::Router public API: removed .draw and let .new to accept a block
22
+ 815391a 2014-01-07 **Luca Guidi** When resetting the router, allow the default values for scheme, host and port to be reinitialized as http_router does
23
+ bc763a8 2013-08-07 **Luca Guidi** Lotus::Routing::EndpointResolver now accepts options to inject namespace and suffix
24
+ 153047f 2013-08-07 **Luca Guidi** Allow resolver and route class to be injected via options. Added options argument to .draw
25
+ cd1128f 2013-08-07 **Luca Guidi** Lotus::EndpointResolver => Lotus::Routing::EndpointResolver
26
+ 96a67c1 2013-07-09 **Luca Guidi** Return 404 for not found and 405 for unacceptable HTTP method
27
+ 7450883 2013-07-05 **Luca Guidi** Allow non-finished Rack responses to be used
28
+ aa92524 2013-06-24 **Luca Guidi** Ensure .draw to always return a Lotus::Router instance
29
+ 30029af 2013-06-22 **Luca Guidi** Implemented lazy loading for endpoints
30
+ 962fbdf 2013-06-21 **Luca Guidi** Implemented Lotus::Router.draw
31
+ 982d95a 2013-06-20 **Luca Guidi** Gemified
32
+ bac478a 2013-06-20 **Luca Guidi** Massive cleanup
33
+ aaf46a1 2013-06-20 **Luca Guidi** Add support for resource
34
+ 41ee67d 2013-06-20 **Luca Guidi** Drastically reduced LOCs :heart_eyes:
35
+ 6b245bf 2013-06-19 **Luca Guidi** Support for resource's member and collection
36
+ 727e997 2013-06-19 **Luca Guidi** Add support for namespaces
37
+ 4950777 2013-06-18 **Luca Guidi** Added support for RESTful resources
38
+ c494c85 2013-06-18 **Luca Guidi** Add support for POST, DELETE, PUT, PATCH, TRACE
39
+ 71fb4a1 2013-06-17 **Luca Guidi** Routes constraints
40
+ 86d696a 2013-06-17 **Luca Guidi** Named urls
41
+ 423cf2c 2013-06-17 **Luca Guidi** Ensure redirect works properly
42
+ 1ee662a 2013-06-17 **Luca Guidi** Run all the test suite
43
+ e2382a0 2013-06-16 **Luca Guidi** Add support for Procs:
44
+ f397aac 2013-06-16 **Luca Guidi** Implemented redirect
45
+ dded0c5 2013-06-14 **Luca Guidi** Initial mess
File without changes
data/README.md CHANGED
@@ -4,11 +4,12 @@ Rack compatible, lightweight and fast HTTP Router for [Lotus](http://lotusrb.org
4
4
 
5
5
  ## Status
6
6
 
7
- [![Gem Version](https://badge.fury.io/rb/lotus-router.png)](http://badge.fury.io/rb/lotus-router)
8
- [![Build Status](https://secure.travis-ci.org/lotus/router.png?branch=master)](http://travis-ci.org/lotus/router?branch=master)
9
- [![Coverage](https://coveralls.io/repos/lotus/router/badge.png?branch=master)](https://coveralls.io/r/lotus/router)
10
- [![Code Climate](https://codeclimate.com/github/lotus/router.png)](https://codeclimate.com/github/lotus/router)
11
- [![Dependencies](https://gemnasium.com/lotus/router.png)](https://gemnasium.com/lotus/router)
7
+ [![Gem Version](http://img.shields.io/gem/v/lotus-router.svg)](https://badge.fury.io/rb/lotus-router)
8
+ [![Build Status](http://img.shields.io/travis/lotus/router/master.svg)](https://travis-ci.org/lotus/router?branch=master)
9
+ [![Coverage](http://img.shields.io/coveralls/lotus/router/master.svg)](https://coveralls.io/r/lotus/router)
10
+ [![Code Climate](http://img.shields.io/codeclimate/github/lotus/router.svg)](https://codeclimate.com/github/lotus/router)
11
+ [![Dependencies](http://img.shields.io/gemnasium/lotus/router.svg)](https://gemnasium.com/lotus/router)
12
+ [![Inline docs](http://inch-ci.org/github/lotus/router.png)](http://inch-ci.org/github/lotus/router)
12
13
 
13
14
  ## Contact
14
15
 
@@ -16,7 +17,8 @@ Rack compatible, lightweight and fast HTTP Router for [Lotus](http://lotusrb.org
16
17
  * Mailing List: http://lotusrb.org/mailing-list
17
18
  * API Doc: http://rdoc.info/gems/lotus-router
18
19
  * Bugs/Issues: https://github.com/lotus/router/issues
19
- * Support: http://stackoverflow.com/questions/tagged/lotusrb
20
+ * Support: http://stackoverflow.com/questions/tagged/lotus-ruby
21
+ * Chat: https://gitter.im/lotus/chat
20
22
 
21
23
  ## Rubies
22
24
 
@@ -74,6 +76,8 @@ Lotus::Router.new do
74
76
 
75
77
  redirect '/legacy', to: '/'
76
78
 
79
+ mount Api::App, to: '/api'
80
+
77
81
  namespace 'admin' do
78
82
  get '/users', to: UsersController::Index
79
83
  end
@@ -129,7 +133,7 @@ router.get '/flowers/:id', id: /\d+/, to: ->(env) { [200, {}, [":id must be a nu
129
133
 
130
134
 
131
135
 
132
- ### String matching with globbling:
136
+ ### String matching with globbing:
133
137
 
134
138
  ```ruby
135
139
  router = Lotus::Router.new
@@ -206,6 +210,26 @@ router.path(:animals_mammals_cats) # => "/animals/mammals/cats"
206
210
 
207
211
 
208
212
 
213
+ ### Mount Rack applications:
214
+
215
+ ```ruby
216
+ Lotus::Router.new do
217
+ mount RackOne, at: '/rack1'
218
+ mount RackTwo, at: '/rack2'
219
+ mount RackThree.new, at: '/rack3'
220
+ mount ->(env) {[200, {}, ['Rack Four']]}, at: '/rack4'
221
+ mount 'dashboard#index', at: '/dashboard'
222
+ end
223
+ ```
224
+
225
+ 1. `RackOne` is used as it is (class), because it respond to `.call`
226
+ 2. `RackTwo` is initialized, because it respond to `#call`
227
+ 3. `RackThree` is used as it is (object), because it respond to `#call`
228
+ 4. That Proc is used as it is, because it respond to `#call`
229
+ 5. That string is resolved as `DashboardController::Index` ([Lotus::Controller](https://github.com/lotus/controller) integration)
230
+
231
+
232
+
209
233
  ### Duck typed endpoints:
210
234
 
211
235
  Everything that responds to `#call` is invoked as it is:
@@ -325,7 +349,7 @@ If you don't need all the default endpoints, just do:
325
349
  router = Lotus::Router.new
326
350
  router.resource 'identity', only: [:edit, :update]
327
351
 
328
- # which is equivalent to:
352
+ #### which is equivalent to:
329
353
 
330
354
  router.resource 'identity', except: [:show, :new, :create, :destroy]
331
355
  ```
@@ -434,7 +458,7 @@ If you don't need all the default endpoints, just do:
434
458
  router = Lotus::Router.new
435
459
  router.resources 'flowers', only: [:new, :create, :show]
436
460
 
437
- # which is equivalent to:
461
+ #### which is equivalent to:
438
462
 
439
463
  router.resources 'flowers', except: [:index, :edit, :update, :destroy]
440
464
  ```
data/lib/lotus/router.rb CHANGED
@@ -75,6 +75,15 @@ module Lotus
75
75
  #
76
76
  # # This isn't mandatory for the default route class (`Lotus::Routing::Route`),
77
77
  # # This behavior can be changed by passing a custom route to `Lotus::Router#initialize`
78
+ #
79
+ # @example Mount an application
80
+ # require 'lotus/router'
81
+ #
82
+ # router = Lotus::Router.new do
83
+ # mount Api::App, at: '/api'
84
+ # end
85
+ #
86
+ # # All the requests starting with "/api" will be forwarded to Api::App
78
87
  class Router
79
88
  # Initialize the router.
80
89
  #
@@ -688,6 +697,95 @@ module Lotus
688
697
  Routing::Resources.new(self, name, options.merge(separator: @router.action_separator), &blk)
689
698
  end
690
699
 
700
+ # Mount a Rack application at the specified path.
701
+ # All the requests starting with the specified path, will be forwarded to
702
+ # the given application.
703
+ #
704
+ # All the other methods (eg #get) support callable objects, but they
705
+ # restrict the range of the acceptable HTTP verb. Mounting an application
706
+ # with #mount doesn't apply this kind of restriction at the router level,
707
+ # but let the application to decide.
708
+ #
709
+ # @param app [#call] a class or an object that responds to #call
710
+ # @param options [Hash] the options to customize the mount
711
+ # @option options [:at] the path prefix where to mount the app
712
+ #
713
+ # @since 0.1.1
714
+ #
715
+ # @example Basic usage
716
+ # require 'lotus/router'
717
+ #
718
+ # Lotus::Router.new do
719
+ # mount Api::App.new, at: '/api'
720
+ # end
721
+ #
722
+ # # Requests:
723
+ # #
724
+ # # GET /api # => 200
725
+ # # GET /api/articles # => 200
726
+ # # POST /api/articles # => 200
727
+ # # GET /api/unknown # => 404
728
+ #
729
+ # @example Difference between #get and #mount
730
+ # require 'lotus/router'
731
+ #
732
+ # Lotus::Router.new do
733
+ # get '/rack1', to: RackOne.new
734
+ # mount RackTwo.new, at: '/rack2'
735
+ # end
736
+ #
737
+ # # Requests:
738
+ # #
739
+ # # # /rack1 will only accept GET
740
+ # # GET /rack1 # => 200 (RackOne.new)
741
+ # # POST /rack1 # => 405
742
+ # #
743
+ # # # /rack2 accepts all the verbs and delegate the decision to RackTwo
744
+ # # GET /rack2 # => 200 (RackTwo.new)
745
+ # # POST /rack2 # => 200 (RackTwo.new)
746
+ #
747
+ # @example Types of mountable applications
748
+ # require 'lotus/router'
749
+ #
750
+ # class RackOne
751
+ # def self.call(env)
752
+ # end
753
+ # end
754
+ #
755
+ # class RackTwo
756
+ # def call(env)
757
+ # end
758
+ # end
759
+ #
760
+ # class RackThree
761
+ # def call(env)
762
+ # end
763
+ # end
764
+ #
765
+ # class DashboardController
766
+ # class Index
767
+ # def call(env)
768
+ # end
769
+ # end
770
+ # end
771
+ #
772
+ # Lotus::Router.new do
773
+ # mount RackOne, at: '/rack1'
774
+ # mount RackTwo, at: '/rack2'
775
+ # mount RackThree.new, at: '/rack3'
776
+ # mount ->(env) {[200, {}, ['Rack Four']]}, at: '/rack4'
777
+ # mount 'dashboard#index', at: '/dashboard'
778
+ # end
779
+ #
780
+ # # 1. RackOne is used as it is (class), because it respond to .call
781
+ # # 2. RackTwo is initialized, because it respond to #call
782
+ # # 3. RackThree is used as it is (object), because it respond to #call
783
+ # # 4. That Proc is used as it is, because it respond to #call
784
+ # # 5. That string is resolved as DashboardController::Index (Lotus::Controller)
785
+ def mount(app, options)
786
+ @router.mount(app, options)
787
+ end
788
+
691
789
  # Resolve the given Rack env to a registered endpoint and invoke it.
692
790
  #
693
791
  # @param env [Hash] a Rack env instance
@@ -1,5 +1,5 @@
1
1
  module Lotus
2
2
  class Router
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
4
  end
5
5
  end
@@ -7,7 +7,7 @@ module Lotus
7
7
  # This is raised when the router fails to load an endpoint at the runtime.
8
8
  #
9
9
  # @since 0.1.0
10
- class EndpointNotFound < ::Exception
10
+ class EndpointNotFound < ::StandardError
11
11
  end
12
12
 
13
13
  # Routing endpoint
@@ -26,7 +26,7 @@ module Lotus
26
26
  # end
27
27
  #
28
28
  # # That string is transformed into "Articles(::Controller::|Controller::)Show"
29
- # # because the risolver is able to lookup (in the given order) for:
29
+ # # because the resolver is able to lookup (in the given order) for:
30
30
  # #
31
31
  # # * Articles::Controller::Show
32
32
  # # * ArticlesController::Show
@@ -65,6 +65,11 @@ module Lotus
65
65
  # @option options [String] :suffix the suffix appended to the controller
66
66
  # name during the lookup. (defaults to `SUFFIX`)
67
67
  #
68
+ # @option options [String] :pattern the string to interpolate in order
69
+ # to return an action name. Please note that this option override
70
+ # :suffix. This string SHOULD contain `'%{controller}'` and `'%{action}'`,
71
+ # all the other keys will be ignored. See the examples below.
72
+ #
68
73
  # @option options [String] :action_separator the sepatator between controller and
69
74
  # action name. (defaults to `ACTION_SEPARATOR`)
70
75
  #
@@ -114,6 +119,18 @@ module Lotus
114
119
  #
115
120
  #
116
121
  #
122
+ # @example Specify custom simple pattern
123
+ # require 'lotus/router'
124
+ #
125
+ # resolver = Lotus::Routing::EndpointResolver.new(pattern: 'Controllers::%{controller}::%{action}')
126
+ # router = Lotus::Router.new(resolver: resolver)
127
+ #
128
+ # router.get('/', to: 'articles#show')
129
+ # # => Will look for:
130
+ # # * Controllers::Articles::Show
131
+ #
132
+ #
133
+ #
117
134
  # @example Specify custom controller-action separator
118
135
  # require 'lotus/router'
119
136
  #
@@ -127,8 +144,9 @@ module Lotus
127
144
  def initialize(options = {})
128
145
  @endpoint_class = options[:endpoint] || Endpoint
129
146
  @namespace = options[:namespace] || Object
130
- @suffix = options[:suffix] || SUFFIX
131
147
  @action_separator = options[:action_separator] || ACTION_SEPARATOR
148
+ @pattern = options[:pattern] ||
149
+ "%{controller}#{options[:suffix] || SUFFIX}%{action}"
132
150
  end
133
151
 
134
152
  # Resolve the given set of HTTP verb, path, endpoint and options.
@@ -229,6 +247,8 @@ module Lotus
229
247
  def resolve_callable(callable)
230
248
  if callable.respond_to?(:call)
231
249
  @endpoint_class.new(callable)
250
+ elsif callable.is_a?(Class) && callable.instance_methods.include?(:call)
251
+ @endpoint_class.new(callable.new)
232
252
  end
233
253
  end
234
254
 
@@ -243,7 +263,7 @@ module Lotus
243
263
  def resolve_action(string)
244
264
  if string.match(action_separator)
245
265
  controller, action = string.split(action_separator).map {|token| classify(token) }
246
- controller + @suffix + action
266
+ @pattern % {controller: controller, action: action}
247
267
  end
248
268
  end
249
269
  end
@@ -93,6 +93,18 @@ module Lotus
93
93
  add_with_request_method(path, :options, options, &blk)
94
94
  end
95
95
 
96
+ # Allow to mount a Rack app
97
+ #
98
+ # @see Lotus::Router#mount
99
+ #
100
+ # @since 0.1.1
101
+ # @api private
102
+ def mount(app, options)
103
+ add("#{ options.fetch(:at) }*").to(
104
+ @resolver.resolve(to: app)
105
+ )
106
+ end
107
+
96
108
  # @api private
97
109
  def reset!
98
110
  uncompile
@@ -8,7 +8,7 @@ module Lotus
8
8
  #
9
9
  # @see Lotus::Router#resource
10
10
  # @see Lotus::Router#resources
11
- class Options < Hash
11
+ class Options
12
12
  # @api private
13
13
  # @since 0.1.0
14
14
  attr_reader :actions
@@ -40,7 +40,32 @@ module Lotus
40
40
  except = Array(options.delete(:except))
41
41
  @actions = ( actions & only ) - except
42
42
 
43
- merge! options
43
+ @options = options
44
+ end
45
+
46
+ # Return the option for the given key
47
+ #
48
+ # @param key [Symbol] the key that should be searched
49
+ #
50
+ # @return [Object,nil] returns the object associated to the given key
51
+ # or nil, if missing.
52
+ #
53
+ # @api private
54
+ # @since 0.1.1
55
+ def [](key)
56
+ @options[key]
57
+ end
58
+
59
+ # Merge the current options with the given hash, without mutating self.
60
+ #
61
+ # @param hash [Hash] the hash to be merged
62
+ #
63
+ # @return [Hash] the result of the merging operation
64
+ #
65
+ # @api private
66
+ # @since 0.1.1
67
+ def merge(hash)
68
+ @options.merge(hash)
44
69
  end
45
70
  end
46
71
  end
data/lotus-router.gemspec CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'http://lotusrb.org'
14
14
  spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ spec.files = `git ls-files -- lib/* CHANGELOG.md LICENSE.md README.md lotus-router.gemspec`.split($/)
17
17
  spec.executables = []
18
18
  spec.test_files = spec.files.grep(%r{^(test)/})
19
19
  spec.require_paths = ['lib']
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lotus-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-23 00:00:00.000000000 Z
11
+ date: 2014-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http_router
@@ -87,21 +87,9 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - ".coveralls.yml"
91
- - ".gitignore"
92
- - ".travis.yml"
93
- - ".yardopts"
94
- - Gemfile
95
- - LICENSE.txt
90
+ - CHANGELOG.md
91
+ - LICENSE.md
96
92
  - README.md
97
- - Rakefile
98
- - benchmarks/callable
99
- - benchmarks/named_routes
100
- - benchmarks/resource
101
- - benchmarks/resources
102
- - benchmarks/routes
103
- - benchmarks/run.sh
104
- - benchmarks/utils.rb
105
93
  - lib/lotus-router.rb
106
94
  - lib/lotus/router.rb
107
95
  - lib/lotus/router/version.rb
@@ -116,20 +104,6 @@ files:
116
104
  - lib/lotus/routing/resources/action.rb
117
105
  - lib/lotus/routing/route.rb
118
106
  - lotus-router.gemspec
119
- - test/fixtures.rb
120
- - test/integration/client_error_test.rb
121
- - test/integration/pass_on_response_test.rb
122
- - test/named_routes_test.rb
123
- - test/namespace_test.rb
124
- - test/new_test.rb
125
- - test/redirect_test.rb
126
- - test/resource_test.rb
127
- - test/resources_test.rb
128
- - test/routing/endpoint_resolver_test.rb
129
- - test/routing/resource/options_test.rb
130
- - test/routing_test.rb
131
- - test/test_helper.rb
132
- - test/version_test.rb
133
107
  homepage: http://lotusrb.org
134
108
  licenses:
135
109
  - MIT
@@ -150,23 +124,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
124
  version: '0'
151
125
  requirements: []
152
126
  rubyforge_project:
153
- rubygems_version: 2.2.0
127
+ rubygems_version: 2.2.2
154
128
  signing_key:
155
129
  specification_version: 4
156
130
  summary: Ruby HTTP Router for Lotus
157
- test_files:
158
- - test/fixtures.rb
159
- - test/integration/client_error_test.rb
160
- - test/integration/pass_on_response_test.rb
161
- - test/named_routes_test.rb
162
- - test/namespace_test.rb
163
- - test/new_test.rb
164
- - test/redirect_test.rb
165
- - test/resource_test.rb
166
- - test/resources_test.rb
167
- - test/routing/endpoint_resolver_test.rb
168
- - test/routing/resource/options_test.rb
169
- - test/routing_test.rb
170
- - test/test_helper.rb
171
- - test/version_test.rb
131
+ test_files: []
172
132
  has_rdoc: