simple_params 0.0.1pre2

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.
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+
3
+ class AcceptanceParams < SimpleParams::Params
4
+ param :name
5
+ param :age, type: Integer, optional: true
6
+ param :color, default: "red", validations: { inclusion: { in: ["red", "green"] }}
7
+
8
+ nested_hash :address do
9
+ param :street
10
+ param :city, validations: { length: { in: 4..40 } }
11
+ param :zip_code, optional: true
12
+ param :state, default: "North Carolina"
13
+ end
14
+ end
15
+
16
+ describe SimpleParams::Params do
17
+ describe "accessors", accessors: true do
18
+ let(:params) { AcceptanceParams.new }
19
+
20
+ it "has getter and setter methods for required param" do
21
+ params.should respond_to(:name)
22
+ params.name.should be_nil
23
+ params.name = "Tom"
24
+ params.name.should eq("Tom")
25
+ end
26
+
27
+ it "has getter and setter methods for optional param" do
28
+ params.should respond_to(:age)
29
+ params.name.should be_nil
30
+ params.age = 19
31
+ params.age.should eq(19)
32
+ end
33
+
34
+ describe "nested params", nested: true do
35
+ it "has getter and setter methods for required param" do
36
+ params.address.should respond_to(:street)
37
+ params.address.street.should be_nil
38
+ params.address.street = "1 Main St."
39
+ params.address.street.should eq("1 Main St.")
40
+ end
41
+
42
+ it "has getter and setter methods for optional param" do
43
+ params.address.should respond_to(:zip_code)
44
+ params.address.zip_code.should be_nil
45
+ params.address.zip_code = "20165"
46
+ params.address.zip_code.should eq("20165")
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "array syntax", array_syntax: true do
52
+ let(:params) do
53
+ AcceptanceParams.new(
54
+ name: "Bill",
55
+ age: 30,
56
+ address: {
57
+ city: "Greenville"
58
+ }
59
+ )
60
+ end
61
+
62
+ it "can access 'name' through array syntax" do
63
+ params[:name].should eq("Bill")
64
+ params["name"].should eq("Bill")
65
+ end
66
+
67
+ it "can set 'name' through array syntax" do
68
+ params[:name] = "Tom"
69
+ params[:name].should eq("Tom")
70
+ params["name"].should eq("Tom")
71
+ end
72
+
73
+ it "can access 'age' through array syntax" do
74
+ params[:age].should eq(30)
75
+ params["age"].should eq(30)
76
+ end
77
+
78
+ it "can set 'age' through array syntax" do
79
+ params[:age] = 42
80
+ params[:age].should eq(42)
81
+ params["age"].should eq(42)
82
+ end
83
+
84
+ describe "nested params", nested: true do
85
+ it "can access 'city' through array syntax" do
86
+ params[:address][:city].should eq("Greenville")
87
+ params["address"]["city"].should eq("Greenville")
88
+ end
89
+
90
+ it "can set 'city' through array syntax" do
91
+ params[:address][:city] = "Asheville"
92
+ params[:address][:city].should eq("Asheville")
93
+ params["address"]["city"].should eq("Asheville")
94
+ end
95
+ end
96
+ end
97
+
98
+ describe "validations", validations: true do
99
+ let(:params) { AcceptanceParams.new }
100
+
101
+ it "validates presence of required param" do
102
+ params.should_not be_valid
103
+ params.errors[:name].should eq(["can't be blank"])
104
+ end
105
+
106
+ it "does not validate presence of optional param" do
107
+ params.should_not be_valid
108
+ params.errors[:age].should be_empty
109
+ end
110
+
111
+ it "does validate other validations of optional param" do
112
+ params = AcceptanceParams.new(color: "blue")
113
+ params.should_not be_valid
114
+ params.errors[:color].should eq(["is not included in the list"])
115
+ end
116
+
117
+ describe "nested params", nested: true do
118
+ it "validates presence of required param" do
119
+ params.should_not be_valid
120
+ params.errors[:address][:street].should eq(["can't be blank"])
121
+ end
122
+
123
+ it "does not validate presence of optional param" do
124
+ params.should_not be_valid
125
+ params.errors[:address][:zip_code].should be_empty
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,453 @@
1
+ require 'spec_helper'
2
+
3
+ describe SimpleParams::Errors do
4
+ class Person
5
+ extend ActiveModel::Naming
6
+ def initialize
7
+ @errors = SimpleParams::Errors.new(self, ["dog"])
8
+ end
9
+
10
+ attr_accessor :name, :age
11
+ attr_reader :errors
12
+
13
+ def dog
14
+ @dog ||= Dog.new
15
+ end
16
+
17
+ def read_attribute_for_validation(attr)
18
+ send(attr)
19
+ end
20
+
21
+ def self.human_attribute_name(attr, options = {})
22
+ attr
23
+ end
24
+
25
+ def self.lookup_ancestors
26
+ [self]
27
+ end
28
+ end
29
+
30
+ class Dog
31
+ extend ActiveModel::Naming
32
+ def initialize
33
+ @errors = SimpleParams::Errors.new(self)
34
+ end
35
+
36
+ attr_accessor :breed
37
+ attr_reader :errors
38
+
39
+ def read_attribute_for_validation(attr)
40
+ send(attr)
41
+ end
42
+
43
+ def self.human_attribute_name(attr, options = {})
44
+ attr
45
+ end
46
+
47
+ def self.lookup_ancestors
48
+ [self]
49
+ end
50
+ end
51
+
52
+ describe "setting and getting errors" do
53
+ it "get returns the errors for the provided key" do
54
+ errors = SimpleParams::Errors.new(self)
55
+ errors[:foo] = "omg"
56
+ errors.get(:foo).should eq(["omg"])
57
+ end
58
+
59
+ it "sets the error with the provided key" do
60
+ errors = SimpleParams::Errors.new(self)
61
+ errors.set(:foo, "omg")
62
+ errors.messages.should eq({ foo: "omg" })
63
+ end
64
+
65
+ it "values returns an array of messages" do
66
+ errors = SimpleParams::Errors.new(self)
67
+ errors.set(:foo, "omg")
68
+ errors.set(:baz, "zomg")
69
+ errors.values.should eq(["omg", "zomg"])
70
+ end
71
+
72
+ it "keys returns the error keys" do
73
+ errors = SimpleParams::Errors.new(self)
74
+ errors.set(:foo, "omg")
75
+ errors.set(:baz, "zomg")
76
+ errors.keys.should eq([:foo, :baz])
77
+ end
78
+
79
+ describe "setting on model" do
80
+ it "assign error" do
81
+ person = Person.new
82
+ person.errors[:name] = 'should not be nil'
83
+ person.errors[:name].should eq(["should not be nil"])
84
+ end
85
+
86
+ it "add an error message on a specific attribute" do
87
+ person = Person.new
88
+ person.errors.add(:name, "can not be blank")
89
+ person.errors[:name].should eq(["can not be blank"])
90
+ end
91
+
92
+ it "add an error with a symbol" do
93
+ person = Person.new
94
+ person.errors.add(:name, :blank)
95
+ message = person.errors.generate_message(:name, :blank)
96
+ person.errors[:name].should eq([message])
97
+ end
98
+
99
+ it "add an error with a proc" do
100
+ person = Person.new
101
+ message = Proc.new { "can not be blank" }
102
+ person.errors.add(:name, message)
103
+ person.errors[:name].should eq(["can not be blank"])
104
+ end
105
+ end
106
+ end
107
+
108
+ describe "setting and getting nested error model" do
109
+ it "can access error model" do
110
+ person = Person.new
111
+ dog = person.dog
112
+ dog_errors = dog.errors
113
+ person.errors[:dog].should eq(dog_errors)
114
+ end
115
+
116
+ it "can add to nested errors through []" do
117
+ person = Person.new
118
+ person.errors[:dog] = 'should not be nil'
119
+ person.dog.errors[:base].should eq(['should not be nil'])
120
+ end
121
+
122
+ it "can add to nested errors through add" do
123
+ person = Person.new
124
+ person.errors.add(:dog, 'should not be nil')
125
+ person.dog.errors[:base].should eq(['should not be nil'])
126
+ end
127
+
128
+ it "can add multiple errors to nested errors through []" do
129
+ person = Person.new
130
+ person.errors[:dog] = 'should not be nil'
131
+ person.errors[:dog] = 'must be cute'
132
+ person.dog.errors[:base].should eq(['should not be nil', 'must be cute'])
133
+ end
134
+
135
+ it "can add multiple errors to nested errors through add" do
136
+ person = Person.new
137
+ person.errors.add(:dog, 'should not be nil')
138
+ person.errors.add(:dog, 'must be cute')
139
+ person.dog.errors[:base].should eq(['should not be nil', 'must be cute'])
140
+ end
141
+
142
+ it "can add individual errors to nested attributes through []" do
143
+ person = Person.new
144
+ person.errors[:dog][:breed] = 'should not be nil'
145
+ person.dog.errors[:breed].should eq(['should not be nil'])
146
+ end
147
+
148
+ it "can add individual errors to nested attributes through add" do
149
+ person = Person.new
150
+ person.errors[:dog].add(:breed, 'should not be nil')
151
+ person.dog.errors[:breed].should eq(['should not be nil'])
152
+ end
153
+ end
154
+
155
+ describe "#clear" do
156
+ it "clears errors" do
157
+ person = Person.new
158
+ person.errors[:name] = 'should not be nil'
159
+ person.errors[:name].should eq(["should not be nil"])
160
+ person.errors.clear
161
+ person.errors.should be_empty
162
+ end
163
+
164
+ it "clears nested errors" do
165
+ person = Person.new
166
+ person.errors[:name] = 'should not be nil'
167
+ person.errors[:name].should eq(["should not be nil"])
168
+ person.errors[:dog] = 'should not be nil'
169
+ person.dog.errors[:base].should eq(['should not be nil'])
170
+ person.errors.clear
171
+ person.errors.should be_empty
172
+ person.dog.errors.should be_empty
173
+ end
174
+ end
175
+
176
+ describe "#empty?, #blank?, and #include?" do
177
+ it "is empty without any errors" do
178
+ person = Person.new
179
+ person.errors.should be_empty
180
+ person.errors.should be_blank
181
+ person.errors.should_not have_key(:name)
182
+ person.errors.should_not have_key(:dog)
183
+ end
184
+
185
+ it "is not empty with errors" do
186
+ person = Person.new
187
+ person.errors[:name] = 'should not be nil'
188
+ person.errors.should_not be_empty
189
+ person.errors.should_not be_blank
190
+ person.errors.should have_key(:name)
191
+ person.errors.should_not have_key(:dog)
192
+ end
193
+
194
+ it "is not empty with nested errors" do
195
+ person = Person.new
196
+ person.errors[:dog] = 'should not be nil'
197
+ person.errors.should_not be_empty
198
+ person.errors.should_not be_blank
199
+ person.errors.should_not have_key(:name)
200
+ person.errors.should have_key(:dog)
201
+ end
202
+ end
203
+
204
+ describe "#added?" do
205
+ it "added? detects if a specific error was added to the object" do
206
+ person = Person.new
207
+ person.errors.add(:name, "can not be blank")
208
+ person.errors.added?(:name, "can not be blank").should be_truthy
209
+ end
210
+
211
+ it "added? handles symbol message" do
212
+ person = Person.new
213
+ person.errors.add(:name, :blank)
214
+ person.errors.added?(:name, :blank).should be_truthy
215
+ end
216
+
217
+ it "added? handles proc messages" do
218
+ person = Person.new
219
+ message = Proc.new { "can not be blank" }
220
+ person.errors.add(:name, message)
221
+ person.errors.added?(:name, message).should be_truthy
222
+ end
223
+
224
+ it "added? defaults message to :invalid" do
225
+ person = Person.new
226
+ person.errors.add(:name)
227
+ person.errors.added?(:name).should be_truthy
228
+ end
229
+
230
+ it "added? matches the given message when several errors are present for the same attribute" do
231
+ person = Person.new
232
+ person.errors.add(:name, "can not be blank")
233
+ person.errors.add(:name, "is invalid")
234
+ person.errors.added?(:name, "can not be blank").should be_truthy
235
+ end
236
+
237
+ it "added? returns false when no errors are present" do
238
+ person = Person.new
239
+ person.errors.added?(:name).should_not be_truthy
240
+ end
241
+
242
+ it "added? returns false when checking a nonexisting error and other errors are present for the given attribute" do
243
+ person = Person.new
244
+ person.errors.add(:name, "is invalid")
245
+ person.errors.added?(:name, "can not be blank").should_not be_truthy
246
+ end
247
+ end
248
+
249
+ describe "#size" do
250
+ it "size calculates the number of error messages" do
251
+ person = Person.new
252
+ person.errors.add(:name, "can not be blank")
253
+ person.errors.size.should eq(1)
254
+ end
255
+
256
+ it "includes nested attributes in size count" do
257
+ person = Person.new
258
+ person.errors.add(:dog, "can not be blank")
259
+ person.errors.size.should eq(1)
260
+ end
261
+ end
262
+
263
+ describe "#to_a" do
264
+ it "to_a returns the list of errors with complete messages containing the attribute names" do
265
+ person = Person.new
266
+ person.errors.add(:name, "can not be blank")
267
+ person.errors.add(:name, "can not be nil")
268
+ person.errors.to_a.should eq(["name can not be blank", "name can not be nil"])
269
+ end
270
+
271
+ it "handles nested attributes" do
272
+ person = Person.new
273
+ person.errors.add(:name, "can not be blank")
274
+ person.dog.errors.add(:breed, "can not be nil")
275
+ person.errors.to_a.should eq(["name can not be blank", "dog breed can not be nil"])
276
+ end
277
+ end
278
+
279
+ describe "#to_hash" do
280
+ it "to_hash returns the error messages hash" do
281
+ person = Person.new
282
+ person.errors.add(:name, "can not be blank")
283
+ person.errors.to_hash.should eq({ name: ["can not be blank"] })
284
+ end
285
+
286
+ it "handles nested attributes" do
287
+ person = Person.new
288
+ person.errors.add(:name, "can not be blank")
289
+ person.dog.errors.add(:breed, "can not be nil")
290
+ person.errors.to_hash.should eq({
291
+ name: ["can not be blank"],
292
+ dog: {
293
+ breed: ["can not be nil"]
294
+ }
295
+ })
296
+ end
297
+
298
+ it "handles nested attributes with base errors" do
299
+ person = Person.new
300
+ person.errors.add(:base, :invalid)
301
+ person.errors.add(:name, "can not be blank")
302
+ person.dog.errors.add(:base, :invalid)
303
+ person.dog.errors.add(:breed, "can not be nil")
304
+ person.errors.to_hash.should eq({
305
+ base: ["is invalid"],
306
+ name: ["can not be blank"],
307
+ dog: {
308
+ base: ["is invalid"],
309
+ breed: ["can not be nil"]
310
+ }
311
+ })
312
+ end
313
+ end
314
+
315
+ describe "#as_json" do
316
+ it "as_json creates a json formatted representation of the errors hash" do
317
+ person = Person.new
318
+ person.errors[:name] = 'can not be nil'
319
+ person.errors[:name].should eq(["can not be nil"])
320
+ person.errors.as_json.should eq({ name: ["can not be nil"] })
321
+ end
322
+
323
+ it "as_json with :full_messages option creates a json formatted representation of the errors containing complete messages" do
324
+ person = Person.new
325
+ person.errors[:name] = 'can not be nil'
326
+ person.errors[:name].should eq(["can not be nil"])
327
+ person.errors.as_json(full_messages: true).should eq({ name: ["name can not be nil"] })
328
+ end
329
+
330
+ it "handles nested attributes without full_messages" do
331
+ person = Person.new
332
+ person.errors[:name] = 'can not be nil'
333
+ person.dog.errors[:breed] = 'is invalid'
334
+ person.errors.as_json.should eq({
335
+ name: ["can not be nil"],
336
+ dog: {
337
+ breed: ["is invalid"]
338
+ }
339
+ })
340
+ end
341
+
342
+ it "handles nested attributes with full_messages" do
343
+ person = Person.new
344
+ person.errors[:name] = 'can not be nil'
345
+ person.dog.errors[:breed] = 'is invalid'
346
+ person.errors.as_json(full_messages: true).should eq({
347
+ name: ["name can not be nil"],
348
+ dog: {
349
+ breed: ["breed is invalid"]
350
+ }
351
+ })
352
+ end
353
+ end
354
+
355
+ describe "#full_messages" do
356
+ it "full_messages creates a list of error messages with the attribute name included" do
357
+ person = Person.new
358
+ person.errors.add(:name, "can not be blank")
359
+ person.errors.add(:name, "can not be nil")
360
+ person.errors.full_messages.should eq(["name can not be blank", "name can not be nil"])
361
+ end
362
+
363
+ it "full_messages_for contains all the error messages for the given attribute" do
364
+ person = Person.new
365
+ person.errors.add(:name, "can not be blank")
366
+ person.errors.add(:name, "can not be nil")
367
+ person.errors.full_messages_for(:name).should eq(["name can not be blank", "name can not be nil"])
368
+ end
369
+
370
+ it "full_messages_for does not contain error messages from other attributes" do
371
+ person = Person.new
372
+ person.errors.add(:name, "can not be blank")
373
+ person.errors.add(:email, "can not be blank")
374
+ person.errors.full_messages_for(:name).should eq(["name can not be blank"])
375
+ end
376
+
377
+ it "full_messages_for returns an empty list in case there are no errors for the given attribute" do
378
+ person = Person.new
379
+ person.errors.add(:name, "can not be blank")
380
+ person.errors.full_messages_for(:email).should eq([])
381
+ end
382
+
383
+ it "full_message returns the given message when attribute is :base" do
384
+ person = Person.new
385
+ person.errors.full_message(:base, "press the button").should eq("press the button")
386
+ end
387
+
388
+ it "full_message returns the given message with the attribute name included" do
389
+ person = Person.new
390
+ person.errors.full_message(:name, "can not be blank").should eq("name can not be blank")
391
+ person.errors.full_message(:name_test, "can not be blank").should eq("name_test can not be blank")
392
+ end
393
+ end
394
+
395
+ describe "#generate_message" do
396
+ it "generate_message works without i18n_scope" do
397
+ person = Person.new
398
+ Person.should_not respond_to(:i18n_scope)
399
+ expect {
400
+ person.errors.generate_message(:name, :blank)
401
+ }.to_not raise_error
402
+ end
403
+ end
404
+
405
+ describe "#adds_on_empty" do
406
+ it "add_on_empty generates message" do
407
+ person = Person.new
408
+ person.errors.should_receive(:generate_message).with(:name, :empty, {})
409
+ person.errors.add_on_empty :name
410
+ end
411
+
412
+ it "add_on_empty generates message for multiple attributes" do
413
+ person = Person.new
414
+ person.errors.should_receive(:generate_message).with(:name, :empty, {})
415
+ person.errors.should_receive(:generate_message).with(:age, :empty, {})
416
+ person.errors.add_on_empty [:name, :age]
417
+ end
418
+
419
+ it "add_on_empty generates message with custom default message" do
420
+ person = Person.new
421
+ person.errors.should_receive(:generate_message).with(:name, :empty, { message: 'custom' })
422
+ person.errors.add_on_empty :name, message: 'custom'
423
+ end
424
+
425
+ it "add_on_empty generates message with empty string value" do
426
+ person = Person.new
427
+ person.name = ''
428
+ person.errors.should_receive(:generate_message).with(:name, :empty, {})
429
+ person.errors.add_on_empty :name
430
+ end
431
+ end
432
+
433
+ describe "#adds_on_blank" do
434
+ it "add_on_blank generates message" do
435
+ person = Person.new
436
+ person.errors.should_receive(:generate_message).with(:name, :blank, {})
437
+ person.errors.add_on_blank :name
438
+ end
439
+
440
+ it "add_on_blank generates message for multiple attributes" do
441
+ person = Person.new
442
+ person.errors.should_receive(:generate_message).with(:name, :blank, {})
443
+ person.errors.should_receive(:generate_message).with(:age, :blank, {})
444
+ person.errors.add_on_blank [:name, :age]
445
+ end
446
+
447
+ it "add_on_blank generates message with custom default message" do
448
+ person = Person.new
449
+ person.errors.should_receive(:generate_message).with(:name, :blank, { message: 'custom' })
450
+ person.errors.add_on_blank :name, message: 'custom'
451
+ end
452
+ end
453
+ end