techthumb-formtastic 1.rails3.sha

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 (58) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +584 -0
  3. data/Rakefile +127 -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 +131 -0
  10. data/generators/formtastic/templates/formtastic.rb +54 -0
  11. data/generators/formtastic/templates/formtastic_changes.css +14 -0
  12. data/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +16 -0
  13. data/init.rb +5 -0
  14. data/lib/formtastic/i18n.rb +35 -0
  15. data/lib/formtastic/layout_helper.rb +10 -0
  16. data/lib/formtastic/railtie.rb +12 -0
  17. data/lib/formtastic/util.rb +36 -0
  18. data/lib/formtastic.rb +1870 -0
  19. data/lib/generators/formtastic/form/form_generator.rb +86 -0
  20. data/lib/generators/formtastic/install/install_generator.rb +24 -0
  21. data/lib/locale/en.yml +8 -0
  22. data/rails/init.rb +2 -0
  23. data/spec/buttons_spec.rb +166 -0
  24. data/spec/commit_button_spec.rb +401 -0
  25. data/spec/custom_builder_spec.rb +98 -0
  26. data/spec/defaults_spec.rb +20 -0
  27. data/spec/error_proc_spec.rb +27 -0
  28. data/spec/errors_spec.rb +105 -0
  29. data/spec/form_helper_spec.rb +142 -0
  30. data/spec/helpers/layout_helper_spec.rb +21 -0
  31. data/spec/i18n_spec.rb +152 -0
  32. data/spec/include_blank_spec.rb +74 -0
  33. data/spec/input_spec.rb +786 -0
  34. data/spec/inputs/boolean_input_spec.rb +104 -0
  35. data/spec/inputs/check_boxes_input_spec.rb +426 -0
  36. data/spec/inputs/country_input_spec.rb +118 -0
  37. data/spec/inputs/date_input_spec.rb +168 -0
  38. data/spec/inputs/datetime_input_spec.rb +310 -0
  39. data/spec/inputs/file_input_spec.rb +34 -0
  40. data/spec/inputs/hidden_input_spec.rb +78 -0
  41. data/spec/inputs/numeric_input_spec.rb +44 -0
  42. data/spec/inputs/password_input_spec.rb +46 -0
  43. data/spec/inputs/radio_input_spec.rb +243 -0
  44. data/spec/inputs/select_input_spec.rb +546 -0
  45. data/spec/inputs/string_input_spec.rb +64 -0
  46. data/spec/inputs/text_input_spec.rb +34 -0
  47. data/spec/inputs/time_input_spec.rb +206 -0
  48. data/spec/inputs/time_zone_input_spec.rb +110 -0
  49. data/spec/inputs_spec.rb +476 -0
  50. data/spec/label_spec.rb +89 -0
  51. data/spec/semantic_errors_spec.rb +98 -0
  52. data/spec/semantic_fields_for_spec.rb +45 -0
  53. data/spec/spec.opts +2 -0
  54. data/spec/spec_helper.rb +289 -0
  55. data/spec/support/custom_macros.rb +494 -0
  56. data/spec/support/output_buffer.rb +4 -0
  57. data/spec/support/test_environment.rb +45 -0
  58. metadata +235 -0
@@ -0,0 +1,45 @@
1
+ # coding: utf-8
2
+ require '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
+ form = semantic_form_for(@new_post) do |builder|
33
+ concat(builder.semantic_fields_for(@bob, :index => 1) do |nested_builder|
34
+ concat(nested_builder.inputs(:login))
35
+ end)
36
+ end
37
+ output_buffer.concat(form) if Formtastic::Util.rails3?
38
+ output_buffer.should have_tag('form fieldset.inputs #post_author_1_login_input')
39
+ # Not valid selector, so using good ol' regex
40
+ output_buffer.should_not =~ /id="post\[author\]_1_login_input"/
41
+ # <=> output_buffer.should_not have_tag('form fieldset.inputs #post[author]_1_login_input')
42
+ end
43
+
44
+ end
45
+
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=progress
@@ -0,0 +1,289 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'active_support'
4
+ require 'action_pack'
5
+ require 'action_view'
6
+ require 'action_controller'
7
+ require 'action_mailer'
8
+
9
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic/util'))
10
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic'))
11
+ require File.expand_path(File.join(File.dirname(__FILE__), '../lib/formtastic/layout_helper'))
12
+
13
+ # Requires supporting files with custom matchers and macros, etc,
14
+ # in ./support/ and its subdirectories in alphabetic order.
15
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each {|f| require f}
16
+
17
+ module FormtasticSpecHelper
18
+ include ActionPack
19
+ include ActionView::Context if defined?(ActionView::Context)
20
+ include ActionController::RecordIdentifier
21
+ include ActionView::Helpers::FormHelper
22
+ include ActionView::Helpers::FormTagHelper
23
+ include ActionView::Helpers::FormOptionsHelper
24
+ include ActionView::Helpers::UrlHelper
25
+ include ActionView::Helpers::TagHelper
26
+ include ActionView::Helpers::TextHelper
27
+ include ActionView::Helpers::ActiveRecordHelper if defined?(ActionView::Helpers::ActiveRecordHelper)
28
+ include ActionView::Helpers::ActiveModelHelper if defined?(ActionView::Helpers::ActiveModelHelper)
29
+ include ActionView::Helpers::DateHelper
30
+ include ActionView::Helpers::CaptureHelper
31
+ include ActionView::Helpers::AssetTagHelper
32
+ include ActiveSupport
33
+ include ActionController::PolymorphicRoutes if defined?(ActionController::PolymorphicRoutes)
34
+
35
+ include Formtastic::SemanticFormHelper
36
+
37
+ def rails3?
38
+ ActionPack::VERSION::MAJOR > 2
39
+ end
40
+
41
+ def rails2?
42
+ ActionPack::VERSION::MAJOR == 2
43
+ end
44
+
45
+ def default_input_type(column_type, column_name = :generic_column_name)
46
+ @new_post.stub!(column_name)
47
+ @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => column_type)) unless column_type.nil?
48
+
49
+ semantic_form_for(@new_post) do |builder|
50
+ @default_type = builder.send(:default_input_type, column_name)
51
+ end
52
+
53
+ return @default_type
54
+ end
55
+
56
+ def active_model_presence_validator(attributes, options = {})
57
+ presence_validator = mock('ActiveModel::Validations::PresenceValidator', :attributes => attributes, :options => options)
58
+ presence_validator.stub!(:kind).and_return(:presence)
59
+ presence_validator
60
+ end
61
+
62
+ class ::Post
63
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
64
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
65
+
66
+ def id
67
+ end
68
+
69
+ def persisted?
70
+ end
71
+ end
72
+ module ::Namespaced
73
+ class Post
74
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
75
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
76
+
77
+ def id
78
+ end
79
+
80
+ def persisted?
81
+ end
82
+ end
83
+ end
84
+ class ::Author
85
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
86
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
87
+
88
+ def to_label
89
+ end
90
+ end
91
+ class ::Continent
92
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
93
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
94
+ end
95
+ class ::PostModel
96
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
97
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
98
+ end
99
+
100
+ def mock_everything
101
+
102
+ # Resource-oriented styles like form_for(@post) will expect a path method for the object,
103
+ # so we're defining some here.
104
+ def post_models_path; "/postmodels/1"; end
105
+
106
+ def post_path(o); "/posts/1"; end
107
+ def posts_path; "/posts"; end
108
+ def new_post_path; "/posts/new"; end
109
+
110
+ def author_path(o); "/authors/1"; end
111
+ def authors_path; "/authors"; end
112
+ def new_author_path; "/authors/new"; end
113
+
114
+ @fred = mock('user')
115
+ @fred.stub!(:to_ary)
116
+ @fred.stub!(:class).and_return(::Author)
117
+ @fred.stub!(:to_label).and_return('Fred Smith')
118
+ @fred.stub!(:login).and_return('fred_smith')
119
+ @fred.stub!(:id).and_return(37)
120
+ @fred.stub!(:new_record?).and_return(false)
121
+ @fred.stub!(:errors).and_return(mock('errors', :[] => nil))
122
+ @fred.stub!(:to_key).and_return(nil)
123
+ @fred.stub!(:persisted?).and_return(nil)
124
+
125
+ @bob = mock('user')
126
+ @bob.stub!(:to_ary)
127
+ @bob.stub!(:class).and_return(::Author)
128
+ @bob.stub!(:to_label).and_return('Bob Rock')
129
+ @bob.stub!(:login).and_return('bob')
130
+ @bob.stub!(:created_at)
131
+ @bob.stub!(:id).and_return(42)
132
+ @bob.stub!(:posts).and_return([])
133
+ @bob.stub!(:post_ids).and_return([])
134
+ @bob.stub!(:new_record?).and_return(false)
135
+ @bob.stub!(:errors).and_return(mock('errors', :[] => nil))
136
+ @bob.stub!(:to_key).and_return(nil)
137
+ @bob.stub!(:persisted?).and_return(nil)
138
+
139
+ @james = mock('user')
140
+ @james.stub!(:to_ary)
141
+ @james.stub!(:class).and_return(::Author)
142
+ @james.stub!(:to_label).and_return('James Shock')
143
+ @james.stub!(:login).and_return('james')
144
+ @james.stub!(:id).and_return(75)
145
+ @james.stub!(:posts).and_return([])
146
+ @james.stub!(:post_ids).and_return([])
147
+ @james.stub!(:new_record?).and_return(false)
148
+ @james.stub!(:errors).and_return(mock('errors', :[] => nil))
149
+ @james.stub!(:to_key).and_return(nil)
150
+ @james.stub!(:persisted?).and_return(nil)
151
+
152
+
153
+ ::Author.stub!(:find).and_return([@fred, @bob])
154
+ ::Author.stub!(:all).and_return([@fred, @bob])
155
+ ::Author.stub!(:to_ary)
156
+ ::Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
157
+ ::Author.stub!(:human_name).and_return('::Author')
158
+ ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
159
+ ::Author.stub!(:content_columns).and_return([mock('column', :name => 'login'), mock('column', :name => 'created_at')])
160
+ ::Author.stub!(:to_key).and_return(nil)
161
+ ::Author.stub!(:persisted?).and_return(nil)
162
+
163
+ # Sometimes we need a mock @post object and some Authors for belongs_to
164
+ @new_post = mock('post')
165
+ @new_post.stub!(:to_ary)
166
+ @new_post.stub!(:class).and_return(::Post)
167
+ @new_post.stub!(:id).and_return(nil)
168
+ @new_post.stub!(:new_record?).and_return(true)
169
+ @new_post.stub!(:errors).and_return(mock('errors', :[] => nil))
170
+ @new_post.stub!(:author).and_return(nil)
171
+ @new_post.stub!(:reviewer).and_return(nil)
172
+ @new_post.stub!(:main_post).and_return(nil)
173
+ @new_post.stub!(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
174
+ @new_post.stub!(:to_key).and_return(nil)
175
+ @new_post.stub!(:to_model).and_return(@new_post)
176
+ @new_post.stub!(:persisted?).and_return(nil)
177
+
178
+ @freds_post = mock('post')
179
+ @freds_post.stub!(:to_ary)
180
+ @freds_post.stub!(:class).and_return(::Post)
181
+ @freds_post.stub!(:to_label).and_return('Fred Smith')
182
+ @freds_post.stub!(:id).and_return(19)
183
+ @freds_post.stub!(:author).and_return(@fred)
184
+ @freds_post.stub!(:author_id).and_return(@fred.id)
185
+ @freds_post.stub!(:authors).and_return([@fred])
186
+ @freds_post.stub!(:author_ids).and_return([@fred.id])
187
+ @freds_post.stub!(:new_record?).and_return(false)
188
+ @freds_post.stub!(:errors).and_return(mock('errors', :[] => nil))
189
+ @freds_post.stub!(:to_key).and_return(nil)
190
+ @freds_post.stub!(:persisted?).and_return(nil)
191
+ @fred.stub!(:posts).and_return([@freds_post])
192
+ @fred.stub!(:post_ids).and_return([@freds_post.id])
193
+
194
+ ::Post.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
195
+ ::Post.stub!(:human_name).and_return('Post')
196
+ ::Post.stub!(:reflect_on_all_validations).and_return([])
197
+ ::Post.stub!(:reflect_on_validations_for).and_return([])
198
+ ::Post.stub!(:reflections).and_return({})
199
+ ::Post.stub!(:reflect_on_association).and_return do |column_name|
200
+ case column_name
201
+ when :author, :author_status
202
+ mock = mock('reflection', :options => {}, :klass => ::Author, :macro => :belongs_to)
203
+ mock.stub!(:[]).with(:class_name).and_return("Author")
204
+ mock
205
+ when :reviewer
206
+ mock = mock('reflection', :options => {:class_name => 'Author'}, :klass => ::Author, :macro => :belongs_to)
207
+ mock.stub!(:[]).with(:class_name).and_return("Author")
208
+ mock
209
+ when :authors
210
+ mock('reflection', :options => {}, :klass => ::Author, :macro => :has_and_belongs_to_many)
211
+ when :sub_posts
212
+ mock('reflection', :options => {}, :klass => ::Post, :macro => :has_many)
213
+ when :main_post
214
+ mock('reflection', :options => {}, :klass => ::Post, :macro => :belongs_to)
215
+ end
216
+
217
+ end
218
+ ::Post.stub!(:find).and_return([@freds_post])
219
+ ::Post.stub!(:all).and_return([@freds_post])
220
+ ::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
221
+ ::Post.stub!(:to_key).and_return(nil)
222
+ ::Post.stub!(:persisted?).and_return(nil)
223
+ ::Post.stub!(:to_ary)
224
+
225
+ @new_post.stub!(:title)
226
+ @new_post.stub!(:to_ary)
227
+ @new_post.stub!(:body)
228
+ @new_post.stub!(:published)
229
+ @new_post.stub!(:publish_at)
230
+ @new_post.stub!(:created_at)
231
+ @new_post.stub!(:secret)
232
+ @new_post.stub!(:time_zone)
233
+ @new_post.stub!(:category_name)
234
+ @new_post.stub!(:allow_comments)
235
+ @new_post.stub!(:country)
236
+ @new_post.stub!(:country_subdivision)
237
+ @new_post.stub!(:country_code)
238
+ @new_post.stub!(:column_for_attribute).with(:meta_description).and_return(mock('column', :type => :string, :limit => 255))
239
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 50))
240
+ @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
241
+ @new_post.stub!(:column_for_attribute).with(:published).and_return(mock('column', :type => :boolean))
242
+ @new_post.stub!(:column_for_attribute).with(:publish_at).and_return(mock('column', :type => :date))
243
+ @new_post.stub!(:column_for_attribute).with(:time_zone).and_return(mock('column', :type => :string))
244
+ @new_post.stub!(:column_for_attribute).with(:allow_comments).and_return(mock('column', :type => :boolean))
245
+ @new_post.stub!(:column_for_attribute).with(:author).and_return(mock('column', :type => :integer))
246
+ @new_post.stub!(:column_for_attribute).with(:country).and_return(mock('column', :type => :string, :limit => 255))
247
+ @new_post.stub!(:column_for_attribute).with(:country_subdivision).and_return(mock('column', :type => :string, :limit => 255))
248
+ @new_post.stub!(:column_for_attribute).with(:country_code).and_return(mock('column', :type => :string, :limit => 255))
249
+
250
+ @new_post.stub!(:author).and_return(@bob)
251
+ @new_post.stub!(:author_id).and_return(@bob.id)
252
+
253
+ @new_post.stub!(:reviewer).and_return(@fred)
254
+ @new_post.stub!(:reviewer_id).and_return(@fred.id)
255
+
256
+ @new_post.should_receive(:publish_at=).any_number_of_times
257
+ @new_post.should_receive(:title=).any_number_of_times
258
+ @new_post.stub!(:main_post_id).and_return(nil)
259
+
260
+ end
261
+
262
+ def self.included(base)
263
+ base.class_eval do
264
+
265
+ attr_accessor :output_buffer
266
+
267
+ def protect_against_forgery?
268
+ false
269
+ end
270
+
271
+ end
272
+ end
273
+
274
+ def with_config(config_method_name, value, &block)
275
+ old_value = ::Formtastic::SemanticFormBuilder.send(config_method_name)
276
+ ::Formtastic::SemanticFormBuilder.send(:"#{config_method_name}=", value)
277
+ yield
278
+ ::Formtastic::SemanticFormBuilder.send(:"#{config_method_name}=", old_value)
279
+ end
280
+
281
+ def with_deprecation_silenced(&block)
282
+ ::ActiveSupport::Deprecation.silenced = true
283
+ yield
284
+ ::ActiveSupport::Deprecation.silenced = false
285
+ end
286
+
287
+ end
288
+
289
+ ::ActiveSupport::Deprecation.silenced = false