nofxx-formtastic 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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