reform 2.2.4 → 2.3.3
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 +11 -6
- data/Appraisals +8 -0
- data/CHANGES.md +57 -4
- data/CONTRIBUTING.md +31 -0
- data/Gemfile +2 -16
- data/ISSUE_TEMPLATE.md +25 -0
- data/LICENSE.txt +1 -1
- data/README.md +5 -7
- data/Rakefile +16 -9
- data/gemfiles/0.13.0.gemfile +8 -0
- data/gemfiles/1.5.0.gemfile +9 -0
- data/lib/reform.rb +1 -0
- data/lib/reform/contract.rb +7 -17
- data/lib/reform/contract/custom_error.rb +41 -0
- data/lib/reform/contract/validate.rb +53 -23
- data/lib/reform/errors.rb +61 -0
- data/lib/reform/form.rb +36 -10
- data/lib/reform/form/call.rb +1 -1
- data/lib/reform/form/composition.rb +2 -2
- data/lib/reform/form/dry.rb +10 -58
- data/lib/reform/form/dry/input_hash.rb +37 -0
- data/lib/reform/form/dry/new_api.rb +45 -0
- data/lib/reform/form/dry/old_api.rb +61 -0
- data/lib/reform/form/populator.rb +11 -27
- data/lib/reform/form/prepopulate.rb +4 -3
- data/lib/reform/form/validate.rb +28 -13
- data/lib/reform/result.rb +90 -0
- data/lib/reform/validation.rb +19 -11
- data/lib/reform/validation/groups.rb +12 -27
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +14 -13
- data/test/benchmarking.rb +39 -6
- data/test/call_new_api.rb +23 -0
- data/test/call_old_api.rb +23 -0
- data/test/changed_test.rb +14 -14
- data/test/coercion_test.rb +57 -25
- data/test/composition_new_api.rb +186 -0
- data/test/composition_old_api.rb +184 -0
- data/test/contract/custom_error_test.rb +55 -0
- data/test/contract_new_api.rb +77 -0
- data/test/contract_old_api.rb +77 -0
- data/test/default_test.rb +4 -4
- data/test/deserialize_test.rb +17 -20
- data/test/errors_new_api.rb +225 -0
- data/test/errors_old_api.rb +230 -0
- data/test/feature_test.rb +10 -12
- data/test/fixtures/dry_error_messages.yml +73 -23
- data/test/fixtures/dry_new_api_error_messages.yml +104 -0
- data/test/form_new_api.rb +57 -0
- data/test/{form_test.rb → form_old_api.rb} +8 -8
- data/test/form_option_new_api.rb +24 -0
- data/test/{form_option_test.rb → form_option_old_api.rb} +5 -5
- data/test/from_test.rb +18 -22
- data/test/inherit_new_api.rb +105 -0
- data/test/inherit_old_api.rb +105 -0
- data/test/{module_test.rb → module_new_api.rb} +26 -31
- data/test/module_old_api.rb +146 -0
- data/test/parse_option_test.rb +40 -0
- data/test/parse_pipeline_test.rb +4 -4
- data/test/populate_new_api.rb +304 -0
- data/test/populate_old_api.rb +304 -0
- data/test/populator_skip_test.rb +11 -11
- data/test/prepopulator_test.rb +23 -24
- data/test/read_only_test.rb +12 -1
- data/test/readable_test.rb +9 -9
- data/test/reform_new_api.rb +204 -0
- data/test/{reform_test.rb → reform_old_api.rb} +44 -65
- data/test/save_new_api.rb +101 -0
- data/test/save_old_api.rb +101 -0
- data/test/setup_test.rb +17 -17
- data/test/skip_if_new_api.rb +85 -0
- data/test/skip_if_old_api.rb +92 -0
- data/test/skip_setter_and_getter_test.rb +9 -10
- data/test/test_helper.rb +25 -14
- data/test/validate_new_api.rb +453 -0
- data/test/{validate_test.rb → validate_old_api.rb} +121 -131
- data/test/validation/dry_validation_new_api.rb +835 -0
- data/test/validation/dry_validation_old_api.rb +772 -0
- data/test/validation/result_test.rb +77 -0
- data/test/validation_library_provided_test.rb +16 -0
- data/test/virtual_test.rb +47 -7
- data/test/writeable_test.rb +38 -9
- metadata +111 -56
- 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/call_test.rb +0 -23
- data/test/composition_test.rb +0 -149
- data/test/contract_test.rb +0 -77
- data/test/deprecation_test.rb +0 -27
- data/test/errors_test.rb +0 -165
- data/test/inherit_test.rb +0 -119
- data/test/populate_test.rb +0 -270
- data/test/readonly_test.rb +0 -14
- data/test/save_test.rb +0 -89
- data/test/skip_if_test.rb +0 -74
- data/test/validation/dry_test.rb +0 -60
- data/test/validation/dry_validation_test.rb +0 -352
- data/test/validation/errors.yml +0 -4
data/test/inherit_test.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'representable/json'
|
3
|
-
|
4
|
-
class InheritTest < BaseTest
|
5
|
-
Populator = Reform::Form::Populator
|
6
|
-
|
7
|
-
class AlbumForm < Reform::Form
|
8
|
-
property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
|
9
|
-
|
10
|
-
property :hit, populator: "Populator" do
|
11
|
-
property :title
|
12
|
-
end
|
13
|
-
|
14
|
-
collection :songs, populate_if_empty: lambda {}, skip_if: :all_blank do
|
15
|
-
property :title
|
16
|
-
end
|
17
|
-
|
18
|
-
property :artist, populate_if_empty: lambda {} do
|
19
|
-
|
20
|
-
def artist_id
|
21
|
-
1
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
puts
|
27
|
-
puts "inherit"
|
28
|
-
|
29
|
-
class CompilationForm < AlbumForm
|
30
|
-
property :title, inherit: true, skip_if: "skip_if from CompilationForm"
|
31
|
-
puts "[#{options_for(:title)[:deserializer].object_id}] COM@@@@@ #{options_for(:title)[:deserializer].inspect}"
|
32
|
-
# property :hit, :inherit => true do
|
33
|
-
# property :rating
|
34
|
-
# validates :title, :rating, :presence => true
|
35
|
-
# end
|
36
|
-
|
37
|
-
# puts representer_class.representable_attrs.
|
38
|
-
# get(:hit)[:extend].evaluate(nil).new(OpenStruct.new).rating
|
39
|
-
|
40
|
-
# NO collection here, this is entirely inherited.
|
41
|
-
# collection :songs, ..
|
42
|
-
|
43
|
-
property :artist, inherit: true do # inherit everything, but explicitely.
|
44
|
-
end
|
45
|
-
|
46
|
-
# completely override.
|
47
|
-
property :hit, skip_if: "SkipParse" do
|
48
|
-
end
|
49
|
-
|
50
|
-
# override partly.
|
51
|
-
end
|
52
|
-
|
53
|
-
let (:album) { Album.new(nil, OpenStruct.new(:hit => OpenStruct.new()) ) }
|
54
|
-
subject { CompilationForm.new(album) }
|
55
|
-
|
56
|
-
|
57
|
-
# valid.
|
58
|
-
# it {
|
59
|
-
# subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
|
60
|
-
# subject.hit.title.must_equal "LA Drone"
|
61
|
-
# subject.hit.rating.must_equal 10
|
62
|
-
# subject.errors.messages.must_equal({})
|
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"
|
73
|
-
|
74
|
-
it "xxx" do
|
75
|
-
# sub hashes like :deserializer must be properly cloned when inheriting.
|
76
|
-
AlbumForm.options_for(:title)[:deserializer].object_id.wont_equal CompilationForm.options_for(:title)[:deserializer].object_id
|
77
|
-
|
78
|
-
# don't overwrite direct deserializer: {} configuration.
|
79
|
-
AlbumForm.options_for(:title)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync
|
80
|
-
AlbumForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if in AlbumForm"
|
81
|
-
|
82
|
-
AlbumForm.options_for(:hit)[:internal_populator].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
|
83
|
-
# AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
|
84
|
-
|
85
|
-
|
86
|
-
AlbumForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
87
|
-
AlbumForm.options_for(:songs)[:deserializer][:skip_parse].must_be_instance_of Reform::Form::Validate::Skip::AllBlank
|
88
|
-
|
89
|
-
AlbumForm.options_for(:artist)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
CompilationForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if from CompilationForm"
|
94
|
-
# pp CompilationForm.options_for(:songs)
|
95
|
-
CompilationForm.options_for(:songs)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
96
|
-
|
97
|
-
|
98
|
-
CompilationForm.options_for(:artist)[:internal_populator].must_be_instance_of Reform::Form::Populator::IfEmpty
|
99
|
-
|
100
|
-
# completely overwrite inherited.
|
101
|
-
CompilationForm.options_for(:hit)[:internal_populator].must_be_instance_of Reform::Form::Populator::Sync # reset to default.
|
102
|
-
CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_equal "SkipParse"
|
103
|
-
|
104
|
-
|
105
|
-
# inherit: true with block will still inherit the original class.
|
106
|
-
AlbumForm.new(OpenStruct.new(artist: OpenStruct.new)).artist.artist_id.must_equal 1
|
107
|
-
CompilationForm.new(OpenStruct.new(artist: OpenStruct.new)).artist.artist_id.must_equal 1
|
108
|
-
end
|
109
|
-
|
110
|
-
|
111
|
-
class CDForm < AlbumForm
|
112
|
-
# override :artist's original populate_if_empty but with :inherit.
|
113
|
-
property :artist, inherit: true, populator: "CD Populator" do
|
114
|
-
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
it { CDForm.options_for(:artist)[:internal_populator].instance_variable_get(:@user_proc).must_equal "CD Populator" }
|
119
|
-
end
|
data/test/populate_test.rb
DELETED
@@ -1,270 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class PopulatorTest < MiniTest::Spec
|
4
|
-
Song = Struct.new(:title, :album, :composer)
|
5
|
-
Album = Struct.new(:name, :songs, :artist)
|
6
|
-
Artist = Struct.new(:name)
|
7
|
-
|
8
|
-
class AlbumForm < Reform::Form
|
9
|
-
property :name, populator: ->(options) { self.name = options[:fragment].reverse }
|
10
|
-
validation do
|
11
|
-
key(:name).required
|
12
|
-
end
|
13
|
-
|
14
|
-
collection :songs,
|
15
|
-
populator: ->(options) {
|
16
|
-
fragment, collection, index = options[:fragment], options[:model], options[:index]
|
17
|
-
|
18
|
-
(item = collection[index]) ? item : collection.insert(index, Song.new) } do
|
19
|
-
|
20
|
-
property :title
|
21
|
-
validation do
|
22
|
-
key(:title).required
|
23
|
-
end
|
24
|
-
|
25
|
-
property :composer, populator: ->(options) { options[:model] || self.composer= Artist.new } do
|
26
|
-
property :name
|
27
|
-
validation do
|
28
|
-
key(:name).required
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# property :artist, populator: lambda { |fragment, options| (item = options.binding.get) ? item : Artist.new } do
|
34
|
-
# NOTE: we have to document that model here is the twin!
|
35
|
-
property :artist, populator: ->(options) { options[:model] || self.artist = Artist.new } do
|
36
|
-
property :name
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
let (:song) { Song.new("Broken") }
|
41
|
-
let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
42
|
-
let (:composer) { Artist.new("Greg Graffin") }
|
43
|
-
let (:artist) { Artist.new("Bad Religion") }
|
44
|
-
let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
|
45
|
-
|
46
|
-
let (:form) { AlbumForm.new(album) }
|
47
|
-
|
48
|
-
it "runs populator on scalar" do
|
49
|
-
form.validate(
|
50
|
-
"name" => "override me!"
|
51
|
-
)
|
52
|
-
|
53
|
-
form.name.must_equal "!em edirrevo"
|
54
|
-
end
|
55
|
-
|
56
|
-
# changing existing property :artist.
|
57
|
-
# TODO: check with artist==nil
|
58
|
-
it do
|
59
|
-
old_id = artist.object_id
|
60
|
-
|
61
|
-
form.validate(
|
62
|
-
"artist" => {"name" => "Marcus Miller"}
|
63
|
-
)
|
64
|
-
|
65
|
-
form.artist.model.object_id.must_equal old_id
|
66
|
-
end
|
67
|
-
|
68
|
-
# use populator for default value on scalars?
|
69
|
-
|
70
|
-
# adding to collection via :populator.
|
71
|
-
# valid.
|
72
|
-
it "yyy" do
|
73
|
-
form.validate(
|
74
|
-
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
|
75
|
-
{"title" => "Rime Of The Ancient Mariner"}, # new song.
|
76
|
-
{"title" => "Re-Education", "composer" => {"name" => "Rise Against"}}], # new song with new composer.
|
77
|
-
).must_equal true
|
78
|
-
|
79
|
-
form.errors.messages.inspect.must_equal "{}"
|
80
|
-
|
81
|
-
# form has updated.
|
82
|
-
form.name.must_equal "The Dissent Of Man"
|
83
|
-
form.songs[0].title.must_equal "Fallout"
|
84
|
-
form.songs[1].title.must_equal "Roxanne"
|
85
|
-
form.songs[1].composer.name.must_equal "Greg Graffin"
|
86
|
-
|
87
|
-
form.songs[1].composer.model.must_be_instance_of Artist
|
88
|
-
|
89
|
-
form.songs[1].title.must_equal "Roxanne"
|
90
|
-
form.songs[2].title.must_equal "Rime Of The Ancient Mariner" # new song added.
|
91
|
-
form.songs[3].title.must_equal "Re-Education"
|
92
|
-
form.songs[3].composer.name.must_equal "Rise Against"
|
93
|
-
form.songs.size.must_equal 4
|
94
|
-
form.artist.name.must_equal "Bad Religion"
|
95
|
-
|
96
|
-
|
97
|
-
# model has not changed, yet.
|
98
|
-
album.name.must_equal "The Dissent Of Man"
|
99
|
-
album.songs[0].title.must_equal "Broken"
|
100
|
-
album.songs[1].title.must_equal "Resist Stance"
|
101
|
-
album.songs[1].composer.name.must_equal "Greg Graffin"
|
102
|
-
album.songs.size.must_equal 2
|
103
|
-
album.artist.name.must_equal "Bad Religion"
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
class PopulateWithMethodTest < Minitest::Spec
|
108
|
-
Album = Struct.new(:title)
|
109
|
-
|
110
|
-
class AlbumForm < Reform::Form
|
111
|
-
property :title, populator: :title!
|
112
|
-
|
113
|
-
def title!(options)
|
114
|
-
self.title = options[:fragment].reverse
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
let (:form) { AlbumForm.new(Album.new) }
|
119
|
-
|
120
|
-
it "runs populator method" do
|
121
|
-
form.validate(
|
122
|
-
"title" => "override me!"
|
123
|
-
)
|
124
|
-
|
125
|
-
form.title.must_equal "!em edirrevo"
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
class PopulateIfEmptyTest < MiniTest::Spec
|
130
|
-
Song = Struct.new(:title, :album, :composer)
|
131
|
-
Album = Struct.new(:name, :songs, :artist)
|
132
|
-
Artist = Struct.new(:name)
|
133
|
-
|
134
|
-
let (:song) { Song.new("Broken") }
|
135
|
-
let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
136
|
-
let (:composer) { Artist.new("Greg Graffin") }
|
137
|
-
let (:artist) { Artist.new("Bad Religion") }
|
138
|
-
let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
class AlbumForm < Reform::Form
|
143
|
-
property :name
|
144
|
-
|
145
|
-
collection :songs,
|
146
|
-
populate_if_empty: Song do # class name works.
|
147
|
-
|
148
|
-
property :title
|
149
|
-
validation do
|
150
|
-
key(:title).required
|
151
|
-
end
|
152
|
-
|
153
|
-
property :composer, populate_if_empty: :populate_composer! do # lambda works, too. in form context.
|
154
|
-
property :name
|
155
|
-
validation do
|
156
|
-
key(:name).required
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
private
|
161
|
-
def populate_composer!(fragment, options)
|
162
|
-
Artist.new
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
property :artist, populate_if_empty: lambda { |args| create_artist(args[:fragment], args[:user_options]) } do # methods work, too.
|
167
|
-
property :name
|
168
|
-
end
|
169
|
-
|
170
|
-
private
|
171
|
-
class Sting < Artist
|
172
|
-
attr_accessor :args
|
173
|
-
end
|
174
|
-
def create_artist(input, user_options)
|
175
|
-
Sting.new.tap { |artist| artist.args=([input, user_options].to_s) }
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
let (:form) { AlbumForm.new(album) }
|
180
|
-
|
181
|
-
it do
|
182
|
-
form.songs.size.must_equal 2
|
183
|
-
|
184
|
-
form.validate(
|
185
|
-
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"},
|
186
|
-
{"title" => "Rime Of The Ancient Mariner"}, # new song.
|
187
|
-
{"title" => "Re-Education", "composer" => {"name" => "Rise Against"}}], # new song with new composer.
|
188
|
-
).must_equal true
|
189
|
-
|
190
|
-
form.errors.messages.inspect.must_equal "{}"
|
191
|
-
|
192
|
-
# form has updated.
|
193
|
-
form.name.must_equal "The Dissent Of Man"
|
194
|
-
form.songs[0].title.must_equal "Fallout"
|
195
|
-
form.songs[1].title.must_equal "Roxanne"
|
196
|
-
form.songs[1].composer.name.must_equal "Greg Graffin"
|
197
|
-
form.songs[1].title.must_equal "Roxanne"
|
198
|
-
form.songs[2].title.must_equal "Rime Of The Ancient Mariner" # new song added.
|
199
|
-
form.songs[3].title.must_equal "Re-Education"
|
200
|
-
form.songs[3].composer.name.must_equal "Rise Against"
|
201
|
-
form.songs.size.must_equal 4
|
202
|
-
form.artist.name.must_equal "Bad Religion"
|
203
|
-
|
204
|
-
|
205
|
-
# model has not changed, yet.
|
206
|
-
album.name.must_equal "The Dissent Of Man"
|
207
|
-
album.songs[0].title.must_equal "Broken"
|
208
|
-
album.songs[1].title.must_equal "Resist Stance"
|
209
|
-
album.songs[1].composer.name.must_equal "Greg Graffin"
|
210
|
-
album.songs.size.must_equal 2
|
211
|
-
album.artist.name.must_equal "Bad Religion"
|
212
|
-
end
|
213
|
-
|
214
|
-
# trigger artist populator. lambda calling form instance method.
|
215
|
-
it "xxxx" do
|
216
|
-
form = AlbumForm.new(album = Album.new)
|
217
|
-
form.validate("artist" => {"name" => "From Autumn To Ashes"})
|
218
|
-
|
219
|
-
form.artist.name.must_equal "From Autumn To Ashes"
|
220
|
-
# test lambda was executed in form context.
|
221
|
-
form.artist.model.must_be_instance_of AlbumForm::Sting
|
222
|
-
# test lambda block arguments.
|
223
|
-
form.artist.model.args.to_s.must_equal "[{\"name\"=>\"From Autumn To Ashes\"}, nil]"
|
224
|
-
|
225
|
-
album.artist.must_equal nil
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
|
230
|
-
# delete songs while deserializing.
|
231
|
-
class PopulateIfEmptyWithDeletionTest < MiniTest::Spec
|
232
|
-
Song = Struct.new(:title, :album, :composer)
|
233
|
-
Album = Struct.new(:name, :songs, :artist)
|
234
|
-
|
235
|
-
let (:song) { Song.new("Broken") }
|
236
|
-
let (:song2) { Song.new("Resist Stance") }
|
237
|
-
let (:album) { Album.new("The Dissent Of Man", [song, song2]) }
|
238
|
-
|
239
|
-
|
240
|
-
class AlbumForm < Reform::Form
|
241
|
-
property :name
|
242
|
-
|
243
|
-
collection :songs,
|
244
|
-
populate_if_empty: Song, skip_if: :delete_song! do
|
245
|
-
|
246
|
-
property :title
|
247
|
-
validation do
|
248
|
-
key(:title).required
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def delete_song!(options)
|
253
|
-
songs.delete(songs[0]) and return true if options[:fragment]["title"] == "Broken, delete me!"
|
254
|
-
false
|
255
|
-
end
|
256
|
-
end
|
257
|
-
|
258
|
-
let (:form) { AlbumForm.new(album) }
|
259
|
-
|
260
|
-
it do
|
261
|
-
form.validate(
|
262
|
-
"songs" => [{"title" => "Broken, delete me!"}, {"title" => "Roxanne"}]
|
263
|
-
).must_equal true
|
264
|
-
|
265
|
-
form.errors.messages.inspect.must_equal "{}"
|
266
|
-
|
267
|
-
form.songs.size.must_equal 1
|
268
|
-
form.songs[0].title.must_equal "Roxanne"
|
269
|
-
end
|
270
|
-
end
|
data/test/readonly_test.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class ReadonlyTest < MiniTest::Spec
|
4
|
-
class SongForm < Reform::Form
|
5
|
-
property :artist
|
6
|
-
property :title, writeable: false
|
7
|
-
# TODO: what to do with virtual values?
|
8
|
-
end
|
9
|
-
|
10
|
-
let (:form) { SongForm.new(OpenStruct.new) }
|
11
|
-
|
12
|
-
it { form.readonly?(:artist).must_equal false }
|
13
|
-
it { form.readonly?(:title).must_equal true }
|
14
|
-
end
|
data/test/save_test.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class SaveTest < BaseTest
|
4
|
-
Song = Struct.new(:title, :album, :composer)
|
5
|
-
Album = Struct.new(:name, :songs, :artist)
|
6
|
-
Artist = Struct.new(:name)
|
7
|
-
|
8
|
-
class AlbumForm < Reform::Form
|
9
|
-
property :name
|
10
|
-
validation do
|
11
|
-
key(:name).required
|
12
|
-
end
|
13
|
-
|
14
|
-
collection :songs do
|
15
|
-
property :title
|
16
|
-
validation do
|
17
|
-
key(:title).required
|
18
|
-
end
|
19
|
-
|
20
|
-
property :composer do
|
21
|
-
property :name
|
22
|
-
validation do
|
23
|
-
key(:name).required
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
property :artist, save: false do
|
29
|
-
property :name
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
module Saveable
|
34
|
-
def save
|
35
|
-
@saved = true
|
36
|
-
end
|
37
|
-
|
38
|
-
def saved?
|
39
|
-
@saved
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
|
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
|
-
|
52
|
-
|
53
|
-
it do
|
54
|
-
form.validate("songs" => [{"title" => "Fixed"}])
|
55
|
-
|
56
|
-
form.save
|
57
|
-
|
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
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
# class SaveWithDynamicOptionsTest < MiniTest::Spec
|
67
|
-
# Song = Struct.new(:id, :title, :length) do
|
68
|
-
# include Saveable
|
69
|
-
# end
|
70
|
-
|
71
|
-
# class SongForm < Reform::Form
|
72
|
-
# property :title#, save: false
|
73
|
-
# property :length, virtual: true
|
74
|
-
# end
|
75
|
-
|
76
|
-
# let (:song) { Song.new }
|
77
|
-
# let (:form) { SongForm.new(song) }
|
78
|
-
|
79
|
-
# # we have access to original input value and outside parameters.
|
80
|
-
# it "xxx" do
|
81
|
-
# form.validate("title" => "A Poor Man's Memory", "length" => 10)
|
82
|
-
# length_seconds = 120
|
83
|
-
# form.save(length: lambda { |value, options| form.model.id = "#{value}: #{length_seconds}" })
|
84
|
-
|
85
|
-
# song.title.must_equal "A Poor Man's Memory"
|
86
|
-
# song.length.must_equal nil
|
87
|
-
# song.id.must_equal "10: 120"
|
88
|
-
# end
|
89
|
-
# end
|