reform 2.2.4 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +17 -0
  3. data/.gitignore +5 -1
  4. data/CHANGES.md +80 -4
  5. data/CONTRIBUTING.md +31 -0
  6. data/Gemfile +2 -16
  7. data/ISSUE_TEMPLATE.md +25 -0
  8. data/LICENSE.txt +1 -1
  9. data/README.md +10 -12
  10. data/Rakefile +6 -10
  11. data/lib/reform/contract/custom_error.rb +41 -0
  12. data/lib/reform/contract/validate.rb +53 -23
  13. data/lib/reform/contract.rb +7 -17
  14. data/lib/reform/errors.rb +61 -0
  15. data/lib/reform/form/call.rb +1 -1
  16. data/lib/reform/form/composition.rb +2 -2
  17. data/lib/reform/form/dry/input_hash.rb +37 -0
  18. data/lib/reform/form/dry.rb +25 -35
  19. data/lib/reform/form/populator.rb +20 -26
  20. data/lib/reform/form/prepopulate.rb +5 -4
  21. data/lib/reform/form/validate.rb +29 -14
  22. data/lib/reform/form.rb +36 -10
  23. data/lib/reform/result.rb +90 -0
  24. data/lib/reform/validation/groups.rb +12 -28
  25. data/lib/reform/validation.rb +19 -11
  26. data/lib/reform/version.rb +1 -1
  27. data/lib/reform.rb +1 -0
  28. data/reform.gemspec +13 -13
  29. data/test/benchmarking.rb +39 -6
  30. data/test/call_test.rb +9 -9
  31. data/test/changed_test.rb +14 -14
  32. data/test/coercion_test.rb +57 -25
  33. data/test/composition_test.rb +85 -49
  34. data/test/contract/custom_error_test.rb +55 -0
  35. data/test/contract_test.rb +20 -20
  36. data/test/default_test.rb +4 -4
  37. data/test/deserialize_test.rb +17 -20
  38. data/test/docs/validation_test.rb +134 -0
  39. data/test/errors_test.rb +142 -82
  40. data/test/feature_test.rb +10 -12
  41. data/test/fixtures/dry_error_messages.yml +83 -23
  42. data/test/form_option_test.rb +5 -5
  43. data/test/form_test.rb +8 -8
  44. data/test/from_test.rb +18 -22
  45. data/test/inherit_test.rb +54 -68
  46. data/test/module_test.rb +27 -32
  47. data/test/parse_option_test.rb +40 -0
  48. data/test/parse_pipeline_test.rb +4 -4
  49. data/test/populate_test.rb +217 -100
  50. data/test/populator_skip_test.rb +11 -11
  51. data/test/prepopulator_test.rb +24 -25
  52. data/test/read_only_test.rb +12 -1
  53. data/test/readable_test.rb +9 -9
  54. data/test/reform_test.rb +47 -66
  55. data/test/save_test.rb +35 -23
  56. data/test/setup_test.rb +17 -17
  57. data/test/skip_if_test.rb +33 -22
  58. data/test/skip_setter_and_getter_test.rb +9 -10
  59. data/test/test_helper.rb +23 -14
  60. data/test/validate_test.rb +165 -145
  61. data/test/validation/dry_validation_test.rb +630 -146
  62. data/test/validation/result_test.rb +77 -0
  63. data/test/validation_library_provided_test.rb +16 -0
  64. data/test/virtual_test.rb +47 -7
  65. data/test/writeable_test.rb +38 -9
  66. metadata +46 -38
  67. data/.travis.yml +0 -11
  68. data/gemfiles/Gemfile.disposable-0.3 +0 -6
  69. data/lib/reform/contract/errors.rb +0 -43
  70. data/lib/reform/form/mongoid.rb +0 -37
  71. data/lib/reform/form/orm.rb +0 -26
  72. data/lib/reform/mongoid.rb +0 -4
  73. data/test/deprecation_test.rb +0 -27
  74. data/test/readonly_test.rb +0 -14
  75. data/test/validation/dry_test.rb +0 -60
  76. data/test/validation/errors.yml +0 -4
@@ -3,13 +3,13 @@ require "test_helper"
3
3
  class ParsePipelineTest < MiniTest::Spec
4
4
  Album = Struct.new(:name)
5
5
 
6
- class AlbumForm < Reform::Form
7
- property :name, deserializer: { parse_pipeline: ->(input, options) { Representable::Pipeline[->(input, options) { options[:represented].name = input.inspect }] } }
6
+ class AlbumForm < TestForm
7
+ property :name, deserializer: {parse_pipeline: ->(input, options) { Representable::Pipeline[->(ipt, opts) { opts[:represented].name = ipt.inspect }] }}
8
8
  end
9
9
 
10
10
  it "allows passing :parse_pipeline directly" do
11
11
  form = AlbumForm.new(Album.new)
12
12
  form.validate("name" => "Greatest Hits")
13
- form.name.must_equal "{\"name\"=>\"Greatest Hits\"}"
13
+ assert_equal form.name, "{\"name\"=>\"Greatest Hits\"}"
14
14
  end
15
- end
15
+ end
@@ -5,27 +5,25 @@ class PopulatorTest < MiniTest::Spec
5
5
  Album = Struct.new(:name, :songs, :artist)
6
6
  Artist = Struct.new(:name)
7
7
 
8
- class AlbumForm < Reform::Form
8
+ class AlbumForm < TestForm
9
9
  property :name, populator: ->(options) { self.name = options[:fragment].reverse }
10
10
  validation do
11
- key(:name).required
11
+ params { required(:name).filled }
12
12
  end
13
13
 
14
14
  collection :songs,
15
- populator: ->(options) {
16
- fragment, collection, index = options[:fragment], options[:model], options[:index]
17
-
18
- (item = collection[index]) ? item : collection.insert(index, Song.new) } do
19
-
15
+ populator: ->(fragment:, model:, index:, **) {
16
+ (item = model[index]) ? item : model.insert(index, Song.new)
17
+ } do
20
18
  property :title
21
19
  validation do
22
- key(:title).required
20
+ params { required(:title).filled }
23
21
  end
24
22
 
25
- property :composer, populator: ->(options) { options[:model] || self.composer= Artist.new } do
23
+ property :composer, populator: ->(options) { options[:model] || self.composer = Artist.new } do
26
24
  property :name
27
25
  validation do
28
- key(:name).required
26
+ params { required(:name).filled }
29
27
  end
30
28
  end
31
29
  end
@@ -37,20 +35,20 @@ class PopulatorTest < MiniTest::Spec
37
35
  end
38
36
  end
39
37
 
40
- let (:song) { Song.new("Broken") }
41
- let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
42
- let (:composer) { Artist.new("Greg Graffin") }
43
- let (:artist) { Artist.new("Bad Religion") }
44
- let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
38
+ let(:song) { Song.new("Broken") }
39
+ let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
40
+ let(:composer) { Artist.new("Greg Graffin") }
41
+ let(:artist) { Artist.new("Bad Religion") }
42
+ let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
45
43
 
46
- let (:form) { AlbumForm.new(album) }
44
+ let(:form) { AlbumForm.new(album) }
47
45
 
48
46
  it "runs populator on scalar" do
49
47
  form.validate(
50
48
  "name" => "override me!"
51
49
  )
52
50
 
53
- form.name.must_equal "!em edirrevo"
51
+ assert_equal form.name, "!em edirrevo"
54
52
  end
55
53
 
56
54
  # changing existing property :artist.
@@ -62,7 +60,7 @@ class PopulatorTest < MiniTest::Spec
62
60
  "artist" => {"name" => "Marcus Miller"}
63
61
  )
64
62
 
65
- form.artist.model.object_id.must_equal old_id
63
+ assert_equal form.artist.model.object_id, old_id
66
64
  end
67
65
 
68
66
  # use populator for default value on scalars?
@@ -70,44 +68,43 @@ class PopulatorTest < MiniTest::Spec
70
68
  # adding to collection via :populator.
71
69
  # valid.
72
70
  it "yyy" do
73
- form.validate(
71
+ assert form.validate(
74
72
  "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
75
73
  {"title" => "Rime Of The Ancient Mariner"}, # new song.
76
74
  {"title" => "Re-Education", "composer" => {"name" => "Rise Against"}}], # new song with new composer.
77
- ).must_equal true
75
+ )
78
76
 
79
- form.errors.messages.inspect.must_equal "{}"
77
+ assert_equal form.errors.messages.inspect, "{}"
80
78
 
81
79
  # form has updated.
82
- form.name.must_equal "The Dissent Of Man"
83
- form.songs[0].title.must_equal "Fallout"
84
- form.songs[1].title.must_equal "Roxanne"
85
- form.songs[1].composer.name.must_equal "Greg Graffin"
86
-
87
- form.songs[1].composer.model.must_be_instance_of Artist
80
+ assert_equal form.name, "The Dissent Of Man"
81
+ assert_equal form.songs[0].title, "Fallout"
82
+ assert_equal form.songs[1].title, "Roxanne"
83
+ assert_equal form.songs[1].composer.name, "Greg Graffin"
88
84
 
89
- form.songs[1].title.must_equal "Roxanne"
90
- form.songs[2].title.must_equal "Rime Of The Ancient Mariner" # new song added.
91
- form.songs[3].title.must_equal "Re-Education"
92
- form.songs[3].composer.name.must_equal "Rise Against"
93
- form.songs.size.must_equal 4
94
- form.artist.name.must_equal "Bad Religion"
85
+ form.songs[1].composer.model.is_a? Artist
95
86
 
87
+ assert_equal form.songs[1].title, "Roxanne"
88
+ assert_equal form.songs[2].title, "Rime Of The Ancient Mariner" # new song added.
89
+ assert_equal form.songs[3].title, "Re-Education"
90
+ assert_equal form.songs[3].composer.name, "Rise Against"
91
+ assert_equal form.songs.size, 4
92
+ assert_equal form.artist.name, "Bad Religion"
96
93
 
97
94
  # model has not changed, yet.
98
- album.name.must_equal "The Dissent Of Man"
99
- album.songs[0].title.must_equal "Broken"
100
- album.songs[1].title.must_equal "Resist Stance"
101
- album.songs[1].composer.name.must_equal "Greg Graffin"
102
- album.songs.size.must_equal 2
103
- album.artist.name.must_equal "Bad Religion"
95
+ assert_equal album.name, "The Dissent Of Man"
96
+ assert_equal album.songs[0].title, "Broken"
97
+ assert_equal album.songs[1].title, "Resist Stance"
98
+ assert_equal album.songs[1].composer.name, "Greg Graffin"
99
+ assert_equal album.songs.size, 2
100
+ assert_equal album.artist.name, "Bad Religion"
104
101
  end
105
102
  end
106
103
 
107
104
  class PopulateWithMethodTest < Minitest::Spec
108
105
  Album = Struct.new(:title)
109
106
 
110
- class AlbumForm < Reform::Form
107
+ class AlbumForm < TestForm
111
108
  property :title, populator: :title!
112
109
 
113
110
  def title!(options)
@@ -115,14 +112,80 @@ class PopulateWithMethodTest < Minitest::Spec
115
112
  end
116
113
  end
117
114
 
118
- let (:form) { AlbumForm.new(Album.new) }
115
+ let(:form) { AlbumForm.new(Album.new) }
119
116
 
120
117
  it "runs populator method" do
121
- form.validate(
122
- "title" => "override me!"
123
- )
118
+ form.validate("title" => "override me!")
119
+
120
+ assert_equal form.title, "!em edirrevo"
121
+ end
122
+ end
123
+
124
+ class PopulateWithCallableTest < Minitest::Spec
125
+ Album = Struct.new(:title)
126
+
127
+ class TitlePopulator
128
+ include Uber::Callable
129
+
130
+ def call(form:, **options)
131
+ form.title = options[:fragment].reverse
132
+ end
133
+ end
134
+
135
+ class TitlePopulatorWithOldSignature
136
+ include Uber::Callable
137
+
138
+ def call(form, options)
139
+ form.title = options[:fragment].reverse
140
+ end
141
+ end
142
+
143
+ class AlbumForm < TestForm
144
+ property :title, populator: TitlePopulator.new
145
+ end
146
+
147
+ class AlbumFormWithOldPopulator < TestForm
148
+ property :title, populator: TitlePopulatorWithOldSignature.new
149
+ end
150
+
151
+ let(:form) { AlbumForm.new(Album.new) }
152
+
153
+ it "runs populator method" do
154
+ form.validate("title" => "override me!")
155
+
156
+ assert_equal form.title, "!em edirrevo"
157
+ end
158
+
159
+ it "gives warning when `form` is accepted as a positional argument" do
160
+ _, warnings = capture_io do
161
+ form = AlbumFormWithOldPopulator.new(Album.new)
162
+ form.validate("title" => "override me!")
163
+
164
+ assert_equal form.title, "!em edirrevo"
165
+ end
166
+
167
+ assert_equal warnings, %{[Reform] Accepting `form` as a positional argument in `:populator` will be deprecated. Please use `def call(form:, **options)` signature instead.
168
+ }
169
+ end
170
+ end
171
+
172
+ class PopulateWithProcTest < Minitest::Spec
173
+ Album = Struct.new(:title)
174
+
175
+ TitlePopulator = ->(options) do
176
+ options[:represented].title = options[:fragment].reverse
177
+ end
178
+
179
+ class AlbumForm < TestForm
180
+ property :title, populator: TitlePopulator
181
+ end
182
+
183
+ let(:form) { AlbumForm.new(Album.new) }
124
184
 
125
- form.title.must_equal "!em edirrevo"
185
+ it "runs populator method" do
186
+ form.validate("title" => "override me!")
187
+
188
+ assert_equal form.title, "!em edirrevo"
126
189
  end
127
190
  end
128
191
 
@@ -131,15 +194,13 @@ class PopulateIfEmptyTest < MiniTest::Spec
131
194
  Album = Struct.new(:name, :songs, :artist)
132
195
  Artist = Struct.new(:name)
133
196
 
134
- let (:song) { Song.new("Broken") }
135
- let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
136
- let (:composer) { Artist.new("Greg Graffin") }
137
- let (:artist) { Artist.new("Bad Religion") }
138
- let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
139
-
197
+ let(:song) { Song.new("Broken") }
198
+ let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
199
+ let(:composer) { Artist.new("Greg Graffin") }
200
+ let(:artist) { Artist.new("Bad Religion") }
201
+ let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
140
202
 
141
-
142
- class AlbumForm < Reform::Form
203
+ class AlbumForm < TestForm
143
204
  property :name
144
205
 
145
206
  collection :songs,
@@ -147,68 +208,67 @@ class PopulateIfEmptyTest < MiniTest::Spec
147
208
 
148
209
  property :title
149
210
  validation do
150
- key(:title).required
211
+ params { required(:title).filled }
151
212
  end
152
213
 
153
214
  property :composer, populate_if_empty: :populate_composer! do # lambda works, too. in form context.
154
215
  property :name
155
216
  validation do
156
- key(:name).required
217
+ params { required(:name).filled }
157
218
  end
158
219
  end
159
220
 
160
221
  private
161
- def populate_composer!(fragment, options)
222
+ def populate_composer!(options)
162
223
  Artist.new
163
224
  end
164
225
  end
165
226
 
166
- property :artist, populate_if_empty: lambda { |args| create_artist(args[:fragment], args[:user_options]) } do # methods work, too.
227
+ property :artist, populate_if_empty: ->(args) { create_artist(args[:fragment], args[:user_options]) } do # methods work, too.
167
228
  property :name
168
229
  end
169
230
 
170
- private
231
+ private
171
232
  class Sting < Artist
172
233
  attr_accessor :args
173
234
  end
174
235
  def create_artist(input, user_options)
175
- Sting.new.tap { |artist| artist.args=([input, user_options].to_s) }
236
+ Sting.new.tap { |artist| artist.args = ([input, user_options].to_s) }
176
237
  end
177
238
  end
178
239
 
179
- let (:form) { AlbumForm.new(album) }
240
+ let(:form) { AlbumForm.new(album) }
180
241
 
181
242
  it do
182
- form.songs.size.must_equal 2
243
+ assert_equal form.songs.size, 2
183
244
 
184
- form.validate(
185
- "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
245
+ assert form.validate(
246
+ "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
186
247
  {"title" => "Rime Of The Ancient Mariner"}, # new song.
187
248
  {"title" => "Re-Education", "composer" => {"name" => "Rise Against"}}], # new song with new composer.
188
- ).must_equal true
249
+ )
189
250
 
190
- form.errors.messages.inspect.must_equal "{}"
251
+ assert_equal form.errors.messages.inspect, "{}"
191
252
 
192
253
  # form has updated.
193
- form.name.must_equal "The Dissent Of Man"
194
- form.songs[0].title.must_equal "Fallout"
195
- form.songs[1].title.must_equal "Roxanne"
196
- form.songs[1].composer.name.must_equal "Greg Graffin"
197
- form.songs[1].title.must_equal "Roxanne"
198
- form.songs[2].title.must_equal "Rime Of The Ancient Mariner" # new song added.
199
- form.songs[3].title.must_equal "Re-Education"
200
- form.songs[3].composer.name.must_equal "Rise Against"
201
- form.songs.size.must_equal 4
202
- form.artist.name.must_equal "Bad Religion"
203
-
254
+ assert_equal form.name, "The Dissent Of Man"
255
+ assert_equal form.songs[0].title, "Fallout"
256
+ assert_equal form.songs[1].title, "Roxanne"
257
+ assert_equal form.songs[1].composer.name, "Greg Graffin"
258
+ assert_equal form.songs[1].title, "Roxanne"
259
+ assert_equal form.songs[2].title, "Rime Of The Ancient Mariner" # new song added.
260
+ assert_equal form.songs[3].title, "Re-Education"
261
+ assert_equal form.songs[3].composer.name, "Rise Against"
262
+ assert_equal form.songs.size, 4
263
+ assert_equal form.artist.name, "Bad Religion"
204
264
 
205
265
  # model has not changed, yet.
206
- album.name.must_equal "The Dissent Of Man"
207
- album.songs[0].title.must_equal "Broken"
208
- album.songs[1].title.must_equal "Resist Stance"
209
- album.songs[1].composer.name.must_equal "Greg Graffin"
210
- album.songs.size.must_equal 2
211
- album.artist.name.must_equal "Bad Religion"
266
+ assert_equal album.name, "The Dissent Of Man"
267
+ assert_equal album.songs[0].title, "Broken"
268
+ assert_equal album.songs[1].title, "Resist Stance"
269
+ assert_equal album.songs[1].composer.name, "Greg Graffin"
270
+ assert_equal album.songs.size, 2
271
+ assert_equal album.artist.name, "Bad Religion"
212
272
  end
213
273
 
214
274
  # trigger artist populator. lambda calling form instance method.
@@ -216,28 +276,26 @@ class PopulateIfEmptyTest < MiniTest::Spec
216
276
  form = AlbumForm.new(album = Album.new)
217
277
  form.validate("artist" => {"name" => "From Autumn To Ashes"})
218
278
 
219
- form.artist.name.must_equal "From Autumn To Ashes"
279
+ assert_equal form.artist.name, "From Autumn To Ashes"
220
280
  # test lambda was executed in form context.
221
- form.artist.model.must_be_instance_of AlbumForm::Sting
281
+ assert form.artist.model.is_a? AlbumForm::Sting
222
282
  # test lambda block arguments.
223
- form.artist.model.args.to_s.must_equal "[{\"name\"=>\"From Autumn To Ashes\"}, nil]"
283
+ assert_equal form.artist.model.args.to_s, "[{\"name\"=>\"From Autumn To Ashes\"}, nil]"
224
284
 
225
- album.artist.must_equal nil
285
+ assert_nil album.artist
226
286
  end
227
287
  end
228
288
 
229
-
230
289
  # delete songs while deserializing.
231
290
  class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
232
291
  Song = Struct.new(:title, :album, :composer)
233
292
  Album = Struct.new(:name, :songs, :artist)
234
293
 
235
- let (:song) { Song.new("Broken") }
236
- let (:song2) { Song.new("Resist Stance") }
237
- let (:album) { Album.new("The Dissent Of Man", [song, song2]) }
238
-
294
+ let(:song) { Song.new("Broken") }
295
+ let(:song2) { Song.new("Resist Stance") }
296
+ let(:album) { Album.new("The Dissent Of Man", [song, song2]) }
239
297
 
240
- class AlbumForm < Reform::Form
298
+ class AlbumForm < TestForm
241
299
  property :name
242
300
 
243
301
  collection :songs,
@@ -245,7 +303,7 @@ class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
245
303
 
246
304
  property :title
247
305
  validation do
248
- key(:title).required
306
+ params { required(:title).filled }
249
307
  end
250
308
  end
251
309
 
@@ -255,16 +313,75 @@ class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
255
313
  end
256
314
  end
257
315
 
258
- let (:form) { AlbumForm.new(album) }
316
+ let(:form) { AlbumForm.new(album) }
259
317
 
260
318
  it do
261
- form.validate(
262
- "songs" => [{"title" => "Broken, delete me!"}, {"title" => "Roxanne"}]
263
- ).must_equal true
319
+ assert form.validate(
320
+ "songs" => [{"title" => "Broken, delete me!"}, {"title" => "Roxanne"}]
321
+ )
322
+
323
+ assert_equal form.errors.messages.inspect, "{}"
324
+
325
+ assert_equal form.songs.size, 1
326
+ assert_equal form.songs[0].title, "Roxanne"
327
+ end
328
+ end
329
+
330
+ class PopulateWithFormKeyTest < MiniTest::Spec
331
+ Song = Struct.new(:title, :album, :composer)
332
+ Album = Struct.new(:name, :songs, :artist)
333
+
334
+ let(:song) { Song.new('Broken') }
335
+ let(:song2) { Song.new('Resist Stance') }
336
+ let(:album) { Album.new('The Dissent Of Man', [song, song2]) }
337
+
338
+ class SongForm < TestForm
339
+ property :title
340
+
341
+ validation do
342
+ params { required(:title).filled }
343
+ end
344
+ end
345
+
346
+ class AlbumForm < TestForm
347
+ property :name
264
348
 
265
- form.errors.messages.inspect.must_equal "{}"
349
+ collection :songs, form: SongForm, populator: :populator!, model_identifier: :title
266
350
 
267
- form.songs.size.must_equal 1
268
- form.songs[0].title.must_equal "Roxanne"
351
+ def populator!(fragment:, **)
352
+ item = songs.find { |song| song.title == fragment['title'] }
353
+ if item && fragment['delete'] == '1'
354
+ songs.delete(item)
355
+ return skip!
356
+ end
357
+ item || songs.append(Song.new)
358
+ end
359
+ end
360
+
361
+ let(:form) { AlbumForm.new(album) }
362
+
363
+ it do
364
+ assert_equal 2, form.songs.size
365
+
366
+ assert form.validate(
367
+ 'songs' => [
368
+ { 'title' => 'Broken' },
369
+ { 'title' => 'Resist Stance' },
370
+ { 'title' => 'Rime Of The Ancient Mariner' }
371
+ ]
372
+ )
373
+
374
+ assert_equal 3, form.songs.size
375
+
376
+ assert form.validate(
377
+ 'songs' => [
378
+ { 'title' => 'Broken', 'delete' => '1' },
379
+ { 'title' => 'Resist Stance' },
380
+ { 'title' => 'Rime Of The Ancient Mariner' }
381
+ ]
382
+ )
383
+ assert_equal 2, form.songs.size
384
+ assert_equal 'Resist Stance', form.songs.first.title
385
+ assert_equal 'Rime Of The Ancient Mariner', form.songs.last.title
269
386
  end
270
387
  end
@@ -4,14 +4,14 @@ class PopulatorSkipTest < MiniTest::Spec
4
4
  Album = Struct.new(:songs)
5
5
  Song = Struct.new(:title)
6
6
 
7
+ class AlbumForm < TestForm
8
+ collection :songs, populator: :my_populator do
9
+ property :title
10
+ end
7
11
 
8
- class AlbumForm < Reform::Form
9
- collection :songs,
10
- populator: ->(options) {
11
- return skip! if options[:fragment][:title] == "Good"
12
- songs[options[:index]]
13
- } do
14
- property :title
12
+ def my_populator(options)
13
+ return skip! if options[:fragment][:title] == "Good"
14
+ songs[options[:index]]
15
15
  end
16
16
  end
17
17
 
@@ -21,8 +21,8 @@ class PopulatorSkipTest < MiniTest::Spec
21
21
 
22
22
  form.validate(hash)
23
23
 
24
- form.songs.size.must_equal 2
25
- form.songs[0].title.must_equal nil
26
- form.songs[1].title.must_equal "Bad"
24
+ assert_equal form.songs.size, 2
25
+ assert_nil form.songs[0].title
26
+ assert_equal form.songs[1].title, "Bad"
27
27
  end
28
- end
28
+ end
@@ -1,17 +1,17 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class PrepopulatorTest < MiniTest::Spec
4
4
  Song = Struct.new(:title, :band, :length)
5
5
  Band = Struct.new(:name)
6
6
 
7
- class AlbumForm < Reform::Form
8
- property :title, prepopulator: ->(*){ self.title = "Another Day At Work" } # normal assignment.
7
+ class AlbumForm < TestForm
8
+ property :title, prepopulator: ->(*) { self.title = "Another Day At Work" } # normal assignment.
9
9
  property :length
10
10
 
11
11
  property :hit, prepopulator: ->(options) { self.hit = Song.new(options[:title]) } do # use user options.
12
12
  property :title
13
13
 
14
- property :band, prepopulator: ->(options){ self.band = my_band(options[:title]) } do # invoke your own code.
14
+ property :band, prepopulator: ->(options) { self.band = my_band(options[:title]) } do # invoke your own code.
15
15
  property :name
16
16
  end
17
17
 
@@ -24,7 +24,7 @@ class PrepopulatorTest < MiniTest::Spec
24
24
  property :title
25
25
  end
26
26
 
27
- private
27
+ private
28
28
  def prepopulate_songs!(options)
29
29
  if songs == nil
30
30
  self.songs = [Song.new, Song.new]
@@ -37,25 +37,25 @@ class PrepopulatorTest < MiniTest::Spec
37
37
  it do
38
38
  form = AlbumForm.new(OpenStruct.new(length: 1)).prepopulate!(title: "Potemkin City Limits")
39
39
 
40
- form.length.must_equal 1
41
- form.title.must_equal "Another Day At Work"
42
- form.hit.model.must_equal Song.new("Potemkin City Limits")
43
- form.songs.size.must_equal 2
44
- form.songs[0].model.must_equal Song.new
45
- form.songs[1].model.must_equal Song.new
46
- form.songs[1].model.must_equal Song.new
40
+ assert_equal form.length, 1
41
+ assert_equal form.title, "Another Day At Work"
42
+ assert_equal form.hit.model, Song.new("Potemkin City Limits")
43
+ assert_equal form.songs.size, 2
44
+ assert_equal form.songs[0].model, Song.new
45
+ assert_equal form.songs[1].model, Song.new
46
+ assert_equal form.songs[1].model, Song.new
47
47
  # prepopulate works more than 1 level, recursive.
48
48
  # it also passes options properly down there.
49
- form.hit.band.model.must_equal Band.new("Potemkin City Limits")
49
+ assert_equal form.hit.band.model, Band.new("Potemkin City Limits")
50
50
  end
51
51
 
52
52
  # add to existing collection.
53
53
  it do
54
- form = AlbumForm.new(OpenStruct.new(songs: [Song.new])).prepopulate!
54
+ form = AlbumForm.new(OpenStruct.new(songs: [Song.new])).prepopulate!(title: "Potemkin City Limits")
55
55
 
56
- form.songs.size.must_equal 2
57
- form.songs[0].model.must_equal Song.new
58
- form.songs[1].model.must_equal Song.new
56
+ assert_equal form.songs.size, 2
57
+ assert_equal form.songs[0].model, Song.new
58
+ assert_equal form.songs[1].model, Song.new
59
59
  end
60
60
  end
61
61
 
@@ -63,7 +63,7 @@ end
63
63
  class PrepopulateWithoutConfiguration < MiniTest::Spec
64
64
  Song = Struct.new(:title)
65
65
 
66
- class AlbumForm < Reform::Form
66
+ class AlbumForm < TestForm
67
67
  collection :songs do
68
68
  property :title
69
69
  end
@@ -75,15 +75,14 @@ class PrepopulateWithoutConfiguration < MiniTest::Spec
75
75
 
76
76
  subject { AlbumForm.new(OpenStruct.new(songs: [], hit: nil)).prepopulate! }
77
77
 
78
- it { subject.songs.size.must_equal 0 }
78
+ it { assert_equal subject.songs.size, 0 }
79
79
  end
80
80
 
81
-
82
81
  class ManualPrepopulatorOverridingTest < MiniTest::Spec
83
82
  Song = Struct.new(:title, :band, :length)
84
83
  Band = Struct.new(:name)
85
84
 
86
- class AlbumForm < Reform::Form
85
+ class AlbumForm < TestForm
87
86
  property :title
88
87
  property :length
89
88
 
@@ -105,8 +104,8 @@ class ManualPrepopulatorOverridingTest < MiniTest::Spec
105
104
  it do
106
105
  form = AlbumForm.new(OpenStruct.new(length: 1)).prepopulate!(title: "Potemkin City Limits")
107
106
 
108
- form.length.must_equal 1
109
- form.hit.model.must_equal Song.new("Potemkin City Limits")
110
- form.hit.title.must_equal "Potemkin City Limits"
107
+ assert_equal form.length, 1
108
+ assert_equal form.hit.model, Song.new("Potemkin City Limits")
109
+ assert_equal form.hit.title, "Potemkin City Limits"
111
110
  end
112
- end
111
+ end
@@ -1,3 +1,14 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
+ class ReadonlyTest < MiniTest::Spec
4
+ class SongForm < TestForm
5
+ property :artist
6
+ property :title, writeable: false
7
+ # TODO: what to do with virtual values?
8
+ end
3
9
 
10
+ let(:form) { SongForm.new(OpenStruct.new) }
11
+
12
+ it { refute form.readonly?(:artist) }
13
+ it { assert form.readonly?(:title) }
14
+ end