formnestic 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/.document +5 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +5 -0
  4. data/.watchr +31 -0
  5. data/Gemfile +27 -0
  6. data/Gemfile.lock +133 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.markdown +126 -0
  9. data/Rakefile +44 -0
  10. data/VERSION +1 -0
  11. data/app/assets/.DS_Store +0 -0
  12. data/app/assets/javascripts/formnestic/formnestic.js +139 -0
  13. data/app/assets/stylesheets/formnestic/entypo.css.scss +327 -0
  14. data/app/assets/stylesheets/formnestic/entypo.eot +0 -0
  15. data/app/assets/stylesheets/formnestic/entypo.svg +296 -0
  16. data/app/assets/stylesheets/formnestic/entypo.ttf +0 -0
  17. data/app/assets/stylesheets/formnestic/entypo.woff +0 -0
  18. data/app/assets/stylesheets/formnestic/formnestic.css.scss +167 -0
  19. data/config/locales/formnestic.en.yml +8 -0
  20. data/formnestic.gemspec +112 -0
  21. data/lib/formnestic/form_builder/base_builder.rb +55 -0
  22. data/lib/formnestic/form_builder/list_form_builder.rb +30 -0
  23. data/lib/formnestic/form_builder/table_form_builder.rb +94 -0
  24. data/lib/formnestic/form_builder.rb +13 -0
  25. data/lib/formnestic/helpers/inputs_helper.rb +82 -0
  26. data/lib/formnestic/helpers.rb +9 -0
  27. data/lib/formnestic/inputs/base/labelling.rb +15 -0
  28. data/lib/formnestic/inputs/base/wrapping.rb +52 -0
  29. data/lib/formnestic/inputs/base.rb +12 -0
  30. data/lib/formnestic/inputs.rb +7 -0
  31. data/lib/formnestic.rb +72 -0
  32. data/lib/generators/formnestic/install_generator.rb +36 -0
  33. data/log/development.log +0 -0
  34. data/rwatchr +1 -0
  35. data/screenshots/list_form.png +0 -0
  36. data/screenshots/table_form.png +0 -0
  37. data/spec/helpers/nested_model_helper_spec.rb +277 -0
  38. data/spec/helpers/nested_model_list_helper_spec.rb +51 -0
  39. data/spec/inputs/boolean_input_spec.rb +223 -0
  40. data/spec/spec_helper.rb +553 -0
  41. data/spec/support/custom_macros.rb +528 -0
  42. data/spec/support/deferred_garbage_collection.rb +21 -0
  43. data/spec/support/deprecation.rb +6 -0
  44. data/spec/support/test_environment.rb +31 -0
  45. metadata +271 -0
data/lib/formnestic.rb ADDED
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+ require 'formtastic/engine' if defined?(::Rails)
3
+ require 'formtastic/helpers'
4
+ require 'formtastic'
5
+ module Formnestic
6
+ extend ActiveSupport::Autoload
7
+ autoload :Helpers, File.join(File.dirname(__FILE__), 'formnestic', 'helpers')
8
+ autoload :FormBuilder, File.join(File.dirname(__FILE__), 'formnestic', 'form_builder')
9
+ autoload :Inputs, File.join(File.dirname(__FILE__), 'formnestic', 'inputs')
10
+
11
+ include Formnestic::Helpers
12
+ include Formnestic::Inputs::Base
13
+
14
+ Formtastic::FormBuilder.send(:alias_method, :formtastic_semantic_fields_for, :semantic_fields_for)
15
+ Formtastic::FormBuilder.send(:include, Formnestic::FormBuilder)
16
+ Formtastic::Inputs::Base.send(:alias_method, :formtastic_input_wrapping, :input_wrapping)
17
+ Formtastic::Inputs::Base.send(:include, Formnestic::Inputs::Base::Wrapping)
18
+
19
+ Formtastic::Inputs::Base.send(:alias_method, :formtastic_render_label?, :render_label?)
20
+ Formtastic::Inputs::Base.send(:include, Formnestic::Inputs::Base::Labelling)
21
+
22
+ Formtastic::Inputs::BooleanInput.send(:alias_method, :formtastic_label_text_with_embedded_checkbox, :label_text_with_embedded_checkbox)
23
+
24
+ [
25
+ 'Formtastic::Inputs::DateSelectInput',
26
+ 'Formtastic::Inputs::DatetimeSelectInput',
27
+ 'Formtastic::Inputs::TimeSelectInput'
28
+ ].each do |date_related_subclass_str|
29
+ if defined?(date_related_subclass_str)
30
+ date_related_subclass = date_related_subclass_str.constantize
31
+ date_related_subclass.send(:alias_method, :formtastic_fragment_label_html, :fragment_label_html)
32
+ date_related_subclass.class_eval do
33
+ def fragment_label_html(fragment)
34
+ if self.builder.options[:display_type] == "table"
35
+ "".html_safe
36
+ else
37
+ formtastic_fragment_label_html(fragment)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ Formtastic::Inputs::BooleanInput.class_eval do
45
+ def label_text_with_embedded_checkbox
46
+ if self.builder.options[:display_type] == 'table'
47
+ check_box_html
48
+ else
49
+ formtastic_label_text_with_embedded_checkbox
50
+ end
51
+ end
52
+ end
53
+
54
+ Formtastic::FormBuilder.class_eval do
55
+ def semantic_fields_for(record_or_name_or_array, *args, &block)
56
+ options = args.dup.extract_options!
57
+ if options[:display_type] == 'table'
58
+ formnestic_table_semantic_fields_for(record_or_name_or_array, *args, &block)
59
+ elsif options[:row_removable].present? or options[:row_addable].present?
60
+ formnestic_list_semantic_fields_for(record_or_name_or_array, *args, &block)
61
+ else
62
+ formtastic_semantic_fields_for(record_or_name_or_array, *args, &block)
63
+ end
64
+ end
65
+ end
66
+
67
+ if defined?(::Rails)
68
+ class Engine < Rails::Engine
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,36 @@
1
+ require 'rails/generators'
2
+
3
+ module Formnestic
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+ source_root File.expand_path("../../../../", __FILE__)
8
+
9
+ def copy_javascript
10
+ directory "app/assets/javascripts/formnestic", 'app/assets/javascripts/formnestic'
11
+ end
12
+
13
+ def copy_css
14
+ directory "app/assets/stylesheets/formnestic", 'app/assets/stylesheets/formnestic'
15
+ end
16
+
17
+ def inject_javascript
18
+ append_to_file 'app/assets/javascripts/application.js' do
19
+ out = "\n"
20
+ out << "//= require formnestic/formnestic"
21
+ end
22
+ end
23
+
24
+ def inject_css
25
+ append_to_file 'app/assets/stylesheets/application.css' do
26
+ out = "\n"
27
+ out << "/* *= require formnestic/formnestic */"
28
+ end
29
+ end
30
+
31
+ def copy_locales
32
+ copy_file "config/locales/formnestic.en.yml", "config/locales/formnestic.en.yml"
33
+ end
34
+ end
35
+ end
36
+ end
File without changes
data/rwatchr ADDED
@@ -0,0 +1 @@
1
+ bundle exec watchr .watchr
Binary file
Binary file
@@ -0,0 +1,277 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'Formnestic Table Form' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ describe 'table formnestic with row_removable=true and row_addable=true' do
9
+ before do
10
+ @output_buffer = ''
11
+ mock_everything
12
+
13
+ concat(semantic_form_for(@alan) do |builder|
14
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true) do |post_builder|
15
+ concat(post_builder.inputs do
16
+ concat(post_builder.input :title)
17
+ concat(post_builder.input :body)
18
+ concat(post_builder.input :post_date, as: :date_select)
19
+ end)
20
+ end)
21
+ end)
22
+ end
23
+
24
+ it 'yields a table with class table-inputs' do
25
+ output_buffer.should have_tag('form table.formnestic-table-inputs', :count => 1)
26
+ end
27
+
28
+ it 'yields 2 table rows with class formnestic-tr-fieldset inside table.formnestic-table-inputs' do
29
+ output_buffer.should have_tag('form table.formnestic-table-inputs tr.formnestic-tr-fieldset', :count => 2)
30
+ end
31
+
32
+ it 'yields 7 table cells inside table.table-inputs' do
33
+ output_buffer.should have_tag('form table.formnestic-table-inputs tr td', :count => 9)
34
+ end
35
+
36
+ it 'yields 1 table cell containing a.formnestic-add-row-field-link' do
37
+ output_buffer.should have_tag('form table.formnestic-table-inputs tr td a.formnestic-add-row-field-link', :count => 1)
38
+ end
39
+
40
+ it 'must not yield any labels tag inside the table td' do
41
+ output_buffer.should have_tag('form table.formnestic-table-inputs tr td label', :count => 0)
42
+ end
43
+
44
+ it 'must have a table thead tag with 2 cells' do
45
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th.formnestic-minus-thead', count: 1)
46
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', :count => 4)
47
+ end
48
+
49
+ it 'must have a table thead tag with 2 cells' do
50
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th.formnestic-minus-thead', count: 1)
51
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', :count => 4)
52
+ end
53
+
54
+ it 'must have 2 div.formnestic-table-minus-button' do
55
+ output_buffer.should have_tag('form table.formnestic-table-inputs tbody div.formnestic-table-minus-button', count: 2)
56
+ end
57
+
58
+ it 'must not have label tag inside a date cell' do
59
+ output_buffer.should_not have_tag('form table.formnestic-table-inputs tbody td.date label')
60
+ end
61
+
62
+ it 'must have a tag with onclick is addNewTableEntry javascript call' do
63
+ output_buffer.should have_tag("form table.formnestic-table-inputs tr.formnestic-table-no-border a[@onclick*='Formnestic.addNewTableEntry']")
64
+ end
65
+
66
+ it 'should have a th tags according to the fields specified in semantic_fields_for body' do
67
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Title/)
68
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Body/)
69
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Post date/)
70
+ end
71
+
72
+ end
73
+
74
+ describe 'table formnestic with row_removable=false and row_addable=true' do
75
+ before do
76
+ @output_buffer = ''
77
+ mock_everything
78
+
79
+ concat(semantic_form_for(@alan) do |builder|
80
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: false, row_addable: true) do |post_builder|
81
+ concat(post_builder.inputs do
82
+ concat(post_builder.input :title)
83
+ concat(post_builder.input :body)
84
+ concat(post_builder.input :post_date, as: :date_select)
85
+ end)
86
+ end)
87
+ end)
88
+ end
89
+
90
+ it 'must not have any div.formnestic-table-minus-button' do
91
+ output_buffer.should have_tag('form table.formnestic-table-inputs tbody div.formnestic-table-minus-button', count: 0)
92
+ end
93
+ end
94
+
95
+ describe 'table formnestic with row_removable=true and row_addable=false' do
96
+ before do
97
+ @output_buffer = ''
98
+ mock_everything
99
+
100
+ concat(semantic_form_for(@alan) do |builder|
101
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: false) do |post_builder|
102
+ concat(post_builder.inputs do
103
+ concat(post_builder.input :title)
104
+ concat(post_builder.input :body)
105
+ concat(post_builder.input :post_date, as: :date_select)
106
+ end)
107
+ end)
108
+ end)
109
+ end
110
+
111
+ it 'must not have an a tag with onclick is addNewTableEntry javascript call' do
112
+ output_buffer.should have_tag("form table.formnestic-table-inputs tr.formnestic-table-no-border a[@onclick*='Formnestic.addNewTableEntry']", count: 0)
113
+ end
114
+ end
115
+
116
+ describe 'table formnestic with custom new record link label' do
117
+ before do
118
+ @output_buffer = ''
119
+ mock_everything
120
+
121
+ concat(semantic_form_for(@alan) do |builder|
122
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option") do |post_builder|
123
+ concat(post_builder.inputs do
124
+ concat(post_builder.input :title)
125
+ concat(post_builder.input :body)
126
+ concat(post_builder.input :post_date, as: :date_select)
127
+ end)
128
+ end)
129
+ end)
130
+ end
131
+
132
+ it "must have a tag with onclick is addNewTableEntry javascript call and text is Add new option" do
133
+ output_buffer.should have_tag("form table.formnestic-table-inputs tr.formnestic-table-no-border a[@onclick*='Formnestic.addNewTableEntry']", "Add new option", count: 1)
134
+ end
135
+ end
136
+
137
+ describe 'table formnestic with boolean field' do
138
+ before do
139
+ @output_buffer = ''
140
+ mock_everything
141
+
142
+ concat(semantic_form_for(@alan) do |builder|
143
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option") do |post_builder|
144
+ concat(post_builder.inputs do
145
+ concat(post_builder.input :recent, as: :boolean)
146
+ end)
147
+ end)
148
+ end)
149
+ end
150
+
151
+ it "must not have is new text in boolean input" do
152
+ output_buffer.should_not have_tag("form table.formnestic-table-inputs tbody label", "Recent")
153
+ end
154
+ end
155
+
156
+ describe 'table formnestic with time field' do
157
+ before do
158
+ @output_buffer = ''
159
+ mock_everything
160
+
161
+ concat(semantic_form_for(@alan) do |builder|
162
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option") do |post_builder|
163
+ concat(post_builder.inputs do
164
+ concat(post_builder.input :post_date, as: :time_select)
165
+ end)
166
+ end)
167
+ end)
168
+ end
169
+
170
+ it 'must not have label tag inside a time cell' do
171
+ output_buffer.should_not have_tag('form table.formnestic-table-inputs tbody td.time_select label')
172
+ end
173
+ end
174
+
175
+ describe 'table formnestic with simple headers' do
176
+ before do
177
+ @output_buffer = ''
178
+ mock_everything
179
+
180
+ concat(semantic_form_for(@alan) do |builder|
181
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option", table_headers: [[{attr: :title}, {attr: :body, wrapper_html: {class: "body-th"}}, {attr: :post_date}]]) do |post_builder|
182
+ concat(post_builder.inputs do
183
+ concat(post_builder.input :title)
184
+ concat(post_builder.input :body)
185
+ concat(post_builder.input :post_date, as: :date_select)
186
+ end)
187
+ end)
188
+ end)
189
+ end
190
+
191
+ it 'should have a th tags according to specified in table headers' do
192
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Title/)
193
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Body/)
194
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Post date/)
195
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th.body-th', count: 1)
196
+ end
197
+ end
198
+
199
+ describe 'table formnestic with headers but specified with label' do
200
+ before do
201
+ @output_buffer = ''
202
+ mock_everything
203
+
204
+ concat(semantic_form_for(@alan) do |builder|
205
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option", table_headers: [[{label: "My Title"}, {label: "My Body"}, {label: "Post Date"}]]) do |post_builder|
206
+ concat(post_builder.inputs do
207
+ concat(post_builder.input :title)
208
+ concat(post_builder.input :body)
209
+ concat(post_builder.input :post_date, as: :date_select)
210
+ end)
211
+ end)
212
+ end)
213
+ end
214
+
215
+ it 'should have a th tags according to specified in table headers' do
216
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^My Title/)
217
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^My Body/)
218
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Post Date/)
219
+ end
220
+ end
221
+
222
+ describe 'table formnestic 2 rows header' do
223
+ before do
224
+ @output_buffer = ''
225
+ mock_everything
226
+
227
+ concat(semantic_form_for(@alan) do |builder|
228
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option", table_headers: [
229
+ [{attr: :title}, {attr: :body}, {attr: :post_date}],
230
+ [{label: "My Title"}, {label: "My Body"}, {label: "Post Date"}]
231
+ ]) do |post_builder|
232
+ concat(post_builder.inputs do
233
+ concat(post_builder.input :title)
234
+ concat(post_builder.input :body)
235
+ concat(post_builder.input :post_date, as: :date_select)
236
+ end)
237
+ end)
238
+ end)
239
+ end
240
+
241
+ it 'should have a th tags according to specified in table headers' do
242
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Title/)
243
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Body/)
244
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Post date/)
245
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^My Title/)
246
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^My Body/)
247
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Post Date/)
248
+ end
249
+ end
250
+
251
+ describe 'table formnestic with table header with colspan specified' do
252
+ before do
253
+ @output_buffer = ''
254
+ mock_everything
255
+
256
+ concat(semantic_form_for(@alan) do |builder|
257
+ concat(builder.semantic_fields_for(:posts, :display_type => "table", row_removable: true, row_addable: true, new_record_link_label: "Add new option", table_headers: [
258
+ [{label: "All my columns", :wrapper_html => {colspan: 3}}],
259
+ [{attr: :title}, {attr: :body}, {attr: :post_date}]
260
+ ]) do |post_builder|
261
+ concat(post_builder.inputs do
262
+ concat(post_builder.input :title)
263
+ concat(post_builder.input :body)
264
+ concat(post_builder.input :post_date, as: :date_select)
265
+ end)
266
+ end)
267
+ end)
268
+ end
269
+
270
+ it 'should have a th tags according to specified in table headers' do
271
+ output_buffer.should have_tag("form table.formnestic-table-inputs thead tr th[colspan='3']", /All my columns/)
272
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Title/)
273
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Body/)
274
+ output_buffer.should have_tag('form table.formnestic-table-inputs thead tr th', /^Post date/)
275
+ end
276
+ end
277
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'Formnestic List Form' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ describe 'table formnestic with row_removable=true and row_addable=true' do
9
+ before do
10
+ @output_buffer = ''
11
+ mock_everything
12
+
13
+ concat(semantic_form_for(@alan) do |builder|
14
+ concat(builder.semantic_fields_for(:posts, row_removable: true, row_addable: true) do |post_builder|
15
+ concat(post_builder.inputs do
16
+ concat(post_builder.input :title)
17
+ concat(post_builder.input :body)
18
+ end)
19
+ end)
20
+ end)
21
+ end
22
+ it 'must not yields any table with class table-inputs' do
23
+ output_buffer.should_not have_tag('form table.formnestic-table-inputs')
24
+ end
25
+
26
+ it 'must have an a tag with onclick is addNewListingEntry javascript call' do
27
+ output_buffer.should have_tag("form a[@onclick*='Formnestic.addNewListEntry']")
28
+ end
29
+
30
+ it 'must have a div tag with class formnestic-list-new-entry-link-container' do
31
+ output_buffer.should have_tag("form div.formnestic-list-new-entry-link-container")
32
+ end
33
+
34
+ it 'should have 2 div tag with class formnestic-li-fieldset' do
35
+ output_buffer.should have_tag("form fieldset.formnestic-li-fieldset", count: 2)
36
+ end
37
+
38
+ it 'should have 2 span tag with class formnestic-li-fieldset-for' do
39
+ output_buffer.should have_tag("form span.formnestic-li-fieldset-for", count: 2)
40
+ end
41
+
42
+ it 'should have 2 span tag with class formnestic-li-fieldset-for' do
43
+ output_buffer.should have_tag("form span.formnestic-li-fieldset-for-order", count: 2)
44
+ end
45
+
46
+ it 'should have 2 div tag with class formnestic-table-minus-button' do
47
+ output_buffer.should have_tag("form div.formnestic-list-item-minus-button", count: 2)
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,223 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'boolean input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ concat(semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:allow_comments, :as => :boolean))
14
+ end)
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class("boolean")
18
+ it_should_have_input_wrapper_with_class(:input)
19
+ it_should_have_input_wrapper_with_id("post_allow_comments_input")
20
+ it_should_apply_error_logic_for_input_type(:boolean)
21
+
22
+ it 'should generate a label containing the input' do
23
+ output_buffer.should_not have_tag('label.label')
24
+ output_buffer.should have_tag('form li label', :count => 1)
25
+ output_buffer.should have_tag('form li label[@for="post_allow_comments"]')
26
+ output_buffer.should have_tag('form li label', /Allow comments/)
27
+ output_buffer.should have_tag('form li label input[@type="checkbox"]', :count => 1)
28
+ output_buffer.should have_tag('form li input[@type="hidden"]', :count => 1)
29
+ output_buffer.should_not have_tag('form li label input[@type="hidden"]', :count => 1) # invalid HTML5
30
+ end
31
+
32
+ it 'should not add a "name" attribute to the label' do
33
+ output_buffer.should_not have_tag('form li label[@name]')
34
+ end
35
+
36
+ it 'should generate a checkbox input' do
37
+ output_buffer.should have_tag('form li label input')
38
+ output_buffer.should have_tag('form li label input#post_allow_comments')
39
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
40
+ output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
41
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"]')
42
+ end
43
+
44
+ it 'should generate a checked input if object.method returns true' do
45
+ output_buffer.should have_tag('form li label input[@checked="checked"]')
46
+ output_buffer.should have_tag('form li input[@name="post[allow_comments]"]', :count => 2)
47
+ output_buffer.should have_tag('form li input#post_allow_comments', :count => 1)
48
+ end
49
+
50
+ it 'should generate a checked input if :input_html is passed :checked => checked' do
51
+ concat(semantic_form_for(@new_post) do |builder|
52
+ concat(builder.input(:answer_comments, :as => :boolean, :input_html => {:checked => 'checked'}))
53
+ end)
54
+ output_buffer.should have_tag('form li label input[@checked="checked"]')
55
+ end
56
+
57
+ it 'should name the hidden input with the :name html_option' do
58
+ concat(semantic_form_for(@new_post) do |builder|
59
+ concat(builder.input(:answer_comments, :as => :boolean, :input_html => { :name => "foo" }))
60
+ end)
61
+
62
+ output_buffer.should have_tag('form li input[@type="checkbox"][@name="foo"]', :count => 1)
63
+ output_buffer.should have_tag('form li input[@type="hidden"][@name="foo"]', :count => 1)
64
+ end
65
+
66
+ it 'should name the hidden input with the :name html_option' do
67
+ concat(semantic_form_for(@new_post) do |builder|
68
+ concat(builder.input(:answer_comments, :as => :boolean, :input_html => { :name => "foo" }))
69
+ end)
70
+
71
+ output_buffer.should have_tag('form li input[@type="checkbox"][@name="foo"]', :count => 1)
72
+ output_buffer.should have_tag('form li input[@type="hidden"][@name="foo"]', :count => 1)
73
+ end
74
+
75
+ it "should generate a disabled input and hidden input if :input_html is passed :disabled => 'disabled' " do
76
+ concat(semantic_form_for(@new_post) do |builder|
77
+ concat(builder.input(:allow_comments, :as => :boolean, :input_html => {:disabled => 'disabled'}))
78
+ end)
79
+ output_buffer.should have_tag('form li label input[@disabled="disabled"]', :count => 1)
80
+ output_buffer.should have_tag('form li input[@type="hidden"][@disabled="disabled"]', :count => 1)
81
+ end
82
+
83
+ it 'should generate an input[id] with matching label[for] when id passed in :input_html' do
84
+ concat(semantic_form_for(@new_post) do |builder|
85
+ concat(builder.input(:allow_comments, :as => :boolean, :input_html => {:id => 'custom_id'}))
86
+ end)
87
+ output_buffer.should have_tag('form li label input[@id="custom_id"]')
88
+ output_buffer.should have_tag('form li label[@for="custom_id"]')
89
+ end
90
+
91
+ it 'should allow checked and unchecked values to be sent' do
92
+ concat(semantic_form_for(@new_post) do |builder|
93
+ concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'checked', :unchecked_value => 'unchecked'))
94
+ end)
95
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="checked"]:not([@unchecked_value][@checked_value])')
96
+ output_buffer.should have_tag('form li input[@type="hidden"][@value="unchecked"]')
97
+ output_buffer.should_not have_tag('form li label input[@type="hidden"]') # invalid HTML5
98
+ end
99
+
100
+ it 'should generate a checked input if object.method returns checked value' do
101
+ @new_post.stub!(:allow_comments).and_return('yes')
102
+
103
+ concat(semantic_form_for(@new_post) do |builder|
104
+ concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'yes', :unchecked_value => 'no'))
105
+ end)
106
+
107
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="yes"][@checked="checked"]')
108
+ end
109
+
110
+ it 'should not generate a checked input if object.method returns unchecked value' do
111
+ @new_post.stub!(:allow_comments).and_return('no')
112
+
113
+ concat(semantic_form_for(@new_post) do |builder|
114
+ concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'yes', :unchecked_value => 'no'))
115
+ end)
116
+
117
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="yes"]:not([@checked])')
118
+ end
119
+
120
+ it 'should generate a checked input if object.method returns checked value' do
121
+ @new_post.stub!(:allow_comments).and_return('yes')
122
+
123
+ concat(semantic_form_for(@new_post) do |builder|
124
+ concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'yes', :unchecked_value => 'no'))
125
+ end)
126
+
127
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="yes"][@checked="checked"]')
128
+ end
129
+
130
+ it 'should not generate a checked input if object.method returns unchecked value' do
131
+ @new_post.stub!(:allow_comments).and_return('no')
132
+
133
+ concat(semantic_form_for(@new_post) do |builder|
134
+ concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'yes', :unchecked_value => 'no'))
135
+ end)
136
+
137
+ output_buffer.should have_tag('form li label input[@type="checkbox"][@value="yes"]:not([@checked])')
138
+ end
139
+
140
+ it 'should generate a label and a checkbox even if no object is given' do
141
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
142
+ concat(builder.input(:allow_comments, :as => :boolean))
143
+ end)
144
+
145
+ output_buffer.should have_tag('form li label[@for="project_allow_comments"]')
146
+ output_buffer.should have_tag('form li label', /Allow comments/)
147
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
148
+
149
+ output_buffer.should have_tag('form li label input#project_allow_comments')
150
+ output_buffer.should have_tag('form li label input[@type="checkbox"]')
151
+ output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
152
+ end
153
+
154
+ context "when required" do
155
+
156
+ it "should add the required attribute to the input's html options" do
157
+ with_config :use_required_attribute, true do
158
+ concat(semantic_form_for(@new_post) do |builder|
159
+ concat(builder.input(:title, :as => :boolean, :required => true))
160
+ end)
161
+ output_buffer.should have_tag("input[@required]")
162
+ end
163
+ end
164
+
165
+ it "should not add the required attribute to the boolean fields input's html options" do
166
+ with_config :use_required_attribute, true do
167
+ concat(semantic_form_for(@new_post) do |builder|
168
+ concat(builder.input(:title, :as => :boolean))
169
+ end)
170
+ output_buffer.should_not have_tag("input[@required]")
171
+ end
172
+ end
173
+
174
+ end
175
+
176
+ describe "when namespace is provided" do
177
+
178
+ before do
179
+ @output_buffer = ''
180
+ mock_everything
181
+
182
+ concat(semantic_form_for(@new_post, :namespace => "context2") do |builder|
183
+ concat(builder.input(:allow_comments, :as => :boolean))
184
+ end)
185
+ end
186
+
187
+ it_should_have_input_wrapper_with_id("context2_post_allow_comments_input")
188
+ it_should_have_an_inline_label_for("context2_post_allow_comments")
189
+
190
+ end
191
+
192
+ describe "when index is provided" do
193
+
194
+ before do
195
+ @output_buffer = ''
196
+ mock_everything
197
+
198
+ concat(semantic_form_for(@new_post) do |builder|
199
+ concat(builder.fields_for(:author, :index => 3) do |author|
200
+ concat(author.input(:name, :as => :boolean))
201
+ end)
202
+ end)
203
+ end
204
+
205
+ it 'should index the id of the wrapper' do
206
+ output_buffer.should have_tag("li#post_author_attributes_3_name_input")
207
+ end
208
+
209
+ it 'should index the id of the input tag' do
210
+ output_buffer.should have_tag("input#post_author_attributes_3_name")
211
+ end
212
+
213
+ it 'should index the name of the hidden input' do
214
+ output_buffer.should have_tag("input[@type='hidden'][@name='post[author_attributes][3][name]']")
215
+ end
216
+
217
+ it 'should index the name of the checkbox input' do
218
+ output_buffer.should have_tag("input[@type='checkbox'][@name='post[author_attributes][3][name]']")
219
+ end
220
+
221
+ end
222
+
223
+ end