foundation_rails_helper 0.4 → 0.5.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b91634e14b82386a58ec5123c79bbf9a7cc00e2c
4
+ data.tar.gz: f668d1586441afb62f4308352eeb81cc8e1a1526
5
+ SHA512:
6
+ metadata.gz: d2d484df58203229b48594064fdf2ca2977924620e4c6c36bc8a9a4fb3b1ec3721a3b295f1599242fd872f94d6712408c130d407a744b6395b371729179bba7b
7
+ data.tar.gz: e50a0e0e2ff994a6d3f11b73af3655c9bc4ae8f85518c9b1d43ddcc92f5d619636215cdc157d46f8256d4333424a83ff84a4f05aef6097249edb7009440d8578
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --backtrace
data/CHANGELOG.md CHANGED
@@ -1,8 +1,23 @@
1
- ## Version 0.1.rc
1
+ ## Version 0.5.0
2
2
 
3
- * initial release candidate (Jan 14th, 2012)
3
+ * Released Oct 10th 2014
4
+ * Bugfixes
5
+
6
+ ## Version 0.4
7
+
8
+ * Not released
9
+ * Compatibility with Rails 4
10
+ * Bugfixes
11
+
12
+ ## Version 0.3
13
+
14
+ * Not released
15
+ * Mostly bugfixes
4
16
 
5
17
  ## Version 0.2.1
6
18
 
7
19
  * First production release (Jan 14th, 2012)
8
20
 
21
+ ## Version 0.1.rc
22
+
23
+ * initial release candidate (Jan 14th, 2012)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # FoundationRailsHelper [![Build Status](https://secure.travis-ci.org/sgruhier/foundation_rails_helper.png)](http://travis-ci.org/sgruhier/foundation_rails_helper)
2
2
 
3
- Gem for Rails 3 applications that use the excellent Zurb Foundation framework.
3
+ Gem for Rails 4.1.x applications that use the excellent Zurb Foundation framework.
4
4
 
5
5
  * [Zurb Foundation](https://github.com/zurb/foundation)
6
6
  * [Zurb Foundation Rails](https://github.com/zurb/foundation-rails)
@@ -11,7 +11,12 @@ So far it includes:
11
11
 
12
12
  * A `display_flash_messages` helper method that uses Zurb Foundation Alerts UI.
13
13
 
14
- This gem has been used with Rails 3.1, 3.2 and ruby 1.9.2, 1.9.3. It should work for Rails 3.0.
14
+ #### Compatibility
15
+
16
+ * Only Rails 4.1 and Foundation 4 and 5 are fully supported
17
+ * Some features may work with Foundation 3 and older, but results may vary, and markup which exists only for those versions will be gradually removed
18
+ * Legacy branches exist for Rails 3 and 4.0 (see the rails3 and rails4.0 branches). These are not actively supported, and fixes are not retroactively applied, but pull requests are welcomed.
19
+
15
20
 
16
21
  ## Screenshots
17
22
 
@@ -58,9 +63,7 @@ And then execute:
58
63
  $ bundle
59
64
  ```
60
65
 
61
- ## Usage
62
-
63
- There is nothing additional to do for form helpers.
66
+ ### Flash Messages
64
67
 
65
68
  To get access to `display_flash_messages` in your views, add
66
69
 
@@ -70,6 +73,119 @@ include FoundationRailsHelper::FlashHelper
70
73
 
71
74
  to `app/helpers/application_helper.rb`
72
75
 
76
+ ## Usage
77
+
78
+ ### form_for
79
+
80
+ Form_for wraps the standard rails form_for helper and adds a 'nice' class by default.
81
+
82
+ ```erb
83
+ <%= form_for @user do |f| %>
84
+ ...
85
+ <% end %>
86
+ ```
87
+
88
+ generates:
89
+
90
+ ```html
91
+ <form accept-charset="UTF-8" action="/users" class="nice" id="new_user" method="post">
92
+ ...
93
+ ```
94
+
95
+ Override the default class like so:
96
+
97
+ ```erb
98
+ <%= form_for(@user, html: {class: 'mean'}) do |f| %>
99
+ ...
100
+ ```
101
+
102
+ ### text_field and Field Helpers
103
+
104
+ Field helpers add a label element and an input of the proper type.
105
+
106
+ ```ruby
107
+ f.text_field :name
108
+ ```
109
+
110
+ generates:
111
+
112
+ ```html
113
+ <label for="user_email">Name</label>
114
+ <input class="medium input-text" id="user_name" name="user[name]" type="text">
115
+ ```
116
+
117
+ The 'input-text' class will always be added to the input element, but the 'medium' class can be replaced.
118
+
119
+ ```ruby
120
+ f.text_field :name, class: 'large'
121
+ ```
122
+
123
+ generates:
124
+
125
+ ```html
126
+ <input class="large input-text" ... >
127
+ ```
128
+
129
+ Prevent the generation of a label:
130
+
131
+ ```ruby
132
+ f.text_field :name, label: false
133
+ ```
134
+
135
+ Change the label text and add a class on the label:
136
+
137
+ ```ruby
138
+ f.text_field :name, label: 'Nombre', label_options: { class: 'large' }
139
+ ```
140
+
141
+ If the hint option is specified
142
+
143
+ ```ruby
144
+ f.text_field :name, hint: "I'm a text field"
145
+ ```
146
+
147
+ an additional span element will be added after the input element:
148
+
149
+ ```html
150
+ <span class="hint">I'm a text field</span>
151
+ ```
152
+
153
+ ### Submit Button
154
+
155
+ The 'submit' helper wraps the rails helper and sets the class attribute to "small radius success button" by default.
156
+
157
+ ```ruby
158
+ f.submit
159
+ ```
160
+
161
+ generates:
162
+
163
+ ```html
164
+ <input class="small radius success button" name="commit" type="submit" value="Create User">
165
+ ```
166
+
167
+ Specify the class option to override the default classes.
168
+
169
+ ### Errors
170
+
171
+ On error,
172
+
173
+ ```ruby
174
+ f.email_field :email
175
+ ```
176
+
177
+ generates:
178
+
179
+ ```html
180
+ <label class=" error" for="user_email">Email</label>
181
+ <input class="medium input-text error" id="user_email" name="user[email]" type="email" value="">
182
+ <small class="error medium input-text error">can't be blank</small>
183
+ ```
184
+
185
+ The class attribute of the 'small' element will mirror the class attribute of the 'input' element.
186
+
187
+ If the `html_safe_errors: true` option is specified on a field, then any HTML you may have embedded in a custom error string will be displayed with the html_safe option.
188
+
73
189
  ## TODO
74
190
 
75
191
  * Handle more UI components
@@ -85,4 +201,7 @@ to `app/helpers/application_helper.rb`
85
201
 
86
202
  ## Copyright
87
203
 
88
- Sébastien Gruhier (http://xilinus.com, http://v2.maptimize.com) - MIT LICENSE - 2012
204
+ Sébastien Gruhier (http://xilinus.com, http://v2.maptimize.com) - MIT LICENSE - 2012
205
+
206
+ [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/sgruhier/foundation_rails_helper/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
207
+
@@ -14,9 +14,14 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "foundation_rails_helper"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = FoundationRailsHelper::VERSION
17
+ gem.license = 'MIT'
17
18
 
18
- gem.add_dependency 'railties', '>= 3.0'
19
- gem.add_dependency "actionpack", '>= 3.0'
20
- gem.add_development_dependency "rspec-rails"
21
- gem.add_development_dependency "capybara"
19
+ gem.add_dependency 'railties', '~> 4.1', '>= 4.1.1'
20
+ gem.add_dependency 'actionpack', '~> 4.1', '>= 4.1.1'
21
+ gem.add_dependency 'activemodel', '~> 4.1', '>= 4.1.1'
22
+ gem.add_dependency 'activesupport', '~> 4.1', '>= 4.1.1'
23
+ gem.add_dependency 'tzinfo', '~> 1.2', '>= 1.2.2'
24
+
25
+ gem.add_development_dependency 'rspec-rails', '~> 2.8', '>= 2.8.1'
26
+ gem.add_development_dependency 'capybara', '~> 2.4', '>= 2.4.3'
22
27
  end
@@ -2,3 +2,6 @@ require "foundation_rails_helper/version"
2
2
  require "foundation_rails_helper/form_builder"
3
3
  require "foundation_rails_helper/flash_helper"
4
4
  require "foundation_rails_helper/action_view_extension"
5
+ ActiveSupport.on_load(:action_view) do
6
+ include FoundationRailsHelper::FlashHelper
7
+ end
@@ -5,16 +5,19 @@ module ActionView
5
5
  options[:builder] ||= FoundationRailsHelper::FormBuilder
6
6
  options[:html] ||= {}
7
7
  options[:html][:class] ||= 'nice'
8
- form_for_without_foundation(record, options, &block)
8
+ options[:auto_labels] = true unless options.has_key? :auto_labels
9
+ form_for_without_foundation(record, options, &block)
9
10
  end
10
-
11
+
11
12
  def fields_for_with_foundation(record_name, record_object = nil, options = {}, &block)
12
13
  options[:builder] ||= FoundationRailsHelper::FormBuilder
13
14
  options[:html] ||= {}
14
15
  options[:html][:class] ||= 'nice'
16
+ options[:html][:attached_labels] = options[:attached_labels]
17
+ options[:auto_labels] = true unless options.has_key? :auto_labels
15
18
  fields_for_without_foundation(record_name, record_object, options, &block)
16
19
  end
17
-
20
+
18
21
  alias_method_chain :form_for, :foundation
19
22
  alias_method_chain :fields_for, :foundation
20
23
  end
@@ -11,12 +11,14 @@ module FoundationRailsHelper
11
11
  :notice => :success,
12
12
  :info => :standard,
13
13
  :secondary => :secondary,
14
+ :success => :success,
15
+ :error => :alert
14
16
  }
15
17
  def display_flash_messages(key_matching = {})
16
18
  key_matching = DEFAULT_KEY_MATCHING.merge(key_matching)
17
19
 
18
20
  flash.inject "" do |message, (key, value)|
19
- message += content_tag :div, :data => { :alert => "" }, :class => "alert-box #{key_matching[key] || :standard}" do
21
+ message += content_tag :div, :data => { :alert => "" }, :class => "alert-box #{key_matching[key.to_sym] || :standard}" do
20
22
  (value + link_to("&times;".html_safe, "#", :class => :close)).html_safe
21
23
  end
22
24
  end.html_safe
@@ -3,7 +3,9 @@ require 'action_view/helpers'
3
3
  module FoundationRailsHelper
4
4
  class FormBuilder < ActionView::Helpers::FormBuilder
5
5
  include ActionView::Helpers::TagHelper
6
- %w(file_field email_field text_field text_area telephone_field phone_field url_field number_field).each do |method_name|
6
+ %w(file_field email_field text_field text_area telephone_field phone_field
7
+ url_field number_field date_field datetime_field datetime_local_field
8
+ month_field week_field time_field range_field search_field color_field ).each do |method_name|
7
9
  define_method(method_name) do |*args|
8
10
  attribute = args[0]
9
11
  options = args[1] || {}
@@ -13,6 +15,13 @@ module FoundationRailsHelper
13
15
  end
14
16
  end
15
17
 
18
+ def label(attribute, text = nil, options = {})
19
+ options[:class] ||= ""
20
+ options[:class] += " error" if has_error?(attribute)
21
+ super(attribute, (text || "").html_safe, options)
22
+ end
23
+
24
+
16
25
  def check_box(attribute, options = {}, checked_value = "1", unchecked_value = "0")
17
26
  custom_label(attribute, options[:label], options[:label_options]) do
18
27
  options.delete(:label)
@@ -22,7 +31,7 @@ module FoundationRailsHelper
22
31
  end
23
32
 
24
33
  def radio_button(attribute, tag_value, options = {})
25
- options[:for] ||= "#{object.class.to_s.downcase}_#{attribute}_#{tag_value}"
34
+ options[:for] ||= "#{@object_name}_#{attribute}_#{tag_value}"
26
35
  c = super(attribute, tag_value, options)
27
36
  l = label(attribute, options.delete(:text), options)
28
37
  l.gsub(/(for=\"\w*\"\>)/, "\\1#{c} ").html_safe
@@ -34,31 +43,45 @@ module FoundationRailsHelper
34
43
  end
35
44
  end
36
45
 
37
- def datetime_select(attribute, options = {})
38
- field attribute, options do |options|
39
- super(attribute, {}, options.merge(:autocomplete => :off))
46
+ def datetime_select(attribute, options = {}, html_options = {})
47
+ field attribute, options, html_options do |html_options|
48
+ super(attribute, options, html_options.merge(:autocomplete => :off))
40
49
  end
41
50
  end
42
51
 
43
52
  def date_select(attribute, options = {}, html_options = {})
44
- field attribute, html_options do |html_options|
53
+ field attribute, options, html_options do |html_options|
45
54
  super(attribute, options, html_options.merge(:autocomplete => :off))
46
55
  end
47
56
  end
48
57
 
49
- def time_zone_select(attribute, options = {})
50
- field attribute, options do |options|
51
- super(attribute, {}, options.merge(:autocomplete => :off))
58
+ def time_zone_select(attribute, priorities = nil, options = {}, html_options = {})
59
+ field attribute, options, html_options do |html_options|
60
+ super(attribute, priorities, options, html_options.merge(:autocomplete => :off))
52
61
  end
53
62
  end
54
63
 
55
64
  def select(attribute, choices, options = {}, html_options = {})
56
- field attribute, options do |options|
65
+ field attribute, options, html_options do |html_options|
57
66
  html_options[:autocomplete] ||= :off
58
67
  super(attribute, choices, options, html_options)
59
68
  end
60
69
  end
61
70
 
71
+ def collection_select(attribute, collection, value_method, text_method, options = {}, html_options = {})
72
+ field attribute, options, html_options do |html_options|
73
+ html_options[:autocomplete] ||= :off
74
+ super(attribute, collection, value_method, text_method, options, html_options)
75
+ end
76
+ end
77
+
78
+ def grouped_collection_select(attribute, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
79
+ field attribute, options, html_options do |html_options|
80
+ html_options[:autocomplete] ||= :off
81
+ super(attribute, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
82
+ end
83
+ end
84
+
62
85
  def autocomplete(attribute, url, options = {})
63
86
  field attribute, options do |options|
64
87
  autocomplete_field(attribute, url, options.merge(:update_elements => options[:update_elements],
@@ -74,22 +97,29 @@ module FoundationRailsHelper
74
97
 
75
98
  private
76
99
  def has_error?(attribute)
77
- !object.errors[attribute].blank?
100
+ object.respond_to?(:errors) && !object.errors[attribute].blank?
78
101
  end
79
102
 
80
103
  def error_for(attribute, options = {})
81
104
  class_name = "error"
82
105
  class_name += " #{options[:class]}" if options[:class]
83
- content_tag(:small, object.errors[attribute].join(', '), :class => class_name) if has_error?(attribute)
106
+ if has_error?(attribute)
107
+ error_messages = object.errors[attribute].join(', ')
108
+ error_messages = error_messages.html_safe if options[:html_safe_errors]
109
+ content_tag(:small, error_messages, :class => class_name)
110
+ end
84
111
  end
85
112
 
86
113
  def custom_label(attribute, text, options, &block)
87
- if text == false
88
- text = ""
89
- elsif text.nil?
90
- text = object.class.human_attribute_name(attribute)
114
+ return block_given? ? block.call.html_safe : "".html_safe if text == false
115
+ if text.nil? || text == true
116
+ text = if object.class.respond_to?(:human_attribute_name)
117
+ object.class.human_attribute_name(attribute)
118
+ else
119
+ attribute.to_s.humanize
120
+ end
91
121
  end
92
- text = block.call.html_safe + text if block_given?
122
+ text = block.call.html_safe + " #{text}" if block_given?
93
123
  options ||= {}
94
124
  options[:class] ||= ""
95
125
  options[:class] += " error" if has_error?(attribute)
@@ -103,15 +133,16 @@ module FoundationRailsHelper
103
133
  html.html_safe
104
134
  end
105
135
 
106
- def field(attribute, options, &block)
136
+ def field(attribute, options, html_options=nil, &block)
107
137
  html = ''.html_safe
108
- html = custom_label(attribute, options[:label], options[:label_options]) if false != options[:label]
109
- options[:class] ||= "medium"
110
- options[:class] = "#{options[:class]} input-text"
111
- options[:class] += " error" if has_error?(attribute)
138
+ html = custom_label(attribute, options[:label], options[:label_options]) if @options[:auto_labels] || options[:label]
139
+ class_options = html_options || options
140
+ class_options[:class] ||= "medium"
141
+ class_options[:class] = "#{class_options[:class]} input-text"
142
+ class_options[:class] += " error" if has_error?(attribute)
112
143
  options.delete(:label)
113
144
  options.delete(:label_options)
114
- html += yield(options)
145
+ html += yield(class_options)
115
146
  html += error_and_hint(attribute, options)
116
147
  end
117
148
  end
@@ -1,3 +1,3 @@
1
1
  module FoundationRailsHelper
2
- VERSION = "0.4"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -13,6 +13,27 @@ describe "FoundationRailsHelper::FormHelper" do
13
13
  end
14
14
  end
15
15
 
16
+ it "should display labels by default" do
17
+ form_for(@author) do |builder|
18
+ node = Capybara.string builder.text_field(:login)
19
+ node.should have_css('label[for="author_login"]', :text => "Login")
20
+ end
21
+ end
22
+
23
+ it "should not display labels by if there are options without auto_labels: false" do
24
+ form_for(@author, {html: {class: 'myclass'}}) do |builder|
25
+ node = Capybara.string builder.text_field(:login)
26
+ node.should have_css('label[for="author_login"]', :text => "Login")
27
+ end
28
+ end
29
+
30
+ it "should not display labels by if there are options without auto_labels: false" do
31
+ form_for(@author, {html: {class: 'myclass'}, auto_labels: false}) do |builder|
32
+ node = Capybara.string builder.text_field(:login)
33
+ node.should_not have_css('label[for="author_login"]', :text => "Login")
34
+ end
35
+ end
36
+
16
37
  describe "input generators" do
17
38
  it "should generate text_field input" do
18
39
  form_for(@author) do |builder|
@@ -49,14 +70,14 @@ describe "FoundationRailsHelper::FormHelper" do
49
70
  node.find_field('author_email').value.should == @author.email
50
71
  end
51
72
  end
52
-
73
+
53
74
  it "should generate url_field input" do
54
75
  form_for(@author) do |builder|
55
76
  node = Capybara.string builder.url_field(:url)
56
77
  node.should have_css('label[for="author_url"]', :text => "Url")
57
78
  node.should have_css('input.medium.input-text[type="url"][name="author[url]"]')
58
79
  node.find_field('author_url').value.should == @author.url
59
- end
80
+ end
60
81
  end
61
82
 
62
83
  it "should generate phone_field input" do
@@ -65,7 +86,7 @@ describe "FoundationRailsHelper::FormHelper" do
65
86
  node.should have_css('label[for="author_phone"]', :text => "Phone")
66
87
  node.should have_css('input.medium.input-text[type="tel"][name="author[phone]"]')
67
88
  node.find_field('author_phone').value.should == @author.phone
68
- end
89
+ end
69
90
  end
70
91
 
71
92
  it "should generate number_field input" do
@@ -74,7 +95,7 @@ describe "FoundationRailsHelper::FormHelper" do
74
95
  node.should have_css('label[for="author_some_number"]', :text => "Some number")
75
96
  node.should have_css('input.medium.input-text[type="number"][name="author[some_number]"]')
76
97
  node.find_field('author_some_number').value.should == @author.some_number
77
- end
98
+ end
78
99
  end
79
100
 
80
101
  it "should generate text_area input" do
@@ -116,9 +137,9 @@ describe "FoundationRailsHelper::FormHelper" do
116
137
  it "should generate check_box input without a label" do
117
138
  form_for(@author) do |builder|
118
139
  node = Capybara.string builder.check_box(:active, :label => false)
119
- node.should have_css('label[for="author_active"] input[type="hidden"][name="author[active]"][value="0"]')
120
- node.should have_css('label[for="author_active"] input[type="checkbox"][name="author[active]"]')
121
- node.should have_css('label[for="author_active"]', :text => "")
140
+ node.should have_css('input[type="hidden"][name="author[active]"][value="0"]')
141
+ node.should have_css('input[type="checkbox"][name="author[active]"]')
142
+ node.should_not have_css('label[for="author_active"]')
122
143
  end
123
144
  end
124
145
 
@@ -161,6 +182,143 @@ describe "FoundationRailsHelper::FormHelper" do
161
182
  end
162
183
  end
163
184
 
185
+ it "should generate datetime_select input" do
186
+ form_for(@author) do |builder|
187
+ node = Capybara.string builder.label(:birthdate) + builder.datetime_select(:birthdate)
188
+ node.should have_css('label[for="author_birthdate"]', :text => "Birthdate")
189
+ %w(1 2 3 4 5).each {|i| node.should have_css("select.medium.input-text[name='author[birthdate(#{i}i)]']") }
190
+ node.should have_css('select#author_birthdate_1i option[selected="selected"][value="1969"]')
191
+ node.should have_css('select#author_birthdate_2i option[selected="selected"][value="6"]')
192
+ node.should have_css('select#author_birthdate_3i option[selected="selected"][value="18"]')
193
+ node.should have_css('select#author_birthdate_4i option[selected="selected"][value="20"]')
194
+ node.should have_css('select#author_birthdate_5i option[selected="selected"][value="30"]')
195
+ end
196
+ end
197
+
198
+ it "should generate datetime_select input with :discard_year => true" do
199
+ form_for(@author) do |builder|
200
+ node = Capybara.string builder.label(:birthdate) + builder.datetime_select(:birthdate, :discard_year => true)
201
+ node.should have_css('label[for="author_birthdate"]', :text => "Birthdate")
202
+ %w(2 3 4 5).each {|i| node.should have_css("select.medium.input-text[name='author[birthdate(#{i}i)]']") }
203
+ node.should_not have_css('select#author_birthdate_1i option[selected="selected"][value="1969"]')
204
+ node.should have_css('select#author_birthdate_2i option[selected="selected"][value="6"]')
205
+ node.should have_css('select#author_birthdate_3i option[selected="selected"][value="18"]')
206
+ node.should have_css('select#author_birthdate_4i option[selected="selected"][value="20"]')
207
+ node.should have_css('select#author_birthdate_5i option[selected="selected"][value="30"]')
208
+ %w(1).each {|i| node.should_not have_css("select.medium.input-text[name='author[birthdate(#{i}i)]']") }
209
+ end
210
+ end
211
+
212
+ it "should generate time_zone_select input" do
213
+ form_for(@author) do |builder|
214
+ node = Capybara.string builder.label(:time_zone) + builder.time_zone_select(:time_zone)
215
+ node.should have_css('label[for="author_time_zone"]', :text => "Time zone")
216
+ node.should have_css('select[name="author[time_zone]"]')
217
+ node.should have_css('select[name="author[time_zone]"] option[value="Perth"]', :text => "(GMT+08:00) Perth")
218
+ end
219
+ end
220
+
221
+ it "should generate date_field input" do
222
+ form_for(@author) do |builder|
223
+ node = Capybara.string builder.date_field(:publish_date)
224
+ node.should have_css('label[for="author_publish_date"]', :text => "date")
225
+ node.should have_css('input.medium.input-text[type="date"][name="author[publish_date]"]')
226
+ node.find_field('author_publish_date').value.should == @author.publish_date.to_s
227
+ end
228
+ end
229
+
230
+ it "should generate datetime_field input" do
231
+ form_for(@author) do |builder|
232
+ node = Capybara.string builder.datetime_field(:forty_two)
233
+ node.should have_css('label[for="author_forty_two"]', :text => "Forty two")
234
+ node.should have_css('input.medium.input-text[type="datetime"][name="author[forty_two]"]')
235
+ value = DateTime.parse( node.find_field('author_forty_two').value)
236
+ value.should == @author.forty_two.to_s
237
+ end
238
+ end
239
+
240
+ it "should generate datetime_local_field" do
241
+ form_for(@author) do |builder|
242
+ node = Capybara.string builder.datetime_local_field(:forty_two)
243
+ node.should have_css('label[for="author_forty_two"]', :text => "Forty two")
244
+ node.should have_css('input.medium.input-text[type="datetime-local"][name="author[forty_two]"]')
245
+ node.find_field('author_forty_two').value.should == @author.forty_two.strftime("%Y-%m-%dT%H:%M:%S")
246
+ end
247
+ end
248
+
249
+ it "should generate month_field input" do
250
+ form_for(@author) do |builder|
251
+ node = Capybara.string builder.month_field(:forty_two)
252
+ node.should have_css('label[for="author_forty_two"]', :text => "Forty two")
253
+ node.should have_css('input.medium.input-text[type="month"][name="author[forty_two]"]')
254
+ node.find_field('author_forty_two').value.should == @author.forty_two.strftime("%Y-%m")
255
+ end
256
+ end
257
+
258
+ it "should generate week_field" do
259
+ form_for(@author) do |builder|
260
+ node = Capybara.string builder.week_field(:forty_two)
261
+ node.should have_css('label[for="author_forty_two"]', :text => "Forty two")
262
+ node.should have_css('input.medium.input-text[type="week"][name="author[forty_two]"]')
263
+ node.find_field('author_forty_two').value.should == @author.forty_two.strftime("%Y-W%V")
264
+ end
265
+ end
266
+
267
+ it "should generate time_field" do
268
+ form_for(@author) do |builder|
269
+ node = Capybara.string builder.time_field(:forty_two)
270
+ node.should have_css('label[for="author_forty_two"]', :text => "Forty two")
271
+ node.should have_css('input.medium.input-text[type="time"][name="author[forty_two]"]')
272
+ node.find_field('author_forty_two').value.should == @author.forty_two.strftime("%H:%M:%S.%L")
273
+ end
274
+ end
275
+
276
+ it "should generate range_field" do
277
+ form_for(@author) do |builder|
278
+ node = Capybara.string builder.range_field(:some_number)
279
+ node.should have_css('label[for="author_some_number"]', :text => "Some number")
280
+ node.should have_css('input.medium.input-text[type="range"][name="author[some_number]"]')
281
+ node.find_field('author_some_number').value.should == @author.some_number
282
+ end
283
+ end
284
+
285
+ it "should generate search_field" do
286
+ form_for(@author) do |builder|
287
+ node = Capybara.string builder.search_field(:description)
288
+ node.should have_css('label[for="author_description"]', :text => "Description")
289
+ node.should have_css('input.medium.input-text[type="search"][name="author[description]"]')
290
+ node.find_field('author_description').value.should == @author.description
291
+ end
292
+ end
293
+
294
+ it "should generate color_field" do
295
+ form_for(@author) do |builder|
296
+ node = Capybara.string builder.color_field(:favorite_color)
297
+ node.should have_css('label[for="author_favorite_color"]', :text => "Favorite color")
298
+ node.should have_css('input.medium.input-text[type="color"][name="author[favorite_color]"]')
299
+ node.find_field('author_favorite_color').value.should == @author.favorite_color
300
+ end
301
+ end
302
+
303
+ it "should generate collection_select input" do
304
+ form_for(@author) do |builder|
305
+ node = Capybara.string builder.collection_select(:favorite_book, Book.all, :id, :title)
306
+ node.should have_css('label[for="author_favorite_book"]', :text => "Favorite book")
307
+ node.should have_css('select[name="author[favorite_book]"]')
308
+ node.should have_css('select[name="author[favorite_book]"] option[value="78"]', :text => "Gulliver's Travels")
309
+ node.should have_css('select[name="author[favorite_book]"] option[value="133"]', :text => "Treasure Island")
310
+ end
311
+ end
312
+
313
+ it "should generate grouped_collection_select input" do
314
+ form_for(@author) do |builder|
315
+ node = Capybara.string builder.grouped_collection_select(:favorite_book, Genre.all, :books, :name, :id, :title)
316
+ node.should have_css('label[for="author_favorite_book"]', :text => "Favorite book")
317
+ node.should have_css('select[name="author[favorite_book]"]')
318
+ node.should have_css('select[name="author[favorite_book]"] optgroup[label="Exploration"] option[value="78"]', :text => "Gulliver's Travels")
319
+ node.should have_css('select[name="author[favorite_book]"] optgroup[label="Pirate Exploits"] option[value="133"]', :text => "Treasure Island")
320
+ end
321
+ end
164
322
  end
165
323
 
166
324
  describe "errors generator" do
@@ -177,5 +335,108 @@ describe "FoundationRailsHelper::FormHelper" do
177
335
  node.should have_css('small.error', :text => "required")
178
336
  end
179
337
  end
338
+ %w(file_field email_field text_field telephone_field phone_field
339
+ url_field number_field date_field datetime_field datetime_local_field
340
+ month_field week_field time_field range_field search_field color_field
341
+
342
+ password_field
343
+ ).each do |field|
344
+ it "should display errors on #{field} inputs" do
345
+ form_for(@author) do |builder|
346
+ @author.stub!(:errors).and_return({:description => ['required']})
347
+ node = Capybara.string builder.public_send(field, :description)
348
+ node.should have_css('label.error[for="author_description"]')
349
+ node.should have_css('input.error[name="author[description]"]')
350
+ end
351
+ end
352
+ end
353
+ it "should display errors on text_area inputs" do
354
+ form_for(@author) do |builder|
355
+ @author.stub!(:errors).and_return({:description => ['required']})
356
+ node = Capybara.string builder.text_area(:description)
357
+ node.should have_css('label.error[for="author_description"]')
358
+ node.should have_css('textarea.error[name="author[description]"]')
359
+ end
360
+ end
361
+ it "should display errors on select inputs" do
362
+ form_for(@author) do |builder|
363
+ @author.stub!(:errors).and_return({:favorite_book => ['required']})
364
+ node = Capybara.string builder.select(:favorite_book, [["Choice #1", :a], ["Choice #2", :b]])
365
+ node.should have_css('label.error[for="author_favorite_book"]')
366
+ node.should have_css('select.error[name="author[favorite_book]"]')
367
+ end
368
+ end
369
+ it "should display errors on date_select inputs" do
370
+ form_for(@author) do |builder|
371
+ @author.stub!(:errors).and_return({:birthdate => ['required']})
372
+ node = Capybara.string builder.date_select(:birthdate)
373
+ node.should have_css('label.error[for="author_birthdate"]')
374
+ %w(1 2 3).each {|i| node.should have_css("select.error[name='author[birthdate(#{i}i)]']") }
375
+ end
376
+ end
377
+ it "should display errors on datetime_select inputs" do
378
+ form_for(@author) do |builder|
379
+ @author.stub!(:errors).and_return({:birthdate => ['required']})
380
+ node = Capybara.string builder.datetime_select(:birthdate)
381
+ node.should have_css('label.error[for="author_birthdate"]')
382
+ %w(1 2 3 4 5).each {|i| node.should have_css("select.error[name='author[birthdate(#{i}i)]']") }
383
+ end
384
+ end
385
+ it "should display errors on time_zone_select inputs" do
386
+ form_for(@author) do |builder|
387
+ @author.stub!(:errors).and_return({:time_zone => ['required']})
388
+ node = Capybara.string builder.time_zone_select(:time_zone)
389
+ node.should have_css('label.error[for="author_time_zone"]')
390
+ node.should have_css('select.error[name="author[time_zone]"]')
391
+ end
392
+ end
393
+
394
+ it "should display errors on collection_select inputs" do
395
+ form_for(@author) do |builder|
396
+ @author.stub!(:errors).and_return({:favorite_book => ['required']})
397
+ node = Capybara.string builder.collection_select(:favorite_book, Book.all, :id, :title)
398
+ node.should have_css('label.error[for="author_favorite_book"]')
399
+ node.should have_css('select.error[name="author[favorite_book]"]')
400
+ end
401
+ end
402
+
403
+ it "should display errors on grouped_collection_select inputs" do
404
+ form_for(@author) do |builder|
405
+ @author.stub!(:errors).and_return({:favorite_book => ['required']})
406
+ node = Capybara.string builder.grouped_collection_select(:favorite_book, Genre.all, :books, :name, :id, :title)
407
+ node.should have_css('label.error[for="author_favorite_book"]')
408
+ node.should have_css('select.error[name="author[favorite_book]"]')
409
+ end
410
+ end
411
+
412
+ # N.B. check_box and radio_button inputs don't have the error class applied
413
+
414
+ it "should display HTML errors when the option is specified" do
415
+ form_for(@author) do |builder|
416
+ @author.stub!(:errors).and_return({:login => ['required <a href="link_target">link</a>']})
417
+ node = Capybara.string builder.text_field(:login, html_safe_errors: true)
418
+ node.should have_link('link', href: 'link_target')
419
+ end
420
+ end
421
+ it "should not display HTML errors when the option is not specified" do
422
+ form_for(@author) do |builder|
423
+ @author.stub!(:errors).and_return({:login => ['required <a href="link_target">link</a>']})
424
+ node = Capybara.string builder.text_field(:login)
425
+ node.should_not have_link('link', href: 'link')
426
+ end
427
+ end
428
+
429
+ it "should not display labels unless specified in the builder method" do
430
+ form_for(@author, auto_labels: false) do |builder|
431
+ node = Capybara.string builder.text_field(:login) +
432
+ builder.check_box(:active, label: true) +
433
+ builder.text_field(:description, label: 'Tell me about you')
434
+
435
+ node.should_not have_css('label[for="author_login"]')
436
+ node.should have_css('label[for="author_active"]', text: 'Active')
437
+ node.should have_css('label[for="author_description"]', text: 'Tell me about you')
438
+ end
439
+ end
440
+
180
441
  end
181
442
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,7 @@
1
1
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
2
2
  require "foundation_rails_helper"
3
- require "capybara"
3
+ require "capybara"
4
+
5
+ # turning off deprecations
6
+ ActiveSupport::Deprecation.silenced = true
7
+ I18n.enforce_available_locales = false
@@ -1,15 +1,17 @@
1
- require 'rails'
1
+ require 'bundler/setup'
2
2
  require 'active_support'
3
3
  require 'action_pack'
4
4
  require 'action_view'
5
5
  require 'action_controller'
6
6
  require 'action_dispatch'
7
+ require 'active_model'
8
+ require 'active_support/core_ext'
7
9
 
8
10
  # Thanks to Justin French for formtastic spec
9
11
  module FoundationRailsSpecHelper
10
12
  include ActionPack
11
13
  include ActionView::Context if defined?(ActionView::Context)
12
- include ActionController::RecordIdentifier
14
+ include ActionView::RecordIdentifier
13
15
  include ActionView::Helpers::FormHelper
14
16
  include ActionView::Helpers::FormTagHelper
15
17
  include ActionView::Helpers::FormOptionsHelper
@@ -23,6 +25,7 @@ module FoundationRailsSpecHelper
23
25
  include ActionView::Helpers::AssetTagHelper
24
26
  include ActiveSupport
25
27
  include ActionController::PolymorphicRoutes if defined?(ActionController::PolymorphicRoutes)
28
+ include ActionDispatch::Routing::UrlFor
26
29
 
27
30
  def active_model_validator(kind, attributes, options = {})
28
31
  validator = mock("ActiveModel::Validations::#{kind.to_s.titlecase}Validator", :attributes => attributes, :options => options)
@@ -57,6 +60,28 @@ module FoundationRailsSpecHelper
57
60
  end
58
61
  end
59
62
 
63
+ class ::Book
64
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
65
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
66
+
67
+ def to_label
68
+ end
69
+
70
+ def persisted?
71
+ end
72
+ end
73
+
74
+ class ::Genre
75
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
76
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
77
+
78
+ def to_label
79
+ end
80
+
81
+ def persisted?
82
+ end
83
+ end
84
+
60
85
  def mock_everything
61
86
  # Resource-oriented styles like form_for(@post) will expect a path method for the object,
62
87
  # so we're defining some here.
@@ -76,12 +101,30 @@ module FoundationRailsSpecHelper
76
101
  @author.stub!(:active).and_return(true)
77
102
  @author.stub!(:description).and_return('bla bla bla')
78
103
  @author.stub!(:avatar).and_return('avatar.png')
79
- @author.stub!(:birthdate).and_return(Date.parse("1969-06-18 20:30"))
104
+ @author.stub!(:birthdate).and_return(DateTime.parse("1969-06-18 20:30"))
80
105
  @author.stub!(:id).and_return(37)
81
106
  @author.stub!(:new_record?).and_return(false)
82
107
  @author.stub!(:errors).and_return(mock('errors', :[] => nil))
83
108
  @author.stub!(:to_key).and_return(nil)
84
109
  @author.stub!(:persisted?).and_return(nil)
110
+ @author.stub!(:time_zone).and_return("Perth")
111
+ @author.stub!(:publish_date).and_return(Date.new( 2000, 1, 1 ))
112
+ @author.stub!(:forty_two).and_return(@author.birthdate + 42.years)
113
+ @author.stub!(:favorite_color).and_return("#424242")
114
+ @author.stub!(:favorite_book).and_return()
115
+
116
+ @book_0 = ::Book.new
117
+ @book_0.stub!(:id).and_return("78")
118
+ @book_0.stub!(:title).and_return("Gulliver's Travels")
119
+ @book_1 = ::Book.new
120
+ @book_1.stub!(:id).and_return("133")
121
+ @book_1.stub!(:title).and_return("Treasure Island")
122
+ @genre_0 = ::Genre.new
123
+ @genre_0.stub!(:name).and_return("Exploration")
124
+ @genre_0.stub!(:books).and_return([@book_0])
125
+ @genre_1 = ::Genre.new
126
+ @genre_1.stub!(:name).and_return("Pirate Exploits")
127
+ @genre_1.stub!(:books).and_return([@book_1])
85
128
 
86
129
  ::Author.stub!(:scoped).and_return(::Author)
87
130
  ::Author.stub!(:find).and_return([@author])
@@ -92,6 +135,9 @@ module FoundationRailsSpecHelper
92
135
  ::Author.stub!(:content_columns).and_return([mock('column', :name => 'login'), mock('column', :name => 'created_at')])
93
136
  ::Author.stub!(:to_key).and_return(nil)
94
137
  ::Author.stub!(:persisted?).and_return(nil)
138
+
139
+ ::Book.stub!(:all).and_return([@book_0, @book_1])
140
+ ::Genre.stub!(:all).and_return([@genre_0, @genre_1])
95
141
  end
96
142
 
97
143
  def self.included(base)
metadata CHANGED
@@ -1,80 +1,155 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foundation_rails_helper
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.4'
5
- prerelease:
4
+ version: 0.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Sebastien Gruhier
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-26 00:00:00.000000000 Z
11
+ date: 2014-10-10 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: railties
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '3.0'
19
+ version: '4.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 4.1.1
22
23
  type: :runtime
23
24
  prerelease: false
24
25
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '4.1'
30
+ - - ">="
28
31
  - !ruby/object:Gem::Version
29
- version: '3.0'
32
+ version: 4.1.1
30
33
  - !ruby/object:Gem::Dependency
31
34
  name: actionpack
32
35
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
36
  requirements:
35
- - - ! '>='
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '4.1'
40
+ - - ">="
36
41
  - !ruby/object:Gem::Version
37
- version: '3.0'
42
+ version: 4.1.1
38
43
  type: :runtime
39
44
  prerelease: false
40
45
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
46
  requirements:
43
- - - ! '>='
47
+ - - "~>"
44
48
  - !ruby/object:Gem::Version
45
- version: '3.0'
49
+ version: '4.1'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 4.1.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: activemodel
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '4.1'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 4.1.1
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '4.1'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 4.1.1
73
+ - !ruby/object:Gem::Dependency
74
+ name: activesupport
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '4.1'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 4.1.1
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.1'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 4.1.1
93
+ - !ruby/object:Gem::Dependency
94
+ name: tzinfo
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.2'
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 1.2.2
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '1.2'
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 1.2.2
46
113
  - !ruby/object:Gem::Dependency
47
114
  name: rspec-rails
48
115
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
116
  requirements:
51
- - - ! '>='
117
+ - - "~>"
118
+ - !ruby/object:Gem::Version
119
+ version: '2.8'
120
+ - - ">="
52
121
  - !ruby/object:Gem::Version
53
- version: '0'
122
+ version: 2.8.1
54
123
  type: :development
55
124
  prerelease: false
56
125
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
126
  requirements:
59
- - - ! '>='
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '2.8'
130
+ - - ">="
60
131
  - !ruby/object:Gem::Version
61
- version: '0'
132
+ version: 2.8.1
62
133
  - !ruby/object:Gem::Dependency
63
134
  name: capybara
64
135
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
136
  requirements:
67
- - - ! '>='
137
+ - - "~>"
68
138
  - !ruby/object:Gem::Version
69
- version: '0'
139
+ version: '2.4'
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: 2.4.3
70
143
  type: :development
71
144
  prerelease: false
72
145
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
146
  requirements:
75
- - - ! '>='
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '2.4'
150
+ - - ">="
76
151
  - !ruby/object:Gem::Version
77
- version: '0'
152
+ version: 2.4.3
78
153
  description: Rails for zurb foundation CSS framework. Form builder, flash message,
79
154
  ...
80
155
  email:
@@ -83,9 +158,9 @@ executables: []
83
158
  extensions: []
84
159
  extra_rdoc_files: []
85
160
  files:
86
- - .gitignore
87
- - .rspec
88
- - .travis.yml
161
+ - ".gitignore"
162
+ - ".rspec"
163
+ - ".travis.yml"
89
164
  - CHANGELOG.md
90
165
  - Gemfile
91
166
  - LICENSE
@@ -103,37 +178,32 @@ files:
103
178
  - spec/spec_helper.rb
104
179
  - spec/support/mock_rails.rb
105
180
  homepage: http://github.com/sgruhier/foundation_rails_helper
106
- licenses: []
181
+ licenses:
182
+ - MIT
183
+ metadata: {}
107
184
  post_install_message:
108
185
  rdoc_options: []
109
186
  require_paths:
110
187
  - lib
111
188
  required_ruby_version: !ruby/object:Gem::Requirement
112
- none: false
113
189
  requirements:
114
- - - ! '>='
190
+ - - ">="
115
191
  - !ruby/object:Gem::Version
116
192
  version: '0'
117
- segments:
118
- - 0
119
- hash: -422087938175981355
120
193
  required_rubygems_version: !ruby/object:Gem::Requirement
121
- none: false
122
194
  requirements:
123
- - - ! '>='
195
+ - - ">="
124
196
  - !ruby/object:Gem::Version
125
197
  version: '0'
126
- segments:
127
- - 0
128
- hash: -422087938175981355
129
198
  requirements: []
130
199
  rubyforge_project:
131
- rubygems_version: 1.8.23
200
+ rubygems_version: 2.2.2
132
201
  signing_key:
133
- specification_version: 3
202
+ specification_version: 4
134
203
  summary: Rails helpers for zurb foundation CSS framework
135
204
  test_files:
136
205
  - spec/foundation_rails_helper/flash_helper_spec.rb
137
206
  - spec/foundation_rails_helper/form_builder_spec.rb
138
207
  - spec/spec_helper.rb
139
208
  - spec/support/mock_rails.rb
209
+ has_rdoc: