Permalink
Browse files

Merge commit 'mainstream/master'

  • Loading branch information...
2 parents 4617139 + cff2291 commit e32deb595f66e8be7aeb9aeb2ef796994f524584 @lifo lifo committed May 22, 2008
@@ -635,6 +635,8 @@ def check_box_checked?(value, checked_value)
value != 0
when String
value == checked_value
+ when Array
+ value.include?(checked_value)
else
value.to_i != 0
end
@@ -464,7 +464,7 @@ def set_cycle(name, cycle_object)
[-\w]+ # subdomain or domain
(?:\.[-\w]+)* # remaining subdomains or domain
(?::\d+)? # port
- (?:/(?:(?:[~\w\+@%=-]|(?:[,.;:][^\s$]))+)?)* # path
+ (?:/(?:(?:[~\w\+@%=\(\)-]|(?:[,.;:][^\s$]))+)?)* # path
(?:\?[\w\+@%&=.;-]+)? # query string
(?:\#[\w\-]*)? # trailing anchor
)
@@ -181,6 +181,17 @@ def test_check_box
'<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
check_box("post", "secret?")
)
+
+ @post.secret = ['0']
+ assert_dom_equal(
+ '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
+ check_box("post", "secret")
+ )
+ @post.secret = ['1']
+ assert_dom_equal(
+ '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
+ check_box("post", "secret")
+ )
end
def test_check_box_with_explicit_checked_and_unchecked_values
@@ -186,6 +186,7 @@ def test_auto_link_parsing
http://en.wikipedia.org/wiki/Wikipedia:Today%27s_featured_picture_%28animation%29/January_20%2C_2007
http://www.mail-archive.com/rails@lists.rubyonrails.org/
http://www.amazon.com/Testing-Equal-Sign-In-Path/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1198861734&sr=8-1
+ http://en.wikipedia.org/wiki/Sprite_(computer_graphics)
)
urls.each do |url|
@@ -210,7 +210,8 @@ def foreign_key_present
def raise_on_type_mismatch(record)
unless record.is_a?(@reflection.klass)
- raise ActiveRecord::AssociationTypeMismatch, "#{@reflection.klass} expected, got #{record.class}"
+ message = "#{@reflection.class_name}(##{@reflection.klass.object_id}) expected, got #{record.class}(##{record.class.object_id})"
+ raise ActiveRecord::AssociationTypeMismatch, message
end
end
@@ -40,6 +40,7 @@ def self.included(base)
base.alias_method_chain :save, :dirty
base.alias_method_chain :save!, :dirty
base.alias_method_chain :update, :dirty
+ base.alias_method_chain :reload, :dirty
base.superclass_delegating_accessor :partial_updates
base.partial_updates = false
@@ -84,6 +85,13 @@ def save_with_dirty!(*args) #:nodoc:
status
end
+ # <tt>reload</tt> the record and clears changed attributes.
+ def reload_with_dirty(*args) #:nodoc:
+ record = reload_without_dirty(*args)
+ changed_attributes.clear
+ record
+ end
+
private
# Map of change attr => original value.
def changed_attributes
@@ -117,14 +125,7 @@ def write_attribute_with_dirty(attr, value)
# The attribute already has an unsaved change.
unless changed_attributes.include?(attr)
old = clone_attribute_value(:read_attribute, attr)
-
- # Remember the original value if it's different.
- typecasted = if column = column_for_attribute(attr)
- column.type_cast(value)
- else
- value
- end
- changed_attributes[attr] = old unless old == typecasted
+ changed_attributes[attr] = old if field_changed?(attr, old, value)
end
# Carry on.
@@ -138,5 +139,20 @@ def update_with_dirty
update_without_dirty
end
end
+
+ def field_changed?(attr, old, value)
+ if column = column_for_attribute(attr)
+ if column.type == :integer && column.null && old.nil?
+ # For nullable integer columns, NULL gets stored in database for blank (i.e. '') values.
+ # Hence we don't record it as a change if the value changes from nil to ''.
+ value = nil if value.blank?
+ else
+ value = column.type_cast(value)
+ end
+ end
+
+ old != value
+ end
+
end
end
@@ -40,47 +40,56 @@ def test_drop_table_with_specific_database
end
def test_add_timestamps
- #we need to actually modify some data, so we make execute to point to the original method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute_with_stub, :execute
- alias_method :execute, :execute_without_stub
- end
- ActiveRecord::Base.connection.create_table :delete_me do |t|
- end
- ActiveRecord::Base.connection.add_timestamps :delete_me
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='updated_at' AND TYPE='datetime'").num_rows, 1
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='created_at' AND TYPE='datetime'").num_rows, 1
- ensure
- ActiveRecord::Base.connection.drop_table :delete_me rescue nil
- #before finishing, we restore the alias to the mock-up method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute, :execute_with_stub
+ with_real_execute do
+ begin
+ ActiveRecord::Base.connection.create_table :delete_me do |t|
+ end
+ ActiveRecord::Base.connection.add_timestamps :delete_me
+ assert column_present?('delete_me', 'updated_at', 'datetime')
+ assert column_present?('delete_me', 'created_at', 'datetime')
+ ensure
+ ActiveRecord::Base.connection.drop_table :delete_me rescue nil
+ end
end
end
def test_remove_timestamps
- #we need to actually modify some data, so we make execute to point to the original method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute_with_stub, :execute
- alias_method :execute, :execute_without_stub
- end
- ActiveRecord::Base.connection.create_table :delete_me do |t|
- t.timestamps
- end
- ActiveRecord::Base.connection.remove_timestamps :delete_me
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='updated_at' AND TYPE='datetime'").num_rows, 0
- assert_equal ActiveRecord::Base.connection.execute("SHOW FIELDS FROM delete_me where FIELD='created_at' AND TYPE='datetime'").num_rows, 0
- ensure
- ActiveRecord::Base.connection.drop_table :delete_me rescue nil
- #before finishing, we restore the alias to the mock-up method
- ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
- alias_method :execute, :execute_with_stub
+ with_real_execute do
+ begin
+ ActiveRecord::Base.connection.create_table :delete_me do |t|
+ t.timestamps
+ end
+ ActiveRecord::Base.connection.remove_timestamps :delete_me
+ assert !column_present?('delete_me', 'updated_at', 'datetime')
+ assert !column_present?('delete_me', 'created_at', 'datetime')
+ ensure
+ ActiveRecord::Base.connection.drop_table :delete_me rescue nil
+ end
end
end
-
private
+ def with_real_execute
+ #we need to actually modify some data, so we make execute point to the original method
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
+ alias_method :execute_with_stub, :execute
+ alias_method :execute, :execute_without_stub
+ end
+ yield
+ ensure
+ #before finishing, we restore the alias to the mock-up method
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
+ alias_method :execute, :execute_with_stub
+ end
+ end
+
+
def method_missing(method_symbol, *arguments)
ActiveRecord::Base.connection.send(method_symbol, *arguments)
end
+
+ def column_present?(table_name, column_name, type)
+ results = ActiveRecord::Base.connection.select_all("SHOW FIELDS FROM #{table_name} LIKE '#{column_name}'")
+ results.first && results.first['Type'] == type
+ end
end
@@ -44,6 +44,16 @@ def test_attribute_changes
assert_nil pirate.catchphrase_change
end
+ def test_nullable_integer_not_marked_as_changed_if_new_value_is_blank
+ pirate = Pirate.new
+
+ ["", nil].each do |value|
+ pirate.parrot_id = value
+ assert !pirate.parrot_id_changed?
+ assert_nil pirate.parrot_id_change
+ end
+ end
+
def test_object_should_be_changed_if_any_attribute_is_changed
pirate = Pirate.new
assert !pirate.changed?
@@ -127,6 +137,14 @@ def test_changed_attributes_should_be_preserved_if_save_failure
check_pirate_after_save_failure(pirate)
end
+ def test_reload_should_clear_changed_attributes
+ pirate = Pirate.create!(:catchphrase => "shiver me timbers")
+ pirate.catchphrase = "*hic*"
+ assert pirate.changed?
+ pirate.reload
+ assert !pirate.changed?
+ end
+
private
def with_partial_updates(klass, on = true)
old = klass.partial_updates?
@@ -281,7 +281,7 @@ def test_native_decimal_insert_manual_vs_automatic
# Do a manual insertion
if current_adapter?(:OracleAdapter)
Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)"
- elsif current_adapter?(:OpenBaseAdapter)
+ elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings
Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')"
else
Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)"
@@ -384,7 +384,7 @@ def test_native_types
assert_not_equal "Z", bob.moment_of_truth.zone
# US/Eastern is -5 hours from GMT
assert_equal Rational(-5, 24), bob.moment_of_truth.offset
- assert_equal "-05:00", bob.moment_of_truth.zone
+ assert_match /\A-05:?00\Z/, bob.moment_of_truth.zone #ruby 1.8.6 uses HH:MM, prior versions use HHMM
assert_equal DateTime::ITALY, bob.moment_of_truth.start
end
end
@@ -24,9 +24,9 @@
end
if options[:sandbox]
- puts "Loading #{ENV['RAILS_ENV']} environment in sandbox (Rails #{Rails::VERSION::STRING})"
+ puts "Loading #{ENV['RAILS_ENV']} environment in sandbox (Rails #{Rails.version})"
puts "Any modifications you make will be rolled back on exit"
else
- puts "Loading #{ENV['RAILS_ENV']} environment (Rails #{Rails::VERSION::STRING})"
+ puts "Loading #{ENV['RAILS_ENV']} environment (Rails #{Rails.version})"
end
exec "#{options[:irb]} #{libs} --simple-prompt"
@@ -62,7 +62,7 @@
default_port, default_ip = 3000, '0.0.0.0'
port = config.scan(/^\s*server.port\s*=\s*(\d+)/).first rescue default_port
ip = config.scan(/^\s*server.bind\s*=\s*"([^"]+)"/).first rescue default_ip
-puts "=> Rails application starting on http://#{ip || default_ip}:#{port || default_port}"
+puts "=> Rails #{Rails.version} application starting on http://#{ip || default_ip}:#{port || default_port}"
tail_thread = nil
@@ -32,7 +32,7 @@
opts.parse!
end
-puts "=> Rails application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
+puts "=> Rails #{Rails.version} application starting on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
parameters = [
"start",
@@ -61,6 +61,6 @@
OPTIONS['working_directory'] = File.expand_path(RAILS_ROOT)
-puts "=> Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
+puts "=> Rails #{Rails.version} application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
puts "=> Ctrl-C to shutdown server; call with --help for options" if OPTIONS[:server_type] == WEBrick::SimpleServer
DispatchServlet.dispatch(OPTIONS)
@@ -43,6 +43,10 @@ def cache
RAILS_CACHE
end
+ def version
+ VERSION::STRING
+ end
+
def public_path
@@public_path ||= self.root ? File.join(self.root, "public") : "public"
end
@@ -119,7 +119,7 @@ def run
config = RailsConfigurator.new(settings) do
defaults[:log] = $stdout if defaults[:environment] == 'development'
- Mongrel.log("=> Rails application starting on http://#{defaults[:host]}:#{defaults[:port]}")
+ Mongrel.log("=> Rails #{Rails.version} application starting on http://#{defaults[:host]}:#{defaults[:port]}")
unless defaults[:daemon]
Mongrel.log("=> Call with -d to detach")

0 comments on commit e32deb5

Please sign in to comment.