attribute_pair_generator 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bac8f3031dcc068e105bf8f30c4cdc0e2008cf98
4
+ data.tar.gz: 2420640934192d3de205e99924aaab25eaab4286
5
+ SHA512:
6
+ metadata.gz: 2b3faef7021f6a4bf7d1ff40fe4762a53d9d9c5bb0145fa1ed964205576344faeecb4b209392dbc8ce6c6e685b198c541faf3bcdaec5c509de2bfb2c56a555e9
7
+ data.tar.gz: 6c46c0d9b9fa7af72f6494257031911b0e50c6439e181201430d4a2ab1c18c834d9c82477f0270d23a471a4eaf120c813cfb458769fb3d5ea042b3a2cedca341
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013, Andrew Thal, Jeff Whitmire, and Contributors. All Rights Reserved.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # Attribute Pair Generator
2
+
3
+ * Easily generate form fields and object information fields with labels.
4
+ * Maintain consistent form structure without lots of html overhead:
5
+
6
+ Using APG, this...
7
+
8
+ <% apg = AttributePairGenerator.new(foo) %>
9
+ <%= form_tag foo_path(foo.id), method: :put do -%>
10
+ <dl>
11
+ <%= apg.text_field(attr: :title, help: "the title of your foo") %>
12
+ <%= apg.date(attr: :starts_at) %>
13
+ <%= apg.plain_text(attr: :status) %>
14
+ </dl>
15
+ <% end %>
16
+
17
+ generates...
18
+
19
+ <form accept-charset="UTF-8" action="/foo" method="post">
20
+ <dl>
21
+ <dt>title</dt>
22
+ <dd>
23
+ <input id="title" name="title" type="text" value="bar">
24
+ <span class="help-inline">the title of your foo</span>
25
+ </dd>
26
+ <dt>starts at</dt>
27
+ <dd>
28
+ <input class="datepicker" id="starts_at" name="starts_at" type="text" value="2013-10-30 05:00:00 +0000">
29
+ <span class="help-inline"></span>
30
+ </dd>
31
+ <dt>status</dt>
32
+ <dd>
33
+ approved
34
+ <span class="help-inline"></span>
35
+ </dd>
36
+ </dl>
37
+ </form>
38
+
39
+ ## Installation
40
+
41
+ Add this line to your application's Gemfile:
42
+
43
+ gem 'attribute_pair_generator'
44
+
45
+ And then execute:
46
+
47
+ $ bundle
48
+
49
+ Or install it yourself as:
50
+
51
+ $ gem install attribute_pair_generator
52
+
53
+ ## Common Usage
54
+
55
+ ### Call any of the apg methods, and pass in a hash of options, common options include:
56
+
57
+ * *attr*: using this option alone, you get the label to be a humanized version of the attr, and the value to be the attr called on the initialized object (if it exists)
58
+ * *label*: override the label
59
+ * *value*: override the value
60
+ * *help*: help text shown after the value
61
+ * *field_options*: pass in options to the `content_tag` for the main desired element (e.g. <a> tag, input, textarea, checkbox)
62
+ * *dd_options*: pass in options to the `content_tag` for the dd (value)
63
+ * *prefix*: give a prefix to input elements' names and values
64
+ * *disabled*: disable the input element or link
65
+
66
+ ## Examples
67
+
68
+ ### link
69
+
70
+ apg.link(title: "foo", url: "http://example.com")
71
+
72
+ ### plain text
73
+
74
+ apg.plain_text(label: 'contract dates', value: date_field_range('contract', 'contract'))
75
+
76
+ ### date (can be used with jqueryui datepicker)
77
+
78
+ apg.date(attr: :starts_at)
79
+
80
+ ### select dropdown
81
+
82
+ apg.select(attr: :lead_editor, value: editor_id, collection: [["Tom", 0], ["Dick", 1], ["Harry", 2]])
83
+
84
+ ### checkbox
85
+
86
+ apg.checkbox(attr: :ops_complete, disabled: !can_mark_ops_complete?)
87
+
88
+ ### text field
89
+
90
+ apg.text_field(attr: :long_title)
91
+ apg.text_field(prefix: 'tax', attr: :id, value: '', disabled: true)
92
+
93
+ ### text area
94
+
95
+ apg.text_area(attr: :email_addresses, value: email_addresses.join("\n"), help: "Email addresses. One per line")
96
+
97
+ ### radio buttons
98
+
99
+ apg.radio(attr: :review_source, collection: [[nil, 'none'], 'Review Site'], dd_options: {class: 'horizontal-layout'})
100
+
101
+ ## Authors
102
+
103
+ * Andrew Thal <andrew.thal@livingsocial.com>
104
+ * Jeff Whitmire <jeff.whitmire@livingsocial.com>
105
+
106
+ ## License
107
+
108
+ Attribute Pair Generator is released under the [MIT License](http://www.opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "rake/testtask"
2
+
3
+ FileList["tasks/*.rake"].each { |task| load task }
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['spec/*_spec.rb']
8
+ end
9
+
10
+ task :default do
11
+ system("rspec -c")
12
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "attribute_pair_generator"
7
+ gem.version = "1.0.1"
8
+ gem.authors = ["Andrew Thal", "Jeff Whitmire"]
9
+ gem.email = "andrew.thal@livingsocial.com"
10
+ gem.description = %q{Easily generate form fields and object information fields with labels.}
11
+ gem.summary = %q{Easily generate form fields and object information fields with labels.}
12
+ gem.homepage = "https://github.com/livingsocial/attribute-pair-generator"
13
+
14
+ gem.license = 'MIT'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.files = `git ls-files`.split("\n")
18
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency 'rake'
22
+ gem.add_development_dependency "faker"
23
+ gem.add_development_dependency "rspec", '~> 2.0'
24
+ gem.add_development_dependency "nokogiri", '~> 1.6'
25
+ gem.add_dependency "actionpack", '>= 3.0.0'
26
+ end
@@ -0,0 +1,109 @@
1
+ class AttributePairGenerator
2
+ require 'action_view'
3
+ include ActionView::Helpers::UrlHelper
4
+ include ActionView::Helpers::FormOptionsHelper
5
+ include ActionView::Helpers::FormTagHelper
6
+
7
+ attr_accessor :output_buffer
8
+ attr_reader :obj
9
+
10
+ def initialize(init_obj = nil)
11
+ @obj = init_obj
12
+ end
13
+
14
+ def link(options)
15
+ content = link_to options[:title], options[:url], options[:field_options]
16
+ render(content, options)
17
+ end
18
+
19
+ def plain_text(options)
20
+ render(value(options), options)
21
+ end
22
+
23
+ def date(options)
24
+ text_field_options = field_options(options)
25
+ ((text_field_options[:class] ||= '') << ' datepicker').strip!
26
+
27
+ content = text_field_tag attribute(options), value(options), text_field_options
28
+ render(content, options)
29
+ end
30
+
31
+ def select(options)
32
+ content = select_tag attribute(options), options_for_select(options[:collection], value(options)), field_options(options, prompt: options[:prompt], include_blank: options[:include_blank])
33
+ render(content, options)
34
+ end
35
+
36
+ def checkbox(options)
37
+ hidden_tag = hidden_field_tag attribute(options), options[:unchecked_value].nil? ? false : options[:unchecked_value]
38
+ checked_value = options[:checked_value] || true
39
+ is_checked = value(options).to_s == checked_value.to_s
40
+ content = hidden_tag + check_box_tag(attribute(options), checked_value, is_checked, field_options(options))
41
+ render(content, options)
42
+ end
43
+
44
+ def text_field(options)
45
+ content = text_field_tag attribute(options), value(options), field_options(options)
46
+ render(content, options)
47
+ end
48
+
49
+ def text_area(options)
50
+ content = text_area_tag attribute(options), value(options), field_options(options)
51
+ render(content, options)
52
+ end
53
+
54
+ def radio(options)
55
+ content = content_tag :ol, class: 'unstyled' do
56
+ options[:collection].map do |element|
57
+ if element.is_a?(Array)
58
+ value = element[0]
59
+ label = element[1]
60
+ else
61
+ value = label = element
62
+ end
63
+ content_tag :li do
64
+ label_tag("#{attribute(options)}_#{value}", radio_button_tag(attribute(options), value || '', value == value(options), field_options(options)) + label, class: 'radio')
65
+ end
66
+ end.flatten.join("").html_safe
67
+ end
68
+
69
+ render(content, options)
70
+ end
71
+
72
+ private
73
+
74
+ def field_options(options, overrides={})
75
+ {disabled: options[:disabled], name: name(options)}.merge(overrides).merge(options.fetch(:field_options, {}))
76
+ end
77
+
78
+ def render(content, options)
79
+ dt_content = options[:label] ? options[:label].to_s : options[:attr].to_s.humanize.downcase
80
+ dd_content = content.to_s
81
+ dd_content += content_tag(:span, class: "help-inline") { options[:help].to_s } if options[:help]
82
+ content_tag(:dt) { dt_content } +
83
+ content_tag(:dd, options[:dd_options]) { dd_content.html_safe }
84
+ end
85
+
86
+ def value(options)
87
+ if options[:value]
88
+ options[:value]
89
+ elsif obj.respond_to?(options[:attr])
90
+ obj.send(options[:attr])
91
+ end
92
+ end
93
+
94
+ def name(options)
95
+ if options[:prefix]
96
+ "#{options[:prefix]}[#{options[:attr]}]"
97
+ else
98
+ options[:attr]
99
+ end
100
+ end
101
+
102
+ def attribute(options)
103
+ if options[:prefix]
104
+ "#{options[:prefix]}_#{options[:attr]}"
105
+ else
106
+ options[:attr]
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,469 @@
1
+ require 'spec_helper'
2
+
3
+ describe AttributePairGenerator do
4
+ let(:test_object) { double(id: 1, full_name: "foo bar", date: "2013-05-13", featured: true, scheduler: 2) }
5
+ let(:subject) { AttributePairGenerator.new(test_object) }
6
+ let(:generated) { Nokogiri::HTML(subject.send(generator_method, generator_arguments)) }
7
+
8
+ shared_examples 'a generated pair structure' do
9
+ it { generated.css('dt').should be_present }
10
+ it { generated.css('dd').should be_present }
11
+ end
12
+
13
+ shared_examples 'accepts standard options' do
14
+ context 'if given a help option' do
15
+ it 'creates a span with the help text' do
16
+ generator_arguments[:help] = Faker::Lorem.sentence
17
+ generated.css("dd span.help-inline").text.should eq(generator_arguments[:help])
18
+ end
19
+ end
20
+
21
+ context 'if no help text given' do
22
+ it 'creates an empty help text area' do
23
+ generator_arguments.keys.should_not include(:help)
24
+ generated.css("dd span.help-inline").text.should be_empty
25
+ end
26
+ end
27
+
28
+ context 'if given a label option' do
29
+ it 'uses the given label in the dt' do
30
+ generator_arguments[:label] = Faker::Lorem.word
31
+ generated.css("dt").text.should eq(generator_arguments[:label])
32
+ end
33
+ end
34
+
35
+ context 'if no label option given' do
36
+ it 'uses the attribute name for the label' do
37
+ generator_arguments.keys.should_not include(:label)
38
+ generated.css("dt").text.should eq(generator_arguments[:attr].to_s.humanize.downcase)
39
+ end
40
+ end
41
+
42
+ context "if given dd_options" do
43
+ let(:dd_options) { {class: 'special-fluffy-dd'} }
44
+ it "uses those options on the dd element" do
45
+ generator_arguments[:dd_options] = dd_options
46
+ generated.css("dd").first.attributes["class"].value.should match /#{dd_options[:class]}/
47
+ end
48
+ end
49
+ end
50
+
51
+ shared_examples 'form field prefix generator' do
52
+ context 'if a prefix option is given' do
53
+ before do
54
+ generator_arguments[:prefix] = 'foo'
55
+ end
56
+
57
+ it 'creates the id as prefix_attribute' do
58
+ generated.css('dd').children.last['id'].should == "#{generator_arguments[:prefix]}_#{generator_arguments[:attr]}"
59
+ end
60
+
61
+ it 'creates the name as prefix[attribute]' do
62
+ generated.css('dd').children.last['name'].should == "#{generator_arguments[:prefix]}[#{generator_arguments[:attr]}]"
63
+ end
64
+
65
+ it 'does not use the prefix in the label' do
66
+ generated.css("dt").text.should eq(generator_arguments[:attr].to_s.humanize.downcase)
67
+ end
68
+ end
69
+
70
+ context 'if not given a prefix option' do
71
+ before do
72
+ generator_arguments.keys.should_not include(:prefix)
73
+ end
74
+
75
+ it 'uses the attribute as the id' do
76
+ generated.css('dd').children.last['id'].should == generator_arguments[:attr].to_s
77
+ end
78
+
79
+ it 'uses the attribute as the name' do
80
+ generated.css('dd').children.last['id'].should == generator_arguments[:attr].to_s
81
+ end
82
+ end
83
+ end
84
+
85
+ shared_examples 'form field value generator' do
86
+ context 'if a value option is given' do
87
+ before do
88
+ generator_arguments[:value] = '7337'
89
+ end
90
+
91
+ it 'uses the value given in the params' do
92
+ node = generated.css('dd').children.first
93
+
94
+ if node.has_attribute?('value')
95
+ node['value'].should == generator_arguments[:value]
96
+ else
97
+ node.text.should match /#{generator_arguments[:value]}/
98
+ end
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '#obj' do
104
+ its(:obj) { should eq(test_object) }
105
+ end
106
+
107
+ context 'information field generators' do
108
+ describe '#plain_text' do
109
+ let(:generator_method) { 'plain_text' }
110
+
111
+ context 'with basic options' do
112
+ let(:generator_arguments) { {attr: :id} }
113
+
114
+ it_should_behave_like 'a generated pair structure'
115
+ it_should_behave_like 'accepts standard options'
116
+
117
+ it 'renders plain text in the dd' do
118
+ generated.css("dd").text.should eq(test_object.id.to_s)
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#link' do
124
+ let(:generator_method) { 'link' }
125
+ let(:generator_arguments) { {title: "foo", url: "http://example.com"} }
126
+
127
+ context 'with basic options' do
128
+ it_should_behave_like 'a generated pair structure'
129
+ it_should_behave_like 'accepts standard options'
130
+
131
+ it 'renders a link in the dd' do
132
+ generated.css("dd").children.first.node_name.should == 'a'
133
+ end
134
+
135
+ it 'uses the title as the text of the link' do
136
+ generated.css("dd a").text.should eq("foo")
137
+ end
138
+
139
+ it 'uses the url as the target of the link' do
140
+ generated.css("dd a").first.attributes["href"].value.should eq("http://example.com")
141
+ end
142
+ end
143
+
144
+ context 'if given an extra field_options parameter' do
145
+ before do
146
+ generator_arguments[:field_options] = {class: 'findable_link'}
147
+ end
148
+
149
+ it 'sticks the extra options on the link element' do
150
+ generated.css("dd a").first.attributes["class"].value.should match /#{generator_arguments[:field_options][:class]}/
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ context 'form input generators' do
157
+ describe '#date' do
158
+ let(:generator_method) { 'date' }
159
+ let(:generator_arguments) { {attr: :date} }
160
+
161
+ context 'with basic options' do
162
+ it_should_behave_like 'a generated pair structure'
163
+ it_should_behave_like 'accepts standard options'
164
+ it_should_behave_like 'form field prefix generator'
165
+ it_should_behave_like 'form field value generator'
166
+
167
+ it 'renders an input element in the dd' do
168
+ generated.css("dd").children.first.node_name.should == 'input'
169
+ end
170
+
171
+ it 'rendered input element should have a text type' do
172
+ generated.css("dd input").first['type'].should match /text/
173
+ end
174
+
175
+ it 'adds the datepicker class to work with jquery-ui datepicker' do
176
+ generated.css("dd input").first['class'].should match /datepicker/
177
+ end
178
+ end
179
+
180
+ context 'with extra classes pass in field_options' do
181
+ before do
182
+ generator_arguments[:field_options] = {class: 'flibberty'}
183
+ end
184
+
185
+ it 'should have both expected classes instead of overwriting' do
186
+ generated.css("dd input").first['class'].should match /datepicker/
187
+ generated.css("dd input").first['class'].should match /#{generator_arguments[:field_options][:class]}/
188
+ end
189
+ end
190
+ end
191
+
192
+ describe '#select' do
193
+ let(:generator_method) { 'select' }
194
+ let(:generator_arguments) { {attr: :scheduler, collection: [[1, "Tom"], [2, "Dick"], [3, "Harry"]]} }
195
+
196
+ context 'with basic options' do
197
+ it_should_behave_like 'a generated pair structure'
198
+ it_should_behave_like 'accepts standard options'
199
+ #it_should_behave_like 'form field generator'
200
+
201
+ it 'renders a select element in the dd' do
202
+ generated.css("dd").children.first.node_name.should == 'select'
203
+ end
204
+
205
+ context 'without the include_blank or prompt options' do
206
+ it 'should not have a blank option element' do
207
+ generated.css("dd select option").any? { |option| option.text.blank? }.should be_false
208
+ end
209
+ end
210
+
211
+ context 'with the include_blank option' do
212
+ before do
213
+ generator_arguments[:include_blank] = true
214
+ end
215
+
216
+ it "includes a blank option first in the selector" do
217
+ generated.css("dd select option")[0].text.should be_blank
218
+ generated.css("dd select option")[0].attributes["value"].to_s.should be_blank
219
+ generated.css("dd select option")[0].attributes["selected"].should be_blank
220
+ end
221
+ end
222
+
223
+ context 'with the prompt option' do
224
+ let(:prompt) { 'Pick Me' }
225
+ before do
226
+ generator_arguments[:prompt] = prompt
227
+ end
228
+
229
+ it "includes a blank option first in the selector" do
230
+ generated.css("dd select option")[0].text.should == prompt
231
+ generated.css("dd select option")[0].attributes["value"].to_s.should be_blank
232
+ generated.css("dd select option")[0].attributes["selected"].should be_blank
233
+ end
234
+ end
235
+
236
+ context 'with just an array of strings as the collection' do
237
+ before do
238
+ generator_arguments[:collection] = %w(Tom Dick Harry)
239
+ end
240
+
241
+ it "generates the expected selector" do
242
+ generated.css("dd select option")[0].text.should eq("Tom")
243
+ generated.css("dd select option")[1].text.should eq("Dick")
244
+ generated.css("dd select option")[2].text.should eq("Harry")
245
+ end
246
+ end
247
+ end
248
+ end
249
+
250
+ describe '#text_field' do
251
+ let(:generator_method) { 'text_field' }
252
+
253
+ context 'with basic options' do
254
+ let(:generator_arguments) { {attr: :full_name} }
255
+
256
+ it_should_behave_like 'a generated pair structure'
257
+ it_should_behave_like 'accepts standard options'
258
+ it_should_behave_like 'form field prefix generator'
259
+ it_should_behave_like 'form field value generator'
260
+
261
+ it 'renders an input element in the dd' do
262
+ generated.css("dd").children.first.node_name.should == 'input'
263
+ end
264
+
265
+ it 'rendered input element should have a text type' do
266
+ generated.css("dd input").first['type'].should match /text/
267
+ end
268
+ end
269
+ end
270
+
271
+ describe '#text_area' do
272
+ let(:generator_method) { 'text_area' }
273
+
274
+ context 'with basic options' do
275
+ let(:generator_arguments) { {attr: :full_name} }
276
+
277
+ it_should_behave_like 'a generated pair structure'
278
+ it_should_behave_like 'accepts standard options'
279
+ it_should_behave_like 'form field prefix generator'
280
+ it_should_behave_like 'form field value generator'
281
+
282
+ it 'renders a textarea element in the dd' do
283
+ generated.css("dd").children.first.node_name.should == 'textarea'
284
+ end
285
+
286
+ it 'sets the value of the textarea to the attribute value' do
287
+ generated.css("dd textarea").text.should match /#{test_object.send(generator_arguments[:attr])}/
288
+ end
289
+ end
290
+ end
291
+
292
+ describe '#radio' do
293
+ let(:generator_method) { 'radio' }
294
+ context 'with basic options' do
295
+ let(:generator_arguments) { {attr: :scheduler, collection: [[1, "Tom"], [2, "Dick"], [3, "Harry"]]} }
296
+
297
+ it_should_behave_like 'a generated pair structure'
298
+ it_should_behave_like 'accepts standard options'
299
+ # can't use the shared example here, this generates a collection of form elements
300
+ #it_should_behave_like 'form field generator'
301
+
302
+ context 'if a prefix option is given' do
303
+ before do
304
+ generator_arguments[:prefix] = 'foo'
305
+ end
306
+
307
+ it 'creates the id as prefix_attribute' do
308
+ generated.css('dd input').each do |radio_element|
309
+ radio_element['id'].should match /^#{generator_arguments[:prefix]}_#{generator_arguments[:attr]}_\d$/
310
+ end
311
+ end
312
+
313
+ it 'creates the name as prefix[attribute]' do
314
+ generated.css('dd input').each do |radio_element|
315
+ radio_element['name'].should == "#{generator_arguments[:prefix]}[#{generator_arguments[:attr]}]"
316
+ end
317
+ end
318
+ end
319
+
320
+ context 'if given a one dimensional array for a collection' do
321
+ before do
322
+ generator_arguments[:collection] = %w(foo bar baz)
323
+ end
324
+
325
+ it 'should generate the same number of labels as the members of the collection' do
326
+ generated.css("dd label").size.should == generator_arguments[:collection].size
327
+ end
328
+
329
+ it 'should generate a label for each member of the collection' do
330
+ generated.css("dd label").collect(&:text).should == generator_arguments[:collection]
331
+ end
332
+
333
+ it 'should generate the same number of input elements as the members of the collection' do
334
+ generated.css("dd input").size.should == generator_arguments[:collection].size
335
+ end
336
+
337
+ it 'should set the input value for each member of the collection' do
338
+ generated.css("dd input").collect{|e| e.attr('value')}.should == generator_arguments[:collection]
339
+ end
340
+ end
341
+
342
+ context 'if not given a prefix option' do
343
+ before do
344
+ generator_arguments.keys.should_not include(:prefix)
345
+ end
346
+
347
+ it 'uses the attribute as the id' do
348
+ generated.css('dd input').each do |radio_element|
349
+ radio_element['id'].should match /^#{generator_arguments[:attr]}_\d$/
350
+ end
351
+ end
352
+
353
+ it 'uses the attribute as the name' do
354
+ generated.css('dd input').each do |radio_element|
355
+ radio_element['name'].should == generator_arguments[:attr].to_s
356
+ end
357
+ end
358
+ end
359
+
360
+ it 'should generate the same number of labels as the members of the collection' do
361
+ generated.css("dd label").size.should == generator_arguments[:collection].size
362
+ end
363
+
364
+ it 'should generate a label for each member of the collection' do
365
+ generated.css("dd label").collect(&:text).should == generator_arguments[:collection].collect { |m| m[1] }
366
+ end
367
+
368
+ it 'should generate the same number of input elements as the members of the collection' do
369
+ generated.css("dd input").size.should == generator_arguments[:collection].size
370
+ end
371
+
372
+ it 'builds a proper label' do
373
+ generator_arguments[:collection].each_with_index do |member, index|
374
+ generated.css("dd label")[index].attributes["for"].value.should eq("#{generator_arguments[:attr]}_#{member[0]}")
375
+ generated.css("dd label")[index].text.should eq(member[1])
376
+ end
377
+ end
378
+
379
+ it 'builds a proper radio button' do
380
+ generator_arguments[:collection].each_with_index do |member, index|
381
+ generated.css("dd input")[index].attributes["name"].value.should eq(generator_arguments[:attr].to_s)
382
+ generated.css("dd input")[index].attributes["value"].value.should eq(member[0].to_s)
383
+ end
384
+ end
385
+
386
+ it 'correctly sets the checked attribute and value based on the right value' do
387
+ generator_arguments[:collection].each_with_index do |member, index|
388
+ if test_object.send(generator_arguments[:attr]) == member[0]
389
+ generated.css("dd input")[index].attributes["checked"].value.should eq("checked")
390
+ else
391
+ generated.css("dd input")[index].should_not have_attribute("checked")
392
+ end
393
+ end
394
+ end
395
+ end
396
+ end
397
+
398
+ describe '#checkbox' do
399
+ let(:generator_method) { 'checkbox' }
400
+ let(:generator_arguments) { { attr: :featured } }
401
+
402
+ context 'with basic options' do
403
+ it_should_behave_like 'a generated pair structure'
404
+ it_should_behave_like 'accepts standard options'
405
+ it_should_behave_like 'form field prefix generator'
406
+
407
+ it 'renders a hidden input element in the dd' do
408
+ generated.css("dd").children.first.node_name.should == 'input'
409
+ generated.css("dd").children.first['type'].should match /hidden/
410
+ end
411
+
412
+ it 'renders a checkbox input element in the dd' do
413
+ generated.css("dd").children[1].node_name.should == 'input'
414
+ generated.css("dd").children[1]['type'].should match /checkbox/
415
+ end
416
+
417
+ it 'has a false hiden value' do
418
+ generated.css("dd input[type='hidden']").first['value'].should eq("false")
419
+ end
420
+
421
+ it 'can override a hidden value' do
422
+ generator_arguments[:unchecked_value] = "foo"
423
+ generated.css("dd input[type='hidden']").first['value'].should eq("foo")
424
+ end
425
+
426
+ context 'there is no explicitly set checked value' do
427
+ let(:generator_arguments) { { attr: :featured } }
428
+ it 'has a value of true' do
429
+ generated.css("dd input").last['value'].should eq("true")
430
+ end
431
+
432
+ context 'when the value is true' do
433
+ it 'sets the checked attribute' do
434
+ generated.css("dd input").last.should have_attribute("checked")
435
+ end
436
+ end
437
+
438
+ context 'when the value is not true' do
439
+ before { test_object.stub(:featured).and_return(false) }
440
+ it 'does not set the checked attribute' do
441
+ generated.css("dd input").last.should_not have_attribute("checked")
442
+ end
443
+ end
444
+ end
445
+
446
+ context 'a checked value is specified' do
447
+ let(:generator_arguments) { { attr: :featured, checked_value: 5 } }
448
+ it 'has a value of the checked value' do
449
+ generated.css("dd input").last['value'].should eq("5")
450
+ end
451
+
452
+ context 'when the value matches the checked_value' do
453
+ before { test_object.stub(:featured).and_return(generator_arguments[:checked_value]) }
454
+ it 'sets the checked attribute' do
455
+ generated.css("dd input").last.should have_attribute("checked")
456
+ end
457
+ end
458
+
459
+ context 'when the value does not matches the checked_value' do
460
+ before { test_object.stub(:featured).and_return(nil) }
461
+ it 'does not set the checked attribute' do
462
+ generated.css("dd input").last.should_not have_attribute("checked")
463
+ end
464
+ end
465
+ end
466
+ end
467
+ end
468
+ end
469
+ end
@@ -0,0 +1,6 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+ require 'rspec/autorun'
4
+ require "attribute_pair_generator"
5
+ require 'nokogiri'
6
+ require 'faker'
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attribute_pair_generator
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Thal
8
+ - Jeff Whitmire
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: '0'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - '>='
26
+ - !ruby/object:Gem::Version
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: faker
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: '2.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: '2.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: nokogiri
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '1.6'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '1.6'
70
+ - !ruby/object:Gem::Dependency
71
+ name: actionpack
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 3.0.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: 3.0.0
84
+ description: Easily generate form fields and object information fields with labels.
85
+ email: andrew.thal@livingsocial.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .gitignore
91
+ - Gemfile
92
+ - MIT-LICENSE
93
+ - README.md
94
+ - Rakefile
95
+ - attribute_pair_generator.gemspec
96
+ - lib/attribute_pair_generator.rb
97
+ - spec/attribute_pair_generator_spec.rb
98
+ - spec/spec_helper.rb
99
+ homepage: https://github.com/livingsocial/attribute-pair-generator
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - '>='
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - '>='
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.0.3
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Easily generate form fields and object information fields with labels.
123
+ test_files:
124
+ - spec/attribute_pair_generator_spec.rb
125
+ - spec/spec_helper.rb