decanter 3.1.0 → 3.3.0

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: 1518df774602ffe66ea5fe6b9ee101f74644876b9ae8417f575828c8b9ffc961
4
- data.tar.gz: a9e2201a3df589f2664b565313f1c74d70ae9c4cd3e9c9836aad4507e8a11418
3
+ metadata.gz: b7ee762570171d13eede776ea7715f54e3daa9228e09b8a83f278c857eaeb04c
4
+ data.tar.gz: 4dee8cfa404faeb3362925832d53b4e55c0f82cddd2427416c0fdf79a66ff85e
5
5
  SHA512:
6
- metadata.gz: ae0d8395af236b8487af2812fd05a778f806055e1167d6635f2d91a4f25d07ccc62067423375fbb3e4da1d58c01d4affb4861b62c9a0a2220c30bae709ef7125
7
- data.tar.gz: 935eab7ccb2ef88db8e01b4faefae22b84d65c5264925432684ae5d67e222bddb0c796672de0d9e4606176f3c321654a220246e889565819cc9116e01a4ce5b5
6
+ metadata.gz: dd1b076ac0cbe78783ab19b4ae43d8fb7d87bd46b76155ec08dcbdfb55638415667c1ad19ccdeff4f81e0b0482c2ef32292a1686df648ee52e0b3ce4824ea069
7
+ data.tar.gz: d34c06b627f4c1b4773829cd9e3003f3a8eb167a97acfa55be361628078d8230d8be1664d576d49eb6de9705d56f95c478ff52c56c2c656b1882d167df69e499
@@ -0,0 +1,2 @@
1
+ # These owners will be the default owners for everything in the repo.
2
+ * @chawes13
@@ -4,5 +4,5 @@
4
4
  ## Author Checklist
5
5
  - [ ] Add unit test(s)
6
6
  - [ ] Update documentation (if necessary)
7
- - [ ] Update version in `version.rb` following [versioning guidelines](https://github.com/LaunchPadLab/opex/blob/master/gists/gem-guidelines.md#pull-requests-and-deployments)
7
+ - [ ] Update version in `version.rb` following [versioning guidelines](https://github.com/LaunchPadLab/opex-public/blob/master/gists/gem-guidelines.md#pull-requests-and-deployments)
8
8
 
@@ -1,6 +1,6 @@
1
1
  # Contributing
2
2
 
3
- Thanks for your interest in contributing! This project follows our [Gem guidelines](https://github.com/LaunchPadLab/opex/blob/master/gists/gem-guidelines.md).
3
+ Thanks for your interest in contributing! This project follows our [Gem guidelines](https://github.com/LaunchPadLab/opex-public/blob/master/gists/gem-guidelines.md).
4
4
 
5
5
  ## Code of Conduct
6
6
 
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in goaltender.gemspec
3
+ # Specify your gem's dependencies in decanter.gemspec
4
4
  gemspec
@@ -1,90 +1,90 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- decanter (3.1.0)
4
+ decanter (3.3.0)
5
5
  actionpack (>= 4.2.10)
6
- activesupport
6
+ activesupport (~> 5.2)
7
7
  rails-html-sanitizer (>= 1.0.4)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- actionpack (5.1.4)
13
- actionview (= 5.1.4)
14
- activesupport (= 5.1.4)
15
- rack (~> 2.0)
12
+ actionpack (5.2.4.4)
13
+ actionview (= 5.2.4.4)
14
+ activesupport (= 5.2.4.4)
15
+ rack (~> 2.0, >= 2.0.8)
16
16
  rack-test (>= 0.6.3)
17
17
  rails-dom-testing (~> 2.0)
18
18
  rails-html-sanitizer (~> 1.0, >= 1.0.2)
19
- actionview (5.1.4)
20
- activesupport (= 5.1.4)
19
+ actionview (5.2.4.4)
20
+ activesupport (= 5.2.4.4)
21
21
  builder (~> 3.1)
22
22
  erubi (~> 1.4)
23
23
  rails-dom-testing (~> 2.0)
24
24
  rails-html-sanitizer (~> 1.0, >= 1.0.3)
25
- activesupport (5.1.4)
25
+ activesupport (5.2.4.4)
26
26
  concurrent-ruby (~> 1.0, >= 1.0.2)
27
- i18n (~> 0.7)
27
+ i18n (>= 0.7, < 2)
28
28
  minitest (~> 5.1)
29
29
  tzinfo (~> 1.1)
30
- builder (3.2.3)
31
- concurrent-ruby (1.0.5)
32
- crass (1.0.4)
33
- diff-lcs (1.3)
30
+ builder (3.2.4)
31
+ concurrent-ruby (1.1.7)
32
+ crass (1.0.6)
33
+ diff-lcs (1.4.4)
34
34
  docile (1.1.5)
35
35
  dotenv (2.2.1)
36
- erubi (1.7.0)
37
- i18n (0.9.3)
36
+ erubi (1.9.0)
37
+ i18n (1.8.5)
38
38
  concurrent-ruby (~> 1.0)
39
- json (2.1.0)
40
- loofah (2.2.2)
39
+ json (2.3.0)
40
+ loofah (2.7.0)
41
41
  crass (~> 1.0.2)
42
42
  nokogiri (>= 1.5.9)
43
- method_source (0.9.0)
44
- mini_portile2 (2.3.0)
45
- minitest (5.11.3)
46
- nokogiri (1.8.5)
47
- mini_portile2 (~> 2.3.0)
48
- rack (2.0.4)
49
- rack-test (0.8.2)
43
+ method_source (1.0.0)
44
+ mini_portile2 (2.4.0)
45
+ minitest (5.14.2)
46
+ nokogiri (1.10.10)
47
+ mini_portile2 (~> 2.4.0)
48
+ rack (2.2.3)
49
+ rack-test (1.1.0)
50
50
  rack (>= 1.0, < 3)
51
51
  rails-dom-testing (2.0.3)
52
52
  activesupport (>= 4.2.0)
53
53
  nokogiri (>= 1.6)
54
- rails-html-sanitizer (1.0.4)
55
- loofah (~> 2.2, >= 2.2.2)
56
- railties (5.1.4)
57
- actionpack (= 5.1.4)
58
- activesupport (= 5.1.4)
54
+ rails-html-sanitizer (1.3.0)
55
+ loofah (~> 2.3)
56
+ railties (5.2.4.4)
57
+ actionpack (= 5.2.4.4)
58
+ activesupport (= 5.2.4.4)
59
59
  method_source
60
60
  rake (>= 0.8.7)
61
- thor (>= 0.18.1, < 2.0)
62
- rake (10.5.0)
63
- rspec-core (3.7.1)
64
- rspec-support (~> 3.7.0)
65
- rspec-expectations (3.7.0)
61
+ thor (>= 0.19.0, < 2.0)
62
+ rake (12.3.3)
63
+ rspec-core (3.9.3)
64
+ rspec-support (~> 3.9.3)
65
+ rspec-expectations (3.9.3)
66
66
  diff-lcs (>= 1.2.0, < 2.0)
67
- rspec-support (~> 3.7.0)
68
- rspec-mocks (3.7.0)
67
+ rspec-support (~> 3.9.0)
68
+ rspec-mocks (3.9.1)
69
69
  diff-lcs (>= 1.2.0, < 2.0)
70
- rspec-support (~> 3.7.0)
71
- rspec-rails (3.7.2)
70
+ rspec-support (~> 3.9.0)
71
+ rspec-rails (3.9.1)
72
72
  actionpack (>= 3.0)
73
73
  activesupport (>= 3.0)
74
74
  railties (>= 3.0)
75
- rspec-core (~> 3.7.0)
76
- rspec-expectations (~> 3.7.0)
77
- rspec-mocks (~> 3.7.0)
78
- rspec-support (~> 3.7.0)
79
- rspec-support (3.7.1)
75
+ rspec-core (~> 3.9.0)
76
+ rspec-expectations (~> 3.9.0)
77
+ rspec-mocks (~> 3.9.0)
78
+ rspec-support (~> 3.9.0)
79
+ rspec-support (3.9.4)
80
80
  simplecov (0.15.1)
81
81
  docile (~> 1.1.0)
82
82
  json (>= 1.8, < 3)
83
83
  simplecov-html (~> 0.10.0)
84
84
  simplecov-html (0.10.2)
85
- thor (0.20.0)
85
+ thor (1.0.1)
86
86
  thread_safe (0.3.6)
87
- tzinfo (1.2.5)
87
+ tzinfo (1.2.7)
88
88
  thread_safe (~> 0.1)
89
89
 
90
90
  PLATFORMS
@@ -94,8 +94,8 @@ DEPENDENCIES
94
94
  bundler (~> 1.9)
95
95
  decanter!
96
96
  dotenv
97
- rake (~> 10.0)
98
- rspec-rails
97
+ rake (~> 12.0)
98
+ rspec-rails (~> 3.9)
99
99
  simplecov (~> 0.15.1)
100
100
 
101
101
  BUNDLED WITH
data/README.md CHANGED
@@ -220,6 +220,25 @@ end
220
220
 
221
221
  _Note: we recommend using [Active Record validations](https://guides.rubyonrails.org/active_record_validations.html) to check for presence of an attribute, rather than using the `required` option. This method is intended for use in non-RESTful routes or cases where Active Record validations are not available._
222
222
 
223
+
224
+ ### Default values
225
+
226
+ If you provide the option `:default_value` for an input in your decanter, the input key will be initialized with the given default value. Input keys not found in the incoming data parameters will be set to the provided default rather than ignoring the missing key. Note: `nil` and empty keys will not be overridden.
227
+
228
+ ```ruby
229
+ class TripDecanter < Decanter::Base
230
+ input :name, :string
231
+ input :destination, :string, default_value: 'Chicago'
232
+ end
233
+
234
+ ```
235
+
236
+ ```
237
+ TripDecanter.decant({ name: 'Vacation 2020' })
238
+ => { name: 'Vacation 2020', destination: 'Chicago' }
239
+
240
+ ```
241
+
223
242
  ### Global configuration
224
243
 
225
244
  You can generate a local copy of the default configuration with `rails generate decanter:install`. This will create an initializer where you can do global configuration:
@@ -28,12 +28,12 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ['lib']
29
29
 
30
30
  spec.add_dependency 'actionpack', '>= 4.2.10'
31
- spec.add_dependency 'activesupport'
31
+ spec.add_dependency 'activesupport', '~> 5.2'
32
32
  spec.add_dependency 'rails-html-sanitizer', '>= 1.0.4'
33
33
 
34
34
  spec.add_development_dependency 'bundler', '~> 1.9'
35
35
  spec.add_development_dependency 'dotenv'
36
- spec.add_development_dependency 'rake', '~> 10.0'
37
- spec.add_development_dependency 'rspec-rails'
36
+ spec.add_development_dependency 'rake', '~> 12.0'
37
+ spec.add_development_dependency 'rspec-rails', '~> 3.9'
38
38
  spec.add_development_dependency 'simplecov', '~> 0.15.1'
39
39
  end
@@ -1,23 +1,25 @@
1
1
  module Decanter
2
2
  module Core
3
-
3
+ DEFAULT_VALUE_KEY = :default_value
4
+ ACTION_CONTROLLER_PARAMETERS_CLASS_NAME = 'ActionController::Parameters'
5
+
4
6
  def self.included(base)
5
7
  base.extend(ClassMethods)
6
8
  end
7
9
 
8
10
  module ClassMethods
9
-
10
- def input(name, parsers=nil, **options)
11
11
 
12
- _name = [name].flatten
12
+ def input(name, parsers=nil, **options)
13
+ # Convert all input names to symbols to correctly calculate handled vs. unhandled keys
14
+ input_names = [name].flatten.map(&:to_sym)
13
15
 
14
- if _name.length > 1 && parsers.blank?
16
+ if input_names.length > 1 && parsers.blank?
15
17
  raise ArgumentError.new("#{self.name} no parser specified for input with multiple values.")
16
18
  end
17
19
 
18
- handlers[_name] = {
19
- key: options.fetch(:key, _name.first),
20
- name: _name,
20
+ handlers[input_names] = {
21
+ key: options.fetch(:key, input_names.first),
22
+ name: input_names,
21
23
  options: options,
22
24
  parsers: parsers,
23
25
  type: :input
@@ -45,7 +47,7 @@ module Decanter
45
47
  end
46
48
 
47
49
  def ignore(*args)
48
- keys_to_ignore.push(*args)
50
+ keys_to_ignore.push(*args).map!(&:to_sym)
49
51
  end
50
52
 
51
53
  def strict(mode)
@@ -56,12 +58,29 @@ module Decanter
56
58
  def decant(args)
57
59
  return handle_empty_args if args.blank?
58
60
  return empty_required_input_error unless required_input_keys_present?(args)
59
- args = args.to_unsafe_h.with_indifferent_access if args.class.name == 'ActionController::Parameters'
60
- {}.merge( unhandled_keys(args) )
61
- .merge( handled_keys(args) )
61
+
62
+ # Convert all params passed to a decanter to a hash with indifferent access to mitigate accessor ambiguity
63
+ accessible_args = to_indifferent_hash(args)
64
+ {}.merge( default_keys )
65
+ .merge( unhandled_keys(accessible_args) )
66
+ .merge( handled_keys(accessible_args) )
62
67
  end
63
68
 
64
- def handle_empty_args
69
+ def default_keys
70
+ # return keys with provided default value when key is not defined within incoming args
71
+ default_result = default_value_inputs
72
+ .map { |input| [input[:key], input[:options][DEFAULT_VALUE_KEY]] }
73
+ .to_h
74
+
75
+ # parse default values
76
+ handled_keys(default_result)
77
+ end
78
+
79
+ def default_value_inputs
80
+ handlers.values.select { |input| input[:options].key?(DEFAULT_VALUE_KEY) }
81
+ end
82
+
83
+ def handle_empty_args
65
84
  any_inputs_required? ? empty_args_error : {}
66
85
  end
67
86
 
@@ -73,7 +92,7 @@ module Decanter
73
92
  handlers.map do |h|
74
93
  options = h.last[:options]
75
94
  h.first.first if options && options[:required]
76
- end
95
+ end
77
96
  end
78
97
 
79
98
  def required_input_keys_present?(args={})
@@ -100,11 +119,11 @@ module Decanter
100
119
  keys_to_ignore -
101
120
  handlers.values
102
121
  .select { |handler| handler[:type] != :input }
103
- .map { |handler| "#{handler[:name]}_attributes".to_sym }
122
+ .map { |handler| "#{handler[:name]}_attributes".to_sym }
104
123
 
105
124
  return {} unless unhandled_keys.any?
106
125
  raise(UnhandledKeysError, "#{self.name} received unhandled keys: #{unhandled_keys.join(', ')}.") if strict_mode
107
- args.select { |key| unhandled_keys.include? key }
126
+ args.select { |key| unhandled_keys.include? key.to_sym }
108
127
  end
109
128
 
110
129
  def handled_keys(args)
@@ -185,13 +204,13 @@ module Decanter
185
204
  def parse(key, parsers, value, options)
186
205
  return { key => value } unless parsers
187
206
  if options[:required] && value_missing?(value)
188
- raise ArgumentError.new("No value for required argument: #{key}")
207
+ raise ArgumentError.new("No value for required argument: #{key}")
189
208
  end
190
209
  parser_classes = Parser.parsers_for(parsers)
191
210
  Parser.compose_parsers(parser_classes).parse(key, value, options)
192
211
  end
193
212
 
194
- def handlers
213
+ def handlers
195
214
  @handlers ||= {}
196
215
  end
197
216
 
@@ -211,6 +230,10 @@ module Decanter
211
230
  value.nil? || value == ""
212
231
  end
213
232
 
233
+ def to_indifferent_hash(args)
234
+ return args.to_unsafe_h if args.class.name == ACTION_CONTROLLER_PARAMETERS_CLASS_NAME
235
+ args.to_h.with_indifferent_access
236
+ end
214
237
  end
215
238
  end
216
239
  end
@@ -1,3 +1,3 @@
1
1
  module Decanter
2
- VERSION = '3.1.0'.freeze
2
+ VERSION = '3.3.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decanter
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Francis
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-04-16 00:00:00.000000000 Z
12
+ date: 2020-11-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -29,16 +29,16 @@ dependencies:
29
29
  name: activesupport
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ">="
32
+ - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: '5.2'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
39
+ - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: '5.2'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rails-html-sanitizer
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -87,28 +87,28 @@ dependencies:
87
87
  requirements:
88
88
  - - "~>"
89
89
  - !ruby/object:Gem::Version
90
- version: '10.0'
90
+ version: '12.0'
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
95
  - - "~>"
96
96
  - !ruby/object:Gem::Version
97
- version: '10.0'
97
+ version: '12.0'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: rspec-rails
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - ">="
102
+ - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: '0'
104
+ version: '3.9'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ">="
109
+ - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: '0'
111
+ version: '3.9'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: simplecov
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -132,6 +132,7 @@ extensions: []
132
132
  extra_rdoc_files: []
133
133
  files:
134
134
  - ".codeclimate.yml"
135
+ - ".github/CODEOWNERS"
135
136
  - ".github/ISSUE_TEMPLATE/BUG_REPORT.md"
136
137
  - ".github/ISSUE_TEMPLATE/FEATURE_REQUEST.md"
137
138
  - ".github/PULL_REQUEST_TEMPLATE.md"