aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorRyan Bigg <radarlistener@gmail.com>2008-10-18 17:43:38 +1030
committerRyan Bigg <radarlistener@gmail.com>2008-10-18 17:43:38 +1030
commit2139a1b6812be7ca86de2df52e9776a2be4a2bf7 (patch)
tree3131e29d3582b8aa1ba1c68710f327ce2f22aa1d /actionpack
parent09b7e351316cb87a815678241fc90af549327cf3 (diff)
parent095cafbcd7fbae3baa845b23b93c8dca93b442f8 (diff)
downloadrails-2139a1b6812be7ca86de2df52e9776a2be4a2bf7.tar.gz
rails-2139a1b6812be7ca86de2df52e9776a2be4a2bf7.tar.bz2
rails-2139a1b6812be7ca86de2df52e9776a2be4a2bf7.zip
Merge branch 'master' of git@github.com:lifo/docrails
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG10
-rw-r--r--actionpack/lib/action_controller/base.rb4
-rw-r--r--actionpack/lib/action_controller/routing/builder.rb4
-rw-r--r--actionpack/lib/action_controller/test_case.rb3
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/atom_feed_helper.rb64
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb18
-rw-r--r--actionpack/test/controller/render_test.rb6
-rw-r--r--actionpack/test/controller/routing_test.rb21
-rw-r--r--actionpack/test/controller/test_test.rb1
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb13
-rw-r--r--actionpack/test/template/atom_feed_helper_test.rb81
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb3
-rw-r--r--actionpack/test/template/prototype_helper_test.rb6
15 files changed, 211 insertions, 32 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 54ea93fb72..c68bfc753c 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,15 @@
*Edge*
+* Added inline builder yield to atom_feed_helper tags where appropriate [Sam Ruby]. Example:
+
+ entry.summary :type => 'xhtml' do |xhtml|
+ xhtml.p pluralize(order.line_items.count, "line item")
+ xhtml.p "Shipped to #{order.address}"
+ xhtml.p "Paid by #{order.pay_type}"
+ end
+
+* Make PrototypeHelper#submit_to_remote a wrapper around PrototypeHelper#button_to_remote. [Tarmo Tänav]
+
* Set HttpOnly for the cookie session store's cookie. #1046
* Added FormTagHelper#image_submit_tag confirm option #784 [Alastair Brunton]
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 413f6d48e5..3ede681253 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -969,7 +969,9 @@ module ActionController #:nodoc:
# If-Modified-Since request header is <= last modified.
def last_modified!(utc_time)
response.last_modified= utc_time
- head(:not_modified) if response.last_modified == request.if_modified_since
+ if request.if_modified_since && request.if_modified_since <= utc_time
+ head(:not_modified)
+ end
end
# Sets the ETag response header. Returns 304 Not Modified if the
diff --git a/actionpack/lib/action_controller/routing/builder.rb b/actionpack/lib/action_controller/routing/builder.rb
index 5704d9d01a..7b888fa8d2 100644
--- a/actionpack/lib/action_controller/routing/builder.rb
+++ b/actionpack/lib/action_controller/routing/builder.rb
@@ -60,12 +60,10 @@ module ActionController
# segments are passed alongside in order to distinguish between default values
# and requirements.
def divide_route_options(segments, options)
- options = options.dup
+ options = options.except(:path_prefix, :name_prefix)
if options[:namespace]
options[:controller] = "#{options.delete(:namespace).sub(/\/$/, '')}/#{options[:controller]}"
- options.delete(:path_prefix)
- options.delete(:name_prefix)
end
requirements = (options.delete(:requirements) || {}).dup
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 6a39039504..4fc60f0697 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -134,6 +134,9 @@ module ActionController
@controller = self.class.controller_class.new
@controller.request = @request = TestRequest.new
@response = TestResponse.new
+
+ @controller.params = {}
+ @controller.send(:initialize_current_url)
end
# Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 63ccde393a..93d38eb929 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -596,7 +596,7 @@ module ActionView
end
def missing_extension?(source)
- extension && File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, directory, "#{source}.#{extension}"))
+ extension && (File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, directory, "#{source}.#{extension}")))
end
def prepend_relative_url_root(source)
diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb
index e65d5d1f60..ccb7df212a 100644
--- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb
+++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb
@@ -51,6 +51,7 @@ module ActionView
# * <tt>:schema_date</tt>: The date at which the tag scheme for the feed was first used. A good default is the year you
# created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
# 2005 is used (as an "I don't care" value).
+ # * <tt>:instruct</tt>: Hash of XML processing instructions in the form {target => {attribute => value, }} or {target => [{attribute => value, }, ]}
#
# Other namespaces can be added to the root element:
#
@@ -74,8 +75,20 @@ module ActionView
# end
# end
#
+ # The Atom spec defines five elements (content rights title subtitle
+ # summary) which may directly contain xhtml content if :type => 'xhtml'
+ # is specified as an attribute. If so, this helper will take care of
+ # the enclosing div and xhtml namespace declaration. Example usage:
#
- # atom_feed yields an AtomFeedBuilder instance.
+ # entry.summary :type => 'xhtml' do |xhtml|
+ # xhtml.p pluralize(order.line_items.count, "line item")
+ # xhtml.p "Shipped to #{order.address}"
+ # xhtml.p "Paid by #{order.pay_type}"
+ # end
+ #
+ #
+ # atom_feed yields an AtomFeedBuilder instance. Nested elements yield
+ # an AtomBuilder instance.
def atom_feed(options = {}, &block)
if options[:schema_date]
options[:schema_date] = options[:schema_date].strftime("%Y-%m-%d") if options[:schema_date].respond_to?(:strftime)
@@ -85,6 +98,15 @@ module ActionView
xml = options[:xml] || eval("xml", block.binding)
xml.instruct!
+ if options[:instruct]
+ options[:instruct].each do |target,attrs|
+ if attrs.respond_to?(:keys)
+ xml.instruct!(target, attrs)
+ elsif attrs.respond_to?(:each)
+ attrs.each { |attr_group| xml.instruct!(target, attr_group) }
+ end
+ end
+ end
feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'}
feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)}
@@ -98,8 +120,38 @@ module ActionView
end
end
+ class AtomBuilder
+ def initialize(xml)
+ @xml = xml
+ end
+
+ private
+ # Delegate to xml builder, first wrapping the element in a xhtml
+ # namespaced div element if the method and arguments indicate
+ # that an xhtml_block? is desired.
+ def method_missing(method, *arguments, &block)
+ if xhtml_block?(method, arguments)
+ @xml.__send__(method, *arguments) do
+ @xml.div(:xmlns => 'http://www.w3.org/1999/xhtml') do |xhtml|
+ block.call(xhtml)
+ end
+ end
+ else
+ @xml.__send__(method, *arguments, &block)
+ end
+ end
+
+ # True if the method name matches one of the five elements defined
+ # in the Atom spec as potentially containing XHTML content and
+ # if :type => 'xhtml' is, in fact, specified.
+ def xhtml_block?(method, arguments)
+ %w( content rights title subtitle summary ).include?(method.to_s) &&
+ arguments.last.respond_to?(:[]) &&
+ arguments.last[:type].to_s == 'xhtml'
+ end
+ end
- class AtomFeedBuilder
+ class AtomFeedBuilder < AtomBuilder
def initialize(xml, view, feed_options = {})
@xml, @view, @feed_options = xml, view, feed_options
end
@@ -131,15 +183,11 @@ module ActionView
@xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:url] || @view.polymorphic_url(record))
- yield @xml
+ yield AtomBuilder.new(@xml)
end
end
-
- private
- def method_missing(method, *arguments, &block)
- @xml.__send__(method, *arguments, &block)
- end
end
+
end
end
end
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 208bf91dd4..7492348c50 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -62,7 +62,7 @@ module ActionView
# # <option>3</option><option>4</option></select>
#
# select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>", :multiple => true
- # # => <select id="colors" multiple="multiple" name="colors"><option>Red</option>
+ # # => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
# # <option>Green</option><option>Blue</option></select>
#
# select_tag "locations", "<option>Home</option><option selected="selected">Work</option><option>Out</option>"
@@ -70,14 +70,15 @@ module ActionView
# # <option>Out</option></select>
#
# select_tag "access", "<option>Read</option><option>Write</option>", :multiple => true, :class => 'form_input'
- # # => <select class="form_input" id="access" multiple="multiple" name="access"><option>Read</option>
+ # # => <select class="form_input" id="access" multiple="multiple" name="access[]"><option>Read</option>
# # <option>Write</option></select>
#
# select_tag "destination", "<option>NYC</option><option>Paris</option><option>Rome</option>", :disabled => true
# # => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
# # <option>Paris</option><option>Rome</option></select>
def select_tag(name, option_tags = nil, options = {})
- content_tag :select, option_tags, { "name" => name, "id" => name }.update(options.stringify_keys)
+ html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
+ content_tag :select, option_tags, { "name" => html_name, "id" => name }.update(options.stringify_keys)
end
# Creates a standard text field; use these text fields to input smaller chunks of text like a username
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index ff41a6d417..a3eccc741d 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -405,7 +405,7 @@ module ActionView
# # Generates: <input name="create_btn" onclick="new Ajax.Request('/testing/create',
# # {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
# # return false;" type="button" value="Create" />
- # <%= button_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
+ # <%= submit_to_remote 'create_btn', 'Create', :url => { :action => 'create' } %>
#
# # Submit to the remote action update and update the DIV succeed or fail based
# # on the success or failure of the request
@@ -413,24 +413,18 @@ module ActionView
# # Generates: <input name="update_btn" onclick="new Ajax.Updater({success:'succeed',failure:'fail'},
# # '/testing/update', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});
# # return false;" type="button" value="Update" />
- # <%= button_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
+ # <%= submit_to_remote 'update_btn', 'Update', :url => { :action => 'update' },
# :update => { :success => "succeed", :failure => "fail" }
#
# <tt>options</tt> argument is the same as in form_remote_tag.
- #
- # Note: This method used to be called submit_to_remote, but that's now just an alias for button_to_remote
- def button_to_remote(name, value, options = {})
+ def submit_to_remote(name, value, options = {})
options[:with] ||= 'Form.serialize(this.form)'
- options[:html] ||= {}
- options[:html][:type] = 'button'
- options[:html][:onclick] = "#{remote_function(options)}; return false;"
- options[:html][:name] = name
- options[:html][:value] = value
+ html_options = options.delete(:html) || {}
+ html_options[:name] = name
- tag("input", options[:html], false)
+ button_to_remote(value, options, html_options)
end
- alias_method :submit_to_remote, :button_to_remote
# Returns '<tt>eval(request.responseText)</tt>' which is the JavaScript function
# that +form_remote_tag+ can call in <tt>:complete</tt> to evaluate a multiple
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 5a6ca98b2e..7b8bb6856b 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -1441,6 +1441,12 @@ class LastModifiedRenderTest < Test::Unit::TestCase
get :conditional_hello_with_bangs
assert_response :not_modified
end
+
+ def test_last_modified_works_with_less_than_too
+ @request.if_modified_since = 5.years.ago.httpdate
+ get :conditional_hello_with_bangs
+ assert_response :not_modified
+ end
end
class RenderingLoggingTest < Test::Unit::TestCase
diff --git a/actionpack/test/controller/routing_test.rb b/actionpack/test/controller/routing_test.rb
index 1eb26a7cfd..9699a04abb 100644
--- a/actionpack/test/controller/routing_test.rb
+++ b/actionpack/test/controller/routing_test.rb
@@ -924,6 +924,20 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
end
+ def test_named_route_with_name_prefix
+ rs.add_named_route :page, 'page', :controller => 'content', :action => 'show_page', :name_prefix => 'my_'
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/page",
+ x.send(:my_page_url))
+ end
+
+ def test_named_route_with_path_prefix
+ rs.add_named_route :page, 'page', :controller => 'content', :action => 'show_page', :path_prefix => 'my'
+ x = setup_for_named_route
+ assert_equal("http://named.route.test/my/page",
+ x.send(:page_url))
+ end
+
def test_named_route_with_nested_controller
rs.add_named_route :users, 'admin/user', :controller => 'admin/user', :action => 'index'
x = setup_for_named_route
@@ -2147,6 +2161,13 @@ uses_mocha 'LegacyRouteSet, Route, RouteSet and RouteLoading' do
assert_equal [:x], set.extra_keys(args)
end
+ def test_generate_with_path_prefix
+ set.draw { |map| map.connect ':controller/:action/:id', :path_prefix => 'my' }
+
+ args = { :controller => "foo", :action => "bar", :id => "7", :x => "y" }
+ assert_equal "/my/foo/bar/7?x=y", set.generate(args)
+ end
+
def test_named_routes_are_never_relative_to_modules
set.draw do |map|
map.connect "/connection/manage/:action", :controller => 'connection/manage'
diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb
index 9eff34a542..a23428804a 100644
--- a/actionpack/test/controller/test_test.rb
+++ b/actionpack/test/controller/test_test.rb
@@ -667,6 +667,7 @@ class NamedRoutesControllerTest < ActionController::TestCase
with_routing do |set|
set.draw { |map| map.resources :contents }
assert_equal 'http://test.host/contents/new', new_content_url
+ assert_equal 'http://test.host/contents/1', content_url(:id => 1)
end
end
end
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index aaf9fe2ebf..6dc1225035 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -230,6 +230,19 @@ class AssetTagHelperTest < ActionView::TestCase
ImageLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
+ uses_mocha 'test image tag with windows behaviour' do
+ def test_image_tag_windows_behaviour
+ old_asset_id, ENV["RAILS_ASSET_ID"] = ENV["RAILS_ASSET_ID"], "1"
+ # This simulates the behaviour of File#exist? on windows when testing a file ending in "."
+ # If the file "rails.png" exists, windows will return true when asked if "rails.png." exists (notice trailing ".")
+ # OS X, linux etc will return false in this case.
+ File.stubs(:exist?).with('template/../fixtures/public/images/rails.png.').returns(true)
+ assert_equal '<img alt="Rails" src="/images/rails.png?1" />', image_tag('rails.png')
+ ensure
+ ENV["RAILS_ASSET_ID"] = old_asset_id
+ end
+ end
+
def test_timebased_asset_id
expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s
assert_equal %(<img alt="Rails" src="/images/rails.png?#{expected_time}" />), image_tag("rails.png")
diff --git a/actionpack/test/template/atom_feed_helper_test.rb b/actionpack/test/template/atom_feed_helper_test.rb
index ef31ab2c76..9247a42d33 100644
--- a/actionpack/test/template/atom_feed_helper_test.rb
+++ b/actionpack/test/template/atom_feed_helper_test.rb
@@ -92,6 +92,64 @@ class ScrollsController < ActionController::Base
end
end
EOT
+ FEEDS["feed_with_xml_processing_instructions"] = <<-EOT
+ atom_feed(:schema_date => '2008',
+ :instruct => {'xml-stylesheet' => { :href=> 't.css', :type => 'text/css' }}) do |feed|
+ feed.title("My great blog!")
+ feed.updated((@scrolls.first.created_at))
+
+ for scroll in @scrolls
+ feed.entry(scroll) do |entry|
+ entry.title(scroll.title)
+ entry.content(scroll.body, :type => 'html')
+
+ entry.author do |author|
+ author.name("DHH")
+ end
+ end
+ end
+ end
+ EOT
+ FEEDS["feed_with_xml_processing_instructions_duplicate_targets"] = <<-EOT
+ atom_feed(:schema_date => '2008',
+ :instruct => {'target1' => [{ :a => '1', :b => '2' }, { :c => '3', :d => '4' }]}) do |feed|
+ feed.title("My great blog!")
+ feed.updated((@scrolls.first.created_at))
+
+ for scroll in @scrolls
+ feed.entry(scroll) do |entry|
+ entry.title(scroll.title)
+ entry.content(scroll.body, :type => 'html')
+
+ entry.author do |author|
+ author.name("DHH")
+ end
+ end
+ end
+ end
+ EOT
+ FEEDS["feed_with_xhtml_content"] = <<-'EOT'
+ atom_feed do |feed|
+ feed.title("My great blog!")
+ feed.updated((@scrolls.first.created_at))
+
+ for scroll in @scrolls
+ feed.entry(scroll) do |entry|
+ entry.title(scroll.title)
+ entry.summary(:type => 'xhtml') do |xhtml|
+ xhtml.p "before #{scroll.id}"
+ xhtml.p {xhtml << scroll.body}
+ xhtml.p "after #{scroll.id}"
+ end
+ entry.tag!('app:edited', Time.now)
+
+ entry.author do |author|
+ author.name("DHH")
+ end
+ end
+ end
+ end
+ EOT
def index
@scrolls = [
Scroll.new(1, "1", "Hello One", "Something <i>COOL!</i>", Time.utc(2007, 12, 12, 15), Time.utc(2007, 12, 12, 15)),
@@ -194,6 +252,29 @@ class AtomFeedTest < Test::Unit::TestCase
end
end
+ def test_feed_xml_processing_instructions
+ with_restful_routing(:scrolls) do
+ get :index, :id => 'feed_with_xml_processing_instructions'
+ assert_match %r{<\?xml-stylesheet type="text/css" href="t.css"\?>}, @response.body
+ end
+ end
+
+ def test_feed_xml_processing_instructions_duplicate_targets
+ with_restful_routing(:scrolls) do
+ get :index, :id => 'feed_with_xml_processing_instructions_duplicate_targets'
+ assert_match %r{<\?target1 (a="1" b="2"|b="2" a="1")\?>}, @response.body
+ assert_match %r{<\?target1 (c="3" d="4"|d="4" c="3")\?>}, @response.body
+ end
+ end
+
+ def test_feed_xhtml
+ with_restful_routing(:scrolls) do
+ get :index, :id => "feed_with_xhtml_content"
+ assert_match %r{xmlns="http://www.w3.org/1999/xhtml"}, @response.body
+ assert_select "summary div p", :text => "Something Boring"
+ assert_select "summary div p", :text => "after 2"
+ end
+ end
private
def with_restful_routing(resources)
with_routing do |set|
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index ad8baef5e4..1849a61f2f 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -211,7 +211,8 @@ class FormTagHelperTest < ActionView::TestCase
def test_boolean_optios
assert_dom_equal %(<input checked="checked" disabled="disabled" id="admin" name="admin" readonly="readonly" type="checkbox" value="1" />), check_box_tag("admin", 1, true, 'disabled' => true, :readonly => "yes")
assert_dom_equal %(<input checked="checked" id="admin" name="admin" type="checkbox" value="1" />), check_box_tag("admin", 1, true, :disabled => false, :readonly => nil)
- assert_dom_equal %(<select id="people" multiple="multiple" name="people"><option>david</option></select>), select_tag("people", "<option>david</option>", :multiple => true)
+ assert_dom_equal %(<select id="people" multiple="multiple" name="people[]"><option>david</option></select>), select_tag("people", "<option>david</option>", :multiple => true)
+ assert_dom_equal %(<select id="people[]" multiple="multiple" name="people[]"><option>david</option></select>), select_tag("people[]", "<option>david</option>", :multiple => true)
assert_dom_equal %(<select id="people" name="people"><option>david</option></select>), select_tag("people", "<option>david</option>", :multiple => nil)
end
diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb
index a1f541fd7b..d6b86a3964 100644
--- a/actionpack/test/template/prototype_helper_test.rb
+++ b/actionpack/test/template/prototype_helper_test.rb
@@ -218,9 +218,9 @@ class PrototypeHelperTest < PrototypeHelperBaseTest
end
- def test_button_to_remote
- assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)}); return false;\" type=\"button\" value=\"1000000\" />),
- button_to_remote("More beer!", 1_000_000, :update => "empty_bottle")
+ def test_submit_to_remote
+ assert_dom_equal %(<input name=\"More beer!\" onclick=\"new Ajax.Updater('empty_bottle', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this.form)});\" type=\"button\" value=\"1000000\" />),
+ submit_to_remote("More beer!", 1_000_000, :update => "empty_bottle")
end
def test_observe_field