visionmedia-dm-forms 0.0.2 → 0.0.3

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.
@@ -1,9 +1,6 @@
1
1
 
2
2
  module DataMapper
3
3
  module Form
4
- module VERSION #:nodoc:
5
- MAJOR, MINOR, TINY = [0, 0, 2]
6
- STRING = [MAJOR, MINOR, TINY].join '.'
7
- end
4
+ VERSION = '0.0.3'
8
5
  end
9
6
  end
@@ -0,0 +1,186 @@
1
+
2
+ def params
3
+ Hash.new { |h, k| k }
4
+ end
5
+ public :params
6
+
7
+ describe DataMapper::Form::Helpers do
8
+
9
+ include DataMapper::Form::Helpers
10
+
11
+ describe "#new_form_context" do
12
+ it "should create a new context each time its called" do
13
+ a = new_form_context
14
+ b = new_form_context
15
+ a.should be_a(DataMapper::Form::Base)
16
+ b.should be_a(DataMapper::Form::Base)
17
+ a.should_not == b
18
+ end
19
+ end
20
+
21
+ describe "#form_context" do
22
+ it "should utilize the previous context or create a new one when not present" do
23
+ a = form_context
24
+ b = form_context
25
+ a.should be_a(DataMapper::Form::Base)
26
+ b.should be_a(DataMapper::Form::Base)
27
+ a.should == b
28
+ end
29
+ end
30
+
31
+ %w( textfield submit file button hidden password radio checkbox ).each do |type|
32
+ describe "##{type}" do
33
+ it "should create an unbound #{type}" do
34
+ send(type, :name => 'foo').should have_tag("input[@type=#{type}]")
35
+ end
36
+ end
37
+ end
38
+
39
+ %w( textfield radio checkbox ).each do |type|
40
+ describe "##{type}" do
41
+ it "should use origin #params method to grab the default value when present" do
42
+ send(type, :name => 'foo').should have_tag("input[@type=#{type}]") do |tag|
43
+ tag.attributes['value'].should == 'foo'
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "#textarea" do
50
+ it "should default its contents using origin #params" do
51
+ textarea(:name => 'comments').should have_tag('textarea[@name=comments]', 'comments')
52
+ end
53
+
54
+ it "should allow contents to be passed as a first argument" do
55
+ def params; {} end
56
+ textarea('Whatever', :name => 'comments').should have_tag('textarea[@name=comments]', 'Whatever')
57
+ end
58
+ end
59
+
60
+ describe "#form" do
61
+ it "should create a form, defaulting method to post" do
62
+ markup = form :action => '/login' do
63
+ textfield :name => 'name'
64
+ textfield :name => 'pass'
65
+ submit 'Login', :name => 'op'
66
+ end
67
+ markup.should have_tag('form[@action=/login]') do |form|
68
+ form.attributes['method'].should == 'post'
69
+ form.should have_tag('input[@name=name]')
70
+ form.should have_tag('input[@name=pass]')
71
+ form.should have_tag('input[@name=op]')
72
+ end
73
+ end
74
+
75
+ it "should create a form with get method" do
76
+ markup = form :action => '/login', :method => :get do
77
+ end
78
+ markup.should have_tag('form[@method=get]')
79
+ end
80
+
81
+ it "should use multipart encoding when multipart is set" do
82
+ markup = form :action => '/login', :multipart => true do
83
+ end
84
+ markup.should have_tag('form[@enctype=multipart/form-data]')
85
+ end
86
+
87
+ it "should use multipart encoding a file field is present" do
88
+ markup = form :action => '/login' do
89
+ file :name => 'image'
90
+ end
91
+ markup.should have_tag('form[@enctype=multipart/form-data]')
92
+ markup.should_not have_tag('input[@type=hidden]')
93
+ end
94
+
95
+ it "should create a hidden input with _method when anything but get or post" do
96
+ markup = form :method => :put do
97
+ file :name => 'image'
98
+ end
99
+ markup.should have_tag('form[@method=post]')
100
+ markup.should have_tag('input[@type=hidden]') do |input|
101
+ input.attributes['name'].should == '_method'
102
+ input.attributes['value'].should == 'put'
103
+ end
104
+ end
105
+
106
+ it "should create a form using yeild syntax" do
107
+ markup = form :action => '/login' do |f|
108
+ f.textfield :name => 'name'
109
+ f.textfield :name => 'pass'
110
+ f.submit 'Login'
111
+ end
112
+ markup.should have_tag('form[@action=/login]') do |form|
113
+ form.should have_tag('input[@name=name]')
114
+ form.should have_tag('input[@name=pass]')
115
+ form.should have_tag('input[@name=submit]')
116
+ end
117
+ end
118
+ end
119
+
120
+ describe "#fieldset" do
121
+ it "should create a fieldset with optional legend" do
122
+ markup = fieldset :legend => 'User Details' do
123
+ textfield :name => 'name'
124
+ textfield :name => 'email'
125
+ end
126
+ markup.should have_tag('fieldset') do |fieldset|
127
+ fieldset.should have_tag('legend', 'User Details')
128
+ fieldset.should have_tag('input[@name=name]')
129
+ fieldset.should have_tag('input[@name=email]')
130
+ end
131
+ end
132
+ end
133
+
134
+ describe "#submit" do
135
+ it "should default value to Submit, and name to submit" do
136
+ submit.should have_tag('input[@name=submit]')
137
+ submit.should have_tag('input[@value=Submit]')
138
+ end
139
+
140
+ it "should allow the first arg to be a value string" do
141
+ submit('Login').should have_tag('input[@value=Login]')
142
+ end
143
+ end
144
+
145
+ describe "#select" do
146
+ before :each do
147
+ @days = {
148
+ 1 => 'Mon',
149
+ 2 => 'Tue',
150
+ 3 => 'Wed',
151
+ 4 => 'Thu',
152
+ 5 => 'Fri',
153
+ 6 => 'Sat',
154
+ 7 => 'Sun',
155
+ }
156
+ end
157
+
158
+ it "should populate options" do
159
+ select(:name => 'days', :options => @days).should have_tag('select[@name=days]') do |select|
160
+ @days.each do |value, contents|
161
+ select.should have_tag("option[@value=#{value}]", contents)
162
+ end
163
+ end
164
+ end
165
+
166
+ it "should allow setting of the selected option" do
167
+ select(:name => 'days', :options => @days, :selected => 2).should have_tag('select[@name=days]') do |select|
168
+ select.should have_tag('option[@selected=selected]', 'Tue')
169
+ end
170
+ end
171
+
172
+ it "should allow a prompt option, defaulting it to selected" do
173
+ select(:name => 'days', :options => @days, :prompt => 'Select day').should have_tag('select[@name=days]') do |select|
174
+ select.should have_tag('option[@selected=selected]', 'Select day')
175
+ end
176
+ end
177
+
178
+ it "should allow a prompt option, but allowing selection of other options" do
179
+ select(:name => 'days', :options => @days, :prompt => 'Select day', :selected => 7).should have_tag('select[@name=days]') do |select|
180
+ select.should have_tag('option[@selected=selected]', 'Sun')
181
+ select.should have_tag('option:not(selected)', 'Select day')
182
+ end
183
+ end
184
+ end
185
+
186
+ end
@@ -0,0 +1,19 @@
1
+
2
+ describe DataMapper::Form::Descriptions do
3
+
4
+ include DataMapper::Form::Helpers
5
+ DataMapper::Form::Base.send :include, DataMapper::Form::Descriptions
6
+
7
+ it "should create elements like normal when descriptions are not utilized" do
8
+ markup = textfield :name => 'email'
9
+ markup.should have_tag('input[@type=textfield]')
10
+ markup.should_not have_tag('span[@class=description]')
11
+ end
12
+
13
+ it "should create elements with descriptions" do
14
+ markup = textfield :name => 'email', :description => 'Please enter a valid email.'
15
+ markup.should have_tag('input[@type=textfield]')
16
+ markup.should have_tag('span[@class=description]')
17
+ end
18
+
19
+ end
@@ -0,0 +1,19 @@
1
+
2
+ describe DataMapper::Form::Labels do
3
+
4
+ include DataMapper::Form::Helpers
5
+ DataMapper::Form::Base.send :include, DataMapper::Form::Labels
6
+
7
+ it "should create elements like normal when labels are not utilized" do
8
+ markup = textfield :name => 'email'
9
+ markup.should have_tag('input[@type=textfield]')
10
+ markup.should_not have_tag('label')
11
+ end
12
+
13
+ it "should create elements with labels" do
14
+ markup = textfield :name => 'email', :label => 'Email'
15
+ markup.should have_tag('input[@type=textfield]')
16
+ markup.should have_tag('label[@for=email]', 'Email')
17
+ end
18
+
19
+ end
@@ -0,0 +1,21 @@
1
+
2
+ describe DataMapper::Form::Wrappers do
3
+
4
+ include DataMapper::Form::Helpers
5
+ DataMapper::Form::Base.send :include, DataMapper::Form::Wrappers
6
+
7
+ it "should create wrappers around elements for styling" do
8
+ markup = textarea :name => 'comments'
9
+ markup.should have_tag('div[@class=form-textarea form-comments]') do |div|
10
+ div.should have_tag('textarea')
11
+ end
12
+ end
13
+
14
+ it "should create wrappers around elements for styling, prioritizing :type for the class" do
15
+ markup = textfield :name => 'email'
16
+ markup.should have_tag('div[@class=form-textfield form-email]') do |div|
17
+ div.should have_tag('input[@type=textfield]')
18
+ end
19
+ end
20
+
21
+ end
@@ -1,49 +1,41 @@
1
1
 
2
2
  describe DataMapper::Form::Tag do
3
3
 
4
- Tag = DataMapper::Form::Tag
5
-
6
- it "should generate classes" do
7
- tag = Tag.new :input, :attributes => { :name => 'email', :type => :textfield }
8
- tag.send(:classes).should == 'form-textfield form-email'
9
- end
10
-
11
- it "should generate classes when no name is present" do
12
- tag = Tag.new :input, :attributes => { :type => :textfield }
13
- tag.send(:classes).should == 'form-textfield'
14
- end
4
+ include DataMapper::Form::Tag
15
5
 
16
- it "should auto-assign boolean attributes" do
17
- tag = Tag.new :input, :attributes => { :name => 'email', :type => :textfield, :disabled => true }
18
- tag.render.should == %(<input disabled="disabled" type="textfield" class="form-textfield form-email" name="email"></input>\n)
19
- end
6
+ describe "#tag" do
7
+ it "should create a simple tag" do
8
+ tag(:div).should have_tag('div')
9
+ end
20
10
 
21
- it "should generate and merge classes" do
22
- tag = Tag.new :input, :attributes => { :class => 'foo bar', :name => 'email', :type => :textfield }
23
- tag.send(:classes).should == 'foo bar form-textfield form-email'
24
- end
25
-
26
- it "should grab inner html for non self-closing tags" do
27
- tag = Tag.new :textarea, :self_closing => false, :attributes => { :value => 'BOOYAH' }
28
- tag.inner_html.should == 'BOOYAH'
29
- end
30
-
31
- it "should allow descriptions and remove from attributes" do
32
- tag = Tag.new :input, :attributes => { :description => 'testing one two three' }
33
- tag.description.should == %(\n<p class="description">testing one two three</p>)
34
- tag.attributes.has_key?(:description).should be_false
35
- end
36
-
37
- it "should allow capturing of elements via block" do
38
- tag = Tag.new :fieldset, :attributes => { :id => 'something' } do |f|
39
- f.button :one
40
- f.button :two
11
+ it "should create a tag with attributes" do
12
+ tag(:div, :id => 'foo').should have_tag('div#foo')
13
+ end
14
+
15
+ it "should create a tag with param contents" do
16
+ tag(:div, 'bar', :id => 'foo').should have_tag('div#foo', 'bar')
17
+ end
18
+
19
+ it "should create a tag with block contents" do
20
+ tag :div, :id => 'foo' do
21
+ 'bar'
22
+ end.
23
+ should have_tag('div#foo', 'bar')
41
24
  end
42
- tag.render.should == <<-HTML.deindent
43
- <fieldset id="something"><input type="button" class="form-button form-one" name="one" />
44
- <input type="button" class="form-button form-two" name="two" />
45
- </fieldset>
46
- HTML
47
- end
48
25
 
26
+ it "should mirror boolean attributes" do
27
+ tag(:option, :selected => true).should have_tag("option[@selected=selected]")
28
+ tag(:option, :selected => 'true').should have_tag("option[@selected=selected]")
29
+ tag(:option, :selected => '1').should have_tag("option[@selected=selected]")
30
+ tag(:option, :selected => 'selected').should have_tag("option[@selected=selected]")
31
+ end
32
+
33
+ it "should negate boolean attributes" do
34
+ tag(:option, :selected => false).should have_tag("option:not([@selected=selected])")
35
+ tag(:option, :selected => '').should have_tag("option:not([@selected=selected])")
36
+ tag(:option, :selected => '0').should have_tag("option:not([@selected=selected])")
37
+ tag(:option, :selected => 'false').should have_tag("option:not([@selected=selected])")
38
+ end
39
+ end
40
+
49
41
  end
@@ -2,69 +2,97 @@
2
2
  require 'dm-core'
3
3
  require 'dm-validations'
4
4
 
5
- include DataMapper::Form::ModelElements
6
-
7
5
  DataMapper.setup :default, 'sqlite3::memory:'
8
6
 
9
7
  class User
10
8
  include DataMapper::Resource
11
- property :id, Serial
12
- property :name, String, :format => /^[\w]+$/
13
- property :email, String, :format => :email_address
9
+ property :id, Serial
10
+ property :name, String, :format => /^[\w]+$/
11
+ property :email, String, :format => :email_address
12
+ property :signature, Text, :nullable => true, :lazy => false
13
+ end
14
+
15
+ class User::Role
16
+ include DataMapper::Resource
17
+ property :id, Serial
18
+ property :name, String
14
19
  end
15
20
 
16
21
  DataMapper.auto_migrate!
17
22
 
18
- describe DataMapper::Form::ModelElements do
23
+ describe DataMapper::Form::Helpers do
24
+
25
+ include DataMapper::Form::Helpers
19
26
 
20
27
  before :each do
21
- @user = User.new :name => 'invalid username', :email => 'is_valid@email.com'
28
+ @valid_user = User.new :name => 'foo bar', :email => 'is-valid@email.com', :signature => 'i like cookies'
29
+ @invalid_user = User.new :name => 'foobar', :email => 'is-valid@email.com', :signature => 'i like cookies'
30
+ @admin_role = User::Role.new :name => 'admin'
31
+ end
32
+
33
+ describe "#new_form_context" do
34
+ it "should generate a name used for prefixing form element names" do
35
+ new_form_context(@admin_role, self).name.should == 'role'
36
+ end
37
+ end
38
+
39
+ describe "#form_for" do
40
+ it "should create a form in context to a model" do
41
+ markup = form_for @valid_user do
42
+ textfield :name, :id => 'username'
43
+ password :pass, :id => 'password'
44
+ end
45
+ markup.should have_tag('form') do |form|
46
+ form.should have_tag('input[@name=user[name]]') { |name| name.attributes['value'].should == 'foo bar' }
47
+ form.should have_tag('input[@name=user[pass]]')
48
+ end
49
+ end
22
50
  end
23
51
 
24
- it "should create a list of errors when a model is invalid" do
25
- errors_for(@user).should == <<-HTML.deindent
26
- <ul class="messages error">
27
- <li>Name has an invalid format</li>
28
- </ul>
29
- HTML
30
- @user.email = 'invalid email@ something.com'
31
- errors_for(@user).should == <<-HTML.deindent
32
- <ul class="messages error">
33
- <li>Name has an invalid format</li>
34
- <li>Email has an invalid format</li>
35
- </ul>
36
- HTML
52
+ describe "#fields_for" do
53
+ it "should create a temporary context within a form" do
54
+ markup = form_for @valid_user do
55
+ textfield :name, :id => 'username'
56
+ fields_for @admin_role do
57
+ textfield :name, :id => 'role-name'
58
+ end
59
+ password :pass, :id => 'password'
60
+ end
61
+ markup.should have_tag('form') do |form|
62
+ form.should have_tag('input[@name=user[name]]') { |name| name.attributes['value'].should == 'foo bar' }
63
+ form.should have_tag('input[@name=user[pass]]')
64
+ form.should have_tag('input[@name=role[name]]')
65
+ end
66
+ end
37
67
  end
38
68
 
39
- it "should create model specific forms with errors on elements" do
40
- results = form_for @user do |f|
41
- f.textfield :name
42
- f.textfield :email
43
- f.submit :op, :value => 'Save'
69
+ describe "#fieldset_for" do
70
+ it "should create a fieldset in context to a model" do
71
+ markup = form_for @valid_user do
72
+ textfield :name, :id => 'username'
73
+ fieldset_for @admin_role, :legend => 'Role' do
74
+ textfield :name, :id => 'role-name'
75
+ end
76
+ password :pass, :id => 'password'
77
+ end
78
+ markup.should have_tag('form') do |form|
79
+ form.should have_tag('input[@name=user[name]]') { |name| name.attributes['value'].should == 'foo bar' }
80
+ form.should have_tag('input[@name=user[pass]]')
81
+ form.should have_tag('fieldset') do |fieldset|
82
+ fieldset.should have_tag('legend', 'Role')
83
+ fieldset.should have_tag('input[@name=role[name]]')
84
+ end
85
+ end
44
86
  end
45
- results.should == <<-HTML.deindent
46
- <form method="post" id="form-user"><input type="textfield" class="error form-textfield form-name" name="name" />
47
- <input type="textfield" class="form-textfield form-email" name="email" />
48
- <input type="submit" class="form-submit form-op" value="Save" name="op" />
49
- </form>
50
- HTML
51
87
  end
52
88
 
53
- it "should use _method put for updating records" do
54
- @user.name = 'tj'
55
- @user.save
56
- results = form_for @user, :action => '/register' do |f|
57
- f.textfield :name
58
- f.textfield :email
59
- f.submit :op, :value => 'Save'
89
+ describe "#textarea" do
90
+ it "should default its contents using the models method" do
91
+ markup = fields_for @valid_user do
92
+ textarea :signature
93
+ end
94
+ markup.should have_tag('textarea[@name=user[signature]]', 'i like cookies')
60
95
  end
61
- results.should == <<-HTML.deindent
62
- <form method="post" action="/register" id="form-user"><input type="hidden" value="put" name="_method" />
63
- <input type="textfield" class="form-textfield form-name" name="name" />
64
- <input type="textfield" class="form-textfield form-email" name="email" />
65
- <input type="submit" class="form-submit form-op" value="Save" name="op" />
66
- </form>
67
- HTML
68
96
  end
69
97
 
70
98
  end