reform 2.2.4 → 2.3.0.rc1
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/.travis.yml +13 -7
- data/CHANGES.md +26 -4
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +1 -12
- data/ISSUE_TEMPLATE.md +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/lib/reform.rb +1 -0
- data/lib/reform/contract.rb +1 -11
- data/lib/reform/contract/validate.rb +49 -23
- data/lib/reform/errors.rb +49 -0
- data/lib/reform/form.rb +20 -5
- data/lib/reform/form/dry.rb +57 -29
- data/lib/reform/form/populator.rb +2 -16
- data/lib/reform/form/prepopulate.rb +1 -1
- data/lib/reform/form/validate.rb +10 -2
- data/lib/reform/result.rb +63 -0
- data/lib/reform/validation.rb +19 -13
- data/lib/reform/validation/groups.rb +11 -25
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +7 -6
- data/test/benchmarking.rb +39 -5
- data/test/call_test.rb +1 -1
- data/test/changed_test.rb +1 -1
- data/test/coercion_test.rb +2 -2
- data/test/composition_test.rb +47 -9
- data/test/contract_test.rb +5 -5
- data/test/default_test.rb +1 -1
- data/test/deserialize_test.rb +3 -3
- data/test/errors_test.rb +36 -21
- data/test/feature_test.rb +1 -1
- data/test/fixtures/dry_error_messages.yml +70 -23
- data/test/form_option_test.rb +3 -3
- data/test/form_test.rb +3 -3
- data/test/from_test.rb +2 -2
- data/test/inherit_test.rb +44 -51
- data/test/module_test.rb +12 -12
- data/test/parse_option_test.rb +40 -0
- data/test/parse_pipeline_test.rb +2 -2
- data/test/populate_test.rb +59 -19
- data/test/populator_skip_test.rb +9 -8
- data/test/prepopulator_test.rb +3 -3
- data/test/readable_test.rb +2 -2
- data/test/readonly_test.rb +1 -1
- data/test/reform_test.rb +16 -31
- data/test/save_test.rb +23 -8
- data/test/setup_test.rb +2 -2
- data/test/skip_if_test.rb +4 -4
- data/test/skip_setter_and_getter_test.rb +1 -1
- data/test/test_helper.rb +13 -10
- data/test/validate_test.rb +18 -18
- data/test/validation/dry_validation_test.rb +430 -117
- data/test/validation/result_test.rb +79 -0
- data/test/validation_library_provided_test.rb +16 -0
- data/test/virtual_test.rb +1 -1
- data/test/writeable_test.rb +31 -2
- metadata +42 -23
- data/gemfiles/Gemfile.disposable-0.3 +0 -6
- data/lib/reform/contract/errors.rb +0 -43
- data/lib/reform/form/mongoid.rb +0 -37
- data/lib/reform/form/orm.rb +0 -26
- data/lib/reform/mongoid.rb +0 -4
- data/test/deprecation_test.rb +0 -27
- data/test/validation/dry_test.rb +0 -60
- data/test/validation/errors.yml +0 -4
data/test/contract_test.rb
CHANGED
@@ -5,30 +5,30 @@ class ContractTest < MiniTest::Spec
|
|
5
5
|
Album = Struct.new(:name, :duration, :songs, :artist)
|
6
6
|
Artist = Struct.new(:name)
|
7
7
|
|
8
|
-
class ArtistForm <
|
8
|
+
class ArtistForm < TestForm
|
9
9
|
property :name
|
10
10
|
end
|
11
11
|
|
12
|
-
class AlbumForm <
|
12
|
+
class AlbumForm < TestContract
|
13
13
|
property :name
|
14
14
|
|
15
15
|
properties :duration
|
16
16
|
properties :year, :style, readable: false
|
17
17
|
|
18
18
|
validation do
|
19
|
-
|
19
|
+
required(:name).filled
|
20
20
|
end
|
21
21
|
|
22
22
|
collection :songs do
|
23
23
|
property :title
|
24
24
|
validation do
|
25
|
-
|
25
|
+
required(:title).filled
|
26
26
|
end
|
27
27
|
|
28
28
|
property :composer do
|
29
29
|
property :name
|
30
30
|
validation do
|
31
|
-
|
31
|
+
required(:name).filled
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/test/default_test.rb
CHANGED
data/test/deserialize_test.rb
CHANGED
@@ -6,7 +6,7 @@ class DeserializeTest < MiniTest::Spec
|
|
6
6
|
Album = Struct.new(:title, :artist)
|
7
7
|
Artist = Struct.new(:name, :callname)
|
8
8
|
|
9
|
-
class JsonAlbumForm <
|
9
|
+
class JsonAlbumForm < TestForm
|
10
10
|
module Json
|
11
11
|
def deserialize(params)
|
12
12
|
deserializer.new(self).
|
@@ -49,7 +49,7 @@ class DeserializeTest < MiniTest::Spec
|
|
49
49
|
end
|
50
50
|
|
51
51
|
describe "infering the deserializer from another form should NOT copy its populators" do
|
52
|
-
class CompilationForm <
|
52
|
+
class CompilationForm < TestForm
|
53
53
|
property :artist, populator: ->(options) { self.artist = Artist.new(nil, options[:fragment].to_s) } do
|
54
54
|
property :name
|
55
55
|
end
|
@@ -75,7 +75,7 @@ class ValidateWithBlockTest < MiniTest::Spec
|
|
75
75
|
Album = Struct.new(:title, :artist)
|
76
76
|
Artist = Struct.new(:name)
|
77
77
|
|
78
|
-
class AlbumForm <
|
78
|
+
class AlbumForm < TestForm
|
79
79
|
property :title
|
80
80
|
property :artist, populate_if_empty: Artist do
|
81
81
|
property :name
|
data/test/errors_test.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
|
+
# TODO:
|
4
|
+
# This test should, at some point soon, only test the `Errors` object and its
|
5
|
+
# Rails-ish API. No validation specifics, etc. to be tested here.
|
6
|
+
|
3
7
|
class ErrorsTest < MiniTest::Spec
|
4
|
-
class AlbumForm <
|
8
|
+
class AlbumForm < TestForm
|
5
9
|
property :title
|
6
10
|
|
7
11
|
property :hit do
|
@@ -29,23 +33,16 @@ class ErrorsTest < MiniTest::Spec
|
|
29
33
|
# TODO: make band a required object.
|
30
34
|
|
31
35
|
validation do
|
32
|
-
# required(:name).filled(:music_taste_ok?)
|
33
|
-
|
34
36
|
configure do
|
35
|
-
config.messages_file = "test/
|
37
|
+
config.messages_file = "test/fixtures/dry_error_messages.yml"
|
36
38
|
|
37
|
-
def
|
39
|
+
def good_musical_taste?(value)
|
38
40
|
value != "Nickelback"
|
39
|
-
# errors.add(:base, "You are a bad person") if name == "Nickelback"
|
40
41
|
end
|
41
42
|
end
|
42
|
-
end
|
43
|
-
# validate :music_taste_ok?
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
# errors.add(:base, "You are a bad person") if name == "Nickelback"
|
48
|
-
# end
|
44
|
+
required(:name).filled(:good_musical_taste?)
|
45
|
+
end
|
49
46
|
end
|
50
47
|
|
51
48
|
validation do
|
@@ -58,8 +55,7 @@ class ErrorsTest < MiniTest::Spec
|
|
58
55
|
:title => "Blackhawks Over Los Angeles",
|
59
56
|
:hit => song,
|
60
57
|
:songs => songs, # TODO: document this requirement,
|
61
|
-
|
62
|
-
:band => Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
|
58
|
+
:band => Struct.new(:name, :label).new("Epitaph", OpenStruct.new),
|
63
59
|
)
|
64
60
|
end
|
65
61
|
let (:song) { OpenStruct.new(:title => "Downtown") }
|
@@ -67,18 +63,24 @@ class ErrorsTest < MiniTest::Spec
|
|
67
63
|
let (:form) { AlbumForm.new(album) }
|
68
64
|
|
69
65
|
|
70
|
-
describe "
|
66
|
+
describe "#errors without #validate" do
|
67
|
+
it do
|
68
|
+
form.errors.size.must_equal 0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "blank everywhere" do
|
71
73
|
before { form.validate(
|
72
74
|
"hit" =>{"title" => ""},
|
73
75
|
"title" => "",
|
74
|
-
"songs" => [{"title" => ""}, {"title" => ""}]) } # FIXME: what happens if item
|
76
|
+
"songs" => [{"title" => ""}, {"title" => ""}]) } # FIXME: what happens if item must be filled?
|
75
77
|
|
76
78
|
it do
|
77
79
|
form.errors.messages.must_equal({
|
78
80
|
:title => ["must be filled"],
|
79
81
|
:"hit.title"=>["must be filled"],
|
80
82
|
:"songs.title"=>["must be filled"],
|
81
|
-
:"band.label.name"=>["
|
83
|
+
:"band.label.name"=>["must be filled"]
|
82
84
|
})
|
83
85
|
end
|
84
86
|
|
@@ -96,8 +98,9 @@ class ErrorsTest < MiniTest::Spec
|
|
96
98
|
:title => ["must be filled"],
|
97
99
|
:"hit.title" => ["must be filled"],
|
98
100
|
:"songs.title"=> ["must be filled"],
|
99
|
-
:"band.label.name"=>["
|
101
|
+
:"band.label.name"=>["must be filled"]
|
100
102
|
})
|
103
|
+
form.errors.size.must_equal(4)
|
101
104
|
end
|
102
105
|
end
|
103
106
|
|
@@ -106,6 +109,7 @@ class ErrorsTest < MiniTest::Spec
|
|
106
109
|
it do
|
107
110
|
form.validate("title"=>"", "band"=>{"label"=>{:name => "Fat Wreck"}}).must_equal false
|
108
111
|
form.errors.messages.must_equal({:title=>["must be filled"]})
|
112
|
+
form.errors.size.must_equal(1)
|
109
113
|
end
|
110
114
|
end
|
111
115
|
|
@@ -115,6 +119,7 @@ class ErrorsTest < MiniTest::Spec
|
|
115
119
|
|
116
120
|
it { @result.must_equal false }
|
117
121
|
it { form.errors.messages.must_equal({:"hit.title"=>["must be filled"]}) }
|
122
|
+
it { form.errors.size.must_equal(1) }
|
118
123
|
end
|
119
124
|
|
120
125
|
|
@@ -123,6 +128,7 @@ class ErrorsTest < MiniTest::Spec
|
|
123
128
|
|
124
129
|
it { @result.must_equal false }
|
125
130
|
it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"]}) }
|
131
|
+
it { form.errors.size.must_equal(1) }
|
126
132
|
end
|
127
133
|
|
128
134
|
|
@@ -130,14 +136,16 @@ class ErrorsTest < MiniTest::Spec
|
|
130
136
|
before { @result = form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}}) }
|
131
137
|
|
132
138
|
it { @result.must_equal false }
|
133
|
-
it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"], :"band.label.name"=>["
|
139
|
+
it { form.errors.messages.must_equal({:"songs.title"=>["must be filled"], :"band.label.name"=>["must be filled"]}) }
|
140
|
+
it { form.errors.size.must_equal(2) }
|
134
141
|
end
|
135
142
|
|
136
143
|
describe "#validate with nested form using :base invalid" do
|
137
144
|
it do
|
138
145
|
result = form.validate("songs"=>[{"title" => "Someday"}], "band" => {"name" => "Nickelback", "label" => {"name" => "Roadrunner Records"}})
|
139
146
|
result.must_equal false
|
140
|
-
form.errors.messages.must_equal({:"band.name"=>["
|
147
|
+
form.errors.messages.must_equal({:"band.name"=>["you're a bad person"]})
|
148
|
+
form.errors.size.must_equal(1)
|
141
149
|
end
|
142
150
|
end
|
143
151
|
|
@@ -153,6 +161,11 @@ class ErrorsTest < MiniTest::Spec
|
|
153
161
|
it { form.hit.title.must_equal "Sacrifice" }
|
154
162
|
it { form.title.must_equal "Second Heat" }
|
155
163
|
it { form.songs.first.title.must_equal "Heart Of A Lion" }
|
164
|
+
it do
|
165
|
+
skip "WE DON'T NEED COUNT AND EMPTY? ON THE CORE ERRORS OBJECT"
|
166
|
+
form.errors.size.must_equal(0)
|
167
|
+
form.errors.empty?.must_equal(true)
|
168
|
+
end
|
156
169
|
end
|
157
170
|
|
158
171
|
|
@@ -160,6 +173,8 @@ class ErrorsTest < MiniTest::Spec
|
|
160
173
|
before { form.validate("songs"=>[{"title" => ""}], "band" => {"label" => {}}) }
|
161
174
|
|
162
175
|
# to_s is aliased to messages
|
163
|
-
it {
|
176
|
+
it {
|
177
|
+
skip "why do we need Errors#to_s ?"
|
178
|
+
form.errors.to_s.must_equal "{:\"songs.title\"=>[\"must be filled\"], :\"band.label.name\"=>[\"must be filled\"]}" }
|
164
179
|
end
|
165
180
|
end
|
data/test/feature_test.rb
CHANGED
@@ -1,44 +1,91 @@
|
|
1
|
-
|
1
|
+
en:
|
2
|
+
errors:
|
3
|
+
array?: "must be an array"
|
2
4
|
|
3
|
-
empty?: "
|
5
|
+
empty?: "must be empty"
|
4
6
|
|
5
|
-
|
7
|
+
excludes?: "must not include %{value}"
|
6
8
|
|
7
|
-
|
9
|
+
excluded_from?:
|
10
|
+
arg:
|
11
|
+
default: "must not be one of: %{list}"
|
12
|
+
range: "must not be one of: %{list_left} - %{list_right}"
|
8
13
|
|
9
|
-
|
14
|
+
eql?: "must be equal to %{left}"
|
10
15
|
|
11
|
-
|
16
|
+
not_eql?: "must not be equal to %{left}"
|
12
17
|
|
13
|
-
|
18
|
+
filled?: "must be filled"
|
14
19
|
|
15
|
-
|
20
|
+
format?: "is in invalid format"
|
16
21
|
|
17
|
-
|
22
|
+
number?: "must be a number"
|
18
23
|
|
19
|
-
|
24
|
+
odd?: "must be odd"
|
20
25
|
|
21
|
-
|
26
|
+
even?: "must be even"
|
22
27
|
|
23
|
-
|
28
|
+
gt?: "must be greater than %{num}"
|
24
29
|
|
25
|
-
|
30
|
+
gteq?: "must be greater than or equal to %{num}"
|
26
31
|
|
27
|
-
|
32
|
+
hash?: "must be a hash"
|
28
33
|
|
29
|
-
|
34
|
+
included_in?:
|
35
|
+
arg:
|
36
|
+
default: "must be one of: %{list}"
|
37
|
+
range: "must be one of: %{list_left} - %{list_right}"
|
30
38
|
|
31
|
-
|
39
|
+
includes?: "must include %{value}"
|
32
40
|
|
33
|
-
|
41
|
+
bool?: "must be boolean"
|
34
42
|
|
35
|
-
|
36
|
-
range: "%{name} size must be within %{left} - %{right}"
|
37
|
-
default: "%{name} size must be %{num}"
|
43
|
+
true?: "must be true"
|
38
44
|
|
39
|
-
|
45
|
+
false?: "must be false"
|
40
46
|
|
41
|
-
|
47
|
+
int?: "must be an integer"
|
42
48
|
|
43
|
-
|
49
|
+
float?: "must be a float"
|
44
50
|
|
51
|
+
decimal?: "must be a decimal"
|
52
|
+
|
53
|
+
date?: "must be a date"
|
54
|
+
|
55
|
+
date_time?: "must be a date time"
|
56
|
+
|
57
|
+
time?: "must be a time"
|
58
|
+
|
59
|
+
key?: "is missing"
|
60
|
+
|
61
|
+
attr?: "is missing"
|
62
|
+
|
63
|
+
lt?: "must be less than %{num}"
|
64
|
+
|
65
|
+
lteq?: "must be less than or equal to %{num}"
|
66
|
+
|
67
|
+
max_size?: "size cannot be greater than %{num}"
|
68
|
+
|
69
|
+
min_size?: "size cannot be less than %{num}"
|
70
|
+
|
71
|
+
none?: "cannot be defined"
|
72
|
+
|
73
|
+
str?: "must be a string"
|
74
|
+
|
75
|
+
type?: "must be %{type}"
|
76
|
+
|
77
|
+
size?:
|
78
|
+
arg:
|
79
|
+
default: "size must be %{size}"
|
80
|
+
range: "size must be within %{size_left} - %{size_right}"
|
81
|
+
|
82
|
+
value:
|
83
|
+
string:
|
84
|
+
arg:
|
85
|
+
default: "length must be %{size}"
|
86
|
+
range: "length must be within %{size_left} - %{size_right}"
|
87
|
+
|
88
|
+
good_musical_taste?: "you're a bad person"
|
89
|
+
de:
|
90
|
+
errors:
|
91
|
+
filled?: "muss abgefüllt sein"
|
data/test/form_option_test.rb
CHANGED
@@ -4,14 +4,14 @@ class FormOptionTest < MiniTest::Spec
|
|
4
4
|
Song = Struct.new(:title)
|
5
5
|
Album = Struct.new(:song)
|
6
6
|
|
7
|
-
class SongForm <
|
7
|
+
class SongForm < TestForm
|
8
8
|
property :title
|
9
9
|
validation do
|
10
|
-
|
10
|
+
required(:title).filled
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
class AlbumForm <
|
14
|
+
class AlbumForm < TestForm
|
15
15
|
property :song, form: SongForm
|
16
16
|
end
|
17
17
|
|
data/test/form_test.rb
CHANGED
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
class FormTest < MiniTest::Spec
|
4
4
|
Artist = Struct.new(:name)
|
5
5
|
|
6
|
-
class AlbumForm <
|
6
|
+
class AlbumForm < TestForm
|
7
7
|
property :title
|
8
8
|
|
9
9
|
property :hit do
|
@@ -37,7 +37,7 @@ class FormTest < MiniTest::Spec
|
|
37
37
|
end
|
38
38
|
|
39
39
|
cloned.validation do
|
40
|
-
|
40
|
+
required(:title).filled
|
41
41
|
end
|
42
42
|
|
43
43
|
cloned.new(OpenStruct.new).validate({})
|
@@ -45,7 +45,7 @@ class FormTest < MiniTest::Spec
|
|
45
45
|
end
|
46
46
|
|
47
47
|
describe "#initialize" do
|
48
|
-
class ArtistForm <
|
48
|
+
class ArtistForm < TestForm
|
49
49
|
property :name
|
50
50
|
property :current_user, virtual: true
|
51
51
|
end
|
data/test/from_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class AsTest < BaseTest
|
4
|
-
class AlbumForm <
|
4
|
+
class AlbumForm < TestForm
|
5
5
|
property :name, from: :title
|
6
6
|
|
7
7
|
property :single, from: :hit do
|
@@ -69,7 +69,7 @@ class AsTest < BaseTest
|
|
69
69
|
hash = nested_hash
|
70
70
|
end
|
71
71
|
|
72
|
-
hash.must_equal({"title"=>"Best Of The Police", "hit"=>{"title"=>"So Lonely"}, "songs"=>[{"title"=>"Message In A Bottle"}, {"title"=>"Roxanne"}]})
|
72
|
+
hash.must_equal({"title"=>"Best Of The Police", "hit"=>{"title"=>"So Lonely"}, "songs"=>[{"title"=>"Message In A Bottle"}, {"title"=>"Roxanne"}], "band"=> nil})
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
data/test/inherit_test.rb
CHANGED
@@ -4,72 +4,66 @@ require 'representable/json'
|
|
4
4
|
class InheritTest < BaseTest
|
5
5
|
Populator = Reform::Form::Populator
|
6
6
|
|
7
|
-
class
|
7
|
+
class SkipParse
|
8
|
+
include Uber::Callable
|
9
|
+
def call(*args)
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class AlbumForm < TestForm
|
8
15
|
property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
|
9
16
|
|
10
|
-
property :hit,
|
17
|
+
property :hit, populate_if_empty: -> (*) { Song.new } do
|
11
18
|
property :title
|
19
|
+
validation do
|
20
|
+
required(:title).filled
|
21
|
+
end
|
12
22
|
end
|
13
23
|
|
14
24
|
collection :songs, populate_if_empty: lambda {}, skip_if: :all_blank do
|
15
25
|
property :title
|
16
26
|
end
|
17
27
|
|
18
|
-
property :
|
28
|
+
property :band, populate_if_empty: lambda {} do
|
19
29
|
|
20
|
-
def
|
30
|
+
def band_id
|
21
31
|
1
|
22
32
|
end
|
23
33
|
end
|
24
34
|
end
|
25
35
|
|
26
|
-
puts
|
27
|
-
puts "inherit"
|
28
|
-
|
29
36
|
class CompilationForm < AlbumForm
|
30
37
|
property :title, inherit: true, skip_if: "skip_if from CompilationForm"
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# puts representer_class.representable_attrs.
|
38
|
-
# get(:hit)[:extend].evaluate(nil).new(OpenStruct.new).rating
|
38
|
+
property :hit, :inherit => true, populate_if_empty: -> (*) { Song.new }, skip_if: SkipParse.new do
|
39
|
+
property :rating
|
40
|
+
validation do
|
41
|
+
required(:rating).filled
|
42
|
+
end
|
43
|
+
end
|
39
44
|
|
40
45
|
# NO collection here, this is entirely inherited.
|
41
|
-
# collection :songs, ..
|
42
46
|
|
43
|
-
property :
|
47
|
+
property :band, inherit: true do # inherit everything, but explicitely.
|
44
48
|
end
|
45
|
-
|
46
|
-
# completely override.
|
47
|
-
property :hit, skip_if: "SkipParse" do
|
48
|
-
end
|
49
|
-
|
50
|
-
# override partly.
|
51
49
|
end
|
52
50
|
|
53
|
-
let (:album) { Album.new(nil,
|
51
|
+
let (:album) { Album.new(nil, Song.new, [], Band.new) }
|
54
52
|
subject { CompilationForm.new(album) }
|
55
53
|
|
54
|
+
it do
|
55
|
+
subject.validate({"hit" => {"title" => "LA Drone", "rating" => 10}})
|
56
|
+
subject.hit.title.must_equal "LA Drone"
|
57
|
+
subject.hit.rating.must_equal 10
|
58
|
+
subject.errors.messages.must_equal({})
|
59
|
+
end
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# }
|
64
|
-
|
65
|
-
# it do
|
66
|
-
# subject.validate({})
|
67
|
-
# subject.hit.title.must_equal nil
|
68
|
-
# subject.hit.rating.must_equal nil
|
69
|
-
# subject.errors.messages.must_equal({:"hit.title"=>["can't be blank"], :"hit.rating"=>["can't be blank"]})
|
70
|
-
# end
|
71
|
-
|
72
|
-
require "pp"
|
61
|
+
it do
|
62
|
+
subject.validate({})
|
63
|
+
assert_nil subject.model.hit.title
|
64
|
+
assert_nil subject.model.hit.rating
|
65
|
+
subject.errors.messages.must_equal({:"hit.title"=>["must be filled"], :"hit.rating"=>["must be filled"]})
|
66
|
+
end
|
73
67
|
|
74
68
|
it "xxx" do
|
75
69
|
# sub hashes like :deserializer must be properly cloned when inheriting.
|
@@ -79,14 +73,14 @@ require "pp"
|
|
79
73
|
AlbumForm.options_for(:title)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync
|
80
74
|
AlbumForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if in AlbumForm"
|
81
75
|
|
82
|
-
AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
|
76
|
+
# AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
|
83
77
|
# AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
|
84
78
|
|
85
79
|
|
86
80
|
AlbumForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
87
81
|
AlbumForm.options_for(:songs)[:deserializer][:skip_parse].must_be_instance_of Reform::Form::Validate::Skip::AllBlank
|
88
82
|
|
89
|
-
AlbumForm.options_for(:
|
83
|
+
AlbumForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
90
84
|
|
91
85
|
|
92
86
|
|
@@ -95,25 +89,24 @@ require "pp"
|
|
95
89
|
CompilationForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
96
90
|
|
97
91
|
|
98
|
-
CompilationForm.options_for(:
|
92
|
+
CompilationForm.options_for(:band)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
99
93
|
|
100
94
|
# completely overwrite inherited.
|
101
|
-
CompilationForm.options_for(:hit)[:
|
102
|
-
CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_equal "SkipParse"
|
95
|
+
CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_be_instance_of SkipParse
|
103
96
|
|
104
97
|
|
105
98
|
# inherit: true with block will still inherit the original class.
|
106
|
-
AlbumForm.new(OpenStruct.new(
|
107
|
-
CompilationForm.new(OpenStruct.new(
|
99
|
+
AlbumForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id.must_equal 1
|
100
|
+
CompilationForm.new(OpenStruct.new(band: OpenStruct.new)).band.band_id.must_equal 1
|
108
101
|
end
|
109
102
|
|
110
103
|
|
111
104
|
class CDForm < AlbumForm
|
112
|
-
# override :
|
113
|
-
property :
|
105
|
+
# override :band's original populate_if_empty but with :inherit.
|
106
|
+
property :band, inherit: true, populator: "CD Populator" do
|
114
107
|
|
115
108
|
end
|
116
109
|
end
|
117
110
|
|
118
|
-
it { CDForm.options_for(:
|
119
|
-
end
|
111
|
+
it { CDForm.options_for(:band)[:internal_populator].instance_variable_get(:@user_proc).must_equal "CD Populator" }
|
112
|
+
end
|