freeform 0.0.2 → 0.0.3.rc1

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.
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # FreeForm
2
2
 
3
- FreeForm is a gem designed to give you total control over form objects, allowing you to map form objects to domain objects in any way that you see fit.
3
+ FreeForm is a gem designed to give you total control over form objects, allowing you to map form objects to domain objects in any way that you see fit. The primary benefits are:
4
+ * Decoupling form objects from domain models
5
+ * Allowing form-specific validations, while respecting model validations
6
+ * Simply composing multi-model forms
7
+ * Removing the ugliness of `accepts_nested_attributes_for`
4
8
 
5
- It is still a very-pre-beta work in progess, but hopefully it can showcase the power of form objects.
6
-
7
- FreeForm is designed primarily with Rails in mind, but it should work on any Ruby framework.
8
-
9
- FreeForm is compatible with (as far as I know) most form gems, including simpleform, formbuilder, and Ryan Bate's nested_form gem.
9
+ FreeForm is designed primarily with Rails in mind, but it should work on any Ruby framework. FreeForm is compatible with most form gems, including simpleform, formbuilder, and Ryan Bate's nested_form gem.
10
10
 
11
11
  ## Installation
12
12
 
@@ -107,6 +107,58 @@ end
107
107
  user = User.new
108
108
  RegistrationForm.new(:user => user, :address => user.build_address)
109
109
  ```
110
+ ## Assigning Parameters
111
+
112
+ Forms can be populated either directly through accessors (e.g. `form.street = "123 Main St."`), or using the `assign_params()` or `fill()` methods.
113
+
114
+ ```ruby
115
+ class RegistrationForm < FreeForm::Form
116
+ form_models :user, :address
117
+
118
+ property :username, :on => :user
119
+ property :street, :on => :address
120
+ end
121
+
122
+ form = RegistrationForm.new(:user => User.new, :address => Address.new)
123
+ form.assign_params({ :username => "myusername", :street => "1600 Pennsylvania Ave." })
124
+ # fill() is just an alias for assign_params
125
+ form.fill({ :username => "myusername", :street => "1600 Pennsylvania Ave." })
126
+ ```
127
+
128
+ ## Saving & Marking For Destruction
129
+
130
+ Calling `form.save` will validate the form, then make a save call to each model defined in the form (and each nested form). A call to `save!` behaves the same way.
131
+
132
+ ```ruby
133
+ class RegistrationForm < FreeForm::Form
134
+ form_models :user, :address
135
+
136
+ property :username, :on => :user
137
+ property :street, :on => :address
138
+ end
139
+
140
+ form = RegistrationForm.new(:user => User.new, :address => Address.new)
141
+ form.fill({ :username => "myusername", :street => "1600 Pennsylvania Ave." })
142
+ form.save # SAVES the User and Address models
143
+ ```
144
+
145
+ Additionally, each model has a method you can add called `allow_destroy_on_save`. This method adds an accessor called `_destroy` (also aliased as `marked_for_destruction`) that can be set. If this is set, each form in the model will receive a `destroy` call on save.
146
+
147
+ ```ruby
148
+ class RegistrationForm < FreeForm::Form
149
+ form_models :user, :address
150
+ allow_destroy_on_save
151
+
152
+ property :username, :on => :user
153
+ property :street, :on => :address
154
+ end
155
+
156
+ form = RegistrationForm.new(:user => User.new, :address => Address.new)
157
+ form.fill({ :username => "myusername", :street => "1600 Pennsylvania Ave.", :_destroy => "1" })
158
+ form.save # DESTROYS the User and Address models
159
+ ```
160
+ This method is necessary if you use the nested_form gem for dynamically creating/deleting models.
161
+
110
162
  ## Form Validations
111
163
 
112
164
  FreeForm handles validations wherever you define them. If you want to check model validations, simply specify that option in your form definition
@@ -64,7 +64,7 @@ module FreeForm
64
64
  form_class = self.class.nested_forms[:"#{attribute}"]
65
65
 
66
66
  # Set default intializer if none provided
67
- initializer ||= send("#{attribute}_form_initializer")
67
+ initializer ||= send("#{attribute}_form_initializer").call
68
68
 
69
69
  # Build new model
70
70
  form_model = form_class.new(initializer)
@@ -33,6 +33,12 @@ module FreeForm
33
33
  @ignored_blank_params ||= []
34
34
  end
35
35
 
36
+ def allow_destroy_on_save
37
+ # Define _destroy method for marked-for-destruction handling
38
+ attr_accessor :_destroy
39
+ alias_method :marked_for_destruction, :_destroy
40
+ end
41
+
36
42
  def property(attribute, options={})
37
43
  if options[:on]
38
44
  def_delegator options[:on], attribute
@@ -1,5 +1,5 @@
1
1
  module FreeForm
2
- module Persistence
2
+ module Validation
3
3
  def self.included(base)
4
4
  base.extend(ClassMethods)
5
5
  end
@@ -9,30 +9,7 @@ module FreeForm
9
9
  validate :model_validity
10
10
  end
11
11
  end
12
-
13
- def save
14
- return false unless valid?
15
- self.class.models.each do |form_model|
16
- if send(form_model).is_a?(Array)
17
- send(form_model).each { |model| return model.save }
18
- else
19
- return false unless send(form_model).save
20
- end
21
- end
22
- return true
23
- end
24
-
25
- def save!
26
- raise StandardError, "form invalid." unless valid?
27
- self.class.models.each do |form_model|
28
- if send(form_model).is_a?(Array)
29
- send(form_model).each { |model| model.save! }
30
- else
31
- send(form_model).save!
32
- end
33
- end
34
- end
35
-
12
+
36
13
  protected
37
14
  def model_validity
38
15
  model_validity = true
data/lib/freeform/form.rb CHANGED
@@ -1,6 +1,10 @@
1
1
  require 'forwardable'
2
2
  require 'ostruct'
3
3
  require 'active_model'
4
+ require 'freeform/form/form_input_key'
5
+ require 'freeform/form/nested'
6
+ require 'freeform/form/property'
7
+ require 'freeform/form/validation'
4
8
 
5
9
  module FreeForm
6
10
  class Form
@@ -9,6 +13,10 @@ module FreeForm
9
13
  extend ActiveModel::Callbacks
10
14
  include ActiveModel::Conversion
11
15
  include ActiveModel::Validations
16
+ include FreeForm::FormInputKey
17
+ include FreeForm::Nested
18
+ include FreeForm::Property
19
+ include FreeForm::Validation
12
20
 
13
21
  # Instance Methods
14
22
  #----------------------------------------------------------------------------
@@ -20,5 +28,44 @@ module FreeForm
20
28
  def initialize(h={})
21
29
  h.each {|k,v| send("#{k}=",v)}
22
30
  end
31
+
32
+ def save
33
+ return false unless valid?
34
+ self.class.models.each do |form_model|
35
+ if send(form_model).is_a?(Array)
36
+ send(form_model).each { |model| return model.save }
37
+ else
38
+ if marked_for_destruction?
39
+ send(form_model).destroy
40
+ else
41
+ return false unless send(form_model).save
42
+ end
43
+ end
44
+ end
45
+ return true
46
+ end
47
+
48
+ def save!
49
+ raise StandardError, "form invalid." unless valid?
50
+ self.class.models.each do |form_model|
51
+ if send(form_model).is_a?(Array)
52
+ send(form_model).each { |model| model.save! }
53
+ else
54
+ if marked_for_destruction?
55
+ send(form_model).destroy
56
+ else
57
+ send(form_model).save!
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def marked_for_destruction?
64
+ if self.respond_to?(:_destroy)
65
+ return self._destroy
66
+ else
67
+ return false
68
+ end
69
+ end
23
70
  end
24
71
  end
@@ -1,3 +1,3 @@
1
1
  module Freeform
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3.rc1"
3
3
  end
data/lib/freeform.rb CHANGED
@@ -1,14 +1,5 @@
1
1
  require 'freeform/version'
2
2
  require 'freeform/form'
3
- #require 'reform/form/composition'
4
- #require 'reform/form/active_model'
5
3
 
6
- if defined?(Rails) # DISCUSS: is everyone ok with this?
7
- # require 'reform/rails'
8
- end
9
-
10
- =begin
11
- module Freeform
12
- # Your code goes here...
13
- end
14
- =end
4
+ if defined?(Rails) # Where to include Rails specific modules...
5
+ end
@@ -0,0 +1,309 @@
1
+ require 'spec_helper'
2
+
3
+ describe FreeForm::Form do
4
+ let(:user_class) do
5
+ Class.new(Module) do
6
+ include ActiveModel::Validations
7
+ def self.model_name; ActiveModel::Name.new(self, nil, "user") end
8
+
9
+ attr_accessor :username
10
+ attr_accessor :email
11
+ validates :username, :presence => true
12
+
13
+ def save; return valid? end
14
+ alias_method :save!, :save
15
+ def destroy; return true end
16
+ end
17
+ end
18
+
19
+ let(:address_class) do
20
+ Class.new(Module) do
21
+ include ActiveModel::Validations
22
+ def self.model_name; ActiveModel::Name.new(self, nil, "address") end
23
+
24
+ attr_accessor :street
25
+ attr_accessor :city
26
+ attr_accessor :state
27
+ validates :street, :presence => true
28
+ validates :city, :presence => true
29
+ validates :state, :presence => true
30
+
31
+ def save; return valid? end
32
+ alias_method :save!, :save
33
+ def destroy; return true end
34
+ end
35
+ end
36
+
37
+ let(:phone_class) do
38
+ Class.new(Module) do
39
+ include ActiveModel::Validations
40
+ def self.model_name; ActiveModel::Name.new(self, nil, "phone") end
41
+
42
+ attr_accessor :area_code
43
+ attr_accessor :number
44
+ validates :number, :presence => true
45
+
46
+ def save; return valid? end
47
+ alias_method :save!, :save
48
+ def destroy; return true end
49
+ end
50
+ end
51
+
52
+ let(:form_class) do
53
+ klass = Class.new(FreeForm::Form) do
54
+ form_input_key :user
55
+ form_models :user, :address
56
+ validate_models
57
+ allow_destroy_on_save
58
+
59
+ property :username, :on => :user
60
+ property :email, :on => :user
61
+ property :street, :on => :address
62
+ property :city, :on => :address
63
+ property :state, :on => :address
64
+
65
+ has_many :phone_numbers do
66
+ form_model :phone
67
+ validate_models
68
+ allow_destroy_on_save
69
+
70
+ property :area_code, :on => :phone
71
+ property :number, :on => :phone
72
+ end
73
+ end
74
+ # This wrapper just avoids CONST warnings
75
+ v, $VERBOSE = $VERBOSE, nil
76
+ Module.const_set("AcceptanceForm", klass)
77
+ $VERBOSE = v
78
+ klass
79
+ end
80
+
81
+ let(:form) do
82
+ form_model = form_class.new(
83
+ :user => user_class.new,
84
+ :address => address_class.new,
85
+ :phone_numbers_form_initializer => lambda { { :phone => phone_class.new } }
86
+ )
87
+ form_model.build_phone_number
88
+ form_model
89
+ end
90
+
91
+ describe "form initialization", :initialization => true do
92
+ it "initializes with user model" do
93
+ form.user.should be_a(user_class)
94
+ end
95
+
96
+ it "initializes with address model" do
97
+ form.address.should be_a(address_class)
98
+ end
99
+
100
+ it "initializes with phone model" do
101
+ form.phone_numbers.first.phone.should be_a(phone_class)
102
+ end
103
+ end
104
+
105
+ describe "building nested models", :nested_models => true do
106
+ it "can build multiple phone_numbers" do
107
+ form.phone_numbers.count.should eq(1)
108
+ form.build_phone_number
109
+ form.build_phone_number
110
+ form.phone_numbers.count.should eq(3)
111
+ end
112
+
113
+ it "build new models for each phone numbers" do
114
+ form.build_phone_number
115
+ phone_1 = form.phone_numbers.first.phone
116
+ phone_2 = form.phone_numbers.last.phone
117
+ phone_1.should_not eq(phone_2)
118
+ end
119
+ end
120
+
121
+ describe "assigning parameters", :assign_params => true do
122
+ let(:attributes) do {
123
+ :username => "dummyuser",
124
+ :email => "test@email.com",
125
+ :street => "1 Maple St.",
126
+ :city => "Portland",
127
+ :state => "Oregon",
128
+ :phone_numbers_attributes => {
129
+ "0" => {
130
+ :area_code => "555",
131
+ :number => "123-4567"
132
+ },
133
+ "1" => {
134
+ :area_code => "202",
135
+ :number => "876-5432"
136
+ }
137
+ } }
138
+ end
139
+
140
+ before(:each) do
141
+ form.fill(attributes)
142
+ end
143
+
144
+ it "assigns username" do
145
+ form.username.should eq("dummyuser")
146
+ end
147
+
148
+ it "assigns street" do
149
+ form.street.should eq("1 Maple St.")
150
+ end
151
+
152
+ it "assigns phone number area code" do
153
+ form.phone_numbers.first.phone.area_code.should eq("555")
154
+ end
155
+
156
+ it "builds new phone number automatically" do
157
+ form.phone_numbers.count.should eq(2)
158
+ end
159
+
160
+ it "assigns second phone number area code" do
161
+ form.phone_numbers.last.phone.area_code.should eq("202")
162
+ end
163
+ end
164
+
165
+ describe "validations", :validations => true do
166
+ context "with invalid attributes" do
167
+ let(:attributes) do {
168
+ :username => "dummyuser",
169
+ :email => "test@email.com",
170
+ :street => nil,
171
+ :city => "Portland",
172
+ :state => "Oregon",
173
+ :phone_numbers_attributes => {
174
+ "0" => {
175
+ :number => "123-4567"
176
+ },
177
+ "1" => {
178
+ :area_code => "202"
179
+ }
180
+ } }
181
+ end
182
+
183
+ before(:each) do
184
+ form.fill(attributes)
185
+ form.valid?
186
+ end
187
+
188
+ it "should be invalid" do
189
+ form.should_not be_valid
190
+ end
191
+
192
+ it "should have errors on street" do
193
+ form.errors[:street].should eq(["can't be blank"])
194
+ end
195
+
196
+ it "should have errors on first phone number's area code" do
197
+ form.phone_numbers.first.errors[:area_code].should be_empty
198
+ end
199
+
200
+ it "should have errors on first phone number's number" do
201
+ form.phone_numbers.last.errors[:number].should eq(["can't be blank"])
202
+ end
203
+
204
+ it "should return false on 'save'" do
205
+ form.save.should be_false
206
+ end
207
+
208
+ it "should raise error on 'save!'" do
209
+ expect{ form.save!.should be_false }.to raise_error
210
+ end
211
+ end
212
+
213
+ context "with valid attributes" do
214
+ let(:attributes) do {
215
+ :username => "dummyuser",
216
+ :email => "test@email.com",
217
+ :street => "1 Maple St.",
218
+ :city => "Portland",
219
+ :state => "Oregon",
220
+ :phone_numbers_attributes => {
221
+ "0" => {
222
+ :area_code => "555",
223
+ :number => "123-4567"
224
+ },
225
+ "1" => {
226
+ :area_code => "202",
227
+ :number => "876-5432"
228
+ }
229
+ } }
230
+ end
231
+
232
+ before(:each) do
233
+ form.fill(attributes)
234
+ end
235
+
236
+ it "should be valid" do
237
+ form.should be_valid
238
+ end
239
+
240
+ it "should return true on 'save', and call save on other models" do
241
+ form.user.should_receive(:save).and_return(true)
242
+ form.address.should_receive(:save).and_return(true)
243
+ form.phone_numbers.first.phone.should_receive(:save).and_return(true)
244
+ form.save
245
+ end
246
+
247
+ it "should return true on 'save!', and call save! on other models" do
248
+ form.user.should_receive(:save!).and_return(true)
249
+ form.address.should_receive(:save!).and_return(true)
250
+ form.phone_numbers.first.phone.should_receive(:save!).and_return(true)
251
+ form.save!
252
+ end
253
+
254
+ describe "destroying on save", :destroy_on_save => true do
255
+ describe "save" do
256
+ it "destroys models on save if set" do
257
+ form._destroy = true
258
+ form.user.should_receive(:destroy).and_return(true)
259
+ form.address.should_receive(:destroy).and_return(true)
260
+ form.phone_numbers.first.phone.should_receive(:save).and_return(true)
261
+ form.save
262
+ end
263
+
264
+ it "destroys models on save if set through attribute" do
265
+ form.fill({:_destroy => "1"})
266
+ form.user.should_receive(:destroy).and_return(true)
267
+ form.address.should_receive(:destroy).and_return(true)
268
+ form.phone_numbers.first.phone.should_receive(:save).and_return(true)
269
+ form.save
270
+ end
271
+
272
+ it "destroys nested models on save if set" do
273
+ form.phone_numbers.first._destroy = true
274
+ form.user.should_receive(:save).and_return(true)
275
+ form.address.should_receive(:save).and_return(true)
276
+ form.phone_numbers.first.phone.should_receive(:destroy).and_return(true)
277
+ form.save
278
+ end
279
+ end
280
+
281
+ describe "save!" do
282
+ it "destroys models on save! if set" do
283
+ form._destroy = true
284
+ form.user.should_receive(:destroy).and_return(true)
285
+ form.address.should_receive(:destroy).and_return(true)
286
+ form.phone_numbers.first.phone.should_receive(:save!).and_return(true)
287
+ form.save!
288
+ end
289
+
290
+ it "destroys models on save! if set" do
291
+ form.fill({:_destroy => "1"})
292
+ form.user.should_receive(:destroy).and_return(true)
293
+ form.address.should_receive(:destroy).and_return(true)
294
+ form.phone_numbers.first.phone.should_receive(:save!).and_return(true)
295
+ form.save!
296
+ end
297
+
298
+ it "destroys nested models on save! if set" do
299
+ form.phone_numbers.first._destroy = true
300
+ form.user.should_receive(:save!).and_return(true)
301
+ form.address.should_receive(:save!).and_return(true)
302
+ form.phone_numbers.first.phone.should_receive(:destroy).and_return(true)
303
+ form.save!
304
+ end
305
+ end
306
+ end
307
+ end
308
+ end
309
+ end
@@ -28,7 +28,9 @@ describe FreeForm::Nested do
28
28
  end
29
29
 
30
30
  let(:form) do
31
- form_class.new( :mailing_address_form_initializer => { :address => OpenStruct.new } )
31
+ form_model = form_class.new(
32
+ :mailing_address_form_initializer => lambda { { :address => OpenStruct.new } }
33
+ )
32
34
  end
33
35
 
34
36
  describe "form class" do
@@ -49,6 +51,16 @@ describe FreeForm::Nested do
49
51
  form.mailing_addresses.first.should be_a(Module::DummyForm::MailingAddressesForm)
50
52
  end
51
53
 
54
+ it "builds unique models" do
55
+ # Using module here, since they initialize uniquely
56
+ form.mailing_address_form_initializer = lambda { { :address => Module.new } }
57
+ form.build_mailing_address
58
+ form.build_mailing_address
59
+ address_1 = form.mailing_addresses.first.address
60
+ address_2 = form.mailing_addresses.last.address
61
+ address_1.should_not eq(address_2)
62
+ end
63
+
52
64
  it "allows nested_forms to be built with custom initializers" do
53
65
  form.build_mailing_address(:address => OpenStruct.new(:street => "1600 Pennsylvania Ave."))
54
66
  form.mailing_addresses.first.street.should eq("1600 Pennsylvania Ave.")
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
  require 'freeform/form/property'
3
3
  require 'freeform/form/nested'
4
- require 'freeform/form/persistence'
4
+ require 'freeform/form/validation'
5
5
 
6
- describe FreeForm::Persistence do
6
+ describe FreeForm::Validation do
7
7
  let(:user) do
8
8
  model = Class.new(Module) do
9
9
  include ActiveModel::Validations
@@ -34,13 +34,13 @@ describe FreeForm::Persistence do
34
34
  end
35
35
 
36
36
  describe "validation", :validation => true do
37
- context "without model validation" do
37
+ context "without model validation", :no_model_validation => true do
38
38
  let(:form_class) do
39
39
  klass = Class.new(Module) do
40
40
  include ActiveModel::Validations
41
41
  include FreeForm::Property
42
42
  include FreeForm::Nested
43
- include FreeForm::Persistence
43
+ include FreeForm::Validation
44
44
 
45
45
  form_model :user
46
46
  property :username, :on => :user
@@ -64,7 +64,9 @@ describe FreeForm::Persistence do
64
64
  end
65
65
 
66
66
  let(:form) do
67
- test_form = form_class.new( :user => OpenStruct.new, :address_form_initializer => { :address => OpenStruct.new } )
67
+ test_form = form_class.new(
68
+ :user => user,
69
+ :address_form_initializer => lambda { { :address => address } } )
68
70
  test_form.build_address
69
71
  test_form
70
72
  end
@@ -84,13 +86,13 @@ describe FreeForm::Persistence do
84
86
  end
85
87
  end
86
88
 
87
- context "with model validation" do
89
+ context "with model validation", :model_validation => true do
88
90
  let(:form_class) do
89
91
  klass = Class.new(Module) do
90
92
  include ActiveModel::Validations
91
93
  include FreeForm::Property
92
94
  include FreeForm::Nested
93
- include FreeForm::Persistence
95
+ include FreeForm::Validation
94
96
  validate_models
95
97
 
96
98
  form_model :user
@@ -102,7 +104,7 @@ describe FreeForm::Persistence do
102
104
  include ActiveModel::Validations
103
105
  include FreeForm::Property
104
106
  include FreeForm::Nested
105
- include FreeForm::Persistence
107
+ include FreeForm::Validation
106
108
  validate_models
107
109
  declared_model :address
108
110
 
@@ -122,7 +124,9 @@ describe FreeForm::Persistence do
122
124
  end
123
125
 
124
126
  let(:form) do
125
- test_form = form_class.new( :user => user, :address_form_initializer => { :address => address } )
127
+ test_form = form_class.new(
128
+ :user => user,
129
+ :address_form_initializer => lambda { { :address => address } } )
126
130
  test_form.build_address
127
131
  test_form
128
132
  end
@@ -147,91 +151,4 @@ describe FreeForm::Persistence do
147
151
  end
148
152
  end
149
153
  end
150
-
151
- describe "saving", :saving => true do
152
- let(:form_class) do
153
- klass = Class.new(Module) do
154
- include ActiveModel::Validations
155
- include FreeForm::Property
156
- include FreeForm::Nested
157
- include FreeForm::Persistence
158
- validate_models
159
-
160
- form_model :user
161
- property :username, :on => :user
162
- property :form_property
163
- validates :form_property, :presence => true
164
-
165
- nested_form :addresses do
166
- include ActiveModel::Validations
167
- include FreeForm::Property
168
- include FreeForm::Nested
169
- include FreeForm::Persistence
170
- validate_models
171
- declared_model :address
172
-
173
- property :street, :on => :address
174
- property :city, :on => :address
175
- end
176
-
177
- def initialize(h={})
178
- h.each {|k,v| send("#{k}=",v)}
179
- end
180
- end
181
- # This wrapper just avoids CONST warnings
182
- v, $VERBOSE = $VERBOSE, nil
183
- Module.const_set("DummyForm", klass)
184
- $VERBOSE = v
185
- klass
186
- end
187
-
188
- let(:form) do
189
- test_form = form_class.new( :user => user, :address_form_initializer => { :address => address } )
190
- test_form.build_address
191
- test_form
192
- end
193
-
194
- context "form is invalid" do
195
- it "should be invalid" do
196
- form.should_not be_valid
197
- end
198
-
199
- it "should return false on 'save'" do
200
- form.save.should be_false
201
- end
202
-
203
- it "should raise error on 'save!'" do
204
- expect{ form.save!.should be_false }.to raise_error
205
- end
206
- end
207
-
208
- context "form is valid" do
209
- before(:each) do
210
- form.fill({
211
- :username => "myusername",
212
- :form_property => "present",
213
- :addresses_attributes => { "0" => {
214
- :street => "123 Main St.",
215
- :city => "Springfield"
216
- } }
217
- })
218
- end
219
-
220
- it "should be valid" do
221
- form.should be_valid
222
- end
223
-
224
- it "should return true on 'save', and call save on other models" do
225
- user.should_receive(:save).and_return(true)
226
- address.should_receive(:save).and_return(true)
227
- form.save.should be_true
228
- end
229
-
230
- it "should return true on 'save!', and call save! on other models" do
231
- user.should_receive(:save!).and_return(true)
232
- address.should_receive(:save!).and_return(true)
233
- form.save!.should be_true
234
- end
235
- end
236
- end
237
154
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freeform
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 0.0.3.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - brycesenz
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-14 00:00:00.000000000 Z
12
+ date: 2013-11-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activemodel
@@ -94,13 +94,14 @@ files:
94
94
  - lib/freeform/form.rb
95
95
  - lib/freeform/form/form_input_key.rb
96
96
  - lib/freeform/form/nested.rb
97
- - lib/freeform/form/persistence.rb
98
97
  - lib/freeform/form/property.rb
98
+ - lib/freeform/form/validation.rb
99
99
  - lib/freeform/version.rb
100
+ - spec/acceptance_spec.rb
100
101
  - spec/form/form_input_key_spec.rb
101
102
  - spec/form/nested_spec.rb
102
- - spec/form/persistence_spec.rb
103
103
  - spec/form/property_spec.rb
104
+ - spec/form/validation_spec.rb
104
105
  - spec/spec_helper.rb
105
106
  homepage: https://github.com/brycesenz/freeform
106
107
  licenses:
@@ -118,9 +119,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
118
119
  required_rubygems_version: !ruby/object:Gem::Requirement
119
120
  none: false
120
121
  requirements:
121
- - - ! '>='
122
+ - - ! '>'
122
123
  - !ruby/object:Gem::Version
123
- version: '0'
124
+ version: 1.3.1
124
125
  requirements: []
125
126
  rubyforge_project:
126
127
  rubygems_version: 1.8.25
@@ -129,8 +130,9 @@ specification_version: 3
129
130
  summary: FreeForm lets you compose forms however you like, explicitly guiding how
130
131
  each field maps back to your domain models. No more accepting nested attributes!
131
132
  test_files:
133
+ - spec/acceptance_spec.rb
132
134
  - spec/form/form_input_key_spec.rb
133
135
  - spec/form/nested_spec.rb
134
- - spec/form/persistence_spec.rb
135
136
  - spec/form/property_spec.rb
137
+ - spec/form/validation_spec.rb
136
138
  - spec/spec_helper.rb