, [">= 0"])
111 | end
112 | end
113 |
114 |
--------------------------------------------------------------------------------
/lib/jintastic.rb:
--------------------------------------------------------------------------------
1 | require 'formtastic'
2 |
3 | class ActionView::Base
4 | def in_place_editor_for(path_spec_or_object, attributes, html_text = nil)
5 | instance = path_spec_or_object.kind_of?(Array) ? path_spec_or_object.last : path_spec_or_object
6 |
7 | if attributes.class==Symbol
8 | #simple one attribute in place editor
9 | #in_place_editor_for @user, :name
10 | attribute = attributes
11 | input_attributes = Array(attribute)
12 |
13 | elsif attributes.values.first==:form
14 | #render default form partial
15 | #in_place_editor_for @user, :name=>:form
16 | attribute = attributes.keys.first
17 |
18 | elsif attributes.values.first.class==String
19 | #render custom form partial
20 | #in_place_editor_for @user, :name=>'users/custom_form'
21 | attribute = attributes.keys.first
22 | form_partial = attributes[attribute]
23 |
24 | else
25 | #attribute is an array
26 | #in_place_editor_for @user, :name=>[:name,:address]
27 | attribute = attributes.keys.first
28 | input_attributes = attributes[attribute]
29 | end
30 |
31 | container_tag = instance.respond_to?(:column_for_attribute) ?
32 | instance.column_for_attribute(attribute).type == :text ? :pre : :span : :span
33 |
34 | form_tag_options = {}
35 | content_tag_options = {:class=>'in_place_attribute'}
36 |
37 | form_partial ||= "#{instance.class.to_s.downcase.pluralize}/form" unless input_attributes
38 |
39 | html_text ||= instance[attribute]
40 |
41 | if instance.valid?
42 | form_tag_options.merge!({:html=>{:style=>"display: none"}})
43 | else
44 | content_tag_options.merge!({:style=>"display: none"})
45 | end
46 |
47 | render :partial => 'jintastic/in_place_editor',
48 | :locals => {:container_tag=>container_tag,
49 | :input_attributes=>input_attributes,
50 | :path_spec_or_object=>path_spec_or_object,
51 | :html_text=>html_text,
52 | :content_tag_options=>content_tag_options,
53 | :form_tag_options=>form_tag_options,
54 | :form_partial=>form_partial}
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/test/jintastic_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | class JintasticTest < Test::Unit::TestCase
4 | should "probably rename this file and start testing for real" do
5 | flunk "hey buddy, you should probably rename this file and start testing for real"
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'test/unit'
3 | require 'shoulda'
4 |
5 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6 | $LOAD_PATH.unshift(File.dirname(__FILE__))
7 | require 'jintastic'
8 |
9 | class Test::Unit::TestCase
10 | end
11 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | coverage
3 | pkg
4 | *~
5 | *watchr.rb
6 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008 Justin French
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/README.textile:
--------------------------------------------------------------------------------
1 | h1. Formtastic
2 |
3 | Formtastic is a Rails FormBuilder DSL (with some other goodies) to make it far easier to create beautiful, semantically rich, syntactically awesome, readily stylable and wonderfully accessible HTML forms in your Rails applications.
4 |
5 | h2. The Story
6 |
7 | One day, I finally had enough, so I opened up my text editor, and wrote a DSL for how I'd like to author forms:
8 |
9 |
10 | <% semantic_form_for @article do |form| %>
11 |
12 | <% form.inputs :name => "Basic" do %>
13 | <%= form.input :title %>
14 | <%= form.input :body %>
15 | <%= form.input :section %>
16 | <%= form.input :publication_state, :as => :radio %>
17 | <%= form.input :category %>
18 | <%= form.input :allow_comments, :label => "Allow commenting on this article" %>
19 | <% end %>
20 |
21 | <% form.inputs :name => "Advanced" do %>
22 | <%= form.input :keywords, :required => false, :hint => "Example: ruby, rails, forms" %>
23 | <%= form.input :extract, :required => false %>
24 | <%= form.input :description, :required => false %>
25 | <%= form.input :url_title, :required => false %>
26 | <% end %>
27 |
28 | <% form.inputs :name => "Author", :for => :author do |author_form| %>
29 | <%= author_form.input :first_name %>
30 | <%= author_form.input :last_name %>
31 | <% end %>
32 |
33 | <% form.buttons do %>
34 | <%= form.commit_button %>
35 | <% end %>
36 |
37 | <% end %>
38 |
39 |
40 | I also wrote the accompanying HTML output I expected, favoring something very similar to the fieldsets, lists and other semantic elements Aaron Gustafson presented in "Learning to Love Forms":http://www.slideshare.net/AaronGustafson/learning-to-love-forms-web-directions-south-07, hacking together enough Ruby to prove it could be done.
41 |
42 |
43 | h2. It's better than _SomeOtherFormBuilder_ because...
44 |
45 | * it can handle @belongs_to@ associations (like Post belongs_to :author), rendering a select or set of radio inputs with choices from the parent model.
46 | * it can handle @has_many@ and @has_and_belongs_to_many@ associations (like: Post has_many :tags), rendering a multi-select with choices from the child models.
47 | * it's Rails 2.3-ready (including nested forms).
48 | * it has internationalization (I18n)!
49 | * it's _really_ quick to get started with a basic form in place (4 lines), then go back to add in more detail if you need it.
50 | * there's heaps of elements, id and class attributes for you to hook in your CSS and JS.
51 | * it handles real world stuff like inline hints, inline error messages & help text.
52 | * it doesn't hijack or change any of the standard Rails form inputs, so you can still use them as expected (even mix and match).
53 | * it's got absolutely awesome spec coverage.
54 | * there's a bunch of people using and working on it (it's not just one developer building half a solution).
55 |
56 |
57 | h2. Why?
58 |
59 | * web apps = lots of forms.
60 | * forms are so friggin' boring to code.
61 | * semantically rich & accessible forms really are possible.
62 | * the "V" is way behind the "M" and "C" in Rails' MVC – it's the ugly sibling.
63 | * best practices and common patterns have to start somewhere.
64 | * i need a challenge.
65 |
66 |
67 | h2. Opinions
68 |
69 | * it should be easier to do things the right way than the wrong way.
70 | * sometimes _more mark-up_ is better.
71 | * elements and attribute hooks are _gold_ for stylesheet authors.
72 | * make the common things we do easy, yet still ensure uncommon things are still possible.
73 |
74 |
75 | h2. Documentation
76 |
77 | RDoc documentation _should_ be automatically generated after each commit and made available on the "rdoc.info website":http://rdoc.info/projects/justinfrench/formtastic.
78 |
79 |
80 | h2. Installation
81 |
82 | The gem is hosted on gemcutter, so *if you haven't already*, add it as a gem source:
83 |
84 |
85 | sudo gem sources -a http://gemcutter.org/
86 |
87 |
88 | Then install the Formtastic gem:
89 |
90 |
91 | sudo gem install formtastic
92 |
93 |
94 | And add it to your environment.rb configuration as a gem dependency:
95 |
96 |
97 | config.gem 'formtastic'
98 |
99 |
100 | Optionally, run @./script/generate formtastic@ to copy the following files into your app:
101 |
102 | * @config/initializers/formtastic_config.rb@ - a commented out Formtastic config initializer
103 | * @public/stylesheets/formtastic.css@
104 | * @public/stylesheets/formtastic_changes.css@
105 |
106 | A proof-of-concept stylesheet is provided which you can include in your layout. Customization is best achieved by overriding these styles in an additional stylesheet so that the Formtastic styles can be updated without clobbering your changes. If you want to use these stylesheets, add both to your layout:
107 |
108 |
109 | <%= stylesheet_link_tag "formtastic" %>
110 | <%= stylesheet_link_tag "formtastic_changes" %>
111 |
112 |
113 | h2. Usage
114 |
115 | Forms are really boring to code... you want to get onto the good stuff as fast as possible.
116 |
117 | This renders a set of inputs (one for _most_ columns in the database table, and one for each ActiveRecord @belongs_to@-association), followed by a submit button:
118 |
119 |
120 | <% semantic_form_for @user do |form| %>
121 | <%= form.inputs %>
122 | <%= form.buttons %>
123 | <% end %>
124 |
125 |
126 | If you want to specify the order of the fields, skip some of the fields or even add in fields that Formtastic couldn't detect, you can pass in a list of field names to @inputs@ and list of button names to @buttons@:
127 |
128 |
129 | <% semantic_form_for @user do |form| %>
130 | <%= form.inputs :title, :body, :section, :categories, :created_at %>
131 | <%= form.buttons :commit %>
132 | <% end %>
133 |
134 |
135 | If you want control over the input type Formtastic uses for each field, you can expand the @inputs@ and @buttons@ blocks. This specifies the @:section@ input should be a set of radio buttons (rather than the default select box), and that the @:created_at@ field should be a string (rather than the default datetime selects):
136 |
137 |
138 | <% semantic_form_for @post do |form| %>
139 | <% form.inputs do %>
140 | <%= form.input :title %>
141 | <%= form.input :body %>
142 | <%= form.input :section, :as => :radio %>
143 | <%= form.input :categories %>
144 | <%= form.input :created_at, :as => :string %>
145 | <% end %>
146 | <% form.buttons do %>
147 | <%= form.commit_button %>
148 | <% end %>
149 | <% end %>
150 |
151 |
152 | If you want to customize the label text, or render some hint text below the field, specify which fields are required/optional, or break the form into two fieldsets, the DSL is pretty comprehensive:
153 |
154 |
155 | <% semantic_form_for @post do |form| %>
156 | <% form.inputs "Basic", :id => "basic" do %>
157 | <%= form.input :title %>
158 | <%= form.input :body %>
159 | <% end %>
160 | <% form.inputs :name => "Advanced Options", :id => "advanced" do %>
161 | <%= form.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false %>
162 | <%= form.input :section, :as => :radio %>
163 | <%= form.input :user, :label => "Author", :label_method => :full_name, %>
164 | <%= form.input :categories, :required => false %>
165 | <%= form.input :created_at, :as => :string, :label => "Publication Date", :required => false %>
166 | <% end %>
167 | <% form.buttons do %>
168 | <%= form.commit_button %>
169 | <% end %>
170 | <% end %>
171 |
172 |
173 | Nested forms (Rails 2.3) are also supported. You can do it in the Rails way:
174 |
175 |
176 | <% semantic_form_for @post do |form| %>
177 | <%= form.inputs :title, :body, :created_at %>
178 | <% form.semantic_fields_for :author do |author| %>
179 | <%= author.inputs :first_name, :last_name, :name => "Author" %>
180 | <% end %>
181 | <%= form.buttons %>
182 | <% end %>
183 |
184 |
185 | Or the Formtastic way with the @:for@ option:
186 |
187 |
188 | <% semantic_form_for @post do |form| %>
189 | <%= form.inputs :title, :body, :created_at %>
190 | <%= form.inputs :first_name, :last_name, :for => :author, :name => "Author" %>
191 | <%= form.buttons %>
192 | <% end %>
193 |
194 |
195 | When working in has many association, you can even supply @"%i"@ in your fieldset name that it will be properly interpolated with the child index. For example:
196 |
197 |
198 | <% semantic_form_for @post do |form| %>
199 | <%= form.inputs %>
200 | <%= form.inputs :name => 'Category #%i', :for => :categories %>
201 | <%= form.buttons %>
202 | <% end %>
203 |
204 |
205 |
206 | Customize HTML attributes for any input using the @:input_html@ option. Typically his is used to disable the input, change the size of a text field, change the rows in a textarea, or even to add a special class to an input to attach special behavior like "autogrow":http://plugins.jquery.com/project/autogrow textareas:
207 |
208 |
209 | <% semantic_form_for @post do |form| %>
210 | <%= form.input :title, :input_html => { :size => 60 } %>
211 | <%= form.input :body, :input_html => { :class => 'autogrow' } %>
212 | <%= form.input :created_at, :input_html => { :disabled => true } %>
213 | <%= form.buttons %>
214 | <% end %>
215 |
216 |
217 | The same can be done for buttons with the @:button_html@ option:
218 |
219 |
220 | <% semantic_form_for @post do |form| %>
221 | ...
222 | <% form.buttons do %>
223 | <%= form.commit_button :button_html => { :class => "primary" } %>
224 | <% end %>
225 | <% end %>
226 |
227 |
228 | Customize the HTML attributes for the @@ wrapper around every input with the @:wrapper_html@ option hash. There's one special key in the hash (@:class@), which will actually _append_ your string of classes to the existing classes provided by Formtastic (like @"required string error"@)
229 |
230 |
231 | <% semantic_form_for @post do |form| %>
232 | <%= form.input :title, :wrapper_html => { :class => "important" } %>
233 | <%= form.input :body %>
234 | <%= form.input :description, :wrapper_html => { :style => "display:none;" } %>
235 | ...
236 | <% end %>
237 |
238 |
239 |
240 | h2. The Available Inputs
241 |
242 | The Formtastic input types:
243 |
244 | * @:select@ - a select menu. Default for ActiveRecord associations: @belongs_to@, @has_many@, and @has_and_belongs_to_many@.
245 | * @:check_boxes@ - a set of check_box inputs. Alternative to @:select@ for ActiveRecord-associations: @has_many@, and @has_and_belongs_to_many@.
246 | * @:radio@ - a set of radio inputs. Alternative to @:select@ for ActiveRecord-associations: @belongs_to@.
247 | * @:time_zone@ - a select input. Default for column types: @:string@ with name matching @"time_zone"@.
248 | * @:password@ - a password input. Default for column types: @:string@ with name matching @"password"@.
249 | * @:text@ - a textarea. Default for column types: @:text@.
250 | * @:date@ - a date select. Default for column types: @:date@.
251 | * @:datetime@ - a date and time select. Default for column types: @:datetime@ and @:timestamp@.
252 | * @:time@ - a time select. Default for column types: @:time@.
253 | * @:boolean@ - a checkbox. Default for column types: @:boolean@.
254 | * @:string@ - a text field. Default for column types: @:string@.
255 | * @:numeric@ - a text field (just like string). Default for column types: @:integer@, @:float@, and @:decimal@.
256 | * @:file@ - a file field. Default for file-attachment attributes matching: "paperclip":http://github.com/thoughtbot/paperclip or "attachment_fu":http://github.com/technoweenie/attachment_fu.
257 | * @:country@ - a select menu of country names. Default for column types: :string with name @"country"@ - requires a *country_select* plugin to be installed.
258 | * @:hidden@ - a hidden field. Creates a hidden field (added for compatibility).
259 |
260 | The documentation is pretty good for each of these (what it does, what the output is, what the options are, etc.) so go check it out.
261 |
262 | h2. Delegation for label lookups
263 |
264 | Formtastic decides which label to use in the following order:
265 |
266 |
267 | 1. :label # :label => "Choose Title"
268 | 2. Formtastic i18n # if either :label => true || i18n_lookups_by_default = true (see Internationalization)
269 | 3. Activerecord i18n # if localization file found for the given attribute
270 | 4. label_str_method # if nothing provided this defaults to :humanize but can be set to a custom method
271 |
272 |
273 | h2. Internationalization (I18n)
274 |
275 | h3. Basic Localization
276 |
277 | Formtastic got some neat I18n-features. ActiveRecord object names and attributes are, by default, taken from calling @@object.human_name@ and @@object.human_attribute_name(attr)@ respectively. There are a few words specific to Formtastic that can be translated. See @lib/locale/en.yml@ for more information.
278 |
279 | Basic localization (labels only, with ActiveRecord):
280 |
281 |
282 | <% semantic_form_for @post do |form| %>
283 | <%= form.input :title %> # => :label => I18n.t('activerecord.attributes.user.title') or 'Title'
284 | <%= form.input :body %> # => :label => I18n.t('activerecord.attributes.user.body') or 'Body'
285 | <%= form.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
286 | <% end %>
287 |
288 |
289 | *Note:* This is perfectly fine if you just want your labels/attributes and/or models to be translated using *ActiveRecord I18n attribute translations*, and you don't use input hints and legends. But what if you do? And what if you don't want same labels in all forms?
290 |
291 | h3. Enhanced Localization (Formtastic I18n API)
292 |
293 | Formtastic supports localized *labels*, *hints*, *legends*, *actions* using the I18n API for more advanced usage. Your forms can now be DRYer and more flexible than ever, and still fully localized. This is how:
294 |
295 | *1. Enable I18n lookups by default (@config/initializers/formtastic.rb@):*
296 |
297 |
298 | Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
299 |
300 |
301 | *2. Add some cool label-translations/variants (@config/locale/en.yml@):*
302 |
303 |
304 | en:
305 | formtastic:
306 | titles:
307 | post_details: "Post details"
308 | labels:
309 | post:
310 | title: "Choose a title..."
311 | body: "Write something..."
312 | edit:
313 | title: "Edit title"
314 | hints:
315 | post:
316 | title: "Choose a good title for you post."
317 | body: "Write something inspiring here."
318 | actions:
319 | create: "Create my {{model}}"
320 | update: "Save changes"
321 | dummie: "Launch!"
322 |
323 |
324 | *Note:* We are using English here still, but you get the point.
325 |
326 | *3. ...and now you'll get:*
327 |
328 |
329 | <% semantic_form_for Post.new do |form| %>
330 | <% form.inputs do %>
331 | <%= form.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for you post."
332 | <%= form.input :body %> # => :label => "Write something...", :hint => "Write something inspiring here."
333 | <%= form.input :section %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
334 | <% end %>
335 | <% form.buttons do %>
336 | <%= form.commit_button %> # => "Create my {{model}}"
337 | <% end %>
338 | <% end %>
339 |
340 |
341 | *4. Localized titles (a.k.a. legends):*
342 |
343 | _Note: Slightly different because Formtastic can't guess how you group fields in a form. Legend text can be set with first (as in the sample below) specified value, or :name/:title options - depending on what flavor is preferred._
344 |
345 |
346 | <% semantic_form_for @post do |form| %>
347 | <% form.inputs :post_details do %> # => :title => "Post details"
348 | # ...
349 | <% end %>
350 | # ...
351 | <% end %>
352 |
353 |
354 | *5. Override I18n settings:*
355 |
356 |
357 | <% semantic_form_for @post do |form| %>
358 | <% form.inputs do %>
359 | <%= form.input :title %> # => :label => "Choose a title...", :hint => "Choose a good title for you post."
360 | <%= form.input :body, :hint => false %> # => :label => "Write something..."
361 | <%= form.input :section, :label => 'Some section' %> # => :label => 'Some section'
362 | <% end %>
363 | <% form.buttons do %>
364 | <%= form.commit_button :dummie %> # => "Launch!"
365 | <% end %>
366 | <% end %>
367 |
368 |
369 | If I18n-lookups is disabled, i.e.:
370 |
371 |
372 | Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
373 |
374 |
375 | ...then you can enable I18n within the forms instead:
376 |
377 |
378 | <% semantic_form_for @post do |form| %>
379 | <% form.inputs do %>
380 | <%= form.input :title, :label => true %> # => :label => "Choose a title..."
381 | <%= form.input :body, :label => true %> # => :label => "Write something..."
382 | <%= form.input :section, :label => true %> # => :label => I18n.t('activerecord.attributes.user.section') or 'Section'
383 | <% end %>
384 | <% form.buttons do %>
385 | <%= form.commit_button true %> # => "Save changes" (if we are in edit that is...)
386 | <% end %>
387 | <% end %>
388 |
389 |
390 | *6. Advanced I18n lookups*
391 |
392 | For more flexible forms; Formtastic find translations using a bottom-up approach taking the following variables in account:
393 |
394 | * @MODEL@, e.g. "post"
395 | * @ACTION@, e.g. "edit"
396 | * @KEY/ATTRIBUTE@, e.g. "title", :my_custom_key, ...
397 |
398 | ...in the following order:
399 |
400 | 1. @formtastic.{titles,labels,hints,actions}.MODEL.ACTION.ATTRIBUTE@ - by model and action
401 | 2. @formtastic.{titles,labels,hints,actions}.MODEL.ATTRIBUTE@ - by model
402 | 3. @formtastic.{titles,labels,hints,actions}.ATTRIBUTE@ - global default
403 |
404 | ...which means that you can define translations like this:
405 |
406 |
407 | en:
408 | formtastic:
409 | labels:
410 | title: "Title" # Default global value
411 | article:
412 | body: "Article content"
413 | post:
414 | new:
415 | title: "Choose a title..."
416 | body: "Write something..."
417 | edit:
418 | title: "Edit title"
419 | body: "Edit body"
420 |
421 |
422 | Values for @labels@/@hints@/@actions@ are can take values: @String@ (explicit value), @Symbol@ (i18n-lookup-key relative to the current "type", e.g. actions:), @true@ (force I18n lookup), @false@ (force no I18n lookup). Titles (legends) can only take: @String@ and @Symbol@ - true/false have no meaning.
423 |
424 |
425 | h2. Semantic errors
426 |
427 | You can show errors on base (by default) and any other attribute just passing it name to semantic_errors method:
428 |
429 |
430 | <% semantic_form_for @post do |form| %>
431 | <%= form.semantic_errors :state %>
432 | <% end %>
433 |
434 |
435 |
436 | h2. ValidationReflection plugin
437 |
438 | If you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin installed, you won't have to specify the @:required@ option (it checks the validations on the model instead).
439 |
440 |
441 | h2. Configuration
442 |
443 | Run @./script/generate formtastic@ to copy a commented out config file into @config/initializers/formtastic.rb@. You can "view the configuration file on GitHub":http://github.com/justinfrench/formtastic/blob/master/generators/formtastic/templates/formtastic.rb
444 |
445 |
446 | h2. Form Generator
447 |
448 | There's a Formtastic form code generator to make your transition to Formtastic easier. All you have to do is to *specify an existing model name*, and optionally specify view template framework (ERB/HAML), and you are good to go. *Note:* This won't overwrite any of you stuff. This is how you use it:
449 |
450 | *Alt. 1: Generate in terminal:*
451 |
452 |
453 | $ ./script/generate form Post
454 | # ---------------------------------------------------------
455 | # GENERATED FORMTASTIC CODE
456 | # ---------------------------------------------------------
457 |
458 | <% f.inputs do %>
459 | <%= f.input :title, :label => 'Title' %>
460 | <%= f.input :body, :label => 'Body' %>
461 | <%= f.input :published, :label => 'Published' %>
462 | <% end %>
463 |
464 | # ---------------------------------------------------------
465 | Copied to clipboard - just paste it!
466 |
467 |
468 | *Alt. 2: Generate partial:*
469 |
470 |
471 | $ ./script/generate form Post --partial
472 | exists app/views/posts
473 | create app/views/posts/_form.html.erb
474 |
475 |
476 | To generate *HAML* markup, just add the @--haml@ as argument:
477 |
478 |
479 | $ ./script/generate form Post --haml
480 | exists app/views/admin/posts
481 | create app/views/admin/posts/_form.html.haml
482 |
483 |
484 | To specify the controller in a namespace (eg admin/posts instead of posts), use the --controller argument:
485 |
486 |
487 | $ ./script/generate form Post --partial --controller admin/posts
488 | exists app/views/admin/posts
489 | create app/views/admin/posts/_form.html.erb
490 |
491 |
492 |
493 | h2. Custom Inputs
494 |
495 | If you want to add your own input types to encapsulate your own logic or interface patterns, you can do so by subclassing SemanticFormBuilder and configuring Formtastic to use your custom builder class.
496 |
497 | @Formtastic::SemanticFormHelper.builder = MyCustomBuilder@
498 |
499 |
500 |
501 |
502 | h2. Status
503 |
504 | Formtastic has been in active development for about a year. We've just recently jumped to an 0.9 version number, signaling that we consider this a 1.0 release candidate, and that the API won't change significantly for the 1.x series.
505 |
506 |
507 | h2. Dependencies
508 |
509 | There are none, but...
510 |
511 | * if you have the "ValidationReflection":http://github.com/redinger/validation_reflection plugin is installed, you won't have to specify the @:required@ option (it checks the validations on the model instead).
512 | * if you want to use the @:country@ input, you'll need to install the "iso-3166-country-select plugin":http://github.com/rails/iso-3166-country-select (or any other country_select plugin with the same API).
513 | * "rspec":http://github.com/dchelimsky/rspec/, "rspec_hpricot_matchers":http://rubyforge.org/projects/rspec-hpricot/ and "rcov":http://github.com/relevance/rcov gems (plus any of their own dependencies) are required for the test suite.
514 |
515 |
516 | h2. Compatibility
517 |
518 | I'm only testing Formtastic with the latest Rails 2.4.x stable release, and it should be fine under Rails 2.3.x as well (including nested forms). Patches are welcome to allow backwards compatibility, but I don't have the energy!
519 |
520 | h2. Got TextMate?
521 |
522 | Well...there's a TextMate-bundle in town, dedicated to make usage of Formtastic in the "TextMate":http://macromates.com/ editor even more of a breeze:
523 |
524 | "Formtastic.tmbundle":http://github.com/grimen/formtastic_tmbundle
525 |
526 |
527 | h2. How to contribute
528 |
529 | *Before you send a pull request*, please ensure that you provide appropriate spec/test coverage and ensure the documentation is up-to-date. Bonus points if you perform your changes in a clean topic branch rather than master.
530 |
531 | Please also keep your commits *atomic* so that they are more likely to apply cleanly. That means that each commit should contain the smallest possible logical change. Don't commit two features at once, don't update the gemspec at the same time you add a feature, don't fix a whole bunch of whitespace in a file at the same time you change a few lines, etc, etc.
532 |
533 | For significant changes, you may wish to discuss your idea on the Formtastic Google group before coding to ensure that your change is likely to be accepted. Formtastic relies heavily on i18n, so if you're unsure of the impact this has on your changes, please discuss them with the group.
534 |
535 |
536 | h2. Maintainers & Contributors
537 |
538 | Formtastic is maintained by "Justin French":http://justinfrench.com, "José Valim":http://github.com/josevalim and "Jonas Grimfelt":http://github.com/grimen, but it wouldn't be as awesome as it is today without help from over 40 contributors.
539 |
540 | @git shortlog -n -s --no-merges@
541 |
542 |
543 | h2. Google Group
544 |
545 | Please join the "Formtastic Google Group":http://groups.google.com.au/group/formtastic, especially if you'd like to talk about a new feature, or report a bug.
546 |
547 |
548 | h2. Project Info
549 |
550 | Formtastic is hosted on Github: "http://github.com/justinfrench/formtastic":http://github.com/justinfrench/formtastic, where your contributions, forkings, comments and feedback are greatly welcomed.
551 |
552 |
553 | Copyright (c) 2007-2008 Justin French, released under the MIT license.
554 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/RELEASE_PROCESS:
--------------------------------------------------------------------------------
1 | git status # check you have a clean working directory
2 | rake version:bump:minor # or patch or major, commits the change
3 | rake gemspec # to generate the new gemspec file
4 | git add formtastic.gemspec # stage changes
5 | git commit -am "new gemspec" # commit and describe the reason for the new gem
6 | git tag -am "0.2.3" 0.2.3 # tag the new version in the code base too
7 | git log 0.2.2..0.2.3 # check the log since last tag
8 | gem build formtastic.gemspec # build the gem
9 | gem push formtastic-0.2.3.gem # publish the gem
10 | git push # push to github
11 | git push --tags # push the tags up to remote too
12 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/Rakefile:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require 'rake'
3 | require 'rake/rdoctask'
4 |
5 | begin
6 | require 'spec/rake/spectask'
7 | rescue LoadError
8 | begin
9 | gem 'rspec-rails', '>= 1.0.0'
10 | require 'spec/rake/spectask'
11 | rescue LoadError
12 | puts "[formtastic:] RSpec - or one of it's dependencies - is not available. Install it with: sudo gem install rspec-rails"
13 | end
14 | end
15 |
16 | begin
17 | GEM = "formtastic"
18 | AUTHOR = "Justin French"
19 | EMAIL = "justin@indent.com.au"
20 | SUMMARY = "A Rails form builder plugin/gem with semantically rich and accessible markup"
21 | HOMEPAGE = "http://github.com/justinfrench/formtastic/tree/master"
22 | INSTALL_MESSAGE = %q{
23 | ========================================================================
24 | Thanks for installing Formtastic!
25 | ------------------------------------------------------------------------
26 | You can now (optionally) run the generator to copy some stylesheets and
27 | a config initializer into your application:
28 | ./script/generate formtastic
29 |
30 | To generate some semantic form markup for your exisiting models, just run:
31 | ./script/generate form MODEL_NAME
32 |
33 | Find out more and get involved:
34 | http://github.com/justinfrench/formtastic
35 | http://groups.google.com.au/group/formtastic
36 | ========================================================================
37 | }
38 |
39 | gem 'jeweler', '>= 1.0.0'
40 | require 'jeweler'
41 |
42 | Jeweler::Tasks.new do |s|
43 | s.name = GEM
44 | s.summary = SUMMARY
45 | s.email = EMAIL
46 | s.homepage = HOMEPAGE
47 | s.description = SUMMARY
48 | s.author = AUTHOR
49 | s.post_install_message = INSTALL_MESSAGE
50 |
51 | s.require_path = 'lib'
52 | s.files = %w(MIT-LICENSE README.textile Rakefile) + Dir.glob("{rails,lib,generators,spec}/**/*")
53 |
54 | # Runtime dependencies: When installing Formtastic these will be checked if they are installed.
55 | # Will be offered to install these if they are not already installed.
56 | s.add_dependency 'activesupport', '>= 2.3.0'
57 | s.add_dependency 'actionpack', '>= 2.3.0'
58 |
59 | # Development dependencies. Not installed by default.
60 | # Install with: sudo gem install formtastic --development
61 | s.add_development_dependency 'rspec-rails', '>= 1.2.6'
62 | s.add_development_dependency 'rspec_tag_matchers', '>= 1.0.0'
63 | end
64 |
65 | Jeweler::GemcutterTasks.new
66 | rescue LoadError
67 | puts "[formtastic:] Jeweler - or one of its dependencies - is not available. Install it with: sudo gem install jeweler -s http://gemcutter.org"
68 | end
69 |
70 | desc 'Default: run unit specs.'
71 | task :default => :spec
72 |
73 | desc 'Generate documentation for the formtastic plugin.'
74 | Rake::RDocTask.new(:rdoc) do |rdoc|
75 | rdoc.rdoc_dir = 'rdoc'
76 | rdoc.title = 'Formtastic'
77 | rdoc.options << '--line-numbers' << '--inline-source'
78 | rdoc.rdoc_files.include('README.textile')
79 | rdoc.rdoc_files.include('lib/**/*.rb')
80 | end
81 |
82 | if defined?(Spec)
83 | desc 'Test the formtastic plugin.'
84 | Spec::Rake::SpecTask.new('spec') do |t|
85 | t.spec_files = FileList['spec/**/*_spec.rb']
86 | t.spec_opts = ["-c"]
87 | end
88 |
89 | desc 'Test the formtastic plugin with specdoc formatting and colors'
90 | Spec::Rake::SpecTask.new('specdoc') do |t|
91 | t.spec_files = FileList['spec/**/*_spec.rb']
92 | t.spec_opts = ["--format specdoc", "-c"]
93 | end
94 |
95 | desc "Run all examples with RCov"
96 | Spec::Rake::SpecTask.new('examples_with_rcov') do |t|
97 | t.spec_files = FileList['spec/**/*_spec.rb']
98 | t.rcov = true
99 | t.rcov_opts = ['--exclude', 'spec,Library']
100 | end
101 | end
102 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/VERSION.yml:
--------------------------------------------------------------------------------
1 | ---
2 | :minor: 9
3 | :patch: 7
4 | :major: 0
5 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/formtastic.gemspec:
--------------------------------------------------------------------------------
1 | # Generated by jeweler
2 | # DO NOT EDIT THIS FILE
3 | # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4 | # -*- encoding: utf-8 -*-
5 |
6 | Gem::Specification.new do |s|
7 | s.name = %q{formtastic}
8 | s.version = "0.9.7"
9 |
10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11 | s.authors = ["Justin French"]
12 | s.date = %q{2009-12-04}
13 | s.description = %q{A Rails form builder plugin/gem with semantically rich and accessible markup}
14 | s.email = %q{justin@indent.com.au}
15 | s.extra_rdoc_files = [
16 | "README.textile"
17 | ]
18 | s.files = [
19 | "MIT-LICENSE",
20 | "README.textile",
21 | "Rakefile",
22 | "generators/form/USAGE",
23 | "generators/form/form_generator.rb",
24 | "generators/form/templates/view__form.html.erb",
25 | "generators/form/templates/view__form.html.haml",
26 | "generators/formtastic/formtastic_generator.rb",
27 | "generators/formtastic/templates/formtastic.css",
28 | "generators/formtastic/templates/formtastic.rb",
29 | "generators/formtastic/templates/formtastic_changes.css",
30 | "generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb",
31 | "lib/formtastic.rb",
32 | "lib/formtastic/i18n.rb",
33 | "lib/locale/en.yml",
34 | "rails/init.rb",
35 | "spec/buttons_spec.rb",
36 | "spec/commit_button_spec.rb",
37 | "spec/custom_builder_spec.rb",
38 | "spec/custom_macros.rb",
39 | "spec/defaults_spec.rb",
40 | "spec/error_proc_spec.rb",
41 | "spec/errors_spec.rb",
42 | "spec/form_helper_spec.rb",
43 | "spec/i18n_spec.rb",
44 | "spec/include_blank_spec.rb",
45 | "spec/input_spec.rb",
46 | "spec/inputs/boolean_input_spec.rb",
47 | "spec/inputs/check_boxes_input_spec.rb",
48 | "spec/inputs/country_input_spec.rb",
49 | "spec/inputs/date_input_spec.rb",
50 | "spec/inputs/datetime_input_spec.rb",
51 | "spec/inputs/file_input_spec.rb",
52 | "spec/inputs/hidden_input_spec.rb",
53 | "spec/inputs/numeric_input_spec.rb",
54 | "spec/inputs/password_input_spec.rb",
55 | "spec/inputs/radio_input_spec.rb",
56 | "spec/inputs/select_input_spec.rb",
57 | "spec/inputs/string_input_spec.rb",
58 | "spec/inputs/text_input_spec.rb",
59 | "spec/inputs/time_input_spec.rb",
60 | "spec/inputs/time_zone_input_spec.rb",
61 | "spec/inputs_spec.rb",
62 | "spec/label_spec.rb",
63 | "spec/semantic_fields_for_spec.rb",
64 | "spec/spec.opts",
65 | "spec/spec_helper.rb"
66 | ]
67 | s.homepage = %q{http://github.com/justinfrench/formtastic/tree/master}
68 | s.post_install_message = %q{
69 | ========================================================================
70 | Thanks for installing Formtastic!
71 | ------------------------------------------------------------------------
72 | You can now (optionally) run the generator to copy some stylesheets and
73 | a config initializer into your application:
74 | ./script/generate formtastic
75 |
76 | To generate some semantic form markup for your exisiting models, just run:
77 | ./script/generate form MODEL_NAME
78 |
79 | Find out more and get involved:
80 | http://github.com/justinfrench/formtastic
81 | http://groups.google.com.au/group/formtastic
82 | ========================================================================
83 | }
84 | s.rdoc_options = ["--charset=UTF-8"]
85 | s.require_paths = ["lib"]
86 | s.rubygems_version = %q{1.3.5}
87 | s.summary = %q{A Rails form builder plugin/gem with semantically rich and accessible markup}
88 | s.test_files = [
89 | "spec/buttons_spec.rb",
90 | "spec/commit_button_spec.rb",
91 | "spec/custom_builder_spec.rb",
92 | "spec/custom_macros.rb",
93 | "spec/defaults_spec.rb",
94 | "spec/error_proc_spec.rb",
95 | "spec/errors_spec.rb",
96 | "spec/form_helper_spec.rb",
97 | "spec/i18n_spec.rb",
98 | "spec/include_blank_spec.rb",
99 | "spec/input_spec.rb",
100 | "spec/inputs/boolean_input_spec.rb",
101 | "spec/inputs/check_boxes_input_spec.rb",
102 | "spec/inputs/country_input_spec.rb",
103 | "spec/inputs/date_input_spec.rb",
104 | "spec/inputs/datetime_input_spec.rb",
105 | "spec/inputs/file_input_spec.rb",
106 | "spec/inputs/hidden_input_spec.rb",
107 | "spec/inputs/numeric_input_spec.rb",
108 | "spec/inputs/password_input_spec.rb",
109 | "spec/inputs/radio_input_spec.rb",
110 | "spec/inputs/select_input_spec.rb",
111 | "spec/inputs/string_input_spec.rb",
112 | "spec/inputs/text_input_spec.rb",
113 | "spec/inputs/time_input_spec.rb",
114 | "spec/inputs/time_zone_input_spec.rb",
115 | "spec/inputs_spec.rb",
116 | "spec/label_spec.rb",
117 | "spec/semantic_fields_for_spec.rb",
118 | "spec/spec_helper.rb"
119 | ]
120 |
121 | if s.respond_to? :specification_version then
122 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
123 | s.specification_version = 3
124 |
125 | if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
126 | s.add_runtime_dependency(%q, [">= 2.3.0"])
127 | s.add_runtime_dependency(%q, [">= 2.3.0"])
128 | s.add_development_dependency(%q, [">= 1.2.6"])
129 | s.add_development_dependency(%q, [">= 1.0.0"])
130 | else
131 | s.add_dependency(%q, [">= 2.3.0"])
132 | s.add_dependency(%q, [">= 2.3.0"])
133 | s.add_dependency(%q, [">= 1.2.6"])
134 | s.add_dependency(%q, [">= 1.0.0"])
135 | end
136 | else
137 | s.add_dependency(%q, [">= 2.3.0"])
138 | s.add_dependency(%q, [">= 2.3.0"])
139 | s.add_dependency(%q, [">= 1.2.6"])
140 | s.add_dependency(%q, [">= 1.0.0"])
141 | end
142 | end
143 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/form/USAGE:
--------------------------------------------------------------------------------
1 | NAME
2 | form - Formtastic form generator.
3 |
4 | DESCRIPTION
5 | Generates formtastic form code based on an existing model. By default the generated code will be printed out directly in the terminal, and also copied to clipboard. Can optionally be saved into partial directly.
6 |
7 | Required:
8 | ExistingModelName - The name of an existing model for which the generator should generate form code.
9 |
10 | Options:
11 | --haml Generate HAML instead of ERB.
12 | --partial Generate a form partial in the model views path, i.e. "_form.html.erb" or _form.html.haml".
13 | --controller PATH Generate for custom controller/view path - in case model and controller namespace is different, i.e. "admin/posts".
14 |
15 | EXAMPLE
16 | ./script/generate form ExistingModelName [--haml] [--partial]
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/form/form_generator.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | # Get current OS - needed for clipboard functionality
3 | case RUBY_PLATFORM
4 | when /darwin/ then
5 | CURRENT_OS = :osx
6 | when /win32/
7 | CURRENT_OS = :win
8 | begin
9 | require 'win32/clipboard'
10 | rescue LoadError
11 | # Do nothing
12 | end
13 | else
14 | CURRENT_OS = :x
15 | end
16 |
17 | class FormGenerator < Rails::Generator::NamedBase
18 |
19 | default_options :haml => false,
20 | :partial => false
21 |
22 | VIEWS_PATH = File.join('app', 'views').freeze
23 | IGNORED_COLUMNS = [:updated_at, :created_at].freeze
24 |
25 | attr_reader :controller_file_name,
26 | :controller_class_path,
27 | :controller_class_nesting,
28 | :controller_class_nesting_depth,
29 | :controller_class_name,
30 | :template_type
31 |
32 | def initialize(runtime_args, runtime_options = {})
33 | super
34 | base_name, @controller_class_path = extract_modules(@name.pluralize)
35 | controller_class_name_without_nesting, @controller_file_name = inflect_names(base_name)
36 | @template_type = options[:haml] ? :haml : :erb
37 | end
38 |
39 | def manifest
40 | record do |m|
41 | if options[:partial]
42 | controller_and_view_path = options[:controller] || File.join(controller_class_path, controller_file_name)
43 | # Ensure directory exists.
44 | m.directory File.join(VIEWS_PATH, controller_and_view_path)
45 | # Create a form partial for the model as "_form" in it's views path.
46 | m.template "view__form.html.#{template_type}", File.join(VIEWS_PATH, controller_and_view_path, "_form.html.#{template_type}")
47 | else
48 | # Load template file, and render without saving to file
49 | template = File.read(File.join(source_root, "view__form.html.#{template_type}"))
50 | erb = ERB.new(template, nil, '-')
51 | generated_code = erb.result(binding).strip rescue nil
52 |
53 | # Print the result, and copy to clipboard
54 | puts "# ---------------------------------------------------------"
55 | puts "# GENERATED FORMTASTIC CODE"
56 | puts "# ---------------------------------------------------------"
57 | puts
58 | puts generated_code || " Nothing could be generated - model exists?"
59 | puts
60 | puts "# ---------------------------------------------------------"
61 | puts " Copied to clipboard - just paste it!" if save_to_clipboard(generated_code)
62 | end
63 | end
64 | end
65 |
66 | protected
67 |
68 | # Save to lipboard with multiple OS support.
69 | def save_to_clipboard(data)
70 | return unless data
71 | begin
72 | case CURRENT_OS
73 | when :osx
74 | `echo "#{data}" | pbcopy`
75 | when :win
76 | ::Win32::Clipboard.data = data
77 | else # :linux/:unix
78 | `echo "#{data}" | xsel --clipboard` || `echo "#{data}" | xclip`
79 | end
80 | rescue
81 | false
82 | else
83 | true
84 | end
85 | end
86 |
87 | # Add additional model attributes if specified in args - probably not that common scenario.
88 | def attributes
89 | # Get columns for the requested model.
90 | existing_attributes = @class_name.constantize.content_columns.reject { |column| IGNORED_COLUMNS.include?(column.name.to_sym) }
91 | @args = super + existing_attributes
92 | end
93 |
94 | def add_options!(opt)
95 | opt.separator ''
96 | opt.separator 'Options:'
97 |
98 | # Allow option to generate HAML views instead of ERB.
99 | opt.on('--haml',
100 | "Generate HAML output instead of the default ERB.") do |v|
101 | options[:haml] = v
102 | end
103 |
104 | # Allow option to generate to partial in model's views path, instead of printing out in terminal.
105 | opt.on('--partial',
106 | "Save generated output directly to a form partial (app/views/{resource}/_form.html.*).") do |v|
107 | options[:partial] = v
108 | end
109 |
110 | opt.on('--controller CONTROLLER_PATH',
111 | "Specify a non-standard controller for the specified model (e.g. admin/posts).") do |v|
112 | options[:controller] = v if v.present?
113 | end
114 | end
115 |
116 | def banner
117 | "Usage: #{$0} form ExistingModelName [--haml] [--partial]"
118 | end
119 |
120 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/form/templates/view__form.html.erb:
--------------------------------------------------------------------------------
1 | <%% f.inputs do %>
2 | <% attributes.each do |attribute| -%>
3 | <%%= f.input :<%= attribute.name %>, :label => '<%= attribute.name.humanize %>' %>
4 | <% end -%>
5 | <%% end %>
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/form/templates/view__form.html.haml:
--------------------------------------------------------------------------------
1 | - f.inputs do
2 | <% attributes.each do |attribute| -%>
3 | = f.input :<%= attribute.name %>, :label => '<%= attribute.name.humanize %>'
4 | <% end -%>
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/formtastic/formtastic_generator.rb:
--------------------------------------------------------------------------------
1 | class FormtasticGenerator < Rails::Generator::Base
2 |
3 | def initialize(*runtime_args)
4 | super
5 | end
6 |
7 | def manifest
8 | record do |m|
9 | m.directory File.join('config', 'initializers')
10 | m.template 'formtastic_config.rb', File.join('config', 'initializers', 'formtastic_config.rb')
11 |
12 | m.directory File.join('public', 'stylesheets')
13 | m.template 'formtastic.css', File.join('public', 'stylesheets', 'formtastic.css')
14 | m.template 'formtastic_changes.css', File.join('public', 'stylesheets', 'formtastic_changes.css')
15 | end
16 | end
17 |
18 | protected
19 |
20 | def banner
21 | %{Usage: #{$0} #{spec.name}\nCopies formtastic.css and formtastic_changes.css to public/stylesheets/ and a config initializer to config/initializers/formtastic_config.rb}
22 | end
23 |
24 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/formtastic/templates/formtastic.css:
--------------------------------------------------------------------------------
1 | /* -------------------------------------------------------------------------------------------------
2 |
3 | It's *strongly* suggested that you don't modify this file. Instead, load a new stylesheet after
4 | this one in your layouts (eg formtastic_changes.css) and override the styles to suit your needs.
5 | This will allow you to update formtastic.css with new releases without clobbering your own changes.
6 |
7 | This stylesheet forms part of the Formtastic Rails Plugin
8 | (c) 2008 Justin French
9 |
10 | --------------------------------------------------------------------------------------------------*/
11 |
12 |
13 | /* NORMALIZE AND RESET - obviously inspired by Yahoo's reset.css, but scoped to just form.formtastic
14 | --------------------------------------------------------------------------------------------------*/
15 | form.formtastic, form.formtastic ul, form.formtastic ol, form.formtastic li, form.formtastic fieldset, form.formtastic legend, form.formtastic input, form.formtastic textarea, form.formtastic select, form.formtastic p { margin:0; padding:0; }
16 | form.formtastic fieldset { border:0; }
17 | form.formtastic em, form.formtastic strong { font-style:normal; font-weight:normal; }
18 | form.formtastic ol, form.formtastic ul { list-style:none; }
19 | form.formtastic abbr, form.formtastic acronym { border:0; font-variant:normal; }
20 | form.formtastic input, form.formtastic textarea, form.formtastic select { font-family:inherit; font-size:inherit; font-weight:inherit; }
21 | form.formtastic input, form.formtastic textarea, form.formtastic select { font-size:100%; }
22 | form.formtastic legend { color:#000; }
23 |
24 |
25 | /* SEMANTIC ERRORS
26 | --------------------------------------------------------------------------------------------------*/
27 | form.formtastic ul.errors { color:#cc0000; margin:0.5em 0 1.5em 25%; list-style:square; }
28 | form.formtastic ul.errors li { padding:0; border:none; display:list-item; }
29 |
30 |
31 | /* FIELDSETS & LISTS
32 | --------------------------------------------------------------------------------------------------*/
33 | form.formtastic fieldset { }
34 | form.formtastic fieldset.inputs { }
35 | form.formtastic fieldset.buttons { padding-left:25%; }
36 | form.formtastic fieldset ol { }
37 | form.formtastic fieldset.buttons li { float:left; padding-right:0.5em; }
38 |
39 | /* clearfixing the fieldsets */
40 | form.formtastic fieldset { display: inline-block; }
41 | form.formtastic fieldset:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
42 | html[xmlns] form.formtastic fieldset { display: block; }
43 | * html form.formtastic fieldset { height: 1%; }
44 |
45 |
46 | /* INPUT LIs
47 | --------------------------------------------------------------------------------------------------*/
48 | form.formtastic fieldset ol li { margin-bottom:1.5em; }
49 |
50 | /* clearfixing the li's */
51 | form.formtastic fieldset ol li { display: inline-block; }
52 | form.formtastic fieldset ol li:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
53 | html[xmlns] form.formtastic fieldset ol li { display: block; }
54 | * html form.formtastic fieldset ol li { height: 1%; }
55 |
56 | form.formtastic fieldset ol li.required { }
57 | form.formtastic fieldset ol li.optional { }
58 | form.formtastic fieldset ol li.error { }
59 |
60 |
61 | /* LABELS
62 | --------------------------------------------------------------------------------------------------*/
63 | form.formtastic fieldset ol li label { display:block; width:25%; float:left; padding-top:.2em; }
64 | form.formtastic fieldset ol li li label { line-height:100%; padding-top:0; }
65 | form.formtastic fieldset ol li li label input { line-height:100%; vertical-align:middle; margin-top:-0.1em;}
66 |
67 |
68 | /* NESTED FIELDSETS AND LEGENDS (radio, check boxes and date/time inputs use nested fieldsets)
69 | --------------------------------------------------------------------------------------------------*/
70 | form.formtastic fieldset ol li fieldset { position:relative; }
71 | form.formtastic fieldset ol li fieldset legend { position:absolute; width:25%; padding-top:0.1em; }
72 | form.formtastic fieldset ol li fieldset legend span { position:absolute; }
73 | form.formtastic fieldset ol li fieldset legend.label label { position:absolute; }
74 | form.formtastic fieldset ol li fieldset ol { float:left; width:74%; margin:0; padding:0 0 0 25%; }
75 | form.formtastic fieldset ol li fieldset ol li { padding:0; border:0; }
76 |
77 |
78 | /* INLINE HINTS
79 | --------------------------------------------------------------------------------------------------*/
80 | form.formtastic fieldset ol li p.inline-hints { color:#666; margin:0.5em 0 0 25%; }
81 |
82 |
83 | /* INLINE ERRORS
84 | --------------------------------------------------------------------------------------------------*/
85 | form.formtastic fieldset ol li p.inline-errors { color:#cc0000; margin:0.5em 0 0 25%; }
86 | form.formtastic fieldset ol li ul.errors { color:#cc0000; margin:0.5em 0 0 25%; list-style:square; }
87 | form.formtastic fieldset ol li ul.errors li { padding:0; border:none; display:list-item; }
88 |
89 |
90 | /* STRING & NUMERIC OVERRIDES
91 | --------------------------------------------------------------------------------------------------*/
92 | form.formtastic fieldset ol li.string input { width:74%; }
93 | form.formtastic fieldset ol li.password input { width:74%; }
94 | form.formtastic fieldset ol li.numeric input { width:74%; }
95 |
96 |
97 | /* TEXTAREA OVERRIDES
98 | --------------------------------------------------------------------------------------------------*/
99 | form.formtastic fieldset ol li.text textarea { width:74%; }
100 |
101 |
102 | /* HIDDEN OVERRIDES
103 | --------------------------------------------------------------------------------------------------*/
104 | form.formtastic fieldset ol li.hidden { display:none; }
105 |
106 |
107 | /* BOOLEAN OVERRIDES
108 | --------------------------------------------------------------------------------------------------*/
109 | form.formtastic fieldset ol li.boolean label { padding-left:25%; width:auto; }
110 | form.formtastic fieldset ol li.boolean label input { margin:0 0.5em 0 0.2em; }
111 |
112 |
113 | /* RADIO OVERRIDES
114 | --------------------------------------------------------------------------------------------------*/
115 | form.formtastic fieldset ol li.radio { }
116 | form.formtastic fieldset ol li.radio fieldset ol { margin-bottom:-0.6em; }
117 | form.formtastic fieldset ol li.radio fieldset ol li { margin:0.1em 0 0.5em 0; }
118 | form.formtastic fieldset ol li.radio fieldset ol li label { float:none; width:100%; }
119 | form.formtastic fieldset ol li.radio fieldset ol li label input { margin-right:0.2em; }
120 |
121 |
122 | /* CHECK BOXES (COLLECTION) OVERRIDES
123 | --------------------------------------------------------------------------------------------------*/
124 | form.formtastic fieldset ol li.check_boxes { }
125 | form.formtastic fieldset ol li.check_boxes fieldset ol { margin-bottom:-0.6em; }
126 | form.formtastic fieldset ol li.check_boxes fieldset ol li { margin:0.1em 0 0.5em 0; }
127 | form.formtastic fieldset ol li.check_boxes fieldset ol li label { float:none; width:100%; }
128 | form.formtastic fieldset ol li.check_boxes fieldset ol li label input { margin-right:0.2em; }
129 |
130 |
131 |
132 | /* DATE & TIME OVERRIDES
133 | --------------------------------------------------------------------------------------------------*/
134 | form.formtastic fieldset ol li.date fieldset ol li,
135 | form.formtastic fieldset ol li.time fieldset ol li,
136 | form.formtastic fieldset ol li.datetime fieldset ol li { float:left; width:auto; margin:0 .3em 0 0; }
137 |
138 | form.formtastic fieldset ol li.date fieldset ol li label,
139 | form.formtastic fieldset ol li.time fieldset ol li label,
140 | form.formtastic fieldset ol li.datetime fieldset ol li label { display:none; }
141 |
142 | form.formtastic fieldset ol li.date fieldset ol li label input,
143 | form.formtastic fieldset ol li.time fieldset ol li label input,
144 | form.formtastic fieldset ol li.datetime fieldset ol li label input { display:inline; margin:0; padding:0; }
145 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/formtastic/templates/formtastic_changes.css:
--------------------------------------------------------------------------------
1 | /* -------------------------------------------------------------------------------------------------
2 |
3 | Load this stylesheet after formtastic.css in your layouts to override the CSS to suit your needs.
4 | This will allow you to update formtastic.css with new releases without clobbering your own changes.
5 |
6 | For example, to make the inline hint paragraphs a little darker in color than the standard #666:
7 |
8 | form.formtastic fieldset ol li p.inline-hints { color:#333; }
9 |
10 | --------------------------------------------------------------------------------------------------*/
11 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/formtastic/templates/formtastic_config.rb:
--------------------------------------------------------------------------------
1 | # Set the default text field size when input is a string. Default is 50.
2 | # Formtastic::SemanticFormBuilder.default_text_field_size = 50
3 |
4 | # Set the default text area height when input is a text. Default is 20.
5 | # Formtastic::SemanticFormBuilder.default_text_area_height = 5
6 |
7 | # Should all fields be considered "required" by default?
8 | # Defaults to true, see ValidationReflection notes below.
9 | # Formtastic::SemanticFormBuilder.all_fields_required_by_default = true
10 |
11 | # Should select fields have a blank option/prompt by default?
12 | # Defaults to true.
13 | # Formtastic::SemanticFormBuilder.include_blank_for_select_by_default = true
14 |
15 | # Set the string that will be appended to the labels/fieldsets which are required
16 | # It accepts string or procs and the default is a localized version of
17 | # '* '. In other words, if you configure formtastic.required
18 | # in your locale, it will replace the abbr title properly. But if you don't want to use
19 | # abbr tag, you can simply give a string as below
20 | # Formtastic::SemanticFormBuilder.required_string = "(required)"
21 |
22 | # Set the string that will be appended to the labels/fieldsets which are optional
23 | # Defaults to an empty string ("") and also accepts procs (see required_string above)
24 | # Formtastic::SemanticFormBuilder.optional_string = "(optional)"
25 |
26 | # Set the way inline errors will be displayed.
27 | # Defaults to :sentence, valid options are :sentence, :list and :none
28 | # Formtastic::SemanticFormBuilder.inline_errors = :sentence
29 |
30 | # Set the method to call on label text to transform or format it for human-friendly
31 | # reading when formtastic is user without object. Defaults to :humanize.
32 | # Formtastic::SemanticFormBuilder.label_str_method = :humanize
33 |
34 | # Set the array of methods to try calling on parent objects in :select and :radio inputs
35 | # for the text inside each @@ tag or alongside each radio @ @. The first method
36 | # that is found on the object will be used.
37 | # Defaults to ["to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"]
38 | # Formtastic::SemanticFormBuilder.collection_label_methods = [
39 | # "to_label", "display_name", "full_name", "name", "title", "username", "login", "value", "to_s"]
40 |
41 | # Formtastic by default renders inside li tags the input, hints and then
42 | # errors messages. Sometimes you want the hints to be rendered first than
43 | # the input, in the following order: hints, input and errors. You can
44 | # customize it doing just as below:
45 | # Formtastic::SemanticFormBuilder.inline_order = [:input, :hints, :errors]
46 |
47 | # Specifies if labels/hints for input fields automatically be looked up using I18n.
48 | # Default value: false. Overridden for specific fields by setting value to true,
49 | # i.e. :label => true, or :hint => true (or opposite depending on initialized value)
50 | # Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
51 |
52 | # You can add custom inputs or override parts of Formtastic by subclassing SemanticFormBuilder and
53 | # specifying that class here. Defaults to SemanticFormBuilder.
54 | # Formtastic::SemanticFormHelper.builder = MyCustomBuilder
55 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb:
--------------------------------------------------------------------------------
1 | class FormtasticStylesheetsGenerator < Rails::Generator::Base
2 |
3 | def initialize(*runtime_args)
4 | puts %q{
5 | ===================================================
6 | Please run `./script/generate formtastic` instead.
7 | ===================================================
8 | }
9 | end
10 |
11 | def manifest
12 | record do |m|
13 | end
14 | end
15 |
16 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/install.rb:
--------------------------------------------------------------------------------
1 | puts "Run `./script/generate formtastic` if you want (copies optional config file and some stylesheets into your app)"
2 | puts "Run `./script/generate form MODEL_NAME` to generate some semantic form markup for any existing model(s) (optional)"
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/lib/formtastic/i18n.rb:
--------------------------------------------------------------------------------
1 | module Formtastic
2 | module I18n
3 |
4 | DEFAULT_SCOPE = [:formtastic].freeze
5 | DEFAULT_VALUES = {
6 | :required => 'required',
7 | :yes => 'Yes',
8 | :no => 'No',
9 | :create => 'Create {{model}}',
10 | :update => 'Update {{model}}'
11 | }.freeze
12 | SCOPES = [
13 | '{{model}}.{{action}}.{{attribute}}',
14 | '{{model}}.{{attribute}}',
15 | '{{attribute}}'
16 | ]
17 |
18 | class << self
19 |
20 | def translate(*args)
21 | key = args.shift.to_sym
22 | options = args.extract_options!
23 | options.reverse_merge!(:default => DEFAULT_VALUES[key])
24 | options[:scope] = [DEFAULT_SCOPE, options[:scope]].flatten.compact
25 | ::I18n.translate(key, *(args << options))
26 | end
27 | alias :t :translate
28 |
29 | end
30 |
31 | end
32 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/lib/locale/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | formtastic:
3 | :yes: 'Yes'
4 | :no: 'No'
5 | create: 'Create'
6 | save: 'Save'
7 | submit: 'Submit'
8 | required: 'Required'
9 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/rails/init.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.join(File.dirname(__FILE__), *%w[.. lib formtastic])
3 | ActionView::Base.send :include, Formtastic::SemanticFormHelper
4 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/buttons_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'SemanticFormBuilder#buttons' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe 'with a block' do
14 | describe 'when no options are provided' do
15 | before do
16 | semantic_form_for(@new_post) do |builder|
17 | builder.buttons do
18 | concat('hello')
19 | end
20 | end
21 | end
22 |
23 | it 'should render a fieldset inside the form, with a class of "inputs"' do
24 | output_buffer.should have_tag("form fieldset.buttons")
25 | end
26 |
27 | it 'should render an ol inside the fieldset' do
28 | output_buffer.should have_tag("form fieldset.buttons ol")
29 | end
30 |
31 | it 'should render the contents of the block inside the ol' do
32 | output_buffer.should have_tag("form fieldset.buttons ol", /hello/)
33 | end
34 |
35 | it 'should not render a legend inside the fieldset' do
36 | output_buffer.should_not have_tag("form fieldset.buttons legend")
37 | end
38 | end
39 |
40 | describe 'when a :name option is provided' do
41 | before do
42 | @legend_text = "Advanced options"
43 |
44 | semantic_form_for(@new_post) do |builder|
45 | builder.buttons :name => @legend_text do
46 | end
47 | end
48 | end
49 | it 'should render a fieldset inside the form' do
50 | output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
51 | end
52 | end
53 |
54 | describe 'when other options are provided' do
55 | before do
56 | @id_option = 'advanced'
57 | @class_option = 'wide'
58 |
59 | semantic_form_for(@new_post) do |builder|
60 | builder.buttons :id => @id_option, :class => @class_option do
61 | end
62 | end
63 | end
64 | it 'should pass the options into the fieldset tag as attributes' do
65 | output_buffer.should have_tag("form fieldset##{@id_option}")
66 | output_buffer.should have_tag("form fieldset.#{@class_option}")
67 | end
68 | end
69 |
70 | end
71 |
72 | describe 'without a block' do
73 |
74 | describe 'with no args (default buttons)' do
75 |
76 | before do
77 | semantic_form_for(@new_post) do |builder|
78 | concat(builder.buttons)
79 | end
80 | end
81 |
82 | it 'should render a form' do
83 | output_buffer.should have_tag('form')
84 | end
85 |
86 | it 'should render a buttons fieldset inside the form' do
87 | output_buffer.should have_tag('form fieldset.buttons')
88 | end
89 |
90 | it 'should not render a legend in the fieldset' do
91 | output_buffer.should_not have_tag('form fieldset.buttons legend')
92 | end
93 |
94 | it 'should render an ol in the fieldset' do
95 | output_buffer.should have_tag('form fieldset.buttons ol')
96 | end
97 |
98 | it 'should render a list item in the ol for each default button' do
99 | output_buffer.should have_tag('form fieldset.buttons ol li', :count => 1)
100 | end
101 |
102 | it 'should render a commit list item for the commit button' do
103 | output_buffer.should have_tag('form fieldset.buttons ol li.commit')
104 | end
105 |
106 | end
107 |
108 | describe 'with button names as args' do
109 |
110 | before do
111 | semantic_form_for(@new_post) do |builder|
112 | concat(builder.buttons(:commit))
113 | end
114 | end
115 |
116 | it 'should render a form with a fieldset containing a list item for each button arg' do
117 | output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
118 | output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit')
119 | end
120 |
121 | end
122 |
123 | describe 'with button names as args and an options hash' do
124 |
125 | before do
126 | semantic_form_for(@new_post) do |builder|
127 | concat(builder.buttons(:commit, :name => "Now click a button", :id => "my-id"))
128 | end
129 | end
130 |
131 | it 'should render a form with a fieldset containing a list item for each button arg' do
132 | output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
133 | output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit', :count => 1)
134 | end
135 |
136 | it 'should pass the options down to the fieldset' do
137 | output_buffer.should have_tag('form > fieldset#my-id.buttons')
138 | end
139 |
140 | it 'should use the special :name option as a text for the legend tag' do
141 | output_buffer.should have_tag('form > fieldset#my-id.buttons > legend', /Now click a button/)
142 | end
143 |
144 | end
145 |
146 | end
147 |
148 | end
149 |
150 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/commit_button_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'SemanticFormBuilder#commit_button' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe 'when used on any record' do
14 |
15 | before do
16 | @new_post.stub!(:new_record?).and_return(false)
17 | semantic_form_for(@new_post) do |builder|
18 | concat(builder.commit_button)
19 | end
20 | end
21 |
22 | it 'should render a commit li' do
23 | output_buffer.should have_tag('li.commit')
24 | end
25 |
26 | it 'should render an input with a type attribute of "submit"' do
27 | output_buffer.should have_tag('li.commit input[@type="submit"]')
28 | end
29 |
30 | it 'should render an input with a name attribute of "commit"' do
31 | output_buffer.should have_tag('li.commit input[@name="commit"]')
32 | end
33 |
34 | it 'should pass options given in :button_html to the button' do
35 | @new_post.stub!(:new_record?).and_return(false)
36 | semantic_form_for(@new_post) do |builder|
37 | concat(builder.commit_button('text', :button_html => {:class => 'my_class', :id => 'my_id'}))
38 | end
39 |
40 | output_buffer.should have_tag('li.commit input#my_id')
41 | output_buffer.should have_tag('li.commit input.my_class')
42 | end
43 |
44 | end
45 |
46 | describe "its accesskey" do
47 |
48 | it 'should allow nil default' do
49 | with_config :default_commit_button_accesskey, nil do
50 | output_buffer.should_not have_tag('li.commit input[@accesskey]')
51 | end
52 | end
53 |
54 | it 'should use the default if set' do
55 | with_config :default_commit_button_accesskey, 's' do
56 | @new_post.stub!(:new_record?).and_return(false)
57 | semantic_form_for(@new_post) do |builder|
58 | concat(builder.commit_button('text', :button_html => {}))
59 | end
60 | output_buffer.should have_tag('li.commit input[@accesskey="s"]')
61 | end
62 | end
63 |
64 | it 'should use the value set in options over the default' do
65 | with_config :default_commit_button_accesskey, 's' do
66 | @new_post.stub!(:new_record?).and_return(false)
67 | semantic_form_for(@new_post) do |builder|
68 | concat(builder.commit_button('text', :accesskey => 'o'))
69 | end
70 | output_buffer.should_not have_tag('li.commit input[@accesskey="s"]')
71 | output_buffer.should have_tag('li.commit input[@accesskey="o"]')
72 | end
73 | end
74 |
75 | it 'should use the value set in button_html over options' do
76 | with_config :default_commit_button_accesskey, 's' do
77 | @new_post.stub!(:new_record?).and_return(false)
78 | semantic_form_for(@new_post) do |builder|
79 | concat(builder.commit_button('text', :accesskey => 'o', :button_html => {:accesskey => 't'}))
80 | end
81 | output_buffer.should_not have_tag('li.commit input[@accesskey="s"]')
82 | output_buffer.should_not have_tag('li.commit input[@accesskey="o"]')
83 | output_buffer.should have_tag('li.commit input[@accesskey="t"]')
84 | end
85 | end
86 |
87 | end
88 |
89 | describe 'when the first option is a string and the second is a hash' do
90 |
91 | before do
92 | @new_post.stub!(:new_record?).and_return(false)
93 | semantic_form_for(@new_post) do |builder|
94 | concat(builder.commit_button("a string", :button_html => { :class => "pretty"}))
95 | end
96 | end
97 |
98 | it "should render the string as the value of the button" do
99 | output_buffer.should have_tag('li input[@value="a string"]')
100 | end
101 |
102 | it "should deal with the options hash" do
103 | output_buffer.should have_tag('li input.pretty')
104 | end
105 |
106 | end
107 |
108 | describe 'when the first option is a hash' do
109 |
110 | before do
111 | @new_post.stub!(:new_record?).and_return(false)
112 | semantic_form_for(@new_post) do |builder|
113 | concat(builder.commit_button(:button_html => { :class => "pretty"}))
114 | end
115 | end
116 |
117 | it "should deal with the options hash" do
118 | output_buffer.should have_tag('li input.pretty')
119 | end
120 |
121 | end
122 |
123 | describe 'label' do
124 | before do
125 | ::Post.stub!(:human_name).and_return('Post')
126 | end
127 |
128 | # No object
129 | describe 'when used without object' do
130 | describe 'when explicit label is provided' do
131 | it 'should render an input with the explicitly specified label' do
132 | semantic_form_for(:post, :url => 'http://example.com') do |builder|
133 | concat(builder.commit_button("Click!"))
134 | end
135 | output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="submit"]')
136 | end
137 | end
138 |
139 | describe 'when no explicit label is provided' do
140 | describe 'when no I18n-localized label is provided' do
141 | before do
142 | ::I18n.backend.store_translations :en, :formtastic => {:submit => 'Submit {{model}}'}
143 | end
144 |
145 | after do
146 | ::I18n.backend.store_translations :en, :formtastic => {:submit => nil}
147 | end
148 |
149 | it 'should render an input with default I18n-localized label (fallback)' do
150 | semantic_form_for(:post, :url => 'http://example.com') do |builder|
151 | concat(builder.commit_button)
152 | end
153 | output_buffer.should have_tag('li.commit input[@value="Submit Post"][@class~="submit"]')
154 | end
155 | end
156 |
157 | describe 'when I18n-localized label is provided' do
158 | before do
159 | ::I18n.backend.store_translations :en,
160 | :formtastic => {
161 | :actions => {
162 | :submit => 'Custom Submit',
163 | :post => {
164 | :submit => 'Custom Submit {{model}}'
165 | }
166 | }
167 | }
168 | ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
169 | end
170 |
171 | it 'should render an input with localized label (I18n)' do
172 | semantic_form_for(:post, :url => 'http://example.com') do |builder|
173 | concat(builder.commit_button)
174 | end
175 | output_buffer.should have_tag(%Q{li.commit input[@value="Custom Submit Post"][@class~="submit"]})
176 | end
177 |
178 | it 'should render an input with anoptional localized label (I18n) - if first is not set' do
179 | ::I18n.backend.store_translations :en,
180 | :formtastic => {
181 | :actions => {
182 | :post => {
183 | :submit => nil
184 | }
185 | }
186 | }
187 | semantic_form_for(:post, :url => 'http://example.com') do |builder|
188 | concat(builder.commit_button)
189 | end
190 | output_buffer.should have_tag(%Q{li.commit input[@value="Custom Submit"][@class~="submit"]})
191 | end
192 |
193 | end
194 | end
195 | end
196 |
197 | # New record
198 | describe 'when used on a new record' do
199 | before do
200 | @new_post.stub!(:new_record?).and_return(true)
201 | end
202 |
203 | describe 'when explicit label is provided' do
204 | it 'should render an input with the explicitly specified label' do
205 | semantic_form_for(@new_post) do |builder|
206 | concat(builder.commit_button("Click!"))
207 | end
208 | output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="create"]')
209 | end
210 | end
211 |
212 | describe 'when no explicit label is provided' do
213 | describe 'when no I18n-localized label is provided' do
214 | before do
215 | ::I18n.backend.store_translations :en, :formtastic => {:create => 'Create {{model}}'}
216 | end
217 |
218 | after do
219 | ::I18n.backend.store_translations :en, :formtastic => {:create => nil}
220 | end
221 |
222 | it 'should render an input with default I18n-localized label (fallback)' do
223 | semantic_form_for(@new_post) do |builder|
224 | concat(builder.commit_button)
225 | end
226 | output_buffer.should have_tag('li.commit input[@value="Create Post"][@class~="create"]')
227 | end
228 | end
229 |
230 | describe 'when I18n-localized label is provided' do
231 | before do
232 | ::I18n.backend.store_translations :en,
233 | :formtastic => {
234 | :actions => {
235 | :create => 'Custom Create',
236 | :post => {
237 | :create => 'Custom Create {{model}}'
238 | }
239 | }
240 | }
241 | ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
242 | end
243 |
244 | after do
245 | ::I18n.backend.store_translations :en, :formtastic => nil
246 | end
247 |
248 | it 'should render an input with localized label (I18n)' do
249 | semantic_form_for(@new_post) do |builder|
250 | concat(builder.commit_button)
251 | end
252 | output_buffer.should have_tag(%Q{li.commit input[@value="Custom Create Post"][@class~="create"]})
253 | end
254 |
255 | it 'should render an input with anoptional localized label (I18n) - if first is not set' do
256 | ::I18n.backend.store_translations :en,
257 | :formtastic => {
258 | :actions => {
259 | :post => {
260 | :create => nil
261 | }
262 | }
263 | }
264 | semantic_form_for(@new_post) do |builder|
265 | concat(builder.commit_button)
266 | end
267 | output_buffer.should have_tag(%Q{li.commit input[@value="Custom Create"][@class~="create"]})
268 | ::I18n.backend.store_translations :en, :formtastic => nil
269 |
270 | end
271 |
272 | end
273 | end
274 | end
275 |
276 | # Existing record
277 | describe 'when used on an existing record' do
278 | before do
279 | @new_post.stub!(:new_record?).and_return(false)
280 | end
281 |
282 | describe 'when explicit label is provided' do
283 | it 'should render an input with the explicitly specified label' do
284 | semantic_form_for(@new_post) do |builder|
285 | concat(builder.commit_button("Click!"))
286 | end
287 | output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="update"]')
288 | end
289 | end
290 |
291 | describe 'when no explicit label is provided' do
292 | describe 'when no I18n-localized label is provided' do
293 | before do
294 | ::I18n.backend.store_translations :en, :formtastic => {:update => 'Save {{model}}'}
295 | end
296 |
297 | after do
298 | ::I18n.backend.store_translations :en, :formtastic => {:update => nil}
299 | end
300 |
301 | it 'should render an input with default I18n-localized label (fallback)' do
302 | semantic_form_for(@new_post) do |builder|
303 | concat(builder.commit_button)
304 | end
305 | output_buffer.should have_tag('li.commit input[@value="Save Post"][@class~="update"]')
306 | end
307 | end
308 |
309 | describe 'when I18n-localized label is provided' do
310 | before do
311 | ::I18n.backend.store_translations :en,
312 | :formtastic => {
313 | :actions => {
314 | :update => 'Custom Save',
315 | :post => {
316 | :update => 'Custom Save {{model}}'
317 | }
318 | }
319 | }
320 | ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
321 | end
322 |
323 | it 'should render an input with localized label (I18n)' do
324 | semantic_form_for(@new_post) do |builder|
325 | concat(builder.commit_button)
326 | end
327 | output_buffer.should have_tag(%Q{li.commit input[@value="Custom Save Post"][@class~="update"]})
328 | end
329 |
330 | it 'should render an input with anoptional localized label (I18n) - if first is not set' do
331 | ::I18n.backend.store_translations :en,
332 | :formtastic => {
333 | :actions => {
334 | :post => {
335 | :update => nil
336 | }
337 | }
338 | }
339 | semantic_form_for(@new_post) do |builder|
340 | concat(builder.commit_button)
341 | end
342 | output_buffer.should have_tag(%Q{li.commit input[@value="Custom Save"][@class~="update"]})
343 | ::I18n.backend.store_translations :en, :formtastic => {}
344 | end
345 |
346 | end
347 | end
348 | end
349 | end
350 |
351 | describe 'when the model is two words' do
352 | before do
353 | output_buffer = ''
354 | class ::UserPost; def id; end; end
355 | @new_user_post = ::UserPost.new
356 |
357 | @new_user_post.stub!(:new_record?).and_return(true)
358 | semantic_form_for(@new_user_post, :url => '') do |builder|
359 | concat(builder.commit_button())
360 | end
361 | end
362 |
363 | it "should render the string as the value of the button" do
364 | output_buffer.should have_tag('li input[@value="Create User post"]')
365 | end
366 |
367 | end
368 |
369 | end
370 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/custom_builder_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'Formtastic::SemanticFormHelper.builder' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | class MyCustomFormBuilder < ::Formtastic::SemanticFormBuilder
9 | def awesome_input(method, options)
10 | self.text_field(method)
11 | end
12 | end
13 |
14 | before do
15 | @output_buffer = ''
16 | mock_everything
17 | end
18 |
19 | it 'is the Formtastic::SemanticFormBuilder by default' do
20 | ::Formtastic::SemanticFormHelper.builder.should == ::Formtastic::SemanticFormBuilder
21 | end
22 |
23 | it 'can be configured to use your own custom form builder' do
24 | # Set it to a custom builder class
25 | ::Formtastic::SemanticFormHelper.builder = MyCustomFormBuilder
26 | ::Formtastic::SemanticFormHelper.builder.should == MyCustomFormBuilder
27 |
28 | # Reset it to the default
29 | ::Formtastic::SemanticFormHelper.builder = ::Formtastic::SemanticFormBuilder
30 | ::Formtastic::SemanticFormHelper.builder.should == ::Formtastic::SemanticFormBuilder
31 | end
32 |
33 | describe "when using a custom builder" do
34 |
35 | before do
36 | @new_post.stub!(:title)
37 | ::Formtastic::SemanticFormHelper.builder = MyCustomFormBuilder
38 | end
39 |
40 | after do
41 | ::Formtastic::SemanticFormHelper.builder = ::Formtastic::SemanticFormBuilder
42 | end
43 |
44 | describe "semantic_form_for" do
45 |
46 | it "should yeild and instance of the custom builder" do
47 | semantic_form_for(@new_post) do |builder|
48 | builder.class.should == MyCustomFormBuilder
49 | end
50 | end
51 |
52 | it "should allow me to call my custom input" do
53 | semantic_form_for(@new_post) do |builder|
54 | concat(builder.input(:title, :as => :awesome))
55 | end
56 | end
57 |
58 | end
59 |
60 | end
61 |
62 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/defaults_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.join(File.dirname(__FILE__), *%w[spec_helper])
3 |
4 | describe 'Formtastic::SemanticFormBuilder-defaults' do
5 |
6 | # Note: This spec might make better sense somewhere else. Just temporary.
7 |
8 | describe "required string" do
9 |
10 | it "should render proc with I18n correctly" do
11 | ::I18n.backend.store_translations :en, :formtastic => {:required => 'Haha!'}
12 |
13 | required_string = Formtastic::SemanticFormBuilder.required_string
14 | required_string = required_string.is_a?(::Proc) ? required_string.call : required_string.to_s
15 | required_string.should == %{* }
16 | end
17 |
18 | end
19 |
20 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/error_proc_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'Rails field_error_proc' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | it "should not be overridden globally for all form builders" do
14 | current_field_error_proc = ::ActionView::Base.field_error_proc
15 |
16 | semantic_form_for(@new_post) do |builder|
17 | ::ActionView::Base.field_error_proc.should_not == current_field_error_proc
18 | end
19 |
20 | ::ActionView::Base.field_error_proc.should == current_field_error_proc
21 |
22 | form_for(@new_post) do |builder|
23 | ::ActionView::Base.field_error_proc.should == current_field_error_proc
24 | end
25 | end
26 |
27 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/errors_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'SemanticFormBuilder#errors_on' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | @title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
12 | @errors = mock('errors')
13 | @new_post.stub!(:errors).and_return(@errors)
14 | end
15 |
16 | describe 'when there are errors' do
17 | before do
18 | @errors.stub!(:[]).with(:title).and_return(@title_errors)
19 | end
20 |
21 | it 'should render a paragraph with the errors joined into a sentence when inline_errors config is :sentence' do
22 | ::Formtastic::SemanticFormBuilder.inline_errors = :sentence
23 | semantic_form_for(@new_post) do |builder|
24 | builder.errors_on(:title).should have_tag('p.inline-errors', @title_errors.to_sentence)
25 | end
26 | end
27 |
28 | it 'should render an unordered list with the class errors when inline_errors config is :list' do
29 | ::Formtastic::SemanticFormBuilder.inline_errors = :list
30 | semantic_form_for(@new_post) do |builder|
31 | builder.errors_on(:title).should have_tag('ul.errors')
32 | @title_errors.each do |error|
33 | builder.errors_on(:title).should have_tag('ul.errors li', error)
34 | end
35 | end
36 | end
37 |
38 | it 'should render a paragraph with the first error when inline_errors config is :first' do
39 | ::Formtastic::SemanticFormBuilder.inline_errors = :first
40 | semantic_form_for(@new_post) do |builder|
41 | builder.errors_on(:title).should have_tag('p.inline-errors', @title_errors.first)
42 | end
43 | end
44 |
45 | it 'should return nil when inline_errors config is :none' do
46 | ::Formtastic::SemanticFormBuilder.inline_errors = :none
47 | semantic_form_for(@new_post) do |builder|
48 | builder.errors_on(:title).should be_nil
49 | end
50 | end
51 |
52 | end
53 |
54 | describe 'when there are no errors (nil)' do
55 | before do
56 | @errors.stub!(:[]).with(:title).and_return(nil)
57 | end
58 |
59 | it 'should return nil when inline_errors config is :sentence, :list or :none' do
60 | [:sentence, :list, :none].each do |config|
61 | ::Formtastic::SemanticFormBuilder.inline_errors = config
62 | semantic_form_for(@new_post) do |builder|
63 | builder.errors_on(:title).should be_nil
64 | end
65 | end
66 | end
67 | end
68 |
69 | describe 'when there are no errors (empty array)' do
70 | before do
71 | @errors.stub!(:[]).with(:title).and_return([])
72 | end
73 |
74 | it 'should return nil when inline_errors config is :sentence, :list or :none' do
75 | [:sentence, :list, :none].each do |config|
76 | ::Formtastic::SemanticFormBuilder.inline_errors = config
77 | semantic_form_for(@new_post) do |builder|
78 | builder.errors_on(:title).should be_nil
79 | end
80 | end
81 | end
82 | end
83 |
84 | end
85 |
86 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/form_helper_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'SemanticFormHelper' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe '#semantic_form_for' do
14 |
15 | it 'yields an instance of SemanticFormBuilder' do
16 | semantic_form_for(:post, ::Post.new, :url => '/hello') do |builder|
17 | builder.class.should == ::Formtastic::SemanticFormBuilder
18 | end
19 | end
20 |
21 | it 'adds a class of "formtastic" to the generated form' do
22 | semantic_form_for(:post, ::Post.new, :url => '/hello') do |builder|
23 | end
24 | output_buffer.should have_tag("form.formtastic")
25 | end
26 |
27 | it 'adds class matching the object name to the generated form when a symbol is provided' do
28 | semantic_form_for(:post, ::Post.new, :url => '/hello') do |builder|
29 | end
30 | output_buffer.should have_tag("form.post")
31 |
32 | semantic_form_for(:project, :url => '/hello') do |builder|
33 | end
34 | output_buffer.should have_tag("form.project")
35 | end
36 |
37 | it 'adds class matching the object\'s class to the generated form when an object is provided' do
38 | semantic_form_for(@new_post) do |builder|
39 | end
40 | output_buffer.should have_tag("form.post")
41 | end
42 |
43 | it 'adds a namespaced class to the generated form' do
44 | semantic_form_for(::Namespaced::Post.new, :url => '/hello') do |builder|
45 | end
46 | output_buffer.should have_tag("form.namespaced_post")
47 | end
48 |
49 | describe 'allows :html options' do
50 | before(:each) do
51 | semantic_form_for(:post, ::Post.new, :url => '/hello', :html => { :id => "something-special", :class => "something-extra", :multipart => true }) do |builder|
52 | end
53 | end
54 |
55 | it 'to add a id of "something-special" to generated form' do
56 | output_buffer.should have_tag("form#something-special")
57 | end
58 |
59 | it 'to add a class of "something-extra" to generated form' do
60 | output_buffer.should have_tag("form.something-extra")
61 | end
62 |
63 | it 'to add enctype="multipart/form-data"' do
64 | output_buffer.should have_tag('form[@enctype="multipart/form-data"]')
65 | end
66 | end
67 |
68 | it 'can be called with a resource-oriented style' do
69 | semantic_form_for(@new_post) do |builder|
70 | builder.object.class.should == ::Post
71 | builder.object_name.should == "post"
72 | end
73 | end
74 |
75 | it 'can be called with a generic style and instance variable' do
76 | semantic_form_for(:post, @new_post, :url => new_post_path) do |builder|
77 | builder.object.class.should == ::Post
78 | builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
79 | end
80 | end
81 |
82 | it 'can be called with a generic style and inline object' do
83 | semantic_form_for(:post, ::Post.new, :url => new_post_path) do |builder|
84 | builder.object.class.should == ::Post
85 | builder.object_name.to_s.should == "post" # TODO: is this forced .to_s a bad assumption somewhere?
86 | end
87 | end
88 |
89 | describe "with :builder option" do
90 | it "yields an instance of the given builder" do
91 | class MyAwesomeCustomBuilder < ::Formtastic::SemanticFormBuilder
92 | end
93 | semantic_form_for(:post, ::Post.new, :url => '/hello', :builder => MyAwesomeCustomBuilder) do |builder|
94 | builder.class.should == MyAwesomeCustomBuilder
95 | end
96 | end
97 | end
98 |
99 | end
100 |
101 | describe '#semantic_fields_for' do
102 | it 'yields an instance of SemanticFormBuilder' do
103 | semantic_fields_for(:post, ::Post.new, :url => '/hello') do |builder|
104 | builder.class.should == ::Formtastic::SemanticFormBuilder
105 | end
106 | end
107 | end
108 |
109 | describe '#semantic_form_remote_for' do
110 | it 'yields an instance of SemanticFormBuilder' do
111 | semantic_form_remote_for(:post, ::Post.new, :url => '/hello') do |builder|
112 | builder.class.should == ::Formtastic::SemanticFormBuilder
113 | end
114 | end
115 | end
116 |
117 | describe '#semantic_form_for_remote' do
118 | it 'yields an instance of SemanticFormBuilder' do
119 | semantic_remote_form_for(:post, ::Post.new, :url => '/hello') do |builder|
120 | builder.class.should == ::Formtastic::SemanticFormBuilder
121 | end
122 | end
123 | end
124 |
125 | end
126 |
127 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/i18n_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.join(File.dirname(__FILE__), *%w[spec_helper])
3 |
4 | describe 'Formtastic::I18n' do
5 |
6 | FORMTASTIC_KEYS = [:required, :yes, :no, :create, :update].freeze
7 |
8 | it "should be defined" do
9 | lambda { ::Formtastic::I18n }.should_not raise_error(::NameError)
10 | end
11 |
12 | describe "default translations" do
13 | it "should be defined" do
14 | lambda { ::Formtastic::I18n::DEFAULT_VALUES }.should_not raise_error(::NameError)
15 | ::Formtastic::I18n::DEFAULT_VALUES.is_a?(::Hash).should == true
16 | end
17 |
18 | it "should exists for the core I18n lookup keys" do
19 | (::Formtastic::I18n::DEFAULT_VALUES.keys & FORMTASTIC_KEYS).size.should == FORMTASTIC_KEYS.size
20 | end
21 | end
22 |
23 | describe "when I18n locales are available" do
24 |
25 | before do
26 | @formtastic_strings = {
27 | :required => 'Default Required',
28 | :yes => 'Default Yes',
29 | :no => 'Default No',
30 | :create => 'Default Create {{model}}',
31 | :update => 'Default Update {{model}}',
32 | :custom_scope => {
33 | :duck => 'Duck',
34 | :duck_pond => '{{ducks}} ducks in a pond'
35 | }
36 | }
37 | ::I18n.backend.store_translations :en, :formtastic => @formtastic_strings
38 | end
39 |
40 | it "should translate core strings correctly" do
41 | ::Formtastic::I18n.t(:required).should == "Default Required"
42 | ::Formtastic::I18n.t(:yes).should == "Default Yes"
43 | ::Formtastic::I18n.t(:no).should == "Default No"
44 | ::Formtastic::I18n.t(:create, :model => 'Post').should == "Default Create Post"
45 | ::Formtastic::I18n.t(:update, :model => 'Post').should == "Default Update Post"
46 | end
47 |
48 | it "should all belong to scope 'formtastic'" do
49 | ::Formtastic::I18n.t(:duck, :scope => [:custom_scope]).should == 'Duck'
50 | end
51 |
52 | it "should override default I18n lookup args if these are specified" do
53 | ::Formtastic::I18n.t(:duck_pond, :scope => [:custom_scope], :ducks => 15).should == '15 ducks in a pond'
54 | end
55 |
56 | it "should be possible to override default values" do
57 | ::I18n.backend.store_translations :en, {:formtastic => {:required => nil}}
58 | ::Formtastic::I18n.t(:required, :default => 'Nothing found!').should == 'Nothing found!'
59 | end
60 |
61 | end
62 |
63 | describe "when no I18n locales are available" do
64 |
65 | before do
66 | ::I18n.backend.store_translations :en, :formtastic => {
67 | :required => nil,
68 | :yes => nil,
69 | :no => nil,
70 | :create => nil,
71 | :update => nil
72 | }
73 | end
74 |
75 | it "should use default strings" do
76 | (::Formtastic::I18n::DEFAULT_VALUES.keys).each do |key|
77 | ::Formtastic::I18n.t(key, :model => '{{model}}').should == ::Formtastic::I18n::DEFAULT_VALUES[key]
78 | end
79 | end
80 |
81 | end
82 |
83 | describe "I18n string lookups" do
84 |
85 | include FormtasticSpecHelper
86 |
87 | before do
88 | @output_buffer = ''
89 | mock_everything
90 |
91 | ::I18n.backend.store_translations :en, :formtastic => {
92 | :labels => {
93 | :title => "Hello world!",
94 | :post => {:title => "Hello post!"},
95 | :project => {:title => "Hello project!"}
96 | }
97 | }
98 | ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
99 |
100 | @new_post.stub!(:title)
101 | @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
102 | end
103 |
104 | after do
105 | ::I18n.backend.store_translations :en, :formtastic => nil
106 | ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
107 | end
108 |
109 | it "lookup scopes should be defined" do
110 | lambda { ::Formtastic::I18n::SCOPES }.should_not raise_error(::NameError)
111 | end
112 |
113 | it "should be able to translate with namespaced object" do
114 | semantic_form_for(@new_post) do |builder|
115 | concat(builder.input(:title))
116 | end
117 | output_buffer.should have_tag("form label", /Hello post!/)
118 | end
119 |
120 | it "should be able to translate without form-object" do
121 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
122 | concat(builder.input(:title))
123 | end
124 | output_buffer.should have_tag("form label", /Hello project!/)
125 | end
126 |
127 | # TODO: Add spec for namespaced models?
128 |
129 | end
130 |
131 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/include_blank_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe "*select: options[:include_blank]" do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | @new_post.stub!(:author_id).and_return(nil)
13 | @new_post.stub!(:publish_at).and_return(nil)
14 |
15 | @select_input_types = {
16 | :select => :author,
17 | :datetime => :publish_at,
18 | :date => :publish_at,
19 | :time => :publish_at
20 | }
21 | end
22 |
23 | describe 'when :include_blank is not set' do
24 | it 'blank value should be included if the default value specified in config is true' do
25 | ::Formtastic::SemanticFormBuilder.include_blank_for_select_by_default = true
26 | @select_input_types.each do |as, attribute|
27 | semantic_form_for(@new_post) do |builder|
28 | concat(builder.input(attribute, :as => as))
29 | end
30 | output_buffer.should have_tag("form li select option[@value='']", "")
31 | end
32 | end
33 |
34 | it 'blank value should not be included if the default value specified in config is false' do
35 | ::Formtastic::SemanticFormBuilder.include_blank_for_select_by_default = false
36 | @select_input_types.each do |as, attribute|
37 | semantic_form_for(@new_post) do |builder|
38 | concat(builder.input(attribute, :as => as))
39 | end
40 | output_buffer.should_not have_tag("form li select option[@value='']", "")
41 | end
42 | end
43 |
44 | after do
45 | ::Formtastic::SemanticFormBuilder.include_blank_for_select_by_default = true
46 | end
47 | end
48 |
49 | describe 'when :include_blank is set to false' do
50 | it 'should not have a blank option' do
51 | @select_input_types.each do |as, attribute|
52 | semantic_form_for(@new_post) do |builder|
53 | concat(builder.input(attribute, :as => as, :include_blank => false))
54 | end
55 | output_buffer.should_not have_tag("form li select option[@value='']", "")
56 | end
57 | end
58 | end
59 |
60 | describe 'when :include_blank => true is set' do
61 | it 'should have a blank select option' do
62 | @select_input_types.each do |as, attribute|
63 | semantic_form_for(@new_post) do |builder|
64 | concat(builder.input(attribute, :as => as, :include_blank => true))
65 | end
66 | output_buffer.should have_tag("form li select option[@value='']", "")
67 | end
68 | end
69 | end
70 | end
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/boolean_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'boolean input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:allow_comments, :as => :boolean))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class("boolean")
18 | it_should_have_input_wrapper_with_id("post_allow_comments_input")
19 | it_should_apply_error_logic_for_input_type(:boolean)
20 |
21 | it 'should generate a label containing the input' do
22 | output_buffer.should have_tag('form li label', :count => 1)
23 | output_buffer.should have_tag('form li label[@for="post_allow_comments"]')
24 | output_buffer.should have_tag('form li label', /Allow comments/)
25 | output_buffer.should have_tag('form li label input[@type="checkbox"]')
26 | end
27 |
28 | it 'should generate a checkbox input' do
29 | output_buffer.should have_tag('form li label input')
30 | output_buffer.should have_tag('form li label input#post_allow_comments')
31 | output_buffer.should have_tag('form li label input[@type="checkbox"]')
32 | output_buffer.should have_tag('form li label input[@name="post[allow_comments]"]')
33 | output_buffer.should have_tag('form li label input[@type="checkbox"][@value="1"]')
34 | end
35 |
36 | it 'should allow checked and unchecked values to be sent' do
37 | semantic_form_for(@new_post) do |builder|
38 | concat(builder.input(:allow_comments, :as => :boolean, :checked_value => 'checked', :unchecked_value => 'unchecked'))
39 | end
40 |
41 | output_buffer.should have_tag('form li label input[@type="checkbox"][@value="checked"]')
42 | output_buffer.should have_tag('form li label input[@type="hidden"][@value="unchecked"]')
43 | end
44 |
45 | it 'should generate a label and a checkbox even if no object is given' do
46 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
47 | concat(builder.input(:allow_comments, :as => :boolean))
48 | end
49 |
50 | output_buffer.should have_tag('form li label[@for="project_allow_comments"]')
51 | output_buffer.should have_tag('form li label', /Allow comments/)
52 | output_buffer.should have_tag('form li label input[@type="checkbox"]')
53 |
54 | output_buffer.should have_tag('form li label input#project_allow_comments')
55 | output_buffer.should have_tag('form li label input[@type="checkbox"]')
56 | output_buffer.should have_tag('form li label input[@name="project[allow_comments]"]')
57 | end
58 |
59 | describe 'when :selected is set' do
60 | before do
61 | @output_buffer = ''
62 | end
63 |
64 | describe "not selected" do
65 | before do
66 | @new_post.stub!(:allow_comments).and_return(true)
67 |
68 | semantic_form_for(@new_post) do |builder|
69 | concat(builder.input(:allow_comments, :as => :boolean, :selected => false))
70 | end
71 | end
72 |
73 | it 'should not be selected' do
74 | output_buffer.should_not have_tag("form li label input[@type='checkbox'][@checked='checked']")
75 | end
76 | end
77 |
78 | describe "selected" do
79 | before do
80 | @new_post.stub!(:allow_comments).and_return(false)
81 |
82 | semantic_form_for(@new_post) do |builder|
83 | concat(builder.input(:allow_comments, :as => :boolean, :selected => true))
84 | end
85 | end
86 |
87 | it 'should be selected' do
88 | output_buffer.should have_tag("form li label input[@type='checkbox'][@checked='checked']")
89 | end
90 | end
91 | end
92 |
93 | end
94 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/check_boxes_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'check_boxes input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | describe 'for a has_many association' do
9 | before do
10 | @output_buffer = ''
11 | mock_everything
12 |
13 | semantic_form_for(@fred) do |builder|
14 | concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true))
15 | end
16 | end
17 |
18 | it_should_have_input_wrapper_with_class("check_boxes")
19 | it_should_have_input_wrapper_with_id("author_posts_input")
20 | it_should_have_a_nested_fieldset
21 | it_should_apply_error_logic_for_input_type(:check_boxes)
22 | it_should_call_find_on_association_class_when_no_collection_is_provided(:check_boxes)
23 | it_should_use_the_collection_when_provided(:check_boxes, 'input[@type="checkbox"]')
24 |
25 | it 'should generate a legend - classified as a label - containing label text for the input' do
26 | output_buffer.should have_tag('form li fieldset legend.label')
27 | output_buffer.should have_tag('form li fieldset legend.label', /Posts/)
28 | end
29 |
30 | it 'should generate an ordered list with a list item for each choice' do
31 | output_buffer.should have_tag('form li fieldset ol')
32 | output_buffer.should have_tag('form li fieldset ol li', :count => ::Post.find(:all).size)
33 | end
34 |
35 | it 'should have one option with a "checked" attribute' do
36 | output_buffer.should have_tag('form li input[@checked]', :count => 1)
37 | end
38 |
39 | it 'should generate hidden inputs with default value blank' do
40 | output_buffer.should have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => ::Post.find(:all).size)
41 | end
42 |
43 | describe "each choice" do
44 |
45 | it 'should contain a label for the radio input with a nested input and label text' do
46 | ::Post.find(:all).each do |post|
47 | output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
48 | output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
49 | end
50 | end
51 |
52 | it 'should use values as li.class when value_as_class is true' do
53 | ::Post.find(:all).each do |post|
54 | output_buffer.should have_tag("form li fieldset ol li.post_#{post.id} label")
55 | end
56 | end
57 |
58 | it 'should have a checkbox input for each post' do
59 | ::Post.find(:all).each do |post|
60 | output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
61 | output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
62 | end
63 | end
64 |
65 | it "should mark input as checked if it's the the existing choice" do
66 | ::Post.find(:all).include?(@fred.posts.first).should be_true
67 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
68 | end
69 | end
70 |
71 | describe 'and no object is given' do
72 | before(:each) do
73 | output_buffer.replace ''
74 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
75 | concat(builder.input(:author_id, :as => :check_boxes, :collection => ::Author.find(:all)))
76 | end
77 | end
78 |
79 | it 'should generate a fieldset with legend' do
80 | output_buffer.should have_tag('form li fieldset legend', /Author/)
81 | end
82 |
83 | it 'shold generate an li tag for each item in the collection' do
84 | output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
85 | end
86 |
87 | it 'should generate labels for each item' do
88 | ::Author.find(:all).each do |author|
89 | output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
90 | output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
91 | end
92 | end
93 |
94 | it 'should generate inputs for each item' do
95 | ::Author.find(:all).each do |author|
96 | output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
97 | output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
98 | output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
99 | output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
100 | end
101 | end
102 | end
103 |
104 | describe 'when :selected is set' do
105 | before do
106 | @output_buffer = ''
107 | end
108 |
109 | describe "no selected items" do
110 | before do
111 | @new_post.stub!(:author_ids).and_return(nil)
112 |
113 | semantic_form_for(@new_post) do |builder|
114 | concat(builder.input(:authors, :as => :check_boxes, :selected => nil))
115 | end
116 | end
117 |
118 | it 'should not have any selected item(s)' do
119 | output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
120 | end
121 | end
122 |
123 | describe "single selected item" do
124 | before do
125 | @new_post.stub!(:author_ids).and_return(nil)
126 |
127 | semantic_form_for(@new_post) do |builder|
128 | concat(builder.input(:authors, :as => :check_boxes, :selected => @fred.id))
129 | end
130 | end
131 |
132 | it "should have one item selected; the specified one" do
133 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']", :count => 1)
134 | output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
135 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@fred.id}']")
136 | end
137 | end
138 |
139 | describe "multiple selected items" do
140 | before do
141 | @new_post.stub!(:author_ids).and_return(nil)
142 |
143 | semantic_form_for(@new_post) do |builder|
144 | concat(builder.input(:authors, :as => :check_boxes, :selected => [@bob.id, @fred.id]))
145 | end
146 | end
147 |
148 | it "should have multiple items selected; the specified ones" do
149 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']", :count => 2)
150 | output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@bob.id}']", /bob/i)
151 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@bob.id}']")
152 | output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
153 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked'][@value='#{@fred.id}']")
154 | end
155 | end
156 |
157 | end
158 |
159 | end
160 |
161 | end
162 |
163 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/country_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'country input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe "when country_select is not available as a helper from a plugin" do
14 |
15 | it "should raise an error, sugesting the author installs a plugin" do
16 | lambda {
17 | semantic_form_for(@new_post) do |builder|
18 | concat(builder.input(:country, :as => :country))
19 | end
20 | }.should raise_error
21 | end
22 |
23 | end
24 |
25 | describe "when country_select is available as a helper (from a plugin)" do
26 |
27 | before do
28 | semantic_form_for(@new_post) do |builder|
29 | builder.stub!(:country_select).and_return("... ")
30 | concat(builder.input(:country, :as => :country))
31 | end
32 | end
33 |
34 | it_should_have_input_wrapper_with_class("country")
35 | it_should_have_input_wrapper_with_id("post_country_input")
36 |
37 | # TODO -- needs stubbing inside the builder block, tricky!
38 | #it_should_apply_error_logic_for_input_type(:country)
39 |
40 | it 'should generate a label for the input' do
41 | output_buffer.should have_tag('form li label')
42 | output_buffer.should have_tag('form li label[@for="post_country"]')
43 | output_buffer.should have_tag('form li label', /Country/)
44 | end
45 |
46 | it "should generate a select" do
47 | output_buffer.should have_tag("form li select")
48 | end
49 |
50 | end
51 |
52 | describe ":priority_countries option" do
53 |
54 | it "should be passed down to the country_select helper when provided" do
55 | priority_countries = ["Foo", "Bah"]
56 | semantic_form_for(@new_post) do |builder|
57 | builder.stub!(:country_select).and_return("... ")
58 | builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("... ")
59 |
60 | concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
61 | end
62 | end
63 |
64 | it "should default to the @@priority_countries config when absent" do
65 | priority_countries = ::Formtastic::SemanticFormBuilder.priority_countries
66 | priority_countries.should_not be_empty
67 | priority_countries.should_not be_nil
68 |
69 | semantic_form_for(@new_post) do |builder|
70 | builder.stub!(:country_select).and_return("... ")
71 | builder.should_receive(:country_select).with(:country, priority_countries, {}, {}).and_return("... ")
72 |
73 | concat(builder.input(:country, :as => :country))
74 | end
75 | end
76 |
77 | end
78 |
79 | end
80 |
81 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/date_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'date input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:publish_at, :as => :date))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class("date")
18 | it_should_have_input_wrapper_with_id("post_publish_at_input")
19 | it_should_have_a_nested_fieldset
20 | it_should_apply_error_logic_for_input_type(:date)
21 |
22 | it 'should have a legend - classified as a label - containing the label text inside the fieldset' do
23 | output_buffer.should have_tag('form li.date fieldset legend.label', /Publish at/)
24 | end
25 |
26 | it 'should have an ordered list of three items inside the fieldset' do
27 | output_buffer.should have_tag('form li.date fieldset ol')
28 | output_buffer.should have_tag('form li.date fieldset ol li', :count => 3)
29 | end
30 |
31 | it 'should have three labels for year, month and day' do
32 | output_buffer.should have_tag('form li.date fieldset ol li label', :count => 3)
33 | output_buffer.should have_tag('form li.date fieldset ol li label', /year/i)
34 | output_buffer.should have_tag('form li.date fieldset ol li label', /month/i)
35 | output_buffer.should have_tag('form li.date fieldset ol li label', /day/i)
36 | end
37 |
38 | it 'should have three selects for year, month and day' do
39 | output_buffer.should have_tag('form li.date fieldset ol li select', :count => 3)
40 | end
41 |
42 | it_should_select_existing_datetime_else_current(:year, :month, :day)
43 | it_should_select_explicit_default_value_if_set(:year, :month, :day)
44 |
45 | describe "when :selected is nil" do
46 |
47 | before(:each) do
48 | output_buffer.replace ''
49 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
50 | concat(builder.input(:publish_at, :as => :datetime, :selected => nil))
51 | end
52 | end
53 |
54 | it "should not pre-select any options" do
55 | output_buffer.should_not have_tag("form li.datetime li select option[@selected]")
56 | end
57 |
58 | end
59 |
60 | end
61 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/datetime_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'datetime input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | @new_post.should_receive(:publish_at=).any_number_of_times
13 | @new_post.should_receive(:created_at=).any_number_of_times
14 | @bob.should_receive(:created_at=).any_number_of_times
15 | @new_post.should_receive(:title=).any_number_of_times # Macro stuff forces this.
16 |
17 | semantic_form_for(@new_post) do |builder|
18 | concat(builder.input(:publish_at, :as => :datetime))
19 | end
20 | end
21 |
22 | it_should_have_input_wrapper_with_class("datetime")
23 | it_should_have_input_wrapper_with_id("post_publish_at_input")
24 | it_should_have_a_nested_fieldset
25 | it_should_apply_error_logic_for_input_type(:datetime)
26 |
27 | it 'should have a legend containing the label text inside the fieldset' do
28 | output_buffer.should have_tag('form li.datetime fieldset legend', /Publish at/)
29 | end
30 |
31 | it 'should have an ordered list of five items inside the fieldset' do
32 | output_buffer.should have_tag('form li.datetime fieldset ol')
33 | output_buffer.should have_tag('form li.datetime fieldset ol li', :count => 5)
34 | end
35 |
36 | it 'should have five labels for year, month, day, hour and minute' do
37 | output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
38 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /year/i)
39 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /month/i)
40 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /day/i)
41 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /hour/i)
42 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /minute/i)
43 | end
44 |
45 | it 'should have five selects for year, month, day, hour and minute' do
46 | output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
47 | end
48 |
49 | it 'should generate a sanitized label and matching ids for attribute' do
50 | semantic_form_for(@new_post) do |builder|
51 | builder.semantic_fields_for(@bob, :index => 10) do |bob_builder|
52 | concat(bob_builder.input(:created_at, :as => :datetime))
53 | end
54 | end
55 |
56 | 1.upto(5) do |i|
57 | output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_10_created_at_#{i}i']")
58 | output_buffer.should have_tag("form li fieldset ol li #post_author_10_created_at_#{i}i")
59 | end
60 | end
61 |
62 | it_should_select_existing_datetime_else_current(:year, :month, :day, :hour, :minute, :second)
63 | it_should_select_explicit_default_value_if_set(:year, :month, :day, :hour, :minute, :second)
64 |
65 | describe 'when :discard_input => true is set' do
66 | it 'should use default attribute value when it is not nil' do
67 | @new_post.stub!(:publish_at).and_return(Date.new(2007,12,27))
68 | semantic_form_for(@new_post) do |builder|
69 | concat(builder.input(:publish_at, :as => :datetime, :discard_day => true))
70 | end
71 |
72 | output_buffer.should have_tag("form li input[@type='hidden'][@value='27']")
73 | end
74 | end
75 |
76 | describe 'inputs order' do
77 | it 'should have a default' do
78 | semantic_form_for(@new_post) do |builder|
79 | self.should_receive(:select_year).once.ordered.and_return('')
80 | self.should_receive(:select_month).once.ordered.and_return('')
81 | self.should_receive(:select_day).once.ordered.and_return('')
82 | builder.input(:publish_at, :as => :datetime)
83 | end
84 | end
85 |
86 | it 'should be specified with :order option' do
87 | ::I18n.backend.store_translations 'en', :date => { :order => [:month, :year, :day] }
88 | semantic_form_for(@new_post) do |builder|
89 | self.should_receive(:select_month).once.ordered.and_return('')
90 | self.should_receive(:select_year).once.ordered.and_return('')
91 | self.should_receive(:select_day).once.ordered.and_return('')
92 | builder.input(:publish_at, :as => :datetime)
93 | end
94 | end
95 |
96 | it 'should be changed through I18n' do
97 | semantic_form_for(@new_post) do |builder|
98 | self.should_receive(:select_day).once.ordered.and_return('')
99 | self.should_receive(:select_month).once.ordered.and_return('')
100 | self.should_receive(:select_year).once.ordered.and_return('')
101 | builder.input(:publish_at, :as => :datetime, :order => [:day, :month, :year])
102 | end
103 | end
104 | end
105 |
106 | describe 'when the locale changes the label text' do
107 | before do
108 | ::I18n.backend.store_translations 'en', :datetime => {:prompts => {
109 | :year => 'The Year', :month => 'The Month', :day => 'The Day',
110 | :hour => 'The Hour', :minute => 'The Minute'
111 | }}
112 | semantic_form_for(@new_post) do |builder|
113 | concat(builder.input(:publish_at, :as => :datetime))
114 | end
115 | end
116 |
117 | after do
118 | ::I18n.backend.store_translations 'en', :formtastic => {
119 | :year => nil, :month => nil, :day => nil,
120 | :hour => nil, :minute => nil
121 | }
122 | end
123 |
124 | it 'should have translated labels for year, month, day, hour and minute' do
125 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Year/)
126 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Month/)
127 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Day/)
128 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Hour/)
129 | output_buffer.should have_tag('form li.datetime fieldset ol li label', /The Minute/)
130 | end
131 | end
132 |
133 | describe 'when no object is given' do
134 | before(:each) do
135 | output_buffer.replace ''
136 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
137 | concat(builder.input(:publish_at, :as => :datetime))
138 | end
139 | end
140 |
141 | it 'should have fieldset with legend - classified as a label' do
142 | output_buffer.should have_tag('form li.datetime fieldset legend.label', /Publish at/)
143 | end
144 |
145 | it 'should have labels for each input' do
146 | output_buffer.should have_tag('form li.datetime fieldset ol li label', :count => 5)
147 | end
148 |
149 | it 'should have selects for each inputs' do
150 | output_buffer.should have_tag('form li.datetime fieldset ol li select', :count => 5)
151 | end
152 | end
153 |
154 | describe "when :selected is nil" do
155 |
156 | before(:each) do
157 | output_buffer.replace ''
158 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
159 | concat(builder.input(:publish_at, :as => :datetime, :selected => nil))
160 | end
161 | end
162 |
163 | it "should not pre-select any options" do
164 | output_buffer.should_not have_tag("form li.datetime li select option[@selected]")
165 | end
166 |
167 | end
168 | end
169 |
170 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/file_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'file input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:body, :as => :file))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class("file")
18 | it_should_have_input_wrapper_with_id("post_body_input")
19 | it_should_have_label_with_text(/Body/)
20 | it_should_have_label_for("post_body")
21 | it_should_have_input_with_id("post_body")
22 | it_should_have_input_with_name("post[body]")
23 | it_should_apply_error_logic_for_input_type(:file)
24 |
25 | it 'should use input_html to style inputs' do
26 | semantic_form_for(@new_post) do |builder|
27 | concat(builder.input(:title, :as => :file, :input_html => { :class => 'myclass' }))
28 | end
29 | output_buffer.should have_tag("form li input.myclass")
30 | end
31 |
32 | end
33 |
34 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/hidden_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'hidden input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:secret, :as => :hidden))
14 | concat(builder.input(:author_id, :as => :hidden, :value => 99))
15 | concat(builder.input(:published, :as => :hidden, :input_html => {:value => true}))
16 | end
17 | end
18 |
19 | it_should_have_input_wrapper_with_class("hidden")
20 | it_should_have_input_wrapper_with_id("post_secret_input")
21 | it_should_not_have_a_label
22 |
23 | it "should generate a input field" do
24 | output_buffer.should have_tag("form li input#post_secret")
25 | output_buffer.should have_tag("form li input#post_secret[@type=\"hidden\"]")
26 | output_buffer.should have_tag("form li input#post_secret[@name=\"post[secret]\"]")
27 | end
28 |
29 | it "should pass any explicitly specified value - using :value" do
30 | output_buffer.should have_tag("form li input#post_author_id[@type=\"hidden\"][@value=\"99\"]")
31 | end
32 |
33 | # Handle Formtastic :input_html options for consistency.
34 | it "should pass any explicitly specified value - using :input_html options" do
35 | output_buffer.should have_tag("form li input#post_published[@type=\"hidden\"][@value=\"true\"]")
36 | end
37 |
38 | it "should not render inline errors" do
39 | @errors = mock('errors')
40 | @errors.stub!(:[]).with(:secret).and_return(["foo", "bah"])
41 | @new_post.stub!(:errors).and_return(@errors)
42 |
43 | semantic_form_for(@new_post) do |builder|
44 | concat(builder.input(:secret, :as => :hidden))
45 | end
46 |
47 | output_buffer.should_not have_tag("form li p.inline-errors")
48 | output_buffer.should_not have_tag("form li ul.errors")
49 | end
50 |
51 | end
52 |
53 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/numeric_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'numeric input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:title, :as => :numeric))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class(:numeric)
18 | it_should_have_input_wrapper_with_id("post_title_input")
19 | it_should_have_label_with_text(/Title/)
20 | it_should_have_label_for("post_title")
21 | it_should_have_input_with_id("post_title")
22 | it_should_have_input_with_type(:text)
23 | it_should_have_input_with_name("post[title]")
24 | it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
25 | it_should_apply_custom_input_attributes_when_input_html_provided(:string)
26 | it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
27 | it_should_apply_error_logic_for_input_type(:numeric)
28 |
29 | describe "when no object is provided" do
30 | before do
31 | semantic_form_for(:project, :url => 'http://test.host/') do |builder|
32 | concat(builder.input(:title, :as => :numeric))
33 | end
34 | end
35 |
36 | it_should_have_label_with_text(/Title/)
37 | it_should_have_label_for("project_title")
38 | it_should_have_input_with_id("project_title")
39 | it_should_have_input_with_type(:text)
40 | it_should_have_input_with_name("project[title]")
41 | end
42 |
43 | end
44 |
45 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/password_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'password input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:title, :as => :password))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class(:password)
18 | it_should_have_input_wrapper_with_id("post_title_input")
19 | it_should_have_label_with_text(/Title/)
20 | it_should_have_label_for("post_title")
21 | it_should_have_input_with_id("post_title")
22 | it_should_have_input_with_type(:password)
23 | it_should_have_input_with_name("post[title]")
24 | it_should_have_maxlength_matching_column_limit
25 | it_should_use_default_text_field_size_for_columns_longer_than_default_text_field_size(:string)
26 | it_should_use_column_size_for_columns_shorter_than_default_text_field_size(:string)
27 | it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
28 | it_should_apply_custom_input_attributes_when_input_html_provided(:string)
29 | it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
30 | it_should_apply_error_logic_for_input_type(:password)
31 |
32 | describe "when no object is provided" do
33 | before do
34 | semantic_form_for(:project, :url => 'http://test.host/') do |builder|
35 | concat(builder.input(:title, :as => :password))
36 | end
37 | end
38 |
39 | it_should_have_label_with_text(/Title/)
40 | it_should_have_label_for("project_title")
41 | it_should_have_input_with_id("project_title")
42 | it_should_have_input_with_type(:password)
43 | it_should_have_input_with_name("project[title]")
44 | end
45 |
46 | end
47 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/radio_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'radio input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe 'for belongs_to association' do
14 | before do
15 | semantic_form_for(@new_post) do |builder|
16 | concat(builder.input(:author, :as => :radio, :value_as_class => true))
17 | end
18 | end
19 |
20 | it_should_have_input_wrapper_with_class("radio")
21 | it_should_have_input_wrapper_with_id("post_author_input")
22 | it_should_have_a_nested_fieldset
23 | it_should_apply_error_logic_for_input_type(:radio)
24 | it_should_use_the_collection_when_provided(:radio, 'input')
25 |
26 |
27 | it 'should generate a legend - classified as a label - containing label text for the input' do
28 | output_buffer.should have_tag('form li fieldset legend.label')
29 | output_buffer.should have_tag('form li fieldset legend.label', /Author/)
30 | end
31 |
32 | it 'should generate an ordered list with a list item for each choice' do
33 | output_buffer.should have_tag('form li fieldset ol')
34 | output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
35 | end
36 |
37 | it 'should have one option with a "checked" attribute' do
38 | output_buffer.should have_tag('form li input[@checked]', :count => 1)
39 | end
40 |
41 | describe "each choice" do
42 |
43 | it 'should contain a label for the radio input with a nested input and label text' do
44 | ::Author.find(:all).each do |author|
45 | output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
46 | output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
47 | end
48 | end
49 |
50 | it 'should use values as li.class when value_as_class is true' do
51 | ::Author.find(:all).each do |author|
52 | output_buffer.should have_tag("form li fieldset ol li.author_#{author.id} label")
53 | end
54 | end
55 |
56 | it "should have a radio input" do
57 | ::Author.find(:all).each do |author|
58 | output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
59 | output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
60 | output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
61 | output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
62 | end
63 | end
64 |
65 | it "should mark input as checked if it's the the existing choice" do
66 | @new_post.author_id.should == @bob.id
67 | @new_post.author.id.should == @bob.id
68 | @new_post.author.should == @bob
69 |
70 | semantic_form_for(@new_post) do |builder|
71 | concat(builder.input(:author, :as => :radio))
72 | end
73 |
74 | output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
75 | end
76 | end
77 |
78 | describe 'and no object is given' do
79 | before(:each) do
80 | output_buffer.replace ''
81 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
82 | concat(builder.input(:author_id, :as => :radio, :collection => ::Author.find(:all)))
83 | end
84 | end
85 |
86 | it 'should generate a fieldset with legend' do
87 | output_buffer.should have_tag('form li fieldset legend', /Author/)
88 | end
89 |
90 | it 'should generate an li tag for each item in the collection' do
91 | output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
92 | end
93 |
94 | it 'should generate labels for each item' do
95 | ::Author.find(:all).each do |author|
96 | output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
97 | output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
98 | end
99 | end
100 |
101 | it 'should generate inputs for each item' do
102 | ::Author.find(:all).each do |author|
103 | output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
104 | output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
105 | output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
106 | output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
107 | end
108 | end
109 | end
110 | end
111 |
112 | describe 'when :selected is set' do
113 | before do
114 | @output_buffer = ''
115 | end
116 |
117 | describe "no selected items" do
118 | before do
119 | @new_post.stub!(:author_ids).and_return(nil)
120 |
121 | semantic_form_for(@new_post) do |builder|
122 | concat(builder.input(:authors, :as => :radio, :selected => nil))
123 | end
124 | end
125 |
126 | it 'should not have any selected item(s)' do
127 | output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
128 | end
129 | end
130 |
131 | describe "single selected item" do
132 | before do
133 | @new_post.stub!(:author_ids).and_return(nil)
134 |
135 | semantic_form_for(@new_post) do |builder|
136 | concat(builder.input(:authors, :as => :radio, :selected => @fred.id))
137 | end
138 | end
139 |
140 | it "should have one item selected; the specified one" do
141 | output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked']", :count => 1)
142 | output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
143 | output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked'][@value='#{@fred.id}']")
144 | end
145 | end
146 |
147 | end
148 |
149 | end
150 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/select_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'select input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe 'explicit values' do
14 | describe 'using an array of values' do
15 | before do
16 | @array_with_values = ["Title A", "Title B", "Title C"]
17 | @array_with_keys_and_values = [["Title D", 1], ["Title E", 2], ["Title F", 3]]
18 | semantic_form_for(@new_post) do |builder|
19 | concat(builder.input(:title, :as => :select, :collection => @array_with_values))
20 | concat(builder.input(:title, :as => :select, :collection => @array_with_keys_and_values))
21 | end
22 | end
23 |
24 | it 'should have a option for each key and/or value' do
25 | @array_with_values.each do |v|
26 | output_buffer.should have_tag("form li select option[@value='#{v}']", /^#{v}$/)
27 | end
28 | @array_with_keys_and_values.each do |v|
29 | output_buffer.should have_tag("form li select option[@value='#{v.second}']", /^#{v.first}$/)
30 | end
31 | end
32 | end
33 |
34 | describe 'using a range' do
35 | before do
36 | @range_with_values = 1..5
37 | semantic_form_for(@new_post) do |builder|
38 | concat(builder.input(:title, :as => :select, :collection => @range_with_values))
39 | end
40 | end
41 |
42 | it 'should have an option for each value' do
43 | @range_with_values.each do |v|
44 | output_buffer.should have_tag("form li select option[@value='#{v}']", /^#{v}$/)
45 | end
46 | end
47 | end
48 | end
49 |
50 | describe 'for a belongs_to association' do
51 | before do
52 | semantic_form_for(@new_post) do |builder|
53 | concat(builder.input(:author, :as => :select))
54 | end
55 | end
56 |
57 | it_should_have_input_wrapper_with_class("select")
58 | it_should_have_input_wrapper_with_id("post_author_input")
59 | it_should_have_label_with_text(/Author/)
60 | it_should_have_label_for('post_author_id')
61 | it_should_apply_error_logic_for_input_type(:select)
62 | it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
63 | it_should_use_the_collection_when_provided(:select, 'option')
64 |
65 | it 'should have a select inside the wrapper' do
66 | output_buffer.should have_tag('form li select')
67 | output_buffer.should have_tag('form li select#post_author_id')
68 | end
69 |
70 | it 'should have a valid name' do
71 | output_buffer.should have_tag("form li select[@name='post[author_id]']")
72 | output_buffer.should_not have_tag("form li select[@name='post[author_id][]']")
73 | end
74 |
75 | it 'should not create a multi-select' do
76 | output_buffer.should_not have_tag('form li select[@multiple]')
77 | end
78 |
79 | it 'should create a select without size' do
80 | output_buffer.should_not have_tag('form li select[@size]')
81 | end
82 |
83 | it 'should have a blank option' do
84 | output_buffer.should have_tag("form li select option[@value='']")
85 | end
86 |
87 | it 'should have a select option for each Author' do
88 | output_buffer.should have_tag('form li select option', :count => ::Author.find(:all).size + 1)
89 | ::Author.find(:all).each do |author|
90 | output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
91 | end
92 | end
93 |
94 | it 'should have one option with a "selected" attribute' do
95 | output_buffer.should have_tag('form li select option[@selected]', :count => 1)
96 | end
97 |
98 | it 'should not singularize the association name' do
99 | @new_post.stub!(:author_status).and_return(@bob)
100 | @new_post.stub!(:author_status_id).and_return(@bob.id)
101 | @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
102 |
103 | semantic_form_for(@new_post) do |builder|
104 | concat(builder.input(:author_status, :as => :select))
105 | end
106 |
107 | output_buffer.should have_tag('form li select#post_author_status_id')
108 | end
109 | end
110 |
111 | describe "for a belongs_to association with :group_by => :author" do
112 | it "should call author.posts" do
113 | [@freds_post].each { |post| post.stub!(:to_label).and_return("Post - #{post.id}") }
114 | @fred.should_receive(:posts)
115 |
116 | semantic_form_for(@new_post) do |builder|
117 | concat(builder.input(:main_post, :as => :select, :group_by => :author ) )
118 | end
119 | end
120 | end
121 |
122 | describe 'for a belongs_to association with :group_by => :continent' do
123 | before do
124 | @authors = [@bob, @fred, @fred, @fred]
125 | ::Author.stub!(:find).and_return(@authors)
126 | @continent_names = %w(Europe Africa)
127 | @continents = (0..1).map { |i| c = ::Continent.new; c.stub!(:id).and_return(100 - i);c }
128 | @authors[0..1].each_with_index { |author, i| author.stub!(:continent).and_return(@continents[i]) }
129 | ::Continent.stub!(:reflect_on_all_associations).and_return {|macro| mock('reflection', :klass => Author) if macro == :has_many}
130 | ::Continent.stub!(:reflect_on_association).and_return {|column_name| mock('reflection', :klass => Author) if column_name == :authors}
131 | ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Continent, :macro => :belongs_to) if column_name == :continent }
132 |
133 |
134 | @continents.each_with_index do |continent, i|
135 | continent.stub!(:to_label).and_return(@continent_names[i])
136 | continent.stub!(:authors).and_return([@authors[i]])
137 | end
138 |
139 | semantic_form_for(@new_post) do |builder|
140 | concat(builder.input(:author, :as => :select, :group_by => :continent ) )
141 | concat(builder.input(:author, :as => :select, :group_by => :continent, :group_label_method => :id ) )
142 | end
143 | end
144 |
145 | it_should_have_input_wrapper_with_class("select")
146 | it_should_have_input_wrapper_with_id("post_author_input")
147 | it_should_have_label_with_text(/Author/)
148 | it_should_have_label_for('post_author_id')
149 |
150 | # TODO, need to find a way to repeat some of the specs and logic from the belongs_to specs without grouping
151 |
152 | 0.upto(1) do |i|
153 | it 'should have all option groups and the right values' do
154 | output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].to_label)
155 | end
156 |
157 | it 'should have custom group labels' do
158 | output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].to_label)
159 | end
160 | end
161 |
162 | it 'should have no duplicate groups' do
163 | output_buffer.should have_tag('form li select optgroup', :count => 4)
164 | end
165 |
166 | it 'should sort the groups on the label method' do
167 | output_buffer.should have_tag("form li select optgroup[@label='Africa']")
168 | output_buffer.should have_tag("form li select optgroup[@label='99']")
169 | end
170 |
171 | it 'should call find with :include for more optimized queries' do
172 | Author.should_receive(:find).with(:all, :include => :continent)
173 |
174 | semantic_form_for(@new_post) do |builder|
175 | concat(builder.input(:author, :as => :select, :group_by => :continent ) )
176 | end
177 | end
178 | end
179 |
180 | describe 'for a has_many association' do
181 | before do
182 | semantic_form_for(@fred) do |builder|
183 | concat(builder.input(:posts, :as => :select))
184 | end
185 | end
186 |
187 | it_should_have_input_wrapper_with_class("select")
188 | it_should_have_input_wrapper_with_id("author_posts_input")
189 | it_should_have_label_with_text(/Post/)
190 | it_should_have_label_for('author_post_ids')
191 | it_should_apply_error_logic_for_input_type(:select)
192 | it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
193 | it_should_use_the_collection_when_provided(:select, 'option')
194 |
195 | it 'should have a select inside the wrapper' do
196 | output_buffer.should have_tag('form li select')
197 | output_buffer.should have_tag('form li select#author_post_ids')
198 | end
199 |
200 | it 'should have a multi-select select' do
201 | output_buffer.should have_tag('form li select[@multiple="multiple"]')
202 | end
203 |
204 | it 'should have a select option for each Post' do
205 | output_buffer.should have_tag('form li select option', :count => ::Post.find(:all).size)
206 | ::Post.find(:all).each do |post|
207 | output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
208 | end
209 | end
210 |
211 | it 'should not have a blank option' do
212 | output_buffer.should_not have_tag("form li select option[@value='']")
213 | end
214 |
215 | it 'should have one option with a "selected" attribute' do
216 | output_buffer.should have_tag('form li select option[@selected]', :count => 1)
217 | end
218 | end
219 |
220 | describe 'for a has_and_belongs_to_many association' do
221 | before do
222 | semantic_form_for(@freds_post) do |builder|
223 | concat(builder.input(:authors, :as => :select))
224 | end
225 | end
226 |
227 | it_should_have_input_wrapper_with_class("select")
228 | it_should_have_input_wrapper_with_id("post_authors_input")
229 | it_should_have_label_with_text(/Author/)
230 | it_should_have_label_for('post_author_ids')
231 | it_should_apply_error_logic_for_input_type(:select)
232 | it_should_call_find_on_association_class_when_no_collection_is_provided(:select)
233 | it_should_use_the_collection_when_provided(:select, 'option')
234 |
235 | it 'should have a select inside the wrapper' do
236 | output_buffer.should have_tag('form li select')
237 | output_buffer.should have_tag('form li select#post_author_ids')
238 | end
239 |
240 | it 'should have a multi-select select' do
241 | output_buffer.should have_tag('form li select[@multiple="multiple"]')
242 | end
243 |
244 | it 'should have a select option for each Author' do
245 | output_buffer.should have_tag('form li select option', :count => ::Author.find(:all).size)
246 | ::Author.find(:all).each do |author|
247 | output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
248 | end
249 | end
250 |
251 | it 'should not have a blank option' do
252 | output_buffer.should_not have_tag("form li select option[@value='']")
253 | end
254 |
255 | it 'should have one option with a "selected" attribute' do
256 | output_buffer.should have_tag('form li select option[@selected]', :count => 1)
257 | end
258 | end
259 |
260 | describe 'when :prompt => "choose something" is set' do
261 | before do
262 | @new_post.stub!(:author_id).and_return(nil)
263 | semantic_form_for(@new_post) do |builder|
264 | concat(builder.input(:author, :as => :select, :prompt => "choose author"))
265 | end
266 | end
267 |
268 | it 'should have a select with prompt' do
269 | output_buffer.should have_tag("form li select option[@value='']", /choose author/)
270 | end
271 |
272 | it 'should not have a blank select option' do
273 | output_buffer.should_not have_tag("form li select option[@value='']", "")
274 | end
275 | end
276 |
277 | describe 'when no object is given' do
278 | before(:each) do
279 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
280 | concat(builder.input(:author, :as => :select, :collection => ::Author.find(:all)))
281 | end
282 | end
283 |
284 | it 'should generate label' do
285 | output_buffer.should have_tag('form li label', /Author/)
286 | output_buffer.should have_tag("form li label[@for='project_author']")
287 | end
288 |
289 | it 'should generate select inputs' do
290 | output_buffer.should have_tag('form li select#project_author')
291 | output_buffer.should have_tag('form li select option', :count => ::Author.find(:all).size + 1)
292 | end
293 |
294 | it 'should generate an option to each item' do
295 | ::Author.find(:all).each do |author|
296 | output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
297 | end
298 | end
299 | end
300 |
301 | describe 'when :selected is set' do
302 | before do
303 | @output_buffer = ''
304 | end
305 |
306 | describe "no selected items" do
307 | before do
308 | @new_post.stub!(:author_id).and_return(nil)
309 | semantic_form_for(@new_post) do |builder|
310 | concat(builder.input(:author, :as => :select, :selected => nil))
311 | end
312 | end
313 |
314 | it 'should not have any selected item(s)' do
315 | output_buffer.should_not have_tag("form li select option[@selected='selected']")
316 | end
317 | end
318 |
319 | describe "single selected item" do
320 | before do
321 | @new_post.stub!(:author_id).and_return(nil)
322 | semantic_form_for(@new_post) do |builder|
323 | concat(builder.input(:author, :as => :select, :selected => @bob.id))
324 | end
325 | end
326 |
327 | it 'should have a selected item; the specified one' do
328 | output_buffer.should have_tag("form li select option[@selected='selected']", :count => 1)
329 | output_buffer.should have_tag("form li select option[@selected='selected']", /bob/i)
330 | output_buffer.should have_tag("form li select option[@selected='selected'][@value='#{@bob.id}']")
331 | end
332 | end
333 |
334 | describe "multiple selected items" do
335 |
336 | describe "when :multiple => false" do
337 | before do
338 | @new_post.stub!(:author_ids).and_return(nil)
339 |
340 | semantic_form_for(@new_post) do |builder|
341 | concat(builder.input(:authors, :as => :select, :selected => [@bob.id, @fred.id], :multiple => false))
342 | end
343 | end
344 |
345 | it "should only select the first value" do
346 | output_buffer.should have_tag("form li select option[@selected='selected']", :count => 1)
347 | # FIXME: Not supported by Nokogiri.
348 | # output_buffer.should have_tag("form li select:not([@multiple]) option[@selected='selected']", /bob/i)
349 | # output_buffer.should have_tag("form li select:not([@multiple]) option[@selected='selected'][@value='#{@bob.id}']")
350 | end
351 | end
352 |
353 | describe "when :multiple => true" do
354 | before do
355 | @new_post.stub!(:author_ids).and_return(nil)
356 |
357 | semantic_form_for(@new_post) do |builder|
358 | concat(builder.input(:authors, :as => :select, :selected => [@bob.id, @fred.id]))
359 | end
360 | end
361 |
362 | it "should have multiple items selected; the specified ones" do
363 | output_buffer.should have_tag("form li select option[@selected='selected']", :count => 2)
364 | output_buffer.should have_tag("form li select[@multiple] option[@selected='selected']", /bob/i)
365 | output_buffer.should have_tag("form li select[@multiple] option[@selected='selected'][@value='#{@bob.id}']")
366 | output_buffer.should have_tag("form li select[@multiple] option[@selected='selected']", /fred/i)
367 | output_buffer.should have_tag("form li select[@multiple] option[@selected='selected'][@value='#{@fred.id}']")
368 | end
369 | end
370 |
371 | end
372 |
373 | end
374 |
375 | describe 'boolean select' do
376 | describe 'default formtastic locale' do
377 | before do
378 | # Note: Works, but something like Formtastic.root.join(...) would probably be "safer".
379 | ::I18n.load_path = [File.join(File.dirname(__FILE__), *%w[.. .. lib locale en.yml])]
380 | ::I18n.backend.send(:init_translations)
381 |
382 | semantic_form_for(@new_post) do |builder|
383 | concat(builder.input(:published, :as => :select))
384 | end
385 | end
386 |
387 | after do
388 | ::I18n.backend.store_translations :en, {}
389 | end
390 |
391 | it 'should render a select with at least options: true/false' do
392 | output_buffer.should have_tag("form li select option[@value='true']", /^Yes$/)
393 | output_buffer.should have_tag("form li select option[@value='false']", /^No$/)
394 | end
395 | end
396 |
397 | describe 'custom locale' do
398 | before do
399 | @boolean_select_labels = {:yes => 'Yep', :no => 'Nope'}
400 | ::I18n.backend.store_translations :en, :formtastic => @boolean_select_labels
401 |
402 | semantic_form_for(@new_post) do |builder|
403 | concat(builder.input(:published, :as => :select))
404 | end
405 | end
406 |
407 | after do
408 | ::I18n.backend.store_translations :en, {}
409 | end
410 |
411 | it 'should render a select with at least options: true/false' do
412 | output_buffer.should have_tag("form li select option[@value='true']", /#{@boolean_select_labels[:yes]}/)
413 | output_buffer.should have_tag("form li select option[@value='false']", /#{@boolean_select_labels[:no]}/)
414 | end
415 | end
416 | end
417 |
418 | describe "enums" do
419 | describe ":collection is set" do
420 | before do
421 | @output_buffer = ''
422 | @some_meta_descriptions = ["One", "Two", "Three"]
423 | @new_post.stub!(:meta_description).any_number_of_times
424 | end
425 |
426 | describe ":as is not set" do
427 | before do
428 | semantic_form_for(@new_post) do |builder|
429 | concat(builder.input(:meta_description, :collection => @some_meta_descriptions))
430 | end
431 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
432 | concat(builder.input(:meta_description, :collection => @some_meta_descriptions))
433 | end
434 | end
435 |
436 | it "should render a select field" do
437 | output_buffer.should have_tag("form li select", :count => 2)
438 | end
439 | end
440 |
441 | describe ":as is set" do
442 | before do
443 | # Should not be a case, but just checking :as got highest priority in setting input type.
444 | semantic_form_for(@new_post) do |builder|
445 | concat(builder.input(:meta_description, :as => :string, :collection => @some_meta_descriptions))
446 | end
447 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
448 | concat(builder.input(:meta_description, :as => :string, :collection => @some_meta_descriptions))
449 | end
450 | end
451 |
452 | it "should render a text field" do
453 | output_buffer.should have_tag("form li input[@type='text']", :count => 2)
454 | end
455 | end
456 | end
457 | end
458 |
459 | end
460 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/string_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'string input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:title, :as => :string))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class(:string)
18 | it_should_have_input_wrapper_with_id("post_title_input")
19 | it_should_have_label_with_text(/Title/)
20 | it_should_have_label_for("post_title")
21 | it_should_have_input_with_id("post_title")
22 | it_should_have_input_with_type(:text)
23 | it_should_have_input_with_name("post[title]")
24 | it_should_have_maxlength_matching_column_limit
25 | it_should_use_default_text_field_size_for_columns_longer_than_default_text_field_size(:string)
26 | it_should_use_column_size_for_columns_shorter_than_default_text_field_size(:string)
27 | it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
28 | it_should_apply_custom_input_attributes_when_input_html_provided(:string)
29 | it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
30 | it_should_apply_error_logic_for_input_type(:string)
31 |
32 | describe "when no object is provided" do
33 | before do
34 | semantic_form_for(:project, :url => 'http://test.host/') do |builder|
35 | concat(builder.input(:title, :as => :string))
36 | end
37 | end
38 |
39 | it_should_have_label_with_text(/Title/)
40 | it_should_have_label_for("project_title")
41 | it_should_have_input_with_id("project_title")
42 | it_should_have_input_with_type(:text)
43 | it_should_have_input_with_name("project[title]")
44 | end
45 |
46 | end
47 |
48 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/text_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'text input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:body, :as => :text))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class("text")
18 | it_should_have_input_wrapper_with_id("post_body_input")
19 | it_should_have_label_with_text(/Body/)
20 | it_should_have_label_for("post_body")
21 | it_should_have_textarea_with_id("post_body")
22 | it_should_have_textarea_with_name("post[body]")
23 | it_should_apply_error_logic_for_input_type(:numeric)
24 |
25 | it 'should use input_html to style inputs' do
26 | semantic_form_for(@new_post) do |builder|
27 | concat(builder.input(:title, :as => :text, :input_html => { :class => 'myclass' }))
28 | end
29 | output_buffer.should have_tag("form li textarea.myclass")
30 | end
31 |
32 | end
33 |
34 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/time_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'time input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:publish_at, :as => :time))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class("time")
18 | it_should_have_input_wrapper_with_id("post_publish_at_input")
19 | it_should_have_a_nested_fieldset
20 | it_should_apply_error_logic_for_input_type(:time)
21 |
22 | it 'should have a legend - classified as a label - containing the label text inside the fieldset' do
23 | output_buffer.should have_tag('form li.time fieldset legend.label', /Publish at/)
24 | end
25 |
26 | it 'should have an ordered list of two items inside the fieldset' do
27 | output_buffer.should have_tag('form li.time fieldset ol')
28 | output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
29 | end
30 |
31 | it 'should have five labels for hour and minute' do
32 | output_buffer.should have_tag('form li.time fieldset ol li label', :count => 2)
33 | output_buffer.should have_tag('form li.time fieldset ol li label', /hour/i)
34 | output_buffer.should have_tag('form li.time fieldset ol li label', /minute/i)
35 | end
36 |
37 | it 'should have two selects for hour and minute' do
38 | output_buffer.should have_tag('form li.time fieldset ol li', :count => 2)
39 | end
40 |
41 | it_should_select_existing_datetime_else_current(:hour, :minute, :second)
42 | it_should_select_explicit_default_value_if_set(:hour, :minute, :second)
43 |
44 | end
45 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs/time_zone_input_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/../spec_helper'
3 |
4 | describe 'time_zone input' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 |
12 | semantic_form_for(@new_post) do |builder|
13 | concat(builder.input(:time_zone))
14 | end
15 | end
16 |
17 | it_should_have_input_wrapper_with_class("time_zone")
18 | it_should_have_input_wrapper_with_id("post_time_zone_input")
19 | it_should_apply_error_logic_for_input_type(:time_zone)
20 |
21 | it 'should generate a label for the input' do
22 | output_buffer.should have_tag('form li label')
23 | output_buffer.should have_tag('form li label[@for="post_time_zone"]')
24 | output_buffer.should have_tag('form li label', /Time zone/)
25 | end
26 |
27 | it "should generate a select" do
28 | output_buffer.should have_tag("form li select")
29 | output_buffer.should have_tag("form li select#post_time_zone")
30 | output_buffer.should have_tag("form li select[@name=\"post[time_zone]\"]")
31 | end
32 |
33 | it 'should use input_html to style inputs' do
34 | semantic_form_for(@new_post) do |builder|
35 | concat(builder.input(:time_zone, :input_html => { :class => 'myclass' }))
36 | end
37 | output_buffer.should have_tag("form li select.myclass")
38 | end
39 |
40 | describe 'when no object is given' do
41 | before(:each) do
42 | semantic_form_for(:project, :url => 'http://test.host/') do |builder|
43 | concat(builder.input(:time_zone, :as => :time_zone))
44 | end
45 | end
46 |
47 | it 'should generate labels' do
48 | output_buffer.should have_tag('form li label')
49 | output_buffer.should have_tag('form li label[@for="project_time_zone"]')
50 | output_buffer.should have_tag('form li label', /Time zone/)
51 | end
52 |
53 | it 'should generate select inputs' do
54 | output_buffer.should have_tag("form li select")
55 | output_buffer.should have_tag("form li select#project_time_zone")
56 | output_buffer.should have_tag("form li select[@name=\"project[time_zone]\"]")
57 | end
58 | end
59 |
60 | describe 'when :selected is set' do
61 | before do
62 | @output_buffer = ''
63 | end
64 |
65 | # Note: Not possible to override default selected value for time_zone input
66 | # without overriding Rails time_zone_select. This Rails helper works "a bit different". =/
67 | #
68 | # describe "no selected items" do
69 | # before do
70 | # @new_post.stub!(:time_zone).and_return('Stockholm')
71 | #
72 | # semantic_form_for(@new_post) do |builder|
73 | # concat(builder.input(:time_zone, :as => :time_zone, :selected => nil))
74 | # end
75 | # end
76 | #
77 | # it 'should not have any selected item(s)' do
78 | # output_buffer.should_not have_tag("form li select option[@selected='selected']")
79 | # end
80 | # end
81 |
82 | describe "single selected item" do
83 | before do
84 | # Note: See above...only works for the "attribute is nil" case.
85 | # @new_post.stub!(:time_zone).and_return('Stockholm')
86 | @new_post.stub!(:time_zone).and_return(nil)
87 |
88 | semantic_form_for(@new_post) do |builder|
89 | concat(builder.input(:time_zone, :as => :time_zone, :selected => 'Melbourne'))
90 | end
91 | end
92 |
93 | it 'should have a selected item; the specified one' do
94 | output_buffer.should have_tag("form li select option[@selected='selected']", :count => 1)
95 | output_buffer.should have_tag("form li select option[@selected='selected']", /Melbourne/i)
96 | output_buffer.should have_tag("form li select option[@selected='selected'][@value='Melbourne']")
97 | end
98 | end
99 |
100 | end
101 |
102 | end
103 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/inputs_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'SemanticFormBuilder#inputs' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | end
12 |
13 | describe 'with a block' do
14 |
15 | describe 'when no options are provided' do
16 | before do
17 | output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
18 | semantic_form_for(@new_post) do |builder|
19 | @inputs_output = builder.inputs do
20 | concat('hello')
21 | end
22 | end
23 | end
24 |
25 | it 'should output just the content wrapped in inputs, not the whole template' do
26 | output_buffer.should =~ /before_builder/
27 | @inputs_output.should_not =~ /before_builder/
28 | end
29 |
30 | it 'should render a fieldset inside the form, with a class of "inputs"' do
31 | output_buffer.should have_tag("form fieldset.inputs")
32 | end
33 |
34 | it 'should render an ol inside the fieldset' do
35 | output_buffer.should have_tag("form fieldset.inputs ol")
36 | end
37 |
38 | it 'should render the contents of the block inside the ol' do
39 | output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
40 | end
41 |
42 | it 'should not render a legend inside the fieldset' do
43 | output_buffer.should_not have_tag("form fieldset.inputs legend")
44 | end
45 |
46 | it 'should render a fieldset even if no object is given' do
47 | semantic_form_for(:project, :url => 'http://test.host/') do |builder|
48 | @inputs_output = builder.inputs do
49 | concat('bye')
50 | end
51 | end
52 |
53 | output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
54 | end
55 | end
56 |
57 | describe 'when a :for option is provided' do
58 |
59 | before do
60 | @new_post.stub!(:respond_to?).and_return(true, true)
61 | @new_post.stub!(:author).and_return(@bob)
62 | end
63 |
64 | it 'should render nested inputs' do
65 | @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
66 |
67 | semantic_form_for(@new_post) do |builder|
68 | builder.inputs :for => [:author, @bob] do |bob_builder|
69 | concat(bob_builder.input(:login))
70 | end
71 | end
72 |
73 | output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
74 | output_buffer.should_not have_tag("form fieldset.inputs #author_login")
75 |
76 | end
77 |
78 | describe "as a symbol representing the association name" do
79 |
80 | it 'should nest the inputs with an _attributes suffix on the association name' do
81 | semantic_form_for(@new_post) do |post|
82 | post.inputs :for => :author do |author|
83 | concat(author.input(:login))
84 | end
85 | end
86 | output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
87 | end
88 |
89 | end
90 |
91 | describe 'as an array containing the a symbole for the association name and the associated object' do
92 |
93 | it 'should nest the inputs with an _attributes suffix on the association name' do
94 | semantic_form_for(@new_post) do |post|
95 | post.inputs :for => [:author, @new_post.author] do |author|
96 | concat(author.input(:login))
97 | end
98 | end
99 | output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
100 | end
101 |
102 | end
103 |
104 | describe 'as an associated object' do
105 |
106 | it 'should not nest the inputs with an _attributes suffix' do
107 | semantic_form_for(@new_post) do |post|
108 | post.inputs :for => @new_post.author do |author|
109 | concat(author.input(:login))
110 | end
111 | end
112 | output_buffer.should have_tag("form input[@name='post[author][login]']")
113 | end
114 |
115 | end
116 |
117 | it 'should raise an error if :for and block with no argument is given' do
118 | semantic_form_for(@new_post) do |builder|
119 | proc {
120 | builder.inputs(:for => [:author, @bob]) do
121 | #
122 | end
123 | }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
124 | 'but the block does not accept any argument.')
125 | end
126 | end
127 |
128 | it 'should pass options down to semantic_fields_for' do
129 | @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
130 |
131 | semantic_form_for(@new_post) do |builder|
132 | builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
133 | concat(bob_builder.input(:login))
134 | end
135 | end
136 |
137 | output_buffer.should have_tag('form fieldset ol li #post_author_attributes_10_login')
138 | end
139 |
140 | it 'should not add builder as a fieldset attribute tag' do
141 | semantic_form_for(@new_post) do |builder|
142 | builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
143 | concat('input')
144 | end
145 | end
146 |
147 | output_buffer.should_not have_tag('fieldset[@builder="Formtastic::SemanticFormHelper"]')
148 | end
149 |
150 | it 'should send parent_builder as an option to allow child index interpolation' do
151 | semantic_form_for(@new_post) do |builder|
152 | builder.instance_variable_set('@nested_child_index', 0)
153 | builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
154 | concat('input')
155 | end
156 | end
157 |
158 | output_buffer.should have_tag('fieldset legend', 'Author #1')
159 | end
160 |
161 | it 'should also provide child index interpolation when nested child index is a hash' do
162 | semantic_form_for(@new_post) do |builder|
163 | builder.instance_variable_set('@nested_child_index', :author => 10)
164 | builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
165 | concat('input')
166 | end
167 | end
168 |
169 | output_buffer.should have_tag('fieldset legend', 'Author #11')
170 | end
171 | end
172 |
173 | describe 'when a :name or :title option is provided' do
174 | describe 'and is a string' do
175 | before do
176 | @legend_text = "Advanced options"
177 | @legend_text_using_name = "Advanced options 2"
178 | @legend_text_using_title = "Advanced options 3"
179 | @nested_forms_legend_text = "This is a nested form title"
180 | semantic_form_for(@new_post) do |builder|
181 | builder.inputs @legend_text do
182 | end
183 | builder.inputs :name => @legend_text_using_name do
184 | end
185 | builder.inputs :title => @legend_text_using_title do
186 | end
187 | builder.inputs @nested_forms_legend_text, :for => :authors do |nf|
188 | end
189 | end
190 | end
191 |
192 | it 'should render a fieldset with a legend inside the form' do
193 | output_buffer.should have_tag("form fieldset legend", /^#{@legend_text}$/)
194 | output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_name}$/)
195 | output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_title}$/)
196 | output_buffer.should have_tag("form fieldset legend", /^#{@nested_forms_legend_text}$/)
197 | end
198 | end
199 |
200 | describe 'and is a symbol' do
201 | before do
202 | @localized_legend_text = "Localized advanced options"
203 | @localized_legend_text_using_name = "Localized advanced options 2"
204 | @localized_legend_text_using_title = "Localized advanced options 3"
205 | @localized_nested_forms_legend_text = "This is a localized nested form title"
206 | ::I18n.backend.store_translations :en, :formtastic => {
207 | :titles => {
208 | :post => {
209 | :advanced_options => @localized_legend_text,
210 | :advanced_options_using_name => @localized_legend_text_using_name,
211 | :advanced_options_using_title => @localized_legend_text_using_title,
212 | :nested_forms_title => @localized_nested_forms_legend_text
213 | }
214 | }
215 | }
216 | semantic_form_for(@new_post) do |builder|
217 | builder.inputs :advanced_options do
218 | end
219 | builder.inputs :name => :advanced_options_using_name do
220 | end
221 | builder.inputs :title => :advanced_options_using_title do
222 | end
223 | builder.inputs :nested_forms_title, :for => :authors do |nf|
224 | end
225 | end
226 | end
227 |
228 | it 'should render a fieldset with a localized legend inside the form' do
229 | output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text}$/)
230 | output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_name}$/)
231 | output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_title}$/)
232 | output_buffer.should have_tag("form fieldset legend", /^#{@localized_nested_forms_legend_text}$/)
233 | end
234 | end
235 | end
236 |
237 | describe 'when other options are provided' do
238 | before do
239 | @id_option = 'advanced'
240 | @class_option = 'wide'
241 |
242 | semantic_form_for(@new_post) do |builder|
243 | builder.inputs :id => @id_option, :class => @class_option do
244 | end
245 | end
246 | end
247 |
248 | it 'should pass the options into the fieldset tag as attributes' do
249 | output_buffer.should have_tag("form fieldset##{@id_option}")
250 | output_buffer.should have_tag("form fieldset.#{@class_option}")
251 | end
252 | end
253 |
254 | end
255 |
256 | describe 'without a block' do
257 |
258 | before do
259 | ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
260 | :comments => mock('reflection', :options => {}, :macro => :has_many) })
261 | ::Author.stub!(:find).and_return([@fred, @bob])
262 |
263 | @new_post.stub!(:title)
264 | @new_post.stub!(:body)
265 | @new_post.stub!(:author_id)
266 |
267 | @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
268 | @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
269 | @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
270 | @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
271 | end
272 |
273 | describe 'with no args' do
274 | before do
275 | semantic_form_for(@new_post) do |builder|
276 | concat(builder.inputs)
277 | end
278 | end
279 |
280 | it 'should render a form' do
281 | output_buffer.should have_tag('form')
282 | end
283 |
284 | it 'should render a fieldset inside the form' do
285 | output_buffer.should have_tag('form > fieldset.inputs')
286 | end
287 |
288 | it 'should not render a legend in the fieldset' do
289 | output_buffer.should_not have_tag('form > fieldset.inputs > legend')
290 | end
291 |
292 | it 'should render an ol in the fieldset' do
293 | output_buffer.should have_tag('form > fieldset.inputs > ol')
294 | end
295 |
296 | it 'should render a list item in the ol for each column and reflection' do
297 | # Remove the :has_many macro and :created_at column
298 | count = ::Post.content_columns.size + ::Post.reflections.size - 2
299 | output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
300 | end
301 |
302 | it 'should render a string list item for title' do
303 | output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
304 | end
305 |
306 | it 'should render a text list item for body' do
307 | output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
308 | end
309 |
310 | it 'should render a select list item for author_id' do
311 | output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
312 | end
313 |
314 | it 'should not render timestamps inputs by default' do
315 | output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
316 | end
317 | end
318 |
319 | describe 'with column names as args' do
320 | describe 'and an object is given' do
321 | it 'should render a form with a fieldset containing two list items' do
322 | semantic_form_for(@new_post) do |builder|
323 | concat(builder.inputs(:title, :body))
324 | end
325 |
326 | output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
327 | output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
328 | output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
329 | end
330 | end
331 |
332 | describe 'and no object is given' do
333 | it 'should render a form with a fieldset containing two list items' do
334 | semantic_form_for(:project, :url => 'http://test.host') do |builder|
335 | concat(builder.inputs(:title, :body))
336 | end
337 |
338 | output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
339 | end
340 | end
341 | end
342 |
343 | describe 'when a :for option is provided' do
344 | describe 'and an object is given' do
345 | it 'should render nested inputs' do
346 | @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
347 |
348 | semantic_form_for(@new_post) do |builder|
349 | concat(builder.inputs(:login, :for => @bob))
350 | end
351 |
352 | output_buffer.should have_tag("form fieldset.inputs #post_author_login")
353 | output_buffer.should_not have_tag("form fieldset.inputs #author_login")
354 | end
355 | end
356 |
357 | describe 'and no object is given' do
358 | it 'should render nested inputs' do
359 | semantic_form_for(:project, :url => 'http://test.host/') do |builder|
360 | concat(builder.inputs(:login, :for => @bob))
361 | end
362 |
363 | output_buffer.should have_tag("form fieldset.inputs #project_author_login")
364 | output_buffer.should_not have_tag("form fieldset.inputs #project_login")
365 | end
366 | end
367 | end
368 |
369 | describe 'with column names and an options hash as args' do
370 | before do
371 | semantic_form_for(@new_post) do |builder|
372 | @legend_text_using_option = "Legendary Legend Text"
373 | @legend_text_using_arg = "Legendary Legend Text 2"
374 | concat(builder.inputs(:title, :body, :name => @legend_text_using_option, :id => "my-id"))
375 | concat(builder.inputs(@legend_text_using_arg, :title, :body, :id => "my-id-2"))
376 | end
377 | end
378 |
379 | it 'should render a form with a fieldset containing two list items' do
380 | output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 4)
381 | end
382 |
383 | it 'should pass the options down to the fieldset' do
384 | output_buffer.should have_tag('form > fieldset#my-id.inputs')
385 | end
386 |
387 | it 'should use the special :name option as a text for the legend tag' do
388 | output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /^#{@legend_text_using_option}$/)
389 | output_buffer.should have_tag('form > fieldset#my-id-2.inputs > legend', /^#{@legend_text_using_arg}$/)
390 | end
391 | end
392 |
393 | end
394 |
395 | end
396 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/label_spec.rb:
--------------------------------------------------------------------------------
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 |
49 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/semantic_errors_spec.rb:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | require File.dirname(__FILE__) + '/spec_helper'
3 |
4 | describe 'SemanticFormBuilder#semantic_errors' do
5 |
6 | include FormtasticSpecHelper
7 |
8 | before do
9 | @output_buffer = ''
10 | mock_everything
11 | @title_errors = ['must not be blank', 'must be awesome']
12 | @base_errors = ['base error message', 'nasty error']
13 | @base_error = 'one base error'
14 | @errors = mock('errors')
15 | @new_post.stub!(:errors).and_return(@errors)
16 | end
17 |
18 | describe 'when there is only one error on base' do
19 | before do
20 | @errors.stub!(:on_base).and_return(@base_error)
21 | end
22 |
23 | it 'should render an unordered list' do
24 | semantic_form_for(@new_post) do |builder|
25 | builder.semantic_errors.should have_tag('ul.errors li', @base_error)
26 | end
27 | end
28 | end
29 |
30 | describe 'when there is more than one error on base' do
31 | before do
32 | @errors.stub!(:on_base).and_return(@base_errors)
33 | end
34 |
35 | it 'should render an unordered list' do
36 | semantic_form_for(@new_post) do |builder|
37 | builder.semantic_errors.should have_tag('ul.errors')
38 | @base_errors.each do |error|
39 | builder.semantic_errors.should have_tag('ul.errors li', error)
40 | end
41 | end
42 | end
43 | end
44 |
45 | describe 'when there are errors on title' do
46 | before do
47 | @errors.stub!(:[]).with(:title).and_return(@title_errors)
48 | @errors.stub!(:on_base).and_return([])
49 | end
50 |
51 | it 'should render an unordered list' do
52 | semantic_form_for(@new_post) do |builder|
53 | title_name = builder.send(:localized_string, :title, :title, :label) || builder.send(:humanized_attribute_name, :title)
54 | builder.semantic_errors(:title).should have_tag('ul.errors li', title_name << " " << @title_errors.to_sentence)
55 | end
56 | end
57 | end
58 |
59 | describe 'when there are errors on title and base' do
60 | before do
61 | @errors.stub!(:[]).with(:title).and_return(@title_errors)
62 | @errors.stub!(:on_base).and_return(@base_error)
63 | end
64 |
65 | it 'should render an unordered list' do
66 | semantic_form_for(@new_post) do |builder|
67 | title_name = builder.send(:localized_string, :title, :title, :label) || builder.send(:humanized_attribute_name, :title)
68 | builder.semantic_errors(:title).should have_tag('ul.errors li', title_name << " " << @title_errors.to_sentence)
69 | builder.semantic_errors(:title).should have_tag('ul.errors li', @base_error)
70 | end
71 | end
72 | end
73 |
74 | describe 'when there are no errors' do
75 | before do
76 | @errors.stub!(:[]).with(:title).and_return(nil)
77 | @errors.stub!(:on_base).and_return(nil)
78 | end
79 |
80 | it 'should return nil' do
81 | semantic_form_for(@new_post) do |builder|
82 | builder.semantic_errors(:title).should be_nil
83 | end
84 | end
85 | end
86 |
87 | describe 'when there is one error on base and options with class is passed' do
88 | before do
89 | @errors.stub!(:on_base).and_return(@base_error)
90 | end
91 |
92 | it 'should render an unordered list with given class' do
93 | semantic_form_for(@new_post) do |builder|
94 | builder.semantic_errors(:class => "awesome").should have_tag('ul.awesome li', @base_error)
95 | end
96 | end
97 | end
98 | end
99 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/semantic_fields_for_spec.rb:
--------------------------------------------------------------------------------
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 |
45 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/spec.opts:
--------------------------------------------------------------------------------
1 | --color
2 | --format=progress
3 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/spec/spec_helper.rb:
--------------------------------------------------------------------------------
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 | module ::Namespaced
65 | class Post
66 | def id
67 | end
68 | end
69 | end
70 | class ::Author
71 | def to_label
72 | end
73 | end
74 | class ::Continent
75 | end
76 |
77 | def mock_everything
78 |
79 | # Resource-oriented styles like form_for(@post) will expect a path method for the object,
80 | # so we're defining some here.
81 | def post_path(o); "/posts/1"; end
82 | def posts_path; "/posts"; end
83 | def new_post_path; "/posts/new"; end
84 |
85 | def author_path(o); "/authors/1"; end
86 | def authors_path; "/authors"; end
87 | def new_author_path; "/authors/new"; end
88 |
89 | @fred = mock('user')
90 | @fred.stub!(:class).and_return(::Author)
91 | @fred.stub!(:to_label).and_return('Fred Smith')
92 | @fred.stub!(:login).and_return('fred_smith')
93 | @fred.stub!(:id).and_return(37)
94 | @fred.stub!(:new_record?).and_return(false)
95 | @fred.stub!(:errors).and_return(mock('errors', :[] => nil))
96 |
97 | @bob = mock('user')
98 | @bob.stub!(:class).and_return(::Author)
99 | @bob.stub!(:to_label).and_return('Bob Rock')
100 | @bob.stub!(:login).and_return('bob')
101 | @bob.stub!(:created_at)
102 | @bob.stub!(:id).and_return(42)
103 | @bob.stub!(:posts).and_return([])
104 | @bob.stub!(:post_ids).and_return([])
105 | @bob.stub!(:new_record?).and_return(false)
106 | @bob.stub!(:errors).and_return(mock('errors', :[] => nil))
107 |
108 | @james = mock('user')
109 | @james.stub!(:class).and_return(::Author)
110 | @james.stub!(:to_label).and_return('James Shock')
111 | @james.stub!(:login).and_return('james')
112 | @james.stub!(:id).and_return(75)
113 | @james.stub!(:posts).and_return([])
114 | @james.stub!(:post_ids).and_return([])
115 | @james.stub!(:new_record?).and_return(false)
116 | @james.stub!(:errors).and_return(mock('errors', :[] => nil))
117 |
118 |
119 | ::Author.stub!(:find).and_return([@fred, @bob])
120 | ::Author.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
121 | ::Author.stub!(:human_name).and_return('::Author')
122 | ::Author.stub!(:reflect_on_validations_for).and_return([])
123 | ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Post, :macro => :has_many) if column_name == :posts }
124 | ::Author.stub!(:content_columns).and_return([mock('column', :name => 'login'), mock('column', :name => 'created_at')])
125 |
126 | # Sometimes we need a mock @post object and some Authors for belongs_to
127 | @new_post = mock('post')
128 | @new_post.stub!(:class).and_return(::Post)
129 | @new_post.stub!(:id).and_return(nil)
130 | @new_post.stub!(:new_record?).and_return(true)
131 | @new_post.stub!(:errors).and_return(mock('errors', :[] => nil))
132 | @new_post.stub!(:author).and_return(nil)
133 | @new_post.stub!(:main_post).and_return(nil)
134 | @new_post.stub!(:sub_posts).and_return([]) #TODO should be a mock with methods for adding sub posts
135 |
136 | @freds_post = mock('post')
137 | @freds_post.stub!(:class).and_return(::Post)
138 | @freds_post.stub!(:to_label).and_return('Fred Smith')
139 | @freds_post.stub!(:id).and_return(19)
140 | @freds_post.stub!(:author).and_return(@fred)
141 | @freds_post.stub!(:author_id).and_return(@fred.id)
142 | @freds_post.stub!(:authors).and_return([@fred])
143 | @freds_post.stub!(:author_ids).and_return([@fred.id])
144 | @freds_post.stub!(:new_record?).and_return(false)
145 | @freds_post.stub!(:errors).and_return(mock('errors', :[] => nil))
146 | @fred.stub!(:posts).and_return([@freds_post])
147 | @fred.stub!(:post_ids).and_return([@freds_post.id])
148 |
149 | ::Post.stub!(:human_attribute_name).and_return { |column_name| column_name.humanize }
150 | ::Post.stub!(:human_name).and_return('Post')
151 | ::Post.stub!(:reflect_on_all_validations).and_return([])
152 | ::Post.stub!(:reflect_on_validations_for).and_return([])
153 | ::Post.stub!(:reflect_on_association).and_return do |column_name|
154 | case column_name
155 | when :author, :author_status
156 | mock = mock('reflection', :options => {}, :klass => ::Author, :macro => :belongs_to)
157 | mock.stub!(:[]).with(:class_name).and_return("Author")
158 | mock
159 | when :authors
160 | mock('reflection', :options => {}, :klass => ::Author, :macro => :has_and_belongs_to_many)
161 | when :sub_posts
162 | mock('reflection', :options => {}, :klass => ::Post, :macro => :has_many)
163 | when :main_post
164 | mock('reflection', :options => {}, :klass => ::Post, :macro => :belongs_to)
165 | end
166 |
167 | end
168 | ::Post.stub!(:find).and_return([@freds_post])
169 | ::Post.stub!(:content_columns).and_return([mock('column', :name => 'title'), mock('column', :name => 'body'), mock('column', :name => 'created_at')])
170 |
171 | @new_post.stub!(:title)
172 | @new_post.stub!(:body)
173 | @new_post.stub!(:published)
174 | @new_post.stub!(:publish_at)
175 | @new_post.stub!(:created_at)
176 | @new_post.stub!(:secret)
177 | @new_post.stub!(:time_zone)
178 | @new_post.stub!(:category_name)
179 | @new_post.stub!(:allow_comments)
180 | @new_post.stub!(:column_for_attribute).with(:meta_description).and_return(mock('column', :type => :string, :limit => 255))
181 | @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 50))
182 | @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
183 | @new_post.stub!(:column_for_attribute).with(:published).and_return(mock('column', :type => :boolean))
184 | @new_post.stub!(:column_for_attribute).with(:publish_at).and_return(mock('column', :type => :date))
185 | @new_post.stub!(:column_for_attribute).with(:time_zone).and_return(mock('column', :type => :string))
186 | @new_post.stub!(:column_for_attribute).with(:allow_comments).and_return(mock('column', :type => :boolean))
187 |
188 | @new_post.stub!(:author).and_return(@bob)
189 | @new_post.stub!(:author_id).and_return(@bob.id)
190 |
191 | @new_post.should_receive(:publish_at=).any_number_of_times
192 | @new_post.should_receive(:title=).any_number_of_times
193 | @new_post.stub!(:main_post_id).and_return(nil)
194 |
195 | end
196 |
197 | def self.included(base)
198 | base.class_eval do
199 |
200 | attr_accessor :output_buffer
201 |
202 | def protect_against_forgery?
203 | false
204 | end
205 |
206 | end
207 | end
208 |
209 | def with_config(config_method_name, value, &block)
210 | old_value = ::Formtastic::SemanticFormBuilder.send(config_method_name)
211 | ::Formtastic::SemanticFormBuilder.send(:"#{config_method_name}=", value)
212 | yield
213 | ::Formtastic::SemanticFormBuilder.send(:"#{config_method_name}=", old_value)
214 | end
215 |
216 | end
217 |
218 | ::ActiveSupport::Deprecation.silenced = false
219 |
--------------------------------------------------------------------------------
/vendor/plugins/formtastic/uninstall.rb:
--------------------------------------------------------------------------------
1 | # Uninstall hook code here
2 |
--------------------------------------------------------------------------------