reform 2.3.2 → 2.6.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +17 -0
- data/.gitignore +1 -1
- data/CHANGES.md +23 -0
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +5 -5
- data/Rakefile +1 -12
- data/lib/reform/contract/validate.rb +1 -1
- data/lib/reform/form/dry.rb +47 -9
- data/lib/reform/form/populator.rb +13 -3
- data/lib/reform/form/prepopulate.rb +1 -1
- data/lib/reform/form/validate.rb +3 -3
- data/lib/reform/validation/groups.rb +0 -1
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +2 -2
- data/test/call_test.rb +23 -0
- data/test/changed_test.rb +6 -6
- data/test/coercion_test.rb +17 -17
- data/test/{composition_new_api.rb → composition_test.rb} +27 -28
- data/test/{contract_new_api.rb → contract_test.rb} +8 -8
- data/test/default_test.rb +2 -2
- data/test/deserialize_test.rb +8 -8
- data/test/docs/validation_test.rb +134 -0
- data/test/{errors_new_api.rb → errors_test.rb} +41 -41
- data/test/feature_test.rb +2 -2
- data/test/fixtures/dry_error_messages.yml +64 -54
- data/test/{form_option_new_api.rb → form_option_test.rb} +1 -1
- data/test/{form_new_api.rb → form_test.rb} +3 -3
- data/test/from_test.rb +10 -10
- data/test/{inherit_new_api.rb → inherit_test.rb} +17 -17
- data/test/{module_new_api.rb → module_test.rb} +10 -10
- data/test/parse_option_test.rb +7 -7
- data/test/parse_pipeline_test.rb +1 -1
- data/test/{populate_new_api.rb → populate_test.rb} +136 -53
- data/test/populator_skip_test.rb +2 -2
- data/test/prepopulator_test.rb +16 -16
- data/test/read_only_test.rb +2 -2
- data/test/readable_test.rb +3 -3
- data/test/{reform_new_api.rb → reform_test.rb} +19 -19
- data/test/{save_new_api.rb → save_test.rb} +4 -4
- data/test/setup_test.rb +9 -9
- data/test/{skip_if_new_api.rb → skip_if_test.rb} +12 -12
- data/test/skip_setter_and_getter_test.rb +6 -6
- data/test/test_helper.rb +5 -6
- data/test/{validate_new_api.rb → validate_test.rb} +65 -78
- data/test/validation/{dry_validation_new_api.rb → dry_validation_test.rb} +128 -128
- data/test/validation/result_test.rb +14 -14
- data/test/virtual_test.rb +7 -7
- data/test/writeable_test.rb +8 -8
- metadata +42 -75
- data/.travis.yml +0 -16
- data/Appraisals +0 -8
- data/gemfiles/0.13.0.gemfile +0 -8
- data/gemfiles/1.5.0.gemfile +0 -9
- data/lib/reform/form/dry/new_api.rb +0 -47
- data/lib/reform/form/dry/old_api.rb +0 -61
- data/test/call_new_api.rb +0 -23
- data/test/call_old_api.rb +0 -23
- data/test/composition_old_api.rb +0 -184
- data/test/contract_old_api.rb +0 -77
- data/test/errors_old_api.rb +0 -230
- data/test/fixtures/dry_new_api_error_messages.yml +0 -104
- data/test/form_old_api.rb +0 -57
- data/test/form_option_old_api.rb +0 -24
- data/test/inherit_old_api.rb +0 -105
- data/test/module_old_api.rb +0 -146
- data/test/populate_old_api.rb +0 -304
- data/test/reform_old_api.rb +0 -202
- data/test/save_old_api.rb +0 -101
- data/test/skip_if_old_api.rb +0 -92
- data/test/validate_old_api.rb +0 -410
- data/test/validation/dry_validation_old_api.rb +0 -772
data/test/contract_old_api.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class ContractTest < MiniTest::Spec
|
4
|
-
Song = Struct.new(:title, :album, :composer)
|
5
|
-
Album = Struct.new(:name, :duration, :songs, :artist)
|
6
|
-
Artist = Struct.new(:name)
|
7
|
-
|
8
|
-
class ArtistForm < TestForm
|
9
|
-
property :name
|
10
|
-
end
|
11
|
-
|
12
|
-
class AlbumForm < TestContract
|
13
|
-
property :name
|
14
|
-
|
15
|
-
properties :duration
|
16
|
-
properties :year, :style, readable: false
|
17
|
-
|
18
|
-
validation do
|
19
|
-
required(:name).filled
|
20
|
-
end
|
21
|
-
|
22
|
-
collection :songs do
|
23
|
-
property :title
|
24
|
-
validation do
|
25
|
-
required(:title).filled
|
26
|
-
end
|
27
|
-
|
28
|
-
property :composer do
|
29
|
-
property :name
|
30
|
-
validation do
|
31
|
-
required(:name).filled
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
property :artist, form: ArtistForm
|
37
|
-
end
|
38
|
-
|
39
|
-
let(:song) { Song.new("Broken") }
|
40
|
-
let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
41
|
-
let(:composer) { Artist.new("Greg Graffin") }
|
42
|
-
let(:artist) { Artist.new("Bad Religion") }
|
43
|
-
let(:album) { Album.new("The Dissent Of Man", 123, [song, song_with_composer], artist) }
|
44
|
-
|
45
|
-
let(:form) { AlbumForm.new(album) }
|
46
|
-
|
47
|
-
# accept `property form: SongForm`.
|
48
|
-
it do
|
49
|
-
form.artist.must_be_instance_of ArtistForm
|
50
|
-
end
|
51
|
-
|
52
|
-
describe ".properties" do
|
53
|
-
it "defines a property when called with one argument" do
|
54
|
-
form.must_respond_to :duration
|
55
|
-
end
|
56
|
-
|
57
|
-
it "defines several properties when called with multiple arguments" do
|
58
|
-
form.must_respond_to :year
|
59
|
-
form.must_respond_to :style
|
60
|
-
end
|
61
|
-
|
62
|
-
it "passes options to each property when options are provided" do
|
63
|
-
readable = AlbumForm.new(album).options_for(:style)[:readable]
|
64
|
-
readable.must_equal false
|
65
|
-
end
|
66
|
-
|
67
|
-
it "returns the list of defined properties" do
|
68
|
-
returned_value = AlbumForm.properties(:hello, :world, virtual: true)
|
69
|
-
returned_value.must_equal %i[hello world]
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe "#options_for" do
|
74
|
-
it { AlbumForm.options_for(:name).extend(Declarative::Inspect).inspect.must_equal "#<Disposable::Twin::Definition: @options={:private_name=>:name, :name=>\"name\"}>" }
|
75
|
-
it { AlbumForm.new(album).options_for(:name).extend(Declarative::Inspect).inspect.must_equal "#<Disposable::Twin::Definition: @options={:private_name=>:name, :name=>\"name\"}>" }
|
76
|
-
end
|
77
|
-
end
|
data/test/errors_old_api.rb
DELETED
@@ -1,230 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class ErrorsTest < MiniTest::Spec
|
4
|
-
class AlbumForm < TestForm
|
5
|
-
property :title
|
6
|
-
validation do
|
7
|
-
required(:title).filled
|
8
|
-
end
|
9
|
-
|
10
|
-
property :artists, default: []
|
11
|
-
property :producer do
|
12
|
-
property :name
|
13
|
-
end
|
14
|
-
|
15
|
-
property :hit do
|
16
|
-
property :title
|
17
|
-
validation do
|
18
|
-
required(:title).filled
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
collection :songs do
|
23
|
-
property :title
|
24
|
-
validation do
|
25
|
-
required(:title).filled
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
property :band do # yepp, people do crazy stuff like that.
|
30
|
-
property :name
|
31
|
-
property :label do
|
32
|
-
property :name
|
33
|
-
validation do
|
34
|
-
required(:name).filled
|
35
|
-
end
|
36
|
-
end
|
37
|
-
# TODO: make band a required object.
|
38
|
-
|
39
|
-
validation do
|
40
|
-
configure do
|
41
|
-
config.messages_file = "test/fixtures/dry_error_messages.yml"
|
42
|
-
|
43
|
-
def good_musical_taste?(value)
|
44
|
-
value != "Nickelback"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
required(:name).filled(:good_musical_taste?)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
validation do
|
53
|
-
required(:title).filled
|
54
|
-
required(:artists).each(:str?)
|
55
|
-
required(:producer).schema do
|
56
|
-
required(:name).filled
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
let(:album_title) { "Blackhawks Over Los Angeles" }
|
62
|
-
let(:album) do
|
63
|
-
OpenStruct.new(
|
64
|
-
title: album_title,
|
65
|
-
hit: song,
|
66
|
-
songs: songs, # TODO: document this requirement,
|
67
|
-
band: Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
|
68
|
-
producer: Struct.new(:name).new("Sun Records")
|
69
|
-
)
|
70
|
-
end
|
71
|
-
let(:song) { OpenStruct.new(title: "Downtown") }
|
72
|
-
let(:songs) { [song = OpenStruct.new(title: "Calling"), song] }
|
73
|
-
let(:form) { AlbumForm.new(album) }
|
74
|
-
|
75
|
-
describe "#validate with invalid array property" do
|
76
|
-
it do
|
77
|
-
form.validate(
|
78
|
-
title: "Swimming Pool - EP",
|
79
|
-
band: {
|
80
|
-
name: "Marie Madeleine",
|
81
|
-
label: {name: "Ekler'o'shocK"}
|
82
|
-
},
|
83
|
-
artists: [42, "Good Charlotte", 43]
|
84
|
-
).must_equal false
|
85
|
-
form.errors.messages.must_equal(artists: {0 => ["must be a string"], 2 => ["must be a string"]})
|
86
|
-
form.errors.size.must_equal(1)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe "#errors without #validate" do
|
91
|
-
it do
|
92
|
-
form.errors.size.must_equal 0
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
describe "blank everywhere" do
|
97
|
-
before do
|
98
|
-
form.validate(
|
99
|
-
"hit" => {"title" => ""},
|
100
|
-
"title" => "",
|
101
|
-
"songs" => [{"title" => ""}, {"title" => ""}],
|
102
|
-
"producer" => {"name" => ""}
|
103
|
-
)
|
104
|
-
end
|
105
|
-
|
106
|
-
it do
|
107
|
-
form.errors.messages.must_equal(
|
108
|
-
title: ["must be filled"],
|
109
|
-
"hit.title": ["must be filled"],
|
110
|
-
"songs.title": ["must be filled"],
|
111
|
-
"band.label.name": ["must be filled"],
|
112
|
-
"producer.name": ["must be filled"]
|
113
|
-
)
|
114
|
-
end
|
115
|
-
|
116
|
-
# it do
|
117
|
-
# form.errors.must_equal({:title => ["must be filled"]})
|
118
|
-
# TODO: this should only contain local errors?
|
119
|
-
# end
|
120
|
-
|
121
|
-
# nested forms keep their own Errors:
|
122
|
-
it { form.producer.errors.messages.must_equal(name: ["must be filled"]) }
|
123
|
-
it { form.hit.errors.messages.must_equal(title: ["must be filled"]) }
|
124
|
-
it { form.songs[0].errors.messages.must_equal(title: ["must be filled"]) }
|
125
|
-
|
126
|
-
it do
|
127
|
-
form.errors.messages.must_equal(
|
128
|
-
title: ["must be filled"],
|
129
|
-
"hit.title": ["must be filled"],
|
130
|
-
"songs.title": ["must be filled"],
|
131
|
-
"band.label.name": ["must be filled"],
|
132
|
-
"producer.name": ["must be filled"]
|
133
|
-
)
|
134
|
-
form.errors.size.must_equal(5)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
describe "#validate with main form invalid" do
|
139
|
-
it do
|
140
|
-
form.validate("title" => "", "band" => {"label" => {name: "Fat Wreck"}}, "producer" => nil).must_equal false
|
141
|
-
form.errors.messages.must_equal(title: ["must be filled"], producer: ["must be a hash"])
|
142
|
-
form.errors.size.must_equal(2)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
describe "#validate with middle nested form invalid" do
|
147
|
-
before { @result = form.validate("hit" => {"title" => ""}, "band" => {"label" => {name: "Fat Wreck"}}) }
|
148
|
-
|
149
|
-
it { @result.must_equal false }
|
150
|
-
it { form.errors.messages.must_equal("hit.title": ["must be filled"]) }
|
151
|
-
it { form.errors.size.must_equal(1) }
|
152
|
-
end
|
153
|
-
|
154
|
-
describe "#validate with collection form invalid" do
|
155
|
-
before { @result = form.validate("songs" => [{"title" => ""}], "band" => {"label" => {name: "Fat Wreck"}}) }
|
156
|
-
|
157
|
-
it { @result.must_equal false }
|
158
|
-
it { form.errors.messages.must_equal("songs.title": ["must be filled"]) }
|
159
|
-
it { form.errors.size.must_equal(1) }
|
160
|
-
end
|
161
|
-
|
162
|
-
describe "#validate with collection and 2-level-nested invalid" do
|
163
|
-
before { @result = form.validate("songs" => [{"title" => ""}], "band" => {"label" => {}}) }
|
164
|
-
|
165
|
-
it { @result.must_equal false }
|
166
|
-
it { form.errors.messages.must_equal("songs.title": ["must be filled"], "band.label.name": ["must be filled"]) }
|
167
|
-
it { form.errors.size.must_equal(2) }
|
168
|
-
end
|
169
|
-
|
170
|
-
describe "#validate with nested form using :base invalid" do
|
171
|
-
it do
|
172
|
-
result = form.validate("songs" => [{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
|
173
|
-
result.must_equal false
|
174
|
-
form.errors.messages.must_equal("band.name": ["you're a bad person"])
|
175
|
-
form.errors.size.must_equal(1)
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
describe "#add" do
|
180
|
-
let(:album_title) { nil }
|
181
|
-
it do
|
182
|
-
form.errors.add(:before, "validate")
|
183
|
-
form.errors.add(:before, "validate 2")
|
184
|
-
form.errors.add(:title, "before validate")
|
185
|
-
result = form.validate("songs" => [{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
|
186
|
-
result.must_equal false
|
187
|
-
form.errors.messages.must_equal(before: ["validate", "validate 2"], title: ["before validate", "must be filled"], "band.name": ["you're a bad person"])
|
188
|
-
# add a new custom error
|
189
|
-
form.errors.add(:policy, "error_text")
|
190
|
-
form.errors.messages.must_equal(before: ["validate", "validate 2"], title: ["before validate", "must be filled"], "band.name": ["you're a bad person"], policy: ["error_text"])
|
191
|
-
# does not duplicate errors
|
192
|
-
form.errors.add(:title, "must be filled")
|
193
|
-
form.errors.messages.must_equal(before: ["validate", "validate 2"], title: ["before validate", "must be filled"], "band.name": ["you're a bad person"], policy: ["error_text"])
|
194
|
-
# merge existing errors
|
195
|
-
form.errors.add(:policy, "another error")
|
196
|
-
form.errors.messages.must_equal(before: ["validate", "validate 2"], title: ["before validate", "must be filled"], "band.name": ["you're a bad person"], policy: ["error_text", "another error"])
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
describe "correct #validate" do
|
201
|
-
before do
|
202
|
-
@result = form.validate(
|
203
|
-
"hit" => {"title" => "Sacrifice"},
|
204
|
-
"title" => "Second Heat",
|
205
|
-
"songs" => [{"title" => "Heart Of A Lion"}],
|
206
|
-
"band" => {"label" => {name: "Fat Wreck"}}
|
207
|
-
)
|
208
|
-
end
|
209
|
-
|
210
|
-
it { @result.must_equal true }
|
211
|
-
it { form.hit.title.must_equal "Sacrifice" }
|
212
|
-
it { form.title.must_equal "Second Heat" }
|
213
|
-
it { form.songs.first.title.must_equal "Heart Of A Lion" }
|
214
|
-
it do
|
215
|
-
skip "WE DON'T NEED COUNT AND EMPTY? ON THE CORE ERRORS OBJECT"
|
216
|
-
form.errors.size.must_equal(0)
|
217
|
-
form.errors.empty?.must_equal(true)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
describe "Errors#to_s" do
|
222
|
-
before { form.validate("songs" => [{"title" => ""}], "band" => {"label" => {}}) }
|
223
|
-
|
224
|
-
# to_s is aliased to messages
|
225
|
-
it {
|
226
|
-
skip "why do we need Errors#to_s ?"
|
227
|
-
form.errors.to_s.must_equal "{:\"songs.title\"=>[\"must be filled\"], :\"band.label.name\"=>[\"must be filled\"]}"
|
228
|
-
}
|
229
|
-
end
|
230
|
-
end
|
@@ -1,104 +0,0 @@
|
|
1
|
-
en:
|
2
|
-
dry_validation:
|
3
|
-
errors:
|
4
|
-
array?: "must be an array"
|
5
|
-
|
6
|
-
empty?: "must be empty"
|
7
|
-
|
8
|
-
excludes?: "must not include %{value}"
|
9
|
-
|
10
|
-
excluded_from?:
|
11
|
-
arg:
|
12
|
-
default: "must not be one of: %{list}"
|
13
|
-
range: "must not be one of: %{list_left} - %{list_right}"
|
14
|
-
|
15
|
-
eql?: "must be equal to %{left}"
|
16
|
-
|
17
|
-
not_eql?: "must not be equal to %{left}"
|
18
|
-
|
19
|
-
filled?: "must be filled"
|
20
|
-
|
21
|
-
format?: "is in invalid format"
|
22
|
-
|
23
|
-
number?: "must be a number"
|
24
|
-
|
25
|
-
odd?: "must be odd"
|
26
|
-
|
27
|
-
even?: "must be even"
|
28
|
-
|
29
|
-
gt?: "must be greater than %{num}"
|
30
|
-
|
31
|
-
gteq?: "must be greater than or equal to %{num}"
|
32
|
-
|
33
|
-
hash?: "must be a hash"
|
34
|
-
|
35
|
-
included_in?:
|
36
|
-
arg:
|
37
|
-
default: "must be one of: %{list}"
|
38
|
-
range: "must be one of: %{list_left} - %{list_right}"
|
39
|
-
|
40
|
-
includes?: "must include %{value}"
|
41
|
-
|
42
|
-
bool?: "must be boolean"
|
43
|
-
|
44
|
-
true?: "must be true"
|
45
|
-
|
46
|
-
false?: "must be false"
|
47
|
-
|
48
|
-
int?: "must be an integer"
|
49
|
-
|
50
|
-
float?: "must be a float"
|
51
|
-
|
52
|
-
decimal?: "must be a decimal"
|
53
|
-
|
54
|
-
date?: "must be a date"
|
55
|
-
|
56
|
-
date_time?: "must be a date time"
|
57
|
-
|
58
|
-
time?: "must be a time"
|
59
|
-
|
60
|
-
key?: "is missing"
|
61
|
-
|
62
|
-
attr?: "is missing"
|
63
|
-
|
64
|
-
lt?: "must be less than %{num}"
|
65
|
-
|
66
|
-
lteq?: "must be less than or equal to %{num}"
|
67
|
-
|
68
|
-
max_size?: "size cannot be greater than %{num}"
|
69
|
-
|
70
|
-
min_size?: "size cannot be less than %{num}"
|
71
|
-
|
72
|
-
none?: "cannot be defined"
|
73
|
-
|
74
|
-
str?: "must be a string"
|
75
|
-
|
76
|
-
type?: "must be %{type}"
|
77
|
-
|
78
|
-
size?:
|
79
|
-
arg:
|
80
|
-
default: "size must be %{size}"
|
81
|
-
range: "size must be within %{size_left} - %{size_right}"
|
82
|
-
|
83
|
-
value:
|
84
|
-
string:
|
85
|
-
arg:
|
86
|
-
default: "length must be %{size}"
|
87
|
-
range: "length must be within %{size_left} - %{size_right}"
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
rules:
|
92
|
-
name:
|
93
|
-
good_musical_taste?: "you're a bad person"
|
94
|
-
title:
|
95
|
-
good_musical_taste?: "you're a bad person"
|
96
|
-
songs:
|
97
|
-
a_song?: "must have at least one enabled song"
|
98
|
-
artist:
|
99
|
-
with_last_name?: "must have last name"
|
100
|
-
|
101
|
-
de:
|
102
|
-
dry_validation:
|
103
|
-
errors:
|
104
|
-
filled?: "muss abgefüllt sein"
|
data/test/form_old_api.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class FormTest < MiniTest::Spec
|
4
|
-
Artist = Struct.new(:name)
|
5
|
-
|
6
|
-
class AlbumForm < TestForm
|
7
|
-
property :title
|
8
|
-
|
9
|
-
property :hit do
|
10
|
-
property :title
|
11
|
-
end
|
12
|
-
|
13
|
-
collection :songs do
|
14
|
-
property :title
|
15
|
-
end
|
16
|
-
|
17
|
-
property :band do # yepp, people do crazy stuff like that.
|
18
|
-
property :label do
|
19
|
-
property :name
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "::dup" do
|
25
|
-
let(:cloned) { AlbumForm.clone }
|
26
|
-
|
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 }
|
30
|
-
|
31
|
-
it do
|
32
|
-
# currently, forms need a name for validation, even without AM.
|
33
|
-
cloned.singleton_class.class_eval do
|
34
|
-
def name
|
35
|
-
"Album"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
cloned.validation do
|
40
|
-
required(:title).filled
|
41
|
-
end
|
42
|
-
|
43
|
-
cloned.new(OpenStruct.new).validate({})
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "#initialize" do
|
48
|
-
class ArtistForm < TestForm
|
49
|
-
property :name
|
50
|
-
property :current_user, virtual: true
|
51
|
-
end
|
52
|
-
|
53
|
-
it "allows injecting :virtual options" do
|
54
|
-
ArtistForm.new(Artist.new, current_user: Object).current_user.must_equal Object
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/test/form_option_old_api.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class FormOptionTest < MiniTest::Spec
|
4
|
-
Song = Struct.new(:title)
|
5
|
-
Album = Struct.new(:song)
|
6
|
-
|
7
|
-
class SongForm < TestForm
|
8
|
-
property :title
|
9
|
-
validation do
|
10
|
-
required(:title).filled
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class AlbumForm < TestForm
|
15
|
-
property :song, form: SongForm
|
16
|
-
end
|
17
|
-
|
18
|
-
it do
|
19
|
-
form = AlbumForm.new(Album.new(Song.new("When It Comes To You")))
|
20
|
-
form.song.title.must_equal "When It Comes To You"
|
21
|
-
|
22
|
-
form.validate(song: {title: "Run For Cover"})
|
23
|
-
end
|
24
|
-
end
|
data/test/inherit_old_api.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
require "representable/json"
|
3
|
-
|
4
|
-
class InheritTest < BaseTest
|
5
|
-
Populator = Reform::Form::Populator
|
6
|
-
|
7
|
-
class SkipParse
|
8
|
-
include Uber::Callable
|
9
|
-
def call(*_args)
|
10
|
-
false
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class AlbumForm < TestForm
|
15
|
-
property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
|
16
|
-
|
17
|
-
property :hit, populate_if_empty: ->(*) { Song.new } do
|
18
|
-
property :title
|
19
|
-
validation do
|
20
|
-
required(:title).filled
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
collection :songs, populate_if_empty: -> {}, skip_if: :all_blank do
|
25
|
-
property :title
|
26
|
-
end
|
27
|
-
|
28
|
-
property :band, populate_if_empty: -> {} do
|
29
|
-
def band_id
|
30
|
-
1
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class CompilationForm < AlbumForm
|
36
|
-
property :title, inherit: true, skip_if: "skip_if from CompilationForm"
|
37
|
-
property :hit, inherit: true, populate_if_empty: ->(*) { Song.new }, skip_if: SkipParse.new do
|
38
|
-
property :rating
|
39
|
-
validation do
|
40
|
-
required(:rating).filled
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# NO collection here, this is entirely inherited.
|
45
|
-
|
46
|
-
property :band, inherit: true do # inherit everything, but explicitely.
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
let(:album) { Album.new(nil, Song.new, [], Band.new) }
|
51
|
-
subject { CompilationForm.new(album) }
|
52
|
-
|
53
|
-
it do
|
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({})
|
58
|
-
end
|
59
|
-
|
60
|
-
it do
|
61
|
-
subject.validate({})
|
62
|
-
assert_nil subject.model.hit.title
|
63
|
-
assert_nil subject.model.hit.rating
|
64
|
-
subject.errors.messages.must_equal("hit.title": ["must be filled"], "hit.rating": ["must be filled"])
|
65
|
-
end
|
66
|
-
|
67
|
-
it "xxx" do
|
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
|
70
|
-
|
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"
|
74
|
-
|
75
|
-
# AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
|
76
|
-
# AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
|
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
|
80
|
-
|
81
|
-
AlbumForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
82
|
-
|
83
|
-
CompilationForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if from CompilationForm"
|
84
|
-
# pp CompilationForm.options_for(:songs)
|
85
|
-
CompilationForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
86
|
-
|
87
|
-
CompilationForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
88
|
-
|
89
|
-
# completely overwrite inherited.
|
90
|
-
CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_be_instance_of SkipParse
|
91
|
-
|
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
|
95
|
-
end
|
96
|
-
|
97
|
-
class CDForm < AlbumForm
|
98
|
-
# override :band's original populate_if_empty but with :inherit.
|
99
|
-
property :band, inherit: true, populator: "CD Populator" do
|
100
|
-
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
it { CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc).must_equal "CD Populator" }
|
105
|
-
end
|