simple_params 1.0.3 → 1.0.4
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 +8 -8
- data/Gemfile.lock +1 -1
- data/lib/simple_params/api_pie_doc/nested_array.rb +31 -0
- data/lib/simple_params/api_pie_doc.rb +15 -0
- data/lib/simple_params/errors.rb +35 -45
- data/lib/simple_params/params.rb +55 -12
- data/lib/simple_params/validations.rb +5 -0
- data/lib/simple_params/version.rb +1 -1
- data/lib/simple_params.rb +1 -0
- data/spec/acceptance_spec.rb +15 -2
- data/spec/api_pie_doc/nested_array_spec.rb +46 -0
- data/spec/api_pie_doc_spec.rb +14 -0
- data/spec/errors_spec.rb +98 -16
- data/spec/fixtures/dummy_params.rb +5 -0
- data/spec/params_spec.rb +55 -4
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWQxN2I0ZTRlYjM1NmFmMDc0ZGRhNDA5YWQ3ZDhjMWUzZWMzM2QzMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjA4ZmQ5NDcxMjM1OTRjNzAwZTMzM2Y3MjExMGJlZDIwNDVmY2YwZQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTI0YjczMDJjMTI0OGQ4NmY4ZDZkZWYwMGNhYTA5NzIyZjZjODRiMGE4ZTZi
|
10
|
+
NzZkZDJlY2YyMDE4YzQ3OWQ1YWE3Mjg1MDg2MjlhZTAyZTJhMTc3NTRiN2M5
|
11
|
+
ZGM5MTFlMTE3NjFjZDhjMDFkMjJhMjZjYTEwNTQ0NzViN2JiNWY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTY4MmRhMWRlYTQ1NmM1N2YzNmMwZjIzNTE3ZTNiZjQ3NDY0ZjhlMTI5MmI5
|
14
|
+
NTBiMmNjYTAxZWJiNzhkZTIxNThkMDFhMDc5NGE0OTdmYjI3ZTQ0ZmQ4ZDc0
|
15
|
+
Nzc4MjllNDYyZGZjNTJjM2FiNmFkNTUxMmEwNmM3ODFkODNlZmU=
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,31 @@
|
|
1
|
+
module SimpleParams
|
2
|
+
class ApiPieDoc::NestedArray < ApiPieDoc::AttributeBase
|
3
|
+
|
4
|
+
attr_accessor :attributes
|
5
|
+
|
6
|
+
def initialize(simple_params_array)
|
7
|
+
super
|
8
|
+
self.attributes = attribute.values[0].map { |attribute| ApiPieDoc::Attribute.new(attribute) }
|
9
|
+
self.options ||= attribute.delete(:options) || attribute[1]
|
10
|
+
end
|
11
|
+
|
12
|
+
def name
|
13
|
+
attribute.keys.first.to_s
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
return nil if do_not_document?
|
18
|
+
nested_description
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def nested_description
|
24
|
+
start = "param :#{name}, Array, #{description}, #{requirement_description} do"
|
25
|
+
attribute_descriptors = []
|
26
|
+
attributes.each { |attribute| attribute_descriptors << attribute.to_s }
|
27
|
+
finish = "end"
|
28
|
+
[start, attribute_descriptors, finish].flatten.join("\n")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -3,16 +3,21 @@ module SimpleParams
|
|
3
3
|
|
4
4
|
attr_accessor :base_attributes,
|
5
5
|
:nested_hashes,
|
6
|
+
:nested_arrays,
|
6
7
|
:nested_attributes,
|
8
|
+
:nested_array_attributes,
|
7
9
|
:docs
|
8
10
|
|
9
11
|
def initialize(simple_params)
|
10
12
|
self.base_attributes = simple_params.defined_attributes
|
11
13
|
self.nested_hashes = simple_params.nested_hashes
|
14
|
+
self.nested_arrays = simple_params.nested_arrays
|
12
15
|
self.nested_attributes = []
|
16
|
+
self.nested_array_attributes = []
|
13
17
|
self.docs = []
|
14
18
|
|
15
19
|
build_nested_attributes
|
20
|
+
build_nested_array_attributes
|
16
21
|
end
|
17
22
|
|
18
23
|
def build
|
@@ -24,6 +29,10 @@ module SimpleParams
|
|
24
29
|
docs << NestedAttribute.new(nested_attribute).to_s
|
25
30
|
end
|
26
31
|
|
32
|
+
nested_array_attributes.each do |nested_attribute|
|
33
|
+
docs << NestedArray.new(nested_attribute).to_s
|
34
|
+
end
|
35
|
+
|
27
36
|
docs.join("\n")
|
28
37
|
end
|
29
38
|
|
@@ -34,5 +43,11 @@ module SimpleParams
|
|
34
43
|
nested_attributes << { name => parameter_set.defined_attributes, options: parameter_set.options }
|
35
44
|
end
|
36
45
|
end
|
46
|
+
|
47
|
+
def build_nested_array_attributes
|
48
|
+
nested_arrays.each do |name, parameter_set|
|
49
|
+
nested_array_attributes << { name => parameter_set.defined_attributes, options: parameter_set.options }
|
50
|
+
end
|
51
|
+
end
|
37
52
|
end
|
38
53
|
end
|
data/lib/simple_params/errors.rb
CHANGED
@@ -2,14 +2,23 @@ require "active_model"
|
|
2
2
|
|
3
3
|
module SimpleParams
|
4
4
|
class Errors < ActiveModel::Errors
|
5
|
+
attr_reader :base
|
5
6
|
|
6
|
-
def initialize(base,
|
7
|
+
def initialize(base, nested_hash_errors = {}, nested_array_errors = {})
|
7
8
|
super(base)
|
8
|
-
@
|
9
|
+
@base = base
|
10
|
+
@nested_hash_errors = symbolize_nested(nested_hash_errors)
|
11
|
+
@nested_array_errors = symbolize_nested(nested_array_errors)
|
9
12
|
end
|
10
13
|
|
11
14
|
def [](attribute)
|
12
|
-
|
15
|
+
if is_a_nested_hash_error_attribute?(attribute)
|
16
|
+
set(attribute.to_sym, @nested_hash_errors[attribute.to_sym])
|
17
|
+
elsif is_a_nested_array_error_attribute?(attribute)
|
18
|
+
set(attribute.to_sym, @nested_array_errors[attribute.to_sym])
|
19
|
+
else
|
20
|
+
get(attribute.to_sym) || set(attribute.to_sym, [])
|
21
|
+
end
|
13
22
|
end
|
14
23
|
|
15
24
|
def []=(attribute, error)
|
@@ -28,26 +37,18 @@ module SimpleParams
|
|
28
37
|
|
29
38
|
def clear
|
30
39
|
super
|
31
|
-
@
|
32
|
-
if fetch_nested_attribute(attribute).present?
|
33
|
-
fetch_nested_attribute(attribute).errors.clear
|
34
|
-
end
|
35
|
-
end
|
40
|
+
@nested_hash_errors.map { |attribute, errors| errors.clear }
|
36
41
|
end
|
37
42
|
|
38
43
|
def empty?
|
39
44
|
super &&
|
40
|
-
@
|
41
|
-
if fetch_nested_attribute(attribute).present?
|
42
|
-
fetch_nested_attribute(attribute).errors.empty?
|
43
|
-
end
|
44
|
-
end
|
45
|
+
@nested_hash_errors.all? { |attribute, errors| errors.empty? }
|
45
46
|
end
|
46
47
|
alias_method :blank?, :empty?
|
47
48
|
|
48
49
|
def include?(attribute)
|
49
|
-
if
|
50
|
-
|
50
|
+
if is_a_nested_hash_error_attribute?(attribute)
|
51
|
+
!@nested_hash_errors[attribute.to_sym].empty?
|
51
52
|
else
|
52
53
|
messages[attribute].present?
|
53
54
|
end
|
@@ -57,21 +58,16 @@ module SimpleParams
|
|
57
58
|
|
58
59
|
def values
|
59
60
|
messages.values +
|
60
|
-
@
|
61
|
-
|
62
|
-
fetch_nested_attribute(attribute).errors.values
|
63
|
-
end
|
61
|
+
@nested_hash_errors.map do |attribute, errors|
|
62
|
+
errors.values
|
64
63
|
end
|
65
64
|
end
|
66
65
|
|
67
66
|
def full_messages
|
68
67
|
parent_messages = map { |attribute, message| full_message(attribute, message) }
|
69
|
-
nested_messages = @
|
70
|
-
|
71
|
-
|
72
|
-
messages.map do |message|
|
73
|
-
"#{attribute} " + message
|
74
|
-
end
|
68
|
+
nested_messages = @nested_hash_errors.map do |attribute, errors|
|
69
|
+
unless errors.full_messages.nil?
|
70
|
+
errors.full_messages.map { |message| "#{attribute} " + message }
|
75
71
|
end
|
76
72
|
end
|
77
73
|
(parent_messages + nested_messages).flatten
|
@@ -88,10 +84,10 @@ module SimpleParams
|
|
88
84
|
self.messages.dup
|
89
85
|
end
|
90
86
|
|
91
|
-
@
|
92
|
-
|
87
|
+
@nested_hash_errors.map do |attribute, errors|
|
88
|
+
error_messages = nested_error_messages(attribute, full_messages)
|
93
89
|
unless errors.empty?
|
94
|
-
messages.merge!(attribute.to_sym =>
|
90
|
+
messages.merge!(attribute.to_sym => error_messages)
|
95
91
|
end
|
96
92
|
end
|
97
93
|
messages
|
@@ -104,14 +100,14 @@ module SimpleParams
|
|
104
100
|
|
105
101
|
private
|
106
102
|
def nested_error_messages(attribute, full_messages = false)
|
107
|
-
if
|
108
|
-
|
109
|
-
|
103
|
+
if is_a_nested_hash_error_attribute?(attribute)
|
104
|
+
errors = @nested_hash_errors[attribute.to_sym]
|
105
|
+
if full_messages
|
110
106
|
errors.messages.each_with_object({}) do |(attr, array), messages|
|
111
107
|
messages[attr] = array.map { |message| errors.full_message(attr, message) }
|
112
108
|
end
|
113
109
|
else
|
114
|
-
|
110
|
+
errors.messages.dup
|
115
111
|
end
|
116
112
|
else
|
117
113
|
{}
|
@@ -119,29 +115,23 @@ module SimpleParams
|
|
119
115
|
end
|
120
116
|
|
121
117
|
def add_error_to_attribute(attribute, error)
|
122
|
-
if
|
123
|
-
|
118
|
+
if is_a_nested_hash_error_attribute?(attribute)
|
119
|
+
@nested_hash_errors[attribute.to_sym][:base] = error
|
124
120
|
else
|
125
121
|
self[attribute] << error
|
126
122
|
end
|
127
123
|
end
|
128
124
|
|
129
|
-
def
|
130
|
-
|
131
|
-
set(attribute.to_sym, fetch_nested_attribute(attribute).errors)
|
132
|
-
else
|
133
|
-
set(attribute.to_sym, [])
|
134
|
-
end
|
125
|
+
def is_a_nested_hash_error_attribute?(attribute)
|
126
|
+
@nested_hash_errors.keys.include?(attribute.to_sym)
|
135
127
|
end
|
136
128
|
|
137
|
-
def
|
138
|
-
|
139
|
-
@base.send(attribute)
|
140
|
-
end
|
129
|
+
def is_a_nested_array_error_attribute?(attribute)
|
130
|
+
@nested_array_errors.keys.include?(attribute.to_sym)
|
141
131
|
end
|
142
132
|
|
143
133
|
def symbolize_nested(nested)
|
144
|
-
nested.
|
134
|
+
nested.inject({}) { |memo,(k,v) | memo[k.to_sym] = v; memo }
|
145
135
|
end
|
146
136
|
end
|
147
137
|
end
|
data/lib/simple_params/params.rb
CHANGED
@@ -5,6 +5,7 @@ module SimpleParams
|
|
5
5
|
class Params
|
6
6
|
include Virtus.model
|
7
7
|
include ActiveModel::Validations
|
8
|
+
extend ActiveModel::Naming
|
8
9
|
include SimpleParams::Validations
|
9
10
|
|
10
11
|
TYPES = [
|
@@ -31,6 +32,10 @@ module SimpleParams
|
|
31
32
|
|
32
33
|
attr_accessor :strict_enforcement, :options
|
33
34
|
|
35
|
+
def model_name
|
36
|
+
ActiveModel::Name.new(self)
|
37
|
+
end
|
38
|
+
|
34
39
|
def api_pie_documentation
|
35
40
|
SimpleParams::ApiPieDoc.new(self).build
|
36
41
|
end
|
@@ -61,11 +66,22 @@ module SimpleParams
|
|
61
66
|
@nested_hashes ||= {}
|
62
67
|
end
|
63
68
|
|
69
|
+
def nested_array(name, opts={}, &block)
|
70
|
+
attr_accessor name
|
71
|
+
nested_array_class = define_nested_class(name, opts, &block)
|
72
|
+
@nested_arrays ||= {}
|
73
|
+
@nested_arrays[name.to_sym] = nested_array_class
|
74
|
+
end
|
75
|
+
|
76
|
+
def nested_arrays
|
77
|
+
@nested_arrays ||= {}
|
78
|
+
end
|
79
|
+
|
64
80
|
def defined_attributes
|
65
81
|
@define_attributes ||= {}
|
66
82
|
end
|
67
|
-
private
|
68
83
|
|
84
|
+
private
|
69
85
|
def define_attribute(name, opts = {})
|
70
86
|
opts[:type] ||= :string
|
71
87
|
defined_attributes[name.to_sym] = opts
|
@@ -103,12 +119,10 @@ module SimpleParams
|
|
103
119
|
def define_nested_class(name, options, &block)
|
104
120
|
klass_name = name.to_s.split('_').collect(&:capitalize).join
|
105
121
|
Class.new(Params).tap do |klass|
|
106
|
-
|
107
|
-
|
108
|
-
# end
|
122
|
+
self.const_set(klass_name, klass)
|
123
|
+
extend ActiveModel::Naming
|
109
124
|
klass.class_eval(&block)
|
110
125
|
klass.class_eval("self.options = #{options}")
|
111
|
-
self.const_set(klass_name, klass)
|
112
126
|
end
|
113
127
|
end
|
114
128
|
end
|
@@ -124,13 +138,16 @@ module SimpleParams
|
|
124
138
|
@original_params = hash_to_symbolized_hash(params)
|
125
139
|
define_attributes(@original_params)
|
126
140
|
|
127
|
-
#
|
141
|
+
# Nested Hashes
|
128
142
|
@nested_params = nested_hashes.keys
|
129
|
-
|
143
|
+
|
144
|
+
# Nested Arrays
|
145
|
+
@nested_arrays = nested_arrays.keys
|
130
146
|
|
131
147
|
# Nested Classes
|
132
148
|
set_accessors(params)
|
133
149
|
initialize_nested_classes
|
150
|
+
initialize_nested_array_classes
|
134
151
|
end
|
135
152
|
|
136
153
|
def define_attributes(params)
|
@@ -140,7 +157,7 @@ module SimpleParams
|
|
140
157
|
end
|
141
158
|
|
142
159
|
def attributes
|
143
|
-
(defined_attributes.keys + nested_hashes.keys).flatten
|
160
|
+
(defined_attributes.keys + nested_hashes.keys + nested_arrays.keys).flatten
|
144
161
|
end
|
145
162
|
|
146
163
|
def original_params
|
@@ -151,9 +168,6 @@ module SimpleParams
|
|
151
168
|
|
152
169
|
def to_hash
|
153
170
|
hash = {}
|
154
|
-
# self.class.defined_attributes.each_pair do |key, opts|
|
155
|
-
# hash[key.to_sym] = send(key)
|
156
|
-
# end
|
157
171
|
attributes.each do |attribute|
|
158
172
|
if send(attribute).is_a?(SimpleParams::Params)
|
159
173
|
hash[attribute] = send(attribute).to_hash
|
@@ -165,6 +179,20 @@ module SimpleParams
|
|
165
179
|
hash
|
166
180
|
end
|
167
181
|
|
182
|
+
def errors
|
183
|
+
nested_errors_hash = {}
|
184
|
+
@nested_params.each do |param|
|
185
|
+
nested_errors_hash[param.to_sym] = send(param).errors
|
186
|
+
end
|
187
|
+
|
188
|
+
nested_arrays_hash = {}
|
189
|
+
@nested_arrays.each do |array|
|
190
|
+
nested_arrays_hash[array.to_sym] = send(array).map(&:errors)
|
191
|
+
end
|
192
|
+
|
193
|
+
@errors ||= SimpleParams::Errors.new(self, nested_errors_hash, nested_arrays_hash)
|
194
|
+
end
|
195
|
+
|
168
196
|
# Overriding this method to allow for non-strict enforcement!
|
169
197
|
def method_missing(method_name, *arguments, &block)
|
170
198
|
if strict_enforcement?
|
@@ -197,7 +225,7 @@ module SimpleParams
|
|
197
225
|
def set_accessors(params={})
|
198
226
|
params.each do |attribute_name, value|
|
199
227
|
# Don't set accessors for nested classes
|
200
|
-
unless value.is_a?(Hash)
|
228
|
+
unless value.is_a?(Hash)
|
201
229
|
send("#{attribute_name}=", value)
|
202
230
|
end
|
203
231
|
end
|
@@ -226,6 +254,10 @@ module SimpleParams
|
|
226
254
|
self.class.nested_hashes
|
227
255
|
end
|
228
256
|
|
257
|
+
def nested_arrays
|
258
|
+
self.class.nested_arrays
|
259
|
+
end
|
260
|
+
|
229
261
|
def initialize_nested_classes
|
230
262
|
nested_hashes.each do |key, klass|
|
231
263
|
initialization_params = @original_params[key.to_sym] || {}
|
@@ -233,6 +265,17 @@ module SimpleParams
|
|
233
265
|
end
|
234
266
|
end
|
235
267
|
|
268
|
+
def initialize_nested_array_classes
|
269
|
+
nested_arrays.each do |key, klass|
|
270
|
+
initialization_params = @original_params[key.to_sym] || []
|
271
|
+
initialization_array = []
|
272
|
+
initialization_params.each do |initialization_param|
|
273
|
+
initialization_array << klass.new(initialization_param, self)
|
274
|
+
end
|
275
|
+
send("#{key}=", initialization_array)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
236
279
|
def define_anonymous_class(name, hash)
|
237
280
|
klass_name = name.to_s.split('_').collect(&:capitalize).join
|
238
281
|
anonymous_klass = Class.new(Params).tap do |klass|
|
@@ -14,6 +14,11 @@ module SimpleParams
|
|
14
14
|
nested_class = send("#{key}")
|
15
15
|
nested_class.valid?
|
16
16
|
end
|
17
|
+
|
18
|
+
nested_arrays.each do |key, array|
|
19
|
+
nested_array = send("#{key}")
|
20
|
+
nested_array.each { |a| a.valid? }
|
21
|
+
end
|
17
22
|
errors.empty?
|
18
23
|
ensure
|
19
24
|
self.validation_context = current_context
|
data/lib/simple_params.rb
CHANGED
@@ -9,6 +9,7 @@ require 'simple_params/type_mappings'
|
|
9
9
|
require 'simple_params/api_pie_doc'
|
10
10
|
require 'simple_params/api_pie_doc/attribute_base'
|
11
11
|
require 'simple_params/api_pie_doc/attribute'
|
12
|
+
require 'simple_params/api_pie_doc/nested_array'
|
12
13
|
require 'simple_params/api_pie_doc/nested_attribute'
|
13
14
|
require 'simple_params/validation_matchers/validation_matcher'
|
14
15
|
require 'simple_params/validation_matchers/coercion_matcher'
|
data/spec/acceptance_spec.rb
CHANGED
@@ -6,6 +6,7 @@ class AcceptanceParams < SimpleParams::Params
|
|
6
6
|
param :name
|
7
7
|
param :age, type: :integer, optional: true, validations: { inclusion: { in: 18..100 } }
|
8
8
|
param :color, default: "red", validations: { inclusion: { in: ["red", "green"] }}
|
9
|
+
param :sibling_names, type: :array, optional: true
|
9
10
|
validate :name_has_letters
|
10
11
|
|
11
12
|
nested_hash :address do
|
@@ -16,6 +17,11 @@ class AcceptanceParams < SimpleParams::Params
|
|
16
17
|
param :company, optional: true
|
17
18
|
end
|
18
19
|
|
20
|
+
nested_array :dogs do
|
21
|
+
param :name
|
22
|
+
param :age, type: :integer, validations: { inclusion: { in: 1..20 } }
|
23
|
+
end
|
24
|
+
|
19
25
|
def name_has_letters
|
20
26
|
if name.present? && !(name =~ /^[a-zA-Z]*$/)
|
21
27
|
errors.add(:name, "must only contain letters")
|
@@ -59,13 +65,15 @@ describe SimpleParams::Params do
|
|
59
65
|
name: "Tom",
|
60
66
|
age: nil,
|
61
67
|
color: "red",
|
68
|
+
sibling_names: nil,
|
62
69
|
address: {
|
63
70
|
street: "1 Main St.",
|
64
71
|
city: nil,
|
65
72
|
zip_code: nil,
|
66
73
|
state: "North Carolina",
|
67
74
|
company: nil
|
68
|
-
}
|
75
|
+
},
|
76
|
+
dogs: []
|
69
77
|
})
|
70
78
|
end
|
71
79
|
end
|
@@ -135,7 +143,7 @@ describe SimpleParams::Params do
|
|
135
143
|
describe "attributes", attributes: true do
|
136
144
|
it "returns array of attribute symbols" do
|
137
145
|
params = AcceptanceParams.new
|
138
|
-
params.attributes.should eq([:reference, :name, :age, :color, :address])
|
146
|
+
params.attributes.should eq([:reference, :name, :age, :color, :sibling_names, :address, :dogs])
|
139
147
|
end
|
140
148
|
|
141
149
|
it "returns array of attribute symbols for nested class" do
|
@@ -305,6 +313,7 @@ describe SimpleParams::Params do
|
|
305
313
|
param :name, String, desc: '', required: true
|
306
314
|
param :age, Integer, desc: '', required: false
|
307
315
|
param :color, String, desc: '', required: false
|
316
|
+
param :sibling_names, Array, desc: '', required: false
|
308
317
|
param :address, Hash, desc: '', required: true do
|
309
318
|
param :street, String, desc: '', required: true
|
310
319
|
param :city, String, desc: '', required: true
|
@@ -312,6 +321,10 @@ describe SimpleParams::Params do
|
|
312
321
|
param :state, String, desc: '', required: false
|
313
322
|
param :company, String, desc: '', required: false
|
314
323
|
end
|
324
|
+
param :dogs, Array, desc: '', required: true do
|
325
|
+
param :name, String, desc: '', required: true
|
326
|
+
param :age, Integer, desc: '', required: true
|
327
|
+
end
|
315
328
|
API_PIE_DOCS
|
316
329
|
|
317
330
|
expect(documentation).to be_a String
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SimpleParams::ApiPieDoc::NestedArray do
|
4
|
+
|
5
|
+
let(:simple_param_attribute) {
|
6
|
+
{:address=>
|
7
|
+
{:street=>{:type=>:string},
|
8
|
+
:city=>{:validations=>{:length=>{:in=>4..40}, :presence=>true}, :type=>:string},
|
9
|
+
:zip_code=>{:optional=>true, :type=>:string},
|
10
|
+
:state=>{:default=>"North Carolina", :type=>:string}
|
11
|
+
},
|
12
|
+
:options=>{desc: 'i like pie'}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
let(:nested_attribute) { described_class.new(simple_param_attribute) }
|
16
|
+
|
17
|
+
it_behaves_like 'a base attribute'
|
18
|
+
|
19
|
+
describe '#initialize' do
|
20
|
+
specify 'should give instance an attribute' do
|
21
|
+
expect(nested_attribute.attribute).to eq simple_param_attribute
|
22
|
+
end
|
23
|
+
|
24
|
+
specify 'should give instance options' do
|
25
|
+
expect(nested_attribute.options).to eq({ desc: 'i like pie' })
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#name' do
|
30
|
+
specify 'should set respond with the right name' do
|
31
|
+
expect(nested_attribute.name).to eq 'address'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#options' do
|
36
|
+
specify 'should return nested attribute options' do
|
37
|
+
expect(nested_attribute.options).to eq({desc: 'i like pie'})
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#to_s' do
|
42
|
+
specify 'should return properly formatted string' do
|
43
|
+
expect(nested_attribute.to_s).to eq("param :address, Array, desc: 'i like pie', required: true do\nparam :street, String, desc: '', required: true\nparam :city, String, desc: '', required: true\nparam :zip_code, String, desc: '', required: false\nparam :state, String, desc: '', required: false\nend")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/api_pie_doc_spec.rb
CHANGED
@@ -16,17 +16,31 @@ describe SimpleParams::ApiPieDoc do
|
|
16
16
|
expect(api_pie_doc.nested_hashes.keys).to eq [:address, :phone]
|
17
17
|
end
|
18
18
|
|
19
|
+
specify "should give object nested_arrays" do
|
20
|
+
expect(api_pie_doc.nested_arrays.keys).to eq [:dogs]
|
21
|
+
end
|
22
|
+
|
19
23
|
specify "should call #build_nested_attributes" do
|
20
24
|
expect_any_instance_of(SimpleParams::ApiPieDoc).to receive(:build_nested_attributes)
|
21
25
|
api_pie_doc
|
22
26
|
end
|
23
27
|
|
28
|
+
specify "should call #build_nested_array_attributes" do
|
29
|
+
expect_any_instance_of(SimpleParams::ApiPieDoc).to receive(:build_nested_array_attributes)
|
30
|
+
api_pie_doc
|
31
|
+
end
|
32
|
+
|
24
33
|
specify "should give object nested_attributes" do
|
25
34
|
expect(api_pie_doc.nested_attributes.flat_map(&:keys)).to include(:address, :phone)
|
26
35
|
expect(api_pie_doc.nested_attributes[0].values.flat_map(&:keys)).to eq [:street, :city, :zip_code, :state]
|
27
36
|
expect(api_pie_doc.nested_attributes[1].values.flat_map(&:keys)).to eq [:cell_phone, :phone_number, :area_code]
|
28
37
|
end
|
29
38
|
|
39
|
+
specify "should give object nested_array_attributes" do
|
40
|
+
expect(api_pie_doc.nested_array_attributes.flat_map(&:keys)).to include(:dogs)
|
41
|
+
expect(api_pie_doc.nested_array_attributes[0].values.flat_map(&:keys)).to eq [:name, :age]
|
42
|
+
end
|
43
|
+
|
30
44
|
specify "should give object docs" do
|
31
45
|
expect(api_pie_doc.docs).to eq []
|
32
46
|
end
|
data/spec/errors_spec.rb
CHANGED
@@ -4,7 +4,10 @@ describe SimpleParams::Errors do
|
|
4
4
|
class Person
|
5
5
|
extend ActiveModel::Naming
|
6
6
|
def initialize
|
7
|
-
@errors = SimpleParams::Errors.new(self,
|
7
|
+
@errors = SimpleParams::Errors.new(self,
|
8
|
+
{ dog: dog.errors },
|
9
|
+
{ cats: cats_errors },
|
10
|
+
)
|
8
11
|
end
|
9
12
|
|
10
13
|
attr_accessor :name, :age
|
@@ -14,6 +17,14 @@ describe SimpleParams::Errors do
|
|
14
17
|
@dog ||= Dog.new
|
15
18
|
end
|
16
19
|
|
20
|
+
def cats
|
21
|
+
@cats ||= [Cat.new]
|
22
|
+
end
|
23
|
+
|
24
|
+
def cats_errors
|
25
|
+
cats.map { |cat| cat.errors }
|
26
|
+
end
|
27
|
+
|
17
28
|
def read_attribute_for_validation(attr)
|
18
29
|
send(attr)
|
19
30
|
end
|
@@ -49,7 +60,30 @@ describe SimpleParams::Errors do
|
|
49
60
|
end
|
50
61
|
end
|
51
62
|
|
52
|
-
|
63
|
+
class Cat
|
64
|
+
extend ActiveModel::Naming
|
65
|
+
def initialize
|
66
|
+
@errors = SimpleParams::Errors.new(self)
|
67
|
+
end
|
68
|
+
|
69
|
+
attr_accessor :name
|
70
|
+
attr_accessor :age
|
71
|
+
attr_reader :errors
|
72
|
+
|
73
|
+
def read_attribute_for_validation(attr)
|
74
|
+
send(attr)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.human_attribute_name(attr, options = {})
|
78
|
+
attr
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.lookup_ancestors
|
82
|
+
[self]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "setting and getting errors", setters_getters: true do
|
53
87
|
it "get returns the errors for the provided key" do
|
54
88
|
errors = SimpleParams::Errors.new(self)
|
55
89
|
errors[:foo] = "omg"
|
@@ -105,7 +139,7 @@ describe SimpleParams::Errors do
|
|
105
139
|
end
|
106
140
|
end
|
107
141
|
|
108
|
-
describe "setting and getting nested error model" do
|
142
|
+
describe "setting and getting nested error model", nested_model: true do
|
109
143
|
it "can access error model" do
|
110
144
|
person = Person.new
|
111
145
|
dog = person.dog
|
@@ -152,7 +186,55 @@ describe SimpleParams::Errors do
|
|
152
186
|
end
|
153
187
|
end
|
154
188
|
|
155
|
-
describe "
|
189
|
+
describe "setting and getting nested array error model", nested_array: true do
|
190
|
+
it "can access error model" do
|
191
|
+
person = Person.new
|
192
|
+
cats = person.cats
|
193
|
+
cat_errors = cats.first.errors
|
194
|
+
person.errors[:cats][0].should eq(cat_errors)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "can add to nested errors through []", failing: true do
|
198
|
+
person = Person.new
|
199
|
+
person.errors[:cats].first[:base] = 'should not be nil'
|
200
|
+
person.errors[:cats].first[:base].should eq(['should not be nil'])
|
201
|
+
person.cats.first.errors[:base].should eq(['should not be nil'])
|
202
|
+
end
|
203
|
+
|
204
|
+
it "can add to nested errors through add" do
|
205
|
+
person = Person.new
|
206
|
+
person.errors[:cats].first.add(:age, 'should not be nil')
|
207
|
+
person.cats.first.errors[:age].should eq(['should not be nil'])
|
208
|
+
end
|
209
|
+
|
210
|
+
it "can add multiple errors to nested errors through []" do
|
211
|
+
person = Person.new
|
212
|
+
person.errors[:cats].first[:name] = 'should not be nil'
|
213
|
+
person.errors[:cats].first[:name] = 'must be cute'
|
214
|
+
person.cats.first.errors[:name].should eq(['should not be nil', 'must be cute'])
|
215
|
+
end
|
216
|
+
|
217
|
+
it "can add multiple errors to nested errors through add" do
|
218
|
+
person = Person.new
|
219
|
+
person.errors[:cats].first.add(:name, 'should not be nil')
|
220
|
+
person.errors[:cats].first.add(:name, 'must be cute')
|
221
|
+
person.cats.first.errors[:name].should eq(['should not be nil', 'must be cute'])
|
222
|
+
end
|
223
|
+
|
224
|
+
it "can add individual errors to nested attributes through []" do
|
225
|
+
person = Person.new
|
226
|
+
person.errors[:cats][0][:age] = 'should not be nil'
|
227
|
+
person.cats.first.errors[:age].should eq(['should not be nil'])
|
228
|
+
end
|
229
|
+
|
230
|
+
it "can add individual errors to nested attributes through add" do
|
231
|
+
person = Person.new
|
232
|
+
person.errors[:cats].first.add(:age, 'should not be nil')
|
233
|
+
person.cats.first.errors[:age].should eq(['should not be nil'])
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "#clear", clear: true do
|
156
238
|
it "clears errors" do
|
157
239
|
person = Person.new
|
158
240
|
person.errors[:name] = 'should not be nil'
|
@@ -173,7 +255,7 @@ describe SimpleParams::Errors do
|
|
173
255
|
end
|
174
256
|
end
|
175
257
|
|
176
|
-
describe "#empty?, #blank?, and #include?" do
|
258
|
+
describe "#empty?, #blank?, and #include?", empty: true do
|
177
259
|
it "is empty without any errors" do
|
178
260
|
person = Person.new
|
179
261
|
person.errors.should be_empty
|
@@ -201,7 +283,7 @@ describe SimpleParams::Errors do
|
|
201
283
|
end
|
202
284
|
end
|
203
285
|
|
204
|
-
describe "#added?" do
|
286
|
+
describe "#added?", added: true do
|
205
287
|
it "added? detects if a specific error was added to the object" do
|
206
288
|
person = Person.new
|
207
289
|
person.errors.add(:name, "can not be blank")
|
@@ -246,7 +328,7 @@ describe SimpleParams::Errors do
|
|
246
328
|
end
|
247
329
|
end
|
248
330
|
|
249
|
-
describe "#size" do
|
331
|
+
describe "#size", size: true do
|
250
332
|
it "size calculates the number of error messages" do
|
251
333
|
person = Person.new
|
252
334
|
person.errors.add(:name, "can not be blank")
|
@@ -260,7 +342,7 @@ describe SimpleParams::Errors do
|
|
260
342
|
end
|
261
343
|
end
|
262
344
|
|
263
|
-
describe "#to_a" do
|
345
|
+
describe "#to_a", to_a: true do
|
264
346
|
it "to_a returns the list of errors with complete messages containing the attribute names" do
|
265
347
|
person = Person.new
|
266
348
|
person.errors.add(:name, "can not be blank")
|
@@ -276,7 +358,7 @@ describe SimpleParams::Errors do
|
|
276
358
|
end
|
277
359
|
end
|
278
360
|
|
279
|
-
describe "#to_s" do
|
361
|
+
describe "#to_s", to_s: true do
|
280
362
|
it "to_a returns the list of errors with complete messages containing the attribute names" do
|
281
363
|
person = Person.new
|
282
364
|
person.errors.add(:name, "can not be blank")
|
@@ -292,8 +374,8 @@ describe SimpleParams::Errors do
|
|
292
374
|
end
|
293
375
|
end
|
294
376
|
|
295
|
-
describe "#to_hash" do
|
296
|
-
it "to_hash returns the error messages hash" do
|
377
|
+
describe "#to_hash", to_hash: true do
|
378
|
+
it "to_hash returns the error messages hash", hash_failing: true do
|
297
379
|
person = Person.new
|
298
380
|
person.errors.add(:name, "can not be blank")
|
299
381
|
person.errors.to_hash.should eq({ name: ["can not be blank"] })
|
@@ -328,7 +410,7 @@ describe SimpleParams::Errors do
|
|
328
410
|
end
|
329
411
|
end
|
330
412
|
|
331
|
-
describe "#as_json" do
|
413
|
+
describe "#as_json", as_json: true do
|
332
414
|
it "as_json creates a json formatted representation of the errors hash" do
|
333
415
|
person = Person.new
|
334
416
|
person.errors[:name] = 'can not be nil'
|
@@ -368,7 +450,7 @@ describe SimpleParams::Errors do
|
|
368
450
|
end
|
369
451
|
end
|
370
452
|
|
371
|
-
describe "#full_messages" do
|
453
|
+
describe "#full_messages", full_messages: true do
|
372
454
|
it "full_messages creates a list of error messages with the attribute name included" do
|
373
455
|
person = Person.new
|
374
456
|
person.errors.add(:name, "can not be blank")
|
@@ -408,7 +490,7 @@ describe SimpleParams::Errors do
|
|
408
490
|
end
|
409
491
|
end
|
410
492
|
|
411
|
-
describe "#generate_message" do
|
493
|
+
describe "#generate_message", generate_message: true do
|
412
494
|
it "generate_message works without i18n_scope" do
|
413
495
|
person = Person.new
|
414
496
|
Person.should_not respond_to(:i18n_scope)
|
@@ -418,7 +500,7 @@ describe SimpleParams::Errors do
|
|
418
500
|
end
|
419
501
|
end
|
420
502
|
|
421
|
-
describe "#adds_on_empty" do
|
503
|
+
describe "#adds_on_empty", add_on_empty: true do
|
422
504
|
it "add_on_empty generates message" do
|
423
505
|
person = Person.new
|
424
506
|
person.errors.should_receive(:generate_message).with(:name, :empty, {})
|
@@ -446,7 +528,7 @@ describe SimpleParams::Errors do
|
|
446
528
|
end
|
447
529
|
end
|
448
530
|
|
449
|
-
describe "#adds_on_blank" do
|
531
|
+
describe "#adds_on_blank", add_on_blank: true do
|
450
532
|
it "add_on_blank generates message" do
|
451
533
|
person = Person.new
|
452
534
|
person.errors.should_receive(:generate_message).with(:name, :blank, {})
|
data/spec/params_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'fixtures/dummy_params'
|
3
3
|
|
4
4
|
describe SimpleParams::Params do
|
5
|
-
describe "strict parameter enforcement" do
|
5
|
+
describe "strict parameter enforcement", param_enforcement: true do
|
6
6
|
context "with default handling (strict enforcement)" do
|
7
7
|
it "raises error on expected param" do
|
8
8
|
expect { DummyParams.new(other_param: 1) }.to raise_error(SimpleParamsError)
|
@@ -67,12 +67,26 @@ describe SimpleParams::Params do
|
|
67
67
|
params.address.zip_code.should eq("20165")
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
describe "nested arrays", nested: true do
|
72
|
+
it "can access nested arrays as arrays" do
|
73
|
+
params.dogs.should respond_to(:first)
|
74
|
+
params.dogs.first.should be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "can access nested arrays as arrays with data", failing: true do
|
78
|
+
params = DummyParams.new(dogs: [{ name: "Spot", age: 20 }])
|
79
|
+
params.dogs.should respond_to(:first)
|
80
|
+
params.dogs.first.should_not be_nil
|
81
|
+
params.dogs.first.name.should eq("Spot")
|
82
|
+
end
|
83
|
+
end
|
70
84
|
end
|
71
85
|
|
72
86
|
describe "attributes", attributes: true do
|
73
87
|
it "returns array of attribute symbols" do
|
74
88
|
params = DummyParams.new
|
75
|
-
params.attributes.should eq([:name, :age, :first_initial, :amount, :color, :height, :address, :phone])
|
89
|
+
params.attributes.should eq([:name, :age, :first_initial, :amount, :color, :height, :address, :phone, :dogs])
|
76
90
|
end
|
77
91
|
end
|
78
92
|
|
@@ -123,7 +137,40 @@ describe SimpleParams::Params do
|
|
123
137
|
end
|
124
138
|
end
|
125
139
|
|
126
|
-
describe "
|
140
|
+
describe "validations", validations: true do
|
141
|
+
let(:params) do
|
142
|
+
DummyParams.new(
|
143
|
+
name: nil,
|
144
|
+
age: 30,
|
145
|
+
address: {
|
146
|
+
city: "Greenville"
|
147
|
+
},
|
148
|
+
dogs: [
|
149
|
+
{ name: "Spot", age: 12 },
|
150
|
+
{ age: 14 }
|
151
|
+
]
|
152
|
+
)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "validates required params" do
|
156
|
+
params.should_not be_valid
|
157
|
+
params.errors[:name].should eq(["can't be blank"])
|
158
|
+
end
|
159
|
+
|
160
|
+
it "validates nested params" do
|
161
|
+
params.should_not be_valid
|
162
|
+
params.address.errors[:street].should eq(["can't be blank"])
|
163
|
+
params.errors[:address][:street].should eq(["can't be blank"])
|
164
|
+
end
|
165
|
+
|
166
|
+
it "validates nested arrays" do
|
167
|
+
params.should_not be_valid
|
168
|
+
params.errors[:dogs][0][:name].should eq([])
|
169
|
+
params.errors[:dogs][1][:name].should eq(["can't be blank"])
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "optional params with inclusion", optional_params: true do
|
127
174
|
let(:params) do
|
128
175
|
DummyParams.new(
|
129
176
|
name: "Bill",
|
@@ -311,7 +358,7 @@ describe SimpleParams::Params do
|
|
311
358
|
end
|
312
359
|
|
313
360
|
describe "api_pie_documentation", api_pie_documentation: true do
|
314
|
-
it "generates
|
361
|
+
it "generates valid api_pie documentation" do
|
315
362
|
documentation = DummyParams.api_pie_documentation
|
316
363
|
api_docs = <<-API_PIE_DOCS
|
317
364
|
param :name, String, desc: '', required: true
|
@@ -331,6 +378,10 @@ describe SimpleParams::Params do
|
|
331
378
|
param :phone_number, String, desc: '', required: true
|
332
379
|
param :area_code, String, desc: '', required: false
|
333
380
|
end
|
381
|
+
param :dogs, Array, desc: '', required: true do
|
382
|
+
param :name, String, desc: '', required: true
|
383
|
+
param :age, Integer, desc: '', required: true
|
384
|
+
end
|
334
385
|
API_PIE_DOCS
|
335
386
|
|
336
387
|
expect(documentation).to be_a String
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_params
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- brycesenz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- lib/simple_params/api_pie_doc.rb
|
132
132
|
- lib/simple_params/api_pie_doc/attribute.rb
|
133
133
|
- lib/simple_params/api_pie_doc/attribute_base.rb
|
134
|
+
- lib/simple_params/api_pie_doc/nested_array.rb
|
134
135
|
- lib/simple_params/api_pie_doc/nested_attribute.rb
|
135
136
|
- lib/simple_params/attribute.rb
|
136
137
|
- lib/simple_params/errors.rb
|
@@ -149,6 +150,7 @@ files:
|
|
149
150
|
- simple_params.gemspec
|
150
151
|
- spec/acceptance_spec.rb
|
151
152
|
- spec/api_pie_doc/attribute_spec.rb
|
153
|
+
- spec/api_pie_doc/nested_array_spec.rb
|
152
154
|
- spec/api_pie_doc/nested_attribute_spec.rb
|
153
155
|
- spec/api_pie_doc_spec.rb
|
154
156
|
- spec/attribute_spec.rb
|
@@ -191,6 +193,7 @@ summary: A DSL for specifying params, including type coercion and validation
|
|
191
193
|
test_files:
|
192
194
|
- spec/acceptance_spec.rb
|
193
195
|
- spec/api_pie_doc/attribute_spec.rb
|
196
|
+
- spec/api_pie_doc/nested_array_spec.rb
|
194
197
|
- spec/api_pie_doc/nested_attribute_spec.rb
|
195
198
|
- spec/api_pie_doc_spec.rb
|
196
199
|
- spec/attribute_spec.rb
|