Compare commits

..

53 Commits

Author SHA1 Message Date
Charlie Somerville
76884dd7f7 Merge pull request #22 from github/actionview-proxy-module-method-cache-nuke
Don't globally invalidate the method and constant cache every view render
2013-10-25 11:43:48 -07:00
Charlie Somerville
29a72262aa here too 2013-10-25 12:46:48 -04:00
Charlie Somerville
76c5bf4f4b instantiate the cached helper class instead of extending AV::B 2013-10-25 12:46:48 -04:00
Charlie Somerville
416b7171b8 delete ActionView::Base#helpers because it's completely useless 2013-10-25 12:46:48 -04:00
Charlie Somerville
e82a3ba2a0 cache a class that is pre-included with the master helper module 2013-10-25 12:46:48 -04:00
Charlie Somerville
8837faac73 Merge pull request #21 from github/kill-blankslate
Kill blankslate
2013-10-25 09:42:01 -07:00
Charlie Somerville
20b12c3b42 call Kernel.block_given? instead of block_given? coz of BasicObject 2013-10-24 14:30:20 -04:00
Charlie Somerville
0cf06787af use fully qualified constant access here 2013-10-24 14:30:20 -04:00
Charlie Somerville
5efad05b11 💀 in a 🔥 blankslate 2013-10-24 14:30:20 -04:00
Charlie Somerville
00521f5118 Merge pull request #23 from github/rip-out-prototype
Rip out prototype/scriptaculous/RJS
2013-10-24 11:29:13 -07:00
Charlie Somerville
a086a33fd4 misc 2013-10-24 13:18:37 -04:00
Charlie Somerville
15678eac1c delete rjs templates 2013-10-24 12:58:08 -04:00
Charlie Somerville
2e21cced12 more test fixing 2013-10-24 12:54:06 -04:00
Charlie Somerville
fb86dada29 delete RJS template handler 2013-10-24 12:48:56 -04:00
Charlie Somerville
aa4dfa6937 delete link_to_function and button_to_function 2013-10-24 12:46:41 -04:00
Charlie Somerville
ca7a53cbe9 fix tests 2013-10-24 12:46:30 -04:00
Charlie Somerville
1ddf5592e4 forgot to remove this require 2013-10-24 12:31:15 -04:00
Charlie Somerville
425a5d5e2e don't include ScriptaculousHelper in places 2013-10-24 12:26:19 -04:00
Charlie Somerville
c8d7945ae4 delete render :update 2013-10-24 12:25:38 -04:00
Charlie Somerville
6db8e71ad8 delete tests that hit PrototypeHelper 2013-10-24 12:25:38 -04:00
Charlie Somerville
0e7a8ce464 don't include PrototypeHelper in places 2013-10-24 12:25:23 -04:00
Charlie Somerville
a4274b33f7 rip out scriptaculous 2013-10-24 12:23:20 -04:00
Charlie Somerville
9645f8be89 delete prototype.js helpers 2013-10-24 12:21:25 -04:00
Charlie Somerville
b2c42ec341 Merge pull request #20 from github/dont-use-ordered-hash
Replace use of OrderedHash with regular hashes
2013-10-15 13:06:46 -07:00
Charlie Somerville
84d39ae996 Let's just use Psych::Omap for YAML omaps 2013-10-15 15:44:53 -04:00
Charlie Somerville
35813faf54 in fact we don't even need to bother creating a new class 2013-10-15 15:42:33 -04:00
Charlie Somerville
ca03813864 AS::OrderedHash#to_yaml is just completely broken
irb(main):004:0> ActiveSupport::OrderedHash["a",1,"b",2].to_yaml
ArgumentError: wrong number of arguments (2 for 0)
	from /Users/charlie/github/github/vendor/gems/2.0.0/ruby/2.0.0/gems/activesupport-2.3.14.github25/lib/active_support/ordered_hash.rb:16:in `block in to_yaml'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/deprecated.rb:19:in `call'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/deprecated.rb:19:in `block in quick_emit'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:449:in `dump_coder'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:126:in `accept'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:92:in `push'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych.rb:244:in `dump'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/core_ext.rb:14:in `psych_to_yaml'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/deprecated.rb:21:in `quick_emit'
	from /Users/charlie/github/github/vendor/gems/2.0.0/ruby/2.0.0/gems/activesupport-2.3.14.github25/lib/active_support/ordered_hash.rb:15:in `to_yaml'
	from (irb):4
	from script/console:56:in `<main>'

irb(main):005:0> YAML.dump(ActiveSupport::OrderedHash["a",1,"b",2])
ArgumentError: wrong number of arguments (2 for 0)
	from /Users/charlie/github/github/vendor/gems/2.0.0/ruby/2.0.0/gems/activesupport-2.3.14.github25/lib/active_support/ordered_hash.rb:16:in `block in to_yaml'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/deprecated.rb:19:in `call'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/deprecated.rb:19:in `block in quick_emit'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:449:in `dump_coder'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:126:in `accept'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych/visitors/yaml_tree.rb:92:in `push'
	from /Users/charlie/.rubies/ruby-2.0.0-github/lib/ruby/2.0.0/psych.rb:244:in `dump'
	from (irb):5
	from script/console:56:in `<main>'
2013-10-15 15:33:15 -04:00
Charlie Somerville
8a78d5922a delete all these method definitions 2013-10-15 15:28:59 -04:00
Charlie Somerville
3770f13b97 replace uses of OrderedHash with just a regular hash 2013-10-15 15:20:43 -04:00
Charlie Somerville
755a361548 while i'm at it, 🔥 other unused monkey patches 2013-10-15 15:18:05 -04:00
Charlie Somerville
422b3d0dcb delete custom Enumerable#group_by 2013-10-15 15:17:27 -04:00
Charlie Somerville
c96caaae9a Merge pull request #19 from github/delete-formatted-route-helper
Delete deprecated formatted_ URL helper
2013-10-01 21:56:02 -07:00
Charlie Somerville
050be61caf delete test for formatted_ 2013-10-02 14:29:50 +10:00
Charlie Somerville
4baefa4de9 delete formatted_ url helper 2013-10-02 14:25:57 +10:00
Charlie Somerville
26fce88209 add readme with note that this fork is unsupported 2013-09-18 00:37:48 +10:00
Charlie Somerville
cb507570a1 Merge pull request #18 from github/remove-use-of-method-private
Remove use of Method#private?
2013-09-16 22:59:19 -07:00
Charlie Somerville
9a2d6cad23 backport rails 4 assign attributes 2013-09-17 15:50:09 +10:00
Charlie Somerville
bf96f35248 we can used defined?() to check if a method is public or protected 2013-09-17 15:45:25 +10:00
Charlie Somerville
21bae614ee Merge pull request #17 from github/remove-warnings-from-tests
Don't use -w in tests
2013-09-16 22:43:27 -07:00
Charlie Somerville
1d6053f5bf remove -w from tests 2013-09-17 15:40:41 +10:00
Charlie Somerville
f90bfeb930 Merge pull request #16 from github/build-on-ruby-1.9.3-and-2.0.0
Build on Ruby 1.9.3 and 2.0.0
2013-09-16 22:35:48 -07:00
Charlie Somerville
bca938dae2 skip over memcached tests 2013-09-17 12:08:57 +10:00
Charlie Somerville
4579aa2767 run rails tests on both ruby 1.9.3 and 2.0.0 2013-09-17 11:47:15 +10:00
Charlie Somerville
0a522af512 Merge pull request #15 from github/add-gemspecs
Add gemspecs
2013-09-16 18:29:30 -07:00
Charlie Somerville
ca6a64758b bump rack dependency to 1.4 to match what we currently have 2013-09-17 11:24:19 +10:00
Charlie Somerville
8573f7f86b pull in gemspecs from upstream 2013-09-17 11:17:06 +10:00
Charlie Somerville
685cb901fc Merge pull request #13 from github/backport-message_verifier
Backport ActiveSupport::MessageVerifier from Rails 3
2013-08-27 03:55:52 -07:00
Charlie Somerville
e9f9d05a94 pass digest as a key in an options hash 2013-08-27 20:51:18 +10:00
Charlie Somerville
7b6670cc08 fix test 2013-08-27 20:51:14 +10:00
Charlie Somerville
ed2d852bdc backport ActiveSupport::MessageVerifier from Rails 3 2013-08-27 20:27:31 +10:00
Greg Ose
726ab5316d Merge pull request #12 from github/authenticity_token_tests
Authenticity token tests
2013-08-13 11:37:09 -07:00
Greg Ose
ecd6fb250a Test for form_for authenticity_token backport 2013-08-12 13:21:03 -05:00
Greg Ose
9f8ee9dd97 Merge tag 'github24' into authenticity_token_tests
github24
2013-08-12 12:54:23 -05:00
70 changed files with 302 additions and 3715 deletions

6
README.md Normal file
View File

@@ -0,0 +1,6 @@
# GitHub Rails
This is GitHub's fork of Rails 2.3.
Please note that this fork is **unsupported**. It is not guaranteed to receive security patches or remain stable. **Use at your own risk.**

View File

@@ -23,8 +23,6 @@ task :default => [ :test ]
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/*_test.rb'
t.verbose = true
t.warning = false
}

View File

@@ -0,0 +1,14 @@
Gem::Specification.new do |s|
s.name = 'actionmailer'
s.version = '2.3.18'
s.summary = 'Service layer for easy email delivery and testing.'
s.description = 'Makes it trivial to test and deliver emails sent from a single service layer.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.add_dependency 'actionpack', '= 2.3.18'
end

View File

@@ -30,16 +30,12 @@ Rake::TestTask.new(:test_action_pack) do |t|
# make sure we include the tests in alphabetical order as on some systems
# this will not happen automatically and the tests (as a whole) will error
t.test_files = Dir.glob( "test/[cftv]*/**/*_test.rb" ).sort
t.verbose = true
#t.warning = true
end
desc 'ActiveRecord Integration Tests'
Rake::TestTask.new(:test_active_record_integration) do |t|
t.libs << "test"
t.test_files = Dir.glob("test/activerecord/*_test.rb")
t.verbose = true
end

View File

@@ -0,0 +1,15 @@
Gem::Specification.new do |s|
s.name = 'actionpack'
s.version = '2.3.18'
s.summary = 'Web-flow and rendering framework putting the VC in MVC.'
s.description = 'Eases web-request routing, handling, and response as a half-way front, half-way page controller. Implemented with specific emphasis on enabling easy unit/integration testing that doesn\'t require a browser.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.add_dependency 'activesupport', '= 2.3.18'
s.add_dependency 'rack', '~> 1.4'
end

View File

@@ -964,13 +964,6 @@ module ActionController #:nodoc:
render_for_text(@template.render(options), options[:status])
end
elsif options[:update]
@template.send(:_evaluate_assigns_and_ivars)
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template, &block)
response.content_type = Mime::JS
render_for_text(generator.to_s, options[:status])
elsif options[:nothing]
render_for_text(nil, options[:status])
@@ -1280,8 +1273,7 @@ module ActionController #:nodoc:
end
def initialize_template_class(response)
response.template = ActionView::Base.new(self.class.view_paths, {}, self)
response.template.helpers.send :include, self.class.master_helper_module
response.template = self.class.master_helper_class.new(self.class.view_paths, {}, self)
response.redirected_to = nil
@performed_render = @performed_redirect = false
end
@@ -1332,10 +1324,7 @@ module ActionController #:nodoc:
if action_methods.include?(action_name)
send(action_name)
default_render unless performed?
elsif RUBY_VERSION == "1.9.3" && respond_to?(:method_missing)
method_missing action_name.intern
default_render unless performed?
elsif RUBY_VERSION >= "2.0.0" && respond_to?(:method_missing, true) && !method(:method_missing).private?
elsif defined?(self.method_missing) # returns "method" if method_missing is public or protected, but not if it's private
method_missing action_name.intern
default_render unless performed?
else

View File

@@ -69,6 +69,22 @@ module ActionController #:nodoc:
# N/A | Carolina Railhaws Training Workshop
#
module ClassMethods
# To avoid extending an instance of ActionView::Base with the master_helper_module
# every single time we render a view, we're caching a class that has
# master_helper_module already included that we can just instantiate.
def master_helper_class
return @master_helper_class if @master_helper_class
@master_helper_class = Class.new(ActionView::Base).tap do |klass|
klass.send(:include, master_helper_module)
end
end
def master_helper_module=(mod)
write_inheritable_attribute(:master_helper_module, mod)
@master_helper_class = nil
end
# Makes all the (instance) methods in the helper module available to templates rendered through this controller.
# See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
# available to the templates.
@@ -182,8 +198,7 @@ module ActionController #:nodoc:
# Provides a proxy to access helpers methods from outside the view.
def helpers
unless @helper_proxy
@helper_proxy = ActionView::Base.new
@helper_proxy.extend master_helper_module
@helper_proxy = master_helper_class.new
else
@helper_proxy
end

View File

@@ -192,14 +192,7 @@ module ActionController
url_for(#{hash_access_method}(opts)) # url_for(hash_for_users_url(opts))
#
end # end
#Add an alias to support the now deprecated formatted_* URL. # #Add an alias to support the now deprecated formatted_* URL.
def formatted_#{selector}(*args) # def formatted_users_url(*args)
ActiveSupport::Deprecation.warn( # ActiveSupport::Deprecation.warn(
"formatted_#{selector}() has been deprecated. " + # "formatted_users_url() has been deprecated. " +
"Please pass format to the standard " + # "Please pass format to the standard " +
"#{selector} method instead.", caller) # "users_url method instead.", caller)
#{selector}(*args) # users_url(*args)
end # end
protected :#{selector} # protected :users_url
end_eval
helpers << selector

View File

@@ -209,7 +209,7 @@ module ActionController
def verifier_for(secret, digest)
key = secret.respond_to?(:call) ? secret.call : secret
ActiveSupport::MessageVerifier.new(key, digest)
ActiveSupport::MessageVerifier.new(key, digest: digest)
end
def generate_sid

View File

@@ -175,13 +175,6 @@ module ActionView #:nodoc:
delegate :logger, :to => 'ActionController::Base'
end
@@debug_rjs = false
##
# :singleton-method:
# Specify whether RJS responses should be wrapped in a try/catch block
# that alert()s the caught exception (and then re-raises it).
cattr_accessor :debug_rjs
# Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed.
# Automatically reloading templates are not thread safe and should only be used in development mode.
@@cache_template_loading = nil
@@ -210,24 +203,10 @@ module ActionView #:nodoc:
ActionView::PathSet.new(Array(value))
end
attr_reader :helpers
class ProxyModule < Module
def initialize(receiver)
@receiver = receiver
end
def include(*args)
super(*args)
@receiver.extend(*args)
end
end
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
@assigns = assigns_for_first_render
@assigns_added = nil
@controller = controller
@helpers = ProxyModule.new(self)
self.view_paths = view_paths
@_first_render = nil
@@ -270,8 +249,6 @@ module ActionView #:nodoc:
elsif options[:text]
options[:text]
end
when :update
update_page(&block)
else
render_partial(:partial => options, :locals => local_assigns)
end

View File

@@ -14,12 +14,10 @@ module ActionView #:nodoc:
autoload :FormTagHelper, 'action_view/helpers/form_tag_helper'
autoload :JavaScriptHelper, 'action_view/helpers/javascript_helper'
autoload :NumberHelper, 'action_view/helpers/number_helper'
autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
autoload :RawOutputHelper, 'action_view/helpers/raw_output_helper'
autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
autoload :RecordTagHelper, 'action_view/helpers/record_tag_helper'
autoload :SanitizeHelper, 'action_view/helpers/sanitize_helper'
autoload :ScriptaculousHelper, 'action_view/helpers/scriptaculous_helper'
autoload :TagHelper, 'action_view/helpers/tag_helper'
autoload :TextHelper, 'action_view/helpers/text_helper'
autoload :TranslationHelper, 'action_view/helpers/translation_helper'
@@ -47,12 +45,10 @@ module ActionView #:nodoc:
include FormTagHelper
include JavaScriptHelper
include NumberHelper
include PrototypeHelper
include RawOutputHelper
include RecordIdentificationHelper
include RecordTagHelper
include SanitizeHelper
include ScriptaculousHelper
include TagHelper
include TextHelper
include TranslationHelper

View File

@@ -1,5 +1,4 @@
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/prototype_helper'
module ActionView
module Helpers
@@ -39,95 +38,6 @@ module ActionView
JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
end
include PrototypeHelper
# Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
# onclick handler and return false after the fact.
#
# The first argument +name+ is used as the link text.
#
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
#
# The +function+ argument can be omitted in favor of an +update_page+
# block, which evaluates to a string when the template is rendered
# (instead of making an Ajax request first).
#
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
#
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
#
#
# Examples:
# link_to_function "Greeting", "alert('Hello world!')"
# Produces:
# <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
#
# link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
# Produces:
# <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
# <img src="/images/delete.png?" alt="Delete"/>
# </a>
#
# link_to_function("Show me more", nil, :id => "more_link") do |page|
# page[:details].visual_effect :toggle_blind
# page[:more_link].replace_html "Show me less"
# end
# Produces:
# <a href="#" id="more_link" onclick="try {
# $(&quot;details&quot;).visualEffect(&quot;toggle_blind&quot;);
# $(&quot;more_link&quot;).update(&quot;Show me less&quot;);
# }
# catch (e) {
# alert('RJS error:\n\n' + e.toString());
# alert('$(\&quot;details\&quot;).visualEffect(\&quot;toggle_blind\&quot;);
# \n$(\&quot;more_link\&quot;).update(\&quot;Show me less\&quot;);');
# throw e
# };
# return false;">Show me more</a>
#
def link_to_function(name, *args, &block)
html_options = args.extract_options!.symbolize_keys
function = block_given? ? update_page(&block) : args[0] || ''
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
href = html_options[:href] || '#'
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
end
# Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
# onclick handler.
#
# The first argument +name+ is used as the button's value or display text.
#
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
#
# The +function+ argument can be omitted in favor of an +update_page+
# block, which evaluates to a string when the template is rendered
# (instead of making an Ajax request first).
#
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
#
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
#
# Examples:
# button_to_function "Greeting", "alert('Hello world!')"
# button_to_function "Delete", "if (confirm('Really?')) do_delete()"
# button_to_function "Details" do |page|
# page[:details].visual_effect :toggle_slide
# end
# button_to_function "Details", :class => "details_button" do |page|
# page[:details].visual_effect :toggle_slide
# end
def button_to_function(name, *args, &block)
html_options = args.extract_options!.symbolize_keys
function = block_given? ? update_page(&block) : args[0] || ''
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
end
JS_ESCAPE_MAP = {
'\\' => '\\\\',
'</' => '<\/',

File diff suppressed because it is too large Load Diff

View File

@@ -1,226 +0,0 @@
require 'action_view/helpers/javascript_helper'
require 'active_support/json'
module ActionView
module Helpers
# Provides a set of helpers for calling Scriptaculous JavaScript
# functions, including those which create Ajax controls and visual effects.
#
# To be able to use these helpers, you must include the Prototype
# JavaScript framework and the Scriptaculous JavaScript library in your
# pages. See the documentation for ActionView::Helpers::JavaScriptHelper
# for more information on including the necessary JavaScript.
#
# The Scriptaculous helpers' behavior can be tweaked with various options.
# See the documentation at http://script.aculo.us for more information on
# using these helpers in your application.
module ScriptaculousHelper
unless const_defined? :TOGGLE_EFFECTS
TOGGLE_EFFECTS = [:toggle_appear, :toggle_slide, :toggle_blind]
end
# Returns a JavaScript snippet to be used on the Ajax callbacks for
# starting visual effects.
#
# Example:
# <%= link_to_remote "Reload", :update => "posts",
# :url => { :action => "reload" },
# :complete => visual_effect(:highlight, "posts", :duration => 0.5)
#
# If no +element_id+ is given, it assumes "element" which should be a local
# variable in the generated JavaScript execution context. This can be
# used for example with +drop_receiving_element+:
#
# <%= drop_receiving_element (...), :loading => visual_effect(:fade) %>
#
# This would fade the element that was dropped on the drop receiving
# element.
#
# For toggling visual effects, you can use <tt>:toggle_appear</tt>, <tt>:toggle_slide</tt>, and
# <tt>:toggle_blind</tt> which will alternate between appear/fade, slidedown/slideup, and
# blinddown/blindup respectively.
#
# You can change the behaviour with various options, see
# http://script.aculo.us for more documentation.
def visual_effect(name, element_id = false, js_options = {})
element = element_id ? ActiveSupport::JSON.encode(element_id) : "element"
js_options[:queue] = if js_options[:queue].is_a?(Hash)
'{' + js_options[:queue].map {|k, v| k == :limit ? "#{k}:#{v}" : "#{k}:'#{v}'" }.join(',') + '}'
elsif js_options[:queue]
"'#{js_options[:queue]}'"
end if js_options[:queue]
[:endcolor, :direction, :startcolor, :scaleMode, :restorecolor].each do |option|
js_options[option] = "'#{js_options[option]}'" if js_options[option]
end
if TOGGLE_EFFECTS.include? name.to_sym
"Effect.toggle(#{element},'#{name.to_s.gsub(/^toggle_/,'')}',#{options_for_javascript(js_options)});"
else
"new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});"
end
end
# Makes the element with the DOM ID specified by +element_id+ sortable
# by drag-and-drop and make an Ajax call whenever the sort order has
# changed. By default, the action called gets the serialized sortable
# element as parameters.
#
# Example:
#
# <%= sortable_element("my_list", :url => { :action => "order" }) %>
#
# In the example, the action gets a "my_list" array parameter
# containing the values of the ids of elements the sortable consists
# of, in the current order.
#
# Important: For this to work, the sortable elements must have id
# attributes in the form "string_identifier". For example, "item_1". Only
# the identifier part of the id attribute will be serialized.
#
# Additional +options+ are:
#
# * <tt>:format</tt> - A regular expression to determine what to send as the
# serialized id to the server (the default is <tt>/^[^_]*_(.*)$/</tt>).
#
# * <tt>:constraint</tt> - Whether to constrain the dragging to either
# <tt>:horizontal</tt> or <tt>:vertical</tt> (or false to make it unconstrained).
#
# * <tt>:overlap</tt> - Calculate the item overlap in the <tt>:horizontal</tt>
# or <tt>:vertical</tt> direction.
#
# * <tt>:tag</tt> - Which children of the container element to treat as
# sortable (default is <tt>li</tt>).
#
# * <tt>:containment</tt> - Takes an element or array of elements to treat as
# potential drop targets (defaults to the original target element).
#
# * <tt>:only</tt> - A CSS class name or array of class names used to filter
# out child elements as candidates.
#
# * <tt>:scroll</tt> - Determines whether to scroll the list during drag
# operations if the list runs past the visual border.
#
# * <tt>:tree</tt> - Determines whether to treat nested lists as part of the
# main sortable list. This means that you can create multi-layer lists,
# and not only sort items at the same level, but drag and sort items
# between levels.
#
# * <tt>:hoverclass</tt> - If set, the Droppable will have this additional CSS class
# when an accepted Draggable is hovered over it.
#
# * <tt>:handle</tt> - Sets whether the element should only be draggable by an
# embedded handle. The value may be a string referencing a CSS class value
# (as of script.aculo.us V1.5). The first child/grandchild/etc. element
# found within the element that has this CSS class value will be used as
# the handle.
#
# * <tt>:ghosting</tt> - Clones the element and drags the clone, leaving
# the original in place until the clone is dropped (default is <tt>false</tt>).
#
# * <tt>:dropOnEmpty</tt> - If true the Sortable container will be made into
# a Droppable, that can receive a Draggable (as according to the containment
# rules) as a child element when there are no more elements inside (default
# is <tt>false</tt>).
#
# * <tt>:onChange</tt> - Called whenever the sort order changes while dragging. When
# dragging from one Sortable to another, the callback is called once on each
# Sortable. Gets the affected element as its parameter.
#
# * <tt>:onUpdate</tt> - Called when the drag ends and the Sortable's order is
# changed in any way. When dragging from one Sortable to another, the callback
# is called once on each Sortable. Gets the container as its parameter.
#
# See http://script.aculo.us for more documentation.
def sortable_element(element_id, options = {})
javascript_tag(sortable_element_js(element_id, options).chop!)
end
def sortable_element_js(element_id, options = {}) #:nodoc:
options[:with] ||= "Sortable.serialize(#{ActiveSupport::JSON.encode(element_id)})"
options[:onUpdate] ||= "function(){" + remote_function(options) + "}"
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
[:tag, :overlap, :constraint, :handle].each do |option|
options[option] = "'#{options[option]}'" if options[option]
end
options[:containment] = array_or_string_for_javascript(options[:containment]) if options[:containment]
options[:only] = array_or_string_for_javascript(options[:only]) if options[:only]
%(Sortable.create(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
# Makes the element with the DOM ID specified by +element_id+ draggable.
#
# Example:
# <%= draggable_element("my_image", :revert => true)
#
# You can change the behaviour with various options, see
# http://script.aculo.us for more documentation.
def draggable_element(element_id, options = {})
javascript_tag(draggable_element_js(element_id, options).chop!)
end
def draggable_element_js(element_id, options = {}) #:nodoc:
%(new Draggable(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
# Makes the element with the DOM ID specified by +element_id+ receive
# dropped draggable elements (created by +draggable_element+).
# and make an AJAX call. By default, the action called gets the DOM ID
# of the element as parameter.
#
# Example:
# <%= drop_receiving_element("my_cart", :url =>
# { :controller => "cart", :action => "add" }) %>
#
# You can change the behaviour with various options, see
# http://script.aculo.us for more documentation.
#
# Some of these +options+ include:
# * <tt>:accept</tt> - Set this to a string or an array of strings describing the
# allowable CSS classes that the +draggable_element+ must have in order
# to be accepted by this +drop_receiving_element+.
#
# * <tt>:confirm</tt> - Adds a confirmation dialog. Example:
#
# :confirm => "Are you sure you want to do this?"
#
# * <tt>:hoverclass</tt> - If set, the +drop_receiving_element+ will have
# this additional CSS class when an accepted +draggable_element+ is
# hovered over it.
#
# * <tt>:onDrop</tt> - Called when a +draggable_element+ is dropped onto
# this element. Override this callback with a JavaScript expression to
# change the default drop behaviour. Example:
#
# :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }"
#
# This callback gets three parameters: The Draggable element, the Droppable
# element and the Event object. You can extract additional information about
# the drop - like if the Ctrl or Shift keys were pressed - from the Event object.
#
# * <tt>:with</tt> - A JavaScript expression specifying the parameters for
# the XMLHttpRequest. Any expressions should return a valid URL query string.
def drop_receiving_element(element_id, options = {})
javascript_tag(drop_receiving_element_js(element_id, options).chop!)
end
def drop_receiving_element_js(element_id, options = {}) #:nodoc:
options[:with] ||= "'id=' + encodeURIComponent(element.id)"
options[:onDrop] ||= "function(element){" + remote_function(options) + "}"
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept]
options[:hoverclass] = "'#{options[:hoverclass]}'" if options[:hoverclass]
# Confirmation happens during the onDrop callback, so it can be removed from the options
options.delete(:confirm) if options[:confirm]
%(Droppables.add(#{ActiveSupport::JSON.encode(element_id)}, #{options_for_javascript(options)});)
end
end
end
end

View File

@@ -98,7 +98,7 @@ module ActionView #:nodoc:
include Renderable
# Templates that are exempt from layouts
@@exempt_from_layout = Set.new([/\.rjs$/])
@@exempt_from_layout = Set.new
# Don't render layouts for templates with the given extensions.
def self.exempt_from_layout(*extensions)

View File

@@ -1,12 +1,10 @@
module ActionView #:nodoc:
module TemplateHandlers #:nodoc:
autoload :ERB, 'action_view/template_handlers/erb'
autoload :RJS, 'action_view/template_handlers/rjs'
autoload :Builder, 'action_view/template_handlers/builder'
def self.extended(base)
base.register_default_template_handler :erb, TemplateHandlers::ERB
base.register_template_handler :rjs, TemplateHandlers::RJS
base.register_template_handler :builder, TemplateHandlers::Builder
# TODO: Depreciate old template extensions

View File

@@ -1,13 +0,0 @@
module ActionView
module TemplateHandlers
class RJS < TemplateHandler
include Compilable
def compile(template)
"@template_format = :html;" +
"controller.response.content_type ||= Mime::JS;" +
"update_page do |page|;#{template.source}\nend"
end
end
end
end

View File

@@ -116,8 +116,7 @@ module ActionView
end
def _view
view = ActionView::Base.new(ActionController::Base.view_paths, _assigns, @controller)
view.helpers.include master_helper_module
view = self.class.master_helper_class.new(ActionController::Base.view_paths, _assigns, @controller)
view.output_buffer = self.output_buffer
view
end

View File

@@ -47,13 +47,6 @@ class AssertSelectTest < ActionController::TestCase
@content = nil
end
def rjs()
render :update do |page|
@update.call page
end
@update = nil
end
def xml()
render :text=>@content, :layout=>false, :content_type=>Mime::XML
@content = nil
@@ -220,43 +213,6 @@ class AssertSelectTest < ActionController::TestCase
end
end
# With single result.
def test_assert_select_from_rjs_with_single_result
render_rjs do |page|
page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
end
assert_select "div" do |elements|
assert elements.size == 2
assert_select "#1"
assert_select "#2"
end
assert_select "div#?", /\d+/ do |elements|
assert_select "#1"
assert_select "#2"
end
end
# With multiple results.
def test_assert_select_from_rjs_with_multiple_results
render_rjs do |page|
page.replace_html "test", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
end
assert_select "div" do |elements|
assert elements.size == 2
assert_select "#1"
assert_select "#2"
end
end
def test_assert_select_rjs_for_positioned_insert_should_fail_when_mixing_arguments
render_rjs do |page|
page.insert_html :top, "test1", "<div id=\"1\">foo</div>"
page.insert_html :bottom, "test2", "<div id=\"2\">foo</div>"
end
assert_raise(Assertion) {assert_select_rjs :insert, :top, "test2"}
end
def test_elect_with_xml_namespace_attributes
render_html %Q{<link xlink:href="http://nowhere.com"></link>}
assert_nothing_raised { assert_select "link[xlink:href=http://nowhere.com]" }
@@ -290,365 +246,6 @@ class AssertSelectTest < ActionController::TestCase
end
end
# With one result.
def test_css_select_from_rjs_with_single_result
render_rjs do |page|
page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
end
assert_equal 2, css_select("div").size
assert_equal 1, css_select("#1").size
assert_equal 1, css_select("#2").size
end
# With multiple results.
def test_css_select_from_rjs_with_multiple_results
render_rjs do |page|
page.replace_html "test", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
end
assert_equal 2, css_select("div").size
assert_equal 1, css_select("#1").size
assert_equal 1, css_select("#2").size
end
#
# Test assert_select_rjs.
#
# Test that we can pick up all statements in the result.
def test_assert_select_rjs_picks_up_all_statements
render_rjs do |page|
page.replace "test", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
end
found = false
assert_select_rjs do
assert_select "#1"
assert_select "#2"
assert_select "#3"
found = true
end
assert found
end
# Test that we fail if there is nothing to pick.
def test_assert_select_rjs_fails_if_nothing_to_pick
render_rjs { }
assert_raise(Assertion) { assert_select_rjs }
end
def test_assert_select_rjs_with_unicode
# Test that non-ascii characters (which are converted into \uXXXX in RJS) are decoded correctly.
render_rjs do |page|
page.replace "test", "<div id=\"1\">\343\203\201\343\202\261\343\203\203\343\203\210</div>"
end
assert_select_rjs do
str = "#1"
assert_select str, :text => "\343\203\201\343\202\261\343\203\203\343\203\210"
assert_select str, "\343\203\201\343\202\261\343\203\203\343\203\210"
if str.respond_to?(:force_encoding)
str.force_encoding(Encoding::UTF_8)
assert_select str, /\343\203\201..\343\203\210/u
assert_raise(Assertion) { assert_select str, /\343\203\201.\343\203\210/u }
else
assert_select str, Regexp.new("\343\203\201..\343\203\210",0,'U')
assert_raise(Assertion) { assert_select str, Regexp.new("\343\203\201.\343\203\210",0,'U') }
end
end
end
def test_assert_select_rjs_with_id
# Test that we can pick up all statements in the result.
render_rjs do |page|
page.replace "test1", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
end
assert_select_rjs "test1" do
assert_select "div", 1
assert_select "#1"
end
assert_select_rjs "test2" do
assert_select "div", 1
assert_select "#2"
end
assert_select_rjs "test3" do
assert_select "div", 1
assert_select "#3"
end
assert_raise(Assertion) { assert_select_rjs "test4" }
end
def test_assert_select_rjs_for_replace
render_rjs do |page|
page.replace "test1", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
end
# Replace.
assert_select_rjs :replace do
assert_select "div", 1
assert_select "#1"
end
assert_select_rjs :replace, "test1" do
assert_select "div", 1
assert_select "#1"
end
assert_raise(Assertion) { assert_select_rjs :replace, "test2" }
# Replace HTML.
assert_select_rjs :replace_html do
assert_select "div", 1
assert_select "#2"
end
assert_select_rjs :replace_html, "test2" do
assert_select "div", 1
assert_select "#2"
end
assert_raise(Assertion) { assert_select_rjs :replace_html, "test1" }
end
def test_assert_select_rjs_for_chained_replace
render_rjs do |page|
page['test1'].replace "<div id=\"1\">foo</div>"
page['test2'].replace_html "<div id=\"2\">foo</div>"
page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
end
# Replace.
assert_select_rjs :chained_replace do
assert_select "div", 1
assert_select "#1"
end
assert_select_rjs :chained_replace, "test1" do
assert_select "div", 1
assert_select "#1"
end
assert_raise(Assertion) { assert_select_rjs :chained_replace, "test2" }
# Replace HTML.
assert_select_rjs :chained_replace_html do
assert_select "div", 1
assert_select "#2"
end
assert_select_rjs :chained_replace_html, "test2" do
assert_select "div", 1
assert_select "#2"
end
assert_raise(Assertion) { assert_select_rjs :replace_html, "test1" }
end
# Simple remove
def test_assert_select_rjs_for_remove
render_rjs do |page|
page.remove "test1"
end
assert_select_rjs :remove, "test1"
end
def test_assert_select_rjs_for_remove_offers_useful_error_when_assertion_fails
render_rjs do |page|
page.remove "test_with_typo"
end
assert_select_rjs :remove, "test1"
rescue Assertion
assert_equal "No RJS statement that removes 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_remove_ignores_block
render_rjs do |page|
page.remove "test1"
end
assert_nothing_raised do
assert_select_rjs :remove, "test1" do
assert_select "p"
end
end
end
# Simple show
def test_assert_select_rjs_for_show
render_rjs do |page|
page.show "test1"
end
assert_select_rjs :show, "test1"
end
def test_assert_select_rjs_for_show_offers_useful_error_when_assertion_fails
render_rjs do |page|
page.show "test_with_typo"
end
assert_select_rjs :show, "test1"
rescue Assertion
assert_equal "No RJS statement that shows 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_show_ignores_block
render_rjs do |page|
page.show "test1"
end
assert_nothing_raised do
assert_select_rjs :show, "test1" do
assert_select "p"
end
end
end
# Simple hide
def test_assert_select_rjs_for_hide
render_rjs do |page|
page.hide "test1"
end
assert_select_rjs :hide, "test1"
end
def test_assert_select_rjs_for_hide_offers_useful_error_when_assertion_fails
render_rjs do |page|
page.hide "test_with_typo"
end
assert_select_rjs :hide, "test1"
rescue Assertion
assert_equal "No RJS statement that hides 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_hide_ignores_block
render_rjs do |page|
page.hide "test1"
end
assert_nothing_raised do
assert_select_rjs :hide, "test1" do
assert_select "p"
end
end
end
# Simple toggle
def test_assert_select_rjs_for_toggle
render_rjs do |page|
page.toggle "test1"
end
assert_select_rjs :toggle, "test1"
end
def test_assert_select_rjs_for_toggle_offers_useful_error_when_assertion_fails
render_rjs do |page|
page.toggle "test_with_typo"
end
assert_select_rjs :toggle, "test1"
rescue Assertion
assert_equal "No RJS statement that toggles 'test1' was rendered.", $!.message
end
def test_assert_select_rjs_for_toggle_ignores_block
render_rjs do |page|
page.toggle "test1"
end
assert_nothing_raised do
assert_select_rjs :toggle, "test1" do
assert_select "p"
end
end
end
# Non-positioned insert.
def test_assert_select_rjs_for_nonpositioned_insert
render_rjs do |page|
page.replace "test1", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
page.insert_html :top, "test3", "<div id=\"3\">foo</div>"
end
assert_select_rjs :insert_html do
assert_select "div", 1
assert_select "#3"
end
assert_select_rjs :insert_html, "test3" do
assert_select "div", 1
assert_select "#3"
end
assert_raise(Assertion) { assert_select_rjs :insert_html, "test1" }
end
# Positioned insert.
def test_assert_select_rjs_for_positioned_insert
render_rjs do |page|
page.insert_html :top, "test1", "<div id=\"1\">foo</div>"
page.insert_html :bottom, "test2", "<div id=\"2\">foo</div>"
page.insert_html :before, "test3", "<div id=\"3\">foo</div>"
page.insert_html :after, "test4", "<div id=\"4\">foo</div>"
end
assert_select_rjs :insert, :top do
assert_select "div", 1
assert_select "#1"
end
assert_select_rjs :insert, :bottom do
assert_select "div", 1
assert_select "#2"
end
assert_select_rjs :insert, :before do
assert_select "div", 1
assert_select "#3"
end
assert_select_rjs :insert, :after do
assert_select "div", 1
assert_select "#4"
end
assert_select_rjs :insert_html do
assert_select "div", 4
end
end
def test_assert_select_rjs_raise_errors
assert_raise(ArgumentError) { assert_select_rjs(:destroy) }
assert_raise(ArgumentError) { assert_select_rjs(:insert, :left) }
end
# Simple selection from a single result.
def test_nested_assert_select_rjs_with_single_result
render_rjs do |page|
page.replace_html "test", "<div id=\"1\">foo</div>\n<div id=\"2\">foo</div>"
end
assert_select_rjs "test" do |elements|
assert_equal 2, elements.size
assert_select "#1"
assert_select "#2"
end
end
# Deal with two results.
def test_nested_assert_select_rjs_with_two_results
render_rjs do |page|
page.replace_html "test", "<div id=\"1\">foo</div>"
page.replace_html "test2", "<div id=\"2\">foo</div>"
end
assert_select_rjs "test" do |elements|
assert_equal 1, elements.size
assert_select "#1"
end
assert_select_rjs "test2" do |elements|
assert_equal 1, elements.size
assert_select "#2"
end
end
def test_feed_item_encoded
render_xml <<-EOF
<rss version="2.0">
@@ -725,11 +322,6 @@ EOF
get :html
end
def render_rjs(&block)
@controller.response_with &block
get :rjs
end
def render_xml(xml)
@controller.response_with = xml
get :xml

View File

@@ -703,13 +703,6 @@ CACHED
assert_match "Some cached content", @store.read('views/test.host/functional_caching/inline_fragment_cached')
end
def test_fragment_caching_in_rjs_partials
xhr :get, :js_fragment_cached_with_partial
assert_response :success
assert_match /Fragment caching in a partial/, @response.body
assert_match "Fragment caching in a partial", @store.read('views/test.host/functional_caching/js_fragment_cached_with_partial')
end
def test_html_formatted_fragment_caching
get :formatted_fragment_cached, :format => "html"
assert_response :success
@@ -729,15 +722,4 @@ CACHED
assert_equal " <p>Builder</p>\n", @store.read('views/test.host/functional_caching/formatted_fragment_cached')
end
def test_js_formatted_fragment_caching
get :formatted_fragment_cached, :format => "js"
assert_response :success
expected_body = %(title = "Hey";\n$("element_1").visualEffect("highlight");\n) +
%($("element_2").visualEffect("highlight");\nfooter = "Bye";)
assert_equal expected_body, @response.body
assert_equal ['$("element_1").visualEffect("highlight");', '$("element_2").visualEffect("highlight");'],
@store.read('views/test.host/functional_caching/formatted_fragment_cached')
end
end

View File

@@ -30,9 +30,6 @@ class ContentTypeController < ActionController::Base
def render_default_for_rxml
end
def render_default_for_rjs
end
def render_change_for_rxml
response.content_type = Mime::HTML
render :action => "render_default_for_rxml"
@@ -123,12 +120,6 @@ class ContentTypeTest < ActionController::TestCase
assert_equal "utf-8", @response.charset
end
def test_default_for_rjs
xhr :post, :render_default_for_rjs
assert_equal Mime::JS, @response.content_type
assert_equal "utf-8", @response.charset
end
def test_change_for_rxml
get :render_change_for_rxml
assert_equal Mime::HTML, @response.content_type

View File

@@ -255,11 +255,6 @@ class MimeControllerTest < ActionController::TestCase
assert_equal "text/html", @response.content_type
assert_equal 'Hello world!', @response.body
@request.accept = "text/javascript"
get :using_defaults
assert_equal "text/javascript", @response.content_type
assert_equal '$("body").visualEffect("highlight");', @response.body
@request.accept = "application/xml"
get :using_defaults
assert_equal "application/xml", @response.content_type
@@ -272,11 +267,6 @@ class MimeControllerTest < ActionController::TestCase
assert_equal "text/html", @response.content_type
assert_equal 'Hello world!', @response.body
@request.accept = "text/javascript"
get :using_defaults_with_type_list
assert_equal "text/javascript", @response.content_type
assert_equal '$("body").visualEffect("highlight");', @response.body
@request.accept = "application/xml"
get :using_defaults_with_type_list
assert_equal "application/xml", @response.content_type
@@ -372,26 +362,12 @@ class MimeControllerTest < ActionController::TestCase
assert_equal 'Whatever you ask for, I got it', @response.body
end
def test_rjs_type_skips_layout
@request.accept = "text/javascript"
get :all_types_with_layout
assert_equal 'RJS for all_types_with_layout', @response.body
end
def test_html_type_with_layout
@request.accept = "text/html"
get :all_types_with_layout
assert_equal '<html><div id="html">HTML for all_types_with_layout</div></html>', @response.body
end
def test_xhr
xhr :get, :js_or_html
assert_equal 'JS', @response.body
xhr :get, :using_defaults
assert_equal '$("body").visualEffect("highlight");', @response.body
end
def test_custom_constant
get :custom_constant_handling, :format => "mobile"
assert_equal "text/x-mobile", @response.content_type

View File

@@ -221,12 +221,6 @@ class TestController < ActionController::Base
render :text => "hello world", :status => 404
end
def render_custom_code_rjs
render :update, :status => 404 do |page|
page.replace :foo, :partial => 'partial'
end
end
def render_text_with_nil
render :text => nil
end
@@ -448,30 +442,6 @@ class TestController < ActionController::Base
render :template => "test/hello_world_from_rxml.builder"
end
module RenderTestHelper
def rjs_helper_method_from_module
page.visual_effect :highlight
end
end
helper RenderTestHelper
helper do
def rjs_helper_method(value)
page.visual_effect :highlight, value
end
end
def enum_rjs_test
render :update do |page|
page.select('.product').each do |value|
page.rjs_helper_method_from_module
page.rjs_helper_method(value)
page.sortable(value, :url => { :action => "order" })
page.draggable(value)
end
end
end
def delete_with_js
@project_id = 4
end
@@ -486,28 +456,6 @@ class TestController < ActionController::Base
render :action => 'delete_with_js'
end
def update_page
render :update do |page|
page.replace_html 'balance', '$37,000,000.00'
page.visual_effect :highlight, 'balance'
end
end
def update_page_with_instance_variables
@money = '$37,000,000.00'
@div_id = 'balance'
render :update do |page|
page.replace_html @div_id, @money
page.visual_effect :highlight, @div_id
end
end
def update_page_with_view_method
render :update do |page|
page.replace_html 'person', pluralize(2, 'person')
end
end
def action_talk_to_layout
# Action template sets variable that's picked up by layout
end
@@ -585,35 +533,10 @@ class TestController < ActionController::Base
render :partial => 'partial.html.erb'
end
def partial_as_rjs
render :update do |page|
page.replace :foo, :partial => 'partial'
end
end
def respond_to_partial_as_rjs
respond_to do |format|
format.js do
render :update do |page|
page.replace :foo, :partial => 'partial'
end
end
end
end
def partial
render :partial => 'partial'
end
def render_alternate_default
# For this test, the method "default_render" is overridden:
@alternate_default_render = lambda do
render :update do |page|
page.replace :foo, :partial => 'partial'
end
end
end
def partial_only_with_layout
render :partial => "partial_only", :layout => true
end
@@ -944,12 +867,6 @@ class RenderTest < ActionController::TestCase
assert_equal 'hello world', @response.body
end
def test_render_custom_code_rjs
get :render_custom_code_rjs
assert_response 404
assert_equal %(Element.replace("foo", "partial html");), @response.body
end
def test_render_text_with_nil
get :render_text_with_nil
assert_response 200
@@ -1023,20 +940,6 @@ class RenderTest < ActionController::TestCase
assert_equal "<test>\n <hello/>\n</test>\n", @response.body
end
def test_enum_rjs_test
ActiveSupport::SecureRandom.stubs(:base64).returns("asdf")
get :enum_rjs_test
body = %{
$$(".product").each(function(value, index) {
new Effect.Highlight(element,{});
new Effect.Highlight(value,{});
Sortable.create(value, {onUpdate:function(){new Ajax.Request('/test/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(value) + '&authenticity_token=' + encodeURIComponent('asdf')})}});
new Draggable(value, {});
});
}.gsub(/^ /, '').strip
assert_equal body, @response.body
end
def test_layout_rendering
get :layout_test
assert_equal "<html>Hello world!</html>", @response.body
@@ -1083,24 +986,6 @@ class RenderTest < ActionController::TestCase
assert_equal "Goodbye, Local David", @response.body
end
def test_render_in_an_rjs_template_should_pick_html_templates_when_available
[:js, "js"].each do |format|
assert_nothing_raised do
get :render_implicit_html_template, :format => format
assert_equal %(document.write("Hello world\\n");), @response.body
end
end
end
def test_explicitly_rendering_an_html_template_with_implicit_html_template_renders_should_be_possible_from_an_rjs_template
[:js, "js"].each do |format|
assert_nothing_raised do
get :render_explicit_html_template, :format => format
assert_equal %(document.write("Hello world\\n");), @response.body
end
end
end
def test_should_implicitly_render_html_template_from_xhr_request
xhr :get, :render_implicit_html_template_from_xhr_request
assert_equal "XHR!\nHello HTML!", @response.body
@@ -1142,26 +1027,6 @@ class RenderTest < ActionController::TestCase
assert_equal "application/atomsvc+xml", @response.content_type
end
def test_render_with_default_from_accept_header
xhr :get, :greeting
assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
end
def test_render_rjs_with_default
get :delete_with_js
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
end
def test_render_rjs_template_explicitly
get :render_js_with_explicit_template
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
end
def test_rendering_rjs_action_explicitly
get :render_js_with_explicit_action_template
assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
end
def test_layout_test_with_different_layout
get :layout_test_with_different_layout
assert_equal "<html>Hello world!</html>", @response.body
@@ -1267,28 +1132,6 @@ class RenderTest < ActionController::TestCase
assert_equal "The secret is area51\n", @response.body
end
def test_update_page
get :update_page
assert_template nil
assert_equal 'text/javascript; charset=utf-8', @response.headers['Content-Type']
assert_equal 2, @response.body.split($/).length
end
def test_update_page_with_instance_variables
get :update_page_with_instance_variables
assert_template nil
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
assert_match /balance/, @response.body
assert_match /\$37/, @response.body
end
def test_update_page_with_view_method
get :update_page_with_view_method
assert_template nil
assert_equal 'text/javascript; charset=utf-8', @response.headers["Content-Type"]
assert_match /2 people/, @response.body
end
def test_yield_content_for
assert_not_deprecated { get :yield_content_for }
assert_equal "<title>Putting stuff in the title!</title>\n\nGreat stuff!\n", @response.body
@@ -1414,26 +1257,11 @@ class RenderTest < ActionController::TestCase
assert_equal 'partial html', @response.body
end
def test_should_render_html_formatted_partial_with_rjs
xhr :get, :partial_as_rjs
assert_equal %(Element.replace("foo", "partial html");), @response.body
end
def test_should_render_html_formatted_partial_with_rjs_and_js_format
xhr :get, :respond_to_partial_as_rjs
assert_equal %(Element.replace("foo", "partial html");), @response.body
end
def test_should_render_js_partial
xhr :get, :partial, :format => 'js'
assert_equal 'partial js', @response.body
end
def test_should_render_with_alternate_default_render
xhr :get, :render_alternate_default
assert_equal %(Element.replace("foo", "partial html");), @response.body
end
def test_partial_only_with_layout
get :partial_only_with_layout
assert_equal "<html>only partial</html>", @response.body

View File

@@ -19,6 +19,14 @@ module RequestForgeryProtectionActions
render :inline => "<% form_remote_tag(:url => '/') {} %>"
end
def external_form_for
render :inline => "<%= form_for(:some_resource, :authenticity_token => 'external_token') {} %>"
end
def form_for_without_token
render :inline => "<%= form_for(:some_resource, :authenticity_token => false ) {} %>"
end
def unsafe
render :text => 'pwn'
end
@@ -156,6 +164,20 @@ module RequestForgeryProtectionTests
assert_nothing_raised { yield }
assert_response :success
end
def test_should_render_form_with_token_tag_with_authenticity_token_requested
assert_not_blocked do
get :external_form_for
end
assert_select 'form>div>input[name=?][value=?]', 'authenticity_token', 'external_token'
end
def test_should_render_form_without_token_tag_with_authenticity_token_set_to_false
assert_not_blocked do
get :form_for_without_token
end
assert_select 'form>div>input[name=?]', 'authenticity_token', false
end
end
# OK let's get our test on

View File

@@ -7,7 +7,7 @@ class CookieStoreTest < ActionController::IntegrationTest
DispatcherApp = ActionController::Dispatcher.new
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, 'SHA1')
Verifier = ActiveSupport::MessageVerifier.new(SessionSecret, digest: 'SHA1')
SignedBar = "BAh7BjoIZm9vIghiYXI%3D--fef868465920f415f2c0652d6910d3af288a0367"

View File

@@ -357,24 +357,6 @@ class UrlWriterTests < ActionController::TestCase
ActionController::Routing::Routes.load!
end
def test_formatted_url_methods_are_deprecated
ActionController::Routing::Routes.draw do |map|
map.resources :posts
end
# We need to create a new class in order to install the new named route.
kls = Class.new { include ActionController::UrlWriter }
controller = kls.new
params = {:id => 1, :format => :xml}
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, params))
end
assert_deprecated do
assert_equal("/posts/1.xml", controller.send(:formatted_post_path, 1, :xml))
end
ensure
ActionController::Routing::Routes.load!
end
def test_multiple_includes_maintain_distinct_options
first_class = Class.new { include ActionController::UrlWriter }
second_class = Class.new { include ActionController::UrlWriter }

View File

@@ -1 +0,0 @@
page.alert 'hello world!'

View File

@@ -1,6 +0,0 @@
page.assign 'title', 'Hey'
cache do
page['element_1'].visual_effect :highlight
page['element_2'].visual_effect :highlight
end
page.assign 'footer', 'Bye'

View File

@@ -1 +0,0 @@
page.replace_html 'notices', :partial => 'partial'

View File

@@ -1 +0,0 @@
page << "RJS for all_types_with_layout"

View File

@@ -1 +0,0 @@
page[:body].visual_effect :highlight

View File

@@ -1 +0,0 @@
page[:body].visual_effect :highlight

View File

@@ -1,2 +0,0 @@
page.remove 'person'
page.visual_effect :highlight, "project-#{@project_id}"

View File

@@ -1,6 +0,0 @@
page.select('.product').each do |value|
page.visual_effect :highlight
page.visual_effect :highlight, value
page.sortable(value, :url => { :action => "order" })
page.draggable(value)
end

View File

@@ -1 +0,0 @@
page[:body].visual_effect :highlight

View File

@@ -1 +0,0 @@
page.call "document.write", render(:partial => "one.html.erb")

View File

@@ -1 +0,0 @@
page.call "document.write", render(:partial => "one")

View File

@@ -1244,28 +1244,6 @@ class FormHelperTest < ActionView::TestCase
end
# Perhaps this test should be moved to prototype helper tests.
def test_remote_form_for_with_labelled_builder
failed_pre_200
self.extend ActionView::Helpers::PrototypeHelper
remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
expected =
%(<form action="http://www.example.com" onsubmit="new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" method="post">) +
"<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
"<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
"<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
"</form>"
assert_dom_equal expected, output_buffer
end
def test_fields_for_with_labelled_builder
fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
concat f.text_field(:title)
@@ -1412,17 +1390,6 @@ class FormHelperTest < ActionView::TestCase
assert_equal expected, output_buffer
end
def test_remote_form_for_with_html_options_adds_options_to_form_tag
failed_pre_200
self.extend ActionView::Helpers::PrototypeHelper
remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" onsubmit=\"new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"></form>"
assert_dom_equal expected, output_buffer
end
protected
def comments_path(post)
"/posts/#{post.id}/comments"

View File

@@ -16,74 +16,6 @@ class JavaScriptHelperTest < ActionView::TestCase
assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags))
end
def test_link_to_function
failed_pre_200
assert_dom_equal %(<a href="#" onclick="alert('Hello world!'); return false;">Greeting</a>),
link_to_function("Greeting", "alert('Hello world!')")
end
def test_link_to_function_with_existing_onclick
failed_pre_200
assert_dom_equal %(<a href="#" onclick="confirm('Sanity!'); alert('Hello world!'); return false;">Greeting</a>),
link_to_function("Greeting", "alert('Hello world!')", :onclick => "confirm('Sanity!')")
end
def test_link_to_function_with_rjs_block
html = link_to_function( "Greet me!" ) do |page|
page.replace_html 'header', "<h1>Greetings</h1>"
end
assert_dom_equal %(<a href="#" onclick="Element.update(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);; return false;">Greet me!</a>), html
end
def test_link_to_function_with_rjs_block_and_options
html = link_to_function( "Greet me!", :class => "updater" ) do |page|
page.replace_html 'header', "<h1>Greetings</h1>"
end
assert_dom_equal %(<a href="#" class="updater" onclick="Element.update(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);; return false;">Greet me!</a>), html
end
def test_link_to_function_with_href
failed_pre_200
assert_dom_equal %(<a href="http://example.com/" onclick="alert('Hello world!'); return false;">Greeting</a>),
link_to_function("Greeting", "alert('Hello world!')", :href => 'http://example.com/')
end
def test_button_to_function
failed_pre_200
assert_dom_equal %(<input type="button" onclick="alert('Hello world!');" value="Greeting" />),
button_to_function("Greeting", "alert('Hello world!')")
end
def test_button_to_function_with_rjs_block
html = button_to_function( "Greet me!" ) do |page|
page.replace_html 'header', "<h1>Greetings</h1>"
end
assert_dom_equal %(<input type="button" onclick="Element.update(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C/h1\\u003E&quot;);;" value="Greet me!" />), html
end
def test_button_to_function_with_rjs_block_and_options
html = button_to_function( "Greet me!", :class => "greeter" ) do |page|
page.replace_html 'header', "<h1>Greetings</h1>"
end
assert_dom_equal %(<input type="button" class="greeter" onclick="Element.update(&quot;header&quot;, &quot;\\u003Ch1\\u003EGreetings\\u003C\/h1\\u003E&quot;);;" value="Greet me!" />), html
end
def test_button_to_function_with_onclick
failed_pre_200
assert_dom_equal "<input onclick=\"alert('Goodbye World :('); alert('Hello world!');\" type=\"button\" value=\"Greeting\" />",
button_to_function("Greeting", "alert('Hello world!')", :onclick => "alert('Goodbye World :(')")
end
def test_button_to_function_without_function
assert_dom_equal "<input onclick=\";\" type=\"button\" value=\"Greeting\" />",
button_to_function("Greeting")
end
def test_javascript_tag
self.output_buffer = 'foo'

View File

@@ -1,666 +0,0 @@
require 'abstract_unit'
Bunny = Struct.new(:Bunny, :id)
class Author
attr_reader :id
def save; @id = 1 end
def new_record?; @id.nil? end
def name
@id.nil? ? 'new author' : "author ##{@id}"
end
end
class Article
attr_reader :id
attr_reader :author_id
def save; @id = 1; @author_id = 1 end
def new_record?; @id.nil? end
def name
@id.nil? ? 'new article' : "article ##{@id}"
end
end
class Author::Nested < Author; end
class PrototypeHelperBaseTest < ActionView::TestCase
attr_accessor :template_format, :output_buffer
def setup
@template = self
@controller = Class.new do
def url_for(options)
if options.is_a?(String)
options
else
url = "http://www.example.com/"
url << options[:action].to_s if options and options[:action]
url << "?a=#{options[:a]}" if options && options[:a]
url << "&b=#{options[:b]}" if options && options[:a] && options[:b]
url
end
end
end.new
end
protected
def request_forgery_protection_token
nil
end
def protect_against_forgery?
false
end
def create_generator
block = Proc.new { |*args| yield *args if block_given? }
JavaScriptGenerator.new self, &block
end
end
class PrototypeHelperTest < PrototypeHelperBaseTest
def setup
@record = @author = Author.new
@article = Article.new
super
end
def test_link_to_remote
failed_pre_200
assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }}, { :class => "fine" })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :complete => "alert(request.responseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :success => "alert(request.responseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&amp;b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.responseText)}}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :failure => "alert(request.responseText)", :url => { :action => "whatnot", :a => '10', :b => '20' })
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:false, evalScripts:true}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :type => :synchronous)
assert_dom_equal %(<a href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, insertion:'bottom'}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", :url => { :action => "whatnot" }, :position => :bottom)
end
def test_link_to_remote_html_options
failed_pre_200
assert_dom_equal %(<a class=\"fine\" href=\"#\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true}); return false;\">Remote outauthor</a>),
link_to_remote("Remote outauthor", { :url => { :action => "whatnot" }, :html => { :class => "fine" } })
end
def test_link_to_remote_url_quote_escaping
failed_pre_200
assert_dom_equal %(<a href="#" onclick="new Ajax.Request('http://www.example.com/whatnot\\\'s', {asynchronous:true, evalScripts:true}); return false;">Remote</a>),
link_to_remote("Remote", { :url => { :action => "whatnot's" } })
end
def test_button_to_remote
failed_pre_200
assert_dom_equal %(<input class=\"fine\" type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true});\" />),
button_to_remote("Remote outpost", { :url => { :action => "whatnot" }}, { :class => "fine" })
assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onComplete:function(request){alert(request.reponseText)}});\" />),
button_to_remote("Remote outpost", :complete => "alert(request.reponseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onSuccess:function(request){alert(request.reponseText)}});\" />),
button_to_remote("Remote outpost", :success => "alert(request.reponseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}});\" />),
button_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot" })
assert_dom_equal %(<input type=\"button\" value=\"Remote outpost\" onclick=\"new Ajax.Request('http://www.example.com/whatnot?a=10&amp;b=20', {asynchronous:true, evalScripts:true, onFailure:function(request){alert(request.reponseText)}});\" />),
button_to_remote("Remote outpost", :failure => "alert(request.reponseText)", :url => { :action => "whatnot", :a => '10', :b => '20' })
end
def test_periodically_call_remote
assert_dom_equal %(<script type="text/javascript">\n//<![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Updater('schremser_bier', 'http://www.example.com/mehr_bier', {asynchronous:true, evalScripts:true})}, 10)\n//]]>\n</script>),
periodically_call_remote(:update => "schremser_bier", :url => { :action => "mehr_bier" })
end
def test_periodically_call_remote_with_frequency
assert_dom_equal(
"<script type=\"text/javascript\">\n//<![CDATA[\nnew PeriodicalExecuter(function() {new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true})}, 2)\n//]]>\n</script>",
periodically_call_remote(:frequency => 2)
)
end
def test_form_remote_tag
failed_pre_200
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast })
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast })
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
form_remote_tag(:update => { :failure => "glass_of_water" }, :url => { :action => :fast })
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">),
form_remote_tag(:update => { :success => 'glass_of_beer', :failure => "glass_of_water" }, :url => { :action => :fast })
end
def test_form_remote_tag_with_method
failed_pre_200
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :html => { :method => :put })
end
def test_form_remote_tag_with_block_in_erb
failed_pre_200
__in_erb_template = ''
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }) { concat "Hello world!" }
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\">Hello world!</form>), output_buffer
end
def test_remote_form_for_with_record_identification_with_new_record
failed_pre_200
remote_form_for(@record, {:html => { :id => 'create-author' }}) {}
expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' id='create-author' method='post'></form>)
assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_record_identification_without_html_options
failed_pre_200
remote_form_for(@record) {}
expected = %(<form action='#{authors_path}' onsubmit="new Ajax.Request('#{authors_path}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_author' method='post' id='new_author'></form>)
assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_record_identification_with_existing_record
failed_pre_200
@record.save
remote_form_for(@record) {}
expected = %(<form action='#{author_path(@record)}' id='edit_author_1' method='post' onsubmit="new Ajax.Request('#{author_path(@record)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_author'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div></form>)
assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_new_object_in_list
failed_pre_200
remote_form_for([@author, @article]) {}
expected = %(<form action='#{author_articles_path(@author)}' onsubmit="new Ajax.Request('#{author_articles_path(@author)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='new_article' method='post' id='new_article'></form>)
assert_dom_equal expected, output_buffer
end
def test_remote_form_for_with_existing_object_in_list
failed_pre_200
@author.save
@article.save
remote_form_for([@author, @article]) {}
expected = %(<form action='#{author_article_path(@author, @article)}' id='edit_article_1' method='post' onsubmit="new Ajax.Request('#{author_article_path(@author, @article)}', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" class='edit_article'><div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div></form>)
assert_dom_equal expected, output_buffer
end
def test_on_callbacks
failed_pre_200
callbacks = [:uninitialized, :loading, :loaded, :interactive, :complete, :success, :failure]
callbacks.each do |callback|
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => { :success => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();")
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({failure:'glass_of_beer'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => { :failure => "glass_of_beer" }, :url => { :action => :fast }, callback=>"monkeys();")
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater({success:'glass_of_beer',failure:'glass_of_water'}, 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => { :success => "glass_of_beer", :failure => "glass_of_water" }, :url => { :action => :fast }, callback=>"monkeys();")
end
#HTTP status codes 200 up to 599 have callbacks
#these should work
100.upto(599) do |callback|
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on#{callback.to_s.capitalize}:function(request){monkeys();}, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
end
#test 200 and 404
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, 200=>"monkeys();", 404=>"bananas();")
#these shouldn't
1.upto(99) do |callback|
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
end
600.upto(999) do |callback|
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, callback=>"monkeys();")
end
#test ultimate combo
assert_dom_equal %(<form action=\"http://www.example.com/fast\" method=\"post\" onsubmit=\"new Ajax.Updater('glass_of_beer', 'http://www.example.com/fast', {asynchronous:true, evalScripts:true, on200:function(request){monkeys();}, on404:function(request){bananas();}, onComplete:function(request){c();}, onFailure:function(request){f();}, onLoading:function(request){c1()}, onSuccess:function(request){s()}, parameters:Form.serialize(this)}); return false;\">),
form_remote_tag(:update => "glass_of_beer", :url => { :action => :fast }, :loading => "c1()", :success => "s()", :failure => "f();", :complete => "c();", 200=>"monkeys();", 404=>"bananas();")
end
def test_submit_to_remote
failed_pre_200
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
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/reorder_if_empty', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>),
observe_field("glass", :frequency => 5.minutes, :url => { :action => "reorder_if_empty" })
end
def test_observe_field_using_with_option
expected = %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/check_value', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(value)})})\n//]]>\n</script>)
assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => 'id')
assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "'id=' + encodeURIComponent(value)")
end
def test_observe_field_using_json_in_with_option
expected = %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {new Ajax.Request('http://www.example.com/check_value', {asynchronous:true, evalScripts:true, parameters:{'id':value}})})\n//]]>\n</script>)
assert_dom_equal expected, observe_field("glass", :frequency => 5.minutes, :url => { :action => "check_value" }, :with => "{'id':value}")
end
def test_observe_field_using_function_for_callback
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.Observer('glass', 300, function(element, value) {alert('Element changed')})\n//]]>\n</script>),
observe_field("glass", :frequency => 5.minutes, :function => "alert('Element changed')")
end
def test_observe_form
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {new Ajax.Request('http://www.example.com/cart_changed', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>),
observe_form("cart", :frequency => 2, :url => { :action => "cart_changed" })
end
def test_observe_form_using_function_for_callback
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Observer('cart', 2, function(element, value) {alert('Form changed')})\n//]]>\n</script>),
observe_form("cart", :frequency => 2, :function => "alert('Form changed')")
end
def test_observe_field_without_frequency
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Form.Element.EventObserver('glass', function(element, value) {new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:value})})\n//]]>\n</script>),
observe_field("glass")
end
def test_update_page
old_output_buffer = output_buffer
block = Proc.new { |page| page.replace_html('foo', 'bar') }
assert_equal create_generator(&block).to_s, update_page(&block)
assert_equal old_output_buffer, output_buffer
end
def test_update_page_tag
block = Proc.new { |page| page.replace_html('foo', 'bar') }
assert_equal javascript_tag(create_generator(&block).to_s), update_page_tag(&block)
end
def test_update_page_tag_with_html_options
block = Proc.new { |page| page.replace_html('foo', 'bar') }
assert_equal javascript_tag(create_generator(&block).to_s, {:defer => 'true'}), update_page_tag({:defer => 'true'}, &block)
end
protected
def author_path(record)
"/authors/#{record.id}"
end
def authors_path
"/authors"
end
def author_articles_path(author)
"/authors/#{author.id}/articles"
end
def author_article_path(author, article)
"/authors/#{author.id}/articles/#{article.id}"
end
end
class JavaScriptGeneratorTest < PrototypeHelperBaseTest
def setup
super
@generator = create_generator
end
def test_insert_html_with_string
assert_equal 'Element.insert("element", { top: "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E" });',
@generator.insert_html(:top, 'element', '<p>This is a test</p>')
assert_equal 'Element.insert("element", { bottom: "\\u003Cp\u003EThis is a test\\u003C/p\u003E" });',
@generator.insert_html(:bottom, 'element', '<p>This is a test</p>')
assert_equal 'Element.insert("element", { before: "\\u003Cp\u003EThis is a test\\u003C/p\u003E" });',
@generator.insert_html(:before, 'element', '<p>This is a test</p>')
assert_equal 'Element.insert("element", { after: "\\u003Cp\u003EThis is a test\\u003C/p\u003E" });',
@generator.insert_html(:after, 'element', '<p>This is a test</p>')
end
def test_replace_html_with_string
assert_equal 'Element.update("element", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");',
@generator.replace_html('element', '<p>This is a test</p>')
end
def test_replace_element_with_string
assert_equal 'Element.replace("element", "\\u003Cdiv id=\"element\"\\u003E\\u003Cp\\u003EThis is a test\\u003C/p\\u003E\\u003C/div\\u003E");',
@generator.replace('element', '<div id="element"><p>This is a test</p></div>')
end
def test_remove
assert_equal 'Element.remove("foo");',
@generator.remove('foo')
assert_equal '["foo","bar","baz"].each(Element.remove);',
@generator.remove('foo', 'bar', 'baz')
end
def test_show
assert_equal 'Element.show("foo");',
@generator.show('foo')
assert_equal '["foo","bar","baz"].each(Element.show);',
@generator.show('foo', 'bar', 'baz')
end
def test_hide
assert_equal 'Element.hide("foo");',
@generator.hide('foo')
assert_equal '["foo","bar","baz"].each(Element.hide);',
@generator.hide('foo', 'bar', 'baz')
end
def test_toggle
assert_equal 'Element.toggle("foo");',
@generator.toggle('foo')
assert_equal '["foo","bar","baz"].each(Element.toggle);',
@generator.toggle('foo', 'bar', 'baz')
end
def test_alert
assert_equal 'alert("hello");', @generator.alert('hello')
end
def test_redirect_to
assert_equal 'window.location.href = "http://www.example.com/welcome";',
@generator.redirect_to(:action => 'welcome')
assert_equal 'window.location.href = "http://www.example.com/welcome?a=b&c=d";',
@generator.redirect_to("http://www.example.com/welcome?a=b&c=d")
end
def test_reload
assert_equal 'window.location.reload();',
@generator.reload
end
def test_delay
@generator.delay(20) do
@generator.hide('foo')
end
assert_equal "setTimeout(function() {\n;\nElement.hide(\"foo\");\n}, 20000);", @generator.to_s
end
def test_to_s
@generator.insert_html(:top, 'element', '<p>This is a test</p>')
@generator.insert_html(:bottom, 'element', '<p>This is a test</p>')
@generator.remove('foo', 'bar')
@generator.replace_html('baz', '<p>This is a test</p>')
assert_equal <<-EOS.chomp, @generator.to_s
Element.insert("element", { top: "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E" });
Element.insert("element", { bottom: "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E" });
["foo","bar"].each(Element.remove);
Element.update("baz", "\\u003Cp\\u003EThis is a test\\u003C/p\\u003E");
EOS
end
def test_element_access
assert_equal %($("hello");), @generator['hello']
end
def test_element_access_on_records
assert_equal %($("bunny_5");), @generator[Bunny.new(:id => 5)]
assert_equal %($("new_bunny");), @generator[Bunny.new]
end
def test_element_proxy_one_deep
@generator['hello'].hide
assert_equal %($("hello").hide();), @generator.to_s
end
def test_element_proxy_variable_access
@generator['hello']['style']
assert_equal %($("hello").style;), @generator.to_s
end
def test_element_proxy_variable_access_with_assignment
@generator['hello']['style']['color'] = 'red'
assert_equal %($("hello").style.color = "red";), @generator.to_s
end
def test_element_proxy_assignment
@generator['hello'].width = 400
assert_equal %($("hello").width = 400;), @generator.to_s
end
def test_element_proxy_two_deep
@generator['hello'].hide("first").clean_whitespace
assert_equal %($("hello").hide("first").cleanWhitespace();), @generator.to_s
end
def test_select_access
assert_equal %($$("div.hello");), @generator.select('div.hello')
end
def test_select_proxy_one_deep
@generator.select('p.welcome b').first.hide
assert_equal %($$("p.welcome b").first().hide();), @generator.to_s
end
def test_visual_effect
assert_equal %(new Effect.Puff("blah",{});),
@generator.visual_effect(:puff,'blah')
end
def test_visual_effect_toggle
assert_equal %(Effect.toggle("blah",'appear',{});),
@generator.visual_effect(:toggle_appear,'blah')
end
def test_sortable
assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize("blah")})}});),
@generator.sortable('blah', :url => { :action => "order" })
assert_equal %(Sortable.create("blah", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:false, evalScripts:true, parameters:Sortable.serialize("blah")})}});),
@generator.sortable('blah', :url => { :action => "order" }, :type => :synchronous)
end
def test_draggable
assert_equal %(new Draggable("blah", {});),
@generator.draggable('blah')
end
def test_drop_receiving
assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});),
@generator.drop_receiving('blah', :url => { :action => "order" })
assert_equal %(Droppables.add("blah", {onDrop:function(element){new Ajax.Request('http://www.example.com/order', {asynchronous:false, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}});),
@generator.drop_receiving('blah', :url => { :action => "order" }, :type => :synchronous)
end
def test_collection_first_and_last
@generator.select('p.welcome b').first.hide()
@generator.select('p.welcome b').last.show()
assert_equal <<-EOS.strip, @generator.to_s
$$("p.welcome b").first().hide();
$$("p.welcome b").last().show();
EOS
end
def test_collection_proxy_with_each
@generator.select('p.welcome b').each do |value|
value.remove_class_name 'selected'
end
@generator.select('p.welcome b').each do |value, index|
@generator.visual_effect :highlight, value
end
assert_equal <<-EOS.strip, @generator.to_s
$$("p.welcome b").each(function(value, index) {
value.removeClassName("selected");
});
$$("p.welcome b").each(function(value, index) {
new Effect.Highlight(value,{});
});
EOS
end
def test_collection_proxy_on_collect
@generator.select('p').collect('a') { |para| para.show }
@generator.select('p').collect { |para| para.hide }
assert_equal <<-EOS.strip, @generator.to_s
var a = $$("p").collect(function(value, index) {
return value.show();
});
$$("p").collect(function(value, index) {
return value.hide();
});
EOS
@generator = create_generator
end
def test_collection_proxy_with_grep
@generator.select('p').grep 'a', /^a/ do |value|
@generator << '(value.className == "welcome")'
end
@generator.select('p').grep 'b', /b$/ do |value, index|
@generator.call 'alert', value
@generator << '(value.className == "welcome")'
end
assert_equal <<-EOS.strip, @generator.to_s
var a = $$("p").grep(/^a/, function(value, index) {
return (value.className == "welcome");
});
var b = $$("p").grep(/b$/, function(value, index) {
alert(value);
return (value.className == "welcome");
});
EOS
end
def test_collection_proxy_with_inject
@generator.select('p').inject 'a', [] do |memo, value|
@generator << '(value.className == "welcome")'
end
@generator.select('p').inject 'b', nil do |memo, value, index|
@generator.call 'alert', memo
@generator << '(value.className == "welcome")'
end
assert_equal <<-EOS.strip, @generator.to_s
var a = $$("p").inject([], function(memo, value, index) {
return (value.className == "welcome");
});
var b = $$("p").inject(null, function(memo, value, index) {
alert(memo);
return (value.className == "welcome");
});
EOS
end
def test_collection_proxy_with_pluck
@generator.select('p').pluck('a', 'className')
assert_equal %(var a = $$("p").pluck("className");), @generator.to_s
end
def test_collection_proxy_with_zip
ActionView::Helpers::JavaScriptCollectionProxy.new(@generator, '[1, 2, 3]').zip('a', [4, 5, 6], [7, 8, 9])
ActionView::Helpers::JavaScriptCollectionProxy.new(@generator, '[1, 2, 3]').zip('b', [4, 5, 6], [7, 8, 9]) do |array|
@generator.call 'array.reverse'
end
assert_equal <<-EOS.strip, @generator.to_s
var a = [1, 2, 3].zip([4,5,6], [7,8,9]);
var b = [1, 2, 3].zip([4,5,6], [7,8,9], function(array) {
return array.reverse();
});
EOS
end
def test_collection_proxy_with_find_all
@generator.select('p').find_all 'a' do |value, index|
@generator << '(value.className == "welcome")'
end
assert_equal <<-EOS.strip, @generator.to_s
var a = $$("p").findAll(function(value, index) {
return (value.className == "welcome");
});
EOS
end
def test_collection_proxy_with_in_groups_of
@generator.select('p').in_groups_of('a', 3)
@generator.select('p').in_groups_of('a', 3, 'x')
assert_equal <<-EOS.strip, @generator.to_s
var a = $$("p").inGroupsOf(3);
var a = $$("p").inGroupsOf(3, "x");
EOS
end
def test_collection_proxy_with_each_slice
@generator.select('p').each_slice('a', 3)
@generator.select('p').each_slice('a', 3) do |group, index|
group.reverse
end
assert_equal <<-EOS.strip, @generator.to_s
var a = $$("p").eachSlice(3);
var a = $$("p").eachSlice(3, function(value, index) {
return value.reverse();
});
EOS
end
def test_debug_rjs
ActionView::Base.debug_rjs = true
@generator['welcome'].replace_html 'Welcome'
assert_equal "try {\n$(\"welcome\").update(\"Welcome\");\n} catch (e) { alert('RJS error:\\n\\n' + e.toString()); alert('$(\\\"welcome\\\").update(\\\"Welcome\\\");'); throw e }", @generator.to_s
ensure
ActionView::Base.debug_rjs = false
end
def test_literal
literal = @generator.literal("function() {}")
assert_equal "function() {}", ActiveSupport::JSON.encode(literal)
assert_equal "", @generator.to_s
end
def test_class_proxy
@generator.form.focus('my_field')
assert_equal "Form.focus(\"my_field\");", @generator.to_s
end
def test_call_with_block
@generator.call(:before)
@generator.call(:my_method) do |p|
p[:one].show
p[:two].hide
end
@generator.call(:in_between)
@generator.call(:my_method_with_arguments, true, "hello") do |p|
p[:three].visual_effect(:highlight)
end
assert_equal "before();\nmy_method(function() { $(\"one\").show();\n$(\"two\").hide(); });\nin_between();\nmy_method_with_arguments(true, \"hello\", function() { $(\"three\").visualEffect(\"highlight\"); });", @generator.to_s
end
def test_class_proxy_call_with_block
@generator.my_object.my_method do |p|
p[:one].show
p[:two].hide
end
assert_equal "MyObject.myMethod(function() { $(\"one\").show();\n$(\"two\").hide(); });", @generator.to_s
end
end

View File

@@ -89,12 +89,6 @@ module RenderTestCases
assert_equal "test/template.erb", @view.render(:file => "test/template.erb")
end
def test_render_update
# TODO: You should not have to stub out template because template is self!
@view.instance_variable_set(:@template, @view)
assert_equal 'alert("Hello, World!");', @view.render(:update) { |page| page.alert('Hello, World!') }
end
def test_render_partial_from_default
assert_equal "only partial", @view.render("test/partial_only")
end

View File

@@ -1,90 +0,0 @@
require 'abstract_unit'
class ScriptaculousHelperTest < ActionView::TestCase
tests ActionView::Helpers::ScriptaculousHelper
def setup
@controller = Class.new do
def url_for(options)
url = "http://www.example.com/"
url << options[:action].to_s if options and options[:action]
url
end
end.new
end
def test_effect
assert_equal "new Effect.Highlight(\"posts\",{});", visual_effect(:highlight, "posts")
assert_equal "new Effect.Highlight(\"posts\",{});", visual_effect("highlight", :posts)
assert_equal "new Effect.Highlight(\"posts\",{});", visual_effect(:highlight, :posts)
assert_equal "new Effect.Fade(\"fademe\",{duration:4.0});", visual_effect(:fade, "fademe", :duration => 4.0)
assert_equal "new Effect.Shake(element,{});", visual_effect(:shake)
assert_equal "new Effect.DropOut(\"dropme\",{queue:'end'});", visual_effect(:drop_out, 'dropme', :queue => :end)
assert_equal "new Effect.Highlight(\"status\",{endcolor:'#EEEEEE'});", visual_effect(:highlight, 'status', :endcolor => '#EEEEEE')
assert_equal "new Effect.Highlight(\"status\",{restorecolor:'#500000', startcolor:'#FEFEFE'});", visual_effect(:highlight, 'status', :restorecolor => '#500000', :startcolor => '#FEFEFE')
# chop the queue params into a comma separated list
beginning, ending = 'new Effect.DropOut("dropme",{queue:{', '}});'
ve = [
visual_effect(:drop_out, 'dropme', :queue => {:position => "end", :scope => "test", :limit => 2}),
visual_effect(:drop_out, 'dropme', :queue => {:scope => :list, :limit => 2}),
visual_effect(:drop_out, 'dropme', :queue => {:position => :end, :scope => :test, :limit => 2})
].collect { |v| v[beginning.length..-ending.length-1].split(',') }
assert ve[0].include?("limit:2")
assert ve[0].include?("scope:'test'")
assert ve[0].include?("position:'end'")
assert ve[1].include?("limit:2")
assert ve[1].include?("scope:'list'")
assert ve[2].include?("limit:2")
assert ve[2].include?("scope:'test'")
assert ve[2].include?("position:'end'")
end
def test_toggle_effects
assert_equal "Effect.toggle(\"posts\",'appear',{});", visual_effect(:toggle_appear, "posts")
assert_equal "Effect.toggle(\"posts\",'slide',{});", visual_effect(:toggle_slide, "posts")
assert_equal "Effect.toggle(\"posts\",'blind',{});", visual_effect(:toggle_blind, "posts")
assert_equal "Effect.toggle(\"posts\",'appear',{});", visual_effect("toggle_appear", "posts")
assert_equal "Effect.toggle(\"posts\",'slide',{});", visual_effect("toggle_slide", "posts")
assert_equal "Effect.toggle(\"posts\",'blind',{});", visual_effect("toggle_blind", "posts")
end
def test_sortable_element
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create(\"mylist\", {onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(\"mylist\")})}})\n//]]>\n</script>),
sortable_element("mylist", :url => { :action => "order" })
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create(\"mylist\", {constraint:'horizontal', onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(\"mylist\")})}, tag:'div'})\n//]]>\n</script>),
sortable_element("mylist", :tag => "div", :constraint => "horizontal", :url => { :action => "order" })
assert_dom_equal %|<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create(\"mylist\", {constraint:'horizontal', containment:['list1','list2'], onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(\"mylist\")})}})\n//]]>\n</script>|,
sortable_element("mylist", :containment => ['list1','list2'], :constraint => "horizontal", :url => { :action => "order" })
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nSortable.create(\"mylist\", {constraint:'horizontal', containment:'list1', onUpdate:function(){new Ajax.Request('http://www.example.com/order', {asynchronous:true, evalScripts:true, parameters:Sortable.serialize(\"mylist\")})}})\n//]]>\n</script>),
sortable_element("mylist", :containment => 'list1', :constraint => "horizontal", :url => { :action => "order" })
end
def test_draggable_element
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Draggable(\"product_13\", {})\n//]]>\n</script>),
draggable_element("product_13")
assert_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nnew Draggable(\"product_13\", {revert:true})\n//]]>\n</script>),
draggable_element("product_13", :revert => true)
end
def test_drop_receiving_element
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add(\"droptarget1\", {onDrop:function(element){new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
drop_receiving_element("droptarget1")
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add(\"droptarget1\", {accept:'products', onDrop:function(element){new Ajax.Request('http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
drop_receiving_element("droptarget1", :accept => 'products')
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add(\"droptarget1\", {accept:'products', onDrop:function(element){new Ajax.Updater('infobox', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
drop_receiving_element("droptarget1", :accept => 'products', :update => 'infobox')
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add(\"droptarget1\", {accept:['tshirts','mugs'], onDrop:function(element){new Ajax.Updater('infobox', 'http://www.example.com/', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)})}})\n//]]>\n</script>),
drop_receiving_element("droptarget1", :accept => ['tshirts','mugs'], :update => 'infobox')
assert_dom_equal %(<script type=\"text/javascript\">\n//<![CDATA[\nDroppables.add("droptarget1", {hoverclass:'dropready', onDrop:function(element){if (confirm('Are you sure?')) { new Ajax.Request('http://www.example.com/update_drop', {asynchronous:true, evalScripts:true, parameters:'id=' + encodeURIComponent(element.id)}); }}})\n//]]>\n</script>),
drop_receiving_element('droptarget1', :hoverclass=>'dropready', :url=>{:action=>'update_drop'}, :confirm => 'Are you sure?')
end
def protect_against_forgery?
false
end
end

View File

@@ -64,7 +64,6 @@ for adapter in %w( mysql postgresql sqlite sqlite3 firebird db2 oracle sybase op
end
adapter_short = adapter == 'db2' ? adapter : adapter[/^[a-z]+/]
t.test_files=Dir.glob( "test/cases/**/*_test{,_#{adapter_short}}.rb" ).sort
t.verbose = true
}
namespace adapter do

View File

@@ -0,0 +1,17 @@
Gem::Specification.new do |s|
s.name = 'activerecord'
s.version = '2.3.18'
s.summary = 'Implements the ActiveRecord pattern for ORM.'
s.description = 'Implements the ActiveRecord pattern (Fowler, PoEAA) for ORM. It ties database tables and classes together for business objects, like Customer or Subscription, that can find, save, and destroy themselves without resorting to manual SQL.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['README']
s.rdoc_options = ['--main', 'README']
s.extra_rdoc_files = ['README']
s.add_dependency 'activesupport', '= 2.3.18'
end

View File

@@ -2920,15 +2920,23 @@ module ActiveRecord #:nodoc:
attributes.each do |k, v|
if k.to_s.include?("(")
multiparameter_attributes << [ k, v ]
elsif RUBY_VERSION == "1.9.3"
respond_to?(:"#{k}=") ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
else
(respond_to?(:"#{k}=", true) && !method(:"#{k}=").private?) ? send(:"#{k}=", v) : raise(UnknownAttributeError, "unknown attribute: #{k}")
_assign_attribute(k, v)
end
end
assign_multiparameter_attributes(multiparameter_attributes) unless multiparameter_attributes.empty?
end
def _assign_attribute(k, v)
public_send("#{k}=", v)
rescue NoMethodError => e
if respond_to?("#{k}=")
raise e
else
raise UnknownAttributeError, "unknown attribute: #{k}"
end
end
def create_or_update
raise ReadOnlyRecord if readonly?

View File

@@ -261,7 +261,7 @@ module ActiveRecord
key_records = key_records.inject({}) { |hsh, r| hsh.merge(r.id => r) }
end
calculated_data.inject(ActiveSupport::OrderedHash.new) do |all, row|
calculated_data.inject({}) do |all, row|
key = group_aliases.map{|group_alias| type_cast_calculated_value(row[group_alias], group_columns[group_alias])}
key = key.first if key.size == 1
key = key_records[key] if associated

View File

@@ -295,7 +295,7 @@ module ActiveRecord
# Removes all errors that have been added.
def clear
@errors = ActiveSupport::OrderedHash.new
@errors = {}
end
# Returns the total number of errors added. Two errors added to the same attribute will be counted as such.

View File

@@ -552,7 +552,7 @@ module NestedAttributesOnACollectionAssociationTests
end
def test_should_sort_the_hash_by_the_keys_before_building_new_associated_models
attributes = ActiveSupport::OrderedHash.new
attributes = {}
attributes['123726353'] = { :name => 'Grace OMalley' }
attributes['2'] = { :name => 'Privateers Greed' } # 2 is lower then 123726353
@pirate.send(association_setter, attributes)
@@ -562,7 +562,6 @@ module NestedAttributesOnACollectionAssociationTests
def test_should_raise_an_argument_error_if_something_else_than_a_hash_is_passed
assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, {}) }
assert_nothing_raised(ArgumentError) { @pirate.send(association_setter, ActiveSupport::OrderedHash.new) }
assert_raise_with_message ArgumentError, 'Hash or Array expected, got String ("foo")' do
@pirate.send(association_setter, "foo")

View File

@@ -31,8 +31,6 @@ Rake::TestTask.new { |t|
t.libs << activesupport_path if File.directory?(activesupport_path)
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = true
}

View File

@@ -0,0 +1,17 @@
Gem::Specification.new do |s|
s.name = 'activeresource'
s.version = '2.3.18'
s.summary = 'Think Active Record for web resources.'
s.description = 'Wraps web resources in model classes that can be manipulated through XML over REST.'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['README']
s.rdoc_options = ['--main', 'README']
s.extra_rdoc_files = ['README']
s.add_dependency 'activesupport', '= 2.3.18'
end

View File

@@ -18,8 +18,6 @@ task :default => :test
Rake::TestTask.new { |t|
t.libs << "test"
t.pattern = 'test/**/*_test.rb'
t.verbose = true
t.warning = true
}
# Create compressed packages

View File

@@ -0,0 +1,12 @@
Gem::Specification.new do |s|
s.name = 'activesupport'
s.version = '2.3.18'
s.summary = 'Support and utility classes used by the Rails framework.'
s.description = 'Utility library which carries commonly used classes and goodies from the Rails framework'
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
end

View File

@@ -1,40 +1,6 @@
require 'active_support/ordered_hash'
module Enumerable
# Ruby 1.8.7 introduces group_by, but the result isn't ordered. Override it.
remove_method(:group_by) if [].respond_to?(:group_by) && RUBY_VERSION < '1.9'
# Collect an enumerable into sets, grouped by the result of a block. Useful,
# for example, for grouping records by date.
#
# Example:
#
# latest_transcripts.group_by(&:day).each do |day, transcripts|
# p "#{day} -> #{transcripts.map(&:class).join(', ')}"
# end
# "2006-03-01 -> Transcript"
# "2006-02-28 -> Transcript"
# "2006-02-27 -> Transcript, Transcript"
# "2006-02-26 -> Transcript, Transcript"
# "2006-02-25 -> Transcript"
# "2006-02-24 -> Transcript, Transcript"
# "2006-02-23 -> Transcript"
def group_by
assoc = ActiveSupport::OrderedHash.new
each do |element|
key = yield(element)
if assoc.has_key?(key)
assoc[key] << element
else
assoc[key] = [element]
end
end
assoc
end unless [].respond_to?(:group_by)
# Calculates a sum from the elements. Examples:
#
# payments.sum { |p| p.price * p.tax_rate }
@@ -62,26 +28,6 @@ module Enumerable
end
end
# Iterates over a collection, passing the current element *and* the
# +memo+ to the block. Handy for building up hashes or
# reducing collections down to one object. Examples:
#
# %w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } #=> {'foo' => 'FOO', 'bar' => 'BAR'}
#
# *Note* that you can't use immutable objects like numbers, true or false as
# the memo. You would think the following returns 120, but since the memo is
# never changed, it does not.
#
# (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
#
def each_with_object(memo, &block)
memo.tap do |m|
each do |element|
block.call(element, m)
end
end
end unless [].respond_to?(:each_with_object)
# Convert an enumerable to a hash. Examples:
#
# people.index_by(&:login)
@@ -103,15 +49,6 @@ module Enumerable
size > 1
end
# Returns true if none of the elements match the given block.
#
# success = responses.none? {|r| r.status / 100 == 5 }
#
# This is a builtin method in Ruby 1.8.7 and later.
def none?(&block)
!any?(&block)
end unless [].respond_to?(:none?)
# The negative of the Enumerable#include?. Returns true if the collection does not include the object.
def exclude?(object)

View File

@@ -1,79 +1,74 @@
require 'active_support/base64'
require 'active_support/deprecation'
require 'active_support/core_ext/object/blank'
module ActiveSupport
# MessageVerifier makes it easy to generate and verify messages which are signed
# +MessageVerifier+ makes it easy to generate and verify messages which are signed
# to prevent tampering.
#
#
# This is useful for cases like remember-me tokens and auto-unsubscribe links where the
# session store isn't suitable or available.
#
# Remember Me:
# cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
#
#
# In the authentication filter:
#
# id, time = @verifier.verify(cookies[:remember_me])
# if time < Time.now
# self.current_user = User.find(id)
# end
#
#
# By default it uses Marshal to serialize the message. If you want to use another
# serialization method, you can set the serializer attribute to something that responds
# to dump and load, e.g.:
#
# @verifier.serializer = YAML
class MessageVerifier
class InvalidSignature < StandardError; end
def initialize(secret, digest = 'SHA1')
def initialize(secret, options = {})
unless options.is_a?(Hash)
ActiveSupport::Deprecation.warn "The second parameter should be an options hash. Use :digest => 'algorithm' to specify the digest algorithm."
options = { :digest => options }
end
@secret = secret
@digest = digest
@digest = options[:digest] || 'SHA1'
@serializer = options[:serializer] || Marshal
end
def verify(signed_message)
raise InvalidSignature if signed_message.blank?
data, digest = signed_message.split("--")
if data.present? && digest.present? && secure_compare(digest, generate_digest(data))
Marshal.load(ActiveSupport::Base64.decode64(data))
@serializer.load(::Base64.decode64(data))
else
raise InvalidSignature
end
end
def generate(value)
data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
data = ::Base64.strict_encode64(@serializer.dump(value))
"#{data}--#{generate_digest(data)}"
end
private
if "foo".respond_to?(:force_encoding)
# constant-time comparison algorithm to prevent timing attacks
def secure_compare(a, b)
a = a.dup.force_encoding(Encoding::BINARY)
b = b.dup.force_encoding(Encoding::BINARY)
if a.length == b.length
result = 0
for i in 0..(a.length - 1)
result |= a[i].ord ^ b[i].ord
end
result == 0
else
false
end
end
else
# For <= 1.8.6
def secure_compare(a, b)
if a.length == b.length
result = 0
for i in 0..(a.length - 1)
result |= a[i] ^ b[i]
end
result == 0
else
false
end
end
private
# constant-time comparison algorithm to prevent timing attacks
def secure_compare(a, b)
return false unless a.bytesize == b.bytesize
l = a.unpack "C#{a.bytesize}"
res = 0
b.each_byte { |byte| res |= byte ^ l.shift }
res == 0
end
def generate_digest(data)
require 'openssl' unless defined?(OpenSSL)
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data)
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
end
end
end

View File

@@ -1,168 +1 @@
require 'yaml'
YAML.add_builtin_type("omap") do |type, val|
ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
end
# OrderedHash is namespaced to prevent conflicts with other implementations
module ActiveSupport
class OrderedHash < ::Hash #:nodoc:
def to_yaml_type
"!tag:yaml.org,2002:omap"
end
def to_yaml(opts = {})
YAML.quick_emit(self, opts) do |out|
out.seq(taguri, to_yaml_style) do |seq|
each do |k, v|
seq.add(k => v)
end
end
end
end
# Hash is ordered in Ruby 1.9!
if RUBY_VERSION < '1.9'
def initialize(*args, &block)
super
@keys = []
end
def self.[](*args)
ordered_hash = new
if (args.length == 1 && args.first.is_a?(Array))
args.first.each do |key_value_pair|
next unless (key_value_pair.is_a?(Array))
ordered_hash[key_value_pair[0]] = key_value_pair[1]
end
return ordered_hash
end
unless (args.size % 2 == 0)
raise ArgumentError.new("odd number of arguments for Hash")
end
args.each_with_index do |val, ind|
next if (ind % 2 != 0)
ordered_hash[val] = args[ind + 1]
end
ordered_hash
end
def initialize_copy(other)
super
# make a deep copy of keys
@keys = other.keys
end
def []=(key, value)
@keys << key if !has_key?(key)
super
end
def delete(key)
if has_key? key
index = @keys.index(key)
@keys.delete_at index
end
super
end
def delete_if
super
sync_keys!
self
end
def reject!
super
sync_keys!
self
end
def reject(&block)
dup.reject!(&block)
end
def keys
@keys.dup
end
def values
@keys.collect { |key| self[key] }
end
def to_hash
self
end
def to_a
@keys.map { |key| [ key, self[key] ] }
end
def each_key
@keys.each { |key| yield key }
end
def each_value
@keys.each { |key| yield self[key]}
end
def each
@keys.each {|key| yield [key, self[key]]}
end
alias_method :each_pair, :each
def clear
super
@keys.clear
self
end
def shift
k = @keys.first
v = delete(k)
[k, v]
end
def merge!(other_hash)
if block_given?
other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
else
other_hash.each { |k, v| self[k] = v }
end
self
end
alias_method :update, :merge!
def merge(other_hash, &block)
dup.merge!(other_hash, &block)
end
# When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
def replace(other)
super
@keys = other.keys
self
end
def invert
OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
end
def inspect
"#<OrderedHash #{super}>"
end
private
def sync_keys!
@keys.delete_if {|k| !has_key?(k)}
end
end
end
end
ActiveSupport::OrderedHash = Hash

View File

@@ -1,5 +1,5 @@
module ActiveSupport #:nodoc:
class OrderedOptions < OrderedHash #:nodoc:
class OrderedOptions < Hash #:nodoc:
def []=(key, value)
super(key.to_sym, value)
end

View File

@@ -1,114 +0,0 @@
#!/usr/bin/env ruby
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
######################################################################
# BlankSlate provides an abstract base class with no predefined
# methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
# BlankSlate is useful as a base class when writing classes that
# depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
#
class BlankSlate
class << self
# Hide the method named +name+ in the BlankSlate class. Don't
# hide +instance_eval+ or any method beginning with "__".
def hide(name)
if (instance_methods.include?(name) || instance_methods.include?(name.to_sym)) and
name !~ /^(__|instance_eval|object_id)/
@hidden_methods ||= {}
@hidden_methods[name] = instance_method(name)
undef_method name
end
end
def find_hidden_method(name)
@hidden_methods ||= {}
@hidden_methods[name] || superclass.find_hidden_method(name)
end
# Redefine a previously hidden method so that it may be called on a blank
# slate object.
def reveal(name)
bound_method = nil
unbound_method = find_hidden_method(name)
fail "Don't know how to reveal method '#{name}'" unless unbound_method
define_method(name) do |*args|
bound_method ||= unbound_method.bind(self)
bound_method.call(*args)
end
end
end
instance_methods.each { |m| hide(m) }
end
######################################################################
# Since Ruby is very dynamic, methods added to the ancestors of
# BlankSlate <em>after BlankSlate is defined</em> will show up in the
# list of available BlankSlate methods. We handle this by defining a
# hook in the Object and Kernel classes that will hide any method
# defined after BlankSlate has been loaded.
#
module Kernel
class << self
alias_method :blank_slate_method_added, :method_added
# Detect method additions to Kernel and remove them in the
# BlankSlate class.
def method_added(name)
result = blank_slate_method_added(name)
return result if self != Kernel
BlankSlate.hide(name)
result
end
end
end
######################################################################
# Same as above, except in Object.
#
class Object
class << self
alias_method :blank_slate_method_added, :method_added
# Detect method additions to Object and remove them in the
# BlankSlate class.
def method_added(name)
result = blank_slate_method_added(name)
return result if self != Object
BlankSlate.hide(name)
result
end
def find_hidden_method(name)
nil
end
end
end
######################################################################
# Also, modules included into Object need to be scanned and have their
# instance methods removed from blank slate. In theory, modules
# included into Kernel would have to be removed as well, but a
# "feature" of Ruby prevents late includes into modules from being
# exposed in the first place.
#
class Module
alias blankslate_original_append_features append_features
def append_features(mod)
result = blankslate_original_append_features(mod)
return result if mod != Object
instance_methods.each do |name|
BlankSlate.hide(name)
end
result
end
end

View File

@@ -1,20 +0,0 @@
#!/usr/bin/env ruby
#--
# Copyright 2004, 2006 by Jim Weirich (jim@weirichhouse.org).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#++
require 'blankslate'
######################################################################
# BlankSlate has been promoted to a top level name and is now
# available as a standalone gem. We make the name available in the
# Builder namespace for compatibility.
#
module Builder
BlankSlate = ::BlankSlate
end

View File

@@ -18,8 +18,6 @@
# Style Sheets (CSS).
require 'builder/blankslate'
module Builder
# Create a Cascading Style Sheet (CSS) using Ruby.
@@ -89,7 +87,7 @@ module Builder
# background: red;
# }
#
class CSS < BlankSlate
class CSS < BasicObject
# Create a CSS builder.
#
@@ -155,7 +153,7 @@ module Builder
def group!(*args, &block)
args.each do |arg|
if arg.is_a?(Symbol)
if arg.is_a?(::Symbol)
instance_eval(&@library[arg])
else
instance_eval(&arg)
@@ -169,7 +167,7 @@ module Builder
end
def method_missing(sym, *args, &block)
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
if block
_start_container(sym, args.first)
_css_block(block)

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env ruby
require 'builder/blankslate'
module Builder
# Generic error for builder
@@ -9,7 +7,7 @@ module Builder
# XmlBase is a base class for building XML builders. See
# Builder::XmlMarkup and Builder::XmlEvents for examples.
class XmlBase < BlankSlate
class XmlBase < BasicObject
# Create an XML markup builder.
#
@@ -37,10 +35,10 @@ module Builder
def method_missing(sym, *args, &block)
text = nil
attrs = nil
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(Symbol)
sym = "#{sym}:#{args.shift}" if args.first.kind_of?(::Symbol)
args.each do |arg|
case arg
when Hash
when ::Hash
attrs ||= {}
attrs.merge!(arg)
else
@@ -50,7 +48,7 @@ module Builder
end
if block
unless text.nil?
raise ArgumentError, "XmlMarkup cannot mix a text argument with a block"
raise ::ArgumentError, "XmlMarkup cannot mix a text argument with a block"
end
_indent
_start_tag(sym, attrs)

View File

@@ -195,7 +195,7 @@ module Builder
end
def comment!(comment_text)
_ensure_no_block block_given?
_ensure_no_block ::Kernel.block_given?
_special("<!-- ", " -->", comment_text, nil)
end
@@ -210,13 +210,13 @@ module Builder
@target << "<!#{inst}"
args.each do |arg|
case arg
when String
when ::String
@target << %{ "#{arg}"} # " WART
when Symbol
when ::Symbol
@target << " #{arg}"
end
end
if block_given?
if ::Kernel.block_given?
@target << " ["
_newline
_nested_structures(block)
@@ -236,7 +236,7 @@ module Builder
# #=> <?aaa bbb="ccc"?>
#
def instruct!(directive_tag=:xml, attrs={})
_ensure_no_block block_given?
_ensure_no_block ::Kernel.block_given?
if directive_tag == :xml
a = { :version=>"1.0", :encoding=>"UTF-8" }
attrs = a.merge attrs
@@ -257,7 +257,7 @@ module Builder
# #=> <![CDATA[text to be included in cdata]]>
#
def cdata!(text)
_ensure_no_block block_given?
_ensure_no_block ::Kernel.block_given?
_special("<![CDATA[", "]]>", text, nil)
end
@@ -309,7 +309,7 @@ module Builder
def _attr_value(value)
case value
when Symbol
when ::Symbol
value.to_s
else
_escape_quote(value.to_s)

View File

@@ -178,6 +178,8 @@ class MemoryStoreTest < ActiveSupport::TestCase
end
uses_memcached 'memcached backed store' do
next # these tests are broken on CI
class MemCacheStoreTest < ActiveSupport::TestCase
def setup
@cache = ActiveSupport::Cache.lookup_store(:mem_cache_store)

View File

@@ -1,16 +1,36 @@
require 'abstract_unit'
class MessageVerifierTest < Test::Unit::TestCase
def setup
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
@data = {:some=>"data", :now=>Time.now}
begin
require 'openssl'
OpenSSL::Digest::SHA1
rescue LoadError, NameError
$stderr.puts "Skipping MessageVerifier test: broken OpenSSL install"
else
require 'active_support/json'
class MessageVerifierTest < ActiveSupport::TestCase
class JSONSerializer
def dump(value)
ActiveSupport::JSON.encode(value)
end
def load(value)
ActiveSupport::JSON.decode(value)
end
end
def setup
@verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!")
@data = { :some => "data", :now => Time.local(2010) }
end
def test_simple_round_tripping
message = @verifier.generate(@data)
assert_equal @data, @verifier.verify(message)
end
def test_missing_signature_raises
assert_not_verified(nil)
assert_not_verified("")
@@ -23,9 +43,23 @@ class MessageVerifierTest < Test::Unit::TestCase
assert_not_verified("purejunk")
end
def test_alternative_serialization_method
verifier = ActiveSupport::MessageVerifier.new("Hey, I'm a secret!", :serializer => JSONSerializer.new)
message = verifier.generate({ :foo => 123, 'bar' => Time.utc(2010) })
assert_equal verifier.verify(message), { "foo" => 123, "bar" => "2010/01/01 00:00:00 +0000" }
end
def test_digest_algorithm_as_second_parameter_deprecation
assert_deprecated(/options hash/) do
ActiveSupport::MessageVerifier.new("secret", "SHA1")
end
end
def assert_not_verified(message)
assert_raise(ActiveSupport::MessageVerifier::InvalidSignature) do
@verifier.verify(message)
end
end
end
end

View File

@@ -35,8 +35,6 @@ end
Rake::TestTask.new("regular_test") do |t|
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.warning = true
t.verbose = true
end

View File

@@ -10,8 +10,7 @@ config.whiny_nils = true
# Show full error reports and disable caching
config.action_controller.consider_all_requests_local = true
config.action_view.debug_rjs = true
config.action_controller.perform_caching = false
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
config.action_mailer.raise_delivery_errors = false

View File

@@ -20,7 +20,7 @@ module RailsGuides
def process(string, current_level=3, counters=[1])
s = StringScanner.new(string)
level_hash = ActiveSupport::OrderedHash.new
level_hash = {}
while !s.eos?
re = %r{^h(\d)(?:\((#.*?)\))?\s*\.\s*(.*)$}

View File

@@ -34,7 +34,7 @@ module Rails
def initialize(app)
@app = app
@metals = ActiveSupport::OrderedHash.new
@metals = {}
self.class.metals.each { |app| @metals[app] = true }
freeze
end

22
railties/railties.gemspec Normal file
View File

@@ -0,0 +1,22 @@
Gem::Specification.new do |s|
s.name = 'rails'
s.version = '2.3.18'
s.summary = 'Web-application framework with template engine, control-flow layer, and ORM.'
s.description = "Rails is a framework for building web-application using CGI, FCGI, mod_ruby, or WEBrick\non top of either MySQL, PostgreSQL, SQLite, DB2, SQL Server, or Oracle with eRuby- or Builder-based templates."
s.author = 'David Heinemeier Hansson'
s.email = 'david@loudthinking.com'
s.homepage = 'http://www.rubyonrails.org'
s.require_path = 'lib'
s.files = ['bin/rails']
s.executables = ['rails']
s.rdoc_options = ['--exclude', '.']
s.add_dependency 'rake', '>= 0.8.3'
s.add_dependency 'activesupport', '= 2.3.18'
s.add_dependency 'activerecord', '= 2.3.18'
s.add_dependency 'actionpack', '= 2.3.18'
s.add_dependency 'actionmailer', '= 2.3.18'
s.add_dependency 'activeresource', '= 2.3.18'
end

View File

@@ -3,38 +3,5 @@
set -x
set -e
RUBY_VERSION="$(cat .ruby-version)"
# Use the right Ruby /without/ rbenv
ruby_dir=$(dirname "$(RBENV_VERSION=$RUBY_VERSION rbenv which ruby)")
export PATH=$ruby_dir:$PATH
# Announce who we are
ruby -v
# Because Rails 2.3 doesn't use Bundler for its own tests,
# we need to setup an isolated gem environment.
gem_environment_version="$(md5sum Gemfile.sh | cut -d' ' -f1)-$(ruby -e 'print RUBY_VERSION')"
gem_dir=`pwd`/.gem
gem_pristine_dir=${gem_dir}-${gem_environment_version}
export GEM_HOME=$gem_dir
export GEM_PATH=$gem_dir:$GEM_PATH
export GEM_ROOT=$gem_dir
rm -rf $gem_dir
if [ ! -d $gem_pristine_dir ]; then
mkdir $gem_dir
. Gemfile.sh
mv $gem_dir $gem_pristine_dir
fi
cp -r $gem_pristine_dir $gem_dir
# Go ham
rake
script/cibuild-on 1.9.3-p231-tcs-github
script/cibuild-on 2.0.0-github

40
script/cibuild-on Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
set -x
set -e
RUBY_VERSION="$1"
# Use the right Ruby /without/ rbenv
ruby_dir=$(dirname "$(RBENV_VERSION=$RUBY_VERSION rbenv which ruby)")
export PATH=$ruby_dir:$PATH
# Announce who we are
ruby -v
# Because Rails 2.3 doesn't use Bundler for its own tests,
# we need to setup an isolated gem environment.
gem_environment_version="$(md5sum Gemfile.sh | cut -d' ' -f1)-$(ruby -e 'print RUBY_VERSION')"
gem_dir=`pwd`/.gem
gem_pristine_dir=${gem_dir}-${gem_environment_version}
export GEM_HOME=$gem_dir
export GEM_PATH=$gem_dir:$GEM_PATH
export GEM_ROOT=$gem_dir
rm -rf $gem_dir
if [ ! -d $gem_pristine_dir ]; then
mkdir $gem_dir
. Gemfile.sh
mv $gem_dir $gem_pristine_dir
fi
cp -r $gem_pristine_dir $gem_dir
# Go ham
rake