reform 1.2.6 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -1
- data/CHANGES.md +14 -0
- data/Gemfile +3 -2
- data/README.md +225 -283
- data/Rakefile +27 -0
- data/TODO.md +12 -0
- data/database.sqlite3 +0 -0
- data/gemfiles/Gemfile.rails-3.0 +1 -0
- data/gemfiles/Gemfile.rails-3.1 +1 -0
- data/gemfiles/Gemfile.rails-3.2 +1 -0
- data/gemfiles/Gemfile.rails-4.0 +1 -0
- data/lib/reform.rb +0 -1
- data/lib/reform/contract.rb +64 -170
- data/lib/reform/contract/validate.rb +10 -13
- data/lib/reform/form.rb +74 -19
- data/lib/reform/form/active_model.rb +19 -14
- data/lib/reform/form/coercion.rb +1 -13
- data/lib/reform/form/composition.rb +2 -24
- data/lib/reform/form/multi_parameter_attributes.rb +43 -62
- data/lib/reform/form/populator.rb +85 -0
- data/lib/reform/form/prepopulate.rb +13 -43
- data/lib/reform/form/validate.rb +29 -90
- data/lib/reform/form/validation/unique_validator.rb +13 -0
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +7 -7
- data/test/active_model_test.rb +43 -0
- data/test/changed_test.rb +23 -51
- data/test/coercion_test.rb +1 -7
- data/test/composition_test.rb +128 -34
- data/test/contract_test.rb +27 -86
- data/test/feature_test.rb +43 -6
- data/test/fields_test.rb +2 -12
- data/test/form_builder_test.rb +28 -25
- data/test/form_option_test.rb +19 -0
- data/test/from_test.rb +0 -75
- data/test/inherit_test.rb +178 -117
- data/test/model_reflections_test.rb +1 -1
- data/test/populate_test.rb +226 -0
- data/test/prepopulator_test.rb +112 -0
- data/test/readable_test.rb +2 -4
- data/test/save_test.rb +56 -112
- data/test/setup_test.rb +48 -0
- data/test/skip_if_test.rb +5 -2
- data/test/skip_setter_and_getter_test.rb +54 -0
- data/test/test_helper.rb +3 -1
- data/test/uniqueness_test.rb +41 -0
- data/test/validate_test.rb +325 -289
- data/test/virtual_test.rb +1 -3
- data/test/writeable_test.rb +3 -4
- metadata +35 -39
- data/lib/reform/composition.rb +0 -63
- data/lib/reform/contract/setup.rb +0 -50
- data/lib/reform/form/changed.rb +0 -9
- data/lib/reform/form/sync.rb +0 -116
- data/lib/reform/representer.rb +0 -84
- data/test/empty_test.rb +0 -58
- data/test/form_composition_test.rb +0 -145
- data/test/nested_form_test.rb +0 -197
- data/test/prepopulate_test.rb +0 -85
- data/test/sync_option_test.rb +0 -83
- data/test/sync_test.rb +0 -56
data/test/prepopulate_test.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class PrepopulateTest < MiniTest::Spec
|
4
|
-
Song = Struct.new(:title, :band, :length)
|
5
|
-
Band = Struct.new(:name)
|
6
|
-
|
7
|
-
class AlbumForm < Reform::Form
|
8
|
-
property :title, prepopulate: ->(options){ "Another Day At Work" }
|
9
|
-
property :length
|
10
|
-
|
11
|
-
property :hit, prepopulate: ->(options){ Song.new } do
|
12
|
-
property :title
|
13
|
-
|
14
|
-
property :band, prepopulate: ->(options){ Band.new } do
|
15
|
-
property :name
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
collection :songs, prepopulate: ->(options){ [Song.new, Song.new] } do
|
20
|
-
property :title
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
subject { AlbumForm.new(OpenStruct.new(length: 1)).prepopulate! }
|
25
|
-
|
26
|
-
it { subject.length.must_equal 1 }
|
27
|
-
it { subject.title.must_equal "Another Day At Work" }
|
28
|
-
it { subject.hit.model.must_equal Song.new }
|
29
|
-
it { subject.songs.size.must_equal 2 }
|
30
|
-
it { subject.songs[0].model.must_equal Song.new }
|
31
|
-
it { subject.songs[1].model.must_equal Song.new }
|
32
|
-
it { subject.hit.band.model.must_equal Band.new }
|
33
|
-
end
|
34
|
-
|
35
|
-
|
36
|
-
class PrepopulateInFormContextTest < MiniTest::Spec
|
37
|
-
Song = Struct.new(:title, :band, :length)
|
38
|
-
Band = Struct.new(:name)
|
39
|
-
|
40
|
-
class AlbumForm < Reform::Form
|
41
|
-
property :title, prepopulate: ->(options){ "#{my_title} #{options.class}" }
|
42
|
-
|
43
|
-
property :hit, prepopulate: ->(options){ my_hit } do
|
44
|
-
property :title
|
45
|
-
|
46
|
-
property :band, prepopulate: ->(options){ my_band } do
|
47
|
-
property :name
|
48
|
-
end
|
49
|
-
|
50
|
-
def my_band
|
51
|
-
Band.new
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def my_title
|
56
|
-
"Rhode Island Shred"
|
57
|
-
end
|
58
|
-
|
59
|
-
def my_hit
|
60
|
-
Song.new
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
subject { AlbumForm.new(OpenStruct.new).prepopulate! }
|
65
|
-
|
66
|
-
it { subject.title.must_equal "Rhode Island Shred Hash" }
|
67
|
-
it { subject.hit.model.must_equal Song.new }
|
68
|
-
it { subject.hit.band.model.must_equal Band.new }
|
69
|
-
end
|
70
|
-
|
71
|
-
class PrepopulateWithExistingCollectionTest < MiniTest::Spec
|
72
|
-
Song = Struct.new(:title)
|
73
|
-
|
74
|
-
class AlbumForm < Reform::Form
|
75
|
-
collection :songs, prepopulate: ->(*){ songs.map(&:model) + [Song.new] } do
|
76
|
-
property :title
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
subject { AlbumForm.new(OpenStruct.new(songs: [Song.new])).prepopulate! }
|
81
|
-
|
82
|
-
it { subject.songs.size.must_equal 2 }
|
83
|
-
it { subject.songs[0].model.must_equal Song.new }
|
84
|
-
it { subject.songs[1].model.must_equal Song.new }
|
85
|
-
end
|
data/test/sync_option_test.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class SyncOptionTest < MiniTest::Spec
|
4
|
-
Band = Struct.new(:name)
|
5
|
-
let (:band) { Band.new("Metallica") }
|
6
|
-
let (:form) { BandForm.new(band) }
|
7
|
-
|
8
|
-
# access to :form!
|
9
|
-
describe ":sync allows you conditionals" do
|
10
|
-
class BandForm < Reform::Form
|
11
|
-
property :name, sync: lambda { |value, options| options.user_options[:form].changed?(:name) ? model.name = value : nil } # change if it hasn't changed
|
12
|
-
end
|
13
|
-
|
14
|
-
# don't set name, didn't change.
|
15
|
-
it do
|
16
|
-
band.instance_exec { def name=(*); raise; end }
|
17
|
-
form.validate("name" => "Metallica").must_equal true
|
18
|
-
form.sync
|
19
|
-
band.name.must_equal "Metallica"
|
20
|
-
end
|
21
|
-
|
22
|
-
# update name.
|
23
|
-
it do
|
24
|
-
form.validate("name" => "Iron Maiden").must_equal true
|
25
|
-
form.sync
|
26
|
-
form.name.must_equal "Iron Maiden"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
class SyncWithDynamicOptionsTest < MiniTest::Spec
|
33
|
-
Song = Struct.new(:id, :title, :length)
|
34
|
-
|
35
|
-
class SongForm < Reform::Form
|
36
|
-
property :id
|
37
|
-
property :title, sync: true
|
38
|
-
property :length
|
39
|
-
end
|
40
|
-
|
41
|
-
let (:song) { Song.new }
|
42
|
-
let (:form) { SongForm.new(song) }
|
43
|
-
|
44
|
-
# we have access to original input value and outside parameters.
|
45
|
-
it do
|
46
|
-
form.validate("title" => "A Poor Man's Memory", "length" => 10)
|
47
|
-
length_seconds = 120
|
48
|
-
form.sync(title: lambda { |value, options| form.model.title = "#{value}: #{length_seconds}" })
|
49
|
-
|
50
|
-
song.title.must_equal "A Poor Man's Memory: 120"
|
51
|
-
song.length.must_equal 10
|
52
|
-
song.id.must_equal nil
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
|
57
|
-
# :virtual wins over :sync
|
58
|
-
# class SyncWithVirtualTest < MiniTest::Spec
|
59
|
-
# Song = Struct.new(:title, :image, :band)
|
60
|
-
# Band = Struct.new(:name)
|
61
|
-
|
62
|
-
# let (:form) { HitForm.new(song) }
|
63
|
-
# let (:song) { Song.new("Injection", Object, Band.new("Rise Against")) }
|
64
|
-
|
65
|
-
# class HitForm < Reform::Form
|
66
|
-
# include Sync::SkipUnchanged
|
67
|
-
# register_feature Sync::SkipUnchanged
|
68
|
-
|
69
|
-
# property :image, sync: lambda { |value, *| model.image = "processed via :sync: #{value}" }
|
70
|
-
# property :band do
|
71
|
-
# property :name, sync: lambda { |value, *| model.name = "band, processed: #{value}" }, virtual: true
|
72
|
-
# end
|
73
|
-
# end
|
74
|
-
|
75
|
-
# it "abc" do
|
76
|
-
# form.validate("image" => "Funny photo of Steve Harris", "band" => {"name" => "Iron Maiden"}).must_equal true
|
77
|
-
|
78
|
-
# form.sync
|
79
|
-
# song.image.must_equal "processed via :sync: Funny photo of Steve Harris"
|
80
|
-
# song.band.name.must_equal "Rise Against"
|
81
|
-
# end
|
82
|
-
# end
|
83
|
-
|
data/test/sync_test.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class SyncTest < BaseTest
|
4
|
-
|
5
|
-
Band = Struct.new(:name, :label)
|
6
|
-
|
7
|
-
describe "populated" do
|
8
|
-
let (:params) {
|
9
|
-
{
|
10
|
-
"title" => "Best Of",
|
11
|
-
"hit" => {"title" => "Roxanne"},
|
12
|
-
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}],
|
13
|
-
:band => {:label => {:name => "Polydor"}}
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
let (:album) { Album.new(nil, hit, [song1, song2], band) }
|
18
|
-
let (:hit) { Song.new }
|
19
|
-
let (:song1) { Song.new }
|
20
|
-
let (:song2) { Song.new }
|
21
|
-
let (:band) { Band.new("The Police", label) }
|
22
|
-
let (:label) { Label.new }
|
23
|
-
|
24
|
-
subject { ErrorsTest::AlbumForm.new(album) }
|
25
|
-
|
26
|
-
before do
|
27
|
-
subject.validate(params)
|
28
|
-
subject.sync
|
29
|
-
end
|
30
|
-
|
31
|
-
it { album.title.must_equal "Best Of" }
|
32
|
-
it { album.hit.must_be_kind_of Struct }
|
33
|
-
it { album.songs[0].must_be_kind_of Struct }
|
34
|
-
it { album.songs[1].must_be_kind_of Struct }
|
35
|
-
|
36
|
-
# it { hit.must_be_kind_of Struct }
|
37
|
-
it { hit.title.must_equal "Roxanne" }
|
38
|
-
it { song1.title.must_equal "Fallout" }
|
39
|
-
it { song2.title.must_equal "Roxanne" }
|
40
|
-
it { label.name.must_equal "Polydor" }
|
41
|
-
end
|
42
|
-
|
43
|
-
describe "with incoming nil value" do
|
44
|
-
it do
|
45
|
-
album = Album.new("GI")
|
46
|
-
form = ErrorsTest::AlbumForm.new(album)
|
47
|
-
|
48
|
-
form.title.must_equal "GI"
|
49
|
-
|
50
|
-
form.validate("title" => nil)
|
51
|
-
form.title.must_equal nil
|
52
|
-
form.sync
|
53
|
-
album.title.must_equal nil
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|