granite-form 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +26 -48
  3. data/.rubocop_todo.yml +304 -27
  4. data/CHANGELOG.md +7 -2
  5. data/granite-form.gemspec +2 -1
  6. data/lib/granite/form/active_record/associations.rb +4 -3
  7. data/lib/granite/form/config.rb +1 -1
  8. data/lib/granite/form/errors.rb +34 -32
  9. data/lib/granite/form/extensions.rb +2 -1
  10. data/lib/granite/form/model/associations/base.rb +6 -2
  11. data/lib/granite/form/model/associations/collection/embedded.rb +1 -1
  12. data/lib/granite/form/model/associations/collection/proxy.rb +3 -3
  13. data/lib/granite/form/model/associations/embeds_any.rb +1 -1
  14. data/lib/granite/form/model/associations/embeds_many.rb +15 -11
  15. data/lib/granite/form/model/associations/embeds_one.rb +9 -8
  16. data/lib/granite/form/model/associations/nested_attributes.rb +60 -32
  17. data/lib/granite/form/model/associations/persistence_adapters/active_record/referenced_proxy.rb +2 -1
  18. data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +7 -6
  19. data/lib/granite/form/model/associations/persistence_adapters/base.rb +8 -4
  20. data/lib/granite/form/model/associations/references_any.rb +1 -1
  21. data/lib/granite/form/model/associations/references_many.rb +3 -2
  22. data/lib/granite/form/model/associations/references_one.rb +1 -1
  23. data/lib/granite/form/model/associations/reflections/base.rb +3 -2
  24. data/lib/granite/form/model/associations/reflections/embeds_any.rb +4 -4
  25. data/lib/granite/form/model/associations/reflections/embeds_many.rb +4 -1
  26. data/lib/granite/form/model/associations/reflections/embeds_one.rb +4 -1
  27. data/lib/granite/form/model/associations/reflections/references_any.rb +6 -6
  28. data/lib/granite/form/model/associations/reflections/references_many.rb +1 -1
  29. data/lib/granite/form/model/associations/reflections/references_one.rb +1 -1
  30. data/lib/granite/form/model/associations/validations.rb +6 -6
  31. data/lib/granite/form/model/associations.rb +6 -4
  32. data/lib/granite/form/model/attributes/attribute.rb +1 -0
  33. data/lib/granite/form/model/attributes/base.rb +9 -7
  34. data/lib/granite/form/model/attributes/reference_one.rb +1 -1
  35. data/lib/granite/form/model/attributes/reflections/base/build_type_definition.rb +2 -1
  36. data/lib/granite/form/model/attributes/reflections/represents/build_type_definition.rb +2 -2
  37. data/lib/granite/form/model/attributes/represents.rb +1 -1
  38. data/lib/granite/form/model/attributes.rb +21 -13
  39. data/lib/granite/form/model/conventions.rb +1 -1
  40. data/lib/granite/form/model/persistence.rb +1 -1
  41. data/lib/granite/form/model/primary.rb +1 -1
  42. data/lib/granite/form/model/representation.rb +4 -4
  43. data/lib/granite/form/model/scopes.rb +5 -5
  44. data/lib/granite/form/model/validations.rb +4 -3
  45. data/lib/granite/form/types/active_support/time_zone.rb +1 -1
  46. data/lib/granite/form/types/array.rb +1 -1
  47. data/lib/granite/form/types/big_decimal.rb +1 -1
  48. data/lib/granite/form/types/boolean.rb +1 -1
  49. data/lib/granite/form/types/date.rb +1 -1
  50. data/lib/granite/form/types/date_time.rb +1 -1
  51. data/lib/granite/form/types/dictionary.rb +1 -1
  52. data/lib/granite/form/types/float.rb +1 -1
  53. data/lib/granite/form/types/has_subtype.rb +1 -0
  54. data/lib/granite/form/types/hash_with_action_controller_parameters.rb +2 -2
  55. data/lib/granite/form/types/integer.rb +1 -1
  56. data/lib/granite/form/types/object.rb +2 -1
  57. data/lib/granite/form/types/string.rb +1 -1
  58. data/lib/granite/form/types/time.rb +1 -1
  59. data/lib/granite/form/types/uuid.rb +1 -1
  60. data/lib/granite/form/util.rb +1 -1
  61. data/lib/granite/form/version.rb +1 -1
  62. data/spec/granite/form/active_record/associations_spec.rb +35 -13
  63. data/spec/granite/form/config_spec.rb +8 -4
  64. data/spec/granite/form/model/associations/embeds_many_spec.rb +99 -51
  65. data/spec/granite/form/model/associations/embeds_one_spec.rb +48 -25
  66. data/spec/granite/form/model/associations/persistence_adapters/active_record_spec.rb +12 -7
  67. data/spec/granite/form/model/associations/references_many_spec.rb +51 -10
  68. data/spec/granite/form/model/associations/references_one_spec.rb +17 -6
  69. data/spec/granite/form/model/associations/reflections/embeds_many_spec.rb +51 -16
  70. data/spec/granite/form/model/associations/reflections/embeds_one_spec.rb +19 -9
  71. data/spec/granite/form/model/associations/reflections/references_many_spec.rb +67 -15
  72. data/spec/granite/form/model/associations/reflections/references_one_spec.rb +34 -11
  73. data/spec/granite/form/model/associations/validations_spec.rb +16 -5
  74. data/spec/granite/form/model/associations_spec.rb +28 -9
  75. data/spec/granite/form/model/attributes/attribute_spec.rb +33 -11
  76. data/spec/granite/form/model/attributes/base_spec.rb +9 -3
  77. data/spec/granite/form/model/attributes/reflections/attribute_spec.rb +1 -0
  78. data/spec/granite/form/model/attributes/reflections/base_spec.rb +1 -0
  79. data/spec/granite/form/model/attributes/reflections/represents/build_type_definition_spec.rb +3 -1
  80. data/spec/granite/form/model/attributes/reflections/represents_spec.rb +2 -2
  81. data/spec/granite/form/model/attributes/represents_spec.rb +2 -2
  82. data/spec/granite/form/model/attributes_spec.rb +76 -36
  83. data/spec/granite/form/model/dirty_spec.rb +3 -0
  84. data/spec/granite/form/model/persistence_spec.rb +15 -5
  85. data/spec/granite/form/model/primary_spec.rb +17 -2
  86. data/spec/granite/form/model/representation_spec.rb +13 -3
  87. data/spec/granite/form/model/scopes_spec.rb +8 -3
  88. data/spec/granite/form/model/validations/associated_spec.rb +20 -6
  89. data/spec/granite/form/model/validations/nested_spec.rb +30 -14
  90. data/spec/granite/form/model/validations_spec.rb +1 -1
  91. data/spec/granite/form/model_spec.rb +1 -0
  92. data/spec/granite/form/types/collection_spec.rb +2 -1
  93. data/spec/granite/form/types/date_spec.rb +1 -1
  94. data/spec/granite/form/types/date_time_spec.rb +0 -2
  95. data/spec/granite/form/types/dictionary_spec.rb +1 -0
  96. data/spec/granite/form/types/has_subtype_spec.rb +6 -1
  97. data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +1 -1
  98. data/spec/granite/form/types/object_spec.rb +2 -0
  99. data/spec/granite/form/types/time_spec.rb +0 -2
  100. data/spec/granite/form/util_spec.rb +6 -3
  101. data/spec/support/active_record.rb +13 -0
  102. data/spec/support/shared/nested_attribute_examples.rb +110 -54
  103. metadata +23 -9
@@ -38,6 +38,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
38
38
  expect { book.creators << author }
39
39
  .to change { book.creators }.from([]).to([author])
40
40
  end
41
+
41
42
  specify do
42
43
  expect { book.creators << author }
43
44
  .to change { book.creator_ids }.from([]).to([author.id])
@@ -59,6 +60,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
59
60
  expect { book.author_names = [author.name] }
60
61
  .to change { book.authors }.from([]).to([author])
61
62
  end
63
+
62
64
  specify do
63
65
  expect { book.authors = [author] }
64
66
  .to change { book.author_names }.from([]).to([author.name])
@@ -79,6 +81,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
79
81
  expect { book.identify = [author.id] }
80
82
  .to change { book.authors }.from([]).to([author])
81
83
  end
84
+
82
85
  specify do
83
86
  expect { book.authors = [author] }
84
87
  .to change { book.identify }.from([]).to([author.id])
@@ -86,7 +89,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
86
89
  end
87
90
 
88
91
  describe ':default' do
89
- shared_examples_for :persisted_default do |default|
92
+ shared_examples_for 'persisted default' do |default|
90
93
  before do
91
94
  stub_model(:book) do
92
95
  include Granite::Form::Model::Associations
@@ -119,10 +122,10 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
119
122
  specify { expect { book.owner_ids = '' }.to change { book.owners }.from([author]).to([]) }
120
123
  end
121
124
 
122
- it_behaves_like :persisted_default, -> { authors.map(&:id) }
123
- it_behaves_like :persisted_default, -> { authors }
125
+ it_behaves_like 'persisted default', -> { authors.map(&:id) }
126
+ it_behaves_like 'persisted default', -> { authors }
124
127
 
125
- shared_examples_for :new_record_default do |default|
128
+ shared_examples_for 'new record default' do |default|
126
129
  before do
127
130
  stub_model(:book) do
128
131
  include Granite::Form::Model::Associations
@@ -139,7 +142,14 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
139
142
  specify { expect { book.owners = [other] }.to change { book.owner_ids }.from([nil]).to([other.id]) }
140
143
  specify { expect { book.owners = [other] }.to change { book.owners }.from([an_instance_of(Author)]).to([other]) }
141
144
  specify { expect { book.owner_ids = [other.id] }.to change { book.owner_ids }.from([nil]).to([other.id]) }
142
- specify { expect { book.owner_ids = [other.id] }.to change { book.owners }.from([an_instance_of(Author)]).to([other]) }
145
+
146
+ specify do
147
+ expect { book.owner_ids = [other.id] }
148
+ .to change { book.owners }
149
+ .from([an_instance_of(Author)])
150
+ .to([other])
151
+ end
152
+
143
153
  specify { expect { book.owners = [] }.to change { book.owner_ids }.from([nil]).to([]) }
144
154
  specify { expect { book.owners = [] }.to change { book.owners }.from([an_instance_of(Author)]).to([]) }
145
155
  specify { expect { book.owner_ids = [] }.not_to change { book.owner_ids }.from([nil]) }
@@ -154,12 +164,14 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
154
164
  specify { expect { book.owner_ids = '' }.to change { book.owners }.from([an_instance_of(Author)]).to([]) }
155
165
  end
156
166
 
157
- it_behaves_like :new_record_default, name: 'Author'
158
- it_behaves_like :new_record_default, -> { Author.new(name: 'Author') }
167
+ it_behaves_like 'new record default', name: 'Author'
168
+ it_behaves_like 'new record default', -> { Author.new(name: 'Author') }
159
169
  end
160
170
 
161
171
  describe 'Book.inspect' do
162
- specify { expect(Book.inspect).to eq('Book(authors: ReferencesMany(Author), title: String, author_ids: (reference))') }
172
+ specify do
173
+ expect(Book.inspect).to eq('Book(authors: ReferencesMany(Author), title: String, author_ids: (reference))')
174
+ end
163
175
  end
164
176
 
165
177
  describe '#scope' do
@@ -179,6 +191,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
179
191
  expect { book.authors = [author1, author2] }
180
192
  .to change { book.authors }.from([]).to([author1, author2])
181
193
  end
194
+
182
195
  specify do
183
196
  expect { book.authors = [author1, author2] }
184
197
  .to change { book.author_ids }.from([]).to([author1.id, author2.id])
@@ -188,6 +201,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
188
201
  expect { book.author_ids = [author1.id, author2.id] }
189
202
  .to change { book.authors }.from([]).to([author2])
190
203
  end
204
+
191
205
  specify do
192
206
  expect { book.author_ids = [author1.id, author2.id] }
193
207
  .to change { book.author_ids }.from([]).to([author2.id])
@@ -197,6 +211,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
197
211
  expect { book.authors = [author1, author2] }
198
212
  .to change { book.authors.reload }.from([]).to([author2])
199
213
  end
214
+
200
215
  specify do
201
216
  expect { book.authors = [author1, author2] }
202
217
  .to change {
@@ -228,14 +243,17 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
228
243
 
229
244
  describe '#reload' do
230
245
  before { book.authors << author.tap { |a| a.name = 'Don Juan' } }
246
+
231
247
  it { expect { book.authors.reload }.to change { book.authors.map(&:name) }.from(['Don Juan']).to(['Rick']) }
232
248
  end
233
249
 
234
250
  describe '#concat' do
235
251
  it { expect { book.authors.concat author }.to change { book.authors }.from([]).to([author]) }
236
252
  it { expect { book.authors << author << other }.to change { book.authors }.from([]).to([author, other]) }
253
+
237
254
  context 'no duplication' do
238
255
  before { book.authors << author }
256
+
239
257
  it { expect { book.authors.concat author }.not_to change { book.authors }.from([author]) }
240
258
  end
241
259
  end
@@ -249,8 +267,20 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
249
267
 
250
268
  describe '#author_ids' do
251
269
  it { expect(book_with_author.author_ids).to eq([author.id]) }
252
- xit { expect { book_with_author.author_ids << other.id }.to change { book_with_author.authors }.from([author]).to([author, other]) }
253
- it { expect { book_with_author.author_ids = [other.id] }.to change { book_with_author.authors }.from([author]).to([other]) }
270
+
271
+ xit do
272
+ expect { book_with_author.author_ids << other.id }
273
+ .to change { book_with_author.authors }
274
+ .from([author])
275
+ .to([author, other])
276
+ end
277
+
278
+ it {
279
+ expect { book_with_author.author_ids = [other.id] }
280
+ .to change { book_with_author.authors }
281
+ .from([author])
282
+ .to([other])
283
+ }
254
284
  end
255
285
 
256
286
  describe '#authors=' do
@@ -259,6 +289,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
259
289
 
260
290
  context do
261
291
  before { book.authors = [other] }
292
+
262
293
  specify { expect { book.authors = [author] }.to change { book.authors }.from([other]).to([author]) }
263
294
  specify { expect { book.authors = [author] }.to change { book.author_ids }.from([other.id]).to([author.id]) }
264
295
  specify { expect { book.authors = [] }.to change { book.authors }.from([other]).to([]) }
@@ -267,16 +298,19 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
267
298
 
268
299
  context 'model not persisted' do
269
300
  let(:author) { Author.new }
301
+
270
302
  specify { expect { book.authors = [author, other] }.to change { book.authors }.from([]).to([author, other]) }
271
303
  specify { expect { book.authors = [author, other] }.to change { book.author_ids }.from([]).to([nil, other.id]) }
272
304
 
273
305
  context do
274
306
  before { book.authors = [author, other] }
307
+
275
308
  specify do
276
309
  expect { author.save! }.to change { book.author_ids }.from([nil, other.id])
277
- .to(match([be_a(Integer), other.id]))
310
+ .to(match([be_a(Integer), other.id]))
278
311
  end
279
- specify { expect { author.save! }.not_to change { book.authors } }
312
+
313
+ specify { expect { author.save! }.not_to(change { book.authors }) }
280
314
  end
281
315
  end
282
316
  end
@@ -289,12 +323,30 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesMany do
289
323
  specify { expect { book.author_ids = [author.id.next.to_s] }.not_to change { book.author_ids }.from([]) }
290
324
  specify { expect { book.author_ids = [author.id.next.to_s] }.not_to change { book.authors }.from([]) }
291
325
 
292
- specify { expect { book.author_ids = [author.id.next.to_s, author.id] }.to change { book.author_ids }.from([]).to([author.id]) }
293
- specify { expect { book.author_ids = [author.id.next.to_s, author.id] }.to change { book.authors }.from([]).to([author]) }
326
+ specify do
327
+ expect { book.author_ids = [author.id.next.to_s, author.id] }
328
+ .to change { book.author_ids }
329
+ .from([])
330
+ .to([author.id])
331
+ end
332
+
333
+ specify do
334
+ expect { book.author_ids = [author.id.next.to_s, author.id] }
335
+ .to change { book.authors }
336
+ .from([])
337
+ .to([author])
338
+ end
294
339
 
295
340
  context do
296
341
  before { book.authors = [other] }
297
- specify { expect { book.author_ids = [author.id] }.to change { book.author_ids }.from([other.id]).to([author.id]) }
342
+
343
+ specify do
344
+ expect { book.author_ids = [author.id] }
345
+ .to change { book.author_ids }
346
+ .from([other.id])
347
+ .to([author.id])
348
+ end
349
+
298
350
  specify { expect { book.author_ids = [author.id] }.to change { book.authors }.from([other]).to([author]) }
299
351
  specify { expect { book.author_ids = [] }.to change { book.author_ids }.from([other.id]).to([]) }
300
352
  specify { expect { book.author_ids = [] }.to change { book.authors }.from([other]).to([]) }
@@ -14,6 +14,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
14
14
  references_one :author
15
15
  end
16
16
  end
17
+
17
18
  let(:book) { Book.new }
18
19
 
19
20
  specify { expect(book.author).to be_nil }
@@ -27,12 +28,14 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
27
28
  references_one :creator, class_name: 'Author'
28
29
  end
29
30
  end
31
+
30
32
  let(:author) { Author.create!(name: 'Rick') }
31
33
 
32
34
  specify do
33
35
  expect { book.creator = author }
34
36
  .to change { book.creator }.from(nil).to(author)
35
37
  end
38
+
36
39
  specify do
37
40
  expect { book.creator = author }
38
41
  .to change { book.creator_id }.from(nil).to(author.id)
@@ -54,6 +57,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
54
57
  expect { book.author_name = author.name }
55
58
  .to change { book.author }.from(nil).to(author)
56
59
  end
60
+
57
61
  specify do
58
62
  expect { book.author = author }
59
63
  .to change { book.author_name }.from(nil).to(author.name)
@@ -74,6 +78,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
74
78
  expect { book.identify = author.id }
75
79
  .to change { book.author }.from(nil).to(author)
76
80
  end
81
+
77
82
  specify do
78
83
  expect { book.author = author }
79
84
  .to change { book.identify }.from(nil).to(author.id)
@@ -81,7 +86,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
81
86
  end
82
87
 
83
88
  describe ':default' do
84
- shared_examples_for :persisted_default do |default|
89
+ shared_examples_for 'persisted default' do |default|
85
90
  before do
86
91
  stub_model(:book) do
87
92
  include Granite::Form::Model::Associations
@@ -108,10 +113,10 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
108
113
  specify { expect { book.owner_id = '' }.to change { book.owner }.from(author).to(nil) }
109
114
  end
110
115
 
111
- it_behaves_like :persisted_default, -> { author.id }
112
- it_behaves_like :persisted_default, -> { author }
116
+ it_behaves_like 'persisted default', -> { author.id }
117
+ it_behaves_like 'persisted default', -> { author }
113
118
 
114
- shared_examples_for :new_record_default do |default|
119
+ shared_examples_for 'new record default' do |default|
115
120
  before do
116
121
  stub_model(:book) do
117
122
  include Granite::Form::Model::Associations
@@ -137,8 +142,8 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
137
142
  specify { expect { book.owner_id = '' }.to change { book.owner }.from(instance_of(Author)).to(nil) }
138
143
  end
139
144
 
140
- it_behaves_like :new_record_default, name: 'Author'
141
- it_behaves_like :new_record_default, -> { Author.new(name: 'Author') }
145
+ it_behaves_like 'new record default', name: 'Author'
146
+ it_behaves_like 'new record default', -> { Author.new(name: 'Author') }
142
147
  end
143
148
 
144
149
  describe 'Book.inspect' do
@@ -160,8 +165,9 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
160
165
 
161
166
  specify do
162
167
  expect { book.author_id = author1.id }
163
- .not_to change { book.author }
168
+ .not_to(change { book.author })
164
169
  end
170
+
165
171
  specify do
166
172
  expect { book.author_id = author2.id }
167
173
  .to change { book.author }.from(nil).to(author2)
@@ -171,6 +177,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
171
177
  expect { book.author = author1 }
172
178
  .to change { book.author_id }.from(nil).to(author1.id)
173
179
  end
180
+
174
181
  specify do
175
182
  expect { book.author = author2 }
176
183
  .to change { book.author_id }.from(nil).to(author2.id)
@@ -183,6 +190,7 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
183
190
  book.author_id
184
191
  }.from(nil).to(author1.id)
185
192
  end
193
+
186
194
  specify do
187
195
  expect { book.author = author2 }
188
196
  .to change {
@@ -193,11 +201,12 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
193
201
 
194
202
  specify do
195
203
  expect { book.author = author1 }
196
- .not_to change {
204
+ .not_to(change do
197
205
  book.association(:author).reload
198
206
  book.author
199
- }
207
+ end)
200
208
  end
209
+
201
210
  specify do
202
211
  expect { book.author = author2 }
203
212
  .to change {
@@ -220,12 +229,15 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
220
229
 
221
230
  describe '#author=' do
222
231
  let(:author) { Author.create! name: 'Author' }
232
+
223
233
  specify { expect { book.author = author }.to change { book.author }.from(nil).to(author) }
224
234
  specify { expect { book.author = 'string' }.to raise_error Granite::Form::AssociationTypeMismatch }
225
235
 
226
236
  context do
227
237
  let(:other) { Author.create! name: 'Other' }
238
+
228
239
  before { book.author = other }
240
+
229
241
  specify { expect { book.author = author }.to change { book.author }.from(other).to(author) }
230
242
  specify { expect { book.author = author }.to change { book.author_id }.from(other.id).to(author.id) }
231
243
  specify { expect { book.author = nil }.to change { book.author }.from(other).to(nil) }
@@ -234,29 +246,40 @@ describe Granite::Form::Model::Associations::Reflections::ReferencesOne do
234
246
 
235
247
  context 'model not persisted' do
236
248
  let(:author) { Author.new }
249
+
237
250
  specify { expect { book.author = author }.to change { book.author }.from(nil).to(author) }
238
251
  specify { expect { book.author = author }.not_to change { book.author_id }.from(nil) }
239
252
 
240
253
  context do
241
254
  before { book.author = author }
255
+
242
256
  specify { expect { author.save! }.to change { book.author_id }.from(nil).to(be_a(Integer)) }
243
- specify { expect { author.save! }.not_to change { book.author } }
257
+ specify { expect { author.save! }.not_to(change { book.author }) }
244
258
  end
245
259
  end
246
260
  end
247
261
 
248
262
  describe '#author_id=' do
249
263
  let(:author) { Author.create!(name: 'Author') }
264
+
250
265
  specify { expect { book.author_id = author.id }.to change { book.author_id }.from(nil).to(author.id) }
251
266
  specify { expect { book.author_id = author.id }.to change { book.author }.from(nil).to(author) }
252
267
  specify { expect { book.author_id = author }.to change { book.author }.from(nil).to(author) }
253
268
 
254
- specify { expect { book.author_id = author.id.next.to_s }.to change { book.author_id }.from(nil).to(author.id.next) }
269
+ specify do
270
+ expect { book.author_id = author.id.next.to_s }
271
+ .to change { book.author_id }
272
+ .from(nil)
273
+ .to(author.id.next)
274
+ end
275
+
255
276
  specify { expect { book.author_id = author.id.next.to_s }.not_to change { book.author }.from(nil) }
256
277
 
257
278
  context do
258
279
  let(:other) { Author.create!(name: 'Other') }
280
+
259
281
  before { book.author = other }
282
+
260
283
  specify { expect { book.author_id = author.id }.to change { book.author_id }.from(other.id).to(author.id) }
261
284
  specify { expect { book.author_id = author.id }.to change { book.author }.from(other).to(author) }
262
285
  specify { expect { book.author_id = nil }.to change { book.author_id }.from(other.id).to(nil) }
@@ -38,16 +38,18 @@ describe Granite::Form::Model::Associations::Validations do
38
38
  let(:project) { Project.new title: 'Project' }
39
39
  let(:projects) { [project] }
40
40
  let(:user) { User.new(login: 'Login', profile: profile, projects: projects) }
41
- let(:author_attributes) { {name: 'Author'} }
41
+ let(:author_attributes) { { name: 'Author' } }
42
+
42
43
  before { project.build_author(author_attributes) }
43
44
 
44
45
  specify { expect(user.validate).to eq(true) }
45
- specify { expect { user.validate }.not_to change { user.errors.messages } }
46
+ specify { expect { user.validate }.not_to(change { user.errors.messages }) }
46
47
 
47
48
  context do
48
49
  let(:author_attributes) { {} }
49
50
 
50
51
  specify { expect(user.validate).to eq(false) }
52
+
51
53
  specify do
52
54
  expect { user.validate }.to change { user.errors.messages }
53
55
  .to('projects.0.author.name': ["can't be blank"])
@@ -58,13 +60,14 @@ describe Granite::Form::Model::Associations::Validations do
58
60
  let(:profile) { Profile.new }
59
61
 
60
62
  specify { expect(user.validate).to eq(true) }
61
- specify { expect { user.validate }.not_to change { user.errors.messages } }
63
+ specify { expect { user.validate }.not_to(change { user.errors.messages }) }
62
64
  end
63
65
 
64
66
  context do
65
67
  let(:projects) { [project, Project.new] }
66
68
 
67
69
  specify { expect(user.validate).to eq(false) }
70
+
68
71
  specify do
69
72
  expect { user.validate }.to change { user.errors.messages }
70
73
  .to('projects.1.title': ["can't be blank"])
@@ -77,7 +80,8 @@ describe Granite::Form::Model::Associations::Validations do
77
80
  let(:project) { Project.new title: 'Project' }
78
81
  let(:projects) { [project] }
79
82
  let(:user) { User.new(login: 'Login', profile: profile, projects: projects) }
80
- let(:author_attributes) { {name: 'Author'} }
83
+ let(:author_attributes) { { name: 'Author' } }
84
+
81
85
  before { project.build_author(author_attributes) }
82
86
 
83
87
  specify { expect(user.validate_ancestry).to eq(true) }
@@ -85,14 +89,16 @@ describe Granite::Form::Model::Associations::Validations do
85
89
  specify { expect { user.validate_ancestry! }.not_to raise_error }
86
90
  specify { expect(user.valid_ancestry?).to eq(true) }
87
91
  specify { expect(user.invalid_ancestry?).to eq(false) }
88
- specify { expect { user.validate_ancestry }.not_to change { user.errors.messages } }
92
+ specify { expect { user.validate_ancestry }.not_to(change { user.errors.messages }) }
89
93
 
90
94
  context do
91
95
  let(:author_attributes) { {} }
96
+
92
97
  specify { expect(user.validate_ancestry).to eq(false) }
93
98
  specify { expect { user.validate_ancestry! }.to raise_error Granite::Form::ValidationError }
94
99
  specify { expect(user.valid_ancestry?).to eq(false) }
95
100
  specify { expect(user.invalid_ancestry?).to eq(true) }
101
+
96
102
  specify do
97
103
  expect { user.validate_ancestry }.to change { user.errors.messages }
98
104
  .to('projects.0.author.name': ["can't be blank"])
@@ -101,10 +107,12 @@ describe Granite::Form::Model::Associations::Validations do
101
107
 
102
108
  context do
103
109
  let(:profile) { Profile.new }
110
+
104
111
  specify { expect(user.validate_ancestry).to eq(false) }
105
112
  specify { expect { user.validate_ancestry! }.to raise_error Granite::Form::ValidationError }
106
113
  specify { expect(user.valid_ancestry?).to eq(false) }
107
114
  specify { expect(user.invalid_ancestry?).to eq(true) }
115
+
108
116
  specify do
109
117
  expect { user.validate_ancestry }.to change { user.errors.messages }
110
118
  .to('profile.first_name': ["can't be blank"])
@@ -113,10 +121,12 @@ describe Granite::Form::Model::Associations::Validations do
113
121
 
114
122
  context do
115
123
  let(:projects) { [project, Project.new] }
124
+
116
125
  specify { expect(user.validate_ancestry).to eq(false) }
117
126
  specify { expect { user.validate_ancestry! }.to raise_error Granite::Form::ValidationError }
118
127
  specify { expect(user.valid_ancestry?).to eq(false) }
119
128
  specify { expect(user.invalid_ancestry?).to eq(true) }
129
+
120
130
  specify do
121
131
  expect { user.validate_ancestry }.to change { user.errors.messages }
122
132
  .to('projects.1.title': ["can't be blank"])
@@ -124,6 +134,7 @@ describe Granite::Form::Model::Associations::Validations do
124
134
 
125
135
  context do
126
136
  before { user.update(login: '') }
137
+
127
138
  specify do
128
139
  expect { user.validate_ancestry }.to change { user.errors.messages }
129
140
  .to('projects.1.title': ["can't be blank"], login: ["can't be blank"])
@@ -34,9 +34,18 @@ describe Granite::Form::Model::Associations do
34
34
 
35
35
  describe '#reflect_on_association' do
36
36
  specify { expect(Nobody.reflect_on_association(:blabla)).to be_nil }
37
- specify { expect(Admin.reflect_on_association('projects')).to be_a Granite::Form::Model::Associations::Reflections::EmbedsMany }
37
+
38
+ specify do
39
+ expect(Admin.reflect_on_association('projects'))
40
+ .to be_a Granite::Form::Model::Associations::Reflections::EmbedsMany
41
+ end
42
+
38
43
  specify { expect(Admin.reflect_on_association('own_projects').name).to eq(:admin_projects) }
39
- specify { expect(Manager.reflect_on_association(:managed_project)).to be_a Granite::Form::Model::Associations::Reflections::EmbedsOne }
44
+
45
+ specify do
46
+ expect(Manager.reflect_on_association(:managed_project))
47
+ .to be_a Granite::Form::Model::Associations::Reflections::EmbedsOne
48
+ end
40
49
  end
41
50
  end
42
51
 
@@ -47,7 +56,8 @@ describe Granite::Form::Model::Associations do
47
56
  include Granite::Form::Model::Associations
48
57
 
49
58
  embeds_one :author, class_name: 'Borogoves'
50
- end.reflect_on_association(:author).data_source end.to raise_error NameError
59
+ end.reflect_on_association(:author).data_source
60
+ end.to raise_error NameError
51
61
  end
52
62
 
53
63
  specify do
@@ -58,7 +68,8 @@ describe Granite::Form::Model::Associations do
58
68
  embeds_many :projects, class_name: 'Borogoves' do
59
69
  attribute :title
60
70
  end
61
- end.reflect_on_association(:projects).data_source end.to raise_error NameError
71
+ end.reflect_on_association(:projects).data_source
72
+ end.to raise_error NameError
62
73
  end
63
74
  end
64
75
 
@@ -108,7 +119,9 @@ describe Granite::Form::Model::Associations do
108
119
  specify { expect(user.profile).to be_nil }
109
120
 
110
121
  describe '.inspect' do
111
- specify { expect(User.inspect).to eq('User(profile: EmbedsOne(Profile), projects: EmbedsMany(Project), login: Object)') }
122
+ specify do
123
+ expect(User.inspect).to eq('User(profile: EmbedsOne(Profile), projects: EmbedsMany(Project), login: Object)')
124
+ end
112
125
  end
113
126
 
114
127
  describe '.association_names' do
@@ -118,9 +131,10 @@ describe Granite::Form::Model::Associations do
118
131
  describe '#inspect' do
119
132
  let(:profile) { Profile.new first_name: 'Name' }
120
133
  let(:project) { Project.new title: 'Project' }
134
+
121
135
  specify do
122
136
  expect(User.new(login: 'Login', profile: profile, projects: [project]).inspect)
123
- .to eq('#<User profile: #<EmbedsOne #<Profile first_name: "Name", last_name: nil>>, projects: #<EmbedsMany [#<Project author: #<EmbedsOne nil>, title: "P...]>, login: "Login">')
137
+ .to eq('#<User profile: #<EmbedsOne #<Profile first_name: "Name", last_name: nil>>, projects: #<EmbedsMany [#<Project author: #<EmbedsOne nil>, title: "P...]>, login: "Login">') # rubocop:disable Layout/LineLength
124
138
  end
125
139
  end
126
140
 
@@ -137,7 +151,8 @@ describe Granite::Form::Model::Associations do
137
151
  specify { expect(User.new(projects: [project])).not_to eql(User.new) }
138
152
 
139
153
  context do
140
- before { User.send(:include, Granite::Form::Model::Primary) }
154
+ before { User.include Granite::Form::Model::Primary }
155
+
141
156
  let(:user) { User.new(projects: [project]) }
142
157
 
143
158
  specify { expect(user).to eq(user.clone.tap { |b| b.projects(author: project) }) }
@@ -161,13 +176,17 @@ describe Granite::Form::Model::Associations do
161
176
  end
162
177
 
163
178
  describe '#instantiate' do
164
- before { User.send(:include, Granite::Form::Model::Persistence) }
179
+ before do
180
+ User.include Granite::Form::Model::Persistence
181
+ project.build_author(name: 'Author')
182
+ end
183
+
165
184
  let(:profile) { Profile.new first_name: 'Name' }
166
185
  let(:project) { Project.new title: 'Project' }
167
186
  let(:user) { User.new(profile: profile, projects: [project]) }
168
- before { project.build_author(name: 'Author') }
169
187
 
170
188
  specify { expect(User.instantiate(JSON.parse(user.to_json))).to eq(user) }
189
+
171
190
  specify do
172
191
  expect(User.instantiate(JSON.parse(user.to_json))
173
192
  .tap { |u| u.projects.first.author.name = 'Other' }).not_to eq(user)
@@ -5,12 +5,16 @@ describe Granite::Form::Model::Attributes::Attribute do
5
5
 
6
6
  def attribute(*args)
7
7
  options = args.extract_options!
8
- Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Attribute, :field, {type: Object}.merge(options))
8
+ Dummy.add_attribute(Granite::Form::Model::Attributes::Reflections::Attribute, :field,
9
+ { type: Object }.merge(options))
9
10
  Dummy.new.attribute(:field)
10
11
  end
11
12
 
12
13
  describe '#read' do
13
- let(:field) { attribute(type: String, normalizer: ->(v) { v ? v.strip : v }, default: :world, enum: %w[hello 42 world]) }
14
+ let(:field) do
15
+ normalizer = ->(v) { v ? v.strip : v }
16
+ attribute(type: String, normalizer: normalizer, default: :world, enum: %w[hello 42 world])
17
+ end
14
18
 
15
19
  specify { expect(field.tap { |r| r.write(nil) }.read).to eq('world') }
16
20
  specify { expect(field.tap { |r| r.write(:world) }.read).to eq('world') }
@@ -36,7 +40,11 @@ describe Granite::Form::Model::Attributes::Attribute do
36
40
  specify { expect(field.tap { |r| r.write('') }.read_before_type_cast).to eq('') }
37
41
 
38
42
  context ':readonly' do
39
- specify { expect(attribute(readonly: true, default: :world).tap { |r| r.write('string') }.read_before_type_cast).to eq(:world) }
43
+ specify do
44
+ attr = attribute(readonly: true, default: :world)
45
+ attr.write('string')
46
+ expect(attr.read_before_type_cast).to eq(:world)
47
+ end
40
48
  end
41
49
  end
42
50
 
@@ -58,11 +66,22 @@ describe Granite::Form::Model::Attributes::Attribute do
58
66
  describe '#normalize' do
59
67
  specify { expect(attribute.normalize(' hello ')).to eq(' hello ') }
60
68
  specify { expect(attribute(normalizer: ->(v) { v.strip }).normalize(' hello ')).to eq('hello') }
61
- specify { expect(attribute(normalizer: [->(v) { v.strip }, ->(v) { v.first(4) }]).normalize(' hello ')).to eq('hell') }
62
- specify { expect(attribute(normalizer: [->(v) { v.first(4) }, ->(v) { v.strip }]).normalize(' hello ')).to eq('hel') }
69
+
70
+ specify do
71
+ normalizers = [->(v) { v.strip }, ->(v) { v.first(4) }]
72
+ attr = attribute(normalizer: normalizers)
73
+ expect(attr.normalize(' hello ')).to eq('hell')
74
+ end
75
+
76
+ specify do
77
+ normalizers = [->(v) { v.first(4) }, ->(v) { v.strip }]
78
+ attr = attribute(normalizer: normalizers)
79
+ expect(attr.normalize(' hello ')).to eq('hel')
80
+ end
63
81
 
64
82
  context do
65
83
  before { allow_any_instance_of(Dummy).to receive_messages(value: 'value') }
84
+
66
85
  let(:other) { 'other' }
67
86
 
68
87
  specify { expect(attribute(normalizer: ->(_v) { value }).normalize(' hello ')).to eq('value') }
@@ -89,12 +108,14 @@ describe Granite::Form::Model::Attributes::Attribute do
89
108
  specify { expect(attribute(normalizer: :strip).normalize(' hello ')).to eq('hello') }
90
109
  specify { expect(attribute(normalizer: %i[strip trim]).normalize(' hello ')).to eq('he') }
91
110
  specify { expect(attribute(normalizer: %i[trim strip]).normalize(' hello ')).to eq('h') }
92
- specify { expect(attribute(normalizer: [:strip, {trim: {length: 4}}]).normalize(' hello ')).to eq('hell') }
93
- specify { expect(attribute(normalizer: {strip: {}, trim: {length: 4}}).normalize(' hello ')).to eq('hell') }
111
+ specify { expect(attribute(normalizer: [:strip, { trim: { length: 4 } }]).normalize(' hello ')).to eq('hell') }
112
+ specify { expect(attribute(normalizer: { strip: {}, trim: { length: 4 } }).normalize(' hello ')).to eq('hell') }
113
+
94
114
  specify do
95
- expect(attribute(normalizer: [:strip, {trim: {length: 4}}, ->(v) { v.last(2) }])
115
+ expect(attribute(normalizer: [:strip, { trim: { length: 4 } }, ->(v) { v.last(2) }])
96
116
  .normalize(' hello ')).to eq('ll')
97
117
  end
118
+
98
119
  specify { expect(attribute(normalizer: :reset).normalize('')).to eq(nil) }
99
120
  specify { expect(attribute(normalizer: %i[strip reset]).normalize(' ')).to eq(nil) }
100
121
  specify { expect(attribute(normalizer: :reset, default: '!!!').normalize(nil)).to eq('!!!') }
@@ -103,10 +124,11 @@ describe Granite::Form::Model::Attributes::Attribute do
103
124
  context do
104
125
  let(:length) { 3 }
105
126
 
106
- specify { expect(attribute(normalizer: [:strip, {trim: {length: 4}}]).normalize(' hello ')).to eq('hel') }
107
- specify { expect(attribute(normalizer: {strip: {}, trim: {length: 4}}).normalize(' hello ')).to eq('hel') }
127
+ specify { expect(attribute(normalizer: [:strip, { trim: { length: 4 } }]).normalize(' hello ')).to eq('hel') }
128
+ specify { expect(attribute(normalizer: { strip: {}, trim: { length: 4 } }).normalize(' hello ')).to eq('hel') }
129
+
108
130
  specify do
109
- expect(attribute(normalizer: [:strip, {trim: {length: 4}}, ->(v) { v.last(2) }])
131
+ expect(attribute(normalizer: [:strip, { trim: { length: 4 } }, ->(v) { v.last(2) }])
110
132
  .normalize(' hello ')).to eq('el')
111
133
  end
112
134
  end