freeform 0.0.4 → 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.
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