tmayad-formtastic 0.9.7

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.
Files changed (48) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +517 -0
  3. data/Rakefile +101 -0
  4. data/generators/form/USAGE +16 -0
  5. data/generators/form/form_generator.rb +120 -0
  6. data/generators/form/templates/view__form.html.erb +5 -0
  7. data/generators/form/templates/view__form.html.haml +4 -0
  8. data/generators/formtastic/formtastic_generator.rb +24 -0
  9. data/generators/formtastic/templates/formtastic.css +138 -0
  10. data/generators/formtastic/templates/formtastic.rb +54 -0
  11. data/generators/formtastic/templates/formtastic_changes.css +10 -0
  12. data/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +16 -0
  13. data/lib/formtastic.rb +1643 -0
  14. data/lib/formtastic/i18n.rb +32 -0
  15. data/lib/locale/en.yml +8 -0
  16. data/rails/init.rb +3 -0
  17. data/spec/buttons_spec.rb +149 -0
  18. data/spec/commit_button_spec.rb +344 -0
  19. data/spec/custom_builder_spec.rb +62 -0
  20. data/spec/custom_macros.rb +561 -0
  21. data/spec/defaults_spec.rb +20 -0
  22. data/spec/error_proc_spec.rb +27 -0
  23. data/spec/errors_spec.rb +85 -0
  24. data/spec/form_helper_spec.rb +120 -0
  25. data/spec/i18n_spec.rb +131 -0
  26. data/spec/include_blank_spec.rb +70 -0
  27. data/spec/input_spec.rb +608 -0
  28. data/spec/inputs/boolean_input_spec.rb +93 -0
  29. data/spec/inputs/check_boxes_input_spec.rb +162 -0
  30. data/spec/inputs/country_input_spec.rb +80 -0
  31. data/spec/inputs/date_input_spec.rb +45 -0
  32. data/spec/inputs/datetime_input_spec.rb +155 -0
  33. data/spec/inputs/file_input_spec.rb +33 -0
  34. data/spec/inputs/hidden_input_spec.rb +52 -0
  35. data/spec/inputs/numeric_input_spec.rb +44 -0
  36. data/spec/inputs/password_input_spec.rb +46 -0
  37. data/spec/inputs/radio_input_spec.rb +149 -0
  38. data/spec/inputs/select_input_spec.rb +459 -0
  39. data/spec/inputs/string_input_spec.rb +47 -0
  40. data/spec/inputs/text_input_spec.rb +33 -0
  41. data/spec/inputs/time_input_spec.rb +44 -0
  42. data/spec/inputs/time_zone_input_spec.rb +102 -0
  43. data/spec/inputs_spec.rb +395 -0
  44. data/spec/label_spec.rb +48 -0
  45. data/spec/semantic_fields_for_spec.rb +44 -0
  46. data/spec/spec.opts +2 -0
  47. data/spec/spec_helper.rb +212 -0
  48. metadata +169 -0
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ describe 'SemanticFormBuilder#label' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ it 'should humanize the given attribute' do
14
+ semantic_form_for(@new_post) do |builder|
15
+ builder.label(:login).should have_tag('label', :with => /Login/)
16
+ end
17
+ end
18
+
19
+ describe 'when required is given' do
20
+ it 'should append a required note' do
21
+ semantic_form_for(@new_post) do |builder|
22
+ builder.label(:login, nil, :required => true).should have_tag('label abbr')
23
+ end
24
+ end
25
+
26
+ it 'should allow require option to be given as second argument' do
27
+ semantic_form_for(@new_post) do |builder|
28
+ builder.label(:login, :required => true).should have_tag('label abbr')
29
+ end
30
+ end
31
+ end
32
+
33
+ describe 'when label is given' do
34
+ it 'should allow the text to be given as label option' do
35
+ semantic_form_for(@new_post) do |builder|
36
+ builder.label(:login, :required => true, :label => 'My label').should have_tag('label', :with => /My label/)
37
+ end
38
+ end
39
+
40
+ it 'should return nil if label is false' do
41
+ semantic_form_for(@new_post) do |builder|
42
+ builder.label(:login, :label => false).should be_blank
43
+ end
44
+ end
45
+ end
46
+
47
+ end
48
+
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ describe 'SemanticFormBuilder#semantic_fields_for' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ @new_post.stub!(:author).and_return(::Author.new)
12
+ end
13
+
14
+ it 'yields an instance of SemanticFormHelper.builder' do
15
+ semantic_form_for(@new_post) do |builder|
16
+ builder.semantic_fields_for(:author) do |nested_builder|
17
+ nested_builder.class.should == ::Formtastic::SemanticFormHelper.builder
18
+ end
19
+ end
20
+ end
21
+
22
+ it 'nests the object name' do
23
+ semantic_form_for(@new_post) do |builder|
24
+ builder.semantic_fields_for(@bob) do |nested_builder|
25
+ nested_builder.object_name.should == 'post[author]'
26
+ end
27
+ end
28
+ end
29
+
30
+ it 'should sanitize html id for li tag' do
31
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
32
+ semantic_form_for(@new_post) do |builder|
33
+ builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
34
+ concat(nested_builder.inputs(:login))
35
+ end
36
+ end
37
+ output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
38
+ # Not valid selector, so using good ol' regex
39
+ output_buffer.should_not =~ /id="post\[author\]_1_login_input"/
40
+ # <=> output_buffer.should_not have_tag('form fieldset.inputs #post[author]_1_login_input')
41
+ end
42
+
43
+ end
44
+
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=progress
@@ -0,0 +1,212 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+
4
+ def smart_require(lib_name, gem_name, gem_version = '>= 0.0.0')
5
+ begin
6
+ require lib_name if lib_name
7
+ rescue LoadError
8
+ if gem_name
9
+ gem gem_name, gem_version
10
+ require lib_name if lib_name
11
+ end
12
+ end
13
+ end
14
+
15
+ smart_require 'spec', 'spec', '>= 1.2.6'
16
+ smart_require false, 'rspec-rails', '>= 1.2.6'
17
+ smart_require 'hpricot', 'hpricot', '>= 0.6.1'
18
+ smart_require 'rspec_tag_matchers', 'rspec_tag_matchers', '>= 1.0.0'
19
+ smart_require 'active_support', 'activesupport', '>= 2.3.4'
20
+ smart_require 'action_controller', 'actionpack', '>= 2.3.4'
21
+ smart_require 'action_view', 'actionpack', '>= 2.3.4'
22
+
23
+ require 'custom_macros'
24
+
25
+ Spec::Runner.configure do |config|
26
+ config.include(RspecTagMatchers)
27
+ config.include(CustomMacros)
28
+ end
29
+
30
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic'))
31
+
32
+
33
+ module FormtasticSpecHelper
34
+ include ActionView::Helpers::FormHelper
35
+ include ActionView::Helpers::FormTagHelper
36
+ include ActionView::Helpers::FormOptionsHelper
37
+ include ActionView::Helpers::UrlHelper
38
+ include ActionView::Helpers::TagHelper
39
+ include ActionView::Helpers::TextHelper
40
+ include ActionView::Helpers::ActiveRecordHelper
41
+ include ActionView::Helpers::RecordIdentificationHelper
42
+ include ActionView::Helpers::DateHelper
43
+ include ActionView::Helpers::CaptureHelper
44
+ include ActiveSupport
45
+ include ActionController::PolymorphicRoutes
46
+
47
+ include Formtastic::SemanticFormHelper
48
+
49
+ def default_input_type(column_type, column_name = :generic_column_name)
50
+ @new_post.stub!(column_name)
51
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type)) unless column_type.nil?
52
+
53
+ semantic_form_for(@new_post) do |builder|
54
+ @default_type = builder.send(:default_input_type, column_name)
55
+ end
56
+
57
+ return @default_type
58
+ end
59
+
60
+ class ::Post
61
+ def id
62
+ end
63
+ end
64
+ class ::Author
65
+ def to_label
66
+ end
67
+ end
68
+ class ::Continent
69
+ end
70
+
71
+ def mock_everything
72
+
73
+ # Resource-oriented styles like form_for(@post) will expect a path method for the object,
74
+ # so we're defining some here.
75
+ def post_path(o); "/posts/1"; end
76
+ def posts_path; "/posts"; end
77
+ def new_post_path; "/posts/new"; end
78
+
79
+ def author_path(o); "/authors/1"; end
80
+ def authors_path; "/authors"; end
81
+ def new_author_path; "/authors/new"; end
82
+
83
+ @fred = mock('user')
84
+ @fred.stub!(:class).and_return(::Author)
85
+ @fred.stub!(:to_label).and_return('Fred Smith')
86
+ @fred.stub!(:login).and_return('fred_smith')
87
+ @fred.stub!(:id).and_return(37)
88
+ @fred.stub!(:new_record?).and_return(false)
89
+ @fred.stub!(:errors).and_return(mock('errors', :[] => nil))
90
+
91
+ @bob = mock('user')
92
+ @bob.stub!(:class).and_return(::Author)
93
+ @bob.stub!(:to_label).and_return('Bob Rock')
94
+ @bob.stub!(:login).and_return('bob')
95
+ @bob.stub!(:created_at)
96
+ @bob.stub!(:id).and_return(42)
97
+ @bob.stub!(:posts).and_return([])
98
+ @bob.stub!(:post_ids).and_return([])
99
+ @bob.stub!(:new_record?).and_return(false)
100
+ @bob.stub!(:errors).and_return(mock('errors', :[] => nil))
101
+
102
+ @james = mock('user')
103
+ @james.stub!(:class).and_return(::Author)
104
+ @james.stub!(:to_label).and_return('James Shock')
105
+ @james.stub!(:login).and_return('james')
106
+ @james.stub!(:id).and_return(75)
107
+ @james.stub!(:posts).and_return([])
108
+ @james.stub!(:post_ids).and_return([])
109
+ @james.stub!(:new_record?).and_return(false)
110
+ @james.stub!(:errors).and_return(mock('errors', :[] => nil))
111
+
112
+
113
+ ::Author.stub!(:find).and_return([@fred, @bob])
114
+ ::Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
115
+ ::Author.stub!(:human_name).and_return('::Author')
116
+ ::Author.stub!(:reflect_on_validations_for).and_return([])
117
+ ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
118
+ ::Author.stub!(:content_columns).and_return([mock('column', :name => 'login'), mock('column', :name => 'created_at')])
119
+
120
+ # Sometimes we need a mock @post object and some Authors for belongs_to
121
+ @new_post = mock('post')
122
+ @new_post.stub!(:class).and_return(::Post)
123
+ @new_post.stub!(:id).and_return(nil)
124
+ @new_post.stub!(:new_record?).and_return(true)
125
+ @new_post.stub!(:errors).and_return(mock('errors', :[] => nil))
126
+ @new_post.stub!(:author).and_return(nil)
127
+ @new_post.stub!(:main_post).and_return(nil)
128
+ @new_post.stub!(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
129
+
130
+ @freds_post = mock('post')
131
+ @freds_post.stub!(:class).and_return(::Post)
132
+ @freds_post.stub!(:to_label).and_return('Fred Smith')
133
+ @freds_post.stub!(:id).and_return(19)
134
+ @freds_post.stub!(:author).and_return(@fred)
135
+ @freds_post.stub!(:author_id).and_return(@fred.id)
136
+ @freds_post.stub!(:authors).and_return([@fred])
137
+ @freds_post.stub!(:author_ids).and_return([@fred.id])
138
+ @freds_post.stub!(:new_record?).and_return(false)
139
+ @freds_post.stub!(:errors).and_return(mock('errors', :[] => nil))
140
+ @fred.stub!(:posts).and_return([@freds_post])
141
+ @fred.stub!(:post_ids).and_return([@freds_post.id])
142
+
143
+ ::Post.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
144
+ ::Post.stub!(:human_name).and_return('Post')
145
+ ::Post.stub!(:reflect_on_all_validations).and_return([])
146
+ ::Post.stub!(:reflect_on_validations_for).and_return([])
147
+ ::Post.stub!(:reflect_on_association).and_return do |column_name|
148
+ case column_name
149
+ when :author, :author_status
150
+ mock = mock('reflection', :options => {}, :klass => ::Author, :macro => :belongs_to)
151
+ mock.stub!(:[]).with(:class_name).and_return("Author")
152
+ mock
153
+ when :authors
154
+ mock('reflection', :options => {}, :klass => ::Author, :macro => :has_and_belongs_to_many)
155
+ when :sub_posts
156
+ mock('reflection', :options => {}, :klass => ::Post, :macro => :has_many)
157
+ when :main_post
158
+ mock('reflection', :options => {}, :klass => ::Post, :macro => :belongs_to)
159
+ end
160
+
161
+ end
162
+ ::Post.stub!(:find).and_return([@freds_post])
163
+ ::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
164
+
165
+ @new_post.stub!(:title)
166
+ @new_post.stub!(:body)
167
+ @new_post.stub!(:published)
168
+ @new_post.stub!(:publish_at)
169
+ @new_post.stub!(:created_at)
170
+ @new_post.stub!(:secret)
171
+ @new_post.stub!(:time_zone)
172
+ @new_post.stub!(:category_name)
173
+ @new_post.stub!(:allow_comments)
174
+ @new_post.stub!(:column_for_attribute).with(:meta_description).and_return(mock('column', :type => :string, :limit => 255))
175
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 50))
176
+ @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
177
+ @new_post.stub!(:column_for_attribute).with(:published).and_return(mock('column', :type => :boolean))
178
+ @new_post.stub!(:column_for_attribute).with(:publish_at).and_return(mock('column', :type => :date))
179
+ @new_post.stub!(:column_for_attribute).with(:time_zone).and_return(mock('column', :type => :string))
180
+ @new_post.stub!(:column_for_attribute).with(:allow_comments).and_return(mock('column', :type => :boolean))
181
+
182
+ @new_post.stub!(:author).and_return(@bob)
183
+ @new_post.stub!(:author_id).and_return(@bob.id)
184
+
185
+ @new_post.should_receive(:publish_at=).any_number_of_times
186
+ @new_post.should_receive(:title=).any_number_of_times
187
+ @new_post.stub!(:main_post_id).and_return(nil)
188
+
189
+ end
190
+
191
+ def self.included(base)
192
+ base.class_eval do
193
+
194
+ attr_accessor :output_buffer
195
+
196
+ def protect_against_forgery?
197
+ false
198
+ end
199
+
200
+ end
201
+ end
202
+
203
+ def with_config(config_method_name, value, &block)
204
+ old_value = ::Formtastic::SemanticFormBuilder.send(config_method_name)
205
+ ::Formtastic::SemanticFormBuilder.send(:"#{config_method_name}=", value)
206
+ yield
207
+ ::Formtastic::SemanticFormBuilder.send(:"#{config_method_name}=", old_value)
208
+ end
209
+
210
+ end
211
+
212
+ ::ActiveSupport::Deprecation.silenced = false
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tmayad-formtastic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.7
5
+ platform: ruby
6
+ authors:
7
+ - TMaYaD
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-04 00:00:00 +05:30
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.3.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: actionpack
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.3.0
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec-rails
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 1.2.6
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: rspec_tag_matchers
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.0
54
+ version:
55
+ description: A Rails form builder plugin/gem with semantically rich and accessible markup
56
+ email: tmayad+formtastic@gmail.com
57
+ executables: []
58
+
59
+ extensions: []
60
+
61
+ extra_rdoc_files:
62
+ - README.textile
63
+ files:
64
+ - MIT-LICENSE
65
+ - README.textile
66
+ - Rakefile
67
+ - generators/form/USAGE
68
+ - generators/form/form_generator.rb
69
+ - generators/form/templates/view__form.html.erb
70
+ - generators/form/templates/view__form.html.haml
71
+ - generators/formtastic/formtastic_generator.rb
72
+ - generators/formtastic/templates/formtastic.css
73
+ - generators/formtastic/templates/formtastic.rb
74
+ - generators/formtastic/templates/formtastic_changes.css
75
+ - generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb
76
+ - lib/formtastic.rb
77
+ - lib/formtastic/i18n.rb
78
+ - lib/locale/en.yml
79
+ - rails/init.rb
80
+ - spec/buttons_spec.rb
81
+ - spec/commit_button_spec.rb
82
+ - spec/custom_builder_spec.rb
83
+ - spec/custom_macros.rb
84
+ - spec/defaults_spec.rb
85
+ - spec/error_proc_spec.rb
86
+ - spec/errors_spec.rb
87
+ - spec/form_helper_spec.rb
88
+ - spec/i18n_spec.rb
89
+ - spec/include_blank_spec.rb
90
+ - spec/input_spec.rb
91
+ - spec/inputs/boolean_input_spec.rb
92
+ - spec/inputs/check_boxes_input_spec.rb
93
+ - spec/inputs/country_input_spec.rb
94
+ - spec/inputs/date_input_spec.rb
95
+ - spec/inputs/datetime_input_spec.rb
96
+ - spec/inputs/file_input_spec.rb
97
+ - spec/inputs/hidden_input_spec.rb
98
+ - spec/inputs/numeric_input_spec.rb
99
+ - spec/inputs/password_input_spec.rb
100
+ - spec/inputs/radio_input_spec.rb
101
+ - spec/inputs/select_input_spec.rb
102
+ - spec/inputs/string_input_spec.rb
103
+ - spec/inputs/text_input_spec.rb
104
+ - spec/inputs/time_input_spec.rb
105
+ - spec/inputs/time_zone_input_spec.rb
106
+ - spec/inputs_spec.rb
107
+ - spec/label_spec.rb
108
+ - spec/semantic_fields_for_spec.rb
109
+ - spec/spec.opts
110
+ - spec/spec_helper.rb
111
+ has_rdoc: true
112
+ homepage: http://github.com/tmayad/formtastic/tree/master
113
+ licenses: []
114
+
115
+ post_install_message: "\n ========================================================================\n Thanks for installing Formtastic!\n ------------------------------------------------------------------------\n You can now (optionally) run the generator to copy some stylesheets and\n a config initializer into your application:\n ./script/generate formtastic\n\n To generate some semantic form markup for your exisiting models, just run:\n ./script/generate form MODEL_NAME\n\n Find out more and get involved:\n http://github.com/justinfrench/formtastic\n http://groups.google.com.au/group/formtastic\n ========================================================================\n "
116
+ rdoc_options:
117
+ - --charset=UTF-8
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: "0"
125
+ version:
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: "0"
131
+ version:
132
+ requirements: []
133
+
134
+ rubyforge_project:
135
+ rubygems_version: 1.3.5
136
+ signing_key:
137
+ specification_version: 3
138
+ summary: A Rails form builder plugin/gem with semantically rich and accessible markup
139
+ test_files:
140
+ - spec/buttons_spec.rb
141
+ - spec/commit_button_spec.rb
142
+ - spec/custom_builder_spec.rb
143
+ - spec/custom_macros.rb
144
+ - spec/defaults_spec.rb
145
+ - spec/error_proc_spec.rb
146
+ - spec/errors_spec.rb
147
+ - spec/form_helper_spec.rb
148
+ - spec/i18n_spec.rb
149
+ - spec/include_blank_spec.rb
150
+ - spec/input_spec.rb
151
+ - spec/inputs/boolean_input_spec.rb
152
+ - spec/inputs/check_boxes_input_spec.rb
153
+ - spec/inputs/country_input_spec.rb
154
+ - spec/inputs/date_input_spec.rb
155
+ - spec/inputs/datetime_input_spec.rb
156
+ - spec/inputs/file_input_spec.rb
157
+ - spec/inputs/hidden_input_spec.rb
158
+ - spec/inputs/numeric_input_spec.rb
159
+ - spec/inputs/password_input_spec.rb
160
+ - spec/inputs/radio_input_spec.rb
161
+ - spec/inputs/select_input_spec.rb
162
+ - spec/inputs/string_input_spec.rb
163
+ - spec/inputs/text_input_spec.rb
164
+ - spec/inputs/time_input_spec.rb
165
+ - spec/inputs/time_zone_input_spec.rb
166
+ - spec/inputs_spec.rb
167
+ - spec/label_spec.rb
168
+ - spec/semantic_fields_for_spec.rb
169
+ - spec/spec_helper.rb