form_assistant 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ module RPH
2
+ module FormAssistant
3
+ # class used to DRY up error handling
4
+ class Error < RuntimeError
5
+ def self.message(msg=nil)
6
+ msg.nil? ? @message : self.message = msg
7
+ end
8
+
9
+ def self.message=(msg)
10
+ @message = msg
11
+ end
12
+ end
13
+
14
+ # custom errors go here
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ module RPH
2
+ module FormAssistant
3
+ # extensions for formatting error messages
4
+ #
5
+ # Ex: <%= errors %>
6
+ # <%= errors.to_s(:break => true) %>
7
+ # <%= errors.to_list %>
8
+ # <%= errors.to_list(:class => 'errorz') %>
9
+ class FieldErrors < Array
10
+ def to_s(options = {})
11
+ return self.join('<br />') if options[:break]
12
+ self.to_sentence
13
+ end
14
+
15
+ # converts an array into an unordered list
16
+ def to_list(options = {})
17
+ css_class = options.delete(:class) || 'errors'
18
+
19
+ list_items = self.inject("") do |items, error|
20
+ items << "<li>#{error}</li>"
21
+ end
22
+
23
+ return '<ul class="%s">%s</ul>' % [css_class, list_items]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,17 @@
1
+ module RPH
2
+ module FormAssistant
3
+ private
4
+ # used to assist generic logic throughout FormAssistant
5
+ class Rules
6
+ # used mainly for #concat() so that this plugin will
7
+ # work with versions of Rails other than edge
8
+ def self.binding_required?
9
+ !!( Rails.version < '2.2.0' )
10
+ end
11
+
12
+ def self.has_I18n_support?
13
+ !!( Rails.version > '2.2.0' )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ desc "copies basic form templates to app/views/forms"
2
+ namespace :form_assistant do
3
+ task :install do
4
+ PLUGIN_ROOT = File.join(File.dirname(__FILE__), '..')
5
+ DESTINATION = File.join(Rails.root, 'app/views', 'forms')
6
+
7
+ FileUtils.mkpath(DESTINATION) unless File.directory?(DESTINATION)
8
+ forms = Dir[File.join(PLUGIN_ROOT, 'forms/*')].select { |f| File.file?(f) }
9
+ longest_filename = forms.inject([]) { |sizes, f| sizes << f.gsub(PLUGIN_ROOT, '').length }.max
10
+
11
+ forms.each do |partial|
12
+ file_to_copy = File.join(DESTINATION, '/', File.basename(partial))
13
+ puts " - form_assistant%-#{longest_filename}s copied to %s" %
14
+ [partial.gsub(PLUGIN_ROOT, ''), DESTINATION.gsub(Rails.root, '')]
15
+ FileUtils.cp [partial], DESTINATION
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ <div class="widget">
2
+ <div class="label">
3
+ <%= label %>
4
+ </div>
5
+ <div class="tip">
6
+ <%= tip %>
7
+ </div>
8
+ <div class="element">
9
+ <%= element %>
10
+ </div>
11
+ <div class="errors">
12
+ <%= errors %>
13
+ </div>
14
+ </div>
@@ -0,0 +1,4 @@
1
+ <h2><%= legend %></h2>
2
+ <div class="fieldset">
3
+ <%= fields %>
4
+ </div>
@@ -0,0 +1,5 @@
1
+ <%= label %>
2
+ <p>
3
+ <%= element %> <span><%= tip %></span><br />
4
+ <%= errors %>
5
+ </p>
@@ -0,0 +1,14 @@
1
+ <div class="widget">
2
+ <div class="label">
3
+ <%= label %>
4
+ </div>
5
+ <div class="tip">
6
+ <%= tip %>
7
+ </div>
8
+ <div class="element">
9
+ <%= element %>
10
+ </div>
11
+ <div class="errors">
12
+ <%= errors %>
13
+ </div>
14
+ </div>
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+
11
+ require 'test/unit'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ ENV["RAILS_ENV"] ||= "test"
16
+ $:.unshift(File.join(File.dirname(__FILE__), *%w[../lib]))
17
+
18
+ require 'ostruct'
19
+ require 'active_support'
20
+ require 'action_controller'
21
+ # require 'action_controller/test_process'
22
+ # require 'action_view/test_case'
23
+ require 'active_record'
24
+
25
+ require 'mocha'
26
+ require 'mock_rails'
27
+ require 'form_assistant'
28
+
@@ -0,0 +1,27 @@
1
+ unless Object.const_defined?(:Rails)
2
+ class Rails
3
+ class << self
4
+ attr_accessor :root, :version
5
+
6
+ def root
7
+ @root ||= File.dirname(__FILE__)
8
+ end
9
+
10
+ def version
11
+ @version ||= '2.2.2'
12
+ end
13
+
14
+ def configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+ end
18
+
19
+ class Configuration
20
+ attr_accessor :view_path
21
+
22
+ def view_path
23
+ @view_path ||= ''
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ require 'helper'
2
+
3
+ class FieldErrorsTest < ActiveSupport::TestCase
4
+ def setup
5
+ @errors = RPH::FormAssistant::FieldErrors.new(%w(A B C))
6
+ end
7
+
8
+ test "should return errors as sentence" do
9
+ assert_equal 'A, B, and C', @errors.to_s
10
+ end
11
+
12
+ test "should return errors with breaks" do
13
+ assert_equal 'A<br />B<br />C', @errors.to_s(:break => true)
14
+ end
15
+
16
+ test "should return errors as list" do
17
+ assert_equal '<ul class="errors"><li>A</li><li>B</li><li>C</li></ul>',
18
+ @errors.to_list
19
+ end
20
+
21
+ test "should return errors as list with custom class" do
22
+ assert_equal '<ul class="problems"><li>A</li><li>B</li><li>C</li></ul>',
23
+ @errors.to_list(:class => 'problems')
24
+ end
25
+ end
@@ -0,0 +1,205 @@
1
+ require 'helper'
2
+
3
+ module FormAssistantHelpers
4
+ attr_accessor :render_options
5
+ attr_accessor :view
6
+ attr_accessor :response
7
+
8
+ def view
9
+ @view ||= ActionView::Base.new(Rails.configuration.view_path)
10
+ end
11
+
12
+ def render(options={})
13
+ self.render_options = options
14
+ @response = view.render(options)
15
+ end
16
+
17
+ def locals
18
+ render_options[:locals] rescue {}
19
+ end
20
+
21
+ def expect_render(expected={})
22
+ assert_hash_includes expected, render_options
23
+ end
24
+
25
+ def assert_hash_includes(expected, actual)
26
+ expected.each do |k, v|
27
+ assert_equal v, actual[k]
28
+ end
29
+ end
30
+
31
+ def expect_locals(expected={})
32
+ assert_hash_includes expected, locals
33
+ end
34
+
35
+ def template_root
36
+ RPH::FormAssistant::FormBuilder.template_root
37
+ end
38
+
39
+ def template_path(name)
40
+ File.join(template_root, name) + '.html.erb'
41
+ end
42
+ end
43
+
44
+ class AddressBook < ActiveRecord::Base
45
+ class Column
46
+ attr_accessor :name, :type
47
+ def initialize(name, type)
48
+ @name, @type = name, type
49
+ end
50
+ end
51
+
52
+ attr_accessor :first_name, :nickname,
53
+ :day, :month, :year, :is_boy,
54
+ :created_at
55
+
56
+ def self.columns
57
+ {}
58
+ end
59
+
60
+ def self.columns_hash
61
+ [ Column.new('first_name', :string),
62
+ Column.new('is_boy', :boolean),
63
+ Column.new('created_at', :datetime)
64
+ ].index_by(&:name)
65
+ end
66
+ end
67
+
68
+ class FormAssistantTest < ActionView::TestCase
69
+ include FormAssistantHelpers
70
+ include ::RPH::FormAssistant::ActionView
71
+ attr_accessor :form
72
+
73
+ def setup
74
+ Rails.configuration.view_path = File.expand_path(File.dirname(__FILE__))
75
+
76
+ @address_book = AddressBook.new
77
+ @form = RPH::FormAssistant::FormBuilder.new(:address_book, @address_book, self, {}, nil)
78
+ RPH::FormAssistant::FormBuilder.template_root = File.expand_path(File.join(File.dirname(__FILE__), 'forms'))
79
+ end
80
+
81
+ test "should use template based on input type" do
82
+ form.text_field :first_name
83
+ expect_render :partial => template_path('text_field')
84
+ end
85
+
86
+ test "should use fallback template if no specific template is found" do
87
+ form.text_field :first_name, :template => 'fancy_template_that_does_not_exist'
88
+ expect_render :partial => template_path(form.fallback_template)
89
+ end
90
+
91
+ test "should render a valid field" do
92
+ form.text_field :first_name
93
+ expect_locals :errors => nil
94
+ end
95
+
96
+ test "should render an invalid field" do
97
+ @address_book.errors.add(:first_name, 'cannot be root')
98
+ form.text_field :first_name
99
+ expect_locals :errors => ['First name cannot be root']
100
+ assert_kind_of RPH::FormAssistant::FieldErrors, locals[:errors]
101
+ end
102
+
103
+ test "should render a field with a tip" do
104
+ form.text_field :nickname, :tip => 'What should we call you?'
105
+ expect_locals :tip => 'What should we call you?'
106
+ end
107
+
108
+ test "should render a field without a template" do
109
+ result = form.text_field(:nickname, :template => false)
110
+ assert_equal text_field(:address_book, :nickname), result
111
+ end
112
+
113
+ test "should create fieldset" do
114
+ fieldset('Information') { "fields-go-here" }
115
+ expect_render :partial => template_path('fieldset')
116
+ expect_locals :legend => 'Information',
117
+ :fields => 'fields-go-here'
118
+ end
119
+
120
+ test "should support I18n if available" do
121
+ if Object.const_defined?(:I18n)
122
+ I18n.backend = I18n::Backend::Simple.new
123
+ I18n.backend.store_translations 'en', :activerecord => {
124
+ :attributes => {
125
+ :address_book => {
126
+ :first_name => 'Given name'
127
+ }
128
+ }
129
+ }
130
+
131
+ @address_book.errors.add(:first_name, 'cannot be root')
132
+ @address_book.errors.add(:first_name, 'cannot be admin')
133
+ form.text_field :first_name
134
+ expect_locals :errors => ['Given name cannot be root', 'Given name cannot be admin']
135
+ end
136
+ end
137
+
138
+ test "should massage error messages when I18n isn't not available" do
139
+ RPH::FormAssistant::Rules.expects(:has_I18n_support?).returns(false)
140
+ @address_book.errors.add(:first_name, 'cannot be root')
141
+ @address_book.errors.add(:first_name, 'cannot be admin')
142
+ form.text_field :first_name
143
+ expect_locals :errors => ['First name cannot be root', 'First name cannot be admin']
144
+ end
145
+
146
+ test "should create widget" do
147
+ @address_book.errors.add(:birthday, 'is invalid')
148
+
149
+ form.widget :birthday, :tip => 'Enter your birthday' do
150
+ concat @day = form.select(:day, (1..31))
151
+ concat @month = form.select(:month, (1..12))
152
+ concat @year = form.select(:year, (1975...1985))
153
+ end
154
+
155
+ expect_locals :element => (@day + @month + @year),
156
+ :errors => ['Birthday is invalid'],
157
+ :tip => 'Enter your birthday',
158
+ :helper => 'widget'
159
+
160
+ expect_render :partial => template_path('field')
161
+ end
162
+
163
+ test "should create widget with multiple fields" do
164
+ @address_book.errors.add(:first_name, 'cannot be root')
165
+ @address_book.errors.add(:nickname, 'cannot be batman')
166
+
167
+ form.widget([:first_name, :nickname], :label => 'Names') do
168
+ concat @first_name = form.text_field(:first_name)
169
+ concat @nickname = form.text_field(:nickname)
170
+ end
171
+
172
+ expect_locals :element => (@first_name + @nickname),
173
+ :errors => [
174
+ 'First name cannot be root',
175
+ 'Nickname cannot be batman'
176
+ ],
177
+ :helper => 'widget'
178
+
179
+ expect_render :partial => template_path('field')
180
+ end
181
+
182
+ test "should pass extra locals" do
183
+ form.text_field :first_name, :locals => { :nickname => true }
184
+ expect_locals :nickname => true
185
+ end
186
+
187
+ test 'should create proper fields with #input' do
188
+ form.expects(:text_field).with(:first_name)
189
+ form.input :first_name
190
+
191
+ form.expects(:check_box).with(:is_boy)
192
+ form.input :is_boy
193
+
194
+ form.expects(:datetime_select).with(:created_at)
195
+ form.input :created_at
196
+ end
197
+
198
+ test 'should create many fields with #inputs' do
199
+ options = { :required => true }
200
+ form.expects(:text_field).with(:first_name, options)
201
+ form.expects(:check_box).with(:is_boy, options)
202
+ form.expects(:datetime_select).with(:created_at, options)
203
+ form.inputs :first_name, :is_boy, :created_at, options
204
+ end
205
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,235 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: form_assistant
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Ryan Heath
14
+ - Chris Scharf
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-07-06 00:00:00 -04:00
20
+ default_executable:
21
+ dependencies:
22
+ - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 49
30
+ segments:
31
+ - 0
32
+ - 8
33
+ - 7
34
+ version: 0.8.7
35
+ type: :runtime
36
+ name: rake
37
+ version_requirements: *id001
38
+ - !ruby/object:Gem::Dependency
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 5
46
+ segments:
47
+ - 2
48
+ - 3
49
+ version: "2.3"
50
+ type: :development
51
+ name: activesupport
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 5
61
+ segments:
62
+ - 2
63
+ - 3
64
+ version: "2.3"
65
+ type: :development
66
+ name: actionpack
67
+ version_requirements: *id003
68
+ - !ruby/object:Gem::Dependency
69
+ prerelease: false
70
+ requirement: &id004 !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ hash: 5
76
+ segments:
77
+ - 2
78
+ - 3
79
+ version: "2.3"
80
+ type: :development
81
+ name: activerecord
82
+ version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ prerelease: false
85
+ requirement: &id005 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ hash: 31
91
+ segments:
92
+ - 3
93
+ - 12
94
+ version: "3.12"
95
+ type: :development
96
+ name: rdoc
97
+ version_requirements: *id005
98
+ - !ruby/object:Gem::Dependency
99
+ prerelease: false
100
+ requirement: &id006 !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ hash: 23
106
+ segments:
107
+ - 1
108
+ - 0
109
+ - 0
110
+ version: 1.0.0
111
+ type: :development
112
+ name: bundler
113
+ version_requirements: *id006
114
+ - !ruby/object:Gem::Dependency
115
+ prerelease: false
116
+ requirement: &id007 !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ~>
120
+ - !ruby/object:Gem::Version
121
+ hash: 63
122
+ segments:
123
+ - 1
124
+ - 8
125
+ - 4
126
+ version: 1.8.4
127
+ type: :development
128
+ name: jeweler
129
+ version_requirements: *id007
130
+ - !ruby/object:Gem::Dependency
131
+ prerelease: false
132
+ requirement: &id008 !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ hash: 3
138
+ segments:
139
+ - 0
140
+ version: "0"
141
+ type: :development
142
+ name: rcov
143
+ version_requirements: *id008
144
+ - !ruby/object:Gem::Dependency
145
+ prerelease: false
146
+ requirement: &id009 !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ type: :development
156
+ name: mocha
157
+ version_requirements: *id009
158
+ description: Custom form builder that attempts to make your forms friendly
159
+ email: scharfie@gmail.com
160
+ executables: []
161
+
162
+ extensions: []
163
+
164
+ extra_rdoc_files:
165
+ - LICENSE.txt
166
+ - README.textile
167
+ files:
168
+ - Gemfile
169
+ - Gemfile.lock
170
+ - LICENSE.txt
171
+ - README.textile
172
+ - Rakefile
173
+ - VERSION
174
+ - autotest/discover.rb
175
+ - autotest/testunit.rb
176
+ - forms/_check_box.html.erb
177
+ - forms/_field.html.erb
178
+ - forms/_fieldset.html.erb
179
+ - forms/_file_field.html.erb
180
+ - forms/_password_field.html.erb
181
+ - forms/_radio_button.html.erb
182
+ - forms/_text_area.html.erb
183
+ - forms/_text_field.html.erb
184
+ - init.rb
185
+ - install.rb
186
+ - lib/form_assistant.rb
187
+ - lib/form_assistant/error.rb
188
+ - lib/form_assistant/field_errors.rb
189
+ - lib/form_assistant/rules.rb
190
+ - tasks/form_assistant_tasks.rake
191
+ - test/forms/_field.html.erb
192
+ - test/forms/_fieldset.html.erb
193
+ - test/forms/_text_field.html.erb
194
+ - test/forms/_widget.html.erb
195
+ - test/helper.rb
196
+ - test/mock_rails.rb
197
+ - test/test_field_errors.rb
198
+ - test/test_form_assistant.rb
199
+ - uninstall.rb
200
+ has_rdoc: true
201
+ homepage: http://github.com/scharfie/form_assistant
202
+ licenses:
203
+ - MIT
204
+ post_install_message:
205
+ rdoc_options: []
206
+
207
+ require_paths:
208
+ - lib
209
+ required_ruby_version: !ruby/object:Gem::Requirement
210
+ none: false
211
+ requirements:
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ hash: 3
215
+ segments:
216
+ - 0
217
+ version: "0"
218
+ required_rubygems_version: !ruby/object:Gem::Requirement
219
+ none: false
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ hash: 3
224
+ segments:
225
+ - 0
226
+ version: "0"
227
+ requirements: []
228
+
229
+ rubyforge_project:
230
+ rubygems_version: 1.4.2
231
+ signing_key:
232
+ specification_version: 3
233
+ summary: Custom form builder that attempts to make your forms friendly
234
+ test_files: []
235
+