reform 2.3.3 → 2.5.0

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/.travis.yml +0 -3
  4. data/CHANGES.md +9 -0
  5. data/Gemfile +1 -1
  6. data/LICENSE.txt +1 -1
  7. data/README.md +5 -5
  8. data/Rakefile +1 -12
  9. data/lib/reform/contract/validate.rb +1 -1
  10. data/lib/reform/form/dry.rb +47 -9
  11. data/lib/reform/validation/groups.rb +0 -1
  12. data/lib/reform/version.rb +1 -1
  13. data/test/call_test.rb +23 -0
  14. data/test/changed_test.rb +6 -6
  15. data/test/coercion_test.rb +17 -17
  16. data/test/{composition_new_api.rb → composition_test.rb} +27 -28
  17. data/test/{contract_new_api.rb → contract_test.rb} +8 -8
  18. data/test/default_test.rb +2 -2
  19. data/test/deserialize_test.rb +8 -8
  20. data/test/docs/validation_test.rb +134 -0
  21. data/test/{errors_new_api.rb → errors_test.rb} +41 -41
  22. data/test/feature_test.rb +2 -2
  23. data/test/fixtures/dry_error_messages.yml +64 -54
  24. data/test/{form_option_new_api.rb → form_option_test.rb} +1 -1
  25. data/test/{form_new_api.rb → form_test.rb} +3 -3
  26. data/test/from_test.rb +10 -10
  27. data/test/{inherit_new_api.rb → inherit_test.rb} +17 -17
  28. data/test/{module_new_api.rb → module_test.rb} +10 -10
  29. data/test/parse_option_test.rb +7 -7
  30. data/test/parse_pipeline_test.rb +1 -1
  31. data/test/{populate_new_api.rb → populate_test.rb} +112 -53
  32. data/test/populator_skip_test.rb +2 -2
  33. data/test/prepopulator_test.rb +15 -15
  34. data/test/read_only_test.rb +2 -2
  35. data/test/readable_test.rb +3 -3
  36. data/test/{reform_new_api.rb → reform_test.rb} +19 -19
  37. data/test/{save_new_api.rb → save_test.rb} +4 -4
  38. data/test/setup_test.rb +9 -9
  39. data/test/{skip_if_new_api.rb → skip_if_test.rb} +12 -12
  40. data/test/skip_setter_and_getter_test.rb +6 -6
  41. data/test/test_helper.rb +5 -6
  42. data/test/{validate_new_api.rb → validate_test.rb} +65 -78
  43. data/test/validation/{dry_validation_new_api.rb → dry_validation_test.rb} +124 -123
  44. data/test/validation/result_test.rb +14 -14
  45. data/test/virtual_test.rb +7 -7
  46. data/test/writeable_test.rb +8 -8
  47. metadata +35 -68
  48. data/Appraisals +0 -8
  49. data/gemfiles/0.13.0.gemfile +0 -8
  50. data/gemfiles/1.5.0.gemfile +0 -9
  51. data/lib/reform/form/dry/new_api.rb +0 -45
  52. data/lib/reform/form/dry/old_api.rb +0 -61
  53. data/test/call_new_api.rb +0 -23
  54. data/test/call_old_api.rb +0 -23
  55. data/test/composition_old_api.rb +0 -184
  56. data/test/contract_old_api.rb +0 -77
  57. data/test/errors_old_api.rb +0 -230
  58. data/test/fixtures/dry_new_api_error_messages.yml +0 -104
  59. data/test/form_old_api.rb +0 -57
  60. data/test/form_option_old_api.rb +0 -24
  61. data/test/inherit_old_api.rb +0 -105
  62. data/test/module_old_api.rb +0 -146
  63. data/test/populate_old_api.rb +0 -304
  64. data/test/reform_old_api.rb +0 -202
  65. data/test/save_old_api.rb +0 -101
  66. data/test/skip_if_old_api.rb +0 -92
  67. data/test/validate_old_api.rb +0 -410
  68. data/test/validation/dry_validation_old_api.rb +0 -772
@@ -17,7 +17,7 @@ class FormOptionTest < MiniTest::Spec
17
17
 
18
18
  it do
19
19
  form = AlbumForm.new(Album.new(Song.new("When It Comes To You")))
20
- _(form.song.title).must_equal "When It Comes To You"
20
+ assert_equal "When It Comes To You", form.song.title
21
21
 
22
22
  form.validate(song: {title: "Run For Cover"})
23
23
  end
@@ -25,8 +25,8 @@ class FormTest < MiniTest::Spec
25
25
  let(:cloned) { AlbumForm.clone }
26
26
 
27
27
  # #dup is called in Op.inheritable_attr(:contract_class), it must be subclass of the original one.
28
- it { _(cloned).wont_equal AlbumForm }
29
- it { _(AlbumForm.definitions).wont_equal cloned.definitions }
28
+ it { refute_equal cloned, AlbumForm }
29
+ it { refute_equal AlbumForm.definitions, cloned.definitions }
30
30
 
31
31
  it do
32
32
  # currently, forms need a name for validation, even without AM.
@@ -51,7 +51,7 @@ class FormTest < MiniTest::Spec
51
51
  end
52
52
 
53
53
  it "allows injecting :virtual options" do
54
- _(ArtistForm.new(Artist.new, current_user: Object).current_user).must_equal Object
54
+ assert_equal ArtistForm.new(Artist.new, current_user: Object).current_user, Object
55
55
  end
56
56
  end
57
57
  end
data/test/from_test.rb CHANGED
@@ -31,19 +31,19 @@ class AsTest < BaseTest
31
31
 
32
32
  subject { AlbumForm.new(Album.new("Best Of", hit, [Song.new("Fallout"), song2])) }
33
33
 
34
- it { _(subject.name).must_equal "Best Of" }
35
- it { _(subject.single.title).must_equal "Roxanne" }
36
- it { _(subject.tracks[0].name).must_equal "Fallout" }
37
- it { _(subject.tracks[1].name).must_equal "Roxanne" }
34
+ it { assert_equal subject.name, "Best Of" }
35
+ it { assert_equal subject.single.title, "Roxanne" }
36
+ it { assert_equal subject.tracks[0].name, "Fallout" }
37
+ it { assert_equal subject.tracks[1].name, "Roxanne" }
38
38
 
39
39
  describe "#validate" do
40
40
 
41
41
  before { subject.validate(params) }
42
42
 
43
- it { _(subject.name).must_equal "Best Of The Police" }
44
- it { _(subject.single.title).must_equal "So Lonely" }
45
- it { _(subject.tracks[0].name).must_equal "Message In A Bottle" }
46
- it { _(subject.tracks[1].name).must_equal "Roxanne" }
43
+ it { assert_equal subject.name, "Best Of The Police" }
44
+ it { assert_equal subject.single.title, "So Lonely" }
45
+ it { assert_equal subject.tracks[0].name, "Message In A Bottle" }
46
+ it { assert_equal subject.tracks[1].name, "Roxanne" }
47
47
  end
48
48
 
49
49
  describe "#sync" do
@@ -52,7 +52,7 @@ class AsTest < BaseTest
52
52
  subject.sync
53
53
  end
54
54
 
55
- it { _(song2.title).must_equal "Livin' Ain't No Crime" }
55
+ it { assert_equal song2.title, "Livin' Ain't No Crime" }
56
56
  end
57
57
 
58
58
  describe "#save (nested hash)" do
@@ -65,7 +65,7 @@ class AsTest < BaseTest
65
65
  hash = nested_hash
66
66
  end
67
67
 
68
- _(hash).must_equal({"title" => "Best Of The Police", "hit" => {"title" => "So Lonely"}, "songs" => [{"title" => "Message In A Bottle"}, {"title" => "Roxanne"}], "band" => nil})
68
+ assert_equal hash, "title" => "Best Of The Police", "hit" => {"title" => "So Lonely"}, "songs" => [{"title" => "Message In A Bottle"}, {"title" => "Roxanne"}], "band" => nil
69
69
  end
70
70
  end
71
71
  end
@@ -52,46 +52,46 @@ class InheritTest < BaseTest
52
52
 
53
53
  it do
54
54
  subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
55
- _(subject.hit.title).must_equal "LA Drone"
56
- _(subject.hit.rating).must_equal 10
57
- _(subject.errors.messages).must_equal({})
55
+ assert_equal subject.hit.title, "LA Drone"
56
+ assert_equal subject.hit.rating, 10
57
+ assert_equal subject.errors.messages, {}
58
58
  end
59
59
 
60
60
  it do
61
61
  subject.validate({})
62
62
  assert_nil subject.model.hit.title
63
63
  assert_nil subject.model.hit.rating
64
- _(subject.errors.messages).must_equal("hit.title": ["must be filled"], "hit.rating": ["must be filled"])
64
+ assert_equal subject.errors.messages, "hit.title": ["must be filled"], "hit.rating": ["must be filled"]
65
65
  end
66
66
 
67
67
  it "xxx" do
68
68
  # sub hashes like :deserializer must be properly cloned when inheriting.
69
- _(AlbumForm.options_for(:title)[:deserializer].object_id).wont_equal CompilationForm.options_for(:title)[:deserializer].object_id
69
+ refute_equal AlbumForm.options_for(:title)[:deserializer].object_id, CompilationForm.options_for(:title)[:deserializer].object_id
70
70
 
71
71
  # don't overwrite direct deserializer: {} configuration.
72
- _(AlbumForm.options_for(:title)[:internal_populator]).must_be_instance_of Reform::Form::Populator::Sync
73
- _(AlbumForm.options_for(:title)[:deserializer][:skip_parse]).must_equal "skip_if in AlbumForm"
72
+ assert AlbumForm.options_for(:title)[:internal_populator].is_a? Reform::Form::Populator::Sync
73
+ assert_equal AlbumForm.options_for(:title)[:deserializer][:skip_parse], "skip_if in AlbumForm"
74
74
 
75
75
  # AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
76
76
  # AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
77
77
 
78
- _(AlbumForm.options_for(:songs)[:internal_populator]).must_be_instance_of Reform::Form::Populator::IfEmpty
79
- _(AlbumForm.options_for(:songs)[:deserializer][:skip_parse]).must_be_instance_of Reform::Form::Validate::Skip::AllBlank
78
+ assert AlbumForm.options_for(:songs)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
79
+ assert AlbumForm.options_for(:songs)[:deserializer][:skip_parse].is_a? Reform::Form::Validate::Skip::AllBlank
80
80
 
81
- _(AlbumForm.options_for(:band)[:internal_populator]).must_be_instance_of Reform::Form::Populator::IfEmpty
81
+ assert AlbumForm.options_for(:band)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
82
82
 
83
- _(CompilationForm.options_for(:title)[:deserializer][:skip_parse]).must_equal "skip_if from CompilationForm"
83
+ assert_equal CompilationForm.options_for(:title)[:deserializer][:skip_parse], "skip_if from CompilationForm"
84
84
  # pp CompilationForm.options_for(:songs)
85
- _(CompilationForm.options_for(:songs)[:internal_populator]).must_be_instance_of Reform::Form::Populator::IfEmpty
85
+ assert CompilationForm.options_for(:songs)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
86
86
 
87
- _(CompilationForm.options_for(:band)[:internal_populator]).must_be_instance_of Reform::Form::Populator::IfEmpty
87
+ assert CompilationForm.options_for(:band)[:internal_populator].is_a? Reform::Form::Populator::IfEmpty
88
88
 
89
89
  # completely overwrite inherited.
90
- _(CompilationForm.options_for(:hit)[:deserializer][:skip_parse]).must_be_instance_of SkipParse
90
+ assert CompilationForm.options_for(:hit)[:deserializer][:skip_parse].is_a? SkipParse
91
91
 
92
92
  # inherit: true with block will still inherit the original class.
93
- _(AlbumForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id).must_equal 1
94
- _(CompilationForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id).must_equal 1
93
+ assert_equal AlbumForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id, 1
94
+ assert_equal CompilationForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id, 1
95
95
  end
96
96
 
97
97
  class CDForm < AlbumForm
@@ -101,5 +101,5 @@ class InheritTest < BaseTest
101
101
  end
102
102
  end
103
103
 
104
- it { _(CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc)).must_equal "CD Populator" }
104
+ it { assert_equal CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc), "CD Populator" }
105
105
  end
@@ -25,8 +25,8 @@ class ModuleInclusionTest < MiniTest::Spec
25
25
  params { required(:band).filled }
26
26
  end
27
27
 
28
- include Dry::Types.module # allows using Types::* in module.
29
- property :cool, type: DRY_TYPES_CONSTANT::Bool # test coercion.
28
+ include Dry.Types(default: :nominal) # allows using Types::* in module.
29
+ property :cool, type: Types::Params::Bool # test coercion.
30
30
  end
31
31
 
32
32
  # TODO: test if works, move stuff into inherit_schema!
@@ -60,24 +60,24 @@ class ModuleInclusionTest < MiniTest::Spec
60
60
  let(:song) { OpenStruct.new(band: OpenStruct.new(title: "Time Again")) }
61
61
 
62
62
  # nested form from module is present and creates accessor.
63
- it { _(SongForm.new(song).band.title).must_equal "Time Again" }
63
+ it { assert_equal SongForm.new(song).band.title, "Time Again" }
64
64
 
65
65
  # methods from module get included.
66
- it { _(SongForm.new(song).id).must_equal 1 }
67
- it { _(SongForm.new(song).band.id).must_equal 2 }
66
+ it { assert_equal SongForm.new(song).id, 1 }
67
+ it { assert_equal SongForm.new(song).band.id, 2 }
68
68
 
69
69
  # validators get inherited.
70
70
  it do
71
71
  form = SongForm.new(OpenStruct.new)
72
72
  form.validate({})
73
- _(form.errors.messages).must_equal(band: ["must be filled"])
73
+ assert_equal form.errors.messages, band: ["must be filled"]
74
74
  end
75
75
 
76
76
  # coercion works
77
77
  it do
78
78
  form = SongForm.new(OpenStruct.new)
79
79
  form.validate(cool: "1")
80
- _(form.cool).must_equal true
80
+ assert form.cool
81
81
  end
82
82
 
83
83
  # include a module into a module into a class :)
@@ -106,7 +106,7 @@ class ModuleInclusionTest < MiniTest::Spec
106
106
  it do
107
107
  form = AlbumForm.new(OpenStruct.new(band: OpenStruct.new))
108
108
  form.validate("band" => {})
109
- _(form.errors.messages).must_equal("band.title": ["must be filled"], "band.label": ["must be filled"], name: ["must be filled"])
109
+ assert_equal form.errors.messages, "band.title": ["must be filled"], "band.label": ["must be filled"], name: ["must be filled"]
110
110
  end
111
111
 
112
112
  describe "module with custom accessors" do
@@ -130,8 +130,8 @@ class ModuleInclusionTest < MiniTest::Spec
130
130
  let(:song) { OpenStruct.new(id: 1, title: "Instant Mash") }
131
131
 
132
132
  it do
133
- _(IncludingSongForm.new(song).id).must_equal 1
134
- _(IncludingSongForm.new(song).title).must_equal "INSTANT MASH"
133
+ assert_equal IncludingSongForm.new(song).id, 1
134
+ assert_equal IncludingSongForm.new(song).title, "INSTANT MASH"
135
135
  end
136
136
  end
137
137
  end
@@ -13,13 +13,13 @@ class ParseOptionTest < MiniTest::Spec
13
13
  let(:form) { CommentForm.new(Comment.new, user: current_user) }
14
14
 
15
15
  it do
16
- _(form.user).must_equal current_user
16
+ assert_equal form.user, current_user
17
17
 
18
18
  lorem = "Lorem ipsum dolor sit amet..."
19
19
  form.validate("content" => lorem, "user" => "not the current user")
20
20
 
21
- _(form.content).must_equal lorem
22
- _(form.user).must_equal current_user
21
+ assert_equal form.content, lorem
22
+ assert_equal form.user, current_user
23
23
  end
24
24
 
25
25
  describe "using ':parse' option doesn't override other ':deserialize' options" do
@@ -30,11 +30,11 @@ class ParseOptionTest < MiniTest::Spec
30
30
  end
31
31
 
32
32
  it do
33
- _(ArticleCommentForm.definitions.get(:user)[:deserializer][:writeable]).must_equal false
34
- _(ArticleCommentForm.definitions.get(:user)[:deserializer][:instance]).must_equal "Instance"
33
+ assert_equal ArticleCommentForm.definitions.get(:user)[:deserializer][:writeable], false
34
+ assert_equal ArticleCommentForm.definitions.get(:user)[:deserializer][:instance], "Instance"
35
35
 
36
- _(ArticleCommentForm.definitions.get(:article)[:deserializer][:writeable]).must_equal true
37
- _(ArticleCommentForm.definitions.get(:article)[:deserializer][:instance]).must_equal "Instance"
36
+ assert ArticleCommentForm.definitions.get(:article)[:deserializer][:writeable]
37
+ assert_equal ArticleCommentForm.definitions.get(:article)[:deserializer][:instance], "Instance"
38
38
  end
39
39
  end
40
40
  end
@@ -10,6 +10,6 @@ class ParsePipelineTest < MiniTest::Spec
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
15
  end
@@ -48,7 +48,7 @@ class PopulatorTest < MiniTest::Spec
48
48
  "name" => "override me!"
49
49
  )
50
50
 
51
- _(form.name).must_equal "!em edirrevo"
51
+ assert_equal form.name, "!em edirrevo"
52
52
  end
53
53
 
54
54
  # changing existing property :artist.
@@ -60,7 +60,7 @@ class PopulatorTest < MiniTest::Spec
60
60
  "artist" => {"name" => "Marcus Miller"}
61
61
  )
62
62
 
63
- _(form.artist.model.object_id).must_equal old_id
63
+ assert_equal form.artist.model.object_id, old_id
64
64
  end
65
65
 
66
66
  # use populator for default value on scalars?
@@ -68,36 +68,36 @@ class PopulatorTest < MiniTest::Spec
68
68
  # adding to collection via :populator.
69
69
  # valid.
70
70
  it "yyy" do
71
- _(form.validate(
71
+ assert form.validate(
72
72
  "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
73
73
  {"title" => "Rime Of The Ancient Mariner"}, # new song.
74
74
  {"title" => "Re-Education", "composer" => {"name" => "Rise Against"}}], # new song with new composer.
75
- )).must_equal true
75
+ )
76
76
 
77
- _(form.errors.messages.inspect).must_equal "{}"
77
+ assert_equal form.errors.messages.inspect, "{}"
78
78
 
79
79
  # form has updated.
80
- _(form.name).must_equal "The Dissent Of Man"
81
- _(form.songs[0].title).must_equal "Fallout"
82
- _(form.songs[1].title).must_equal "Roxanne"
83
- _(form.songs[1].composer.name).must_equal "Greg Graffin"
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"
84
84
 
85
- _(form.songs[1].composer.model).must_be_instance_of Artist
85
+ form.songs[1].composer.model.is_a? Artist
86
86
 
87
- _(form.songs[1].title).must_equal "Roxanne"
88
- _(form.songs[2].title).must_equal "Rime Of The Ancient Mariner" # new song added.
89
- _(form.songs[3].title).must_equal "Re-Education"
90
- _(form.songs[3].composer.name).must_equal "Rise Against"
91
- _(form.songs.size).must_equal 4
92
- _(form.artist.name).must_equal "Bad Religion"
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"
93
93
 
94
94
  # model has not changed, yet.
95
- _(album.name).must_equal "The Dissent Of Man"
96
- _(album.songs[0].title).must_equal "Broken"
97
- _(album.songs[1].title).must_equal "Resist Stance"
98
- _(album.songs[1].composer.name).must_equal "Greg Graffin"
99
- _(album.songs.size).must_equal 2
100
- _(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"
101
101
  end
102
102
  end
103
103
 
@@ -117,7 +117,7 @@ class PopulateWithMethodTest < Minitest::Spec
117
117
  it "runs populator method" do
118
118
  form.validate("title" => "override me!")
119
119
 
120
- _(form.title).must_equal "!em edirrevo"
120
+ assert_equal form.title, "!em edirrevo"
121
121
  end
122
122
  end
123
123
 
@@ -141,7 +141,7 @@ class PopulateWithCallableTest < Minitest::Spec
141
141
  it "runs populator method" do
142
142
  form.validate("title" => "override me!")
143
143
 
144
- _(form.title).must_equal "!em edirrevo"
144
+ assert_equal form.title, "!em edirrevo"
145
145
  end
146
146
  end
147
147
 
@@ -161,7 +161,7 @@ class PopulateWithProcTest < Minitest::Spec
161
161
  it "runs populator method" do
162
162
  form.validate("title" => "override me!")
163
163
 
164
- _(form.title).must_equal "!em edirrevo"
164
+ assert_equal form.title, "!em edirrevo"
165
165
  end
166
166
  end
167
167
 
@@ -216,35 +216,35 @@ class PopulateIfEmptyTest < MiniTest::Spec
216
216
  let(:form) { AlbumForm.new(album) }
217
217
 
218
218
  it do
219
- _(form.songs.size).must_equal 2
219
+ assert_equal form.songs.size, 2
220
220
 
221
- _(form.validate(
221
+ assert form.validate(
222
222
  "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
223
223
  {"title" => "Rime Of The Ancient Mariner"}, # new song.
224
224
  {"title" => "Re-Education", "composer" => {"name" => "Rise Against"}}], # new song with new composer.
225
- )).must_equal true
225
+ )
226
226
 
227
- _(form.errors.messages.inspect).must_equal "{}"
227
+ assert_equal form.errors.messages.inspect, "{}"
228
228
 
229
229
  # form has updated.
230
- _(form.name).must_equal "The Dissent Of Man"
231
- _(form.songs[0].title).must_equal "Fallout"
232
- _(form.songs[1].title).must_equal "Roxanne"
233
- _(form.songs[1].composer.name).must_equal "Greg Graffin"
234
- _(form.songs[1].title).must_equal "Roxanne"
235
- _(form.songs[2].title).must_equal "Rime Of The Ancient Mariner" # new song added.
236
- _(form.songs[3].title).must_equal "Re-Education"
237
- _(form.songs[3].composer.name).must_equal "Rise Against"
238
- _(form.songs.size).must_equal 4
239
- _(form.artist.name).must_equal "Bad Religion"
230
+ assert_equal form.name, "The Dissent Of Man"
231
+ assert_equal form.songs[0].title, "Fallout"
232
+ assert_equal form.songs[1].title, "Roxanne"
233
+ assert_equal form.songs[1].composer.name, "Greg Graffin"
234
+ assert_equal form.songs[1].title, "Roxanne"
235
+ assert_equal form.songs[2].title, "Rime Of The Ancient Mariner" # new song added.
236
+ assert_equal form.songs[3].title, "Re-Education"
237
+ assert_equal form.songs[3].composer.name, "Rise Against"
238
+ assert_equal form.songs.size, 4
239
+ assert_equal form.artist.name, "Bad Religion"
240
240
 
241
241
  # model has not changed, yet.
242
- _(album.name).must_equal "The Dissent Of Man"
243
- _(album.songs[0].title).must_equal "Broken"
244
- _(album.songs[1].title).must_equal "Resist Stance"
245
- _(album.songs[1].composer.name).must_equal "Greg Graffin"
246
- _(album.songs.size).must_equal 2
247
- _(album.artist.name).must_equal "Bad Religion"
242
+ assert_equal album.name, "The Dissent Of Man"
243
+ assert_equal album.songs[0].title, "Broken"
244
+ assert_equal album.songs[1].title, "Resist Stance"
245
+ assert_equal album.songs[1].composer.name, "Greg Graffin"
246
+ assert_equal album.songs.size, 2
247
+ assert_equal album.artist.name, "Bad Religion"
248
248
  end
249
249
 
250
250
  # trigger artist populator. lambda calling form instance method.
@@ -252,11 +252,11 @@ class PopulateIfEmptyTest < MiniTest::Spec
252
252
  form = AlbumForm.new(album = Album.new)
253
253
  form.validate("artist" => {"name" => "From Autumn To Ashes"})
254
254
 
255
- _(form.artist.name).must_equal "From Autumn To Ashes"
255
+ assert_equal form.artist.name, "From Autumn To Ashes"
256
256
  # test lambda was executed in form context.
257
- _(form.artist.model).must_be_instance_of AlbumForm::Sting
257
+ assert form.artist.model.is_a? AlbumForm::Sting
258
258
  # test lambda block arguments.
259
- _(form.artist.model.args.to_s).must_equal "[{\"name\"=>\"From Autumn To Ashes\"}, nil]"
259
+ assert_equal form.artist.model.args.to_s, "[{\"name\"=>\"From Autumn To Ashes\"}, nil]"
260
260
 
261
261
  assert_nil album.artist
262
262
  end
@@ -292,13 +292,72 @@ class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
292
292
  let(:form) { AlbumForm.new(album) }
293
293
 
294
294
  it do
295
- _(form.validate(
295
+ assert form.validate(
296
296
  "songs" => [{"title" => "Broken, delete me!"}, {"title" => "Roxanne"}]
297
- )).must_equal true
297
+ )
298
+
299
+ assert_equal form.errors.messages.inspect, "{}"
300
+
301
+ assert_equal form.songs.size, 1
302
+ assert_equal form.songs[0].title, "Roxanne"
303
+ end
304
+ end
305
+
306
+ class PopulateWithFormKeyTest < MiniTest::Spec
307
+ Song = Struct.new(:title, :album, :composer)
308
+ Album = Struct.new(:name, :songs, :artist)
309
+
310
+ let(:song) { Song.new('Broken') }
311
+ let(:song2) { Song.new('Resist Stance') }
312
+ let(:album) { Album.new('The Dissent Of Man', [song, song2]) }
313
+
314
+ class SongForm < TestForm
315
+ property :title
316
+
317
+ validation do
318
+ params { required(:title).filled }
319
+ end
320
+ end
321
+
322
+ class AlbumForm < TestForm
323
+ property :name
298
324
 
299
- _(form.errors.messages.inspect).must_equal "{}"
325
+ collection :songs, form: SongForm, populator: :populator!, model_identifier: :title
326
+
327
+ def populator!(fragment:, **)
328
+ item = songs.find { |song| song.title == fragment['title'] }
329
+ if item && fragment['delete'] == '1'
330
+ songs.delete(item)
331
+ return skip!
332
+ end
333
+ item || songs.append(Song.new)
334
+ end
335
+ end
300
336
 
301
- _(form.songs.size).must_equal 1
302
- _(form.songs[0].title).must_equal "Roxanne"
337
+ let(:form) { AlbumForm.new(album) }
338
+
339
+ it do
340
+ assert_equal 2, form.songs.size
341
+
342
+ assert form.validate(
343
+ 'songs' => [
344
+ { 'title' => 'Broken' },
345
+ { 'title' => 'Resist Stance' },
346
+ { 'title' => 'Rime Of The Ancient Mariner' }
347
+ ]
348
+ )
349
+
350
+ assert_equal 3, form.songs.size
351
+
352
+ assert form.validate(
353
+ 'songs' => [
354
+ { 'title' => 'Broken', 'delete' => '1' },
355
+ { 'title' => 'Resist Stance' },
356
+ { 'title' => 'Rime Of The Ancient Mariner' }
357
+ ]
358
+ )
359
+ assert_equal 2, form.songs.size
360
+ assert_equal 'Resist Stance', form.songs.first.title
361
+ assert_equal 'Rime Of The Ancient Mariner', form.songs.last.title
303
362
  end
304
363
  end