lotus-controller 0.4.4 → 0.4.5

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: b692a62b7c7775da832e5f7367ef67c50a279e1f
4
- data.tar.gz: f24b0ee003fb32a6f063d2e243c1e6eed2c68e83
3
+ metadata.gz: 04ae3ccf09d545e91ee49d06a52dd18ea196871f
4
+ data.tar.gz: 645e47bc4dacb1147cf01007668bd73ece973169
5
5
  SHA512:
6
- metadata.gz: 381a491ce463d8051437e9f186b0181141a135d2eed5d259b0ba54f7abb1cb9f28672ebe7e71553ba553be5ce40982955a60699c38f4510ae07376a99c189eb9
7
- data.tar.gz: 4d23ef2177b9dac081083d51c1bdf2a01b6b6620a752167612e4b7e20bcbb59200592c18d46d981892298d5c7a776590b92d0840b78a8301eb92a56e95d21614
6
+ metadata.gz: cc76f8ea93416a106fb491bdd3168df82722386b85306eabdf73fca31fa20dff7c38f38ebb317b8393f849a54ec56a3c08e774780691a92289bcf2848af70487
7
+ data.tar.gz: 923df9fa385da1b3358ebfc46ed386665e6f3f0814f901a39b960603e32dfead3f1f04e90fcf323d56f9401cbbd2e236d52bd5a3ef1a4d1f61f2659322502090
@@ -1,6 +1,14 @@
1
1
  # Lotus::Controller
2
2
  Complete, fast and testable actions for Rack
3
3
 
4
+ ## v0.4.5 - 2015-09-30
5
+ ### Added
6
+ - [Theo Felippe] Added configuration entries: `#default_request_format` and `default_response_format`.
7
+ - [Wellington Santos] Error handling to take account of inherited exceptions.
8
+
9
+ ### Changed
10
+ - [Theo Felippe] Deprecated `#default_format` in favor of: `#default_request_format`.
11
+
4
12
  ## v0.4.4 - 2015-06-23
5
13
  ### Added
6
14
  - [Luca Guidi] Security protection against Cross Site Request Forgery (CSRF).
data/README.md CHANGED
@@ -432,6 +432,51 @@ action = Articles::Show.new
432
432
  action.call({id: 'unknown'}) # => raises RecordNotFound
433
433
  ```
434
434
 
435
+ #### Inherited Exceptions
436
+
437
+ ```ruby
438
+ class MyCustomException < StandardError
439
+ end
440
+
441
+ module Articles
442
+ class Index
443
+ include Lotus::Action
444
+
445
+ handle_exception MyCustomException => :handle_my_exception
446
+
447
+ def call(params)
448
+ raise MyCustomException
449
+ end
450
+
451
+ private
452
+
453
+ def handle_my_exception
454
+ # ...
455
+ end
456
+ end
457
+
458
+ class Show
459
+ include Lotus::Action
460
+
461
+ handle_exception StandardError => :handle_standard_error
462
+
463
+ def call(params)
464
+ raise MyCustomException
465
+ end
466
+
467
+ private
468
+
469
+ def handle_standard_error
470
+ # ...
471
+ end
472
+ end
473
+ end
474
+
475
+ Articles::Index.new.call({}) # => `handle_my_exception` will be invoked
476
+ Articles::Show.new.call({}) # => `handle_standard_error` will be invoked,
477
+ # because `MyCustomException` inherits from `StandardError`
478
+ ```
479
+
435
480
  ### Throwable HTTP statuses
436
481
 
437
482
  When `#halt` is used with a valid HTTP code, it stops the execution and sets the proper status and body for the response:
@@ -754,7 +799,7 @@ action = Create.new
754
799
  action.call({ article: { title: 'Hello' }}) # => [301, {'Location' => '/articles/23'}, '']
755
800
  ```
756
801
 
757
- ### Mime Types
802
+ ### MIME Types
758
803
 
759
804
  `Lotus::Action` automatically sets the `Content-Type` header, according to the request.
760
805
 
@@ -796,7 +841,7 @@ action.call({ 'HTTP_ACCEPT' => 'text/html' }) # Content-Type "application/json"
796
841
  action.format # :json
797
842
  ```
798
843
 
799
- You can restrict the accepted mime types:
844
+ You can restrict the accepted MIME types:
800
845
 
801
846
  ```ruby
802
847
  class Show
@@ -814,7 +859,7 @@ end
814
859
  # When called with "application/xml" => 406
815
860
  ```
816
861
 
817
- You can check if the requested mime type is accepted by the client.
862
+ You can check if the requested MIME type is accepted by the client.
818
863
 
819
864
  ```ruby
820
865
  class Show
@@ -841,7 +886,7 @@ class Show
841
886
  end
842
887
  ```
843
888
 
844
- Lotus::Controller is shipped with an extensive list of the most common mime types.
889
+ Lotus::Controller is shipped with an extensive list of the most common MIME types.
845
890
  Also, you can register your own:
846
891
 
847
892
  ```ruby
@@ -1002,16 +1047,23 @@ Lotus::Controller.configure do
1002
1047
  #
1003
1048
  handle_exception ArgumentError => 404
1004
1049
 
1005
- # Register a format to mime type mapping
1006
- # Argument: hash, key: format symbol, value: mime type string, empty by default
1050
+ # Register a format to MIME type mapping
1051
+ # Argument: hash, key: format symbol, value: MIME type string, empty by default
1007
1052
  #
1008
1053
  format custom: 'application/custom'
1009
1054
 
1010
- # Define a default format to return in case of HTTP request with `Accept: */*`
1055
+ # Define a fallback format to detect in case of HTTP request with `Accept: */*`
1056
+ # If not defined here, it will return Rack's default: `application/octet-stream`
1057
+ # Argument: symbol, it should be already known. defaults to `nil`
1058
+ #
1059
+ default_request_format :html
1060
+
1061
+ # Define a default format to set as `Content-Type` header for response,
1062
+ # unless otherwise specified.
1011
1063
  # If not defined here, it will return Rack's default: `application/octet-stream`
1012
1064
  # Argument: symbol, it should be already known. defaults to `nil`
1013
1065
  #
1014
- default_format :html
1066
+ default_response_format :html
1015
1067
 
1016
1068
  # Define a default charset to return in the `Content-Type` response header
1017
1069
  # If not defined here, it returns `utf-8`
@@ -28,6 +28,10 @@ module Lotus
28
28
  # @api private
29
29
  COOKIE_STRING_KEY = 'rack.request.cookie_string'.freeze
30
30
 
31
+ # @since 0.4.5
32
+ # @api private
33
+ COOKIE_SEPARATOR = ';,'.freeze
34
+
31
35
  # Initialize the CookieJar
32
36
  #
33
37
  # @param env [Hash] a raw Rack env
@@ -128,7 +132,7 @@ module Lotus
128
132
  string = env[HTTP_HEADER]
129
133
 
130
134
  return hash if string == env[COOKIE_STRING_KEY]
131
- # TODO Next Rack 1.6.x version will have ::Rack::Utils.parse_cookies
135
+ # TODO Next Rack 1.7.x ?? version will have ::Rack::Utils.parse_cookies
132
136
  # We can then replace the following lines.
133
137
  hash.clear
134
138
 
@@ -137,7 +141,7 @@ module Lotus
137
141
  # the Cookie header such that those with more specific Path attributes
138
142
  # precede those with less specific. Ordering with respect to other
139
143
  # attributes (e.g., Domain) is unspecified.
140
- cookies = ::Rack::Utils.parse_query(string, ';,') { |s| ::Rack::Utils.unescape(s) rescue s }
144
+ cookies = ::Rack::Utils.parse_query(string, COOKIE_SEPARATOR) { |s| ::Rack::Utils.unescape(s) rescue s }
141
145
  cookies.each { |k,v| hash[k] = Array === v ? v.first : v }
142
146
  env[COOKIE_STRING_KEY] = string
143
147
  hash
@@ -1,6 +1,7 @@
1
1
  require 'rack/utils'
2
2
  require 'lotus/utils'
3
3
  require 'lotus/utils/kernel'
4
+ require 'lotus/utils/deprecation'
4
5
 
5
6
  module Lotus
6
7
  module Action
@@ -169,7 +170,7 @@ module Lotus
169
170
  # @since 0.1.0
170
171
  #
171
172
  # @see Lotus::Action::Mime#format=
172
- # @see Lotus::Configuration#default_format
173
+ # @see Lotus::Configuration#default_request_format
173
174
  # @see Lotus::Action::Mime#default_content_type
174
175
  # @see Lotus::Action::Mime#DEFAULT_CONTENT_TYPE
175
176
  #
@@ -185,7 +186,7 @@ module Lotus
185
186
  # end
186
187
  # end
187
188
  def content_type
188
- @content_type || accepts || default_content_type || DEFAULT_CONTENT_TYPE
189
+ @content_type || default_response_type || accepts || default_content_type || DEFAULT_CONTENT_TYPE
189
190
  end
190
191
 
191
192
  # Action charset setter, receives new charset value
@@ -421,12 +422,18 @@ module Lotus
421
422
  end
422
423
  end
423
424
 
425
+ # @since 0.5.0
426
+ # @api private
427
+ def default_response_type
428
+ self.class.format_to_mime_type(configuration.default_response_format) if configuration.default_response_format
429
+ end
430
+
424
431
  # @since 0.2.0
425
432
  # @api private
426
433
  def default_content_type
427
434
  self.class.format_to_mime_type(
428
- configuration.default_format
429
- ) if configuration.default_format
435
+ configuration.default_request_format
436
+ ) if configuration.default_request_format
430
437
  end
431
438
 
432
439
  # @since 0.2.0
@@ -191,7 +191,16 @@ module Lotus
191
191
  #
192
192
  # @see Lotus::Controller::Configuration#handle_exception
193
193
  def exception_handler(exception)
194
- @handled_exceptions.fetch(exception.class) { DEFAULT_ERROR_CODE }
194
+ handler = nil
195
+
196
+ @handled_exceptions.each do |exception_class, h|
197
+ if exception.kind_of?(exception_class)
198
+ handler = h
199
+ break
200
+ end
201
+ end
202
+
203
+ handler || DEFAULT_ERROR_CODE
195
204
  end
196
205
 
197
206
  # Check if the given exception is handled.
@@ -409,35 +418,90 @@ module Lotus
409
418
  # an argument, it will set the corresponding instance variable. When
410
419
  # called without, it will return the already set value, or the default.
411
420
  #
412
- # @overload default_format(format)
421
+ # @overload default_request_format(format)
413
422
  # Sets the given value
414
423
  # @param format [#to_sym] the symbol format
415
424
  # @raise [TypeError] if it cannot be coerced to a symbol
416
425
  #
417
- # @overload default_format
426
+ # @overload default_request_format
418
427
  # Gets the value
419
428
  # @return [Symbol,nil]
420
429
  #
421
- # @since 0.2.0
430
+ # @since 0.5.0
422
431
  #
423
432
  # @see Lotus::Action::Mime
424
433
  #
425
434
  # @example Getting the value
426
435
  # require 'lotus/controller'
427
436
  #
428
- # Lotus::Controller.configuration.default_format # => nil
437
+ # Lotus::Controller.configuration.default_request_format # => nil
429
438
  #
430
439
  # @example Setting the value
431
440
  # require 'lotus/controller'
432
441
  #
433
442
  # Lotus::Controller.configure do
434
- # default_format :html
443
+ # default_request_format :html
435
444
  # end
445
+ def default_request_format(format = nil)
446
+ if format
447
+ @default_request_format = Utils::Kernel.Symbol(format)
448
+ else
449
+ @default_request_format
450
+ end
451
+ end
452
+
453
+ # Set a format as default fallback for all the requests without a strict
454
+ # requirement for the mime type.
455
+ #
456
+ # @since 0.2.0
457
+ #
458
+ # @deprecated Use {#default_request_format} instead.
436
459
  def default_format(format = nil)
460
+ Lotus::Utils::Deprecation.new('default_format is deprecated, please use default_request_format')
461
+ default_request_format(format)
462
+ end
463
+
464
+ # Set a format to be used for all responses regardless of the request type.
465
+ #
466
+ # The given format must be coercible to a symbol, and be a valid mime type
467
+ # alias. If it isn't, at the runtime the framework will raise a
468
+ # `Lotus::Controller::UnknownFormatError`.
469
+ #
470
+ # By default this value is nil.
471
+ #
472
+ # This is part of a DSL, for this reason when this method is called with
473
+ # an argument, it will set the corresponding instance variable. When
474
+ # called without, it will return the already set value, or the default.
475
+ #
476
+ # @overload default_response_format(format)
477
+ # Sets the given value
478
+ # @param format [#to_sym] the symbol format
479
+ # @raise [TypeError] if it cannot be coerced to a symbol
480
+ #
481
+ # @overload default_response_format
482
+ # Gets the value
483
+ # @return [Symbol,nil]
484
+ #
485
+ # @since 0.5.0
486
+ #
487
+ # @see Lotus::Action::Mime
488
+ #
489
+ # @example Getting the value
490
+ # require 'lotus/controller'
491
+ #
492
+ # Lotus::Controller.configuration.default_response_format # => nil
493
+ #
494
+ # @example Setting the value
495
+ # require 'lotus/controller'
496
+ #
497
+ # Lotus::Controller.configure do
498
+ # default_response_format :json
499
+ # end
500
+ def default_response_format(format = nil)
437
501
  if format
438
- @default_format = Utils::Kernel.Symbol(format)
502
+ @default_response_format = Utils::Kernel.Symbol(format)
439
503
  else
440
- @default_format
504
+ @default_response_format
441
505
  end
442
506
  end
443
507
 
@@ -569,7 +633,8 @@ module Lotus
569
633
  c.action_module = action_module
570
634
  c.modules = modules.dup
571
635
  c.formats = formats.dup
572
- c.default_format = default_format
636
+ c.default_request_format = default_request_format
637
+ c.default_response_format = default_response_format
573
638
  c.default_charset = default_charset
574
639
  c.default_headers = default_headers.dup
575
640
  c.cookies = cookies.dup
@@ -591,15 +656,16 @@ module Lotus
591
656
  # @since 0.2.0
592
657
  # @api private
593
658
  def reset!
594
- @handle_exceptions = true
595
- @handled_exceptions = {}
596
- @modules = []
597
- @formats = DEFAULT_FORMATS.dup
598
- @default_format = nil
599
- @default_charset = nil
600
- @default_headers = {}
601
- @cookies = {}
602
- @action_module = ::Lotus::Action
659
+ @handle_exceptions = true
660
+ @handled_exceptions = {}
661
+ @modules = []
662
+ @formats = DEFAULT_FORMATS.dup
663
+ @default_request_format = nil
664
+ @default_response_format = nil
665
+ @default_charset = nil
666
+ @default_headers = {}
667
+ @cookies = {}
668
+ @action_module = ::Lotus::Action
603
669
  end
604
670
 
605
671
  # Copy the configuration for the given action
@@ -632,7 +698,8 @@ module Lotus
632
698
  attr_accessor :formats
633
699
  attr_writer :action_module
634
700
  attr_writer :modules
635
- attr_writer :default_format
701
+ attr_writer :default_request_format
702
+ attr_writer :default_response_format
636
703
  attr_writer :default_charset
637
704
  attr_writer :default_headers
638
705
  attr_writer :cookies
@@ -3,6 +3,6 @@ module Lotus
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '0.4.4'.freeze
6
+ VERSION = '0.4.5'.freeze
7
7
  end
8
8
  end
@@ -6,8 +6,8 @@ require 'lotus/controller/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'lotus-controller'
8
8
  spec.version = Lotus::Controller::VERSION
9
- spec.authors = ['Luca Guidi', 'Trung Lê']
10
- spec.email = ['me@lucaguidi.com', 'trung.le@ruby-journal.com']
9
+ spec.authors = ['Luca Guidi', 'Trung Lê', 'Alfonso Uceda']
10
+ spec.email = ['me@lucaguidi.com', 'trung.le@ruby-journal.com', 'uceda73@gmail.com']
11
11
  spec.description = %q{Complete, fast and testable actions for Rack}
12
12
  spec.summary = %q{Complete, fast and testable actions for Rack and Lotus}
13
13
  spec.homepage = 'http://lotusrb.org'
@@ -19,9 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
  spec.required_ruby_version = '>= 2.0.0'
21
21
 
22
- spec.add_dependency 'rack', '~> 1.5'
22
+ spec.add_dependency 'rack', '~> 1.6', '>= 1.6.2'
23
23
  spec.add_dependency 'lotus-utils', '~> 0.5'
24
- spec.add_dependency 'lotus-validations', '~> 0.3'
24
+ spec.add_dependency 'lotus-validations', '~> 0.3', '>= 0.3.3'
25
25
 
26
26
  spec.add_development_dependency 'bundler', '~> 1.6'
27
27
  spec.add_development_dependency 'minitest', '~> 5'
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lotus-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  - Trung Lê
9
+ - Alfonso Uceda
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2015-06-23 00:00:00.000000000 Z
13
+ date: 2015-09-30 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: rack
@@ -17,14 +18,20 @@ dependencies:
17
18
  requirements:
18
19
  - - "~>"
19
20
  - !ruby/object:Gem::Version
20
- version: '1.5'
21
+ version: '1.6'
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.6.2
21
25
  type: :runtime
22
26
  prerelease: false
23
27
  version_requirements: !ruby/object:Gem::Requirement
24
28
  requirements:
25
29
  - - "~>"
26
30
  - !ruby/object:Gem::Version
27
- version: '1.5'
31
+ version: '1.6'
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 1.6.2
28
35
  - !ruby/object:Gem::Dependency
29
36
  name: lotus-utils
30
37
  requirement: !ruby/object:Gem::Requirement
@@ -46,6 +53,9 @@ dependencies:
46
53
  - - "~>"
47
54
  - !ruby/object:Gem::Version
48
55
  version: '0.3'
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 0.3.3
49
59
  type: :runtime
50
60
  prerelease: false
51
61
  version_requirements: !ruby/object:Gem::Requirement
@@ -53,6 +63,9 @@ dependencies:
53
63
  - - "~>"
54
64
  - !ruby/object:Gem::Version
55
65
  version: '0.3'
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.3
56
69
  - !ruby/object:Gem::Dependency
57
70
  name: bundler
58
71
  requirement: !ruby/object:Gem::Requirement
@@ -113,6 +126,7 @@ description: Complete, fast and testable actions for Rack
113
126
  email:
114
127
  - me@lucaguidi.com
115
128
  - trung.le@ruby-journal.com
129
+ - uceda73@gmail.com
116
130
  executables: []
117
131
  extensions: []
118
132
  extra_rdoc_files: []
@@ -171,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
171
185
  version: '0'
172
186
  requirements: []
173
187
  rubyforge_project:
174
- rubygems_version: 2.4.8
188
+ rubygems_version: 2.4.5.1
175
189
  signing_key:
176
190
  specification_version: 4
177
191
  summary: Complete, fast and testable actions for Rack and Lotus