merb-helpers 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +180 -0
- data/Rakefile +77 -0
- data/TODO +5 -0
- data/lib/merb-helpers.rb +38 -0
- data/lib/merb-helpers/core_ext.rb +57 -0
- data/lib/merb-helpers/core_ext/numeric.rb +388 -0
- data/lib/merb-helpers/date_time_formatting.rb +127 -0
- data/lib/merb-helpers/date_time_helpers.rb +190 -0
- data/lib/merb-helpers/form/builder.rb +410 -0
- data/lib/merb-helpers/form/helpers.rb +448 -0
- data/lib/merb-helpers/form_helpers.rb +24 -0
- data/lib/merb-helpers/tag_helpers.rb +61 -0
- data/lib/merb-helpers/text_helpers.rb +61 -0
- data/lib/merb-helpers/time_dsl.rb +59 -0
- data/spec/core_ext_spec.rb +19 -0
- data/spec/fixture/app/controllers/application.rb +4 -0
- data/spec/fixture/app/controllers/bound_check_box.rb +2 -0
- data/spec/fixture/app/controllers/bound_file_field.rb +2 -0
- data/spec/fixture/app/controllers/bound_hidden_field.rb +2 -0
- data/spec/fixture/app/controllers/bound_option_tag.rb +2 -0
- data/spec/fixture/app/controllers/bound_password_field.rb +2 -0
- data/spec/fixture/app/controllers/bound_radio_button.rb +2 -0
- data/spec/fixture/app/controllers/bound_radio_group.rb +2 -0
- data/spec/fixture/app/controllers/bound_select.rb +2 -0
- data/spec/fixture/app/controllers/bound_text_area.rb +2 -0
- data/spec/fixture/app/controllers/bound_text_field.rb +2 -0
- data/spec/fixture/app/controllers/button.rb +2 -0
- data/spec/fixture/app/controllers/check_box.rb +2 -0
- data/spec/fixture/app/controllers/custom_builder.rb +2 -0
- data/spec/fixture/app/controllers/delete_button.rb +2 -0
- data/spec/fixture/app/controllers/exceptions.rb +25 -0
- data/spec/fixture/app/controllers/field_set.rb +2 -0
- data/spec/fixture/app/controllers/fields_for.rb +3 -0
- data/spec/fixture/app/controllers/file_field.rb +2 -0
- data/spec/fixture/app/controllers/foo.rb +23 -0
- data/spec/fixture/app/controllers/form.rb +2 -0
- data/spec/fixture/app/controllers/form_for.rb +2 -0
- data/spec/fixture/app/controllers/hidden_field.rb +2 -0
- data/spec/fixture/app/controllers/label.rb +3 -0
- data/spec/fixture/app/controllers/numeric_ext.rb +3 -0
- data/spec/fixture/app/controllers/option_tag.rb +2 -0
- data/spec/fixture/app/controllers/password_field.rb +2 -0
- data/spec/fixture/app/controllers/radio_button.rb +2 -0
- data/spec/fixture/app/controllers/radio_group.rb +2 -0
- data/spec/fixture/app/controllers/select.rb +2 -0
- data/spec/fixture/app/controllers/specs_controller.rb +11 -0
- data/spec/fixture/app/controllers/submit.rb +2 -0
- data/spec/fixture/app/controllers/tag_helper.rb +21 -0
- data/spec/fixture/app/controllers/text_area.rb +2 -0
- data/spec/fixture/app/controllers/text_field.rb +3 -0
- data/spec/fixture/app/helpers/global_helpers.rb +8 -0
- data/spec/fixture/app/models/fake_dm_model.rb +25 -0
- data/spec/fixture/app/models/first_generic_fake_model.rb +57 -0
- data/spec/fixture/app/models/second_generic_fake_model.rb +18 -0
- data/spec/fixture/app/models/third_generic_fake_model.rb +3 -0
- data/spec/fixture/app/views/bound_check_box_specs/basic.html.erb +4 -0
- data/spec/fixture/app/views/bound_check_box_specs/checked.html.erb +4 -0
- data/spec/fixture/app/views/bound_check_box_specs/errors.html.erb +4 -0
- data/spec/fixture/app/views/bound_check_box_specs/label.html.erb +3 -0
- data/spec/fixture/app/views/bound_check_box_specs/on_and_off.html.erb +3 -0
- data/spec/fixture/app/views/bound_check_box_specs/raise_value_error.html.erb +3 -0
- data/spec/fixture/app/views/bound_file_field_specs/additional_attributes.html.erb +3 -0
- data/spec/fixture/app/views/bound_file_field_specs/takes_string.html.erb +3 -0
- data/spec/fixture/app/views/bound_file_field_specs/with_label.html.erb +3 -0
- data/spec/fixture/app/views/bound_hidden_field_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/bound_hidden_field_specs/errors.html.erb +3 -0
- data/spec/fixture/app/views/bound_hidden_field_specs/hidden_error.html.erb +3 -0
- data/spec/fixture/app/views/bound_hidden_field_specs/label.html.erb +3 -0
- data/spec/fixture/app/views/bound_option_tag_specs/grouped.html.erb +3 -0
- data/spec/fixture/app/views/bound_option_tag_specs/nested.html.erb +3 -0
- data/spec/fixture/app/views/bound_option_tag_specs/text_and_value.html.erb +4 -0
- data/spec/fixture/app/views/bound_password_field_specs/attributes.html.erb +3 -0
- data/spec/fixture/app/views/bound_password_field_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/bound_password_field_specs/label.html.erb +3 -0
- data/spec/fixture/app/views/bound_radio_button_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/bound_radio_group_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/bound_radio_group_specs/hashes.html.erb +3 -0
- data/spec/fixture/app/views/bound_radio_group_specs/mixed.html.erb +4 -0
- data/spec/fixture/app/views/bound_radio_group_specs/override_id.html.erb +3 -0
- data/spec/fixture/app/views/bound_select_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/bound_select_specs/blank.html.erb +3 -0
- data/spec/fixture/app/views/bound_select_specs/multiple.html.erb +3 -0
- data/spec/fixture/app/views/bound_select_specs/prompt.html.erb +3 -0
- data/spec/fixture/app/views/bound_select_specs/with_options.html.erb +3 -0
- data/spec/fixture/app/views/bound_select_specs/with_options_with_blank.html.erb +3 -0
- data/spec/fixture/app/views/bound_text_area_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/bound_text_field_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/button_specs/button_with_label.html.erb +1 -0
- data/spec/fixture/app/views/button_specs/button_with_values.html.erb +1 -0
- data/spec/fixture/app/views/button_specs/disabled_button.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/boolean.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/label.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/on_off_is_boolean.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/raise_unless_both_on_and_off.html.erb +2 -0
- data/spec/fixture/app/views/check_box_specs/raises_error_if_not_boolean.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/raises_error_if_on_off_and_boolean_false.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/simple.html.erb +1 -0
- data/spec/fixture/app/views/check_box_specs/to_string.html.erb +8 -0
- data/spec/fixture/app/views/check_box_specs/unchecked.html.erb +2 -0
- data/spec/fixture/app/views/custom_builder_specs/everything.html.erb +10 -0
- data/spec/fixture/app/views/delete_button_specs/delete_with_explicit_url.html.erb +1 -0
- data/spec/fixture/app/views/delete_button_specs/delete_with_extra_params.html.erb +1 -0
- data/spec/fixture/app/views/delete_button_specs/delete_with_label.html.erb +1 -0
- data/spec/fixture/app/views/delete_button_specs/simple_delete.html.erb +1 -0
- data/spec/fixture/app/views/exeptions/client_error.html.erb +37 -0
- data/spec/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
- data/spec/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
- data/spec/fixture/app/views/exeptions/not_found.html.erb +40 -0
- data/spec/fixture/app/views/fields_for_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/fields_for_specs/midstream.html.erb +7 -0
- data/spec/fixture/app/views/fields_for_specs/nil.html.erb +3 -0
- data/spec/fixture/app/views/fieldset_specs/legend.html.erb +3 -0
- data/spec/fixture/app/views/file_field_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/file_field_specs/makes_multipart.html.erb +3 -0
- data/spec/fixture/app/views/file_field_specs/with_label.html.erb +1 -0
- data/spec/fixture/app/views/file_field_specs/with_values.html.erb +1 -0
- data/spec/fixture/app/views/foo/bar.html.erb +0 -0
- data/spec/fixture/app/views/form_for_specs/basic.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/create_a_form.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/create_a_multipart_form.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/fake_delete_if_set.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/fake_put_if_set.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/get_if_set.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/post_by_default.html.erb +3 -0
- data/spec/fixture/app/views/form_specs/resourceful_form.html.erb +3 -0
- data/spec/fixture/app/views/hidden_field_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/hidden_field_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/hidden_field_specs/label.html.erb +1 -0
- data/spec/fixture/app/views/label_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/layout/application.html.erb +11 -0
- data/spec/fixture/app/views/numeric_ext_specs/minutes_to_hours.html.erb +1 -0
- data/spec/fixture/app/views/numeric_ext_specs/to_concurrency_default.html.erb +1 -0
- data/spec/fixture/app/views/numeric_ext_specs/two_digits.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/array.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/clean.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/collection.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/multiple_selects.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/no_extra_attributes.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/optgroups.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/selected.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/with_blank.html.erb +1 -0
- data/spec/fixture/app/views/option_tag_specs/with_prompt.html.erb +1 -0
- data/spec/fixture/app/views/password_field_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/password_field_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/radio_button_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/radio_button_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/radio_button_specs/label.html.erb +1 -0
- data/spec/fixture/app/views/radio_group_specs/attributes.html.erb +1 -0
- data/spec/fixture/app/views/radio_group_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/radio_group_specs/hash.html.erb +1 -0
- data/spec/fixture/app/views/radio_group_specs/specific_attributes.html.erb +1 -0
- data/spec/fixture/app/views/select_specs/blank.html.erb +1 -0
- data/spec/fixture/app/views/select_specs/multiple.html.erb +1 -0
- data/spec/fixture/app/views/submit_specs/disabled_submit.html.erb +1 -0
- data/spec/fixture/app/views/submit_specs/submit_with_label.html.erb +1 -0
- data/spec/fixture/app/views/submit_specs/submit_with_values.html.erb +1 -0
- data/spec/fixture/app/views/tag_helper/nested_tags.html.erb +5 -0
- data/spec/fixture/app/views/tag_helper/tag_with_attributes.html.erb +1 -0
- data/spec/fixture/app/views/tag_helper/tag_with_content.html.erb +1 -0
- data/spec/fixture/app/views/tag_helper/tag_with_content_in_the_block.html.erb +3 -0
- data/spec/fixture/app/views/text_area_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/text_area_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/text_area_specs/label.html.erb +1 -0
- data/spec/fixture/app/views/text_area_specs/nil.html.erb +1 -0
- data/spec/fixture/app/views/text_field_specs/basic.html.erb +1 -0
- data/spec/fixture/app/views/text_field_specs/class.html.erb +1 -0
- data/spec/fixture/app/views/text_field_specs/disabled.html.erb +1 -0
- data/spec/fixture/app/views/text_field_specs/label.html.erb +1 -0
- data/spec/fixture/config/environments/development.rb +6 -0
- data/spec/fixture/config/environments/production.rb +5 -0
- data/spec/fixture/config/environments/test.rb +6 -0
- data/spec/fixture/config/init.rb +46 -0
- data/spec/fixture/config/rack.rb +11 -0
- data/spec/fixture/config/router.rb +36 -0
- data/spec/fixture/log/merb.main.pid +1 -0
- data/spec/fixture/log/merb_test.log +624 -0
- data/spec/fixture/public/images/merb.jpg +0 -0
- data/spec/fixture/public/merb.fcgi +4 -0
- data/spec/fixture/public/stylesheets/master.css +119 -0
- data/spec/merb_helpers_config_spec.rb +82 -0
- data/spec/merb_helpers_date_time_spec.rb +257 -0
- data/spec/merb_helpers_form_spec.rb +1266 -0
- data/spec/merb_helpers_tag_helper_spec.rb +46 -0
- data/spec/merb_helpers_text_spec.rb +67 -0
- data/spec/numeric_extlib_spec.rb +135 -0
- data/spec/ordinalize_spec.rb +51 -0
- data/spec/spec_helper.rb +149 -0
- data/spec/time_dsl_spec.rb +43 -0
- metadata +303 -0
|
@@ -0,0 +1,1266 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
# Quick rundown of how these specs work
|
|
4
|
+
# please read before hacking on this plugin
|
|
5
|
+
#
|
|
6
|
+
# helpers must be tested through then entire stack
|
|
7
|
+
# what that means is that each spec must
|
|
8
|
+
# send a request to a controller and render a template
|
|
9
|
+
#
|
|
10
|
+
# Start by creating a spec controller subclassing SpecController
|
|
11
|
+
# which itself is a subclass of Merb::Controller
|
|
12
|
+
# specs_controller.rb (available at spec/fixture/app/controllers/specs_controller.rb)
|
|
13
|
+
# defines SpecController.
|
|
14
|
+
# Create a new controller in the spec/fixture/app/controllers/ if you are adding a new helper
|
|
15
|
+
#
|
|
16
|
+
# To test your helper, start by initializing a controller
|
|
17
|
+
#
|
|
18
|
+
# @controller = CustomHelperSpecs.new(Merb::Request.new({}))
|
|
19
|
+
#
|
|
20
|
+
# Note that we are sending a real request to the controller, feel free to use the request as needed
|
|
21
|
+
#
|
|
22
|
+
# You might need to access real objects in your views
|
|
23
|
+
# you can do that by setting them up in the controller
|
|
24
|
+
#
|
|
25
|
+
# @obj = FakeModel.new # FaKeModel is defined in spec/fixture/models/first_generic_fake_model.rb check it out!
|
|
26
|
+
# @controller.instance_variable_set(:@obj, @obj)
|
|
27
|
+
#
|
|
28
|
+
# To test a helper, you need to render a view:
|
|
29
|
+
#
|
|
30
|
+
# result = @controller.render :view_name
|
|
31
|
+
#
|
|
32
|
+
# Of course, you need to create a view:
|
|
33
|
+
# spec/fixture/app/views/custom_helper_specs/view_name.html.erb
|
|
34
|
+
# in the view, call the helper you want to test
|
|
35
|
+
#
|
|
36
|
+
# You can now test the helper in the view:
|
|
37
|
+
# result.should match_tag(:form, :method => "post")
|
|
38
|
+
#
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
Merb::Plugins.config[:helpers] = {
|
|
42
|
+
:default_builder => Merb::Helpers::Form::Builder::FormWithErrors
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Merb::Router.append do
|
|
46
|
+
resources :obj
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
describe "error_messages_for" do
|
|
51
|
+
|
|
52
|
+
before :each do
|
|
53
|
+
@c = Application.new({})
|
|
54
|
+
@dm_obj = Object.new
|
|
55
|
+
@sq_obj = Object.new
|
|
56
|
+
@dm_errors = [["foo", "bar"],["baz","bat"]]
|
|
57
|
+
@sq_errors = Object.new
|
|
58
|
+
@sq_errors.stub!(:full_messages).and_return(["foo", "baz"])
|
|
59
|
+
@dm_obj.stub!(:errors).and_return(@dm_errors)
|
|
60
|
+
@dm_obj.stub!(:new_record?).and_return(false)
|
|
61
|
+
@sq_obj.stub!(:errors).and_return(@sq_errors)
|
|
62
|
+
@sq_obj.stub!(:new_record?).and_return(false)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should build default error messages for AR-like models" do
|
|
66
|
+
errs = @c.error_messages_for(@dm_obj)
|
|
67
|
+
errs.should include("<h2>Form submission failed because of 2 problems</h2>")
|
|
68
|
+
errs.should include("<li>foo bar</li>")
|
|
69
|
+
errs.should include("<li>baz bat</li>")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should build default error messages for Sequel-like models" do
|
|
73
|
+
errs = @c.error_messages_for(@sq_obj)
|
|
74
|
+
errs.should include("<h2>Form submission failed because of 2 problems</h2>")
|
|
75
|
+
errs.should include("<li>foo</li>")
|
|
76
|
+
errs.should include("<li>baz</li>")
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# it "should build default error messages for symbol" do
|
|
80
|
+
# errs = error_messages_for(:obj)
|
|
81
|
+
# errs.should include("<h2>Form submittal failed because of 2 problems</h2>")
|
|
82
|
+
# errs.should include("<li>foo bar</li>")
|
|
83
|
+
# errs.should include("<li>baz bat</li>")
|
|
84
|
+
# end
|
|
85
|
+
|
|
86
|
+
it "should accept a custom HTML class" do
|
|
87
|
+
errs = @c.error_messages_for(@dm_obj, :error_class => "foo")
|
|
88
|
+
errs.should include("<div class='foo'>")
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should accept a custom header block" do
|
|
92
|
+
errs = @c.error_messages_for(@dm_obj, :header => "<h3>Failure: %s issue%s</h3>")
|
|
93
|
+
errs.should include("<h3>Failure: 2 issues</h3>")
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# it "should put the error messages inside a form if :before is false" do
|
|
97
|
+
# ret = @c.form_for @dm_obj do
|
|
98
|
+
# _buffer << error_messages
|
|
99
|
+
# end
|
|
100
|
+
# ret.should =~ /\A\s*<form.*<div class='error'>/
|
|
101
|
+
# end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe "form" do
|
|
106
|
+
|
|
107
|
+
before :each do
|
|
108
|
+
@c = FormSpecs.new(Merb::Request.new({}))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
describe "when _default_builder is Merb::Helpers::Form::Builder::ResourcefulFormWithErrors" do
|
|
112
|
+
|
|
113
|
+
before(:each) do
|
|
114
|
+
@obj = FakeModel2.new
|
|
115
|
+
@c.instance_variable_set(:@obj, @obj)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should not explode when #form is called" do
|
|
119
|
+
r = @c.render :resourceful_form
|
|
120
|
+
pending
|
|
121
|
+
#r.should =~ /action="fake_model2\/#{@obj.id}"/
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
it "should use the post method by default" do
|
|
127
|
+
ret = @c.render(:post_by_default)
|
|
128
|
+
ret.should match_tag(:form, :method => "post")
|
|
129
|
+
ret.should include("CONTENT")
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "should use the get method if set" do
|
|
133
|
+
ret = @c.render(:get_if_set)
|
|
134
|
+
ret.should match_tag(:form, :method => "get")
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should fake out the put method if set" do
|
|
138
|
+
ret = @c.render(:fake_put_if_set)
|
|
139
|
+
ret.should match_tag(:form, :method => "post")
|
|
140
|
+
ret.should match_tag(:input, :type => "hidden", :name => "_method", :value => "put")
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should fake out the delete method if set" do
|
|
144
|
+
ret = @c.render(:fake_delete_if_set)
|
|
145
|
+
ret.should match_tag(:form, :method => "post")
|
|
146
|
+
ret.should match_tag(:input, :type => "hidden", :name => "_method", :value => "delete")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# TODO: Why is this required?
|
|
150
|
+
# ---------------------------
|
|
151
|
+
#
|
|
152
|
+
# it "should silently set method to post if an unsupported method is used" do
|
|
153
|
+
# form_tag :method => :dodgy do
|
|
154
|
+
# _buffer << "CONTENT"
|
|
155
|
+
# end
|
|
156
|
+
# _buffer.should match_tag(:form, :method => "post")
|
|
157
|
+
# _buffer.should_not match_tag(:input, :type => "hidden", :name => "_method", :value => "dodgy")
|
|
158
|
+
# end
|
|
159
|
+
|
|
160
|
+
it "should take create a form" do
|
|
161
|
+
ret = @c.render(:create_a_form)
|
|
162
|
+
ret.should match_tag(:form, :action => "foo", :method => "post")
|
|
163
|
+
ret.should include("Hello")
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "should set a form to be multipart" do
|
|
167
|
+
ret = @c.render(:create_a_multipart_form)
|
|
168
|
+
ret.should match_tag( :form, :action => "foo", :method => "post", :enctype => "multipart/form-data")
|
|
169
|
+
ret.should include("CONTENT")
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
describe "form_for" do
|
|
175
|
+
|
|
176
|
+
before :each do
|
|
177
|
+
@c = FormForSpecs.new(Merb::Request.new({}))
|
|
178
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it "should wrap the contents in a form tag" do
|
|
182
|
+
form = @c.render :basic
|
|
183
|
+
form.should match_tag(:form, :method => "post")
|
|
184
|
+
form.should match_tag(:input, :type => "hidden", :value => "put", :name => "_method")
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should set the method to post be default" do
|
|
188
|
+
new_fake_model = FakeModel2.new
|
|
189
|
+
@c.instance_variable_set(:@obj, new_fake_model)
|
|
190
|
+
form = @c.render :basic
|
|
191
|
+
form.should match_tag(:form, :method => "post")
|
|
192
|
+
form.should_not match_tag(:input, :type => "hidden", :name => "_method")
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should support PUT if the object passed in is not a new_record? via a hidden field" do
|
|
196
|
+
form = @c.render :basic
|
|
197
|
+
form.should match_tag(:form, :method => "post")
|
|
198
|
+
form.should match_tag(:input, :type => "hidden", :value => "put", :name => "_method")
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
describe "fields_for" do
|
|
205
|
+
|
|
206
|
+
before :each do
|
|
207
|
+
@c = FieldsForSpecs.new(Merb::Request.new({}))
|
|
208
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
it "should dump the contents in the context of the object" do
|
|
213
|
+
r = @c.render :basic
|
|
214
|
+
r.should match_tag(:input, :type => "text", :value => "foowee")
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "should be able to modify the context midstream" do
|
|
218
|
+
@c.instance_variable_set(:@obj2, FakeModel2.new)
|
|
219
|
+
r = @c.render :midstream
|
|
220
|
+
r.should match_tag(:input, :type => "text", :value => "foowee")
|
|
221
|
+
r.should match_tag(:input, :name => "fake_model2[foo]", :type => "text", :value => "foowee2")
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
it "should handle an explicit nil attribute" do
|
|
225
|
+
r = @c.render :nil
|
|
226
|
+
r.should match_tag(:input, :name => "fake_model[foo]", :value => "foowee", :type => "text")
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
it "should pass context back to the old object after exiting block" do
|
|
230
|
+
@c.instance_variable_set(:@obj2, FakeModel2.new)
|
|
231
|
+
r = @c.render :midstream
|
|
232
|
+
r.should match_tag(:input, :id => "fake_model_foo", :name => "fake_model[foo]", :type => "text", :extra => "true")
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
describe "text_field" do
|
|
237
|
+
|
|
238
|
+
before :each do
|
|
239
|
+
@c = TextFieldSpecs.new(Merb::Request.new({}))
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it "should return a basic text field based on the values passed in" do
|
|
243
|
+
r = @c.render :basic
|
|
244
|
+
r.should match_tag( :input, :type => "text", :name => "foo", :value => "bar")
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
248
|
+
r = @c.render :basic
|
|
249
|
+
r.should match(/<label>LABEL<\/label>/)
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
it "should update an existing :class with a new class" do
|
|
253
|
+
r = @c.render :class
|
|
254
|
+
r.should == "<input type=\"text\" class=\"awesome foobar text\"/>"
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
258
|
+
r = @c.render :disabled
|
|
259
|
+
r.should match_tag(:input, :type => "text", :disabled => "disabled")
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it "should provide an additional label tag if the :label option is passed in as a hash" do
|
|
263
|
+
r = @c.render :label
|
|
264
|
+
r.should match(/<label class="cool">LABEL<\/label>/)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
describe "bound_text_field" do
|
|
270
|
+
|
|
271
|
+
before :each do
|
|
272
|
+
@c = BoundTextFieldSpecs.new(Merb::Request.new({}))
|
|
273
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "should take a string object and return a useful text control" do
|
|
277
|
+
r = @c.render :basic
|
|
278
|
+
r.should match_tag(:input, :type => "text", :name => "fake_model[foo]", :value => "foowee")
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it "should take additional attributes and use them" do
|
|
282
|
+
r = @c.render :basic
|
|
283
|
+
r.should match_tag(:input, :type => "text", :name => "fake_model[foo]", :value => "foowee", :bar => "7")
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
287
|
+
form = @c.render :basic
|
|
288
|
+
form.should match(/<label.*>LABEL<\/label><input/)
|
|
289
|
+
res = form.scan(/<[^>]*>/)
|
|
290
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "should not errorify the field for a new object" do
|
|
294
|
+
r = @c.render :basic
|
|
295
|
+
r.should_not match_tag(:input, :type => "text", :name => "fake_model[foo]", :class => "error")
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
it "should errorify a field for a model with errors" do
|
|
299
|
+
model = mock("model")
|
|
300
|
+
model.stub!(:new_record?).and_return(true)
|
|
301
|
+
model.stub!(:class).and_return("MyClass")
|
|
302
|
+
model.stub!(:foo).and_return("FOO")
|
|
303
|
+
errors = mock("errors")
|
|
304
|
+
errors.should_receive(:on).with(:foo).and_return(true)
|
|
305
|
+
|
|
306
|
+
model.stub!(:errors).and_return(errors)
|
|
307
|
+
@c.instance_variable_set(:@obj, model)
|
|
308
|
+
r = @c.render :basic
|
|
309
|
+
r.should match_tag(:input, :class => "error text")
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
describe "bound_radio_button" do
|
|
314
|
+
|
|
315
|
+
before :each do
|
|
316
|
+
@c = BoundRadioButtonSpecs.new(Merb::Request.new({}))
|
|
317
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
it "should take a string object and return a useful text control" do
|
|
321
|
+
r = @c.render :basic
|
|
322
|
+
r.should match_tag(:input, :type => "radio", :name => "fake_model[foo]", :value => "foowee")
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
it "should take additional attributes and use them" do
|
|
326
|
+
r = @c.render :basic
|
|
327
|
+
r.should match_tag(:input, :type => "radio", :name => "fake_model[foo]", :value => "foowee", :bar => "7")
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
331
|
+
form = @c.render :basic
|
|
332
|
+
form.should match(/<input.*><label.*>LABEL<\/label>/)
|
|
333
|
+
res = form.scan(/<[^>]*>/)
|
|
334
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it "should not errorify the field for a new object" do
|
|
338
|
+
r = @c.render :basic
|
|
339
|
+
r.should_not match_tag(:input, :type => "radio", :name => "fake_model[foo]", :class => "error")
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
it "should errorify a field for a model with errors" do
|
|
343
|
+
model = mock("model")
|
|
344
|
+
model.stub!(:new_record?).and_return(true)
|
|
345
|
+
model.stub!(:class).and_return("MyClass")
|
|
346
|
+
model.stub!(:foo).and_return("FOO")
|
|
347
|
+
errors = mock("errors")
|
|
348
|
+
errors.should_receive(:on).with(:foo).and_return(true)
|
|
349
|
+
|
|
350
|
+
model.stub!(:errors).and_return(errors)
|
|
351
|
+
@c.instance_variable_set(:@obj, model)
|
|
352
|
+
r = @c.render :basic
|
|
353
|
+
r.should match_tag(:input, :class => "error radio")
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
describe "password_field" do
|
|
358
|
+
|
|
359
|
+
before :each do
|
|
360
|
+
@c = PasswordFieldSpecs.new(Merb::Request.new({}))
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it "should return a basic password field, but omit the value" do
|
|
364
|
+
r = @c.render :basic
|
|
365
|
+
r.should match_tag(:input, :type => "password", :name => "foo")
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
369
|
+
r = @c.render :basic
|
|
370
|
+
r.should match(/<label.*>LABEL<\/label>/)
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
374
|
+
r = @c.render :disabled
|
|
375
|
+
r.should match_tag(:input, :type => "password", :disabled => "disabled")
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
describe "bound_password_field" do
|
|
380
|
+
|
|
381
|
+
before :each do
|
|
382
|
+
@c = BoundPasswordFieldSpecs.new(Merb::Request.new({}))
|
|
383
|
+
@obj = FakeModel.new
|
|
384
|
+
@c.instance_variable_set(:@obj, @obj)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
it "should take a string object and return a useful password control, but omit the value" do
|
|
388
|
+
r = @c.render :basic
|
|
389
|
+
r.should match_tag(:input, :type => "password", :name => "fake_model[foo]")
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it "should take additional attributes and use them" do
|
|
393
|
+
r = @c.render :basic
|
|
394
|
+
r.should match_tag(:input, :type => "password", :name => "fake_model[foo]", :bar => "7", :value => @obj.foo)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
398
|
+
r = @c.render :basic
|
|
399
|
+
r.should match(/<label.*>LABEL<\/label><input/)
|
|
400
|
+
res = r.scan(/<[^>]*>/)
|
|
401
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
it "should not errorify the field for a new object" do
|
|
405
|
+
r = @c.render :basic
|
|
406
|
+
r.should_not match_tag(:input, :class => "error")
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
it "should errorify a field for a model with errors" do
|
|
410
|
+
model = mock("model")
|
|
411
|
+
model.stub!(:new_record?).and_return(true)
|
|
412
|
+
model.stub!(:class).and_return("MyClass")
|
|
413
|
+
model.stub!(:foo).and_return("FOO")
|
|
414
|
+
errors = mock("errors")
|
|
415
|
+
errors.should_receive(:on).with(:foo).and_return(true)
|
|
416
|
+
|
|
417
|
+
model.stub!(:errors).and_return(errors)
|
|
418
|
+
|
|
419
|
+
@c.instance_variable_set(:@obj, model)
|
|
420
|
+
r = @c.render :basic
|
|
421
|
+
r.should match_tag(:input, :class => "error password")
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
describe "check_box" do
|
|
427
|
+
|
|
428
|
+
before :each do
|
|
429
|
+
@c = CheckBoxSpecs.new(Merb::Request.new({}))
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
it "should return a basic checkbox based on the values passed in" do
|
|
433
|
+
r = @c.render :basic
|
|
434
|
+
r.should match_tag(:input, :class => "checkbox", :name => "foo", :checked => "checked")
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
438
|
+
result = @c.render :label
|
|
439
|
+
result.should match(/<input.*><label>LABEL<\/label>/)
|
|
440
|
+
res = result.scan(/<[^>]*>/)
|
|
441
|
+
res[0].should_not match_tag(:input, :label => "LABEL")
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
it 'should remove the checked="checked" attribute if :checked is false or nil' do
|
|
445
|
+
r = @c.render :unchecked
|
|
446
|
+
r.should_not include('checked="')
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
it 'should have the checked="checked" attribute if :checked => true is passed in' do
|
|
450
|
+
r = @c.render :basic
|
|
451
|
+
r.should include('checked="checked"')
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
it "should not be boolean by default" do
|
|
455
|
+
r = @c.render :basic
|
|
456
|
+
r.should match_tag(:input, :type => "checkbox", :name => "foo")
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
it "should add a hidden input if boolean" do
|
|
460
|
+
r = @c.render :boolean
|
|
461
|
+
r.should have_tag(:input, :type => "checkbox", :value => "1")
|
|
462
|
+
r.should have_tag(:input, :type => "hidden", :value => "0")
|
|
463
|
+
r.should match(/<input.*?type="hidden"[^>]*>[^<]*<input.*?type="checkbox"[^>]*>/)
|
|
464
|
+
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
it "should not allow a :value param if boolean" do
|
|
468
|
+
lambda { @c.render :raises_error_if_not_boolean }.
|
|
469
|
+
should raise_error(ArgumentError, /can't be used with a boolean checkbox/)
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
it "should not allow :boolean => false if :on and :off are specified" do
|
|
473
|
+
lambda { @c.render :raises_error_if_on_off_and_boolean_false }.
|
|
474
|
+
should raise_error(ArgumentError, /cannot be used/)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
it "should be boolean if :on and :off are specified" do
|
|
478
|
+
html = @c.render :on_off_is_boolean
|
|
479
|
+
html.should have_tag(:input, :type => "checkbox", :value => "YES", :name => "foo")
|
|
480
|
+
html.should have_tag(:input, :type => "hidden", :value => "NO", :name => "foo")
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it "should have both :on and :off specified or neither" do
|
|
484
|
+
lambda { @c.render :raise_unless_both_on_and_off }.should raise_error(ArgumentError, /must be specified/)
|
|
485
|
+
lambda { @c.render :raise_unless_both_on_and_off }.should raise_error(ArgumentError, /must be specified/)
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
it "should convert :value to a string on a non-boolean checkbox" do
|
|
489
|
+
r = @c.render :to_string
|
|
490
|
+
r.should match_tag(:input, :value => "")
|
|
491
|
+
r.should match_tag(:input, :value => "false")
|
|
492
|
+
r.should match_tag(:input, :value => "0")
|
|
493
|
+
r.should match_tag(:input, :value => "0")
|
|
494
|
+
r.should match_tag(:input, :value => "1")
|
|
495
|
+
r.should match_tag(:input, :value => "1")
|
|
496
|
+
r.should match_tag(:input, :value => "true")
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
500
|
+
r = @c.render :disabled
|
|
501
|
+
r.should match_tag(:input, :type => "checkbox", :disabled => "disabled")
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
it "should be possible to call with just check_box" do
|
|
505
|
+
r = @c.render :simple
|
|
506
|
+
r.should match_tag(:input, :type => "checkbox", :class => "checkbox")
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
describe "bound_check_box" do
|
|
511
|
+
|
|
512
|
+
before :each do
|
|
513
|
+
@c = BoundCheckBoxSpecs.new(Merb::Request.new({}))
|
|
514
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
it "should take a string and return a useful checkbox control" do
|
|
518
|
+
r = @c.render :basic
|
|
519
|
+
r.should match_tag(:input, :type =>"checkbox", :name => "fake_model[baz]", :class => "checkbox", :value => "1", :checked => "checked", :id => "fake_model_baz")
|
|
520
|
+
r.should match_tag(:input, :type =>"checkbox", :name => "fake_model[bat]", :class => "checkbox", :value => "0")
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
it "should raise an error if you try to use :value" do
|
|
524
|
+
lambda { @c.render(:raise_value_error) }.should raise_error(ArgumentError, /:value can't be used with a bound_check_box/)
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
it "should support models from datamapper" do
|
|
528
|
+
@c.instance_variable_set(:@obj, FakeDMModel.new)
|
|
529
|
+
r = @c.render :basic
|
|
530
|
+
r.should match_tag(:input,
|
|
531
|
+
:type =>"checkbox",
|
|
532
|
+
:name => "fake_dm_model[baz]",
|
|
533
|
+
:class => "checkbox",
|
|
534
|
+
:value => "1",
|
|
535
|
+
:checked => "checked",
|
|
536
|
+
:id => "fake_dm_model_baz")
|
|
537
|
+
r.should match_tag(:input, :type =>"checkbox", :name => "fake_dm_model[bat]", :class => "checkbox", :value => "0")
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
it "should allow a user to set the :off value" do
|
|
541
|
+
r = @c.render :on_and_off
|
|
542
|
+
r.should match_tag(:input, :type =>"checkbox", :name => "fake_model[bat]", :class => "checkbox", :value => "off")
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
it "should render controls with errors if their attribute contains an error" do
|
|
546
|
+
r = @c.render :errors
|
|
547
|
+
r.should match_tag(:input, :type =>"checkbox", :name => "fake_model[bazbad]", :class => "error checkbox", :value => "1", :checked => "checked")
|
|
548
|
+
r.should match_tag(:input, :type =>"checkbox", :name => "fake_model[batbad]", :class => "error checkbox", :value => "0")
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
552
|
+
form = @c.render :label
|
|
553
|
+
form.should match( /<input.*><label.*>LABEL<\/label>/ )
|
|
554
|
+
res = form.scan(/<[^>]*>/)
|
|
555
|
+
res[0].should_not match_tag(:input, :label => "LABEL")
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
it "should not errorify the field for a new object" do
|
|
559
|
+
r = @c.render :basic
|
|
560
|
+
r.should_not match_tag(:input, :type => "checkbox", :class => "error checkbox")
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
it "should errorify a field for a model with errors" do
|
|
564
|
+
model = mock("model")
|
|
565
|
+
model.stub!(:new_record?).and_return(true)
|
|
566
|
+
model.stub!(:class).and_return("MyClass")
|
|
567
|
+
model.stub!(:baz).and_return("BAZ")
|
|
568
|
+
model.stub!(:bat).and_return("BAT")
|
|
569
|
+
errors = mock("errors")
|
|
570
|
+
errors.should_receive(:on).with(:baz).and_return(true)
|
|
571
|
+
errors.should_receive(:on).with(:bat).and_return(true)
|
|
572
|
+
|
|
573
|
+
model.stub!(:errors).and_return(errors)
|
|
574
|
+
|
|
575
|
+
@c.instance_variable_set(:@obj, model)
|
|
576
|
+
r = @c.render :basic
|
|
577
|
+
r.should match_tag(:input, :type => "checkbox", :class => "error checkbox")
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
it "should be boolean" do
|
|
581
|
+
r = @c.render :basic
|
|
582
|
+
r.should have_tag(:input, :type => "checkbox", :value => "1")
|
|
583
|
+
r.should have_tag(:input, :type => "hidden", :value => "0")
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
it "should be checked if the value of the model's attribute is equal to the value of :on" do
|
|
587
|
+
r = @c.render :checked
|
|
588
|
+
r.should match_tag(:input, :type =>"checkbox", :value => "foowee", :checked => "checked")
|
|
589
|
+
r.should match_tag(:input, :type =>"checkbox", :value => "YES", :checked => "checked")
|
|
590
|
+
|
|
591
|
+
end
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
describe "hidden_field" do
|
|
595
|
+
|
|
596
|
+
before :each do
|
|
597
|
+
@c = HiddenFieldSpecs.new(Merb::Request.new({}))
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
it "should return a basic checkbox based on the values passed in" do
|
|
601
|
+
r = @c.render :basic
|
|
602
|
+
r.should match_tag(:input, :type => "hidden", :name => "foo", :value => "bar")
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
it "should not render a label if the :label option is passed in" do
|
|
606
|
+
res = @c.render :label
|
|
607
|
+
res.should_not match(/<label>LABEL/)
|
|
608
|
+
res.should_not match_tag(:input, :label=> "LABEL")
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
612
|
+
r = @c.render :disabled
|
|
613
|
+
r.should match_tag(:input, :type => "hidden", :disabled => "disabled")
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
describe "bound_hidden_field" do
|
|
618
|
+
|
|
619
|
+
before :each do
|
|
620
|
+
@c = BoundHiddenFieldSpecs.new(Merb::Request.new({}))
|
|
621
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
it "should take a string and return a hidden field control" do
|
|
625
|
+
r = @c.render :basic
|
|
626
|
+
r.should match_tag(:input, :type =>"hidden", :name => "fake_model[foo]", :value => "foowee")
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
it "should render controls with errors if their attribute contains an error" do
|
|
630
|
+
r = @c.render :errors
|
|
631
|
+
r.should match_tag(:input, :type =>"hidden", :name => "fake_model[foobad]", :value => "foowee", :class => "error hidden")
|
|
632
|
+
end
|
|
633
|
+
|
|
634
|
+
it "should not render a label if the :label option is passed in" do
|
|
635
|
+
r = @c.render :label
|
|
636
|
+
r.should_not match(/<label>LABEL/)
|
|
637
|
+
r.should_not match_tag(:input, :label=> "LABEL")
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
it "should not errorify the field for a new object" do
|
|
641
|
+
r = @c.render :basic
|
|
642
|
+
r.should_not match_tag(:input, :type => "hidden", :class => "error")
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
it "should not errorify a field for a model with errors" do
|
|
646
|
+
model = mock("model")
|
|
647
|
+
model.stub!(:new_record?).and_return(true)
|
|
648
|
+
model.stub!(:class).and_return("MyClass")
|
|
649
|
+
model.stub!(:foo).and_return("FOO")
|
|
650
|
+
errors = mock("errors")
|
|
651
|
+
errors.should_receive(:on).with(:foo).and_return(true)
|
|
652
|
+
|
|
653
|
+
model.stub!(:errors).and_return(errors)
|
|
654
|
+
|
|
655
|
+
Merb::Router.append do
|
|
656
|
+
resources :models
|
|
657
|
+
end
|
|
658
|
+
|
|
659
|
+
@c.instance_variable_set(:@model, model)
|
|
660
|
+
r = @c.render :hidden_error
|
|
661
|
+
r.should match_tag(:input, :type => "hidden", :name => "my_class[foo]", :class => "error hidden")
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
describe "radio_button" do
|
|
667
|
+
|
|
668
|
+
before :each do
|
|
669
|
+
@c = RadioButtonSpecs.new(Merb::Request.new({}))
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
it "should should return a basic radio button based on the values passed in" do
|
|
673
|
+
r = @c.render :basic
|
|
674
|
+
r.should match_tag(:input, :type => "radio", :name => "foo", :value => "bar", :id => "baz")
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
678
|
+
result = @c.render :label
|
|
679
|
+
# result.should match(/<label.*>LABEL<\/label><input/)
|
|
680
|
+
# res = result.scan(/<[^>]*>/)
|
|
681
|
+
# res[2].should_not match_tag(:input, :label => "LABEL")
|
|
682
|
+
result.should match(/<input.*><label.*>LABEL<\/label>/)
|
|
683
|
+
res = result.scan(/<[^>]*>/)
|
|
684
|
+
res[0].should_not match_tag(:input, :label => "LABEL")
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
688
|
+
r = @c.render :disabled
|
|
689
|
+
r.should match_tag(:input, :type => "radio", :disabled => "disabled")
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
describe "radio_group" do
|
|
694
|
+
|
|
695
|
+
before :each do
|
|
696
|
+
@c = RadioGroupSpecs.new(Merb::Request.new({}))
|
|
697
|
+
end
|
|
698
|
+
|
|
699
|
+
it "should return a group of radio buttons" do
|
|
700
|
+
radio = @c.render :basic
|
|
701
|
+
radio = radio.scan(/<[^>]*>/)
|
|
702
|
+
radio[0].should match_tag(:input, :type => "radio", :value => "foowee")
|
|
703
|
+
radio[3].should match_tag(:input, :type => "radio", :value => "baree")
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
it "should provide an additional label tag for each option in array-based options" do
|
|
707
|
+
radio = @c.render :basic
|
|
708
|
+
radio.scan( /<input.*?><label.*?>(foowee|baree)<\/label>/ ).size.should == 2
|
|
709
|
+
radio = radio.scan(/<[^>]*>/)
|
|
710
|
+
radio[0].should_not match_tag(:input, :label => "LABEL")
|
|
711
|
+
radio[3].should_not match_tag(:input, :label => "LABEL")
|
|
712
|
+
end
|
|
713
|
+
|
|
714
|
+
it "should accept array of hashes as options" do
|
|
715
|
+
radio = @c.render :hash
|
|
716
|
+
radio.scan( /<input.*?><label.*?>(Five|Bar)<\/label>/ ).size.should == 2
|
|
717
|
+
radio = radio.scan(/<[^>]*>/)
|
|
718
|
+
radio.size.should == 6
|
|
719
|
+
radio[0].should match_tag(:input, :value => 5)
|
|
720
|
+
radio[1].should match_tag(:label)
|
|
721
|
+
radio[2].should match_tag('/label')
|
|
722
|
+
radio[3].should match_tag(:input, :value => 'bar', :id => 'bar_id')
|
|
723
|
+
radio[4].should match_tag(:label, :for => 'bar_id')
|
|
724
|
+
radio[5].should match_tag('/label')
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
it "should apply attributes to each element" do
|
|
728
|
+
radio = @c.render :attributes
|
|
729
|
+
radio = radio.scan(/<[^>]*>/)
|
|
730
|
+
radio[0].should match_tag(:input, :type => "radio", :value => "foowee", :class => "CLASS radio")
|
|
731
|
+
radio[3].should match_tag(:input, :type => "radio", :value => "baree", :class => "CLASS radio")
|
|
732
|
+
end
|
|
733
|
+
|
|
734
|
+
it "should override universal attributes with specific ones" do
|
|
735
|
+
radio = @c.render :specific_attributes
|
|
736
|
+
radio = radio.scan(/<[^>]*>/)
|
|
737
|
+
radio[0].should match_tag(:input, :type => "radio", :value => "foowee", :class => "CLASS radio")
|
|
738
|
+
radio[3].should match_tag(:input, :type => "radio", :value => "baree", :class => "BAREE radio")
|
|
739
|
+
end
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
describe "bound_radio_group" do
|
|
744
|
+
|
|
745
|
+
before do
|
|
746
|
+
@c = BoundRadioGroupSpecs.new(Merb::Request.new({}))
|
|
747
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
748
|
+
end
|
|
749
|
+
|
|
750
|
+
it "should return a group of radio buttons" do
|
|
751
|
+
r = @c.render :basic
|
|
752
|
+
radio = r.scan(/<[^>]*>/)
|
|
753
|
+
radio[2].should match_tag(:input, :type => "radio", :name => "fake_model[foo]", :value => "foowee", :checked => "checked")
|
|
754
|
+
radio[5].should match_tag(:input, :type => "radio", :name => "fake_model[foo]", :value => "baree")
|
|
755
|
+
radio[6].should not_match_tag(:checked => "checked")
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
it "should provide an additional label tag for each option in array-based options" do
|
|
759
|
+
r = @c.render :basic
|
|
760
|
+
r.scan( /<input.*?><label.*?>(foowee|baree)<\/label>/ ).size.should == 2
|
|
761
|
+
radio = r.scan(/<[^>]*>/)[2..-2]
|
|
762
|
+
radio[0].should_not match_tag(:input, :label => "LABEL")
|
|
763
|
+
radio[3].should_not match_tag(:input, :label => "LABEL")
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
it "should accept array of hashes as options" do
|
|
767
|
+
r = @c.render :hashes
|
|
768
|
+
r.scan( /<input.*?><label.*?>(Five|Bar)<\/label>/ ).size.should == 2
|
|
769
|
+
radio = r.scan(/<[^>]*>/)[2..-2]
|
|
770
|
+
radio.size.should == 6
|
|
771
|
+
radio[0].should match_tag(:input, :value => 5)
|
|
772
|
+
radio[1].should match_tag(:label)
|
|
773
|
+
radio[2].should match_tag('/label')
|
|
774
|
+
radio[3].should match_tag(:input, :value => 'bar', :id => 'bar_id')
|
|
775
|
+
radio[4].should match_tag(:label, :for => 'bar_id')
|
|
776
|
+
radio[5].should match_tag('/label')
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
it "should provide autogenerated id for inputs" do
|
|
780
|
+
r = @c.render :mixed
|
|
781
|
+
radio = r.scan(/<[^>]*>/)[2..-2]
|
|
782
|
+
pp radio
|
|
783
|
+
radio[0].should match_tag(:input, :id => 'fake_model_foo_bar')
|
|
784
|
+
radio[1].should match_tag(:label, :for => 'fake_model_foo_bar')
|
|
785
|
+
radio[3].should match_tag(:input, :id => 'fake_model_foo_bar')
|
|
786
|
+
radio[4].should match_tag(:label, :for => 'fake_model_foo_bar')
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
it "should override autogenerated id for inputs with hash-given id" do
|
|
790
|
+
r = @c.render :override_id
|
|
791
|
+
radio = r.scan(/<[^>]*>/)[2..-2]
|
|
792
|
+
radio[0].should match_tag(:input, :id => 'bar_id')
|
|
793
|
+
radio[1].should match_tag(:label, :for => 'bar_id')
|
|
794
|
+
end
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
|
|
798
|
+
describe "text_area" do
|
|
799
|
+
|
|
800
|
+
before do
|
|
801
|
+
@c = TextAreaSpecs.new(Merb::Request.new({}))
|
|
802
|
+
end
|
|
803
|
+
|
|
804
|
+
it "should should return a basic text area based on the values passed in" do
|
|
805
|
+
r = @c.render :basic
|
|
806
|
+
r.should match_tag(:textarea, :name => "foo")
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
it "should handle a nil content" do
|
|
810
|
+
r = @c.render :nil
|
|
811
|
+
r.should == "<textarea name=\"foo\"></textarea>"
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
|
|
815
|
+
# TODO: Why is this required?
|
|
816
|
+
# ---------------------------
|
|
817
|
+
#
|
|
818
|
+
# it "should handle a nil attributes hash" do
|
|
819
|
+
# text_area("CONTENT", nil).should == "<textarea>CONTENT</textarea>"
|
|
820
|
+
# end
|
|
821
|
+
|
|
822
|
+
it "should render a label when the label is passed in" do
|
|
823
|
+
result = @c.render :label
|
|
824
|
+
result.should match(/<label.*>LABEL<\/label><textarea/)
|
|
825
|
+
res = result.scan(/<[^>]*>/)
|
|
826
|
+
res[1].should_not match_tag(:textarea, :label => "LABEL")
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
830
|
+
r = @c.render :disabled
|
|
831
|
+
r.should match_tag(:textarea, :disabled => "disabled")
|
|
832
|
+
end
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
describe "bound_text_area" do
|
|
836
|
+
|
|
837
|
+
before do
|
|
838
|
+
@c = BoundTextAreaSpecs.new(Merb::Request.new({}))
|
|
839
|
+
@obj = FakeModel.new
|
|
840
|
+
@c.instance_variable_set(:@obj, @obj)
|
|
841
|
+
end
|
|
842
|
+
|
|
843
|
+
it "should provide :id attribute" do
|
|
844
|
+
r = @c.render :basic
|
|
845
|
+
r.should match_tag(:textarea, :id => 'fake_model_foo', :name => "fake_model[foo]")
|
|
846
|
+
r.should =~ />\s*#{@obj.foo}\s*</
|
|
847
|
+
end
|
|
848
|
+
end
|
|
849
|
+
|
|
850
|
+
describe "select" do
|
|
851
|
+
|
|
852
|
+
before do
|
|
853
|
+
@c = SelectSpecs.new(Merb::Request.new({}))
|
|
854
|
+
end
|
|
855
|
+
|
|
856
|
+
it "should provide a blank option if you :include_blank" do
|
|
857
|
+
r = @c.render :blank
|
|
858
|
+
r.should =~ /<option.*>\s*<\/option>/
|
|
859
|
+
end
|
|
860
|
+
|
|
861
|
+
it "should render the select tag with suffix '[]' to name when :multiple => true" do
|
|
862
|
+
r = @c.render :multiple
|
|
863
|
+
r.should match_tag( :select, :name => "foo[]" )
|
|
864
|
+
end
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
describe "bound_select" do
|
|
868
|
+
|
|
869
|
+
before do
|
|
870
|
+
@c = BoundSelectSpecs.new(Merb::Request.new({}))
|
|
871
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
it "should render the select tag with the correct id and name" do
|
|
875
|
+
r = @c.render :basic
|
|
876
|
+
r.should match_tag( :select, :id => "fake_model_foo", :name => "fake_model[foo]" )
|
|
877
|
+
end
|
|
878
|
+
|
|
879
|
+
it "should render the select tag with suffix '[]' to name when :multiple => true" do
|
|
880
|
+
r = @c.render :multiple
|
|
881
|
+
r.should match_tag( :select, :id => "fake_model_foo", :name => "fake_model[foo][]" )
|
|
882
|
+
end
|
|
883
|
+
|
|
884
|
+
it "should include a blank option" do
|
|
885
|
+
r = @c.render :blank
|
|
886
|
+
r.should match_tag(:option, :value => '')
|
|
887
|
+
r.should =~ /<option.*>\s*<\/option>/
|
|
888
|
+
end
|
|
889
|
+
|
|
890
|
+
it "should render a prompt option without a value" do
|
|
891
|
+
r = @c.render :prompt
|
|
892
|
+
r.should match_tag(:option, :value => '')
|
|
893
|
+
r.should =~ /<option.*>Choose<\/option>/
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
it "should render a select tag with options" do
|
|
897
|
+
r = @c.render :with_options
|
|
898
|
+
r.should match_tag( :select, :class => "class1 class2", :title=> "This is the title" )
|
|
899
|
+
r.should =~ /<select.*>\s*<\/select>/
|
|
900
|
+
end
|
|
901
|
+
|
|
902
|
+
it "should render a select tag with options and a blank option" do
|
|
903
|
+
r = @c.render :with_options_with_blank
|
|
904
|
+
r.should match_tag( :select, :title => "TITLE" )
|
|
905
|
+
r.should match_tag( :option, :value => '' )
|
|
906
|
+
r.should =~ /<option.*>\s*<\/option>/
|
|
907
|
+
end
|
|
908
|
+
|
|
909
|
+
# Not sure how this makes any sense
|
|
910
|
+
# ---------------------------------
|
|
911
|
+
#
|
|
912
|
+
# it "should render the text as the value if no text_method is specified" do
|
|
913
|
+
# form_for @obj do
|
|
914
|
+
# content = select( :foo, :collection => [FakeModel] )
|
|
915
|
+
# content.should match_tag( :option, :value => "FakeModel" )
|
|
916
|
+
# end
|
|
917
|
+
# end
|
|
918
|
+
|
|
919
|
+
end
|
|
920
|
+
|
|
921
|
+
describe "bound option tags" do
|
|
922
|
+
|
|
923
|
+
before do
|
|
924
|
+
@c = BoundOptionTagSpecs.new(Merb::Request.new({}))
|
|
925
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
it "should use text_method and value_method for tag generation" do
|
|
930
|
+
r = @c.render :text_and_value
|
|
931
|
+
r.should match_tag( :option, :content => "foowee", :value => "7" )
|
|
932
|
+
r.should match_tag( :option, :content => "foowee2", :value => "barbar" )
|
|
933
|
+
|
|
934
|
+
# content = options_from_collection_for_select( [FakeModel.new, FakeModel2.new], :text_method => 'foo', :value_method => 'bar' )
|
|
935
|
+
# content.should match_tag( :option, :content => "foowee", :value => "7" )
|
|
936
|
+
# content.should match_tag( :option, :content => "foowee2", :value => "barbar" )
|
|
937
|
+
end
|
|
938
|
+
|
|
939
|
+
it "should render a hash of arrays as a grouped select box" do
|
|
940
|
+
model1 = FakeModel.new ; model1.make = "Ford" ; model1.model = "Mustang" ; model1.vin = '1'
|
|
941
|
+
model2 = FakeModel.new ; model2.make = "Ford" ; model2.model = "Falcon" ; model2.vin = '2'
|
|
942
|
+
model3 = FakeModel.new ; model3.make = "Holden" ; model3.model = "Commodore" ; model3.vin = '3'
|
|
943
|
+
@c.instance_variable_set(:@model1, model1)
|
|
944
|
+
@c.instance_variable_set(:@model2, model2)
|
|
945
|
+
@c.instance_variable_set(:@model3, model3)
|
|
946
|
+
@c.instance_variable_set(:@collection, [model1, model2, model3].inject({}) {|s,e| (s[e.make] ||= []) << e; s })
|
|
947
|
+
r = @c.render :grouped
|
|
948
|
+
# Blank actually defaults to ""
|
|
949
|
+
r.should =~ /<optgroup label=\"Ford\"><option/
|
|
950
|
+
r.should match_tag( :optgroup, :label => "Ford" )
|
|
951
|
+
r.should match_tag( :option, :selected => "selected", :value => "1", :content => "Mustang" )
|
|
952
|
+
r.should match_tag( :option, :value => "2", :content => "Falcon" )
|
|
953
|
+
r.should match_tag( :optgroup, :label => "Holden" )
|
|
954
|
+
r.should match_tag( :option, :value => "3", :content => "Commodore" )
|
|
955
|
+
|
|
956
|
+
# collection = [@model1, @model2, @model3].inject({}) {|s,e| (s[e.make] ||= []) << e; s }
|
|
957
|
+
# content = options_from_collection_for_select(collection, :text_method => 'model', :value_method => 'vin', :selected => '1')
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
it "should render a collection of nested value/content arrays" do
|
|
961
|
+
r = @c.render :nested
|
|
962
|
+
r.should match_tag(:select, :id => "fake_model_foo", :name => "fake_model[foo]")
|
|
963
|
+
r.should match_tag(:option, :value => "small", :content => "Small")
|
|
964
|
+
r.should match_tag(:option, :value => "medium", :content => "Medium")
|
|
965
|
+
r.should match_tag(:option, :value => "large", :content => "Large")
|
|
966
|
+
end
|
|
967
|
+
|
|
968
|
+
# Is this really worth the extra speed hit? I'm thinking not
|
|
969
|
+
# ----------------------------------------------------------
|
|
970
|
+
#
|
|
971
|
+
# it "should humanize and titlize keys in the label for the option group" do
|
|
972
|
+
# collection = { :some_snake_case_key => [FakeModel.new] }
|
|
973
|
+
# form_for @obj do
|
|
974
|
+
# content = select( :foo, :collection => collection )
|
|
975
|
+
# content.should match_tag( :optgroup, :label => "Some Snake Case Key" )
|
|
976
|
+
# end
|
|
977
|
+
# end
|
|
978
|
+
|
|
979
|
+
end
|
|
980
|
+
|
|
981
|
+
require "hpricot"
|
|
982
|
+
|
|
983
|
+
describe "option tags" do
|
|
984
|
+
|
|
985
|
+
before do
|
|
986
|
+
@c = OptionTagSpecs.new(Merb::Request.new({}))
|
|
987
|
+
@c.instance_variable_set(:@collection, [['rabbit','Rabbit'],['horse','Horse'],['bird','Bird']])
|
|
988
|
+
end
|
|
989
|
+
|
|
990
|
+
it "should provide an option tag for each item in the collection" do
|
|
991
|
+
r = @c.render :collection
|
|
992
|
+
doc = Hpricot( r )
|
|
993
|
+
(doc/"option").size.should == 3
|
|
994
|
+
end
|
|
995
|
+
|
|
996
|
+
it "should provide a blank option" do
|
|
997
|
+
r = @c.render :with_blank
|
|
998
|
+
r.should match_tag( :option, :value => '' )
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
it "should render the prompt option at the top" do
|
|
1002
|
+
r = @c.render :with_prompt
|
|
1003
|
+
#ontent = select( :collection => [["foo", "Foo"]], :prompt => 'Choose' )
|
|
1004
|
+
r.should match(/<option[^>]*>Choose<\/option>[^<]*<option[^>]*>Foo<\/option>/)
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
it "should provide selected options by value" do
|
|
1008
|
+
r = @c.render :selected
|
|
1009
|
+
r.should match_tag( :option, :value => 'rabbit', :selected => 'selected', :content => 'Rabbit' )
|
|
1010
|
+
r.should_not match_tag( :option, :value => 'chicken', :selected => nil, :content => 'Chicken' )
|
|
1011
|
+
end
|
|
1012
|
+
|
|
1013
|
+
it "should handle arrays for selected when :multiple is true" do
|
|
1014
|
+
r = @c.render :multiple_selects
|
|
1015
|
+
r.should match_tag( :option, :value => 'minutes', :selected => 'selected', :content => 'Time' )
|
|
1016
|
+
r.should match_tag( :option, :value => 'dollars', :selected => 'selected', :content => 'Money' )
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
it "should render a hash of options as optgroup" do
|
|
1020
|
+
r = @c.render :optgroups
|
|
1021
|
+
r.should match_tag( :optgroup, :label => 'Fruit' )
|
|
1022
|
+
r.should match_tag( :optgroup, :label => 'Vegetables' )
|
|
1023
|
+
r.should match_tag( :option, :value => 'banana', :selected => 'selected', :content => 'Banana' )
|
|
1024
|
+
end
|
|
1025
|
+
|
|
1026
|
+
it "should accept an array of strings in :collection as the content/value of each option" do
|
|
1027
|
+
r = @c.render :array
|
|
1028
|
+
r.should match_tag(:option, :content => "one", :value => "one")
|
|
1029
|
+
r.should match_tag(:option, :content => "two", :value => "two")
|
|
1030
|
+
end
|
|
1031
|
+
|
|
1032
|
+
it "should only pass :selected and :value attrs to <option> tags" do
|
|
1033
|
+
r = @c.render :no_extra_attributes
|
|
1034
|
+
r = r.slice(/<option[^>]*>[^<]*<\/option>/)
|
|
1035
|
+
r.should match_tag(:option, :value => "rabbit", :content => "Rabbit")
|
|
1036
|
+
r.should_not match_tag(:option, :id => "my_id", :name => "my_name", :class => "classy")
|
|
1037
|
+
end
|
|
1038
|
+
|
|
1039
|
+
it "should not pollute the <select> attributes with <option> attributes" do
|
|
1040
|
+
r = @c.render :clean
|
|
1041
|
+
r = r.slice(/<select[^>]*>/)
|
|
1042
|
+
r.should_not match_tag(:select, :value => "banana", :selected => "selected")
|
|
1043
|
+
end
|
|
1044
|
+
end
|
|
1045
|
+
|
|
1046
|
+
describe "fieldset" do
|
|
1047
|
+
|
|
1048
|
+
before :each do
|
|
1049
|
+
@c = FieldsetSpecs.new(Merb::Request.new({}))
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
it "should provide legend option" do
|
|
1053
|
+
r = @c.render :legend
|
|
1054
|
+
# res = fieldset :legend => 'TEST' do
|
|
1055
|
+
# _buffer << "CONTENT"
|
|
1056
|
+
# end
|
|
1057
|
+
r.should include("CONTENT")
|
|
1058
|
+
r.should match_tag(:fieldset, {})
|
|
1059
|
+
r.should match_tag(:legend, :content => 'TEST')
|
|
1060
|
+
end
|
|
1061
|
+
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1064
|
+
describe "label" do
|
|
1065
|
+
|
|
1066
|
+
before :each do
|
|
1067
|
+
@c = LabelSpecs.new(Merb::Request.new({}))
|
|
1068
|
+
end
|
|
1069
|
+
|
|
1070
|
+
it "should render a label tag" do
|
|
1071
|
+
r = @c.render :basic
|
|
1072
|
+
#r = label("First Name", :id => "user_first_name")
|
|
1073
|
+
r.should match_tag(:label, :for => "user_first_name", :content => "First Name")
|
|
1074
|
+
end
|
|
1075
|
+
end
|
|
1076
|
+
|
|
1077
|
+
describe "file_field" do
|
|
1078
|
+
|
|
1079
|
+
before :each do
|
|
1080
|
+
@c = FileFieldSpecs.new(Merb::Request.new({}))
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
it "should return a basic file field based on the values passed in" do
|
|
1084
|
+
r = @c.render :with_values
|
|
1085
|
+
#file_field(:name => "foo", :value => "bar")
|
|
1086
|
+
r.should match_tag( :input, :type => "file", :name => "foo", :value => "bar")
|
|
1087
|
+
end
|
|
1088
|
+
|
|
1089
|
+
it "should wrap the field in a label if the :label option is passed to the file" do
|
|
1090
|
+
r = @c.render :with_label
|
|
1091
|
+
r.should match(/<label>LABEL<\/label><input type="file" class="file"\s*\/>/)
|
|
1092
|
+
end
|
|
1093
|
+
|
|
1094
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
1095
|
+
r = @c.render :disabled
|
|
1096
|
+
r.should match_tag(:input, :type => "file", :disabled => "disabled")
|
|
1097
|
+
end
|
|
1098
|
+
|
|
1099
|
+
it "should make the surrounding form multipart" do
|
|
1100
|
+
r = @c.render :makes_multipart
|
|
1101
|
+
r.should match_tag(:form, :enctype => "multipart/form-data")
|
|
1102
|
+
end
|
|
1103
|
+
end
|
|
1104
|
+
|
|
1105
|
+
describe "bound_file_field" do
|
|
1106
|
+
|
|
1107
|
+
before :each do
|
|
1108
|
+
@c = BoundFileFieldSpecs.new(Merb::Request.new({}))
|
|
1109
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
it "should take a string object and return a useful file control" do
|
|
1113
|
+
r = @c.render :takes_string
|
|
1114
|
+
r.should match_tag(:input, :type => "file", :name => "fake_model[foo]", :value => "foowee")
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1117
|
+
it "should take additional attributes and use them" do
|
|
1118
|
+
r = @c.render :additional_attributes
|
|
1119
|
+
r.should match_tag(:input, :type => "file", :name => "fake_model[foo]", :value => "foowee", :bar => "7")
|
|
1120
|
+
end
|
|
1121
|
+
|
|
1122
|
+
it "should wrap the file_field in a label if the :label option is passed in" do
|
|
1123
|
+
r = @c.render :with_label
|
|
1124
|
+
# form = form_for @obj do
|
|
1125
|
+
# _buffer << text_field(:foo, :label => "LABEL")
|
|
1126
|
+
# end
|
|
1127
|
+
r.should match(/<label.*>LABEL<\/label><input/)
|
|
1128
|
+
res = r.scan(/<[^>]*>/)
|
|
1129
|
+
res[2].should_not match_tag(:input, :label => "LABEL")
|
|
1130
|
+
end
|
|
1131
|
+
end
|
|
1132
|
+
|
|
1133
|
+
describe "submit" do
|
|
1134
|
+
|
|
1135
|
+
before :each do
|
|
1136
|
+
@c = SubmitSpecs.new(Merb::Request.new({}))
|
|
1137
|
+
end
|
|
1138
|
+
|
|
1139
|
+
it "should return a basic submit input based on the values passed in" do
|
|
1140
|
+
r = @c.render :submit_with_values
|
|
1141
|
+
r.should match_tag(:input, :type => "submit", :name => "foo", :value => "Done")
|
|
1142
|
+
end
|
|
1143
|
+
|
|
1144
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
1145
|
+
r = @c.render :submit_with_label
|
|
1146
|
+
r.should match(/<input.*type="submit"/)
|
|
1147
|
+
r.should match(/<input.*name="submit"/)
|
|
1148
|
+
r.should match(/<input.*value="Done"/)
|
|
1149
|
+
r.should match(/<label.*>LABEL<\/label>/)
|
|
1150
|
+
end
|
|
1151
|
+
|
|
1152
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
1153
|
+
r = @c.render :disabled_submit
|
|
1154
|
+
r.should match_tag(:input, :type => "submit", :value => "Done", :disabled => "disabled")
|
|
1155
|
+
end
|
|
1156
|
+
end
|
|
1157
|
+
|
|
1158
|
+
describe "button" do
|
|
1159
|
+
|
|
1160
|
+
before :each do
|
|
1161
|
+
@c = ButtonSpecs.new(Merb::Request.new({}))
|
|
1162
|
+
end
|
|
1163
|
+
|
|
1164
|
+
it "should return a button based on the values passed in" do
|
|
1165
|
+
r = @c.render :button_with_values
|
|
1166
|
+
r.should match_tag(:button, :type => "button", :name => "foo", :value => "bar", :content => "Click Me")
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
it "should provide an additional label tag if the :label option is passed in" do
|
|
1170
|
+
r = @c.render :button_with_label
|
|
1171
|
+
r.should match(/<button.*value="foo"/)
|
|
1172
|
+
r.should match(/<label.*>LABEL<\/label>/)
|
|
1173
|
+
end
|
|
1174
|
+
|
|
1175
|
+
it "should be disabled if :disabled => true is passed in" do
|
|
1176
|
+
r = @c.render :disabled_button
|
|
1177
|
+
r.should match_tag(:button, :disabled => "true")
|
|
1178
|
+
end
|
|
1179
|
+
end
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
class MyBuilder < Merb::Helpers::Form::Builder::Base
|
|
1183
|
+
|
|
1184
|
+
def update_bound_controls(method, attrs, type)
|
|
1185
|
+
super
|
|
1186
|
+
attrs[:bound] = type
|
|
1187
|
+
end
|
|
1188
|
+
|
|
1189
|
+
def update_unbound_controls(attrs, type)
|
|
1190
|
+
super
|
|
1191
|
+
attrs[:unbound] = type
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1194
|
+
end
|
|
1195
|
+
|
|
1196
|
+
describe "custom builder" do
|
|
1197
|
+
|
|
1198
|
+
before :each do
|
|
1199
|
+
@c = CustomBuilderSpecs.new(Merb::Request.new({}))
|
|
1200
|
+
@c.instance_variable_set(:@obj, FakeModel.new)
|
|
1201
|
+
end
|
|
1202
|
+
|
|
1203
|
+
it "should let you override update_bound_controls" do
|
|
1204
|
+
r = @c.render :everything
|
|
1205
|
+
r.should =~ / bound="file"/
|
|
1206
|
+
r.should =~ / bound="text"/
|
|
1207
|
+
r.should =~ / bound="hidden"/
|
|
1208
|
+
r.should =~ / bound="password"/
|
|
1209
|
+
r.should =~ / bound="radio"/
|
|
1210
|
+
r.should =~ / bound="text_area"/
|
|
1211
|
+
end
|
|
1212
|
+
|
|
1213
|
+
it "should let you override update_unbound_controls" do
|
|
1214
|
+
r = @c.render :everything
|
|
1215
|
+
r.should match_tag(:button, :unbound => "button")
|
|
1216
|
+
r.should match_tag(:input, :unbound => "submit")
|
|
1217
|
+
r.should match_tag(:textarea, :unbound => "text_area")
|
|
1218
|
+
end
|
|
1219
|
+
end
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
describe 'delete_button' do
|
|
1223
|
+
|
|
1224
|
+
before :each do
|
|
1225
|
+
@controller = DeleteButtonSpecs.new(Merb::Request.new({}))
|
|
1226
|
+
@controller.instance_variable_set(:@obj, FakeModel.new)
|
|
1227
|
+
end
|
|
1228
|
+
|
|
1229
|
+
it "should have a default submit button text" do
|
|
1230
|
+
result = @controller.render :simple_delete # <%= delete_button @obj %>
|
|
1231
|
+
result.should match(/<input type=\"submit\">Delete<\/input>/)
|
|
1232
|
+
end
|
|
1233
|
+
|
|
1234
|
+
it 'should return a button inside of a form for the object' do
|
|
1235
|
+
result = @controller.render :simple_delete # <%= delete_button @obj %>
|
|
1236
|
+
result.should match_tag(:form, :action => "/fake_models/fake_model", :method => "post")
|
|
1237
|
+
result.should match_tag(:input, :type => "hidden", :value => "DELETE", :name => "_method")
|
|
1238
|
+
end
|
|
1239
|
+
|
|
1240
|
+
it 'should allow you to modify the label' do
|
|
1241
|
+
result = @controller.render :delete_with_label # <%= delete_button(@obj, "Delete moi!") %>
|
|
1242
|
+
result.should match(/<input type=\"submit\">Delete moi!<\/input>/)
|
|
1243
|
+
end
|
|
1244
|
+
|
|
1245
|
+
it "should allow you to pass some extra params like a class" do
|
|
1246
|
+
result = @controller.render :delete_with_extra_params
|
|
1247
|
+
result.should match(/<input type=\"submit\" class=\"custom-class\">Delete<\/input>/)
|
|
1248
|
+
end
|
|
1249
|
+
|
|
1250
|
+
it "should allow to pass an explicit url as a string" do
|
|
1251
|
+
result = @controller.render :delete_with_explicit_url # <%= delete_button('/test/custom_url') %>
|
|
1252
|
+
result.should match_tag(:form, :action => "/test/custom_url", :method => "post")
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
end
|
|
1256
|
+
|
|
1257
|
+
# describe "control_value" do
|
|
1258
|
+
#
|
|
1259
|
+
#
|
|
1260
|
+
# it 'should escape [&"<>]' do
|
|
1261
|
+
# @obj.vin = '&"<>'
|
|
1262
|
+
# f = form_for :obj do
|
|
1263
|
+
# control_value(:vin).should == '&"<>'
|
|
1264
|
+
# end
|
|
1265
|
+
# end
|
|
1266
|
+
# end
|