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/feature_test.rb
CHANGED
@@ -1,18 +1,55 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class FeatureInheritanceTest < BaseTest
|
4
|
+
Song = Struct.new(:title, :album, :composer)
|
5
|
+
Album = Struct.new(:name, :songs, :artist)
|
6
|
+
Artist = Struct.new(:name)
|
7
|
+
|
8
|
+
module Date
|
9
|
+
def date
|
10
|
+
"May 16"
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.included(base)
|
14
|
+
base.representer_class.representable_attrs.features << self # TODO: register_feature
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# module Name
|
19
|
+
# def name
|
20
|
+
# "Violins"
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
|
4
24
|
class AlbumForm < Reform::Form
|
5
|
-
#
|
6
|
-
|
7
|
-
# include MultiParameterAttributes
|
25
|
+
feature Date # feature.
|
26
|
+
property :name
|
8
27
|
|
9
|
-
|
10
|
-
property :
|
28
|
+
collection :songs do
|
29
|
+
property :title
|
30
|
+
|
31
|
+
property :composer do
|
32
|
+
property :name
|
11
33
|
end
|
12
34
|
end
|
35
|
+
|
36
|
+
property :artist do
|
37
|
+
property :name
|
38
|
+
end
|
13
39
|
end
|
14
40
|
|
15
|
-
|
41
|
+
let (:song) { Song.new("Broken") }
|
42
|
+
let (:song_with_composer) { Song.new("Resist Stance", nil, composer) }
|
43
|
+
let (:composer) { Artist.new("Greg Graffin") }
|
44
|
+
let (:artist) { Artist.new("Bad Religion") }
|
45
|
+
let (:album) { Album.new("The Dissent Of Man", [song, song_with_composer], artist) }
|
46
|
+
|
47
|
+
let (:form) { AlbumForm.new(album) }
|
48
|
+
|
49
|
+
it do
|
50
|
+
form.date.must_equal "May 16"
|
51
|
+
form.songs[0].date.must_equal "May 16"
|
52
|
+
end
|
16
53
|
|
17
54
|
# it { subject.class.include?(Reform::Form::ActiveModel) }
|
18
55
|
# it { subject.class.include?(Reform::Form::Coercion) }
|
data/test/fields_test.rb
CHANGED
@@ -6,19 +6,9 @@ class FieldsTest < MiniTest::Spec
|
|
6
6
|
fields = Reform::Contract::Fields.new([:name, :title])
|
7
7
|
fields.name.must_equal nil
|
8
8
|
fields.title.must_equal nil
|
9
|
-
end
|
10
9
|
|
11
|
-
|
12
|
-
fields
|
13
|
-
fields.name.must_equal nil
|
14
|
-
fields.title.must_equal "The Body"
|
15
|
-
end
|
16
|
-
|
17
|
-
it "processes value syms" do
|
18
|
-
skip "we don't need to test this as representer.to_hash always returns strings"
|
19
|
-
fields = Reform::Fields.new(["name", "title"], :title => "The Body")
|
20
|
-
fields.name.must_equal nil
|
21
|
-
fields.title.must_equal "The Body"
|
10
|
+
fields.title= "Planet X"
|
11
|
+
fields.title.must_equal "Planet X"
|
22
12
|
end
|
23
13
|
end
|
24
14
|
end
|
data/test/form_builder_test.rb
CHANGED
@@ -1,37 +1,39 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class FormBuilderCompatTest < BaseTest
|
4
|
-
|
5
|
-
|
6
|
-
include Reform::Form::ActiveModel::FormBuilderMethods
|
4
|
+
class AlbumForm < Reform::Form
|
5
|
+
feature Reform::Form::ActiveModel::FormBuilderMethods
|
7
6
|
|
8
|
-
|
9
|
-
property :name
|
10
|
-
validates :name, :presence => true
|
11
|
-
end
|
7
|
+
feature Reform::Form::MultiParameterAttributes
|
12
8
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
9
|
+
property :artist do
|
10
|
+
property :name
|
11
|
+
validates :name, :presence => true
|
12
|
+
end
|
18
13
|
|
19
|
-
|
20
|
-
|
21
|
-
|
14
|
+
collection :songs do
|
15
|
+
feature Reform::Form::ActiveModel::FormBuilderMethods
|
16
|
+
property :title
|
17
|
+
property :release_date, :multi_params => true
|
18
|
+
validates :title, :presence => true
|
19
|
+
end
|
22
20
|
|
23
|
-
|
21
|
+
class LabelForm < Reform::Form
|
22
|
+
property :name
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
property :label, form: LabelForm
|
26
|
+
|
27
|
+
property :band do
|
28
|
+
property :label do
|
29
|
+
property :name
|
29
30
|
end
|
30
31
|
end
|
31
|
-
|
32
|
+
end
|
33
|
+
|
32
34
|
|
33
35
|
let (:song) { OpenStruct.new }
|
34
|
-
let (:form) {
|
36
|
+
let (:form) { AlbumForm.new(OpenStruct.new(
|
35
37
|
:artist => Artist.new(:name => "Propagandhi"),
|
36
38
|
:songs => [song],
|
37
39
|
:label => OpenStruct.new,
|
@@ -40,9 +42,10 @@ class FormBuilderCompatTest < BaseTest
|
|
40
42
|
)) }
|
41
43
|
|
42
44
|
it "respects _attributes params hash" do
|
43
|
-
form.validate(
|
44
|
-
"
|
45
|
-
"
|
45
|
+
form.validate(
|
46
|
+
"artist_attributes" => {"name" => "Blink 182"},
|
47
|
+
"songs_attributes" => {"0" => {"title" => "Damnit"}},
|
48
|
+
"band_attributes" => {"label_attributes" => {"name" => "Epitaph"}})
|
46
49
|
|
47
50
|
form.artist.name.must_equal "Blink 182"
|
48
51
|
form.songs.first.title.must_equal "Damnit"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FormOptionTest < MiniTest::Spec
|
4
|
+
Song = Struct.new(:title)
|
5
|
+
Album = Struct.new(:song)
|
6
|
+
|
7
|
+
class SongForm < Reform::Form
|
8
|
+
property :title
|
9
|
+
validates_presence_of :title
|
10
|
+
end
|
11
|
+
|
12
|
+
class AlbumForm < Reform::Form
|
13
|
+
property :song, form: SongForm
|
14
|
+
end
|
15
|
+
|
16
|
+
it do
|
17
|
+
AlbumForm.new(Album.new(Song.new("When It Comes To You"))).song.title.must_equal "When It Comes To You"
|
18
|
+
end
|
19
|
+
end
|
data/test/from_test.rb
CHANGED
@@ -73,78 +73,3 @@ class AsTest < BaseTest
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
77
|
-
|
78
|
-
class AsREMOVEMEin20Test < BaseTest # TODO: remove me in 2.0.
|
79
|
-
class AlbumForm < Reform::Form
|
80
|
-
property :name, as: :title
|
81
|
-
|
82
|
-
property :single, as: :hit do
|
83
|
-
property :title
|
84
|
-
end
|
85
|
-
|
86
|
-
collection :tracks, as: :songs do
|
87
|
-
property :name, as: :title
|
88
|
-
end
|
89
|
-
|
90
|
-
property :band do
|
91
|
-
property :company, as: :label do
|
92
|
-
property :business, as: :name
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
let (:song2) { Song.new("Roxanne") }
|
98
|
-
|
99
|
-
let (:params) {
|
100
|
-
{
|
101
|
-
"name" => "Best Of The Police",
|
102
|
-
"single" => {"title" => "So Lonely"},
|
103
|
-
"tracks" => [{"name" => "Message In A Bottle"}, {"name" => "Roxanne"}]
|
104
|
-
}
|
105
|
-
}
|
106
|
-
|
107
|
-
subject { AlbumForm.new(Album.new("Best Of", hit, [Song.new("Fallout"), song2])) }
|
108
|
-
|
109
|
-
it { subject.name.must_equal "Best Of" }
|
110
|
-
it { subject.single.title.must_equal "Roxanne" }
|
111
|
-
it { subject.tracks[0].name.must_equal "Fallout" }
|
112
|
-
it { subject.tracks[1].name.must_equal "Roxanne" }
|
113
|
-
|
114
|
-
|
115
|
-
describe "#validate" do
|
116
|
-
|
117
|
-
|
118
|
-
before { subject.validate(params) }
|
119
|
-
|
120
|
-
it { subject.name.must_equal "Best Of The Police" }
|
121
|
-
it { subject.single.title.must_equal "So Lonely" }
|
122
|
-
it { subject.tracks[0].name.must_equal "Message In A Bottle" }
|
123
|
-
it { subject.tracks[1].name.must_equal "Roxanne" }
|
124
|
-
end
|
125
|
-
|
126
|
-
|
127
|
-
describe "#sync" do
|
128
|
-
before {
|
129
|
-
subject.tracks[1].name = "Livin' Ain't No Crime"
|
130
|
-
subject.sync
|
131
|
-
}
|
132
|
-
|
133
|
-
it { song2.title.must_equal "Livin' Ain't No Crime" }
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
|
-
describe "#save (nested hash)" do
|
138
|
-
before { subject.validate(params) }
|
139
|
-
|
140
|
-
it do
|
141
|
-
hash = nil
|
142
|
-
|
143
|
-
subject.save do |nested_hash|
|
144
|
-
hash = nested_hash
|
145
|
-
end
|
146
|
-
|
147
|
-
hash.must_equal({"title"=>"Best Of The Police", "hit"=>{"title"=>"So Lonely"}, "songs"=>[{"title"=>"Message In A Bottle"}, {"title"=>"Roxanne"}]})
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
data/test/inherit_test.rb
CHANGED
@@ -3,26 +3,50 @@ require 'representable/json'
|
|
3
3
|
|
4
4
|
class InheritTest < BaseTest
|
5
5
|
class AlbumForm < Reform::Form
|
6
|
-
property :title
|
6
|
+
property :title, deserializer: {instance: "Instance"}, skip_if: "skip_if in AlbumForm" # allow direct configuration of :deserializer.
|
7
|
+
# puts "[#{options_for(:title)[:deserializer].object_id}] ALB@@@@@ #{options_for(:title)[:deserializer].inspect}"
|
7
8
|
|
8
|
-
property :hit do
|
9
|
+
property :hit, populator: "Populator" do
|
9
10
|
property :title
|
10
11
|
end
|
11
12
|
|
12
|
-
collection :songs do
|
13
|
+
collection :songs, populate_if_empty: lambda {}, skip_if: :all_blank do
|
13
14
|
property :title
|
14
15
|
end
|
15
|
-
end
|
16
16
|
|
17
|
-
|
17
|
+
property :artist, populate_if_empty: lambda {} do
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def artist_id
|
20
|
+
1
|
21
|
+
end
|
22
22
|
end
|
23
|
+
end
|
24
|
+
|
25
|
+
puts
|
26
|
+
puts "inherit"
|
27
|
+
|
28
|
+
class CompilationForm < AlbumForm
|
29
|
+
property :title, inherit: true, skip_if: "skip_if from CompilationForm"
|
30
|
+
puts "[#{options_for(:title)[:deserializer].object_id}] COM@@@@@ #{options_for(:title)[:deserializer].inspect}"
|
31
|
+
# property :hit, :inherit => true do
|
32
|
+
# property :rating
|
33
|
+
# validates :title, :rating, :presence => true
|
34
|
+
# end
|
23
35
|
|
24
36
|
# puts representer_class.representable_attrs.
|
25
37
|
# get(:hit)[:extend].evaluate(nil).new(OpenStruct.new).rating
|
38
|
+
|
39
|
+
# NO collection here, this is entirely inherited.
|
40
|
+
# collection :songs, ..
|
41
|
+
|
42
|
+
property :artist, inherit: true do # inherit everything, but explicitely.
|
43
|
+
end
|
44
|
+
|
45
|
+
# completely override.
|
46
|
+
property :hit, skip_if: "SkipParse" do
|
47
|
+
end
|
48
|
+
|
49
|
+
# override partly.
|
26
50
|
end
|
27
51
|
|
28
52
|
let (:album) { Album.new(nil, OpenStruct.new(:hit => OpenStruct.new()) ) }
|
@@ -30,146 +54,183 @@ class InheritTest < BaseTest
|
|
30
54
|
|
31
55
|
|
32
56
|
# valid.
|
33
|
-
it {
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
}
|
39
|
-
|
40
|
-
it do
|
41
|
-
subject.validate({})
|
42
|
-
subject.hit.title.must_equal nil
|
43
|
-
subject.hit.rating.must_equal nil
|
44
|
-
subject.errors.messages.must_equal({:"hit.title"=>["can't be blank"], :"hit.rating"=>["can't be blank"]})
|
45
|
-
end
|
46
|
-
end
|
57
|
+
# it {
|
58
|
+
# subject.validate("hit" => {"title" => "LA Drone", "rating" => 10})
|
59
|
+
# subject.hit.title.must_equal "LA Drone"
|
60
|
+
# subject.hit.rating.must_equal 10
|
61
|
+
# subject.errors.messages.must_equal({})
|
62
|
+
# }
|
47
63
|
|
64
|
+
# it do
|
65
|
+
# subject.validate({})
|
66
|
+
# subject.hit.title.must_equal nil
|
67
|
+
# subject.hit.rating.must_equal nil
|
68
|
+
# subject.errors.messages.must_equal({:"hit.title"=>["can't be blank"], :"hit.rating"=>["can't be blank"]})
|
69
|
+
# end
|
48
70
|
|
49
|
-
require
|
50
|
-
class ModuleInclusionTest < MiniTest::Spec
|
51
|
-
module BandPropertyForm
|
52
|
-
include Reform::Form::Module
|
71
|
+
require "pp"
|
53
72
|
|
54
|
-
|
55
|
-
|
73
|
+
it "xxx" do
|
74
|
+
# sub hashes like :deserializer must be properly cloned when inheriting.
|
75
|
+
AlbumForm.options_for(:title)[:deserializer].object_id.wont_equal CompilationForm.options_for(:title)[:deserializer].object_id
|
56
76
|
|
57
|
-
|
77
|
+
# don't overwrite direct deserializer: {} configuration.
|
78
|
+
AlbumForm.options_for(:title)[:deserializer][:instance].must_equal "Instance"
|
79
|
+
AlbumForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if in AlbumForm"
|
58
80
|
|
59
|
-
|
60
|
-
|
61
|
-
end
|
62
|
-
end
|
81
|
+
AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_match /Reform::Form::Populator:.+ @user_proc="Populator"/
|
82
|
+
# AlbumForm.options_for(:hit)[:deserializer][:instance].inspect.must_be_instance_with Reform::Form::Populator, user_proc: "Populator"
|
63
83
|
|
64
|
-
def id # gets mixed into Form, too.
|
65
|
-
1
|
66
|
-
end
|
67
84
|
|
68
|
-
|
85
|
+
AlbumForm.options_for(:songs)[:deserializer][:instance].must_be_instance_of Reform::Form::Populator::IfEmpty
|
86
|
+
AlbumForm.options_for(:songs)[:deserializer][:skip_parse].must_be_instance_of Reform::Form::Validate::Skip::AllBlank
|
69
87
|
|
70
|
-
|
71
|
-
end
|
88
|
+
AlbumForm.options_for(:artist)[:deserializer][:instance].must_be_instance_of Reform::Form::Populator::IfEmpty
|
72
89
|
|
73
|
-
# TODO: test if works, move stuff into inherit_schema!
|
74
|
-
module AirplaysPropertyForm
|
75
|
-
include Reform::Form::Module
|
76
90
|
|
77
|
-
collection :airplays do
|
78
|
-
property :station
|
79
|
-
validates :station, :presence => true
|
80
|
-
end
|
81
|
-
validates :airplays, :presence => true
|
82
|
-
end
|
83
91
|
|
92
|
+
CompilationForm.options_for(:title)[:deserializer][:skip_parse].must_equal "skip_if from CompilationForm"
|
93
|
+
# pp CompilationForm.options_for(:songs)
|
94
|
+
CompilationForm.options_for(:songs)[:deserializer][:instance].must_be_instance_of Reform::Form::Populator::IfEmpty
|
84
95
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
96
|
+
CompilationForm.options_for(:artist)[:deserializer][:instance].must_be_instance_of Reform::Form::Populator::IfEmpty
|
97
|
+
|
98
|
+
# completely overwrite inherited.
|
99
|
+
CompilationForm.options_for(:hit)[:deserializer][:instance].must_be_instance_of Reform::Form::Populator::Sync # reset to default.
|
100
|
+
CompilationForm.options_for(:hit)[:deserializer][:skip_parse].must_equal "SkipParse"
|
90
101
|
|
91
|
-
class SongForm < Reform::Form
|
92
|
-
property :title
|
93
102
|
|
94
|
-
|
103
|
+
# inherit: true with block will still inherit the original class.
|
104
|
+
AlbumForm.new(OpenStruct.new(artist: OpenStruct.new)).artist.artist_id.must_equal 1
|
105
|
+
CompilationForm.new(OpenStruct.new(artist: OpenStruct.new)).artist.artist_id.must_equal 1
|
95
106
|
end
|
107
|
+
end
|
96
108
|
|
97
109
|
|
98
|
-
|
110
|
+
# require 'reform/form/coercion'
|
111
|
+
# class ModuleInclusionTest < MiniTest::Spec
|
112
|
+
# module BandPropertyForm
|
113
|
+
# include Reform::Form::Module
|
99
114
|
|
100
|
-
|
101
|
-
|
115
|
+
# property :band do
|
116
|
+
# property :title
|
102
117
|
|
103
|
-
|
104
|
-
it { SongForm.new(song).id.must_equal 1 }
|
105
|
-
it { SongForm.new(song).band.id.must_equal 2 }
|
118
|
+
# validates :title, :presence => true
|
106
119
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
form.errors.messages.must_equal({:band=>["can't be blank"]})
|
112
|
-
end
|
120
|
+
# def id # gets mixed into Form, too.
|
121
|
+
# 2
|
122
|
+
# end
|
123
|
+
# end
|
113
124
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
form.validate({:cool => "1"})
|
118
|
-
form.cool.must_equal true
|
119
|
-
end
|
125
|
+
# def id # gets mixed into Form, too.
|
126
|
+
# 1
|
127
|
+
# end
|
120
128
|
|
129
|
+
# validates :band, :presence => true
|
121
130
|
|
122
|
-
|
123
|
-
|
124
|
-
include Reform::Form::Module
|
125
|
-
include BandPropertyForm
|
131
|
+
# property :cool, type: Virtus::Attribute::Boolean # test coercion.
|
132
|
+
# end
|
126
133
|
|
127
|
-
|
128
|
-
|
129
|
-
|
134
|
+
# # TODO: test if works, move stuff into inherit_schema!
|
135
|
+
# module AirplaysPropertyForm
|
136
|
+
# include Reform::Form::Module
|
130
137
|
|
131
|
-
|
132
|
-
|
138
|
+
# collection :airplays do
|
139
|
+
# property :station
|
140
|
+
# validates :station, :presence => true
|
141
|
+
# end
|
142
|
+
# validates :airplays, :presence => true
|
143
|
+
# end
|
133
144
|
|
134
|
-
property :band, :inherit => true do
|
135
|
-
property :label
|
136
|
-
validates :label, :presence => true
|
137
|
-
end
|
138
|
-
end
|
139
|
-
# puts "......"+ AlbumForm.representer_class.representable_attrs.get(:band).inspect
|
140
145
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
+
# # test:
|
147
|
+
# # by including BandPropertyForm into multiple classes we assure that options hashes don't get messed up by AM:V.
|
148
|
+
# class HitForm < Reform::Form
|
149
|
+
# include BandPropertyForm
|
150
|
+
# end
|
146
151
|
|
152
|
+
# class SongForm < Reform::Form
|
153
|
+
# property :title
|
147
154
|
|
148
|
-
|
149
|
-
|
150
|
-
include Representable
|
155
|
+
# include BandPropertyForm
|
156
|
+
# end
|
151
157
|
|
152
|
-
property :title
|
153
|
-
property :manager do
|
154
|
-
property :title
|
155
|
-
end
|
156
|
-
end
|
157
158
|
|
158
|
-
|
159
|
-
property :location
|
159
|
+
# let (:song) { OpenStruct.new(:band => OpenStruct.new(:title => "Time Again")) }
|
160
160
|
|
161
|
-
|
162
|
-
|
163
|
-
property :manager, :inherit => true do
|
164
|
-
validates :title, :presence => true
|
165
|
-
end
|
166
|
-
end
|
167
|
-
puts "......"+ LabelForm.representer_class.representable_attrs.get(:title).inspect
|
161
|
+
# # nested form from module is present and creates accessor.
|
162
|
+
# it { SongForm.new(song).band.title.must_equal "Time Again" }
|
168
163
|
|
164
|
+
# # methods from module get included.
|
165
|
+
# it { SongForm.new(song).id.must_equal 1 }
|
166
|
+
# it { SongForm.new(song).band.id.must_equal 2 }
|
169
167
|
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
end
|
168
|
+
# # validators get inherited.
|
169
|
+
# it do
|
170
|
+
# form = SongForm.new(OpenStruct.new)
|
171
|
+
# form.validate({})
|
172
|
+
# form.errors.messages.must_equal({:band=>["can't be blank"]})
|
173
|
+
# end
|
174
|
+
|
175
|
+
# # coercion works
|
176
|
+
# it do
|
177
|
+
# form = SongForm.new(OpenStruct.new)
|
178
|
+
# form.validate({:cool => "1"})
|
179
|
+
# form.cool.must_equal true
|
180
|
+
# end
|
181
|
+
|
182
|
+
|
183
|
+
# # include a module into a module into a class :)
|
184
|
+
# module AlbumFormModule
|
185
|
+
# include Reform::Form::Module
|
186
|
+
# include BandPropertyForm
|
187
|
+
|
188
|
+
# property :name
|
189
|
+
# validates :name, :presence => true
|
190
|
+
# end
|
191
|
+
|
192
|
+
# class AlbumForm < Reform::Form
|
193
|
+
# include AlbumFormModule
|
194
|
+
|
195
|
+
# property :band, :inherit => true do
|
196
|
+
# property :label
|
197
|
+
# validates :label, :presence => true
|
198
|
+
# end
|
199
|
+
# end
|
200
|
+
# # puts "......"+ AlbumForm.representer_class.representable_attrs.get(:band).inspect
|
201
|
+
|
202
|
+
# it do
|
203
|
+
# form = AlbumForm.new(OpenStruct.new(:band => OpenStruct.new))
|
204
|
+
# form.validate({"band" => {}})
|
205
|
+
# form.errors.messages.must_equal({:"band.title"=>["can't be blank"], :"band.label"=>["can't be blank"], :name=>["can't be blank"]})
|
206
|
+
# end
|
207
|
+
|
208
|
+
|
209
|
+
# # including representer into form
|
210
|
+
# module GenericRepresenter
|
211
|
+
# include Representable
|
212
|
+
|
213
|
+
# property :title
|
214
|
+
# property :manager do
|
215
|
+
# property :title
|
216
|
+
# end
|
217
|
+
# end
|
218
|
+
|
219
|
+
# class LabelForm < Reform::Form
|
220
|
+
# property :location
|
221
|
+
|
222
|
+
# include GenericRepresenter
|
223
|
+
# validates :title, :presence => true
|
224
|
+
# property :manager, :inherit => true do
|
225
|
+
# validates :title, :presence => true
|
226
|
+
# end
|
227
|
+
# end
|
228
|
+
# puts "......"+ LabelForm.representer_class.representable_attrs.get(:title).inspect
|
229
|
+
|
230
|
+
|
231
|
+
# it do
|
232
|
+
# form = LabelForm.new(OpenStruct.new(:manager => OpenStruct.new))
|
233
|
+
# form.validate({"manager" => {}, "title"=>""}) # it's important to pass both nested and scalar here!
|
234
|
+
# form.errors.messages.must_equal(:title=>["can't be blank"], :"manager.title"=>["can't be blank"], )
|
235
|
+
# end
|
236
|
+
# end
|