granite-form 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/workflows/ruby.yml +3 -5
  4. data/.rubocop.yml +26 -48
  5. data/.rubocop_todo.yml +304 -27
  6. data/Appraisals +1 -1
  7. data/CHANGELOG.md +15 -2
  8. data/gemfiles/{rails.5.0.gemfile → rails.7.1.gemfile} +3 -3
  9. data/granite-form.gemspec +6 -5
  10. data/lib/granite/form/active_record/associations.rb +4 -3
  11. data/lib/granite/form/config.rb +1 -1
  12. data/lib/granite/form/errors.rb +34 -32
  13. data/lib/granite/form/extensions.rb +2 -1
  14. data/lib/granite/form/model/associations/base.rb +6 -2
  15. data/lib/granite/form/model/associations/collection/embedded.rb +1 -1
  16. data/lib/granite/form/model/associations/collection/proxy.rb +3 -3
  17. data/lib/granite/form/model/associations/embeds_any.rb +1 -1
  18. data/lib/granite/form/model/associations/embeds_many.rb +15 -11
  19. data/lib/granite/form/model/associations/embeds_one.rb +9 -8
  20. data/lib/granite/form/model/associations/nested_attributes.rb +60 -32
  21. data/lib/granite/form/model/associations/persistence_adapters/active_record/referenced_proxy.rb +2 -1
  22. data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +7 -6
  23. data/lib/granite/form/model/associations/persistence_adapters/base.rb +8 -4
  24. data/lib/granite/form/model/associations/references_any.rb +1 -1
  25. data/lib/granite/form/model/associations/references_many.rb +3 -2
  26. data/lib/granite/form/model/associations/references_one.rb +1 -1
  27. data/lib/granite/form/model/associations/reflections/base.rb +3 -2
  28. data/lib/granite/form/model/associations/reflections/embeds_any.rb +4 -4
  29. data/lib/granite/form/model/associations/reflections/embeds_many.rb +4 -1
  30. data/lib/granite/form/model/associations/reflections/embeds_one.rb +4 -1
  31. data/lib/granite/form/model/associations/reflections/references_any.rb +6 -6
  32. data/lib/granite/form/model/associations/reflections/references_many.rb +1 -1
  33. data/lib/granite/form/model/associations/reflections/references_one.rb +1 -1
  34. data/lib/granite/form/model/associations/validations.rb +6 -6
  35. data/lib/granite/form/model/associations.rb +6 -4
  36. data/lib/granite/form/model/attributes/attribute.rb +1 -0
  37. data/lib/granite/form/model/attributes/base.rb +9 -7
  38. data/lib/granite/form/model/attributes/reference_one.rb +1 -1
  39. data/lib/granite/form/model/attributes/reflections/base/build_type_definition.rb +2 -1
  40. data/lib/granite/form/model/attributes/reflections/represents/build_type_definition.rb +2 -2
  41. data/lib/granite/form/model/attributes/represents.rb +1 -1
  42. data/lib/granite/form/model/attributes.rb +21 -13
  43. data/lib/granite/form/model/conventions.rb +1 -1
  44. data/lib/granite/form/model/persistence.rb +1 -1
  45. data/lib/granite/form/model/primary.rb +1 -1
  46. data/lib/granite/form/model/representation.rb +4 -4
  47. data/lib/granite/form/model/scopes.rb +5 -5
  48. data/lib/granite/form/model/validations.rb +4 -3
  49. data/lib/granite/form/types/active_support/time_zone.rb +1 -1
  50. data/lib/granite/form/types/array.rb +1 -1
  51. data/lib/granite/form/types/big_decimal.rb +1 -1
  52. data/lib/granite/form/types/boolean.rb +1 -1
  53. data/lib/granite/form/types/date.rb +1 -1
  54. data/lib/granite/form/types/date_time.rb +1 -1
  55. data/lib/granite/form/types/dictionary.rb +1 -1
  56. data/lib/granite/form/types/float.rb +1 -1
  57. data/lib/granite/form/types/has_subtype.rb +1 -0
  58. data/lib/granite/form/types/hash_with_action_controller_parameters.rb +2 -2
  59. data/lib/granite/form/types/integer.rb +1 -1
  60. data/lib/granite/form/types/object.rb +2 -1
  61. data/lib/granite/form/types/string.rb +1 -1
  62. data/lib/granite/form/types/time.rb +1 -1
  63. data/lib/granite/form/types/uuid.rb +1 -1
  64. data/lib/granite/form/util.rb +1 -1
  65. data/lib/granite/form/version.rb +1 -1
  66. data/spec/granite/form/active_record/associations_spec.rb +35 -13
  67. data/spec/granite/form/config_spec.rb +8 -4
  68. data/spec/granite/form/model/associations/embeds_many_spec.rb +99 -51
  69. data/spec/granite/form/model/associations/embeds_one_spec.rb +48 -25
  70. data/spec/granite/form/model/associations/persistence_adapters/active_record_spec.rb +12 -7
  71. data/spec/granite/form/model/associations/references_many_spec.rb +51 -10
  72. data/spec/granite/form/model/associations/references_one_spec.rb +17 -6
  73. data/spec/granite/form/model/associations/reflections/embeds_many_spec.rb +51 -16
  74. data/spec/granite/form/model/associations/reflections/embeds_one_spec.rb +19 -9
  75. data/spec/granite/form/model/associations/reflections/references_many_spec.rb +67 -15
  76. data/spec/granite/form/model/associations/reflections/references_one_spec.rb +34 -11
  77. data/spec/granite/form/model/associations/validations_spec.rb +16 -5
  78. data/spec/granite/form/model/associations_spec.rb +28 -9
  79. data/spec/granite/form/model/attributes/attribute_spec.rb +33 -11
  80. data/spec/granite/form/model/attributes/base_spec.rb +26 -2
  81. data/spec/granite/form/model/attributes/reflections/attribute_spec.rb +1 -0
  82. data/spec/granite/form/model/attributes/reflections/base_spec.rb +1 -0
  83. data/spec/granite/form/model/attributes/reflections/represents/build_type_definition_spec.rb +3 -1
  84. data/spec/granite/form/model/attributes/reflections/represents_spec.rb +2 -2
  85. data/spec/granite/form/model/attributes/represents_spec.rb +2 -2
  86. data/spec/granite/form/model/attributes_spec.rb +76 -36
  87. data/spec/granite/form/model/dirty_spec.rb +3 -0
  88. data/spec/granite/form/model/persistence_spec.rb +15 -5
  89. data/spec/granite/form/model/primary_spec.rb +17 -2
  90. data/spec/granite/form/model/representation_spec.rb +13 -3
  91. data/spec/granite/form/model/scopes_spec.rb +8 -3
  92. data/spec/granite/form/model/validations/associated_spec.rb +20 -6
  93. data/spec/granite/form/model/validations/nested_spec.rb +30 -14
  94. data/spec/granite/form/model/validations_spec.rb +1 -1
  95. data/spec/granite/form/model_spec.rb +1 -0
  96. data/spec/granite/form/types/collection_spec.rb +2 -1
  97. data/spec/granite/form/types/date_spec.rb +1 -1
  98. data/spec/granite/form/types/date_time_spec.rb +0 -2
  99. data/spec/granite/form/types/dictionary_spec.rb +1 -0
  100. data/spec/granite/form/types/has_subtype_spec.rb +6 -1
  101. data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +1 -1
  102. data/spec/granite/form/types/object_spec.rb +2 -0
  103. data/spec/granite/form/types/time_spec.rb +0 -2
  104. data/spec/granite/form/util_spec.rb +6 -3
  105. data/spec/support/active_record.rb +13 -0
  106. data/spec/support/shared/nested_attribute_examples.rb +110 -54
  107. metadata +28 -16
  108. data/gemfiles/rails.5.1.gemfile +0 -14
  109. data/gemfiles/rails.5.2.gemfile +0 -14
@@ -22,7 +22,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
22
22
  let(:book) { Book.new(title: 'Book') }
23
23
  let(:association) { book.association(:author) }
24
24
 
25
- let(:existing_book) { Book.instantiate title: 'My Life', author: {'name' => 'Johny'} }
25
+ let(:existing_book) { Book.instantiate title: 'My Life', author: { 'name' => 'Johny' } }
26
26
  let(:existing_association) { existing_book.association(:author) }
27
27
 
28
28
  context 'callbacks' do
@@ -41,6 +41,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
41
41
  collection :callbacks, Array
42
42
  end
43
43
  end
44
+
44
45
  let(:author1) { Author.new(name: 'Author1') }
45
46
  let(:author2) { Author.new(name: 'Author2') }
46
47
 
@@ -57,9 +58,9 @@ describe Granite::Form::Model::Associations::EmbedsOne do
57
58
  end
58
59
  .to change { book.callbacks }
59
60
  .to([
60
- [:before_add, author1], [:after_add, author1],
61
- [:before_add, author2], [:after_add, author2]
62
- ])
61
+ [:before_add, author1], [:after_add, author1],
62
+ [:before_add, author2], [:after_add, author2]
63
+ ])
63
64
  end
64
65
 
65
66
  specify do
@@ -76,18 +77,18 @@ describe Granite::Form::Model::Associations::EmbedsOne do
76
77
  end
77
78
  .to change { book.callbacks }
78
79
  .to([
79
- [:before_add, author1], [:after_add, author1],
80
- [:before_add, author1], [:after_add, author1]
81
- ])
80
+ [:before_add, author1], [:after_add, author1],
81
+ [:before_add, author1], [:after_add, author1]
82
+ ])
82
83
  end
83
84
 
84
85
  context 'default' do
85
86
  before do
86
87
  Book.class_eval do
87
88
  embeds_one :author,
88
- before_add: ->(object) { callbacks.push([:before_add, object]) },
89
- after_add: ->(object) { callbacks.push([:after_add, object]) },
90
- default: -> { {name: 'Author1'} }
89
+ before_add: ->(object) { callbacks.push([:before_add, object]) },
90
+ after_add: ->(object) { callbacks.push([:after_add, object]) },
91
+ default: -> { { name: 'Author1' } }
91
92
 
92
93
  collection :callbacks, Array
93
94
  end
@@ -97,9 +98,9 @@ describe Granite::Form::Model::Associations::EmbedsOne do
97
98
  expect { association.writer(author2) }
98
99
  .to change { book.callbacks }
99
100
  .to([
100
- [:before_add, author1], [:after_add, author1],
101
- [:before_add, author2], [:after_add, author2]
102
- ])
101
+ [:before_add, author1], [:after_add, author1],
102
+ [:before_add, author2], [:after_add, author2]
103
+ ])
103
104
  end
104
105
  end
105
106
  end
@@ -113,10 +114,12 @@ describe Granite::Form::Model::Associations::EmbedsOne do
113
114
  let(:author) { Author.new(name: 'Author') }
114
115
 
115
116
  specify { expect(association.build.embedder).to eq(book) }
117
+
116
118
  specify do
117
119
  expect { association.writer(author) }
118
120
  .to change { author.embedder }.from(nil).to(book)
119
121
  end
122
+
120
123
  specify do
121
124
  expect { association.target = author }
122
125
  .to change { author.embedder }.from(nil).to(book)
@@ -125,7 +128,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
125
128
  context 'default' do
126
129
  before do
127
130
  Book.class_eval do
128
- embeds_one :author, default: -> { {name: 'Author1'} }
131
+ embeds_one :author, default: -> { { name: 'Author1' } }
129
132
  end
130
133
  end
131
134
 
@@ -159,12 +162,12 @@ describe Granite::Form::Model::Associations::EmbedsOne do
159
162
 
160
163
  specify do
161
164
  expect { association.build(name: 'Fred') }
162
- .not_to change { book.read_attribute(:author) }
165
+ .not_to(change { book.read_attribute(:author) })
163
166
  end
164
167
 
165
168
  specify do
166
169
  expect { existing_association.build(name: 'Fred') }
167
- .not_to change { existing_book.read_attribute(:author) }
170
+ .not_to(change { existing_book.read_attribute(:author) })
168
171
  end
169
172
  end
170
173
 
@@ -175,13 +178,14 @@ describe Granite::Form::Model::Associations::EmbedsOne do
175
178
  end
176
179
 
177
180
  describe '#default' do
178
- before { Book.embeds_one :author, default: -> { {name: 'Default'} } }
179
181
  before do
182
+ Book.embeds_one :author, default: -> { { name: 'Default' } }
180
183
  Author.class_eval do
181
184
  include Granite::Form::Model::Primary
182
185
  primary :name
183
186
  end
184
187
  end
188
+
185
189
  let(:new_author) { Author.new.tap { |a| a.name = 'Morty' } }
186
190
  let(:existing_book) { Book.instantiate title: 'My Life' }
187
191
 
@@ -191,11 +195,18 @@ describe Granite::Form::Model::Associations::EmbedsOne do
191
195
  specify { expect { association.replace(nil) }.to change { association.target }.to be_nil }
192
196
 
193
197
  specify { expect(existing_association.target).to be_nil }
194
- specify { expect { existing_association.replace(new_author) }.to change { existing_association.target }.to(an_instance_of(Author)) }
195
- specify { expect { existing_association.replace(nil) }.not_to change { existing_association.target } }
198
+
199
+ specify do
200
+ expect { existing_association.replace(new_author) }
201
+ .to change { existing_association.target }
202
+ .to(an_instance_of(Author))
203
+ end
204
+
205
+ specify { expect { existing_association.replace(nil) }.not_to(change { existing_association.target }) }
196
206
 
197
207
  context do
198
- before { Author.send(:include, Granite::Form::Model::Dirty) }
208
+ before { Author.include Granite::Form::Model::Dirty }
209
+
199
210
  specify { expect(association.target).not_to be_changed }
200
211
  end
201
212
  end
@@ -220,6 +231,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
220
231
 
221
232
  context do
222
233
  before { association.build(name: 'Fred') }
234
+
223
235
  specify do
224
236
  expect { association.reload }
225
237
  .to change { association.reader.try(:attributes) }.from('name' => 'Fred').to(nil)
@@ -228,6 +240,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
228
240
 
229
241
  context do
230
242
  before { existing_association.build(name: 'Fred') }
243
+
231
244
  specify do
232
245
  expect { existing_association.reload }
233
246
  .to change { existing_association.reader.try(:attributes) }
@@ -256,16 +269,17 @@ describe Granite::Form::Model::Associations::EmbedsOne do
256
269
 
257
270
  specify do
258
271
  expect { association.sync }.to change { book.read_attribute(:author) }
259
- .from(nil).to('name' => 'Fred', 'reviews' => [{'rating' => 7}])
272
+ .from(nil).to('name' => 'Fred', 'reviews' => [{ 'rating' => 7 }])
260
273
  end
261
274
  end
262
275
  end
263
276
 
264
277
  describe '#clear' do
265
278
  specify { expect(association.clear).to eq(true) }
266
- specify { expect { association.clear }.not_to change { association.reader } }
279
+ specify { expect { association.clear }.not_to(change { association.reader }) }
267
280
 
268
281
  specify { expect(existing_association.clear).to eq(true) }
282
+
269
283
  specify do
270
284
  expect { existing_association.clear }
271
285
  .to change { existing_association.reader.try(:attributes) }.from('name' => 'Johny').to(nil)
@@ -280,6 +294,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
280
294
 
281
295
  context do
282
296
  before { association.build }
297
+
283
298
  specify { expect(association.reader).to be_a Author }
284
299
  specify { expect(association.reader).not_to be_persisted }
285
300
  specify { expect(association.reader(true)).to be_nil }
@@ -287,6 +302,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
287
302
 
288
303
  context do
289
304
  before { existing_association.build(name: 'Fred') }
305
+
290
306
  specify { expect(existing_association.reader.name).to eq('Fred') }
291
307
  specify { expect(existing_association.reader(true).name).to eq('Johny') }
292
308
  end
@@ -305,8 +321,9 @@ describe Granite::Form::Model::Associations::EmbedsOne do
305
321
 
306
322
  specify do
307
323
  expect { association.writer(nil) }
308
- .not_to change { book.read_attribute(:author) }
324
+ .not_to(change { book.read_attribute(:author) })
309
325
  end
326
+
310
327
  specify do
311
328
  expect { association.writer(new_author) }
312
329
  .to change { association.reader.try(:attributes) }.from(nil).to('name' => 'Morty')
@@ -321,6 +338,7 @@ describe Granite::Form::Model::Associations::EmbedsOne do
321
338
 
322
339
  specify { expect(association.writer(nil)).to be_nil }
323
340
  specify { expect(association.writer(new_author)).to eq(new_author) }
341
+
324
342
  specify do
325
343
  expect { association.writer(new_author) }
326
344
  .to change { association.reader.try(:attributes) }.from(nil).to('name' => 'Morty')
@@ -332,12 +350,17 @@ describe Granite::Form::Model::Associations::EmbedsOne do
332
350
  end
333
351
 
334
352
  specify do
335
- expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.writer(stub_model(:dummy).new) } }
336
- .not_to change { existing_association.reader }
353
+ expect do
354
+ muffle(Granite::Form::AssociationTypeMismatch) do
355
+ existing_association.writer(stub_model(:dummy).new)
356
+ end
357
+ end
358
+ .not_to(change { existing_association.reader })
337
359
  end
338
360
 
339
361
  specify { expect(existing_association.writer(nil)).to be_nil }
340
362
  specify { expect(existing_association.writer(new_author)).to eq(new_author) }
363
+
341
364
  specify do
342
365
  expect { existing_association.writer(new_author) }
343
366
  .to change { existing_association.reader.try(:attributes) }
@@ -1,38 +1,43 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Granite::Form::Model::Associations::PersistenceAdapters::ActiveRecord do
4
+ subject(:adapter) { described_class.new(Author, primary_key, scope_proc) }
5
+
4
6
  before do
5
7
  stub_class(:author, ActiveRecord::Base)
6
8
  end
7
9
 
8
- subject(:adapter) { described_class.new(Author, primary_key, scope_proc) }
9
10
  let(:primary_key) { :id }
10
11
  let(:scope_proc) { nil }
11
12
 
12
13
  describe '#build' do
13
14
  subject { adapter.build(name: name) }
15
+
14
16
  let(:name) { 'John Doe' }
15
17
 
16
- its(:name) { should == name }
18
+ its(:name) { is_expected.to eq name }
17
19
  it { is_expected.to be_a Author }
18
20
  end
19
21
 
20
22
  describe '#find_one' do
21
23
  subject { adapter.find_one(nil, author.id) }
24
+
22
25
  let(:author) { Author.create }
23
26
 
24
- it { should == author }
27
+ it { is_expected.to eq author }
25
28
  end
26
29
 
27
30
  describe '#find_all' do
28
31
  subject { adapter.find_all(nil, authors.map(&:id)) }
32
+
29
33
  let(:authors) { Array.new(2) { Author.create } }
30
34
 
31
- it { should == authors }
35
+ it { is_expected.to eq authors }
32
36
  end
33
37
 
34
38
  describe '#scope' do
35
39
  subject { adapter.scope(owner, source) }
40
+
36
41
  let(:authors) { ['John Doe', 'Sam Smith', 'John Smith'].map { |name| Author.create(name: name) } }
37
42
  let(:source) { authors[0..1].map(&:id) }
38
43
  let(:owner) { nil }
@@ -40,19 +45,19 @@ describe Granite::Form::Model::Associations::PersistenceAdapters::ActiveRecord d
40
45
  it { is_expected.to be_a ActiveRecord::Relation }
41
46
 
42
47
  context 'without scope_proc' do
43
- it { should == Author.where(primary_key => source) }
48
+ it { is_expected.to eq Author.where(primary_key => source) }
44
49
  end
45
50
 
46
51
  context 'with scope_proc' do
47
52
  let(:scope_proc) { -> { where("name LIKE 'John%'") } }
48
53
 
49
- its(:to_a) { should == [Author.first] }
54
+ its(:to_a) { is_expected.to eq [Author.first] }
50
55
  end
51
56
  end
52
57
 
53
58
  describe '#primary_key_type' do
54
59
  subject { adapter.primary_key_type }
55
60
 
56
- it { should == Integer }
61
+ it { is_expected.to eq Integer }
57
62
  end
58
63
  end
@@ -52,6 +52,7 @@ describe Granite::Form::Model::Associations::ReferencesMany do
52
52
 
53
53
  describe '#default' do
54
54
  before { Book.references_many :authors, default: ->(_book) { author.id } }
55
+
55
56
  let(:existing_book) { Book.instantiate title: 'Genesis' }
56
57
 
57
58
  specify { expect(association.target).to eq([author]) }
@@ -60,7 +61,7 @@ describe Granite::Form::Model::Associations::ReferencesMany do
60
61
 
61
62
  specify { expect(existing_association.target).to eq([]) }
62
63
  specify { expect { existing_association.replace([other]) }.to change { existing_association.target }.to([other]) }
63
- specify { expect { existing_association.replace([]) }.not_to change { existing_association.target } }
64
+ specify { expect { existing_association.replace([]) }.not_to(change { existing_association.target }) }
64
65
  end
65
66
 
66
67
  describe '#loaded?' do
@@ -77,6 +78,7 @@ describe Granite::Form::Model::Associations::ReferencesMany do
77
78
 
78
79
  context do
79
80
  before { existing_association.reader.last.name = 'Conan' }
81
+
80
82
  specify do
81
83
  expect { existing_association.reload }
82
84
  .to change { existing_association.reader.map(&:name) }
@@ -87,13 +89,18 @@ describe Granite::Form::Model::Associations::ReferencesMany do
87
89
 
88
90
  describe '#reader' do
89
91
  specify { expect(association.reader).to eq([]) }
90
- specify { expect(association.reader).to be_a Granite::Form::Model::Associations::PersistenceAdapters::ActiveRecord::ReferencedProxy }
92
+
93
+ specify do
94
+ expect(association.reader)
95
+ .to be_a Granite::Form::Model::Associations::PersistenceAdapters::ActiveRecord::ReferencedProxy
96
+ end
91
97
 
92
98
  specify { expect(existing_association.reader.first).to be_a Author }
93
99
  specify { expect(existing_association.reader.first).to be_persisted }
94
100
 
95
101
  context do
96
102
  before { association.concat author }
103
+
97
104
  specify { expect(association.reader.last).to be_a Author }
98
105
  specify { expect(association.reader.size).to eq(1) }
99
106
  specify { expect(association.reader(true)).to eq([author]) }
@@ -101,6 +108,7 @@ describe Granite::Form::Model::Associations::ReferencesMany do
101
108
 
102
109
  context do
103
110
  before { existing_association.concat other }
111
+
104
112
  specify { expect(existing_association.reader.size).to eq(2) }
105
113
  specify { expect(existing_association.reader.last.name).to eq('Ben') }
106
114
  specify { expect(existing_association.reader(true).size).to eq(2) }
@@ -128,10 +136,12 @@ describe Granite::Form::Model::Associations::ReferencesMany do
128
136
  specify { expect(association.writer([])).to eq([]) }
129
137
 
130
138
  specify { expect(association.writer([new_author1])).to eq([new_author1]) }
139
+
131
140
  specify do
132
141
  expect { association.writer([new_author1]) }
133
142
  .to change { association.reader.map(&:name) }.from([]).to(['John'])
134
143
  end
144
+
135
145
  specify do
136
146
  expect { association.writer([new_author1]) }
137
147
  .to change { book.read_attribute(:author_ids) }
@@ -142,41 +152,57 @@ describe Granite::Form::Model::Associations::ReferencesMany do
142
152
  expect { existing_association.writer([new_author1, Dummy.new, new_author2]) }
143
153
  .to raise_error Granite::Form::AssociationTypeMismatch
144
154
  end
155
+
145
156
  specify do
146
- expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.writer([new_author1, Dummy.new, new_author2]) } }
147
- .not_to change { existing_book.read_attribute(:author_ids) }
157
+ expect do
158
+ muffle(Granite::Form::AssociationTypeMismatch) do
159
+ existing_association.writer([new_author1, Dummy.new, new_author2])
160
+ end
161
+ end
162
+ .not_to(change { existing_book.read_attribute(:author_ids) })
148
163
  end
164
+
149
165
  specify do
150
- expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.writer([new_author1, Dummy.new, new_author2]) } }
151
- .not_to change { existing_association.reader }
166
+ expect do
167
+ muffle(Granite::Form::AssociationTypeMismatch) do
168
+ existing_association.writer([new_author1, Dummy.new, new_author2])
169
+ end
170
+ end
171
+ .not_to(change { existing_association.reader })
152
172
  end
153
173
 
154
174
  specify { expect { existing_association.writer(nil) }.to raise_error NoMethodError }
175
+
155
176
  specify do
156
177
  expect { muffle(NoMethodError) { existing_association.writer(nil) } }
157
- .not_to change { existing_book.read_attribute(:author_ids) }
178
+ .not_to(change { existing_book.read_attribute(:author_ids) })
158
179
  end
180
+
159
181
  specify do
160
182
  expect { muffle(NoMethodError) { existing_association.writer(nil) } }
161
- .not_to change { existing_association.reader }
183
+ .not_to(change { existing_association.reader })
162
184
  end
163
185
 
164
186
  specify { expect(existing_association.writer([])).to eq([]) }
187
+
165
188
  specify do
166
189
  expect { existing_association.writer([]) }
167
190
  .to change { existing_book.read_attribute(:author_ids) }.to([])
168
191
  end
192
+
169
193
  specify do
170
194
  expect { existing_association.writer([]) }
171
195
  .to change { existing_association.reader }.from([author]).to([])
172
196
  end
173
197
 
174
198
  specify { expect(existing_association.writer([new_author1, new_author2])).to eq([new_author1, new_author2]) }
199
+
175
200
  specify do
176
201
  expect { existing_association.writer([new_author1, new_author2]) }
177
202
  .to change { existing_association.reader.map(&:name) }
178
203
  .from(['Rick']).to(%w[John Adam])
179
204
  end
205
+
180
206
  specify do
181
207
  expect { existing_association.writer([new_author1, new_author2]) }
182
208
  .to change { existing_book.read_attribute(:author_ids) }
@@ -187,6 +213,7 @@ describe Granite::Form::Model::Associations::ReferencesMany do
187
213
  expect { existing_association.writer([new_author3]) }
188
214
  .to change { existing_association.target }.from([author]).to([new_author3])
189
215
  end
216
+
190
217
  specify do
191
218
  expect { existing_association.writer([new_author3]) }
192
219
  .to change { existing_book.read_attribute(:author_ids) }
@@ -209,10 +236,12 @@ describe Granite::Form::Model::Associations::ReferencesMany do
209
236
  specify { expect(existing_association.concat).to eq(existing_book.authors) }
210
237
 
211
238
  specify { expect(association.concat(new_author1)).to eq([new_author1]) }
239
+
212
240
  specify do
213
241
  expect { association.concat(new_author1) }
214
242
  .to change { association.reader.map(&:name) }.from([]).to(['John'])
215
243
  end
244
+
216
245
  specify do
217
246
  expect { association.concat(new_author1) }
218
247
  .to change { book.read_attribute(:author_ids) }.from([]).to([new_author1.id])
@@ -222,13 +251,23 @@ describe Granite::Form::Model::Associations::ReferencesMany do
222
251
  expect { existing_association.concat(new_author1, Dummy.new, new_author2) }
223
252
  .to raise_error Granite::Form::AssociationTypeMismatch
224
253
  end
254
+
225
255
  specify do
226
- expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.concat(new_author1, Dummy.new, new_author2) } }
256
+ expect do
257
+ muffle(Granite::Form::AssociationTypeMismatch) do
258
+ existing_association.concat(new_author1, Dummy.new, new_author2)
259
+ end
260
+ end
227
261
  .to change { existing_book.read_attribute(:author_ids) }
228
262
  .from([author.id]).to([author.id, new_author1.id])
229
263
  end
264
+
230
265
  specify do
231
- expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.concat(new_author1, Dummy.new, new_author2) } }
266
+ expect do
267
+ muffle(Granite::Form::AssociationTypeMismatch) do
268
+ existing_association.concat(new_author1, Dummy.new, new_author2)
269
+ end
270
+ end
232
271
  .to change { existing_association.reader.map(&:name) }
233
272
  .from(['Rick']).to(%w[Rick John])
234
273
  end
@@ -237,11 +276,13 @@ describe Granite::Form::Model::Associations::ReferencesMany do
237
276
  expect(existing_association.concat(new_author1, new_author2))
238
277
  .to eq([author, new_author1, new_author2])
239
278
  end
279
+
240
280
  specify do
241
281
  expect { existing_association.concat([new_author1, new_author2]) }
242
282
  .to change { existing_association.reader.map(&:name) }
243
283
  .from(['Rick']).to(%w[Rick John Adam])
244
284
  end
285
+
245
286
  specify do
246
287
  expect { existing_association.concat([new_author1, new_author2]) }
247
288
  .to change { existing_book.read_attribute(:author_ids) }
@@ -58,6 +58,7 @@ describe Granite::Form::Model::Associations::ReferencesOne do
58
58
 
59
59
  context do
60
60
  before { existing_association.reader.name = 'New' }
61
+
61
62
  specify do
62
63
  expect { existing_association.reload }
63
64
  .to change { existing_association.reader.name }
@@ -75,6 +76,7 @@ describe Granite::Form::Model::Associations::ReferencesOne do
75
76
 
76
77
  describe '#default' do
77
78
  before { Book.references_one :author, default: ->(_book) { author.id } }
79
+
78
80
  let(:existing_book) { Book.instantiate title: 'My Life' }
79
81
 
80
82
  specify { expect(association.target).to eq(author) }
@@ -83,7 +85,7 @@ describe Granite::Form::Model::Associations::ReferencesOne do
83
85
 
84
86
  specify { expect(existing_association.target).to be_nil }
85
87
  specify { expect { existing_association.replace(other) }.to change { existing_association.target }.to(other) }
86
- specify { expect { existing_association.replace(nil) }.not_to change { existing_association.target } }
88
+ specify { expect { existing_association.replace(nil) }.not_to(change { existing_association.target }) }
87
89
  end
88
90
 
89
91
  describe '#writer' do
@@ -98,13 +100,15 @@ describe Granite::Form::Model::Associations::ReferencesOne do
98
100
 
99
101
  specify do
100
102
  expect { association.writer(nil) }
101
- .not_to change { book.author_id }
103
+ .not_to(change { book.author_id })
102
104
  end
105
+
103
106
  specify do
104
107
  expect { association.writer(new_author) }
105
108
  .to change { muffle(NoMethodError) { association.reader.name } }
106
109
  .from(nil).to('Morty')
107
110
  end
111
+
108
112
  specify do
109
113
  expect { association.writer(new_author) }
110
114
  .not_to change { book.author_id }.from(nil)
@@ -121,17 +125,20 @@ describe Granite::Form::Model::Associations::ReferencesOne do
121
125
 
122
126
  specify { expect(association.writer(nil)).to be_nil }
123
127
  specify { expect(association.writer(new_author)).to eq(new_author) }
128
+
124
129
  specify do
125
130
  expect { association.writer(nil) }
126
- .not_to change { book.read_attribute(:author_id) }
131
+ .not_to(change { book.read_attribute(:author_id) })
127
132
  end
133
+
128
134
  specify do
129
135
  expect { association.writer(new_author) }
130
136
  .to change { association.reader }.from(nil).to(new_author)
131
137
  end
138
+
132
139
  specify do
133
140
  expect { association.writer(new_author) }
134
- .to change { book.read_attribute(:author_id) }
141
+ .to(change { book.read_attribute(:author_id) })
135
142
  end
136
143
 
137
144
  context do
@@ -143,26 +150,30 @@ describe Granite::Form::Model::Associations::ReferencesOne do
143
150
 
144
151
  specify do
145
152
  expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.writer(Dummy.new) } }
146
- .not_to change { existing_book.read_attribute(:author_id) }
153
+ .not_to(change { existing_book.read_attribute(:author_id) })
147
154
  end
155
+
148
156
  specify do
149
157
  expect { muffle(Granite::Form::AssociationTypeMismatch) { existing_association.writer(Dummy.new) } }
150
- .not_to change { existing_association.reader }
158
+ .not_to(change { existing_association.reader })
151
159
  end
152
160
  end
153
161
 
154
162
  specify { expect(existing_association.writer(nil)).to be_nil }
155
163
  specify { expect(existing_association.writer(new_author)).to eq(new_author) }
164
+
156
165
  specify do
157
166
  expect { existing_association.writer(nil) }
158
167
  .to change { existing_book.read_attribute(:author_id) }
159
168
  .from(author.id).to(nil)
160
169
  end
170
+
161
171
  specify do
162
172
  expect { existing_association.writer(new_author) }
163
173
  .to change { existing_association.reader }
164
174
  .from(author).to(new_author)
165
175
  end
176
+
166
177
  specify do
167
178
  expect { existing_association.writer(new_author) }
168
179
  .to change { existing_book.read_attribute(:author_id) }