hanami-controller 0.8.1 → 1.0.0.beta1

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: 94316cf20a120464d9314f31c0ea0774d8256847
4
- data.tar.gz: 0d468b04cc1ae458ee3d2cb1188adfae48e63402
3
+ metadata.gz: 0f0fb43da2ad920ba9c799b41f4ccfc87eb5b438
4
+ data.tar.gz: 294e4ed9ebf6e18c13c52d560efb181f69ded99b
5
5
  SHA512:
6
- metadata.gz: 68a1d9c7ae87c693fa7a9ac85ae15b0736bdd1de6dc02f21a9ef320a08f6f1f9b0fc3e99b88a92186c7e1ebc5ebf48cb52b914a400f655c1699b12bdb8bbe61b
7
- data.tar.gz: b49bfaff6ee7d1150f1f1e99ea335948300d519c8522b200dc0b914ddc7a0d3f7ee9c9778fdc79abfa267998987aa65216f9f2488e09db2b9c1321bb5fc2b69b
6
+ metadata.gz: 6b7ce52381b3e383caf8a169f9c40af67e8a8a546503c89d0b3b7642fe8e36321ab3bf5bee8d844d9e26ace64d5c1c49f894f642b469dcac63c712d5025246b0
7
+ data.tar.gz: f6e6cfe2e117ce0d3946b308b2684dfd53ae31783510ec143f10cd9959e671338abe613bc70ef2070a2c5ecdd1383fbcffad76070cfd76e457ebf218be22759e
data/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Hanami::Controller
2
2
  Complete, fast and testable actions for Rack
3
3
 
4
+ ## v1.0.0beta1 - 2017-02-14
5
+ ### Added
6
+ - [Luca Guidi] Official support for Ruby: MRI 2.4
7
+
8
+ ### Fixed
9
+ - [Marcello Rocha & Luca Guidi] Avoid MIME type conflicts for `Action#format` detection
10
+ - [Matias H. Leidemer & Luca Guidi] Ensure `Flash` to return only fresh data
11
+ - [Luca Guidi] Ensure `session` keys to be accessed as symbols in action unit tests
12
+
13
+ ### Changed
14
+ - [Anton Davydov & Luca Guidi] Make it work only with Rack 2.0
15
+
4
16
  ## v0.8.1 - 2016-12-19
5
17
  ### Fixed
6
18
  - [Thorbjørn Hermansen] Don't pollute Rack env's `rack.exception` key if an exception is handled
data/README.md CHANGED
@@ -282,7 +282,7 @@ class Show
282
282
  expose :article
283
283
 
284
284
  def call(params)
285
- @article = ArticleRepository.find params[:id]
285
+ @article = ArticleRepository.new.find(params[:id])
286
286
  end
287
287
  end
288
288
 
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ['lib']
20
20
  spec.required_ruby_version = '>= 2.3.0'
21
21
 
22
- spec.add_dependency 'rack', '~> 1.6', '>= 1.6.2'
23
- spec.add_dependency 'hanami-utils', '~> 0.9'
22
+ spec.add_dependency 'rack', '~> 2.0'
23
+ spec.add_dependency 'hanami-utils', '~> 1.0.0.beta1'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.6'
26
26
  spec.add_development_dependency 'rack-test', '~> 0.6'
@@ -15,6 +15,18 @@ module Hanami
15
15
  # @since 0.7.0
16
16
  ROUTER_PARAMS = 'router.params'.freeze
17
17
 
18
+ # The key that returns Rack session params from the Rack env
19
+ # Please note that this is used only when an action is unit tested.
20
+ #
21
+ # @since 1.0.0.beta1
22
+ # @api private
23
+ #
24
+ # @example
25
+ # # action unit test
26
+ # action.call('rack.session' => { 'foo' => 'bar' })
27
+ # action.session[:foo] # => "bar"
28
+ RACK_SESSION = 'rack.session'.freeze
29
+
18
30
  # @attr_reader env [Hash] the Rack env
19
31
  #
20
32
  # @since 0.7.0
@@ -37,7 +49,7 @@ module Hanami
37
49
  def initialize(env)
38
50
  @env = env
39
51
  @raw = _extract_params
40
- @params = Utils::Hash.new(@raw).deep_dup.symbolize!.to_h
52
+ @params = Utils::Hash.new(@raw).deep_dup.deep_symbolize!.to_h
41
53
  freeze
42
54
  end
43
55
 
@@ -143,7 +155,13 @@ module Hanami
143
155
  # @since 0.7.0
144
156
  # @api private
145
157
  def _router_params(fallback = {})
146
- env.fetch(ROUTER_PARAMS, fallback)
158
+ env.fetch(ROUTER_PARAMS) do
159
+ if session = fallback.delete(RACK_SESSION) # rubocop:disable Lint/AssignmentInCondition
160
+ fallback[RACK_SESSION] = Utils::Hash.new(session).symbolize!.to_hash
161
+ end
162
+
163
+ fallback
164
+ end
147
165
  end
148
166
  end
149
167
  end
@@ -55,7 +55,7 @@ module Hanami
55
55
  # @since 0.1.0
56
56
  def initialize(env, headers, default_options)
57
57
  @_headers = headers
58
- @cookies = Utils::Hash.new(extract(env)).symbolize!
58
+ @cookies = Utils::Hash.new(extract(env)).deep_symbolize!
59
59
  @default_options = default_options
60
60
  end
61
61
 
@@ -142,7 +142,7 @@ module Hanami
142
142
  # @since 0.3.0
143
143
  # @api private
144
144
  def _values
145
- flash.values
145
+ flash.select { |session_id, _| !delete?(session_id) }.values
146
146
  end
147
147
 
148
148
  # Determine if delete data from flash for the given Request ID
@@ -59,7 +59,7 @@ module Hanami
59
59
  #
60
60
  # @since 0.4.3
61
61
  def sending_file?
62
- @_body.is_a?(::Rack::File)
62
+ @_body.is_a?(::Rack::File::Iterator)
63
63
  end
64
64
  end
65
65
  end
@@ -1,7 +1,6 @@
1
1
  require 'rack/utils'
2
2
  require 'hanami/utils'
3
3
  require 'hanami/utils/kernel'
4
- require 'hanami/utils/deprecation'
5
4
 
6
5
  module Hanami
7
6
  module Action
@@ -41,6 +40,64 @@ module Hanami
41
40
  # @api private
42
41
  DEFAULT_CHARSET = 'utf-8'.freeze
43
42
 
43
+ # Most commom mime types used for responses
44
+ #
45
+ # @since 1.0.0.beta1
46
+ # @api private
47
+ MIME_TYPES = {
48
+ txt: 'text/plain',
49
+ html: 'text/html',
50
+ json: 'application/json',
51
+ manifest: 'text/cache-manifest',
52
+ atom: 'application/atom+xml',
53
+ avi: 'video/x-msvideo',
54
+ bmp: 'image/bmp',
55
+ bz: 'application/x-bzip',
56
+ bz2: 'application/x-bzip2',
57
+ chm: 'application/vnd.ms-htmlhelp',
58
+ css: 'text/css',
59
+ csv: 'text/csv',
60
+ flv: 'video/x-flv',
61
+ gif: 'image/gif',
62
+ gz: 'application/x-gzip',
63
+ h264: 'video/h264',
64
+ ico: 'image/vnd.microsoft.icon',
65
+ ics: 'text/calendar',
66
+ jpg: 'image/jpeg',
67
+ js: 'application/javascript',
68
+ mp4: 'video/mp4',
69
+ mov: 'video/quicktime',
70
+ mp3: 'audio/mpeg',
71
+ mp4a: 'audio/mp4',
72
+ mpg: 'video/mpeg',
73
+ oga: 'audio/ogg',
74
+ ogg: 'application/ogg',
75
+ ogv: 'video/ogg',
76
+ pdf: 'application/pdf',
77
+ pgp: 'application/pgp-encrypted',
78
+ png: 'image/png',
79
+ psd: 'image/vnd.adobe.photoshop',
80
+ rtf: 'application/rtf',
81
+ sh: 'application/x-sh',
82
+ svg: 'image/svg+xml',
83
+ swf: 'application/x-shockwave-flash',
84
+ tar: 'application/x-tar',
85
+ torrent: 'application/x-bittorrent',
86
+ tsv: 'text/tab-separated-values',
87
+ uri: 'text/uri-list',
88
+ vcs: 'text/x-vcalendar',
89
+ wav: 'audio/x-wav',
90
+ webm: 'video/webm',
91
+ wmv: 'video/x-ms-wmv',
92
+ woff: 'application/font-woff',
93
+ woff2: 'application/font-woff2',
94
+ wsdl: 'application/wsdl+xml',
95
+ xhtml: 'application/xhtml+xml',
96
+ xml: 'application/xml',
97
+ xslt: 'application/xslt+xml',
98
+ yml: 'text/yaml',
99
+ zip: 'application/zip' }.freeze
100
+
44
101
  # Override Ruby's hook for modules.
45
102
  # It includes Mime types logic
46
103
  #
@@ -62,7 +119,7 @@ module Hanami
62
119
  # @api private
63
120
  def format_to_mime_type(format)
64
121
  configuration.mime_type_for(format) ||
65
- ::Rack::Mime.mime_type(".#{ format }", nil) or
122
+ MIME_TYPES[format] or
66
123
  raise Hanami::Controller::UnknownFormatError.new(format)
67
124
  end
68
125
 
@@ -100,6 +157,8 @@ module Hanami
100
157
  format_to_mime_type(format)
101
158
  end
102
159
 
160
+ configuration.restrict_mime_types!(mime_types)
161
+
103
162
  before do
104
163
  unless mime_types.find {|mt| accept?(mt) }
105
164
  halt 406
@@ -298,12 +357,12 @@ module Hanami
298
357
  # When the format is set, the framework searches for a corresponding mime
299
358
  # type to be set as the `Content-Type` header of the response.
300
359
  # This lookup is performed first in the configuration, and then in
301
- # `Rack::Mime::MIME_TYPES`. If the lookup fails, it raises an error.
360
+ # `Hanami::Action::Mime::MIME_TYPES`. If the lookup fails, it raises an error.
302
361
  #
303
362
  # PERFORMANCE: Because `Hanami::Controller::Configuration#formats` is
304
- # smaller and looked up first than `Rack::Mime::MIME_TYPES`, we suggest to
305
- # configure the most common mime types used by your application, **even
306
- # if they are already present in that Rack constant**.
363
+ # smaller and looked up first than `Hanami::Action::Mime::MIME_TYPES`,
364
+ # we suggest to configure the most common mime types used by your
365
+ # application, **even if they are already present in that Rack constant**.
307
366
  #
308
367
  # @param format [#to_sym] the format
309
368
  #
@@ -482,8 +541,7 @@ module Hanami
482
541
  # @since 0.2.0
483
542
  # @api private
484
543
  def detect_format
485
- configuration.format_for(content_type) ||
486
- ::Rack::Mime::MIME_TYPES.key(content_type).gsub(/\A\./, '').to_sym
544
+ configuration.format_for(content_type) || MIME_TYPES.key(content_type)
487
545
  end
488
546
 
489
547
  # @since 0.3.0
@@ -282,7 +282,7 @@ module Hanami
282
282
  # end
283
283
  # end
284
284
  def send_file(path)
285
- result = File.new(path).call(@_env)
285
+ result = File.new(path, self.class.configuration.public_directory).call(@_env)
286
286
  headers.merge!(result[1])
287
287
  halt result[0], result[2]
288
288
  end
@@ -10,20 +10,27 @@ module Hanami
10
10
  #
11
11
  # @see Hanami::Action::Rack#send_file
12
12
  class File
13
+
14
+ # The key that returns path info from the Rack env
15
+ #
16
+ # @since 1.0.0.beta1
17
+ # @api private
18
+ PATH_INFO = "PATH_INFO".freeze
19
+
13
20
  # @param path [String,Pathname] file path
14
21
  #
15
22
  # @since 0.4.3
16
23
  # @api private
17
- def initialize(path)
18
- @file = ::Rack::File.new(nil)
24
+ def initialize(path, root)
25
+ @file = ::Rack::File.new(root)
19
26
  @path = path
20
27
  end
21
28
 
22
29
  # @since 0.4.3
23
30
  # @api private
24
31
  def call(env)
25
- @file.path = @path.to_s
26
- @file.serving(env)
32
+ env[PATH_INFO] = @path
33
+ @file.get(env)
27
34
  rescue Errno::ENOENT
28
35
  [404, {}, nil]
29
36
  end
@@ -26,6 +26,14 @@ module Hanami
26
26
  # @api private
27
27
  DEFAULT_ERROR_CODE = 500
28
28
 
29
+ # Default public directory
30
+ #
31
+ # It serves as base root for file downloads
32
+ #
33
+ # @since 1.0.0.beta1
34
+ # @api private
35
+ DEFAULT_PUBLIC_DIRECTORY = 'public'.freeze
36
+
29
37
  # Default Mime type to format mapping
30
38
  #
31
39
  # @since 0.2.0
@@ -212,7 +220,7 @@ module Hanami
212
220
  #
213
221
  # @param exception [Exception] an exception
214
222
  #
215
- # @since x.x.x
223
+ # @since 1.0.0.beta1
216
224
  # @api private
217
225
  #
218
226
  # @see Hanami::Controller::Configuration#handle_exception
@@ -423,10 +431,22 @@ module Hanami
423
431
  def mime_types
424
432
  @mime_types ||= begin
425
433
  ((@formats.keys - DEFAULT_FORMATS.keys) +
426
- ::Rack::Mime::MIME_TYPES.values).freeze
434
+ Hanami::Action::Mime::MIME_TYPES.values).freeze
427
435
  end
428
436
  end
429
437
 
438
+ # Restrict the MIME types set only to the given set
439
+ #
440
+ # @param mime_types [Array] the set of MIME types
441
+ #
442
+ # @since 1.0.0.beta1
443
+ # @api private
444
+ #
445
+ # @see Hanami::Action::Mime::ClassMethods#accept
446
+ def restrict_mime_types!(mime_types)
447
+ @mime_types = self.mime_types & mime_types
448
+ end
449
+
430
450
  # Set a format as default fallback for all the requests without a strict
431
451
  # requirement for the mime type.
432
452
  #
@@ -631,6 +651,14 @@ module Hanami
631
651
  @formats.key(format)
632
652
  end
633
653
 
654
+ def public_directory(value = nil)
655
+ if value.nil?
656
+ @public_directory
657
+ else
658
+ @public_directory = Pathname.new(Dir.pwd).join(value).to_s
659
+ end
660
+ end
661
+
634
662
  # Duplicate by copying the settings in a new instance.
635
663
  #
636
664
  # @return [Hanami::Controller::Configuration] a copy of the configuration
@@ -648,6 +676,7 @@ module Hanami
648
676
  c.default_response_format = default_response_format
649
677
  c.default_charset = default_charset
650
678
  c.default_headers = default_headers.dup
679
+ c.public_directory = public_directory
651
680
  c.cookies = cookies.dup
652
681
  end
653
682
  end
@@ -677,6 +706,7 @@ module Hanami
677
706
  @default_charset = nil
678
707
  @default_headers = {}
679
708
  @cookies = {}
709
+ @public_directory = ::File.join(Dir.pwd, "public")
680
710
  @action_module = ::Hanami::Action
681
711
  end
682
712
 
@@ -722,6 +752,7 @@ module Hanami
722
752
  attr_writer :default_charset
723
753
  attr_writer :default_headers
724
754
  attr_writer :cookies
755
+ attr_writer :public_directory
725
756
  end
726
757
  end
727
758
  end
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '0.8.1'.freeze
6
+ VERSION = '1.0.0.beta1'.freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 1.0.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-12-19 00:00:00.000000000 Z
13
+ date: 2017-02-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -18,34 +18,28 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '1.6'
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: 1.6.2
21
+ version: '2.0'
25
22
  type: :runtime
26
23
  prerelease: false
27
24
  version_requirements: !ruby/object:Gem::Requirement
28
25
  requirements:
29
26
  - - "~>"
30
27
  - !ruby/object:Gem::Version
31
- version: '1.6'
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: 1.6.2
28
+ version: '2.0'
35
29
  - !ruby/object:Gem::Dependency
36
30
  name: hanami-utils
37
31
  requirement: !ruby/object:Gem::Requirement
38
32
  requirements:
39
33
  - - "~>"
40
34
  - !ruby/object:Gem::Version
41
- version: '0.9'
35
+ version: 1.0.0.beta1
42
36
  type: :runtime
43
37
  prerelease: false
44
38
  version_requirements: !ruby/object:Gem::Requirement
45
39
  requirements:
46
40
  - - "~>"
47
41
  - !ruby/object:Gem::Version
48
- version: '0.9'
42
+ version: 1.0.0.beta1
49
43
  - !ruby/object:Gem::Dependency
50
44
  name: bundler
51
45
  requirement: !ruby/object:Gem::Requirement
@@ -149,9 +143,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
143
  version: 2.3.0
150
144
  required_rubygems_version: !ruby/object:Gem::Requirement
151
145
  requirements:
152
- - - ">="
146
+ - - ">"
153
147
  - !ruby/object:Gem::Version
154
- version: '0'
148
+ version: 1.3.1
155
149
  requirements: []
156
150
  rubyforge_project:
157
151
  rubygems_version: 2.6.8