reform 2.3.0.rc1 → 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.
- checksums.yaml +5 -5
- data/.gitignore +5 -1
- data/.travis.yml +7 -11
- data/CHANGES.md +43 -3
- data/Gemfile +2 -5
- data/ISSUE_TEMPLATE.md +1 -1
- data/LICENSE.txt +1 -1
- data/README.md +7 -9
- data/Rakefile +6 -10
- data/lib/reform/contract.rb +7 -7
- data/lib/reform/contract/custom_error.rb +41 -0
- data/lib/reform/contract/validate.rb +10 -6
- data/lib/reform/errors.rb +27 -15
- data/lib/reform/form.rb +22 -11
- data/lib/reform/form/call.rb +1 -1
- data/lib/reform/form/composition.rb +2 -2
- data/lib/reform/form/dry.rb +22 -60
- data/lib/reform/form/dry/input_hash.rb +37 -0
- data/lib/reform/form/populator.rb +9 -11
- data/lib/reform/form/prepopulate.rb +3 -2
- data/lib/reform/form/validate.rb +19 -12
- data/lib/reform/result.rb +36 -9
- data/lib/reform/validation.rb +10 -8
- data/lib/reform/validation/groups.rb +2 -4
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +9 -9
- data/test/benchmarking.rb +10 -11
- data/test/call_test.rb +8 -8
- data/test/changed_test.rb +13 -13
- data/test/coercion_test.rb +56 -24
- data/test/composition_test.rb +49 -51
- data/test/contract/custom_error_test.rb +55 -0
- data/test/contract_test.rb +18 -18
- data/test/default_test.rb +3 -3
- data/test/deserialize_test.rb +14 -17
- data/test/docs/validation_test.rb +134 -0
- data/test/errors_test.rb +131 -86
- data/test/feature_test.rb +9 -11
- data/test/fixtures/dry_error_messages.yml +65 -52
- data/test/form_option_test.rb +3 -3
- data/test/form_test.rb +6 -6
- data/test/from_test.rb +17 -21
- data/test/inherit_test.rb +28 -35
- data/test/module_test.rb +23 -28
- data/test/parse_option_test.rb +12 -12
- data/test/parse_pipeline_test.rb +3 -3
- data/test/populate_test.rb +146 -93
- data/test/populator_skip_test.rb +3 -4
- data/test/prepopulator_test.rb +20 -21
- data/test/read_only_test.rb +12 -1
- data/test/readable_test.rb +7 -7
- data/test/reform_test.rb +38 -42
- data/test/save_test.rb +16 -19
- data/test/setup_test.rb +15 -15
- data/test/skip_if_test.rb +30 -19
- data/test/skip_setter_and_getter_test.rb +8 -9
- data/test/test_helper.rb +12 -5
- data/test/validate_test.rb +160 -140
- data/test/validation/dry_validation_test.rb +407 -236
- data/test/validation/result_test.rb +29 -31
- data/test/validation_library_provided_test.rb +3 -3
- data/test/virtual_test.rb +46 -6
- data/test/writeable_test.rb +13 -13
- metadata +32 -29
- data/test/readonly_test.rb +0 -14
data/test/setup_test.rb
CHANGED
@@ -20,29 +20,29 @@ class SetupTest < MiniTest::Spec
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
let
|
24
|
-
let
|
25
|
-
let
|
26
|
-
let
|
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
|
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
|
35
|
-
form.songs[0].title
|
34
|
+
assert_equal form.name, "The Dissent Of Man"
|
35
|
+
assert_equal form.songs[0].title, "Broken"
|
36
36
|
assert_nil form.songs[0].composer
|
37
|
-
form.songs[1].title
|
38
|
-
form.songs[1].composer.name
|
39
|
-
form.artist.name
|
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].
|
43
|
-
form.songs[1].
|
44
|
-
form.songs[1].composer.
|
45
|
-
form.artist.
|
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
|
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
7
|
class AlbumForm < TestForm
|
6
8
|
property :title
|
7
9
|
|
8
|
-
property :hit, skip_if:
|
10
|
+
property :hit, skip_if: ->(options) { options[:fragment]["title"] == "" } do
|
9
11
|
property :title
|
10
12
|
validation do
|
11
|
-
required(:title).filled
|
13
|
+
params { required(:title).filled }
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
@@ -21,30 +23,26 @@ 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"})
|
32
|
-
form.hit.title
|
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" => ""})
|
36
|
+
assert form.validate("hit" => {"title" => ""})
|
39
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}])
|
46
|
-
form.songs.size
|
47
|
-
form.songs[0].title
|
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
|
|
@@ -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" => ""}])
|
64
|
-
form.songs.size
|
65
|
-
form.songs[0].title
|
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"}])
|
71
|
-
form.songs.size
|
72
|
-
form.songs[0].title
|
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
|
@@ -31,24 +31,23 @@ class SetupSkipSetterAndGetterTest < MiniTest::Spec
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
let
|
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
|
42
|
-
form.artist.name
|
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
|
47
|
-
form.artist.name
|
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
|
52
|
-
album.artist.name
|
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,12 @@
|
|
1
1
|
require "reform"
|
2
|
-
require
|
2
|
+
require "minitest/autorun"
|
3
3
|
require "representable/debug"
|
4
4
|
require "declarative/testing"
|
5
5
|
require "pp"
|
6
|
-
require
|
6
|
+
require "pry-byebug"
|
7
7
|
|
8
8
|
require "reform/form/dry"
|
9
|
+
|
9
10
|
# setup test classes so we can test without dry being included
|
10
11
|
class TestForm < Reform::Form
|
11
12
|
feature Reform::Form::Dry
|
@@ -15,6 +16,10 @@ class TestContract < Reform::Contract
|
|
15
16
|
feature Reform::Form::Dry
|
16
17
|
end
|
17
18
|
|
19
|
+
module Types
|
20
|
+
include Dry.Types()
|
21
|
+
end
|
22
|
+
|
18
23
|
class BaseTest < MiniTest::Spec
|
19
24
|
class AlbumForm < TestForm
|
20
25
|
property :title
|
@@ -34,11 +39,14 @@ class BaseTest < MiniTest::Spec
|
|
34
39
|
Label = Struct.new(:name)
|
35
40
|
Length = Struct.new(:minutes, :seconds)
|
36
41
|
|
37
|
-
|
38
|
-
let (:hit) { Song.new("Roxanne") }
|
42
|
+
let(:hit) { Song.new("Roxanne") }
|
39
43
|
end
|
40
44
|
|
41
45
|
MiniTest::Spec.class_eval do
|
46
|
+
Song = Struct.new(:title, :album, :composer)
|
47
|
+
Album = Struct.new(:name, :songs, :artist)
|
48
|
+
Artist = Struct.new(:name)
|
49
|
+
|
42
50
|
module Saveable
|
43
51
|
def save
|
44
52
|
@saved = true
|
@@ -49,4 +57,3 @@ MiniTest::Spec.class_eval do
|
|
49
57
|
end
|
50
58
|
end
|
51
59
|
end
|
52
|
-
|
data/test/validate_test.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
2
|
|
3
3
|
class ContractValidateTest < MiniTest::Spec
|
4
|
-
Song = Struct.new(:title, :album, :composer)
|
5
|
-
Album = Struct.new(:name, :songs, :artist)
|
6
|
-
Artist = Struct.new(:name)
|
7
|
-
|
8
4
|
class AlbumForm < TestContract
|
9
5
|
property :name
|
10
6
|
validation do
|
11
|
-
required(:name).filled
|
7
|
+
params { required(:name).filled }
|
12
8
|
end
|
13
9
|
|
14
10
|
collection :songs do
|
15
11
|
property :title
|
16
12
|
validation do
|
17
|
-
required(:title).filled
|
13
|
+
params { required(:title).filled }
|
18
14
|
end
|
19
15
|
|
20
16
|
property :composer do
|
21
17
|
validation do
|
22
|
-
required(:name).filled
|
18
|
+
params { required(:name).filled }
|
23
19
|
end
|
24
20
|
property :name
|
25
21
|
end
|
@@ -30,18 +26,18 @@ class ContractValidateTest < MiniTest::Spec
|
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
33
|
-
let
|
34
|
-
let
|
35
|
-
let
|
36
|
-
let
|
37
|
-
let
|
29
|
+
let(:song) { Song.new("Broken") }
|
30
|
+
let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
31
|
+
let(:composer) { Artist.new("Greg Graffin") }
|
32
|
+
let(:artist) { Artist.new("Bad Religion") }
|
33
|
+
let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
|
38
34
|
|
39
|
-
let
|
35
|
+
let(:form) { AlbumForm.new(album) }
|
40
36
|
|
41
37
|
# valid
|
42
38
|
it do
|
43
|
-
form.validate
|
44
|
-
form.errors.messages.inspect
|
39
|
+
assert form.validate
|
40
|
+
assert_equal form.errors.messages.inspect, "{}"
|
45
41
|
end
|
46
42
|
|
47
43
|
# invalid
|
@@ -49,35 +45,29 @@ class ContractValidateTest < MiniTest::Spec
|
|
49
45
|
album.songs[1].composer.name = nil
|
50
46
|
album.name = nil
|
51
47
|
|
52
|
-
form.validate
|
53
|
-
form.errors.messages.inspect
|
48
|
+
assert_equal form.validate, false
|
49
|
+
assert_equal form.errors.messages.inspect, "{:name=>[\"must be filled\"], :\"songs.composer.name\"=>[\"must be filled\"]}"
|
54
50
|
end
|
55
51
|
end
|
56
52
|
|
57
|
-
|
58
53
|
# no configuration results in "sync" (formerly known as parse_strategy: :sync).
|
59
54
|
class ValidateWithoutConfigurationTest < MiniTest::Spec
|
60
|
-
Song = Struct.new(:title, :album, :composer)
|
61
|
-
Album = Struct.new(:name, :songs, :artist)
|
62
|
-
Artist = Struct.new(:name)
|
63
|
-
|
64
55
|
class AlbumForm < TestForm
|
65
56
|
property :name
|
66
57
|
validation do
|
67
|
-
required(:name).filled
|
58
|
+
params { required(:name).filled }
|
68
59
|
end
|
69
60
|
|
70
61
|
collection :songs do
|
71
|
-
|
72
62
|
property :title
|
73
63
|
validation do
|
74
|
-
required(:title).filled
|
64
|
+
params { required(:title).filled }
|
75
65
|
end
|
76
66
|
|
77
67
|
property :composer do
|
78
68
|
property :name
|
79
69
|
validation do
|
80
|
-
required(:name).filled
|
70
|
+
params { required(:name).filled }
|
81
71
|
end
|
82
72
|
end
|
83
73
|
end
|
@@ -87,62 +77,63 @@ class ValidateWithoutConfigurationTest < MiniTest::Spec
|
|
87
77
|
end
|
88
78
|
end
|
89
79
|
|
90
|
-
let
|
91
|
-
let
|
92
|
-
let
|
93
|
-
let
|
94
|
-
let
|
80
|
+
let(:song) { Song.new("Broken") }
|
81
|
+
let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
82
|
+
let(:composer) { Artist.new("Greg Graffin") }
|
83
|
+
let(:artist) { Artist.new("Bad Religion") }
|
84
|
+
let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
|
95
85
|
|
96
|
-
let
|
86
|
+
let(:form) { AlbumForm.new(album) }
|
97
87
|
|
98
88
|
# valid.
|
99
89
|
it do
|
100
|
-
object_ids = {
|
101
|
-
|
90
|
+
object_ids = {
|
91
|
+
song: form.songs[0].object_id, song_with_composer: form.songs[1].object_id,
|
92
|
+
artist: form.artist.object_id, composer: form.songs[1].composer.object_id
|
93
|
+
}
|
102
94
|
|
103
|
-
form.validate(
|
95
|
+
assert form.validate(
|
104
96
|
"name" => "Best Of",
|
105
97
|
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne", "composer" => {"name" => "Sting"}}],
|
106
|
-
"artist" => {"name" => "The Police"}
|
107
|
-
)
|
98
|
+
"artist" => {"name" => "The Police"}
|
99
|
+
)
|
108
100
|
|
109
|
-
form.errors.messages.inspect
|
101
|
+
assert_equal form.errors.messages.inspect, "{}"
|
110
102
|
|
111
103
|
# form has updated.
|
112
|
-
form.name
|
113
|
-
form.songs[0].title
|
114
|
-
form.songs[1].title
|
115
|
-
form.songs[1].composer.name
|
116
|
-
form.artist.name
|
104
|
+
assert_equal form.name, "Best Of"
|
105
|
+
assert_equal form.songs[0].title, "Fallout"
|
106
|
+
assert_equal form.songs[1].title, "Roxanne"
|
107
|
+
assert_equal form.songs[1].composer.name, "Sting"
|
108
|
+
assert_equal form.artist.name, "The Police"
|
117
109
|
|
118
110
|
# objects are still the same.
|
119
|
-
form.songs[0].object_id
|
120
|
-
form.songs[1].object_id
|
121
|
-
form.songs[1].composer.object_id
|
122
|
-
form.artist.object_id
|
123
|
-
|
111
|
+
assert_equal form.songs[0].object_id, object_ids[:song]
|
112
|
+
assert_equal form.songs[1].object_id, object_ids[:song_with_composer]
|
113
|
+
assert_equal form.songs[1].composer.object_id, object_ids[:composer]
|
114
|
+
assert_equal form.artist.object_id, object_ids[:artist]
|
124
115
|
|
125
116
|
# model has not changed, yet.
|
126
|
-
album.name
|
127
|
-
album.songs[0].title
|
128
|
-
album.songs[1].title
|
129
|
-
album.songs[1].composer.name
|
130
|
-
album.artist.name
|
117
|
+
assert_equal album.name, "The Dissent Of Man"
|
118
|
+
assert_equal album.songs[0].title, "Broken"
|
119
|
+
assert_equal album.songs[1].title, "Resist Stance"
|
120
|
+
assert_equal album.songs[1].composer.name, "Greg Graffin"
|
121
|
+
assert_equal album.artist.name, "Bad Religion"
|
131
122
|
end
|
132
123
|
|
133
124
|
# with symbols.
|
134
125
|
it do
|
135
|
-
form.validate(
|
126
|
+
assert form.validate(
|
136
127
|
name: "Best Of",
|
137
128
|
songs: [{title: "The X-Creep"}, {title: "Trudging", composer: {name: "SNFU"}}],
|
138
|
-
artist: {name: "The Police"}
|
139
|
-
)
|
140
|
-
|
141
|
-
form.name
|
142
|
-
form.songs[0].title
|
143
|
-
form.songs[1].title
|
144
|
-
form.songs[1].composer.name
|
145
|
-
form.artist.name
|
129
|
+
artist: {name: "The Police"}
|
130
|
+
)
|
131
|
+
|
132
|
+
assert_equal form.name, "Best Of"
|
133
|
+
assert_equal form.songs[0].title, "The X-Creep"
|
134
|
+
assert_equal form.songs[1].title, "Trudging"
|
135
|
+
assert_equal form.songs[1].composer.name, "SNFU"
|
136
|
+
assert_equal form.artist.name, "The Police"
|
146
137
|
end
|
147
138
|
|
148
139
|
# throws exception when no populators.
|
@@ -156,120 +147,113 @@ class ValidateWithoutConfigurationTest < MiniTest::Spec
|
|
156
147
|
end
|
157
148
|
|
158
149
|
class ValidateWithInternalPopulatorOptionTest < MiniTest::Spec
|
159
|
-
Song = Struct.new(:title, :album, :composer)
|
160
|
-
Album = Struct.new(:name, :songs, :artist)
|
161
|
-
Artist = Struct.new(:name)
|
162
|
-
|
163
150
|
class AlbumForm < TestForm
|
164
151
|
property :name
|
165
152
|
validation do
|
166
|
-
required(:name).filled
|
153
|
+
params { required(:name).filled }
|
167
154
|
end
|
168
155
|
|
169
156
|
collection :songs,
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
157
|
+
internal_populator: ->(input, options) {
|
158
|
+
collection = options[:represented].songs
|
159
|
+
(item = collection[options[:index]]) ? item : collection.insert(options[:index], Song.new)
|
160
|
+
} do
|
174
161
|
property :title
|
175
162
|
validation do
|
176
|
-
required(:title).filled
|
163
|
+
params { required(:title).filled }
|
177
164
|
end
|
178
165
|
|
179
|
-
property :composer, internal_populator:
|
166
|
+
property :composer, internal_populator: ->(input, options) { (item = options[:represented].composer) ? item : Artist.new } do
|
180
167
|
property :name
|
181
168
|
validation do
|
182
|
-
required(:name).filled
|
169
|
+
params { required(:name).filled }
|
183
170
|
end
|
184
171
|
end
|
185
172
|
end
|
186
173
|
|
187
|
-
property :artist, internal_populator:
|
174
|
+
property :artist, internal_populator: ->(input, options) { (item = options[:represented].artist) ? item : Artist.new } do
|
188
175
|
property :name
|
189
176
|
validation do
|
190
|
-
required(:name).filled
|
177
|
+
params { required(:name).filled }
|
191
178
|
end
|
192
179
|
end
|
193
180
|
end
|
194
181
|
|
195
|
-
let
|
196
|
-
let
|
197
|
-
let
|
198
|
-
let
|
199
|
-
let
|
182
|
+
let(:song) { Song.new("Broken") }
|
183
|
+
let(:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
184
|
+
let(:composer) { Artist.new("Greg Graffin") }
|
185
|
+
let(:artist) { Artist.new("Bad Religion") }
|
186
|
+
let(:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
|
200
187
|
|
201
|
-
let
|
188
|
+
let(:form) { AlbumForm.new(album) }
|
202
189
|
|
203
190
|
# valid.
|
204
191
|
it("xxx") do
|
205
|
-
form.validate(
|
192
|
+
assert form.validate(
|
206
193
|
"name" => "Best Of",
|
207
194
|
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne", "composer" => {"name" => "Sting"}}],
|
208
|
-
"artist" => {"name" => "The Police"}
|
209
|
-
)
|
195
|
+
"artist" => {"name" => "The Police"}
|
196
|
+
)
|
210
197
|
|
211
|
-
form.errors.messages.inspect
|
198
|
+
assert_equal form.errors.messages.inspect, "{}"
|
212
199
|
|
213
200
|
# form has updated.
|
214
|
-
form.name
|
215
|
-
form.songs[0].title
|
216
|
-
form.songs[1].title
|
217
|
-
form.songs[1].composer.name
|
218
|
-
form.artist.name
|
219
|
-
|
201
|
+
assert_equal form.name, "Best Of"
|
202
|
+
assert_equal form.songs[0].title, "Fallout"
|
203
|
+
assert_equal form.songs[1].title, "Roxanne"
|
204
|
+
assert_equal form.songs[1].composer.name, "Sting"
|
205
|
+
assert_equal form.artist.name, "The Police"
|
220
206
|
|
221
207
|
# model has not changed, yet.
|
222
|
-
album.name
|
223
|
-
album.songs[0].title
|
224
|
-
album.songs[1].title
|
225
|
-
album.songs[1].composer.name
|
226
|
-
album.artist.name
|
208
|
+
assert_equal album.name, "The Dissent Of Man"
|
209
|
+
assert_equal album.songs[0].title, "Broken"
|
210
|
+
assert_equal album.songs[1].title, "Resist Stance"
|
211
|
+
assert_equal album.songs[1].composer.name, "Greg Graffin"
|
212
|
+
assert_equal album.artist.name, "Bad Religion"
|
227
213
|
end
|
228
214
|
|
229
215
|
# invalid.
|
230
216
|
it do
|
231
|
-
form.validate(
|
217
|
+
assert_equal form.validate(
|
232
218
|
"name" => "",
|
233
219
|
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne", "composer" => {"name" => ""}}],
|
234
220
|
"artist" => {"name" => ""},
|
235
|
-
)
|
221
|
+
), false
|
236
222
|
|
237
|
-
form.errors.messages.inspect
|
223
|
+
assert_equal form.errors.messages.inspect, "{:name=>[\"must be filled\"], :\"songs.composer.name\"=>[\"must be filled\"], :\"artist.name\"=>[\"must be filled\"]}"
|
238
224
|
end
|
239
225
|
|
240
226
|
# adding to collection via :instance.
|
241
227
|
# valid.
|
242
228
|
it do
|
243
|
-
form.validate(
|
244
|
-
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}, {"title" => "Rime Of The Ancient Mariner"}]
|
245
|
-
)
|
229
|
+
assert form.validate(
|
230
|
+
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}, {"title" => "Rime Of The Ancient Mariner"}]
|
231
|
+
)
|
246
232
|
|
247
|
-
form.errors.messages.inspect
|
233
|
+
assert_equal form.errors.messages.inspect, "{}"
|
248
234
|
|
249
235
|
# form has updated.
|
250
|
-
form.name
|
251
|
-
form.songs[0].title
|
252
|
-
form.songs[1].title
|
253
|
-
form.songs[1].composer.name
|
254
|
-
form.songs[1].title
|
255
|
-
form.songs[2].title
|
256
|
-
form.songs.size
|
257
|
-
form.artist.name
|
258
|
-
|
236
|
+
assert_equal form.name, "The Dissent Of Man"
|
237
|
+
assert_equal form.songs[0].title, "Fallout"
|
238
|
+
assert_equal form.songs[1].title, "Roxanne"
|
239
|
+
assert_equal form.songs[1].composer.name, "Greg Graffin"
|
240
|
+
assert_equal form.songs[1].title, "Roxanne"
|
241
|
+
assert_equal form.songs[2].title, "Rime Of The Ancient Mariner" # new song added.
|
242
|
+
assert_equal form.songs.size, 3
|
243
|
+
assert_equal form.artist.name, "Bad Religion"
|
259
244
|
|
260
245
|
# model has not changed, yet.
|
261
|
-
album.name
|
262
|
-
album.songs[0].title
|
263
|
-
album.songs[1].title
|
264
|
-
album.songs[1].composer.name
|
265
|
-
album.songs.size
|
266
|
-
album.artist.name
|
246
|
+
assert_equal album.name, "The Dissent Of Man"
|
247
|
+
assert_equal album.songs[0].title, "Broken"
|
248
|
+
assert_equal album.songs[1].title, "Resist Stance"
|
249
|
+
assert_equal album.songs[1].composer.name, "Greg Graffin"
|
250
|
+
assert_equal album.songs.size, 2
|
251
|
+
assert_equal album.artist.name, "Bad Religion"
|
267
252
|
end
|
268
253
|
|
269
|
-
|
270
254
|
# allow writeable: false even in the deserializer.
|
271
255
|
class SongForm < TestForm
|
272
|
-
property :title, deserializer: {
|
256
|
+
property :title, deserializer: {writeable: false}
|
273
257
|
end
|
274
258
|
|
275
259
|
it do
|
@@ -278,13 +262,57 @@ class ValidateWithInternalPopulatorOptionTest < MiniTest::Spec
|
|
278
262
|
assert_nil form.title
|
279
263
|
form.title = "Unopened"
|
280
264
|
form.sync # only the deserializer is marked as not-writeable.
|
281
|
-
song.title
|
265
|
+
assert_equal song.title, "Unopened"
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
# memory leak test
|
270
|
+
class ValidateUsingDifferentFormObject < MiniTest::Spec
|
271
|
+
class AlbumForm < TestForm
|
272
|
+
property :name
|
273
|
+
|
274
|
+
validation do
|
275
|
+
option :form
|
276
|
+
|
277
|
+
params { required(:name).filled(:str?) }
|
278
|
+
|
279
|
+
rule(:name) do
|
280
|
+
if form.name == 'invalid'
|
281
|
+
key.failure('Invalid name')
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
let(:album) { Album.new }
|
288
|
+
|
289
|
+
let(:form) { AlbumForm.new(album) }
|
290
|
+
|
291
|
+
it 'sets name correctly' do
|
292
|
+
assert form.validate(name: 'valid')
|
293
|
+
form.sync
|
294
|
+
assert_equal form.model.name, 'valid'
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'validates presence of name' do
|
298
|
+
refute form.validate(name: nil)
|
299
|
+
assert_equal form.errors[:name], ["must be filled"]
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'validates type of name' do
|
303
|
+
refute form.validate(name: 1)
|
304
|
+
assert_equal form.errors[:name], ["must be a string"]
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'when name is invalid' do
|
308
|
+
refute form.validate(name: 'invalid')
|
309
|
+
assert_equal form.errors[:name], ["Invalid name"]
|
282
310
|
end
|
283
311
|
end
|
284
312
|
|
285
313
|
# # not sure if we should catch that in Reform or rather do that in disposable. this is https://github.com/trailblazer/reform/pull/104
|
286
314
|
# # describe ":populator with :empty" do
|
287
|
-
# # let
|
315
|
+
# # let(:form) {
|
288
316
|
# # Class.new(Reform::Form) do
|
289
317
|
# # collection :songs, :empty => true, :populator => lambda { |fragment, index, args|
|
290
318
|
# # songs[index] = args.binding[:form].new(Song.new)
|
@@ -294,7 +322,7 @@ end
|
|
294
322
|
# # end
|
295
323
|
# # }
|
296
324
|
|
297
|
-
# # let
|
325
|
+
# # let(:params) {
|
298
326
|
# # {
|
299
327
|
# # "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}]
|
300
328
|
# # }
|
@@ -308,10 +336,9 @@ end
|
|
308
336
|
# # it { subject.songs[1].title.must_equal "Roxanne" }
|
309
337
|
# # end
|
310
338
|
|
311
|
-
|
312
339
|
# # test cardinalities.
|
313
340
|
# describe "with empty collection and cardinality" do
|
314
|
-
# let
|
341
|
+
# let(:album) { Album.new }
|
315
342
|
|
316
343
|
# subject { Class.new(Reform::Form) do
|
317
344
|
# include Reform::Form::ActiveModel
|
@@ -329,7 +356,6 @@ end
|
|
329
356
|
# validates :hit, :presence => true
|
330
357
|
# end.new(album) }
|
331
358
|
|
332
|
-
|
333
359
|
# describe "invalid" do
|
334
360
|
# before { subject.validate({}).must_equal false }
|
335
361
|
|
@@ -342,9 +368,8 @@ end
|
|
342
368
|
# end
|
343
369
|
# end
|
344
370
|
|
345
|
-
|
346
371
|
# describe "valid" do
|
347
|
-
# let
|
372
|
+
# let(:album) { Album.new(nil, Song.new, [Song.new("Urban Myth")]) }
|
348
373
|
|
349
374
|
# before {
|
350
375
|
# subject.validate({"songs" => [{"title"=>"Daddy, Brother, Lover, Little Boy"}], "hit" => {"title"=>"The Horse"}}).
|
@@ -355,13 +380,9 @@ end
|
|
355
380
|
# end
|
356
381
|
# end
|
357
382
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
383
|
# # providing manual validator method allows accessing form's API.
|
363
384
|
# describe "with ::validate" do
|
364
|
-
# let
|
385
|
+
# let(:form) {
|
365
386
|
# Class.new(Reform::Form) do
|
366
387
|
# property :title
|
367
388
|
|
@@ -373,8 +394,8 @@ end
|
|
373
394
|
# end
|
374
395
|
# }
|
375
396
|
|
376
|
-
# let
|
377
|
-
# let
|
397
|
+
# let(:params) { {"title" => "Fallout"} }
|
398
|
+
# let(:song) { Song.new("Englishman") }
|
378
399
|
|
379
400
|
# subject { form.new(song) }
|
380
401
|
|
@@ -384,10 +405,9 @@ end
|
|
384
405
|
# it { subject.errors.messages.must_equal({:title=>["not lowercase"]}) }
|
385
406
|
# end
|
386
407
|
|
387
|
-
|
388
408
|
# # overriding the reader for a nested form should only be considered when rendering.
|
389
409
|
# describe "with overridden reader for nested form" do
|
390
|
-
# let
|
410
|
+
# let(:form) {
|
391
411
|
# Class.new(Reform::Form) do
|
392
412
|
# property :band, :populate_if_empty => lambda { |*| Band.new } do
|
393
413
|
# property :label
|
@@ -407,7 +427,7 @@ end
|
|
407
427
|
# end.new(album)
|
408
428
|
# }
|
409
429
|
|
410
|
-
# let
|
430
|
+
# let(:album) { Album.new }
|
411
431
|
|
412
432
|
# # don't use #artist when validating!
|
413
433
|
# it do
|