nofxx-formtastic 0.1.8 → 0.1.9

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.
@@ -236,6 +236,10 @@ describe 'Formtastic' do
236
236
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
237
237
  end
238
238
 
239
+ after do
240
+ Formtastic::SemanticFormHelper.builder = Formtastic::SemanticFormBuilder
241
+ end
242
+
239
243
  it "can be overridden" do
240
244
 
241
245
  class CustomFormBuilder < Formtastic::SemanticFormBuilder
@@ -287,6 +291,103 @@ describe 'Formtastic' do
287
291
  end
288
292
  end
289
293
 
294
+ describe '#label' do
295
+ it 'should humanize the given attribute' do
296
+ semantic_form_for(@new_post) do |builder|
297
+ builder.label(:login).should have_tag('label', :with => /Login/)
298
+ end
299
+ end
300
+
301
+ it 'should be printed as span' do
302
+ semantic_form_for(@new_post) do |builder|
303
+ builder.label(:login, nil, { :required => true, :as_span => true }).should have_tag('span.label abbr')
304
+ end
305
+ end
306
+
307
+ describe 'when required is given' do
308
+ it 'should append a required note' do
309
+ semantic_form_for(@new_post) do |builder|
310
+ builder.label(:login, nil, :required => true).should have_tag('label abbr')
311
+ end
312
+ end
313
+
314
+ it 'should allow require option to be given as second argument' do
315
+ semantic_form_for(@new_post) do |builder|
316
+ builder.label(:login, :required => true).should have_tag('label abbr')
317
+ end
318
+ end
319
+ end
320
+
321
+ describe 'when label is given' do
322
+ it 'should allow the text to be given as label option' do
323
+ semantic_form_for(@new_post) do |builder|
324
+ builder.label(:login, :required => true, :label => 'My label').should have_tag('label', :with => /My label/)
325
+ end
326
+ end
327
+
328
+ it 'should return nil if label is false' do
329
+ semantic_form_for(@new_post) do |builder|
330
+ builder.label(:login, :label => false).should be_nil
331
+ end
332
+ end
333
+ end
334
+ end
335
+
336
+ describe '#errors_on' do
337
+ before(:each) do
338
+ @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
339
+ @errors = mock('errors')
340
+ @errors.stub!(:on).with('title').and_return(@title_errors)
341
+ @errors.stub!(:on).with('body').and_return(nil)
342
+ @new_post.stub!(:errors).and_return(@errors)
343
+ end
344
+
345
+ describe 'and the errors will be displayed as a sentence' do
346
+ it 'should render a paragraph with the errors joined into a sentence' do
347
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
348
+ semantic_form_for(@new_post) do |builder|
349
+ builder.errors_on(:title).should have_tag('p.inline-errors', @title_errors.to_sentence)
350
+ end
351
+ end
352
+ end
353
+
354
+ describe 'and the errors will be displayed as a list' do
355
+ it 'should render an unordered list with the class errors' do
356
+ Formtastic::SemanticFormBuilder.inline_errors = :list
357
+ semantic_form_for(@new_post) do |builder|
358
+ builder.errors_on(:title).should have_tag('ul.errors')
359
+ end
360
+ end
361
+
362
+ it 'should include a list element for each of the errors within the unordered list' do
363
+ Formtastic::SemanticFormBuilder.inline_errors = :list
364
+ semantic_form_for(@new_post) do |builder|
365
+ @title_errors.each do |error|
366
+ builder.errors_on(:title).should have_tag('ul.errors li', error)
367
+ end
368
+ end
369
+ end
370
+ end
371
+
372
+ describe 'but the errors will not be shown' do
373
+ it 'should return nil' do
374
+ Formtastic::SemanticFormBuilder.inline_errors = :none
375
+ semantic_form_for(@new_post) do |builder|
376
+ builder.errors_on(:title).should be_nil
377
+ end
378
+ end
379
+ end
380
+
381
+ describe 'and no error is found on the method' do
382
+ it 'should return nil' do
383
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
384
+ semantic_form_for(@new_post) do |builder|
385
+ builder.errors_on(:body).should be_nil
386
+ end
387
+ end
388
+ end
389
+ end
390
+
290
391
  describe '#input' do
291
392
 
292
393
  before do
@@ -540,6 +641,10 @@ describe 'Formtastic' do
540
641
  default_input_type(:decimal).should == :numeric
541
642
  end
542
643
 
644
+ it 'should default to :country for :string columns named country' do
645
+ default_input_type(:string, :country).should == :country
646
+ end
647
+
543
648
  describe 'defaulting to file column' do
544
649
  Formtastic::SemanticFormBuilder.file_methods.each do |method|
545
650
  it "should default to :file for attributes that respond to ##{method}" do
@@ -562,7 +667,7 @@ describe 'Formtastic' do
562
667
  end
563
668
 
564
669
  it 'should call the corresponding input method' do
565
- [:select, :time_zone, :radio, :date, :datetime, :time, :boolean].each do |input_style|
670
+ [:select, :time_zone, :radio, :date, :datetime, :time, :boolean, :check_boxes, :hidden].each do |input_style|
566
671
  @new_post.stub!(:generic_column_name)
567
672
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
568
673
  semantic_form_for(@new_post) do |builder|
@@ -649,6 +754,30 @@ describe 'Formtastic' do
649
754
 
650
755
  end
651
756
 
757
+ describe ':size option' do
758
+ describe 'when provided' do
759
+ it 'should be passed down to the input tag' do
760
+ semantic_form_for(@new_post) do |builder|
761
+ concat(builder.input(:title, :size => 17))
762
+ end
763
+ output_buffer.should have_tag('form li input#post_title[@size=17]')
764
+ end
765
+ end
766
+
767
+ describe 'when not provided' do
768
+ it 'should default to the configured default text size' do
769
+ # Temporarily rewrite the value so that we know the output size isn't just a coincidence
770
+ old_value = Formtastic::SemanticFormBuilder.default_text_field_size
771
+ Formtastic::SemanticFormBuilder.default_text_field_size = 31
772
+ semantic_form_for(@new_post) do |builder|
773
+ concat(builder.input(:title))
774
+ end
775
+ Formtastic::SemanticFormBuilder.default_text_field_size = old_value
776
+ output_buffer.should have_tag('form li input#post_title[@size=31]')
777
+ end
778
+ end
779
+ end
780
+
652
781
  describe ':wrapper_html option' do
653
782
 
654
783
  describe 'when provided' do
@@ -702,7 +831,6 @@ describe 'Formtastic' do
702
831
  end
703
832
 
704
833
  describe 'when there are errors on the object for this method' do
705
-
706
834
  before do
707
835
  @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
708
836
  @errors = mock('errors')
@@ -724,65 +852,24 @@ describe 'Formtastic' do
724
852
  output_buffer.should_not have_tag('div.fieldWithErrors')
725
853
  end
726
854
 
727
- describe 'and the errors will be displayed as a sentence' do
728
-
729
- before do
730
- Formtastic::SemanticFormBuilder.inline_errors = :sentence
731
- semantic_form_for(@new_post) do |builder|
732
- concat(builder.input(:title))
733
- end
734
- end
735
-
736
- it 'should render a paragraph with the errors joined into a sentence' do
737
- output_buffer.should have_tag('form li.error p.inline-errors', @title_errors.to_sentence)
738
- end
739
-
740
- end
741
-
742
- describe 'and the errors will be displayed as a list' do
743
-
744
- before do
745
- Formtastic::SemanticFormBuilder.inline_errors = :list
746
- semantic_form_for(@new_post) do |builder|
747
- concat(builder.input(:title))
748
- end
749
- end
750
-
751
- it 'should render an unordered list with the class errors' do
752
- output_buffer.should have_tag('form li.error ul.errors')
753
- end
754
-
755
- it 'should include a list element for each of the errors within the unordered list' do
756
- @title_errors.each do |error|
757
- output_buffer.should have_tag('form li.error ul.errors li', error)
758
- end
855
+ it 'should render a paragraph for the errors' do
856
+ Formtastic::SemanticFormBuilder.inline_errors = :sentence
857
+ semantic_form_for(@new_post) do |builder|
858
+ concat(builder.input(:title))
759
859
  end
760
-
860
+ output_buffer.should have_tag('form li.error p.inline-errors')
761
861
  end
762
862
 
763
- describe 'but the errors will not be shown' do
764
-
765
- before do
766
- Formtastic::SemanticFormBuilder.inline_errors = :none
767
- semantic_form_for(@new_post) do |builder|
768
- concat(builder.input(:title))
769
- end
770
- end
771
-
772
- it 'should not display an error sentence' do
773
- output_buffer.should_not have_tag('form li.error p.inline-errors')
774
- end
775
-
776
- it 'should not display an error list' do
777
- output_buffer.should_not have_tag('form li.error ul.errors')
863
+ it 'should not display an error list' do
864
+ Formtastic::SemanticFormBuilder.inline_errors = :list
865
+ semantic_form_for(@new_post) do |builder|
866
+ concat(builder.input(:title))
778
867
  end
779
-
868
+ output_buffer.should have_tag('form li.error ul.errors')
780
869
  end
781
-
782
870
  end
783
871
 
784
872
  describe 'when there are no errors on the object for this method' do
785
-
786
873
  before do
787
874
  semantic_form_for(@new_post) do |builder|
788
875
  concat(builder.input(:title))
@@ -800,11 +887,9 @@ describe 'Formtastic' do
800
887
  it 'should not display an error list' do
801
888
  output_buffer.should_not have_tag('form li.error ul.errors')
802
889
  end
803
-
804
890
  end
805
891
 
806
892
  describe 'when no object is provided' do
807
-
808
893
  before do
809
894
  semantic_form_for(:project, :url => 'http://test.host') do |builder|
810
895
  concat(builder.input(:title))
@@ -822,7 +907,6 @@ describe 'Formtastic' do
822
907
  it 'should not display an error list' do
823
908
  output_buffer.should_not have_tag('form li.error ul.errors')
824
909
  end
825
-
826
910
  end
827
911
  end
828
912
 
@@ -989,30 +1073,65 @@ describe 'Formtastic' do
989
1073
 
990
1074
  end
991
1075
 
992
- it 'should generate input and labels even if no object is given' do
993
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
994
- concat(builder.input(:title, :as => type))
1076
+ describe 'when no object is given' do
1077
+ before(:each) do
1078
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1079
+ concat(builder.input(:title, :as => type))
1080
+ end
995
1081
  end
996
1082
 
997
- output_buffer.should have_tag('form li label')
998
- output_buffer.should have_tag('form li label[@for="project_title"')
999
- output_buffer.should have_tag('form li label', /Title/)
1083
+ it 'should generate input' do
1084
+ if template_method.to_s =~ /_field$/ # password_field
1085
+ output_buffer.should have_tag("form li input")
1086
+ output_buffer.should have_tag("form li input#project_title")
1087
+ output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1088
+ output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
1089
+ else
1090
+ output_buffer.should have_tag("form li #{input_type}")
1091
+ output_buffer.should have_tag("form li #{input_type}#project_title")
1092
+ output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
1093
+ end
1094
+ end
1000
1095
 
1001
- if template_method.to_s =~ /_field$/ # password_field
1002
- output_buffer.should have_tag("form li input")
1003
- output_buffer.should have_tag("form li input#project_title")
1004
- output_buffer.should have_tag("form li input[@type=\"#{input_type}\"]")
1005
- output_buffer.should have_tag("form li input[@name=\"project[title]\"]")
1006
- else
1007
- output_buffer.should have_tag("form li #{input_type}")
1008
- output_buffer.should have_tag("form li #{input_type}#project_title")
1009
- output_buffer.should have_tag("form li #{input_type}[@name=\"project[title]\"]")
1096
+ it 'should generate labels' do
1097
+ output_buffer.should have_tag('form li label')
1098
+ output_buffer.should have_tag('form li label[@for="project_title"')
1099
+ output_buffer.should have_tag('form li label', /Title/)
1010
1100
  end
1011
1101
  end
1012
1102
 
1013
1103
  end
1014
1104
  end
1015
1105
 
1106
+ describe ":as => :hidden" do
1107
+ before do
1108
+ @new_post.stub!(:hidden)
1109
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1110
+
1111
+ semantic_form_for(@new_post) do |builder|
1112
+ concat(builder.input(:hidden, :as => :hidden))
1113
+ end
1114
+ end
1115
+
1116
+ it "should have a hidden class on the wrapper" do
1117
+ output_buffer.should have_tag('form li.hidden')
1118
+ end
1119
+
1120
+ it 'should have a post_hidden_input id on the wrapper' do
1121
+ output_buffer.should have_tag('form li#post_hidden_input')
1122
+ end
1123
+
1124
+ it 'should not generate a label for the input' do
1125
+ output_buffer.should_not have_tag('form li label')
1126
+ end
1127
+
1128
+ it "should generate a input field" do
1129
+ output_buffer.should have_tag("form li input#post_hidden")
1130
+ output_buffer.should have_tag("form li input[@type=\"hidden\"]")
1131
+ output_buffer.should have_tag("form li input[@name=\"post[hidden]\"]")
1132
+ end
1133
+ end
1134
+
1016
1135
  describe ":as => :time_zone" do
1017
1136
  before do
1018
1137
  @new_post.stub!(:time_zone)
@@ -1050,27 +1169,110 @@ describe 'Formtastic' do
1050
1169
  output_buffer.should have_tag("form li select.myclass")
1051
1170
  end
1052
1171
 
1053
- it 'should generate input and labels even if no object is given' do
1054
- semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1055
- concat(builder.input(:time_zone, :as => :time_zone))
1172
+ describe 'when no object is given' do
1173
+ before(:each) do
1174
+ semantic_form_for(:project, :url => 'http://test.host/') do |builder|
1175
+ concat(builder.input(:time_zone, :as => :time_zone))
1176
+ end
1056
1177
  end
1057
1178
 
1058
- output_buffer.should have_tag('form li label')
1059
- output_buffer.should have_tag('form li label[@for="project_time_zone"')
1060
- output_buffer.should have_tag('form li label', /Time zone/)
1179
+ it 'should generate labels' do
1180
+ output_buffer.should have_tag('form li label')
1181
+ output_buffer.should have_tag('form li label[@for="project_time_zone"')
1182
+ output_buffer.should have_tag('form li label', /Time zone/)
1183
+ end
1061
1184
 
1062
- output_buffer.should have_tag("form li select")
1063
- output_buffer.should have_tag("form li select#project_time_zone")
1064
- output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
1185
+ it 'should generate select inputs' do
1186
+ output_buffer.should have_tag("form li select")
1187
+ output_buffer.should have_tag("form li select#project_time_zone")
1188
+ output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
1189
+ end
1065
1190
  end
1066
1191
  end
1067
1192
 
1193
+ describe ":as => :country" do
1194
+
1195
+ before do
1196
+ @new_post.stub!(:country)
1197
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :string))
1198
+ end
1199
+
1200
+ describe "when country_select is not available as a helper from a plugin" do
1201
+
1202
+ it "should raise an error, sugesting the author installs a plugin" do
1203
+ lambda {
1204
+ semantic_form_for(@new_post) do |builder|
1205
+ concat(builder.input(:country, :as => :country))
1206
+ end
1207
+ }.should raise_error
1208
+ end
1209
+
1210
+ end
1211
+
1212
+ describe "when country_select is available as a helper (from a plugin)" do
1213
+
1214
+ before do
1215
+ semantic_form_for(@new_post) do |builder|
1216
+ builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1217
+ concat(builder.input(:country, :as => :country))
1218
+ end
1219
+ end
1220
+
1221
+ it "should have a time_zone class on the wrapper" do
1222
+ output_buffer.should have_tag('form li.country')
1223
+ end
1224
+
1225
+ it 'should have a post_title_input id on the wrapper' do
1226
+ output_buffer.should have_tag('form li#post_country_input')
1227
+ end
1228
+
1229
+ it 'should generate a label for the input' do
1230
+ output_buffer.should have_tag('form li label')
1231
+ output_buffer.should have_tag('form li label[@for="post_country"')
1232
+ output_buffer.should have_tag('form li label', /Country/)
1233
+ end
1234
+
1235
+ it "should generate a select" do
1236
+ output_buffer.should have_tag("form li select")
1237
+ end
1238
+
1239
+ end
1240
+
1241
+ describe ":priority_countries option" do
1242
+
1243
+ it "should be passed down to the country_select helper when provided" do
1244
+ priority_countries = ["Foo", "Bah"]
1245
+ semantic_form_for(@new_post) do |builder|
1246
+ builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1247
+ builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
1248
+
1249
+ concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
1250
+ end
1251
+ end
1252
+
1253
+ it "should default to the @@priority_countries config when absent" do
1254
+ priority_countries = Formtastic::SemanticFormBuilder.priority_countries
1255
+ priority_countries.should_not be_empty
1256
+ priority_countries.should_not be_nil
1257
+
1258
+ semantic_form_for(@new_post) do |builder|
1259
+ builder.stub!(:country_select).and_return("<select><option>...</option></select>")
1260
+ builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("<select><option>...</option></select>")
1261
+
1262
+ concat(builder.input(:country, :as => :country))
1263
+ end
1264
+ end
1265
+
1266
+ end
1267
+
1268
+ end
1269
+
1068
1270
  describe ':as => :radio' do
1069
1271
 
1070
1272
  before do
1071
1273
  @new_post.stub!(:author).and_return(@bob)
1072
1274
  @new_post.stub!(:author_id).and_return(@bob.id)
1073
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1275
+ Post.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :klass => Author, :macro => :belongs_to) }
1074
1276
  end
1075
1277
 
1076
1278
  describe 'for belongs_to association' do
@@ -1084,7 +1286,7 @@ describe 'Formtastic' do
1084
1286
  output_buffer.should have_tag('form li.radio')
1085
1287
  end
1086
1288
 
1087
- it 'should have a post_author_id_input id on the wrapper' do
1289
+ it 'should have a post_author_input id on the wrapper' do
1088
1290
  output_buffer.should have_tag('form li#post_author_input')
1089
1291
  end
1090
1292
 
@@ -1099,7 +1301,7 @@ describe 'Formtastic' do
1099
1301
  output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1100
1302
  end
1101
1303
 
1102
- it 'should have one option with a "selected" attribute' do
1304
+ it 'should have one option with a "checked" attribute' do
1103
1305
  output_buffer.should have_tag('form li input[@checked]', :count => 1)
1104
1306
  end
1105
1307
 
@@ -1107,10 +1309,8 @@ describe 'Formtastic' do
1107
1309
 
1108
1310
  it 'should contain a label for the radio input with a nested input and label text' do
1109
1311
  Author.find(:all).each do |author|
1110
- output_buffer.should have_tag('form li fieldset ol li label')
1111
1312
  output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1112
1313
  output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
1113
- output_buffer.should have_tag("form li fieldset ol li label input")
1114
1314
  end
1115
1315
  end
1116
1316
 
@@ -1142,29 +1342,39 @@ describe 'Formtastic' do
1142
1342
  end
1143
1343
  end
1144
1344
 
1145
- it 'should generate a fieldset, legend, labels and inputs even if no object is given' do
1146
- output_buffer.replace ''
1345
+ describe 'and no object is given' do
1346
+ before(:each) do
1347
+ output_buffer.replace ''
1348
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
1349
+ concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
1350
+ end
1351
+ end
1147
1352
 
1148
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1149
- concat(builder.input(:author_id, :as => :radio, :collection => Author.find(:all)))
1353
+ it 'should generate a fieldset with legend' do
1354
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
1150
1355
  end
1151
1356
 
1152
- output_buffer.should have_tag('form li fieldset legend', /Author/)
1153
- output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1357
+ it 'shold generate an li tag for each item in the collection' do
1358
+ output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1359
+ end
1154
1360
 
1155
- Author.find(:all).each do |author|
1156
- output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1157
- output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1361
+ it 'should generate labels for each item' do
1362
+ Author.find(:all).each do |author|
1363
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1364
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1365
+ end
1366
+ end
1158
1367
 
1159
- output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1160
- output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1161
- output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1162
- output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
1368
+ it 'should generate inputs for each item' do
1369
+ Author.find(:all).each do |author|
1370
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1371
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
1372
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1373
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
1374
+ end
1163
1375
  end
1164
1376
  end
1165
-
1166
1377
  end
1167
-
1168
1378
  end
1169
1379
 
1170
1380
  describe ':as => :select' do
@@ -1322,19 +1532,126 @@ describe 'Formtastic' do
1322
1532
  end
1323
1533
  end
1324
1534
 
1325
- it 'should generate label, select and options even if object is not given' do
1326
- semantic_form_for(:project, :url => 'http://test.host') do |builder|
1327
- concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
1535
+ describe 'when no object is given' do
1536
+ before(:each) do
1537
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
1538
+ concat(builder.input(:author, :as => :select, :collection => Author.find(:all)))
1539
+ end
1328
1540
  end
1329
1541
 
1330
- output_buffer.should have_tag('form li label', /Author/)
1331
- output_buffer.should have_tag("form li label[@for='project_author']")
1542
+ it 'should generate label' do
1543
+ output_buffer.should have_tag('form li label', /Author/)
1544
+ output_buffer.should have_tag("form li label[@for='project_author']")
1545
+ end
1332
1546
 
1333
- output_buffer.should have_tag('form li select#project_author')
1334
- output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1547
+ it 'should generate select inputs' do
1548
+ output_buffer.should have_tag('form li select#project_author')
1549
+ output_buffer.should have_tag('form li select option', :count => Author.find(:all).size)
1550
+ end
1335
1551
 
1336
- Author.find(:all).each do |author|
1337
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1552
+ it 'should generate an option to each item' do
1553
+ Author.find(:all).each do |author|
1554
+ output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
1555
+ end
1556
+ end
1557
+ end
1558
+ end
1559
+
1560
+ describe ':as => :check_boxes' do
1561
+
1562
+ describe 'for a has_many association' do
1563
+ before do
1564
+ semantic_form_for(@fred) do |builder|
1565
+ concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true))
1566
+ end
1567
+ end
1568
+
1569
+ it 'should have a check_boxes class on the wrapper' do
1570
+ output_buffer.should have_tag('form li.check_boxes')
1571
+ end
1572
+
1573
+ it 'should have a author_posts_input id on the wrapper' do
1574
+ output_buffer.should have_tag('form li#author_posts_input')
1575
+ end
1576
+
1577
+ it 'should generate a fieldset and legend containing label text for the input' do
1578
+ output_buffer.should have_tag('form li fieldset')
1579
+ output_buffer.should have_tag('form li fieldset legend')
1580
+ output_buffer.should have_tag('form li fieldset legend', /Posts/)
1581
+ end
1582
+
1583
+ it 'should generate an ordered list with a list item for each choice' do
1584
+ output_buffer.should have_tag('form li fieldset ol')
1585
+ output_buffer.should have_tag('form li fieldset ol li', :count => Post.find(:all).size)
1586
+ end
1587
+
1588
+ it 'should have one option with a "checked" attribute' do
1589
+ output_buffer.should have_tag('form li input[@checked]', :count => 1)
1590
+ end
1591
+
1592
+ it 'should generate hidden inputs with default value blank' do
1593
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => Post.find(:all).size)
1594
+ end
1595
+
1596
+ describe "each choice" do
1597
+
1598
+ it 'should contain a label for the radio input with a nested input and label text' do
1599
+ Post.find(:all).each do |post|
1600
+ output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
1601
+ output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
1602
+ end
1603
+ end
1604
+
1605
+ it 'should use values as li.class when value_as_class is true' do
1606
+ Post.find(:all).each do |post|
1607
+ output_buffer.should have_tag("form li fieldset ol li.#{post.id} label")
1608
+ end
1609
+ end
1610
+
1611
+ it 'should have a checkbox input for each post' do
1612
+ Post.find(:all).each do |post|
1613
+ output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
1614
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
1615
+ end
1616
+ end
1617
+
1618
+ it "should mark input as checked if it's the the existing choice" do
1619
+ Post.find(:all).include?(@fred.posts.first).should be_true
1620
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
1621
+ end
1622
+ end
1623
+
1624
+ describe 'and no object is given' do
1625
+ before(:each) do
1626
+ output_buffer.replace ''
1627
+ semantic_form_for(:project, :url => 'http://test.host') do |builder|
1628
+ concat(builder.input(:author_id, :as => :check_boxes, :collection => Author.find(:all)))
1629
+ end
1630
+ end
1631
+
1632
+ it 'should generate a fieldset with legend' do
1633
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
1634
+ end
1635
+
1636
+ it 'shold generate an li tag for each item in the collection' do
1637
+ output_buffer.should have_tag('form li fieldset ol li', :count => Author.find(:all).size)
1638
+ end
1639
+
1640
+ it 'should generate labels for each item' do
1641
+ Author.find(:all).each do |author|
1642
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
1643
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
1644
+ end
1645
+ end
1646
+
1647
+ it 'should generate inputs for each item' do
1648
+ Author.find(:all).each do |author|
1649
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
1650
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
1651
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
1652
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
1653
+ end
1654
+ end
1338
1655
  end
1339
1656
  end
1340
1657
  end
@@ -1347,7 +1664,7 @@ describe 'Formtastic' do
1347
1664
  @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
1348
1665
  end
1349
1666
 
1350
- { :select => :option, :radio => :input }.each do |type, countable|
1667
+ { :select => :option, :radio => :input, :check_boxes => :'input[@type="checkbox"]' }.each do |type, countable|
1351
1668
 
1352
1669
  describe ":as => #{type.inspect}" do
1353
1670
  describe 'when the :collection option is not provided' do
@@ -1402,9 +1719,9 @@ describe 'Formtastic' do
1402
1719
  concat(builder.input(:category_name, :as => type, :collection => @categories))
1403
1720
  end
1404
1721
 
1405
- @categories.each do |item|
1406
- output_buffer.should have_tag("form li.#{type}", /#{item}/)
1407
- output_buffer.should have_tag("form li.#{type} #{countable}[@value=#{item}]")
1722
+ @categories.each do |value|
1723
+ output_buffer.should have_tag("form li.#{type}", /#{value}/)
1724
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
1408
1725
  end
1409
1726
  end
1410
1727
 
@@ -1437,7 +1754,7 @@ describe 'Formtastic' do
1437
1754
 
1438
1755
  @categories.each do |label, value|
1439
1756
  output_buffer.should have_tag("form li.#{type}", /#{label}/)
1440
- output_buffer.should have_tag("form li.#{type} #{countable}[@value=#{value}]")
1757
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value}']")
1441
1758
  end
1442
1759
  end
1443
1760
  end
@@ -1450,12 +1767,13 @@ describe 'Formtastic' do
1450
1767
 
1451
1768
  it "should use the first value as the label text and the last value as the value attribute for #{countable}" do
1452
1769
  semantic_form_for(@new_post) do |builder|
1453
- concat(builder.input(:category_name, :as => :radio, :collection => @categories))
1770
+ concat(builder.input(:category_name, :as => type, :collection => @categories))
1454
1771
  end
1455
1772
 
1456
- @categories.each do |label, value|
1457
- output_buffer.should have_tag('form li fieldset ol li label', /#{label}/i)
1458
- output_buffer.should have_tag('form li fieldset ol li label input[@value='+value+']')
1773
+ @categories.each do |text, value|
1774
+ label = type == :select ? :option : :label
1775
+ output_buffer.should have_tag("form li.#{type} #{label}", /#{text}/i)
1776
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
1459
1777
  end
1460
1778
  end
1461
1779
  end
@@ -1468,12 +1786,13 @@ describe 'Formtastic' do
1468
1786
 
1469
1787
  it "should use the symbol as the label text and value for each #{countable}" do
1470
1788
  semantic_form_for(@new_post) do |builder|
1471
- concat(builder.input(:category_name, :as => :radio, :collection => @categories))
1789
+ concat(builder.input(:category_name, :as => type, :collection => @categories))
1472
1790
  end
1473
1791
 
1474
1792
  @categories.each do |value|
1475
- output_buffer.should have_tag('form li fieldset ol li label', /#{value}/i)
1476
- output_buffer.should have_tag('form li fieldset ol li label input[@value='+value.to_s+']')
1793
+ label = type == :select ? :option : :label
1794
+ output_buffer.should have_tag("form li.#{type} #{label}", /#{value}/i)
1795
+ output_buffer.should have_tag("form li.#{type} #{countable}[@value='#{value.to_s}']")
1477
1796
  end
1478
1797
  end
1479
1798
  end
@@ -1530,8 +1849,15 @@ describe 'Formtastic' do
1530
1849
  end
1531
1850
 
1532
1851
  end
1852
+ end
1853
+ end
1533
1854
 
1534
- describe 'when attribute is a boolean' do
1855
+ describe 'for boolean attributes' do
1856
+
1857
+ { :select => :option, :radio => :input }.each do |type, countable|
1858
+ checked_or_selected = { :select => :selected, :radio => :checked }[type]
1859
+
1860
+ describe ":as => #{type.inspect}" do
1535
1861
 
1536
1862
  before do
1537
1863
  @new_post.stub!(:allow_comments)
@@ -1579,8 +1905,6 @@ describe 'Formtastic' do
1579
1905
  end
1580
1906
  end
1581
1907
 
1582
- checked_or_selected = { :select => :selected, :radio => :checked }[type]
1583
-
1584
1908
  describe 'when the value is nil' do
1585
1909
  before do
1586
1910
  @new_post.stub!(:allow_comments).and_return(nil)
@@ -1647,6 +1971,7 @@ describe 'Formtastic' do
1647
1971
  end
1648
1972
  end
1649
1973
  end
1974
+
1650
1975
  end
1651
1976
  end
1652
1977
  end
@@ -1755,7 +2080,7 @@ describe 'Formtastic' do
1755
2080
  concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
1756
2081
  end
1757
2082
 
1758
- output_buffer.should have_tag("form li fieldset input[@type='hidden'][@value='1']")
2083
+ output_buffer.should have_tag("form li input[@type='hidden'][@value='1']")
1759
2084
  end
1760
2085
 
1761
2086
  it 'should use default attribute value when it is not nil' do
@@ -1764,7 +2089,7 @@ describe 'Formtastic' do
1764
2089
  concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
1765
2090
  end
1766
2091
 
1767
- output_buffer.should have_tag("form li fieldset input[@type='hidden'][@value='27']")
2092
+ output_buffer.should have_tag("form li input[@type='hidden'][@value='27']")
1768
2093
  end
1769
2094
  end
1770
2095
 
@@ -1837,16 +2162,25 @@ describe 'Formtastic' do
1837
2162
  end
1838
2163
  end
1839
2164
 
1840
- it 'should have fieldset, legend, label and selects even if object is not given' do
1841
- output_buffer.replace ''
2165
+ describe 'when no object is given' do
2166
+ before(:each) do
2167
+ output_buffer.replace ''
2168
+ semantic_form_for(:project, :url => 'http://test.host') do |@builder|
2169
+ concat(@builder.input(:publish_at, :as => :datetime))
2170
+ end
2171
+ end
1842
2172
 
1843
- semantic_form_for(:project, :url => 'http://test.host') do |@builder|
1844
- concat(@builder.input(:publish_at, :as => :datetime))
2173
+ it 'should have fieldset with legend' do
2174
+ output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
1845
2175
  end
1846
2176
 
1847
- output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
1848
- output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
1849
- output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
2177
+ it 'should have labels for each input' do
2178
+ output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
2179
+ end
2180
+
2181
+ it 'should have selects for each inputs' do
2182
+ output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
2183
+ end
1850
2184
  end
1851
2185
  end
1852
2186
 
@@ -1883,8 +2217,9 @@ describe 'Formtastic' do
1883
2217
  output_buffer.should have_tag('form li.time fieldset li label', /minute/i)
1884
2218
  end
1885
2219
 
1886
- it 'should have five selects for hour and minute' do
1887
- output_buffer.should have_tag('form li.time fieldset li select', :count => 2)
2220
+ it 'should have two selects for hour and minute' do
2221
+ #output_buffer.should have_tag('form li.time fieldset ol li select', :count => 2)
2222
+ output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
1888
2223
  end
1889
2224
  end
1890
2225
 
@@ -1963,7 +2298,6 @@ describe 'Formtastic' do
1963
2298
  end
1964
2299
  end
1965
2300
 
1966
-
1967
2301
  describe '#inputs' do
1968
2302
 
1969
2303
  describe 'with a block' do
@@ -2519,9 +2853,9 @@ describe 'Formtastic' do
2519
2853
 
2520
2854
  it "should have a add method" do
2521
2855
  @new_post.stub!(:authors).and_return(mock("Authors", :build => mock('Author')))
2856
+ should_receive(:render).with(hash_including(:partial => "mock")).and_return('"attributes___idx___test__idxx__"')
2522
2857
 
2523
2858
  semantic_form_for(@new_post) do |builder|
2524
- builder.should_receive(:render).with(hash_including(:partial => "mock")).and_return('"attributes___idx___test__idxx__"')
2525
2859
  builder.inputs :name => "Contacts", :id => "contacts" do
2526
2860
  concat(builder.add_associated_link(:name, :authors))
2527
2861
  end
@@ -2531,29 +2865,35 @@ describe 'Formtastic' do
2531
2865
  output_buffer.should match(/\\&quot;attributes___idx___test__idxx__\\&quot;&quot;.replace/)
2532
2866
  end
2533
2867
 
2534
- it "should have a remove method" do
2535
- semantic_form_for(@new_post) do |builder|
2536
- builder.semantic_fields_for(:links) do |link_builder|
2537
- concat(link_builder.remove_link("Remove"))
2538
- end
2539
- end
2540
2868
 
2541
- output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><input id=\"post_links__delete\" name=\"post[links][_delete]\" type=\"hidden\" /><a href=\"#\" onclick=\"$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;\">Remove</a></form>")
2542
- end
2543
2869
 
2544
2870
  it "should have a show method" do
2545
2871
  @new_post.stub!(:authors).and_return([mock("Author")])
2872
+ should_receive(:render).with(hash_including(:partial => "mock")).and_return("fields")
2546
2873
 
2547
2874
  semantic_form_for(@new_post) do |builder|
2548
- builder.should_receive(:render).with(hash_including(:partial => "mock")).and_return("fields")
2549
2875
  builder.inputs :name => "Contacts" do
2550
2876
  concat(builder.render_associated_form @new_post.authors)
2551
2877
  end
2552
2878
  end
2553
2879
 
2880
+ # output_buffer.shou
2554
2881
  output_buffer.should eql("<form action=\"/posts\" class=\"formtastic post\" id=\"new_post\" method=\"post\"><fieldset class=\"inputs\"><legend><span>Contacts</span></legend><ol>fields</ol></fieldset></form>")
2555
2882
  end
2556
2883
 
2884
+
2885
+ it "should have a remove method" do
2886
+ semantic_form_for(@new_post) do |builder|
2887
+ builder.semantic_fields_for(:links) do |link_builder|
2888
+ concat(link_builder.remove_link("Remove"))
2889
+ end
2890
+ end
2891
+
2892
+ output_buffer.should have_tag("form input[@type=hidden]")
2893
+ output_buffer.should have_tag("form a[@href=#]")
2894
+ # output_buffer.should match(/$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;)
2895
+ # output_buffer.should eql("<<input id=\"post_links__delete\" name=\"post[links][_delete]\" type=\"hidden\" /><a href=\"#\" onclick=\"$(this).parents('.nil_class').hide(); $(this).prev(':input').val('1');; return false;\">Remove</a></form>")
2896
+ end
2557
2897
  end
2558
2898
 
2559
2899
  end