mirror of
https://github.com/github/rails.git
synced 2026-01-12 08:08:31 -05:00
Compare commits
35 Commits
github24
...
actionview
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
71dc3f7fa3 | ||
|
|
47d4630c39 | ||
|
|
7e5382f27e | ||
|
|
88b2f91442 | ||
|
|
26a1e3738f | ||
|
|
b2c42ec341 | ||
|
|
84d39ae996 | ||
|
|
35813faf54 | ||
|
|
ca03813864 | ||
|
|
8a78d5922a | ||
|
|
3770f13b97 | ||
|
|
755a361548 | ||
|
|
422b3d0dcb | ||
|
|
c96caaae9a | ||
|
|
050be61caf | ||
|
|
4baefa4de9 | ||
|
|
26fce88209 | ||
|
|
cb507570a1 | ||
|
|
9a2d6cad23 | ||
|
|
bf96f35248 | ||
|
|
21bae614ee | ||
|
|
1d6053f5bf | ||
|
|
f90bfeb930 | ||
|
|
bca938dae2 | ||
|
|
4579aa2767 | ||
|
|
0a522af512 | ||
|
|
ca6a64758b | ||
|
|
8573f7f86b | ||
|
|
685cb901fc | ||
|
|
e9f9d05a94 | ||
|
|
7b6670cc08 | ||
|
|
ed2d852bdc | ||
|
|
726ab5316d | ||
|
|
ecd6fb250a | ||
|
|
9f8ee9dd97 |
6
README.md
Normal file
6
README.md
Normal 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.**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
14
actionmailer/actionmailer.gemspec
Normal file
14
actionmailer/actionmailer.gemspec
Normal 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
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
15
actionpack/actionpack.gemspec
Normal file
15
actionpack/actionpack.gemspec
Normal 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
|
||||
@@ -1280,8 +1280,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 +1331,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
|
||||
|
||||
@@ -5,8 +5,8 @@ module ActionController #:nodoc:
|
||||
module Helpers #:nodoc:
|
||||
def self.included(base)
|
||||
# Initialize the base module to aggregate its helpers.
|
||||
base.class_inheritable_accessor :master_helper_module
|
||||
base.master_helper_module = Module.new
|
||||
base.class_inheritable_accessor :master_helper_class
|
||||
base.master_helper_class = Class.new(ActionView::Base)
|
||||
|
||||
# Set the default directory for helpers
|
||||
base.class_inheritable_accessor :helpers_dir
|
||||
@@ -73,7 +73,7 @@ module ActionController #:nodoc:
|
||||
# See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
|
||||
# available to the templates.
|
||||
def add_template_helper(helper_module) #:nodoc:
|
||||
master_helper_module.module_eval { include helper_module }
|
||||
master_helper_class.class_eval { include helper_module }
|
||||
end
|
||||
|
||||
# The +helper+ class method can take a series of helper module names, a block, or both.
|
||||
@@ -141,7 +141,7 @@ module ActionController #:nodoc:
|
||||
end
|
||||
|
||||
# Evaluate block in template class if given.
|
||||
master_helper_module.module_eval(&block) if block_given?
|
||||
master_helper_class.class_eval(&block) if block_given?
|
||||
end
|
||||
|
||||
# Declare a controller method as a helper. For example, the following
|
||||
@@ -162,7 +162,7 @@ module ActionController #:nodoc:
|
||||
# <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
|
||||
def helper_method(*methods)
|
||||
methods.flatten.each do |method|
|
||||
master_helper_module.module_eval <<-end_eval
|
||||
master_helper_class.class_eval <<-end_eval
|
||||
def #{method}(*args, &block) # def current_user(*args, &block)
|
||||
controller.send(%(#{method}), *args, &block) # controller.send(%(current_user), *args, &block)
|
||||
end # end
|
||||
@@ -182,8 +182,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
|
||||
@@ -207,8 +206,7 @@ module ActionController #:nodoc:
|
||||
inherited_without_helper(child)
|
||||
|
||||
begin
|
||||
child.master_helper_module = Module.new
|
||||
child.master_helper_module.__send__ :include, master_helper_module
|
||||
child.master_helper_class = Class.new(master_helper_class)
|
||||
child.__send__ :default_helper_module!
|
||||
rescue MissingSourceFile => e
|
||||
raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -210,24 +210,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
|
||||
|
||||
@@ -91,7 +91,7 @@ module ActionView
|
||||
def helper_method(*methods)
|
||||
# Almost a duplicate from ActionController::Helpers
|
||||
methods.flatten.each do |method|
|
||||
master_helper_module.module_eval <<-end_eval
|
||||
master_helper_class.class_eval <<-end_eval
|
||||
def #{method}(*args, &block) # def current_user(*args, &block)
|
||||
_test_case.send(%(#{method}), *args, &block) # test_case.send(%(current_user), *args, &block)
|
||||
end # end
|
||||
@@ -109,15 +109,14 @@ module ActionView
|
||||
private
|
||||
def make_test_case_available_to_view!
|
||||
test_case_instance = self
|
||||
master_helper_module.module_eval do
|
||||
master_helper_class.class_eval do
|
||||
define_method(:_test_case) { test_case_instance }
|
||||
private :_test_case
|
||||
end
|
||||
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
|
||||
|
||||
@@ -118,7 +118,7 @@ class HelperTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_all_helpers
|
||||
methods = ApplicationController.master_helper_module.instance_methods.map(&:to_s)
|
||||
methods = ApplicationController.master_helper_class.instance_methods.map(&:to_s)
|
||||
|
||||
# abc_helper.rb
|
||||
assert methods.include?('bare_a')
|
||||
@@ -134,7 +134,7 @@ class HelperTest < Test::Unit::TestCase
|
||||
@controller_class.helpers_dir = File.dirname(__FILE__) + '/../fixtures/alternate_helpers'
|
||||
|
||||
# Reload helpers
|
||||
@controller_class.master_helper_module = Module.new
|
||||
@controller_class.master_helper_class = Class.new(ActionView::Base)
|
||||
@controller_class.helper :all
|
||||
|
||||
# helpers/abc_helper.rb should not be included
|
||||
@@ -166,7 +166,7 @@ class HelperTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def master_helper_methods
|
||||
@controller_class.master_helper_module.instance_methods.map(&:to_s)
|
||||
@controller_class.master_helper_class.instance_methods.map(&:to_s)
|
||||
end
|
||||
|
||||
def missing_methods
|
||||
|
||||
@@ -1034,6 +1034,10 @@ class RenderTest < ActionController::TestCase
|
||||
new Draggable(value, {});
|
||||
});
|
||||
}.gsub(/^ /, '').strip
|
||||
if body != @response.body
|
||||
puts "<<<<<<<\n#{body}\n=======\n#{@response.body}\n>>>>>>>>"
|
||||
exit!
|
||||
end
|
||||
assert_equal body, @response.body
|
||||
end
|
||||
|
||||
@@ -1113,7 +1117,7 @@ class RenderTest < ActionController::TestCase
|
||||
|
||||
def test_should_implicitly_render_js_template_without_layout
|
||||
get :render_implicit_js_template_without_layout, :format => :js
|
||||
assert_no_match /<html>/, @response.body
|
||||
assert_no_match(/<html>/, @response.body)
|
||||
end
|
||||
|
||||
def test_should_render_formatted_template
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -122,7 +122,7 @@ module ActionView
|
||||
test "named routes can be used from helper included in view" do
|
||||
with_routing do |set|
|
||||
set.draw { |map| map.resources :contents }
|
||||
master_helper_module.module_eval do
|
||||
master_helper_class.class_eval do
|
||||
def render_from_helper
|
||||
new_content_url
|
||||
end
|
||||
@@ -146,7 +146,7 @@ module ActionView
|
||||
end
|
||||
|
||||
test "is able to make methods available to the view" do
|
||||
master_helper_module.module_eval do
|
||||
master_helper_class.class_eval do
|
||||
def render_from_helper; from_test_case end
|
||||
end
|
||||
assert_equal 'Word!', render(:partial => 'test/from_helper')
|
||||
|
||||
@@ -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
|
||||
|
||||
17
activerecord/activerecord.gemspec
Normal file
17
activerecord/activerecord.gemspec
Normal 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
|
||||
@@ -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?
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
||||
17
activeresource/activeresource.gemspec
Normal file
17
activeresource/activeresource.gemspec
Normal 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
|
||||
@@ -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
|
||||
|
||||
12
activesupport/activesupport.gemspec
Normal file
12
activesupport/activesupport.gemspec
Normal 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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
module ActiveSupport #:nodoc:
|
||||
class OrderedOptions < OrderedHash #:nodoc:
|
||||
class OrderedOptions < Hash #:nodoc:
|
||||
def []=(key, value)
|
||||
super(key.to_sym, value)
|
||||
end
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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*(.*)$}
|
||||
|
||||
@@ -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
22
railties/railties.gemspec
Normal 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
|
||||
@@ -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
40
script/cibuild-on
Executable 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
|
||||
Reference in New Issue
Block a user