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
@@ -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) }
@@ -14,6 +14,7 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
14
14
  embeds_many :projects
15
15
  end
16
16
  end
17
+
17
18
  let(:user) { User.new }
18
19
 
19
20
  context ':read, :write' do
@@ -24,14 +25,14 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
24
25
 
25
26
  attribute :name
26
27
  embeds_many :projects,
27
- read: lambda { |reflection, object|
28
- value = object.instance_variable_get("@_value_#{reflection.name}")
29
- JSON.parse(value) if value.present?
30
- },
31
- write: lambda { |reflection, object, value|
32
- value = value.to_json if value
33
- object.instance_variable_set("@_value_#{reflection.name}", value)
34
- }
28
+ read: lambda { |reflection, object|
29
+ value = object.instance_variable_get("@_value_#{reflection.name}")
30
+ JSON.parse(value) if value.present?
31
+ },
32
+ write: lambda { |reflection, object, value|
33
+ value = value.to_json if value
34
+ object.instance_variable_set("@_value_#{reflection.name}", value)
35
+ }
35
36
  end
36
37
  end
37
38
 
@@ -55,16 +56,18 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
55
56
 
56
57
  describe '#build' do
57
58
  let(:project) { Project.new title: 'Project' }
59
+
58
60
  specify { expect(user.projects.build(title: 'Project')).to eq(project) }
59
61
  specify { expect { user.projects.build(title: 'Project') }.to change { user.projects }.from([]).to([project]) }
60
62
  end
61
63
 
62
64
  describe '#reload' do
63
65
  let(:project) { Project.new title: 'Project' }
66
+
64
67
  before do
65
- user.write_attribute(:projects, [{title: 'Project'}])
68
+ user.write_attribute(:projects, [{ title: 'Project' }])
69
+ user.projects.build
66
70
  end
67
- before { user.projects.build }
68
71
 
69
72
  specify { expect(user.projects.count).to eq(2) }
70
73
  specify { expect(user.projects.reload).to eq([project]) }
@@ -72,26 +75,42 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
72
75
 
73
76
  describe '#concat' do
74
77
  let(:project) { Project.new title: 'Project' }
78
+
75
79
  specify { expect { user.projects.concat project }.to change { user.projects }.from([]).to([project]) }
76
- specify { expect { user.projects.concat project, 'string' }.to raise_error Granite::Form::AssociationTypeMismatch }
80
+
81
+ specify do
82
+ expect do
83
+ user.projects.concat project, 'string'
84
+ end.to raise_error Granite::Form::AssociationTypeMismatch
85
+ end
77
86
 
78
87
  context do
79
88
  let(:other) { Project.new title: 'Other' }
89
+
80
90
  before { user.projects = [other] }
81
- specify { expect { user.projects.concat project }.to change { user.projects }.from([other]).to([other, project]) }
91
+
92
+ specify do
93
+ expect { user.projects.concat project }
94
+ .to change { user.projects }
95
+ .from([other])
96
+ .to([other, project])
97
+ end
82
98
  end
83
99
  end
84
100
  end
85
101
 
86
102
  describe '#projects=' do
87
103
  let(:project) { Project.new title: 'Project' }
104
+
88
105
  specify { expect { user.projects = [] }.not_to change { user.projects }.from([]) }
89
106
  specify { expect { user.projects = [project] }.to change { user.projects }.from([]).to([project]) }
90
107
  specify { expect { user.projects = [project, 'string'] }.to raise_error Granite::Form::AssociationTypeMismatch }
91
108
 
92
109
  context do
93
110
  let(:other) { Project.new title: 'Other' }
111
+
94
112
  before { user.projects = [other] }
113
+
95
114
  specify { expect { user.projects = [project] }.to change { user.projects }.from([other]).to([project]) }
96
115
  specify { expect { user.projects = [] }.to change { user.projects }.from([other]).to([]) }
97
116
  end
@@ -112,8 +131,18 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
112
131
 
113
132
  specify { expect(User.reflect_on_association(:projects).klass).to eq(User::Project) }
114
133
  specify { expect(User.new.projects).to eq([]) }
115
- specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to be_a(Granite::Form::Model::Associations::Collection::Embedded) }
116
- specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to match([have_attributes(title: 'Project')]) }
134
+
135
+ specify do
136
+ user = User.new
137
+ user.projects.build(title: 'Project')
138
+ expect(user.projects).to be_a(Granite::Form::Model::Associations::Collection::Embedded)
139
+ end
140
+
141
+ specify do
142
+ user = User.new
143
+ user.projects.build(title: 'Project')
144
+ expect(user.projects).to match([have_attributes(title: 'Project')])
145
+ end
117
146
  end
118
147
 
119
148
  context do
@@ -130,8 +159,14 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsMany do
130
159
 
131
160
  specify { expect(User.reflect_on_association(:projects).klass).to eq(User::Project) }
132
161
  specify { expect(User.new.projects).to eq([]) }
133
- specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to be_a(Granite::Form::Model::Associations::Collection::Embedded) }
134
- specify { expect(User.new.tap { |u| u.projects.build(title: 'Project') }.projects).to match([have_attributes(title: 'Project', value: nil)]) }
162
+
163
+ specify do
164
+ user = User.new
165
+ user.projects.build(title: 'Project')
166
+ expect(user.projects)
167
+ .to be_a(Granite::Form::Model::Associations::Collection::Embedded)
168
+ .and match([have_attributes(title: 'Project', value: nil)])
169
+ end
135
170
  end
136
171
  end
137
172
  end
@@ -15,6 +15,7 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
15
15
  embeds_one :author
16
16
  end
17
17
  end
18
+
18
19
  let(:book) { Book.new }
19
20
 
20
21
  specify { expect(book.author).to be_nil }
@@ -27,14 +28,14 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
27
28
 
28
29
  attribute :title
29
30
  embeds_one :author,
30
- read: lambda { |reflection, object|
31
- value = object.instance_variable_get("@_value_#{reflection.name}")
32
- JSON.parse(value) if value.present?
33
- },
34
- write: lambda { |reflection, object, value|
35
- value = value.to_json if value
36
- object.instance_variable_set("@_value_#{reflection.name}", value)
37
- }
31
+ read: lambda { |reflection, object|
32
+ value = object.instance_variable_get("@_value_#{reflection.name}")
33
+ JSON.parse(value) if value.present?
34
+ },
35
+ write: lambda { |reflection, object, value|
36
+ value = value.to_json if value
37
+ object.instance_variable_set("@_value_#{reflection.name}", value)
38
+ }
38
39
  end
39
40
  end
40
41
 
@@ -53,12 +54,15 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
53
54
 
54
55
  describe '#author=' do
55
56
  let(:author) { Author.new name: 'Author' }
57
+
56
58
  specify { expect { book.author = author }.to change { book.author }.from(nil).to(author) }
57
59
  specify { expect { book.author = 'string' }.to raise_error Granite::Form::AssociationTypeMismatch }
58
60
 
59
61
  context do
60
62
  let(:other) { Author.new name: 'Other' }
63
+
61
64
  before { book.author = other }
65
+
62
66
  specify { expect { book.author = author }.to change { book.author }.from(other).to(author) }
63
67
  specify { expect { book.author = nil }.to change { book.author }.from(other).to(nil) }
64
68
  end
@@ -66,6 +70,7 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
66
70
 
67
71
  describe '#build_author' do
68
72
  let(:author) { Author.new name: 'Author' }
73
+
69
74
  specify { expect(book.build_author(name: 'Author')).to eq(author) }
70
75
  specify { expect { book.build_author(name: 'Author') }.to change { book.author }.from(nil).to(author) }
71
76
  end
@@ -104,7 +109,12 @@ describe Granite::Form::Model::Associations::Reflections::EmbedsOne do
104
109
  specify { expect(Book.reflect_on_association(:author).klass).to eq(Book::Author) }
105
110
  specify { expect(Book.new.author).to be_nil }
106
111
  specify { expect(Book.new.tap { |b| b.build_author(name: 'Author') }.author).to be_a(Book::Author) }
107
- specify { expect(Book.new.tap { |b| b.build_author(name: 'Author') }.author).to have_attributes(name: 'Author', age: nil) }
112
+
113
+ specify do
114
+ book = Book.new
115
+ book.build_author(name: 'Author')
116
+ expect(book.author).to have_attributes(name: 'Author', age: nil)
117
+ end
108
118
  end
109
119
  end
110
120
  end