erector-form_for 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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