hanami-controller 1.2.0 → 1.3.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
  SHA256:
3
- metadata.gz: 0fa2474de61eb665874dbb5aac1bc97558bbdfd255de8aaa7f21e659f18adb61
4
- data.tar.gz: e5fe8ce5a5bfae4768bb1c1966ddff3d6d2ace31e0996422520977ce4fdf0c8b
3
+ metadata.gz: 70d59d43ccadadc8779881bb8c2bbc9a324e5e68e84e9a68ac7ef994b6124ea6
4
+ data.tar.gz: fab5066f435669ac7dbf7d8d0b7b5d7ec4c52ea2aef4975985ab24542d073994
5
5
  SHA512:
6
- metadata.gz: 0cb4a8984ac4a16991662ac5ab90063a31349590cd14358b2c745da2fe5c523c4a2cf2db5aa8196d87508e57ac25ef5e6c8ebaeb9378051c7ec53e9ddcfc3177
7
- data.tar.gz: 8c7c414fbacbb6564df2ce58a1d512491e25ffda2a6e64c3779063c8e5791e3241b88bc451f8a048a913d1e292939acfdacb702f16dd2820b8b78c0ab4b981b1
6
+ metadata.gz: 40ebcfe48e2b61e4e45447cfa7d6c30a471dc949668895b0758a7519d0a6a1de810f4da6b73a42e2e7a69abc0fd759ce9da16d5a8633fafd473694d639347759
7
+ data.tar.gz: 6f1983a3efc8900850f5496b755d9cf769065bc60e3c2423ec97828cba619db5971b8af4a70d648588e858cda144aa761c5c7d63149d26f379e4ae70f2369c1e
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.3.0.beta1 - 2018-08-08
5
+ ### Added
6
+ - [Luca Guidi] Official support for JRuby 9.2.0.0
7
+
8
+ ### Fixed
9
+ - [Yuji Ueki] Ensure that if `If-None-Match` or `If-Modified-Since` response HTTP headers are missing, `Etag` or `Last-Modified` headers will be in response HTTP headers.
10
+ - [Gustavo Caso] Don't show flash message for the request after a HTTP redirect.
11
+ - [Gustavo Caso] Ensure `Hanami::Action::Flash#each`, `#map`, and `#empty?` to not reference stale flash data.
12
+
13
+ ### Deprecated
14
+ - [Gustavo Caso] Deprecate `Hanami::Action#parsed_request_body`
15
+
4
16
  ## v1.2.0 - 2018-04-11
5
17
 
6
18
  ## v1.2.0.rc2 - 2018-04-06
data/README.md CHANGED
@@ -4,12 +4,12 @@ Complete, fast and testable actions for Rack and [Hanami](http://hanamirb.org)
4
4
 
5
5
  ## Status
6
6
 
7
- [![Gem Version](https://badge.fury.io/rb/hanami-controller.png)](http://badge.fury.io/rb/hanami-controller)
8
- [![Build Status](https://secure.travis-ci.org/hanami/controller.png?branch=master)](http://travis-ci.org/hanami/controller?branch=master)
9
- [![Coverage](https://coveralls.io/repos/hanami/controller/badge.png?branch=master)](https://coveralls.io/r/hanami/controller)
10
- [![Code Climate](https://codeclimate.com/github/hanami/controller.png)](https://codeclimate.com/github/hanami/controller)
11
- [![Dependencies](https://gemnasium.com/hanami/controller.png)](https://gemnasium.com/hanami/controller)
12
- [![Inline docs](http://inch-ci.org/github/hanami/controller.png)](http://inch-ci.org/github/hanami/controller)
7
+ [![Gem Version](https://badge.fury.io/rb/hanami-controller.svg)](https://badge.fury.io/rb/hanami-controller)
8
+ [![TravisCI](https://travis-ci.org/hanami/controller.svg?branch=master)](https://travis-ci.org/hanami/controller)
9
+ [![CircleCI](https://circleci.com/gh/hanami/controller/tree/master.svg?style=svg)](https://circleci.com/gh/hanami/controller/tree/master)
10
+ [![Test Coverage](https://codecov.io/gh/hanami/controller/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/controller)
11
+ [![Depfu](https://badges.depfu.com/badges/7cd17419fba78b726be1353118fb01de/overview.svg)](https://depfu.com/github/hanami/controller?project=Bundler)
12
+ [![Inline Docs](http://inch-ci.org/github/hanami/controller.svg)](http://inch-ci.org/github/hanami/controller)
13
13
 
14
14
  ## Contact
15
15
 
@@ -20,10 +20,10 @@ Gem::Specification.new do |spec|
20
20
  spec.required_ruby_version = '>= 2.3.0'
21
21
 
22
22
  spec.add_dependency 'rack', '~> 2.0'
23
- spec.add_dependency 'hanami-utils', '~> 1.2'
23
+ spec.add_dependency 'hanami-utils', '~> 1.3.beta'
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.6'
26
- spec.add_development_dependency 'rack-test', '~> 0.6'
26
+ spec.add_development_dependency 'rack-test', '~> 1.0'
27
27
  spec.add_development_dependency 'rake', '~> 12'
28
28
  spec.add_development_dependency 'rspec', '~> 3.7'
29
29
  end
@@ -41,7 +41,7 @@ module Hanami
41
41
  # @since 0.3.0
42
42
  # @api private
43
43
  def header
44
- { ETAG => @value } if none_match
44
+ { ETAG => @value } if @value
45
45
  end
46
46
 
47
47
  private
@@ -67,13 +67,13 @@ module Hanami
67
67
  # @since 0.3.0
68
68
  # @api private
69
69
  def fresh?
70
- !Hanami::Utils::Blank.blank?(modified_since) && Time.httpdate(modified_since).to_i >= @value.to_i
70
+ !Hanami::Utils::Blank.blank?(modified_since) && Time.httpdate(modified_since).to_i >= @value.to_time.to_i
71
71
  end
72
72
 
73
73
  # @since 0.3.0
74
74
  # @api private
75
75
  def header
76
- { LAST_MODIFIED => @value.httpdate } if modified_since
76
+ { LAST_MODIFIED => @value.httpdate } if @value && @value.respond_to?(:httpdate)
77
77
  end
78
78
 
79
79
  private
@@ -12,29 +12,26 @@ module Hanami
12
12
  # @api private
13
13
  SESSION_KEY = :__flash
14
14
 
15
- # Session key where the last request_id is stored
15
+ # Session key where keep data is store for redirect
16
16
  #
17
- # @since 0.4.0
17
+ # @since 1.3.0
18
18
  # @api private
19
- LAST_REQUEST_KEY = :__last_request_id
19
+ KEPT_KEY = :__kept_key
20
20
 
21
21
  # Initialize a new Flash instance
22
22
  #
23
23
  # @param session [Rack::Session::Abstract::SessionHash] the session
24
- # @param request_id [String] the HTTP Request ID
25
24
  #
26
25
  # @return [Hanami::Action::Flash] the flash
27
26
  #
28
27
  # @see http://www.rubydoc.info/gems/rack/Rack/Session/Abstract/SessionHash
29
28
  # @see Hanami::Action::Rack#session_id
30
- def initialize(session, request_id)
29
+ def initialize(session)
31
30
  @session = session
32
- @request_id = request_id
33
- @last_request_id = session[LAST_REQUEST_KEY]
34
- @merged = {}
31
+ @keep = false
35
32
 
36
- session[SESSION_KEY] ||= {}
37
- session[SESSION_KEY][request_id] ||= {}
33
+ session[KEPT_KEY] ||= []
34
+ session[SESSION_KEY] = {}
38
35
  end
39
36
 
40
37
  # Set the given value for the given key
@@ -45,7 +42,7 @@ module Hanami
45
42
  # @since 0.3.0
46
43
  # @api private
47
44
  def []=(key, value)
48
- data[key] = value
45
+ _data[key] = value
49
46
  end
50
47
 
51
48
  # Get the value associated to the given key, if any
@@ -55,28 +52,26 @@ module Hanami
55
52
  # @since 0.3.0
56
53
  # @api private
57
54
  def [](key)
58
- @merged.fetch(key) do
59
- _values.find {|data| !data[key].nil? }
60
- end
55
+ _data.fetch(key) { search_in_kept_data(key) }
61
56
  end
62
57
 
63
- # Iterates through data
58
+ # Iterates through current request data and kept data
64
59
  #
65
60
  # @param blk [Proc]
66
61
  #
67
62
  # @since 1.2.0
68
63
  def each(&blk)
69
- @merged.each(&blk)
64
+ _values.each(&blk)
70
65
  end
71
66
 
72
- # Iterates through data
67
+ # Iterates through current request data and kept data
73
68
  #
74
69
  # @param blk [Proc]
75
70
  # @return [Array]
76
71
  #
77
72
  # @since 1.2.0
78
73
  def map(&blk)
79
- @merged.map(&blk)
74
+ _values.map(&blk)
80
75
  end
81
76
 
82
77
  # Removes entirely the flash from the session if it has stale contents
@@ -91,11 +86,11 @@ module Hanami
91
86
  # this bug that I've found via a browser.
92
87
  #
93
88
  # It may happen that `#flash` is nil, and those two methods will fail
94
- unless flash.nil?
95
- expire_stale!
96
- remove!
97
- merge!
98
- set_last_request_id!
89
+ unless _data.nil?
90
+ update_kept_request_count
91
+ keep_data if @keep
92
+ expire_kept
93
+ remove
99
94
  end
100
95
  end
101
96
 
@@ -107,112 +102,167 @@ module Hanami
107
102
  # @since 0.3.0
108
103
  # @api private
109
104
  def empty?
110
- _values.all?(&:empty?)
105
+ _values.empty?
111
106
  end
112
107
 
113
108
  # @return [String]
114
109
  #
115
110
  # @since 1.0.0
116
111
  def inspect
117
- "#<#{self.class}:#{'0x%x' % (__id__ << 1)} #{@merged.inspect}>"
112
+ "#<#{self.class}:#{'0x%x' % (__id__ << 1)} {:data=>#{_data.inspect}, :kept=>#{kept_data.inspect}} >"
113
+ end
114
+
115
+ # Set @keep to true, is use when triggering a redirect, and the content of _data is not empty.
116
+ # @return [TrueClass, NilClass]
117
+ #
118
+ # @since 1.3.0
119
+ # @api private
120
+ #
121
+ # @see Hanami::Action::Flash#empty?
122
+ def keep!
123
+ return if empty?
124
+ @keep = true
118
125
  end
119
126
 
120
127
  private
121
128
 
122
- # The flash registry that holds the data for **all** the recent requests
129
+ # The flash registry that holds the data for the current requests
123
130
  #
124
131
  # @return [Hash] the flash
125
132
  #
126
133
  # @since 0.3.0
127
134
  # @api private
128
- def flash
135
+ def _data
129
136
  @session[SESSION_KEY] || {}
130
137
  end
131
138
 
132
- # The flash registry that holds the data **only for** the current request
139
+ # Remove the flash entirely from the session if empty.
133
140
  #
134
- # @return [Hash] the flash for the current request
141
+ # @return [void]
135
142
  #
136
143
  # @since 0.3.0
137
144
  # @api private
138
- def data
139
- flash[@request_id] || {}
145
+ #
146
+ # @see Hanami::Action::Flash#empty?
147
+ def remove
148
+ if empty?
149
+ @session.delete(SESSION_KEY)
150
+ @session.delete(KEPT_KEY)
151
+ end
140
152
  end
141
153
 
142
- # Expire the stale data from the previous request.
154
+ # Returns the values from current session and kept.
143
155
  #
144
- # @return [void]
156
+ # @return [Hash]
145
157
  #
146
158
  # @since 0.3.0
147
159
  # @api private
148
- def expire_stale!
149
- flash.each do |request_id, _|
150
- flash.delete(request_id) if delete?(request_id)
151
- end
160
+ def _values
161
+ _data.merge(kept_data)
152
162
  end
153
163
 
154
- # Remove the flash entirely from the session if empty.
164
+ # Get the kept request data
155
165
  #
156
- # @return [void]
166
+ # @return [Array]
157
167
  #
158
- # @since 0.3.0
168
+ # @since 1.3.0
159
169
  # @api private
160
- #
161
- # @see Hanami::Action::Flash#empty?
162
- def remove!
163
- @session.delete(SESSION_KEY) if empty?
170
+ def kept
171
+ @session[KEPT_KEY] || []
164
172
  end
165
173
 
166
- # @since 1.0.0
167
- # @api private
174
+ # Merge current data into KEPT_KEY hash
175
+ #
176
+ # @return [Hash] the current value of KEPT_KEY
168
177
  #
169
- # @see Hanami::Action::Flash#[]
170
- def merge!
171
- @merged = last_request_flash.merge(data)
178
+ # @since 1.3.0
179
+ # @api private
180
+ def keep_data
181
+ new_kept_data = kept << JSON.generate({ count: 0, data: _data })
182
+
183
+ update_kept(new_kept_data)
172
184
  end
173
185
 
174
- # Values from all the stored requests
186
+ # Removes from kept data those who have lived for more than two requests
175
187
  #
176
- # @return [Array]
188
+ # @return [Hash] the current value of KEPT_KEY
177
189
  #
178
- # @since 0.3.0
190
+ # @since 1.3.0
179
191
  # @api private
180
- def _values
181
- flash.select { |session_id, _| !delete?(session_id) }.values
192
+ def expire_kept
193
+ new_kept_data = kept.reject do |kept_data|
194
+ parsed = JSON.parse(kept_data)
195
+ parsed['count'] >= 2 if is_hash?(parsed) && parsed['count'].is_a?(Integer)
196
+ end
197
+
198
+ update_kept(new_kept_data)
182
199
  end
183
200
 
184
- # Determine if delete data from flash for the given Request ID
201
+ # Update the count of request for each kept data
185
202
  #
186
- # @return [TrueClass,FalseClass] the result of the check
203
+ # @return [Hash] the current value of KEPT_KEY
187
204
  #
188
- # @since 0.4.0
205
+ # @since 1.3.0
189
206
  # @api private
207
+ def update_kept_request_count
208
+ new_kept_data = kept.map do |kept_data|
209
+ parsed = JSON.parse(kept_data)
210
+ parsed['count'] += 1 if is_hash?(parsed) && parsed['count'].is_a?(Integer)
211
+ JSON.generate(parsed)
212
+ end
213
+
214
+ update_kept(new_kept_data)
215
+ end
216
+
217
+ # Search in the kept data for a match on the key
190
218
  #
191
- # @see Hanami::Action::Flash#expire_stale!
192
- def delete?(request_id)
193
- ![@request_id, @session[LAST_REQUEST_KEY]].include?(request_id)
219
+ # @param key [#to_s] the key
220
+ # @return [Object, NilClass]
221
+ #
222
+ # @since 1.3.0
223
+ # @api private
224
+ def search_in_kept_data(key)
225
+ string_key = key.to_s
226
+
227
+ data = kept.find do |kept_data|
228
+ parsed = JSON.parse(kept_data)
229
+ parsed['data'].fetch(string_key, nil) if is_hash?(parsed['data'])
230
+ end
231
+
232
+ JSON.parse(data)['data'][string_key] if data
194
233
  end
195
234
 
196
- # Get the last request session flash
235
+ # Set the given new_kept_data to KEPT_KEY
197
236
  #
198
- # @return [Hash] the flash of last request
237
+ # @param new_kept_data
238
+ # @return [Hash] the current value of KEPT_KEY
199
239
  #
200
- # @since 0.4.0
240
+ # @since 1.3.0
201
241
  # @api private
202
- def last_request_flash
203
- flash[@last_request_id] || {}
242
+ def update_kept(new_kept_data)
243
+ @session[KEPT_KEY] = new_kept_data
204
244
  end
205
245
 
206
- # Store the last request_id to create the next flash with its values
207
- # is current flash is not empty.
246
+ # Values from kept
208
247
  #
209
- # @return [void]
210
- # @since 0.4.0
248
+ # @return [Hash]
249
+ #
250
+ # @since 1.3.0
211
251
  # @api private
212
- def set_last_request_id!
213
- @session[LAST_REQUEST_KEY] = @request_id if !empty?
252
+ def kept_data
253
+ kept.each_with_object({}) { |kept_data, result| result.merge!(JSON.parse(kept_data)['data']) }
214
254
  end
215
255
 
256
+ # Check if data is a hash
257
+ #
258
+ # @param data
259
+ # @return [TrueClass, FalseClass]
260
+ #
261
+ # @since 1.3.0
262
+ # @api private
263
+ def is_hash?(data)
264
+ data && data.is_a?(Hash)
265
+ end
216
266
  end
217
267
  end
218
268
  end
@@ -3,6 +3,7 @@ require 'hanami/action/request'
3
3
  require 'hanami/action/base_params'
4
4
  require 'hanami/action/rack/callable'
5
5
  require 'hanami/action/rack/file'
6
+ require 'hanami/utils/deprecation'
6
7
 
7
8
  module Hanami
8
9
  module Action
@@ -245,7 +246,10 @@ module Hanami
245
246
  end
246
247
 
247
248
  # Return parsed request body
249
+ #
250
+ # @deprecated
248
251
  def parsed_request_body
252
+ Hanami::Utils::Deprecation.new('#parsed_request_body is deprecated and it will be removed in future versions')
249
253
  @_env.fetch(ROUTER_PARSED_BODY, nil)
250
254
  end
251
255
 
@@ -83,7 +83,7 @@ module Hanami
83
83
  #
84
84
  # @see Hanami::Action::Flash
85
85
  def flash
86
- @flash ||= Flash.new(session, request_id)
86
+ @flash ||= Flash.new(session)
87
87
  end
88
88
 
89
89
  # In case of validations errors, preserve those informations after a
@@ -134,7 +134,7 @@ module Hanami
134
134
  if params.respond_to?(:valid?)
135
135
  flash[ERRORS_KEY] = errors.to_a unless params.valid?
136
136
  end
137
-
137
+ flash.keep!
138
138
  super
139
139
  end
140
140
 
@@ -96,8 +96,8 @@ module Hanami
96
96
  # Hanami::Controller::Configuration.for(MyApp::Controllers::Dashboard)
97
97
  # # => will duplicate from MyApp::Controller
98
98
  def self.for(base)
99
- namespace = Utils::String.namespace(base)
100
- framework = Utils::Class.load_from_pattern!("(#{namespace}|Hanami)::Controller")
99
+ namespace = Utils::String.namespace(base.name)
100
+ framework = Utils::Class.load("#{namespace}::Controller") || Utils::Class.load!('Hanami::Controller')
101
101
  framework.configuration.duplicate
102
102
  end
103
103
 
@@ -3,6 +3,6 @@ module Hanami
3
3
  # Defines the version
4
4
  #
5
5
  # @since 0.1.0
6
- VERSION = '1.2.0'.freeze
6
+ VERSION = '1.3.0.beta1'.freeze
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hanami-controller
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luca Guidi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-11 00:00:00.000000000 Z
11
+ date: 2018-08-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.2'
33
+ version: 1.3.beta
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.2'
40
+ version: 1.3.beta
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.6'
61
+ version: '1.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.6'
68
+ version: '1.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -153,12 +153,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
153
  version: 2.3.0
154
154
  required_rubygems_version: !ruby/object:Gem::Requirement
155
155
  requirements:
156
- - - ">="
156
+ - - ">"
157
157
  - !ruby/object:Gem::Version
158
- version: '0'
158
+ version: 1.3.1
159
159
  requirements: []
160
160
  rubyforge_project:
161
- rubygems_version: 2.7.6
161
+ rubygems_version: 2.7.7
162
162
  signing_key:
163
163
  specification_version: 4
164
164
  summary: Complete, fast and testable actions for Rack and Hanami