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
@@ -1,30 +1,30 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class ReadableTest < MiniTest::Spec
4
4
  Credentials = Struct.new(:password)
5
5
 
6
- class PasswordForm < Reform::Form
6
+ class PasswordForm < TestForm
7
7
  property :password, readable: false
8
8
  end
9
9
 
10
- let (:cred) { Credentials.new }
11
- let (:form) { PasswordForm.new(cred) }
10
+ let(:cred) { Credentials.new }
11
+ let(:form) { PasswordForm.new(cred) }
12
12
 
13
13
  it {
14
- form.password.must_equal nil # password not read.
14
+ assert_nil form.password # password not read.
15
15
 
16
16
  form.validate("password" => "123")
17
17
 
18
- form.password.must_equal "123"
18
+ assert_equal form.password, "123"
19
19
 
20
20
  form.sync
21
- cred.password.must_equal "123" # password written.
21
+ assert_equal cred.password, "123" # password written.
22
22
 
23
23
  hash = {}
24
24
  form.save do |nested|
25
25
  hash = nested
26
26
  end
27
27
 
28
- hash.must_equal("password"=> "123")
28
+ assert_equal hash, "password" => "123"
29
29
  }
30
- end
30
+ end
data/test/reform_test.rb CHANGED
@@ -1,47 +1,46 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
- # TODO: this test should be removed.
4
3
  class ReformTest < Minitest::Spec
5
- let (:comp) { OpenStruct.new(:name => "Duran Duran", :title => "Rio") }
4
+ let(:comp) { OpenStruct.new(name: "Duran Duran", title: "Rio") }
6
5
 
7
- let (:form) { SongForm.new(comp) }
6
+ let(:form) { SongForm.new(comp) }
8
7
 
9
- class SongForm < Reform::Form
8
+ class SongForm < TestForm
10
9
  property :name
11
10
  property :title
12
11
 
13
12
  validation do
14
- key(:name).required
13
+ params { required(:name).filled }
15
14
  end
16
15
  end
17
16
 
18
17
  describe "(new) form with empty models" do
19
- let (:comp) { OpenStruct.new }
18
+ let(:comp) { OpenStruct.new }
20
19
 
21
20
  it "returns empty fields" do
22
- form.title.must_equal nil
23
- form.name.must_equal nil
21
+ assert_nil form.title
22
+ assert_nil form.name
24
23
  end
25
24
 
26
25
  describe "and submitted values" do
27
26
  it "returns filled-out fields" do
28
27
  form.validate("name" => "Duran Duran")
29
28
 
30
- form.title.must_equal nil
31
- form.name.must_equal "Duran Duran"
29
+ assert_nil form.title
30
+ assert_equal form.name, "Duran Duran"
32
31
  end
33
32
  end
34
33
  end
35
34
 
36
35
  describe "(edit) form with existing models" do
37
36
  it "returns filled-out fields" do
38
- form.name.must_equal "Duran Duran"
39
- form.title.must_equal "Rio"
37
+ assert_equal form.name, "Duran Duran"
38
+ assert_equal form.title, "Rio"
40
39
  end
41
40
  end
42
41
 
43
42
  describe "#validate" do
44
- let (:comp) { OpenStruct.new }
43
+ let(:comp) { OpenStruct.new }
45
44
 
46
45
  it "ignores unmapped fields in input" do
47
46
  form.validate("name" => "Duran Duran", :genre => "80s")
@@ -51,71 +50,58 @@ class ReformTest < Minitest::Spec
51
50
  end
52
51
 
53
52
  it "returns true when valid" do
54
- form.validate("name" => "Duran Duran").must_equal true
53
+ assert_equal form.validate("name" => "Duran Duran"), true
55
54
  end
56
55
 
57
56
  it "exposes input via property accessors" do
58
57
  form.validate("name" => "Duran Duran")
59
58
 
60
- form.name.must_equal "Duran Duran"
59
+ assert_equal form.name, "Duran Duran"
61
60
  end
62
61
 
63
62
  it "doesn't change model properties" do
64
63
  form.validate("name" => "Duran Duran")
65
64
 
66
- comp.name.must_equal nil # don't touch model, yet.
65
+ assert_nil comp.name # don't touch model, yet.
67
66
  end
68
67
 
69
68
  # TODO: test errors. test valid.
70
69
  describe "invalid input" do
71
- class ValidatingForm < Reform::Form
70
+ class ValidatingForm < TestForm
72
71
  property :name
73
72
  property :title
74
73
 
75
74
  validation do
76
- key(:name).required
77
- key(:title).required
75
+ params do
76
+ required(:name).filled
77
+ required(:title).filled
78
+ end
78
79
  end
79
80
  end
80
- let (:form) { ValidatingForm.new(comp) }
81
+ let(:form) { ValidatingForm.new(comp) }
81
82
 
82
83
  it "returns false when invalid" do
83
- form.validate({}).must_equal false
84
+ assert_equal form.validate({}), false
84
85
  end
85
86
 
86
87
  it "populates errors" do
87
88
  form.validate({})
88
- form.errors.messages.must_equal({:name=>["is missing"], :title=>["is missing"]})
89
+ assert_equal form.errors.messages, name: ["must be filled"], title: ["must be filled"]
89
90
  end
90
91
  end
91
92
  end
92
93
 
93
- # FIXME: add this test to reform-rails.
94
- describe "#errors" do
95
- before { form.validate({})}
96
-
97
- it { form.errors.must_be_kind_of Reform::Contract::Errors }
98
-
99
- it { form.errors.messages.must_equal({}) }
100
-
101
- it do
102
- form.validate({"name"=>""})
103
- form.errors.messages.must_equal({:name=>["must be filled"]})
104
- end
105
- end
106
-
107
-
108
94
  describe "#save" do
109
- let (:comp) { OpenStruct.new }
110
- let (:form) { SongForm.new(comp) }
95
+ let(:comp) { OpenStruct.new }
96
+ let(:form) { SongForm.new(comp) }
111
97
 
112
98
  before { form.validate("name" => "Diesel Boy") }
113
99
 
114
100
  it "xxpushes data to models" do
115
101
  form.save
116
102
 
117
- comp.name.must_equal "Diesel Boy"
118
- comp.title.must_equal nil
103
+ assert_equal comp.name, "Diesel Boy"
104
+ assert_nil comp.title
119
105
  end
120
106
 
121
107
  describe "#save with block" do
@@ -126,42 +112,39 @@ class ReformTest < Minitest::Spec
126
112
  hash = map
127
113
  end
128
114
 
129
- hash.must_equal({"name"=>"Diesel Boy"})
115
+ assert_equal hash, "name" => "Diesel Boy", "title" => nil
130
116
  end
131
117
  end
132
118
  end
133
119
 
134
-
135
120
  describe "#model" do
136
- it { form.model.must_equal comp }
121
+ it { assert_equal form.model, comp }
137
122
  end
138
123
 
139
-
140
124
  describe "inheritance" do
141
125
  class HitForm < SongForm
142
126
  property :position
143
127
  validation do
144
- key(:position).required
128
+ params { required(:position).filled }
145
129
  end
146
130
  end
147
131
 
148
- let (:form) { HitForm.new(OpenStruct.new()) }
132
+ let(:form) { HitForm.new(OpenStruct.new()) }
149
133
  it do
150
- form.validate({"title" => "The Body"})
151
- form.title.must_equal "The Body"
152
- form.position.must_equal nil
153
- form.errors.messages.must_equal({:name=>["is missing"], :position=>["is missing"]})
134
+ form.validate("title" => "The Body")
135
+ assert_equal form.title, "The Body"
136
+ assert_nil form.position
137
+ assert_equal form.errors.messages, name: ["must be filled"], position: ["must be filled"]
154
138
  end
155
139
  end
156
140
  end
157
141
 
158
-
159
142
  class OverridingAccessorsTest < BaseTest
160
- class SongForm < Reform::Form
143
+ class SongForm < TestForm
161
144
  property :title
162
145
 
163
146
  def title=(v) # used in #validate.
164
- super v*2
147
+ super v * 2
165
148
  end
166
149
 
167
150
  def title # used in #sync.
@@ -169,23 +152,22 @@ class OverridingAccessorsTest < BaseTest
169
152
  end
170
153
  end
171
154
 
172
- let (:song) { Song.new("Pray") }
155
+ let(:song) { Song.new("Pray") }
173
156
  subject { SongForm.new(song) }
174
157
 
175
158
  # override reader for presentation.
176
- it { subject.title.must_equal "pray" }
177
-
159
+ it { assert_equal subject.title, "pray" }
178
160
 
179
161
  describe "#save" do
180
162
  before { subject.validate("title" => "Hey Little World") }
181
163
 
182
164
  # reader always used
183
- it { subject.title.must_equal "hey little worldhey little world" }
165
+ it { assert_equal subject.title, "hey little worldhey little world" }
184
166
 
185
167
  # the reader is not used when saving/syncing.
186
168
  it do
187
169
  subject.save do |hash|
188
- hash["title"].must_equal "Hey Little WorldHey Little World"
170
+ assert_equal hash["title"], "Hey Little WorldHey Little World"
189
171
  end
190
172
  end
191
173
 
@@ -193,14 +175,13 @@ class OverridingAccessorsTest < BaseTest
193
175
  it do
194
176
  song.extend(Saveable)
195
177
  subject.save
196
- song.title.must_equal "Hey Little WorldHey Little World"
178
+ assert_equal song.title, "Hey Little WorldHey Little World"
197
179
  end
198
180
  end
199
181
  end
200
182
 
201
-
202
183
  class MethodInFormTest < MiniTest::Spec
203
- class AlbumForm < Reform::Form
184
+ class AlbumForm < TestForm
204
185
  property :title
205
186
 
206
187
  def title
@@ -217,7 +198,7 @@ class MethodInFormTest < MiniTest::Spec
217
198
  end
218
199
 
219
200
  # methods can be used instead of created accessors.
220
- subject { AlbumForm.new(OpenStruct.new(:hit => OpenStruct.new)) }
221
- it { subject.title.must_equal "The Suffer And The Witness" }
222
- it { subject.hit.title.must_equal "Drones" }
201
+ subject { AlbumForm.new(OpenStruct.new(hit: OpenStruct.new)) }
202
+ it { assert_equal subject.title, "The Suffer And The Witness" }
203
+ it { assert_equal subject.hit.title, "Drones" }
223
204
  end
data/test/save_test.rb CHANGED
@@ -1,26 +1,26 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class SaveTest < BaseTest
4
4
  Song = Struct.new(:title, :album, :composer)
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
10
10
  validation do
11
- key(:name).required
11
+ params { required(:name).filled }
12
12
  end
13
13
 
14
14
  collection :songs do
15
15
  property :title
16
16
  validation do
17
- key(:title).required
17
+ params { required(:title).filled }
18
18
  end
19
19
 
20
20
  property :composer do
21
21
  property :name
22
22
  validation do
23
- key(:name).required
23
+ params { required(:name).filled }
24
24
  end
25
25
  end
26
26
  end
@@ -36,45 +36,57 @@ class SaveTest < BaseTest
36
36
  end
37
37
 
38
38
  def saved?
39
- @saved
39
+ defined?(@saved) && @saved
40
40
  end
41
41
  end
42
42
 
43
+ let(:song) { Song.new("Broken").extend(Saveable) }
44
+ # let(:song_with_composer) { Song.new("Resist Stance", nil, composer).extend(Saveable) }
45
+ let(:composer) { Artist.new("Greg Graffin").extend(Saveable) }
46
+ let(:artist) { Artist.new("Bad Religion").extend(Saveable).extend(Saveable) }
47
+ let(:album) { Album.new("The Dissent Of Man", [song], artist).extend(Saveable) }
43
48
 
44
- let (:song) { Song.new("Broken").extend(Saveable) }
45
- # let (:song_with_composer) { Song.new("Resist Stance", nil, composer).extend(Saveable) }
46
- let (:composer) { Artist.new("Greg Graffin").extend(Saveable) }
47
- let (:artist) { Artist.new("Bad Religion").extend(Saveable).extend(Saveable) }
48
- let (:album) { Album.new("The Dissent Of Man", [song], artist).extend(Saveable) }
49
-
50
- let (:form) { AlbumForm.new(album) }
51
-
49
+ let(:form) { AlbumForm.new(album) }
52
50
 
53
51
  it do
54
52
  form.validate("songs" => [{"title" => "Fixed"}])
55
53
 
56
54
  form.save
57
55
 
58
- album.saved?.must_equal true
59
- album.songs[0].title.must_equal "Fixed"
60
- album.songs[0].saved?.must_equal true
61
- album.artist.saved?.must_equal nil
56
+ assert album.saved?
57
+ assert_equal album.songs[0].title, "Fixed"
58
+ assert album.songs[0].saved?
59
+ assert_nil album.artist.saved?
62
60
  end
63
- end
64
61
 
62
+ describe "#sync with block" do
63
+ it do
64
+ form = AlbumForm.new(Album.new("Greatest Hits"))
65
+
66
+ form.validate(name: nil) # nil-out the title.
67
+
68
+ nested_hash = nil
69
+ form.sync do |hash|
70
+ nested_hash = hash
71
+ end
72
+
73
+ assert_equal nested_hash, "name" => nil, "artist" => nil
74
+ end
75
+ end
76
+ end
65
77
 
66
78
  # class SaveWithDynamicOptionsTest < MiniTest::Spec
67
79
  # Song = Struct.new(:id, :title, :length) do
68
80
  # include Saveable
69
81
  # end
70
82
 
71
- # class SongForm < Reform::Form
83
+ # class SongForm < TestForm
72
84
  # property :title#, save: false
73
85
  # property :length, virtual: true
74
86
  # end
75
87
 
76
- # let (:song) { Song.new }
77
- # let (:form) { SongForm.new(song) }
88
+ # let(:song) { Song.new }
89
+ # let(:form) { SongForm.new(song) }
78
90
 
79
91
  # # we have access to original input value and outside parameters.
80
92
  # it "xxx" do
@@ -83,7 +95,7 @@ end
83
95
  # form.save(length: lambda { |value, options| form.model.id = "#{value}: #{length_seconds}" })
84
96
 
85
97
  # song.title.must_equal "A Poor Man's Memory"
86
- # song.length.must_equal nil
98
+ # assert_nil song.length
87
99
  # song.id.must_equal "10: 120"
88
100
  # end
89
101
  # end
data/test/setup_test.rb CHANGED
@@ -5,7 +5,7 @@ class SetupTest < 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
10
10
  collection :songs do
11
11
  property :title
@@ -20,29 +20,29 @@ class SetupTest < MiniTest::Spec
20
20
  end
21
21
  end
22
22
 
23
- let (:song) { Song.new("Broken") }
24
- let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
25
- let (:composer) { Artist.new("Greg Graffin") }
26
- let (:artist) { Artist.new("Bad Religion") }
23
+ let(:song) { Song.new("Broken") }
24
+ let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
25
+ let(:composer) { Artist.new("Greg Graffin") }
26
+ let(:artist) { Artist.new("Bad Religion") }
27
27
 
28
28
  describe "with nested objects" do
29
- let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
29
+ let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
30
30
 
31
31
  it do
32
32
  form = AlbumForm.new(album)
33
33
 
34
- form.name.must_equal "The Dissent Of Man"
35
- form.songs[0].title.must_equal "Broken"
36
- form.songs[0].composer.must_equal nil
37
- form.songs[1].title.must_equal "Resist Stance"
38
- form.songs[1].composer.name.must_equal "Greg Graffin"
39
- form.artist.name.must_equal "Bad Religion"
34
+ assert_equal form.name, "The Dissent Of Man"
35
+ assert_equal form.songs[0].title, "Broken"
36
+ assert_nil form.songs[0].composer
37
+ assert_equal form.songs[1].title, "Resist Stance"
38
+ assert_equal form.songs[1].composer.name, "Greg Graffin"
39
+ assert_equal form.artist.name, "Bad Religion"
40
40
 
41
41
  # make sure all is wrapped in forms.
42
- form.songs[0].must_be_kind_of Reform::Form
43
- form.songs[1].must_be_kind_of Reform::Form
44
- form.songs[1].composer.must_be_kind_of Reform::Form
45
- form.artist.must_be_kind_of Reform::Form
42
+ assert form.songs[0].is_a? Reform::Form
43
+ assert form.songs[1].is_a? Reform::Form
44
+ assert form.songs[1].composer.is_a? Reform::Form
45
+ assert form.artist.is_a? Reform::Form
46
46
  end
47
47
  end
48
- end
48
+ end
data/test/skip_if_test.rb CHANGED
@@ -1,14 +1,16 @@
1
- require 'test_helper'
1
+ require "test_helper"
2
2
 
3
3
  class SkipIfTest < BaseTest
4
+ let(:hit) { Song.new }
5
+ let(:album) { Album.new(nil, hit, [], nil) }
4
6
 
5
- class AlbumForm < Reform::Form
7
+ class AlbumForm < TestForm
6
8
  property :title
7
9
 
8
- property :hit, skip_if: lambda { |options| options[:fragment]["title"]=="" } do
10
+ property :hit, skip_if: ->(options) { options[:fragment]["title"] == "" } do
9
11
  property :title
10
12
  validation do
11
- key(:title).required
13
+ params { required(:title).filled }
12
14
  end
13
15
  end
14
16
 
@@ -21,36 +23,32 @@ class SkipIfTest < BaseTest
21
23
  end
22
24
  end
23
25
 
24
-
25
- let (:hit) { Song.new }
26
- let (:album) { Album.new(nil, hit, [], nil) }
27
-
28
26
  # deserializes when present.
29
27
  it do
30
28
  form = AlbumForm.new(album)
31
- form.validate("hit" => {"title" => "Altar Of Sacrifice"}).must_equal true
32
- form.hit.title.must_equal "Altar Of Sacrifice"
29
+ assert form.validate("hit" => {"title" => "Altar Of Sacrifice"})
30
+ assert_equal form.hit.title, "Altar Of Sacrifice"
33
31
  end
34
32
 
35
33
  # skips deserialization when not present.
36
34
  it do
37
35
  form = AlbumForm.new(Album.new)
38
- form.validate("hit" => {"title" => ""}).must_equal true
39
- form.hit.must_equal nil # hit hasn't been deserialised.
36
+ assert form.validate("hit" => {"title" => ""})
37
+ assert_nil form.hit # hit hasn't been deserialised.
40
38
  end
41
39
 
42
40
  # skips deserialization when not present.
43
41
  it do
44
42
  form = AlbumForm.new(Album.new(nil, nil, []))
45
- form.validate("songs" => [{"title" => "Waste Of Breath"}, {"title" => nil}]).must_equal true
46
- form.songs.size.must_equal 1
47
- form.songs[0].title.must_equal "Waste Of Breath"
43
+ assert form.validate("songs" => [{"title" => "Waste Of Breath"}, {"title" => nil}])
44
+ assert_equal form.songs.size, 1
45
+ assert_equal form.songs[0].title, "Waste Of Breath"
48
46
  end
49
47
  end
50
48
 
51
49
  class SkipIfAllBlankTest < BaseTest
52
50
  # skip_if: :all_blank"
53
- class AlbumForm < Reform::Form
51
+ class AlbumForm < TestForm
54
52
  collection :songs, skip_if: :all_blank, populate_if_empty: BaseTest::Song do
55
53
  property :title
56
54
  property :length
@@ -60,15 +58,28 @@ class SkipIfAllBlankTest < BaseTest
60
58
  # create only one object.
61
59
  it do
62
60
  form = AlbumForm.new(OpenStruct.new(songs: []))
63
- form.validate("songs" => [{"title"=>"Apathy"}, {"title"=>"", "length" => ""}]).must_equal true
64
- form.songs.size.must_equal 1
65
- form.songs[0].title.must_equal "Apathy"
61
+ assert form.validate("songs" => [{"title" => "Apathy"}, {"title" => "", "length" => ""}])
62
+ assert_equal form.songs.size, 1
63
+ assert_equal form.songs[0].title, "Apathy"
66
64
  end
67
65
 
68
66
  it do
69
67
  form = AlbumForm.new(OpenStruct.new(songs: []))
70
- form.validate("songs" => [{"title"=>"", "length" => ""}, {"title"=>"Apathy"}]).must_equal true
71
- form.songs.size.must_equal 1
72
- form.songs[0].title.must_equal "Apathy"
68
+ assert form.validate("songs" => [{"title" => "", "length" => ""}, {"title" => "Apathy"}])
69
+ assert_equal form.songs.size, 1
70
+ assert_equal form.songs[0].title, "Apathy"
71
+ end
72
+ end
73
+
74
+ class InvalidOptionsCombinationTest < BaseTest
75
+ it do
76
+ assert_raises(Reform::Form::InvalidOptionsCombinationError) do
77
+ class AlbumForm < TestForm
78
+ collection :songs, skip_if: :all_blank, populator: -> {} do
79
+ property :title
80
+ property :length
81
+ end
82
+ end
83
+ end
73
84
  end
74
85
  end
@@ -7,7 +7,7 @@ class SetupSkipSetterAndGetterTest < MiniTest::Spec
7
7
  Album = Struct.new(:title, :artist)
8
8
  Artist = Struct.new(:name)
9
9
 
10
- class AlbumForm < Reform::Form
10
+ class AlbumForm < TestForm
11
11
  property :title
12
12
 
13
13
  def title
@@ -31,24 +31,23 @@ class SetupSkipSetterAndGetterTest < MiniTest::Spec
31
31
  end
32
32
  end
33
33
 
34
- let (:artist) { Artist.new("Bad Religion") }
35
-
34
+ let(:artist) { Artist.new("Bad Religion") }
36
35
 
37
36
  it do
38
37
  album = Album.new("Greatest Hits", artist)
39
38
  form = AlbumForm.new(album)
40
39
 
41
- form.title.must_equal "GREATEST HITS"
42
- form.artist.name.must_equal "bad religion"
40
+ assert_equal form.title, "GREATEST HITS"
41
+ assert_equal form.artist.name, "bad religion"
43
42
 
44
43
  form.validate("title" => "Resiststance", "artist" => {"name" => "Greg Graffin"})
45
44
 
46
- form.title.must_equal "ECNATSTSISER" # first, setter called, then getter.
47
- form.artist.name.must_equal "greg graffi"
45
+ assert_equal form.title, "ECNATSTSISER" # first, setter called, then getter.
46
+ assert_equal form.artist.name, "greg graffi"
48
47
 
49
48
  form.sync
50
49
 
51
- album.title.must_equal "ecnatstsiseR" # setter called, but not getter.
52
- album.artist.name.must_equal "Greg Graffi"
50
+ assert_equal album.title, "ecnatstsiseR" # setter called, but not getter.
51
+ assert_equal album.artist.name, "Greg Graffi"
53
52
  end
54
- end
53
+ end
data/test/test_helper.rb CHANGED
@@ -1,11 +1,26 @@
1
1
  require "reform"
2
- require 'minitest/autorun'
2
+ require "minitest/autorun"
3
3
  require "representable/debug"
4
4
  require "declarative/testing"
5
5
  require "pp"
6
6
 
7
+ require "reform/form/dry"
8
+
9
+ # setup test classes so we can test without dry being included
10
+ class TestForm < Reform::Form
11
+ feature Reform::Form::Dry
12
+ end
13
+
14
+ class TestContract < Reform::Contract
15
+ feature Reform::Form::Dry
16
+ end
17
+
18
+ module Types
19
+ include Dry.Types()
20
+ end
21
+
7
22
  class BaseTest < MiniTest::Spec
8
- class AlbumForm < Reform::Form
23
+ class AlbumForm < TestForm
9
24
  property :title
10
25
 
11
26
  property :hit do
@@ -17,17 +32,20 @@ class BaseTest < MiniTest::Spec
17
32
  end
18
33
  end
19
34
 
20
- Song = Struct.new(:title, :length)
35
+ Song = Struct.new(:title, :length, :rating)
21
36
  Album = Struct.new(:title, :hit, :songs, :band)
22
37
  Band = Struct.new(:label)
23
38
  Label = Struct.new(:name)
24
39
  Length = Struct.new(:minutes, :seconds)
25
40
 
26
-
27
- let (:hit) { Song.new("Roxanne") }
41
+ let(:hit) { Song.new("Roxanne") }
28
42
  end
29
43
 
30
44
  MiniTest::Spec.class_eval do
45
+ Song = Struct.new(:title, :album, :composer)
46
+ Album = Struct.new(:name, :songs, :artist)
47
+ Artist = Struct.new(:name)
48
+
31
49
  module Saveable
32
50
  def save
33
51
  @saved = true
@@ -38,12 +56,3 @@ MiniTest::Spec.class_eval do
38
56
  end
39
57
  end
40
58
  end
41
-
42
- require "reform/form/dry"
43
- Reform::Contract.class_eval do
44
- feature Reform::Form::Dry
45
- end
46
- # FIXME!
47
- Reform::Form.class_eval do
48
- feature Reform::Form::Dry
49
- end