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.
- data/README.textile +51 -30
- data/generators/formtastic_stylesheets/templates/formtastic.css +51 -23
- data/lib/formtastic.rb +216 -72
- data/spec/formtastic_spec.rb +486 -146
- metadata +3 -3
data/spec/formtastic_spec.rb
CHANGED
@@ -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
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
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
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
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
|
-
|
993
|
-
|
994
|
-
|
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
|
-
|
998
|
-
|
999
|
-
|
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
|
-
|
1002
|
-
output_buffer.should have_tag(
|
1003
|
-
output_buffer.should have_tag(
|
1004
|
-
output_buffer.should have_tag(
|
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
|
-
|
1054
|
-
|
1055
|
-
|
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
|
-
|
1059
|
-
|
1060
|
-
|
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
|
-
|
1063
|
-
|
1064
|
-
|
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
|
-
|
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
|
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 "
|
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
|
-
|
1146
|
-
|
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
|
-
|
1149
|
-
|
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
|
-
|
1153
|
-
|
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
|
-
|
1156
|
-
|
1157
|
-
|
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
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
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
|
-
|
1326
|
-
|
1327
|
-
|
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
|
-
|
1331
|
-
|
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
|
-
|
1334
|
-
|
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
|
-
|
1337
|
-
|
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 |
|
1406
|
-
output_buffer.should have_tag("form li.#{type}", /#{
|
1407
|
-
output_buffer.should have_tag("form li.#{type} #{countable}[@value
|
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
|
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 =>
|
1770
|
+
concat(builder.input(:category_name, :as => type, :collection => @categories))
|
1454
1771
|
end
|
1455
1772
|
|
1456
|
-
@categories.each do |
|
1457
|
-
|
1458
|
-
output_buffer.should have_tag(
|
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 =>
|
1789
|
+
concat(builder.input(:category_name, :as => type, :collection => @categories))
|
1472
1790
|
end
|
1473
1791
|
|
1474
1792
|
@categories.each do |value|
|
1475
|
-
|
1476
|
-
output_buffer.should have_tag(
|
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
|
-
|
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
|
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
|
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
|
-
|
1841
|
-
|
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
|
-
|
1844
|
-
|
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
|
-
|
1848
|
-
|
1849
|
-
|
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
|
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(/\\"attributes___idx___test__idxx__\\"".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
|