freeform 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/.gitignore +8 -17
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +150 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.md +31 -43
  6. data/Rakefile +32 -1
  7. data/freeform.gemspec +22 -15
  8. data/lib/freeform/builder/builder_mixin.rb +111 -0
  9. data/lib/freeform/builder/builders.rb +32 -0
  10. data/lib/freeform/builder/engine.rb +14 -0
  11. data/lib/freeform/builder/view_helper.rb +56 -0
  12. data/lib/freeform/form/form_input_key.rb +1 -1
  13. data/lib/freeform/form/nested.rb +17 -55
  14. data/lib/freeform/form/property.rb +82 -42
  15. data/lib/freeform/form/validation.rb +38 -11
  16. data/lib/freeform/form.rb +24 -27
  17. data/lib/freeform/version.rb +1 -1
  18. data/lib/freeform.rb +4 -0
  19. data/lib/generators/freeform/install_generator.rb +17 -0
  20. data/lib/tasks/freeform_tasks.rake +4 -0
  21. data/spec/acceptance_spec.rb +261 -155
  22. data/spec/builder/builder_spec.rb +215 -0
  23. data/spec/builder/view_helper_spec.rb +97 -0
  24. data/spec/dummy/README.rdoc +28 -0
  25. data/spec/dummy/Rakefile +6 -0
  26. data/spec/dummy/app/assets/images/.keep +0 -0
  27. data/spec/dummy/app/assets/javascripts/application.js +5 -0
  28. data/spec/dummy/app/assets/javascripts/jquery.js +9404 -0
  29. data/spec/dummy/app/assets/javascripts/jquery_events_test.js +19 -0
  30. data/spec/dummy/app/assets/javascripts/projects.js +2 -0
  31. data/spec/dummy/app/assets/javascripts/prototype.js +6082 -0
  32. data/spec/dummy/app/assets/javascripts/prototype_events_test.js +20 -0
  33. data/spec/dummy/app/assets/stylesheets/application.css +7 -0
  34. data/spec/dummy/app/assets/stylesheets/companies.css +4 -0
  35. data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
  36. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  37. data/spec/dummy/app/controllers/companies_controller.rb +5 -0
  38. data/spec/dummy/app/controllers/projects_controller.rb +11 -0
  39. data/spec/dummy/app/forms/milestone_form.rb +4 -0
  40. data/spec/dummy/app/forms/project_form.rb +11 -0
  41. data/spec/dummy/app/forms/task_form.rb +10 -0
  42. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  43. data/spec/dummy/app/mailers/.keep +0 -0
  44. data/spec/dummy/app/models/.keep +0 -0
  45. data/spec/dummy/app/models/company.rb +5 -0
  46. data/spec/dummy/app/models/milestone.rb +6 -0
  47. data/spec/dummy/app/models/project.rb +9 -0
  48. data/spec/dummy/app/models/project_task.rb +3 -0
  49. data/spec/dummy/app/models/task.rb +7 -0
  50. data/spec/dummy/app/views/companies/new.html.erb +16 -0
  51. data/spec/dummy/app/views/layouts/application.html.erb +19 -0
  52. data/spec/dummy/app/views/projects/new.html.erb +13 -0
  53. data/spec/dummy/app/views/projects/without_intermediate_inputs.html.erb +11 -0
  54. data/spec/dummy/bin/bundle +3 -0
  55. data/spec/dummy/bin/rails +4 -0
  56. data/spec/dummy/bin/rake +4 -0
  57. data/spec/dummy/config/application.rb +35 -0
  58. data/spec/dummy/config/boot.rb +5 -0
  59. data/spec/dummy/config/database.yml +25 -0
  60. data/spec/dummy/config/environment.rb +5 -0
  61. data/spec/dummy/config/environments/development.rb +29 -0
  62. data/spec/dummy/config/environments/production.rb +80 -0
  63. data/spec/dummy/config/environments/test.rb +36 -0
  64. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  65. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  66. data/spec/dummy/config/initializers/inflections.rb +16 -0
  67. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  68. data/spec/dummy/config/initializers/secret_token.rb +13 -0
  69. data/spec/dummy/config/initializers/session_store.rb +3 -0
  70. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  71. data/spec/dummy/config/locales/en.yml +23 -0
  72. data/spec/dummy/config/routes.rb +5 -0
  73. data/spec/dummy/config.ru +4 -0
  74. data/spec/dummy/db/migrate/20110710143903_initial_tables.rb +38 -0
  75. data/spec/dummy/db/schema.rb +43 -0
  76. data/spec/dummy/db/test.sqlite3 +0 -0
  77. data/spec/dummy/lib/assets/.keep +0 -0
  78. data/spec/dummy/log/.keep +0 -0
  79. data/spec/dummy/log/development.log +0 -0
  80. data/spec/dummy/log/test.log +39736 -0
  81. data/spec/dummy/public/404.html +58 -0
  82. data/spec/dummy/public/422.html +58 -0
  83. data/spec/dummy/public/500.html +57 -0
  84. data/spec/dummy/public/favicon.ico +0 -0
  85. data/spec/dummy/tmp/cache/assets/C54/850/sprockets%2Fd484f47085686f151320ff7248bb5105 +0 -0
  86. data/spec/dummy/tmp/cache/assets/C76/160/sprockets%2F49c594d143212b346d11f1ecf9358103 +0 -0
  87. data/spec/dummy/tmp/cache/assets/C99/4D0/sprockets%2F5e30a6b911437f1428dc32c3ae182123 +0 -0
  88. data/spec/dummy/tmp/cache/assets/C99/7D0/sprockets%2F79513e6956e0ee8624976e041fd5636d +0 -0
  89. data/spec/dummy/tmp/cache/assets/CAA/C90/sprockets%2F1e6c8ee1258009385ccf5b84015424b3 +0 -0
  90. data/spec/dummy/tmp/cache/assets/CB2/CB0/sprockets%2F11cc8d161d71a716dd36f16849d90870 +0 -0
  91. data/spec/dummy/tmp/cache/assets/CB7/7F0/sprockets%2Fac97b043470f6fcc925c352f16956643 +0 -0
  92. data/spec/dummy/tmp/cache/assets/CBA/680/sprockets%2F912d84e091e5f2190b1ab7926de19679 +0 -0
  93. data/spec/dummy/tmp/cache/assets/CC7/430/sprockets%2F48e99a3e16ba3e65749e009d82546f94 +0 -0
  94. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  95. data/spec/dummy/tmp/cache/assets/CDB/8A0/sprockets%2Faed2a2575c376263c26e93b56b57051d +0 -0
  96. data/spec/dummy/tmp/cache/assets/CF1/E80/sprockets%2F7735295e1e3085f2e1dc29d59a45e8e6 +0 -0
  97. data/spec/dummy/tmp/cache/assets/D0F/E60/sprockets%2F1123d9a479fdf5c2b8415087e2a43ec6 +0 -0
  98. data/spec/dummy/tmp/cache/assets/D1F/A10/sprockets%2F60317e62cb324bfd9987e8da9636fd06 +0 -0
  99. data/spec/dummy/tmp/cache/assets/D25/E20/sprockets%2F29ba1a4a2b611731334f54abb9e5b5d1 +0 -0
  100. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  101. data/spec/dummy/tmp/cache/assets/D35/760/sprockets%2F49e26620c5c743ac4cdab7703f54db06 +0 -0
  102. data/spec/dummy/tmp/cache/assets/D49/870/sprockets%2F90896142645585acc8baf56ad57e3afb +0 -0
  103. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  104. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  105. data/spec/dummy/tmp/cache/assets/D62/F00/sprockets%2F6ac03a007f26b1c18ed3d53498ad3eb8 +0 -0
  106. data/spec/dummy/tmp/cache/assets/D79/BC0/sprockets%2F85a1db977361cc5130fcefb4637ff67e +0 -0
  107. data/spec/dummy/tmp/cache/assets/D87/1F0/sprockets%2F61c9ceafb877fb740c67416ff6f782a9 +0 -0
  108. data/spec/dummy/tmp/cache/assets/DA8/900/sprockets%2Fde7a2b3987b89b9d9afb268ce4204a4a +0 -0
  109. data/spec/dummy/tmp/cache/assets/DAD/4F0/sprockets%2F765acd1bf68dc90f7d3e61da78b1e659 +0 -0
  110. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  111. data/spec/dummy/tmp/cache/assets/E03/3F0/sprockets%2F82b37ae9eccec44c1ef44cfdd07d8534 +0 -0
  112. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  113. data/spec/dummy/tmp/cache/assets/E0A/CA0/sprockets%2F7fe72ac1c0db1a7e8e7f59cf25e8a39e +0 -0
  114. data/spec/dummy/tmp/cache/assets/E20/9B0/sprockets%2F2fa6cd86b1af7bda41f5b7921cdadf10 +0 -0
  115. data/spec/dummy/tmp/cache/assets/E3A/A60/sprockets%2F7c72c96cfc66454caf5fc8ca0fedd4f3 +0 -0
  116. data/spec/dummy/tmp/cache/assets/E54/400/sprockets%2Fd0cbc16cc37efcf9dc41f242b5dbbf81 +0 -0
  117. data/spec/dummy/tmp/cache/assets/EB7/AB0/sprockets%2F801d29a5debdbfbfb4eef14d70d9bcdb +0 -0
  118. data/spec/dummy/tmp/cache/assets/F48/5E0/sprockets%2F26cd6ffcffbebbe2fd6cd1a8f0c2debc +0 -0
  119. data/spec/form/nested_spec.rb +75 -61
  120. data/spec/form/property_spec.rb +167 -14
  121. data/spec/form/validation_spec.rb +46 -23
  122. data/spec/javascript_spec.rb +60 -0
  123. data/spec/persistence_spec.rb +608 -0
  124. data/spec/spec_helper.rb +18 -2
  125. data/vendor/assets/javascripts/jquery_freeform.js +120 -0
  126. data/vendor/assets/javascripts/jquery_nested_form.js +0 -0
  127. data/vendor/assets/javascripts/prototype_freeform.js +69 -0
  128. data/vendor/assets/javascripts/prototype_nested_form.js +0 -0
  129. metadata +341 -3
@@ -1,74 +1,42 @@
1
1
  require 'spec_helper'
2
2
 
3
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
4
+ let!(:task_class) do
5
+ klass = Class.new(FreeForm::Form) do
6
+ form_input_key :task
7
+ form_model :task
8
+ validate_models
9
+ allow_destroy_on_save
10
+
11
+ property :name, :on => :task
12
+ property :start_date, :on => :task
13
+ property :end_date, :on => :task
49
14
  end
15
+ # This wrapper just avoids CONST warnings
16
+ v, $VERBOSE = $VERBOSE, nil
17
+ Module.const_set("TaskForm", klass)
18
+ $VERBOSE = v
19
+ klass
50
20
  end
51
21
 
52
22
  let(:form_class) do
53
23
  klass = Class.new(FreeForm::Form) do
54
- form_input_key :user
55
- form_models :user, :address
24
+ form_input_key :company
25
+ form_models :company
26
+ child_model :project do
27
+ company.project.present? ? company.project : company.build_project
28
+ end
56
29
  validate_models
57
30
  allow_destroy_on_save
58
31
 
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
32
+ property :name, :on => :company, :as => :company_name
33
+ property :name, :on => :project, :as => :project_name
34
+ property :due_date, :on => :project
64
35
 
65
- has_many :phone_numbers, :class_initializer => :phone_number_initializer 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
36
+ has_many :tasks, :class => Module::TaskForm, :default_initializer => :default_task_initializer
37
+
38
+ def default_task_initializer
39
+ { :task => Task.new(:project => project) }
72
40
  end
73
41
  end
74
42
  # This wrapper just avoids CONST warnings
@@ -79,57 +47,65 @@ describe FreeForm::Form do
79
47
  end
80
48
 
81
49
  let(:form) do
82
- form_class.phone_number_initializer = lambda { {:phone => phone_class.new} }
83
- form_model = form_class.new( :user => user_class.new, :address => address_class.new)
84
- form_model.build_phone_number
85
- form_model
50
+ f = form_class.new( :company => Company.new )
51
+ f.build_task
52
+ f
86
53
  end
87
-
54
+
88
55
  describe "form initialization", :initialization => true do
89
- it "initializes with user model" do
90
- form.user.should be_a(user_class)
56
+ it "initializes with Company model" do
57
+ form.company.should be_a(Company)
58
+ end
59
+
60
+ it "initializes with Project model" do
61
+ form.project.should be_a(Project)
91
62
  end
92
63
 
93
- it "initializes with address model" do
94
- form.address.should be_a(address_class)
64
+ it "initializes with Task model" do
65
+ form.tasks.first.task.should be_a(Task)
95
66
  end
96
67
 
97
- it "initializes with phone model" do
98
- form.phone_numbers.first.phone.should be_a(phone_class)
68
+ it "initializes with Task with project parent", :failing => true do
69
+ task = form.tasks.first.task
70
+ task.project.should eq(form.project)
99
71
  end
100
72
  end
101
73
 
102
74
  describe "building nested models", :nested_models => true do
103
- it "can build multiple phone_numbers" do
104
- form.phone_numbers.count.should eq(1)
105
- form.build_phone_number
106
- form.build_phone_number
107
- form.phone_numbers.count.should eq(3)
75
+ it "can build multiple tasks" do
76
+ form.tasks.count.should eq(1)
77
+ form.build_task
78
+ form.build_task
79
+ form.tasks.count.should eq(3)
108
80
  end
109
81
 
110
- it "build new models for each phone numbers" do
111
- form.build_phone_number
112
- phone_1 = form.phone_numbers.first.phone
113
- phone_2 = form.phone_numbers.last.phone
114
- phone_1.should_not eq(phone_2)
82
+ it "build new models for each task" do
83
+ form.build_task
84
+ task_1 = form.tasks.first.task
85
+ task_2 = form.tasks.last.task
86
+ task_1.should_not eq(task_2)
115
87
  end
116
88
  end
117
89
 
118
90
  describe "assigning parameters", :assign_params => true do
119
91
  let(:attributes) do {
120
- :username => "dummyuser",
121
- :email => "test@email.com",
122
- :street => "1 Maple St.",
123
- :city => "Portland",
124
- :state => "Oregon",
125
- :phone_numbers_attributes => {
92
+ :company_name => "dummycorp",
93
+ :project_name => "railsapp",
94
+ "due_date(1i)" => "2014",
95
+ "due_date(2i)" => "10",
96
+ "due_date(3i)" => "30",
97
+ :tasks_attributes => {
126
98
  "0" => {
127
- :area_code => "555",
128
- :number => "123-4567"
99
+ :name => "task_1",
100
+ "start_date(1i)" => "2012",
101
+ "start_date(2i)" => "1",
102
+ "start_date(3i)" => "2",
129
103
  },
130
104
  "1" => {
131
- :area_code => "202",
132
- :number => "876-5432"
105
+ :name => "task_2",
106
+ "end_date(1i)" => "2011",
107
+ "end_date(2i)" => "12",
108
+ "end_date(3i)" => "15",
133
109
  }
134
110
  } }
135
111
  end
@@ -138,41 +114,62 @@ describe FreeForm::Form do
138
114
  form.fill(attributes)
139
115
  end
140
116
 
141
- it "assigns username" do
142
- form.username.should eq("dummyuser")
117
+ it "assigns company name" do
118
+ form.company_name.should eq("dummycorp")
119
+ form.company.name.should eq("dummycorp")
120
+ end
121
+
122
+ it "assigns project name" do
123
+ form.project_name.should eq("railsapp")
124
+ form.project.name.should eq("railsapp")
143
125
  end
144
126
 
145
- it "assigns street" do
146
- form.street.should eq("1 Maple St.")
127
+ it "assigns project due date" do
128
+ form.due_date.should eq(Date.new(2014, 10, 30))
129
+ form.project.due_date.should eq(Date.new(2014, 10, 30))
147
130
  end
148
131
 
149
- it "assigns phone number area code" do
150
- form.phone_numbers.first.phone.area_code.should eq("555")
132
+ it "builds new task automatically" do
133
+ form.tasks.count.should eq(2)
151
134
  end
152
135
 
153
- it "builds new phone number automatically" do
154
- form.phone_numbers.count.should eq(2)
136
+ it "assigns first task name" do
137
+ form.tasks.first.task.name.should eq("task_1")
155
138
  end
156
139
 
157
- it "assigns second phone number area code" do
158
- form.phone_numbers.last.phone.area_code.should eq("202")
140
+ it "assigns first task start_date" do
141
+ form.tasks.first.task.start_date.should eq(Date.new(2012, 1, 2))
142
+ end
143
+
144
+ it "assigns second task name" do
145
+ form.tasks.last.task.name.should eq("task_2")
146
+ end
147
+
148
+ it "assigns second task end_date" do
149
+ form.tasks.last.task.end_date.should eq(Date.new(2011, 12, 15))
159
150
  end
160
151
  end
161
152
 
162
153
  describe "validations", :validations => true do
163
154
  context "with invalid attributes" do
164
155
  let(:attributes) do {
165
- :username => "dummyuser",
166
- :email => "test@email.com",
167
- :street => nil,
168
- :city => "Portland",
169
- :state => "Oregon",
170
- :phone_numbers_attributes => {
156
+ :company_name => "dummycorp",
157
+ :project_name => nil,
158
+ "due_date(1i)" => "2014",
159
+ "due_date(2i)" => "10",
160
+ "due_date(3i)" => "30",
161
+ :tasks_attributes => {
171
162
  "0" => {
172
- :number => "123-4567"
163
+ :name => "task_1",
164
+ "start_date(1i)" => "2012",
165
+ "start_date(2i)" => "1",
166
+ "start_date(3i)" => "2",
173
167
  },
174
168
  "1" => {
175
- :area_code => "202"
169
+ :name => "task_2",
170
+ "end_date(1i)" => "2011",
171
+ "end_date(2i)" => "12",
172
+ "end_date(3i)" => "15",
176
173
  }
177
174
  } }
178
175
  end
@@ -186,18 +183,116 @@ describe FreeForm::Form do
186
183
  form.should_not be_valid
187
184
  end
188
185
 
189
- it "should have errors on street" do
190
- form.errors[:street].should eq(["can't be blank"])
186
+ it "should have errors on project name" do
187
+ form.errors[:project_name].should eq(["can't be blank"])
188
+ end
189
+
190
+ it "should have errors on last tasks's start_date" do
191
+ form.tasks.last.errors[:start_date].should eq(["can't be blank"])
192
+ end
193
+ end
194
+
195
+ context "with invalid nested model only" do
196
+ let(:attributes) do {
197
+ :company_name => "dummycorp",
198
+ :project_name => "rails app",
199
+ "due_date(1i)" => "2014",
200
+ "due_date(2i)" => "10",
201
+ "due_date(3i)" => "30",
202
+ :tasks_attributes => {
203
+ "0" => {
204
+ :name => "task_1",
205
+ "start_date(1i)" => "2012",
206
+ "start_date(2i)" => "1",
207
+ "start_date(3i)" => "2",
208
+ },
209
+ "1" => {
210
+ :name => "task_2",
211
+ "end_date(1i)" => "2011",
212
+ "end_date(2i)" => "12",
213
+ "end_date(3i)" => "15",
214
+ }
215
+ } }
216
+ end
217
+
218
+ before(:each) do
219
+ form.fill(attributes)
220
+ form.valid?
221
+ end
222
+
223
+ it "should be invalid" do
224
+ form.should_not be_valid
191
225
  end
192
226
 
193
- it "should have errors on first phone number's area code" do
194
- form.phone_numbers.first.errors[:area_code].should be_empty
227
+ it "should have errors on last tasks's start_date" do
228
+ form.tasks.last.errors[:start_date].should eq(["can't be blank"])
195
229
  end
230
+ end
196
231
 
197
- it "should have errors on first phone number's number" do
198
- form.phone_numbers.last.errors[:number].should eq(["can't be blank"])
232
+ context "with valid attributes" do
233
+ let(:attributes) do {
234
+ :company_name => "dummycorp",
235
+ :project_name => "railsapp",
236
+ "due_date(1i)" => "2014",
237
+ "due_date(2i)" => "10",
238
+ "due_date(3i)" => "30",
239
+ :tasks_attributes => {
240
+ "0" => {
241
+ :name => "task_1",
242
+ "start_date(1i)" => "2012",
243
+ "start_date(2i)" => "1",
244
+ "start_date(3i)" => "2",
245
+ },
246
+ "1" => {
247
+ :name => "task_2",
248
+ "start_date(1i)" => "2011",
249
+ "start_date(2i)" => "8",
250
+ "start_date(3i)" => "15",
251
+ "end_date(1i)" => "2011",
252
+ "end_date(2i)" => "12",
253
+ "end_date(3i)" => "15",
254
+ }
255
+ } }
199
256
  end
257
+
258
+ before(:each) do
259
+ form.fill(attributes)
260
+ end
261
+
262
+ it "should be valid" do
263
+ form.should be_valid
264
+ end
265
+ end
266
+ end
200
267
 
268
+ describe "saving and destroying", :saving => true do
269
+ context "with invalid attributes" do
270
+ let(:attributes) do {
271
+ :company_name => "dummycorp",
272
+ :project_name => nil,
273
+ "due_date(1i)" => "2014",
274
+ "due_date(2i)" => "10",
275
+ "due_date(3i)" => "30",
276
+ :tasks_attributes => {
277
+ "0" => {
278
+ :name => "task_1",
279
+ "start_date(1i)" => "2012",
280
+ "start_date(2i)" => "1",
281
+ "start_date(3i)" => "2",
282
+ },
283
+ "1" => {
284
+ :name => "task_2",
285
+ "end_date(1i)" => "2011",
286
+ "end_date(2i)" => "12",
287
+ "end_date(3i)" => "15",
288
+ }
289
+ } }
290
+ end
291
+
292
+ before(:each) do
293
+ form.fill(attributes)
294
+ end
295
+
201
296
  it "should return false on 'save'" do
202
297
  form.save.should be_false
203
298
  end
@@ -209,19 +304,26 @@ describe FreeForm::Form do
209
304
 
210
305
  context "with valid attributes" do
211
306
  let(:attributes) do {
212
- :username => "dummyuser",
213
- :email => "test@email.com",
214
- :street => "1 Maple St.",
215
- :city => "Portland",
216
- :state => "Oregon",
217
- :phone_numbers_attributes => {
307
+ :company_name => "dummycorp",
308
+ :project_name => "railsapp",
309
+ "due_date(1i)" => "2014",
310
+ "due_date(2i)" => "10",
311
+ "due_date(3i)" => "30",
312
+ :tasks_attributes => {
218
313
  "0" => {
219
- :area_code => "555",
220
- :number => "123-4567"
314
+ :name => "task_1",
315
+ "start_date(1i)" => "2012",
316
+ "start_date(2i)" => "1",
317
+ "start_date(3i)" => "2",
221
318
  },
222
319
  "1" => {
223
- :area_code => "202",
224
- :number => "876-5432"
320
+ :name => "task_2",
321
+ "start_date(1i)" => "2011",
322
+ "start_date(2i)" => "8",
323
+ "start_date(3i)" => "15",
324
+ "end_date(1i)" => "2011",
325
+ "end_date(2i)" => "12",
326
+ "end_date(3i)" => "15",
225
327
  }
226
328
  } }
227
329
  end
@@ -230,47 +332,48 @@ describe FreeForm::Form do
230
332
  form.fill(attributes)
231
333
  end
232
334
 
233
- it "should be valid" do
234
- form.should be_valid
235
- end
236
-
237
335
  it "should return true on 'save', and call save on other models" do
238
- form.user.should_receive(:save).and_return(true)
239
- form.address.should_receive(:save).and_return(true)
240
- form.phone_numbers.first.phone.should_receive(:save).and_return(true)
336
+ form.company.should_receive(:save).and_return(true)
337
+ form.project.should_receive(:save).and_return(true)
338
+ form.tasks.first.task.should_receive(:save).and_return(true)
339
+ form.tasks.last.task.should_receive(:save).and_return(true)
241
340
  form.save
242
341
  end
243
342
 
244
343
  it "should return true on 'save!', and call save! on other models" do
245
- form.user.should_receive(:save!).and_return(true)
246
- form.address.should_receive(:save!).and_return(true)
247
- form.phone_numbers.first.phone.should_receive(:save!).and_return(true)
344
+ form.company.should_receive(:save!).and_return(true)
345
+ form.project.should_receive(:save!).and_return(true)
346
+ form.tasks.first.task.should_receive(:save!).and_return(true)
347
+ form.tasks.last.task.should_receive(:save!).and_return(true)
248
348
  form.save!
249
349
  end
250
-
350
+
251
351
  describe "destroying on save", :destroy_on_save => true do
252
352
  describe "save" do
253
353
  it "destroys models on save if set" do
254
354
  form._destroy = true
255
- form.user.should_receive(:destroy).and_return(true)
256
- form.address.should_receive(:destroy).and_return(true)
257
- form.phone_numbers.first.phone.should_receive(:save).and_return(true)
355
+ form.company.should_receive(:destroy).and_return(true)
356
+ form.project.should_receive(:destroy).and_return(true)
357
+ form.tasks.first.task.should_receive(:save).and_return(true)
358
+ form.tasks.last.task.should_receive(:save).and_return(true)
258
359
  form.save
259
360
  end
260
361
 
261
362
  it "destroys models on save if set through attribute" do
262
363
  form.fill({:_destroy => "1"})
263
- form.user.should_receive(:destroy).and_return(true)
264
- form.address.should_receive(:destroy).and_return(true)
265
- form.phone_numbers.first.phone.should_receive(:save).and_return(true)
364
+ form.company.should_receive(:destroy).and_return(true)
365
+ form.project.should_receive(:destroy).and_return(true)
366
+ form.tasks.first.task.should_receive(:save).and_return(true)
367
+ form.tasks.last.task.should_receive(:save).and_return(true)
266
368
  form.save
267
369
  end
268
370
 
269
371
  it "destroys nested models on save if set" do
270
- form.phone_numbers.first._destroy = true
271
- form.user.should_receive(:save).and_return(true)
272
- form.address.should_receive(:save).and_return(true)
273
- form.phone_numbers.first.phone.should_receive(:destroy).and_return(true)
372
+ form.tasks.first._destroy = true
373
+ form.company.should_receive(:save).and_return(true)
374
+ form.project.should_receive(:save).and_return(true)
375
+ form.tasks.first.task.should_receive(:destroy).and_return(true)
376
+ form.tasks.last.task.should_receive(:save).and_return(true)
274
377
  form.save
275
378
  end
276
379
  end
@@ -278,25 +381,28 @@ describe FreeForm::Form do
278
381
  describe "save!" do
279
382
  it "destroys models on save! if set" do
280
383
  form._destroy = true
281
- form.user.should_receive(:destroy).and_return(true)
282
- form.address.should_receive(:destroy).and_return(true)
283
- form.phone_numbers.first.phone.should_receive(:save!).and_return(true)
384
+ form.company.should_receive(:destroy).and_return(true)
385
+ form.project.should_receive(:destroy).and_return(true)
386
+ form.tasks.first.task.should_receive(:save!).and_return(true)
387
+ form.tasks.last.task.should_receive(:save!).and_return(true)
284
388
  form.save!
285
389
  end
286
390
 
287
391
  it "destroys models on save! if set" do
288
392
  form.fill({:_destroy => "1"})
289
- form.user.should_receive(:destroy).and_return(true)
290
- form.address.should_receive(:destroy).and_return(true)
291
- form.phone_numbers.first.phone.should_receive(:save!).and_return(true)
393
+ form.company.should_receive(:destroy).and_return(true)
394
+ form.project.should_receive(:destroy).and_return(true)
395
+ form.tasks.first.task.should_receive(:save!).and_return(true)
396
+ form.tasks.last.task.should_receive(:save!).and_return(true)
292
397
  form.save!
293
398
  end
294
399
 
295
400
  it "destroys nested models on save! if set" do
296
- form.phone_numbers.first._destroy = true
297
- form.user.should_receive(:save!).and_return(true)
298
- form.address.should_receive(:save!).and_return(true)
299
- form.phone_numbers.first.phone.should_receive(:destroy).and_return(true)
401
+ form.tasks.last._destroy = true
402
+ form.company.should_receive(:save!).and_return(true)
403
+ form.project.should_receive(:save!).and_return(true)
404
+ form.tasks.first.task.should_receive(:save!).and_return(true)
405
+ form.tasks.last.task.should_receive(:destroy).and_return(true)
300
406
  form.save!
301
407
  end
302
408
  end