reform 0.2.7 → 1.0.0
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/CHANGES.md +18 -0
- data/Gemfile +2 -1
- data/README.md +196 -17
- data/TODO.md +14 -3
- data/database.sqlite3 +0 -0
- data/lib/reform.rb +9 -1
- data/lib/reform/composition.rb +41 -34
- data/lib/reform/contract.rb +109 -0
- data/lib/reform/contract/errors.rb +33 -0
- data/lib/reform/contract/setup.rb +44 -0
- data/lib/reform/contract/validate.rb +48 -0
- data/lib/reform/form.rb +13 -309
- data/lib/reform/form/active_model.rb +8 -5
- data/lib/reform/form/active_record.rb +30 -37
- data/lib/reform/form/coercion.rb +10 -11
- data/lib/reform/form/composition.rb +40 -50
- data/lib/reform/form/multi_parameter_attributes.rb +6 -1
- data/lib/reform/form/save.rb +61 -0
- data/lib/reform/form/sync.rb +60 -0
- data/lib/reform/form/validate.rb +104 -0
- data/lib/reform/form/virtual_attributes.rb +3 -5
- data/lib/reform/representer.rb +17 -3
- data/lib/reform/version.rb +1 -1
- data/reform.gemspec +2 -1
- data/test/active_model_test.rb +0 -92
- data/test/as_test.rb +75 -0
- data/test/coercion_test.rb +26 -8
- data/test/composition_test.rb +8 -8
- data/test/contract_test.rb +57 -0
- data/test/errors_test.rb +37 -10
- data/test/feature_test.rb +28 -0
- data/test/form_builder_test.rb +105 -0
- data/test/form_composition_test.rb +30 -13
- data/test/nested_form_test.rb +12 -18
- data/test/reform_test.rb +11 -6
- data/test/save_test.rb +81 -0
- data/test/setup_test.rb +38 -0
- data/test/sync_test.rb +39 -0
- data/test/test_helper.rb +36 -2
- data/test/validate_test.rb +191 -0
- metadata +42 -4
data/test/sync_test.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SyncTest < BaseTest
|
4
|
+
describe "populated" do
|
5
|
+
let (:params) {
|
6
|
+
{
|
7
|
+
"title" => "Best Of",
|
8
|
+
"hit" => {"title" => "Roxanne"},
|
9
|
+
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}],
|
10
|
+
:band => {:label => {:name => "Polydor"}}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
let (:album) { Album.new(nil, hit, [song1, song2], band) }
|
15
|
+
let (:hit) { Song.new }
|
16
|
+
let (:song1) { Song.new }
|
17
|
+
let (:song2) { Song.new }
|
18
|
+
let (:band) { Band.new(label) }
|
19
|
+
let (:label) { Label.new }
|
20
|
+
|
21
|
+
subject { ErrorsTest::AlbumForm.new(album) }
|
22
|
+
|
23
|
+
before do
|
24
|
+
subject.validate(params)
|
25
|
+
subject.sync
|
26
|
+
end
|
27
|
+
|
28
|
+
it { album.title.must_equal "Best Of" }
|
29
|
+
it { album.hit.must_be_kind_of Struct }
|
30
|
+
it { album.songs[0].must_be_kind_of Struct }
|
31
|
+
it { album.songs[1].must_be_kind_of Struct }
|
32
|
+
|
33
|
+
# it { hit.must_be_kind_of Struct }
|
34
|
+
it { hit.title.must_equal "Roxanne" }
|
35
|
+
it { song1.title.must_equal "Fallout" }
|
36
|
+
it { song2.title.must_equal "Roxanne" }
|
37
|
+
it { label.name.must_equal "Polydor" }
|
38
|
+
end
|
39
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -2,8 +2,8 @@ require 'reform'
|
|
2
2
|
require 'minitest/autorun'
|
3
3
|
|
4
4
|
class ReformSpec < MiniTest::Spec
|
5
|
-
let (:duran) {
|
6
|
-
let (:rio) {
|
5
|
+
let (:duran) { Struct.new(:name).new("Duran Duran") }
|
6
|
+
let (:rio) { Struct.new(:title).new("Rio") }
|
7
7
|
end
|
8
8
|
|
9
9
|
require 'active_record'
|
@@ -15,3 +15,37 @@ ActiveRecord::Base.establish_connection(
|
|
15
15
|
)
|
16
16
|
|
17
17
|
#Artist.delete_all
|
18
|
+
|
19
|
+
class BaseTest < MiniTest::Spec
|
20
|
+
class AlbumForm < Reform::Form
|
21
|
+
property :title
|
22
|
+
|
23
|
+
property :hit do
|
24
|
+
property :title
|
25
|
+
end
|
26
|
+
|
27
|
+
collection :songs do
|
28
|
+
property :title
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Song = Struct.new(:title)
|
33
|
+
Album = Struct.new(:title, :hit, :songs, :band)
|
34
|
+
Band = Struct.new(:label)
|
35
|
+
Label = Struct.new(:name)
|
36
|
+
|
37
|
+
|
38
|
+
let (:hit) { Song.new("Roxanne") }
|
39
|
+
end
|
40
|
+
|
41
|
+
MiniTest::Spec.class_eval do
|
42
|
+
module Saveable
|
43
|
+
def save
|
44
|
+
@saved = true
|
45
|
+
end
|
46
|
+
|
47
|
+
def saved?
|
48
|
+
@saved
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ValidateTest < BaseTest
|
4
|
+
describe "populated" do
|
5
|
+
let (:params) {
|
6
|
+
{
|
7
|
+
"title" => "Best Of",
|
8
|
+
"hit" => {"title" => "Roxanne"},
|
9
|
+
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}]
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
subject { AlbumForm.new(Album.new(nil, Song.new, [Song.new, Song.new])) }
|
14
|
+
|
15
|
+
before { subject.validate(params) }
|
16
|
+
|
17
|
+
it { subject.title.must_equal "Best Of" }
|
18
|
+
|
19
|
+
it { subject.hit.must_be_kind_of Reform::Form }
|
20
|
+
it { subject.hit.title.must_equal "Roxanne" }
|
21
|
+
|
22
|
+
it { subject.songs.must_be_kind_of Array }
|
23
|
+
it { subject.songs.size.must_equal 2 }
|
24
|
+
|
25
|
+
it { subject.songs[0].must_be_kind_of Reform::Form }
|
26
|
+
it { subject.songs[0].title.must_equal "Fallout" }
|
27
|
+
|
28
|
+
it { subject.songs[1].must_be_kind_of Reform::Form }
|
29
|
+
it { subject.songs[1].title.must_equal "Roxanne" }
|
30
|
+
end
|
31
|
+
|
32
|
+
# TODO: the following tests go to populate_test.rb
|
33
|
+
describe "manual setup with populator" do
|
34
|
+
let (:form) {
|
35
|
+
Class.new(Reform::Form) do
|
36
|
+
property :hit, :populator => lambda { |fragment, args|
|
37
|
+
puts "******************* #{fragment}"
|
38
|
+
|
39
|
+
hit or self.hit = args.binding[:form].new(Song.new)
|
40
|
+
} do
|
41
|
+
property :title
|
42
|
+
end
|
43
|
+
end
|
44
|
+
}
|
45
|
+
|
46
|
+
let (:params) {
|
47
|
+
{
|
48
|
+
"hit" => {"title" => "Roxanne"},
|
49
|
+
# "songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}]
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
subject { form.new(Album.new) }
|
54
|
+
|
55
|
+
before { subject.validate(params) }
|
56
|
+
|
57
|
+
it { subject.hit.title.must_equal "Roxanne" }
|
58
|
+
end
|
59
|
+
|
60
|
+
describe ":populate_if_empty" do
|
61
|
+
let (:form) {
|
62
|
+
Class.new(Reform::Form) do
|
63
|
+
property :hit, :populate_if_empty => lambda { |fragment, args| Song.new } do
|
64
|
+
property :title
|
65
|
+
end
|
66
|
+
|
67
|
+
collection :songs, :populate_if_empty => lambda { |fragment, args| model.songs.build } do
|
68
|
+
property :title
|
69
|
+
end
|
70
|
+
|
71
|
+
property :band, :populate_if_empty => lambda { |fragment, args| Band.new } do
|
72
|
+
property :label, :populate_if_empty => lambda { |fragment, args| Label.new } do
|
73
|
+
property :name
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
}
|
78
|
+
|
79
|
+
let (:params) {
|
80
|
+
{
|
81
|
+
"hit" => {"title" => "Roxanne"},
|
82
|
+
"songs" => [{"title" => "Fallout"}, {"title" => "Roxanne"}],
|
83
|
+
"band" => {"label" => {"name" => "Epitaph"}}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
let (:song_collection_proxy) { Class.new(Array) { def build; Song.new; end } }
|
88
|
+
let (:album) { Album.new(nil,nil, song_collection_proxy.new, nil) }
|
89
|
+
subject { form.new(album) } # DISCUSS: require at least an array here? this is provided by all ORMs.
|
90
|
+
|
91
|
+
before { subject.validate(params) }
|
92
|
+
|
93
|
+
it { subject.hit.title.must_equal "Roxanne" }
|
94
|
+
it { subject.songs[0].title.must_equal "Fallout" }
|
95
|
+
it { subject.songs[1].title.must_equal "Roxanne" }
|
96
|
+
|
97
|
+
it { album.hit.must_be_kind_of Struct }
|
98
|
+
it { album.songs.size.must_equal 2 } # #validate must associate items with model.
|
99
|
+
|
100
|
+
it { subject.band.label.name.must_equal "Epitaph" }
|
101
|
+
end
|
102
|
+
|
103
|
+
|
104
|
+
describe "populate_if_empty: Class" do
|
105
|
+
let (:form) {
|
106
|
+
Class.new(Reform::Form) do
|
107
|
+
property :hit, :populate_if_empty => Song do
|
108
|
+
property :title
|
109
|
+
end
|
110
|
+
end
|
111
|
+
}
|
112
|
+
|
113
|
+
let (:params) {
|
114
|
+
{
|
115
|
+
"hit" => {"title" => "Roxanne"},
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
let (:album) { Album.new }
|
120
|
+
subject { form.new(album) }
|
121
|
+
|
122
|
+
before { subject.validate(params) }
|
123
|
+
|
124
|
+
it { subject.hit.title.must_equal "Roxanne" }
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
# test cardinalities.
|
129
|
+
describe "with empty collection and cardinality" do
|
130
|
+
let (:album) { Album.new }
|
131
|
+
|
132
|
+
subject { Class.new(Reform::Form) do
|
133
|
+
include Reform::Form::ActiveModel
|
134
|
+
model :album
|
135
|
+
|
136
|
+
collection :songs do
|
137
|
+
property :title
|
138
|
+
end
|
139
|
+
|
140
|
+
property :hit do
|
141
|
+
property :title
|
142
|
+
end
|
143
|
+
|
144
|
+
validates :songs, :length => {:minimum => 1}
|
145
|
+
validates :hit, :presence => true
|
146
|
+
end.new(album) }
|
147
|
+
|
148
|
+
|
149
|
+
describe "invalid" do
|
150
|
+
before { subject.validate({}).must_equal false }
|
151
|
+
|
152
|
+
it { subject.errors.messages.must_equal(
|
153
|
+
:songs => ["is too short (minimum is 1 characters)"],
|
154
|
+
:hit => ["can't be blank"]) }
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
describe "valid" do
|
159
|
+
let (:album) { Album.new(nil, Song.new, [Song.new("Urban Myth")]) }
|
160
|
+
|
161
|
+
before {
|
162
|
+
subject.validate({"songs" => [{"title"=>"Daddy, Brother, Lover, Little Boy"}], "hit" => {"title"=>"The Horse"}}).
|
163
|
+
must_equal true
|
164
|
+
}
|
165
|
+
|
166
|
+
it { subject.errors.messages.must_equal({}) }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
describe "with symbols" do
|
172
|
+
let (:album) { OpenStruct.new(:band => OpenStruct.new(:label => OpenStruct.new(:name => "Epitaph"))) }
|
173
|
+
subject { ErrorsTest::AlbumForm.new(album) }
|
174
|
+
let (:params) { {:band => {:label => {:name => "Stiff"}}, :title => "House Of Fun"} }
|
175
|
+
|
176
|
+
before {
|
177
|
+
subject.validate(params).must_equal true
|
178
|
+
}
|
179
|
+
|
180
|
+
it { subject.band.label.name.must_equal "Stiff" }
|
181
|
+
it { subject.title.must_equal "House Of Fun" }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
# #validate(params)
|
186
|
+
# title=(params[:title])
|
187
|
+
# song.validate(params[:song], errors)
|
188
|
+
|
189
|
+
# #sync (assumes that forms already have updated fields)
|
190
|
+
# model.title=
|
191
|
+
# song.sync
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: reform
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-05-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: representable
|
@@ -17,14 +17,28 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 1.
|
20
|
+
version: 1.8.1
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 1.
|
27
|
+
version: 1.8.1
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: disposable
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.0.3
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 0.0.3
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: uber
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -175,12 +189,19 @@ files:
|
|
175
189
|
- lib/reform.rb
|
176
190
|
- lib/reform/active_record.rb
|
177
191
|
- lib/reform/composition.rb
|
192
|
+
- lib/reform/contract.rb
|
193
|
+
- lib/reform/contract/errors.rb
|
194
|
+
- lib/reform/contract/setup.rb
|
195
|
+
- lib/reform/contract/validate.rb
|
178
196
|
- lib/reform/form.rb
|
179
197
|
- lib/reform/form/active_model.rb
|
180
198
|
- lib/reform/form/active_record.rb
|
181
199
|
- lib/reform/form/coercion.rb
|
182
200
|
- lib/reform/form/composition.rb
|
183
201
|
- lib/reform/form/multi_parameter_attributes.rb
|
202
|
+
- lib/reform/form/save.rb
|
203
|
+
- lib/reform/form/sync.rb
|
204
|
+
- lib/reform/form/validate.rb
|
184
205
|
- lib/reform/form/virtual_attributes.rb
|
185
206
|
- lib/reform/rails.rb
|
186
207
|
- lib/reform/representer.rb
|
@@ -188,8 +209,10 @@ files:
|
|
188
209
|
- reform.gemspec
|
189
210
|
- test/active_model_test.rb
|
190
211
|
- test/active_record_test.rb
|
212
|
+
- test/as_test.rb
|
191
213
|
- test/coercion_test.rb
|
192
214
|
- test/composition_test.rb
|
215
|
+
- test/contract_test.rb
|
193
216
|
- test/dummy/Rakefile
|
194
217
|
- test/dummy/app/controllers/albums_controller.rb
|
195
218
|
- test/dummy/app/controllers/application_controller.rb
|
@@ -214,11 +237,17 @@ files:
|
|
214
237
|
- test/dummy/log/production.log
|
215
238
|
- test/dummy/log/server.log
|
216
239
|
- test/errors_test.rb
|
240
|
+
- test/feature_test.rb
|
241
|
+
- test/form_builder_test.rb
|
217
242
|
- test/form_composition_test.rb
|
218
243
|
- test/nested_form_test.rb
|
219
244
|
- test/rails/integration_test.rb
|
220
245
|
- test/reform_test.rb
|
246
|
+
- test/save_test.rb
|
247
|
+
- test/setup_test.rb
|
248
|
+
- test/sync_test.rb
|
221
249
|
- test/test_helper.rb
|
250
|
+
- test/validate_test.rb
|
222
251
|
homepage: ''
|
223
252
|
licenses:
|
224
253
|
- MIT
|
@@ -247,8 +276,10 @@ summary: Decouples your models from form by giving you form objects with validat
|
|
247
276
|
test_files:
|
248
277
|
- test/active_model_test.rb
|
249
278
|
- test/active_record_test.rb
|
279
|
+
- test/as_test.rb
|
250
280
|
- test/coercion_test.rb
|
251
281
|
- test/composition_test.rb
|
282
|
+
- test/contract_test.rb
|
252
283
|
- test/dummy/Rakefile
|
253
284
|
- test/dummy/app/controllers/albums_controller.rb
|
254
285
|
- test/dummy/app/controllers/application_controller.rb
|
@@ -273,8 +304,15 @@ test_files:
|
|
273
304
|
- test/dummy/log/production.log
|
274
305
|
- test/dummy/log/server.log
|
275
306
|
- test/errors_test.rb
|
307
|
+
- test/feature_test.rb
|
308
|
+
- test/form_builder_test.rb
|
276
309
|
- test/form_composition_test.rb
|
277
310
|
- test/nested_form_test.rb
|
278
311
|
- test/rails/integration_test.rb
|
279
312
|
- test/reform_test.rb
|
313
|
+
- test/save_test.rb
|
314
|
+
- test/setup_test.rb
|
315
|
+
- test/sync_test.rb
|
280
316
|
- test/test_helper.rb
|
317
|
+
- test/validate_test.rb
|
318
|
+
has_rdoc:
|