erector-form_for 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .DS_Store
6
+ *.swp
7
+ *.swo
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in form_erector.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require "rspec/core/rake_task"
3
+
4
+ task :default => [:spec]
5
+
6
+ desc "Run specs"
7
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "erector/form_for/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "erector-form_for"
7
+ s.version = FormErector::VERSION
8
+ s.authors = ["Macario"]
9
+ s.email = ["macarui@gmail.com"]
10
+ s.homepage = "http://github.com/maca/erector-form_for"
11
+ s.summary = %q{Form helper inspired by erector targeting html5}
12
+ s.description = %q{Form helper inspired by erector targeting html5}
13
+
14
+ s.rubyforge_project = "erector-form_for"
15
+
16
+ s.add_dependency 'erector'
17
+ s.add_dependency 'sinatra'
18
+ s.add_dependency 'sinatra-trails'
19
+ s.add_dependency 'i18n'
20
+ s.add_dependency 'activesupport', '>= 3.0'
21
+
22
+ s.add_development_dependency 'rake'
23
+ s.add_development_dependency 'rspec'
24
+ s.add_development_dependency 'capybara'
25
+ s.add_development_dependency 'rack-test'
26
+ s.add_development_dependency 'rack_csrf'
27
+ s.add_development_dependency 'sequel'
28
+ s.add_development_dependency 'sqlite3'
29
+
30
+ s.files = `git ls-files`.split("\n")
31
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
32
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
33
+ s.require_paths = ["lib"]
34
+ end
@@ -0,0 +1,3 @@
1
+ module FormErector
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,204 @@
1
+ # encoding: utf-8
2
+ require 'sinatra/trails'
3
+ require "erector"
4
+
5
+ libdir = File.dirname( __FILE__)
6
+ $:.unshift(libdir) unless $:.include?(libdir)
7
+ require "form_for/version"
8
+
9
+ module Erector
10
+ module FormFor
11
+ class Form < Erector::InlineWidget
12
+ attr_reader :object_name
13
+ needs :action, :method => 'post'
14
+
15
+ def initialize app, object, opts, &block
16
+ assigns = {}
17
+ @app = app
18
+ @object = object
19
+ @opts = opts
20
+ @object_name = opts.delete(:object_name)
21
+ assigns[:method] = opts.delete(:method)
22
+
23
+ if opts.has_key?(:action)
24
+ assigns[:action] = opts.delete(:action)
25
+ end
26
+
27
+ if object_is_record?
28
+ @object_name ||= object.class.table_name.to_s.singularize
29
+ if object.new_record?
30
+ assigns[:action] ||= app.path_for("new_#{object_name}") if app.respond_to?(:path_for)
31
+ assigns[:method] ||= 'post'
32
+ opts[:id] ||= "new-#{object_name}"
33
+ else
34
+ assigns[:action] ||= app.path_for("edit_#{object_name}", object) if app.respond_to?(:path_for)
35
+ assigns[:method] ||= 'put'
36
+ opts[:id] ||= "edit-#{object_name}"
37
+ end
38
+ end
39
+
40
+ super assigns, &block
41
+
42
+ @method = @method.to_s
43
+ @action = @app.url @action
44
+ end
45
+
46
+ def fields attrs = {}, &block
47
+ legend_text = attrs.delete(:legend)
48
+ fieldset attrs do
49
+ ol &block
50
+ legend(legend_text) if legend_text
51
+ end
52
+ end
53
+
54
+ def form_input field, attrs = {}
55
+ widget WrappedInput.new(@object, @object_name, field, attrs)
56
+ end
57
+
58
+ private
59
+ def content
60
+ opts = @opts.merge(:method => @method == 'get' ? 'get' : 'post', :action => @action)
61
+ form opts do
62
+ input :type => "hidden", :name => "_method", :value => @method unless %(get post).include? @method
63
+ if @method != 'get' && @app.env['rack.session'] && @app.env['rack.session']['csrf.token']
64
+ text! Rack::Csrf.csrf_tag(@app.env)
65
+ end
66
+ input :type => "hidden", :name => "utf8", :value => '✓'
67
+ super
68
+ end
69
+ end
70
+
71
+ def object_is_record?
72
+ @object.class.respond_to?(:table_name) && @object.respond_to?(:new_record?)
73
+ end
74
+ end
75
+
76
+ class Input < Erector::Widget
77
+ EQUIVALENCIES = {:string => :text, :datetime_local => :'datetime-local', :phone => :tel, :fax => :tel}
78
+ attr_reader :id
79
+
80
+ def initialize kind, object, object_name, column, opts
81
+ opts[:name] ||= object_name ? "#{object_name}[#{column}]" : column
82
+ opts[:id] ||= [object_name, column].compact.join('-').dasherize
83
+ opts[:value] ||= Hash === object ? object[column] : object.send(column)
84
+ @type = kind.to_sym
85
+ @label = opts.delete(:label) || column.to_s.titleize
86
+ super opts
87
+ end
88
+
89
+ def content
90
+ case @type
91
+ when :boolean
92
+ input :type => :hidden, :value => 0, :name => @name
93
+ label :for => id do
94
+ input assigns.merge(:type => :checkbox, :value => 1)
95
+ text @label
96
+ end
97
+ when :text
98
+ label @label, :for => id
99
+ textarea @value, assigns
100
+ when :select
101
+ label @label, :for => id
102
+ assigns.delete(:collection) || raise("Missing parameter :collection")
103
+ assigns.delete(:value)
104
+ select assigns do
105
+ @collection.each do |value, text|
106
+ option text || value, :value => value, :selected => value.to_s == @value.to_s ? 'selected' : nil
107
+ end
108
+ end
109
+ when :radio
110
+ assigns.delete(:collection) || raise("Missing parameter :collection")
111
+ assigns.delete(:value)
112
+ fieldset do
113
+ label @label
114
+ ol do
115
+ @collection.each do |value, label_text|
116
+ li do
117
+ label do
118
+ input :value => value, :id => "#{@id}-#{value}".downcase.dasherize, :checked => value.to_s == @value.to_s ? 'checked' : nil
119
+ text " #{label_text || value}"
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+ else
126
+ label @label, :for => id
127
+ input assigns.merge(:type => EQUIVALENCIES[@type] || @type)
128
+ end
129
+ end
130
+ end
131
+
132
+ class WrappedInput < Erector::Widget
133
+ needs :as, :id => nil, :required => false
134
+
135
+ def initialize object, object_name, column, opts
136
+ assigns = {}
137
+
138
+ [:as, :required].each do |key|
139
+ opts.has_key?(key) and assigns[key] = opts.delete(key)
140
+ end
141
+
142
+ case column.to_s
143
+ when /email/
144
+ assigns[:as] ||= :email
145
+ when /url/
146
+ assigns[:as] ||= :url
147
+ when /password/
148
+ assigns[:as] ||= :password
149
+ when /search/, /query/, 'q'
150
+ assigns[:as] ||= :search
151
+ when /phone/, /fax/
152
+ assigns[:as] ||= :tel
153
+ end
154
+
155
+ if Sequel::Model === object
156
+ column_schema = object.db_schema[column.to_sym]
157
+ assigns[:required] = !column_schema[:allow_null] unless assigns.has_key?(:required)
158
+
159
+ type = column_schema[:db_type]
160
+ case type
161
+ when /char/
162
+ opts[:maxlength] ||= /\d+/.match(type)
163
+ assigns[:as] ||= :string
164
+ else
165
+ assigns[:as] ||= type.downcase
166
+ end
167
+ end
168
+
169
+ super assigns
170
+
171
+ case @as = @as.to_sym
172
+ when :hidden, :string, :text, :boolean, :email, :color, :date, :datetime, :'datetime-local', :datetime_local, :email, :file, :image, :month, :number, :password, :range, :search, :tel, :phone, :fax, :time, :url, :week, :select, :radio
173
+ @widget = Input.new @as, object, object_name, column, opts.merge(:required => @required)
174
+ else
175
+ raise ArgumentError, ":as => #{@as.inspect} is not a valid option"
176
+ end
177
+
178
+ @wrapper_html = {:class => []}
179
+ @wrapper_html[:id] = "input-#{@widget.id}"
180
+ @wrapper_html[:class].push(@required ? 'required' : 'optional')
181
+ @wrapper_html[:class].push @as
182
+ end
183
+
184
+ private
185
+ def content
186
+ li @wrapper_html do
187
+ widget @widget
188
+ end
189
+ end
190
+ end
191
+
192
+ module Helpers
193
+ def form_for object, opts = {}, &block
194
+ Form.new(self, object, opts, &block).to_html
195
+ end
196
+ end
197
+
198
+ class << self
199
+ def extended base
200
+ base.send :include, Helpers
201
+ end
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,392 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'form erector' do
5
+ include Rack::Test::Methods
6
+ include SpecHelper
7
+
8
+ describe 'form tag attributes' do
9
+ describe 'form for record' do
10
+ describe 'action and method for new record' do
11
+ before do
12
+ app.user_form(new_user)
13
+ get '/users/new'
14
+ end
15
+
16
+ it { page.should have_css "form[action='http://example.org/users/new']" }
17
+ it { page.should have_css "form[method='post']" }
18
+ it { page.should have_css "form[id='new-user']" }
19
+ it { page.should_not have_css "input[name=_method]" }
20
+ end
21
+
22
+ describe 'action and method for existing record' do
23
+ before do
24
+ app.user_form(existing_user)
25
+ get '/users/new'
26
+ end
27
+
28
+ it { page.should have_css "form[action='http://example.org/users/1/edit']" }
29
+ it { page.should have_css "form[method='post']" }
30
+ it { page.should have_css "form[id='edit-user']" }
31
+ it { page.should have_xpath "//input[@name='_method' and @value='put']" }
32
+ end
33
+
34
+ describe 'overriding method (get) and action and setting html attributes' do
35
+ before do
36
+ app.user_form(existing_user, :action => '/users', :method => :get, :id => 'search-users', :class => 'search-form')
37
+ get '/users/new'
38
+ end
39
+
40
+ it { page.should have_css "form[action='http://example.org/users']" }
41
+ it { page.should have_css "form[method='get']" }
42
+ it { page.should_not have_css "input[name=_method]" }
43
+ it { page.should have_css "form#search-users" }
44
+ it { page.should have_css "form.search-form" }
45
+ end
46
+ end
47
+
48
+ describe 'form for hash' do
49
+ describe 'action and method for new record and defaulting method to post' do
50
+ before do
51
+ app.user_form({}, :action => '/search')
52
+ get '/users/new'
53
+ end
54
+
55
+ it { page.should have_css "form[action='http://example.org/search']" }
56
+ it { page.should have_css "form[method='post']" }
57
+ end
58
+
59
+ it 'should requiere action' do
60
+ lambda{
61
+ app.user_form({}, :method => 'post')
62
+ get '/users/new'
63
+ }.should raise_error
64
+ end
65
+ end
66
+
67
+ describe 'csrf' do
68
+ it 'should have protection protection off' do
69
+ app.user_form(existing_user)
70
+ get '/users/new'
71
+ page.should_not have_xpath "//input[@name='_csrf' and @type='hidden']"
72
+ end
73
+
74
+ it 'should have protection on' do
75
+ app.use Rack::Session::Cookie, :secret => 'my secret'
76
+ app.use Rack::Csrf
77
+ app.user_form(existing_user)
78
+ get '/users/new'
79
+ page.should have_xpath "//input[@name='_csrf' and @type='hidden']"
80
+ end
81
+
82
+ it 'should have protection off for get' do
83
+ app.use Rack::Session::Cookie, :secret => 'my secret'
84
+ app.use Rack::Csrf
85
+ app.user_form(existing_user, :method => :get)
86
+ get '/users/new'
87
+ page.should_not have_xpath "//input[@name='_csrf' and @type='hidden']"
88
+ end
89
+ end
90
+
91
+ it 'should have utf8 field' do
92
+ app.user_form(existing_user)
93
+ get '/users/new'
94
+ page.should have_xpath "//input[@name='utf8' and @type='hidden' and @value='✓']"
95
+ end
96
+
97
+ it 'should pass self to block' do
98
+ app.user_form(new_user) do |form|
99
+ form.should be_a Erector::FormFor::Form
100
+ end
101
+ get '/users/new'
102
+ end
103
+ end
104
+
105
+ describe 'formfield' do
106
+ describe 'basic' do
107
+ before do
108
+ app.user_form(new_user) do |form|
109
+ fields
110
+ end
111
+ get '/users/new'
112
+ end
113
+ it { page.should have_xpath "//form/fieldset" }
114
+ it { page.should have_xpath "//form/fieldset/ol" }
115
+ it { page.should_not have_xpath "//form/fieldset/legend" }
116
+ end
117
+
118
+ describe 'with legend and attributes' do
119
+ before do
120
+ app.user_form(new_user) do |form|
121
+ fields :legend => 'Basic', :id => 'basic'
122
+ end
123
+ get '/users/new'
124
+ end
125
+ it { page.should have_xpath "//form/fieldset" }
126
+ it { page.should have_xpath "//form/fieldset[@id='basic']" }
127
+ it { page.should have_xpath "//form/fieldset/legend", :text => 'Basic' }
128
+ end
129
+ end
130
+
131
+ describe 'inputs' do
132
+ describe 'for record' do
133
+ describe 'basic' do
134
+ before do
135
+ new_user.stub!(:name).and_return('Macario')
136
+ app.user_form(new_user) do
137
+ fields do
138
+ form_input :name
139
+ form_input :about
140
+ end
141
+ end
142
+ get '/users/new'
143
+ end
144
+
145
+ describe 'wrap' do
146
+ it { page.should have_xpath "//form/fieldset/ol/li" }
147
+ it { page.should have_css "li#input-user-name" }
148
+ it { page.should have_css "li#input-user-name.required" }
149
+ it { page.should have_css "li#input-user-name.string" }
150
+ it { page.should have_css "li#input-user-about.optional" }
151
+ end
152
+
153
+ describe 'input' do
154
+ it { page.should have_xpath "//form/fieldset/ol/li/input" }
155
+ it { page.should have_css "input#user-name" }
156
+ it { page.should have_css "input#user-name[type='text']" }
157
+ it { page.should have_css "input#user-name[name='user[name]']" }
158
+ it { page.should have_css "input#user-name[value='Macario']" }
159
+ it { page.should have_css "input#user-name[maxlength='255']" }
160
+ it { page.should have_css "input#user-name[required]" }
161
+ it { page.should_not have_css "input#user-about[required]" }
162
+ end
163
+
164
+ describe 'label' do
165
+ it { page.should have_css "label[for='user-name']" }
166
+ it { page.should have_css "label[for='user-name']", :text => "Name" }
167
+ end
168
+ end
169
+
170
+ describe 'overriding defaults' do
171
+ before do
172
+ new_user.stub!(:name).and_return('Macario')
173
+ app.user_form(new_user) do
174
+ fields do
175
+ form_input :name, :required => false, :value => 'Luis', :id => 'nombre', :name => 'nombre', :maxlength => 100, :label => 'Escriba su nombre', :as => 'email'
176
+ end
177
+ end
178
+ get '/users/new'
179
+ end
180
+
181
+ describe 'wrap' do
182
+ it { page.should have_xpath "//form/fieldset/ol/li" }
183
+ it { page.should have_css "li#input-nombre" }
184
+ it { page.should have_css "li#input-nombre.optional" }
185
+ it { page.should have_css "li#input-nombre.email" }
186
+ end
187
+
188
+ describe 'input' do
189
+ it { page.should have_xpath "//form/fieldset/ol/li/input" }
190
+ it { page.should have_css "input#nombre" }
191
+ it { page.should have_css "input#nombre[type='email']" }
192
+ it { page.should have_css "input#nombre[name='nombre']" }
193
+ it { page.should have_css "input#nombre[value='Luis']" }
194
+ it { page.should have_css "input#nombre[maxlength='100']" }
195
+ end
196
+
197
+ describe 'label' do
198
+ it { page.should have_css "label[for='nombre']" }
199
+ it { page.should have_css "label[for='nombre']", :text => "Escriba su nombre" }
200
+ end
201
+ end
202
+ end
203
+
204
+ describe 'for hash' do
205
+ before do
206
+ app.user_form({:name => 'Macario', :about => nil}, :action => '/new') do
207
+ fields do
208
+ form_input :name, :as => :string, :required => true
209
+ form_input :about, :as => :string
210
+ end
211
+ end
212
+ get '/users/new'
213
+ end
214
+
215
+ describe 'wrap for required' do
216
+ it { page.should have_xpath "//form/fieldset/ol/li" }
217
+ it { page.should have_css "li#input-name" }
218
+ it { page.should have_css "li#input-name.required" }
219
+ it { page.should have_css "li#input-name.string" }
220
+ end
221
+
222
+ describe 'wrap for optional' do
223
+ it { page.should have_css "li#input-about.optional" }
224
+ end
225
+
226
+ describe 'input' do
227
+ it { page.should have_xpath "//form/fieldset/ol/li/input" }
228
+ it { page.should have_css "input#name" }
229
+ it { page.should have_css "input#name[type='text']" }
230
+ it { page.should have_css "input#name[name='name']" }
231
+ it { page.should have_css "input#name[value='Macario']" }
232
+ end
233
+
234
+ describe 'label' do
235
+ it { page.should have_css "label[for='name']" }
236
+ it { page.should have_css "label[for='name']", :text => "Name" }
237
+ end
238
+ end
239
+
240
+ describe 'input' do
241
+ describe 'boolean input with sequel reflection' do
242
+ before do
243
+ app.user_form(new_user) do
244
+ fields { form_input :confirmed }
245
+ end
246
+ get '/users/new'
247
+ end
248
+
249
+ it { page.should have_xpath "//form/fieldset/ol/li/label/input[@id='user-confirmed']" }
250
+ it { page.should have_css "input#user-confirmed[type='checkbox']" }
251
+ it { page.should have_css "input#user-confirmed[value='1']" }
252
+ it { page.should have_css "input#user-confirmed[name='user[confirmed]']" }
253
+ it { page.should have_xpath "//form/fieldset/ol/li/input[@type='hidden' and @name='user[confirmed]']" }
254
+ it { page.should have_xpath "//form/fieldset/ol/li/input[@type='hidden' and @value='0']" }
255
+ it { page.should have_xpath "//form/fieldset/ol/li/input[@type='hidden' and @name='user[confirmed]']" }
256
+ end
257
+
258
+ %w(hidden color date datetime datetime-local datetime_local email file image month number password range search tel phone fax time url week).each do |type|
259
+ describe "#{type} input" do
260
+ before "should emit type='#{type}'" do
261
+ app.user_form({}, :action => '/search') do
262
+ fields { form_input :any, :as => type }
263
+ end
264
+ get '/users/new'
265
+ @type =
266
+ case type
267
+ when 'datetime_local' then 'datetime-local'
268
+ when 'phone', 'fax' then 'tel'
269
+ else type end
270
+ end
271
+
272
+ it { page.should have_css "input[type='#{@type}']" }
273
+ end
274
+ end
275
+
276
+ describe 'type default by name' do
277
+ before do
278
+ app.user_form({}, :action => '/search') do
279
+ fields do
280
+ form_input :email
281
+ form_input :url
282
+ form_input :password
283
+ form_input :password_confirmation
284
+ form_input :search
285
+ form_input :query
286
+ form_input :q
287
+ form_input :phone
288
+ form_input :request_fax
289
+ end
290
+ end
291
+ get '/users/new'
292
+ end
293
+ it { page.should have_css "input#email[type='email']" }
294
+ it { page.should have_css "input#url[type='url']" }
295
+ it { page.should have_css "input#password[type='password']" }
296
+ it { page.should have_css "input#password-confirmation[type='password']" }
297
+ it { page.should have_css "input#search[type='search']" }
298
+ it { page.should have_css "input#query[type='search']" }
299
+ it { page.should have_css "input#q[type='search']" }
300
+ it { page.should have_css "input#phone[type='tel']" }
301
+ it { page.should have_css "input#request-fax[type='tel']" }
302
+ end
303
+ end
304
+
305
+ describe 'text input' do
306
+ describe 'text input with sequel reflection' do
307
+ before do
308
+ new_user.stub!(:bio).and_return('Lorem ipsum...')
309
+ app.user_form(new_user) do
310
+ fields { form_input :bio }
311
+ end
312
+ get '/users/new'
313
+ end
314
+
315
+ it { page.should have_xpath "//form/fieldset/ol/li/label[@for='user-bio']" }
316
+ it { page.should have_xpath "//form/fieldset/ol/li/textarea[@id='user-bio']" }
317
+ it { page.should_not have_css "texarea[value]" }
318
+ it { page.should have_css "textarea", :text => 'Lorem ipsum...' }
319
+ end
320
+ end
321
+
322
+ describe 'select input' do
323
+ describe 'with hash' do
324
+ before do
325
+ app.user_form({:quality => 'best'}, :action => '/search') do
326
+ fields { form_input :quality, :as => :select, :collection => {:worse => 'Worse', :best => 'Best'} }
327
+ end
328
+ get '/users/new'
329
+ end
330
+
331
+ it { page.should have_xpath "//form/fieldset/ol/li/label[@for='quality']" }
332
+ it { page.should have_xpath "//form/fieldset/ol/li/select[@id='quality']" }
333
+ it { page.should have_xpath "//form/fieldset/ol/li/select[@name='quality']" }
334
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='worse']" }
335
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='best']" }
336
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='worse']", :text => 'Worse' }
337
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='best']", :text => 'Best' }
338
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='best' and @selected='selected']" }
339
+ end
340
+
341
+ describe 'with multi array' do
342
+ before do
343
+ app.user_form({:quality => 'best'}, :action => '/search') do
344
+ fields { form_input :quality, :as => :select, :collection => [%w(worse Worse), %w(best Best)] }
345
+ end
346
+ get '/users/new'
347
+ end
348
+
349
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='worse']", :text => 'Worse' }
350
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='best']", :text => 'Best' }
351
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='best' and @selected='selected']" }
352
+ end
353
+
354
+ describe 'with array' do
355
+ before do
356
+ app.user_form({:quality => 'Best'}, :action => '/search') do
357
+ fields { form_input :quality, :as => :select, :collection => %w(Worse Best) }
358
+ end
359
+ get '/users/new'
360
+ end
361
+
362
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='Worse']", :text => 'Worse' }
363
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='Best']", :text => 'Best' }
364
+ it { page.should have_xpath "//form/fieldset/ol/li/select/option[@value='Best' and @selected='selected']" }
365
+ end
366
+ end
367
+
368
+ describe 'radio buttons' do
369
+ before do
370
+ app.user_form({:quality => 'best'}, :action => '/search') do
371
+ fields { form_input :quality, :as => :radio, :collection => {:worse => 'Worse', :best => 'Best'} }
372
+ end
373
+ get '/users/new'
374
+ end
375
+
376
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset" }
377
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/label", :text => 'Quality' }
378
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol" }
379
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li", :count => 2 }
380
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label", :count => 2 }
381
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input", :count => 2 }
382
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input[@value='worse']" }
383
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input[@value='best']" }
384
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input[@value='worse' and @id='quality-worse']" }
385
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input[@value='best']" }
386
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input[@value='best' and @id='quality-best']" }
387
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label", :text => 'Worse' }
388
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label", :text => 'Best' }
389
+ it { page.should have_xpath "//form/fieldset/ol/li/fieldset/ol/li/label/input[@value='best' and @checked='checked']" }
390
+ end
391
+ end
392
+ end
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'rspec'
3
+ require 'capybara'
4
+ require 'rack/test'
5
+ require 'rack/csrf'
6
+ require 'sqlite3'
7
+ require 'sequel'
8
+
9
+ $:.unshift File.join(File.dirname( __FILE__), '..', 'lib')
10
+ require 'erector/form_for'
11
+
12
+ DB = Sequel.sqlite
13
+ DB.create_table :users do
14
+ primary_key :id
15
+ String :name, :null => false
16
+ String :about, :fixed => true
17
+ String :any
18
+ Text :bio
19
+ Boolean :confirmed
20
+ end
21
+
22
+ class User < Sequel::Model
23
+ end
24
+
25
+ module SpecHelper
26
+ def self.included base
27
+ base.instance_eval do
28
+ let(:app) do
29
+ app = Class.new(Sinatra::Base)
30
+ app.register Sinatra::Trails
31
+ app.register Erector::FormFor
32
+ def app.user_form *args, &block
33
+ resources(:users) do
34
+ get(new_user){ form_for(*args, &block) }
35
+ end
36
+ end
37
+ app.set :environment, :test
38
+ end
39
+
40
+ let(:new_user) do
41
+ user = User.new
42
+ user.stub!(:new_record?).and_return(true)
43
+ user
44
+ end
45
+
46
+ let(:existing_user) do
47
+ user = User.new
48
+ user.stub!(:new_record?).and_return(false)
49
+ user.stub!(:to_param).and_return(1)
50
+ user
51
+ end
52
+
53
+ let(:page) do
54
+ Capybara::Node::Simple.new(last_response.body)
55
+ end
56
+ end
57
+ end
58
+ end
metadata ADDED
@@ -0,0 +1,188 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erector-form_for
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Macario
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-30 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: erector
16
+ requirement: &70307239220860 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70307239220860
25
+ - !ruby/object:Gem::Dependency
26
+ name: sinatra
27
+ requirement: &70307239220260 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70307239220260
36
+ - !ruby/object:Gem::Dependency
37
+ name: sinatra-trails
38
+ requirement: &70307239219560 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70307239219560
47
+ - !ruby/object:Gem::Dependency
48
+ name: i18n
49
+ requirement: &70307239218940 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70307239218940
58
+ - !ruby/object:Gem::Dependency
59
+ name: activesupport
60
+ requirement: &70307239218120 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '3.0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70307239218120
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: &70307239217480 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70307239217480
80
+ - !ruby/object:Gem::Dependency
81
+ name: rspec
82
+ requirement: &70307239201960 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70307239201960
91
+ - !ruby/object:Gem::Dependency
92
+ name: capybara
93
+ requirement: &70307239201400 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70307239201400
102
+ - !ruby/object:Gem::Dependency
103
+ name: rack-test
104
+ requirement: &70307239200900 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70307239200900
113
+ - !ruby/object:Gem::Dependency
114
+ name: rack_csrf
115
+ requirement: &70307239200360 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *70307239200360
124
+ - !ruby/object:Gem::Dependency
125
+ name: sequel
126
+ requirement: &70307239199860 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *70307239199860
135
+ - !ruby/object:Gem::Dependency
136
+ name: sqlite3
137
+ requirement: &70307239199380 !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ! '>='
141
+ - !ruby/object:Gem::Version
142
+ version: '0'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: *70307239199380
146
+ description: Form helper inspired by erector targeting html5
147
+ email:
148
+ - macarui@gmail.com
149
+ executables: []
150
+ extensions: []
151
+ extra_rdoc_files: []
152
+ files:
153
+ - .gitignore
154
+ - .rspec
155
+ - Gemfile
156
+ - Rakefile
157
+ - form_erector.gemspec
158
+ - lib/erector/form_for.rb
159
+ - lib/erector/form_for/version.rb
160
+ - spec/form_erector_spec.rb
161
+ - spec/spec_helper.rb
162
+ homepage: http://github.com/maca/erector-form_for
163
+ licenses: []
164
+ post_install_message:
165
+ rdoc_options: []
166
+ require_paths:
167
+ - lib
168
+ required_ruby_version: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ! '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ required_rubygems_version: !ruby/object:Gem::Requirement
175
+ none: false
176
+ requirements:
177
+ - - ! '>='
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project: erector-form_for
182
+ rubygems_version: 1.8.8
183
+ signing_key:
184
+ specification_version: 3
185
+ summary: Form helper inspired by erector targeting html5
186
+ test_files:
187
+ - spec/form_erector_spec.rb
188
+ - spec/spec_helper.rb