reform 1.2.6 → 2.0.0.beta1
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 +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
|