diff options
-rw-r--r-- | activerecord/lib/active_record/attribute_methods/serialization.rb | 7 | ||||
-rw-r--r-- | activerecord/lib/active_record/base.rb | 9 | ||||
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 3 | ||||
-rw-r--r-- | activerecord/lib/active_record/locking/optimistic.rb | 2 | ||||
-rw-r--r-- | activerecord/test/cases/base_test.rb | 9 | ||||
-rw-r--r-- | activesupport/CHANGELOG.md | 3 | ||||
-rw-r--r-- | activesupport/lib/active_support/json/encoding.rb | 12 | ||||
-rw-r--r-- | activesupport/lib/active_support/json/variable.rb | 10 | ||||
-rw-r--r-- | activesupport/lib/active_support/testing/setup_and_teardown.rb | 5 | ||||
-rw-r--r-- | activesupport/test/json/encoding_test.rb | 17 | ||||
-rw-r--r-- | activesupport/test/test_case_test.rb | 44 | ||||
-rw-r--r-- | railties/lib/rails/generators/app_base.rb | 2 | ||||
-rw-r--r-- | railties/lib/rails/source_annotation_extractor.rb | 4 | ||||
-rw-r--r-- | railties/test/application/rake/notes_test.rb | 14 | ||||
-rw-r--r-- | railties/test/generators/app_generator_test.rb | 2 |
15 files changed, 113 insertions, 30 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/serialization.rb b/activerecord/lib/active_record/attribute_methods/serialization.rb index 1798afc3b7..00023b0b6c 100644 --- a/activerecord/lib/active_record/attribute_methods/serialization.rb +++ b/activerecord/lib/active_record/attribute_methods/serialization.rb @@ -58,12 +58,13 @@ module ActiveRecord self.serialized_attributes = serialized_attributes.merge(attr_name.to_s => coder) end - def initialize_attributes(attributes) #:nodoc: - super + def initialize_attributes(attributes, options = {}) #:nodoc: + serialized = (options.delete(:serialized) { true }) ? :serialized : :unserialized + super(attributes, options) serialized_attributes.each do |key, coder| if attributes.key?(key) - attributes[key] = Attribute.new(coder, attributes[key], :serialized) + attributes[key] = Attribute.new(coder, attributes[key], serialized) end end diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8c8717b759..c6f2102a5f 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -450,12 +450,12 @@ module ActiveRecord #:nodoc: private def relation #:nodoc: - relation ||= Relation.new(self, arel_table) + @relation ||= Relation.new(self, arel_table) if finder_needs_type_condition? - relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name) + @relation.where(type_condition).create_with(inheritance_column.to_sym => sti_name) else - relation + @relation end end end @@ -489,6 +489,7 @@ module ActiveRecord #:nodoc: @marked_for_destruction = false @previously_changed = {} @changed_attributes = {} + @relation = nil ensure_proper_type @@ -533,7 +534,7 @@ module ActiveRecord #:nodoc: # The dup method does not preserve the timestamps (created|updated)_(at|on). def initialize_dup(other) cloned_attributes = other.clone_attributes(:read_attribute_before_type_cast) - self.class.initialize_attributes(cloned_attributes) + self.class.initialize_attributes(cloned_attributes, :serialized => false) cloned_attributes.delete(self.class.primary_key) diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 2d1517b65e..822f8f73de 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -344,7 +344,8 @@ module ActiveRecord # Is this connection alive and ready for queries? def active? - @connection.status == PGconn::CONNECTION_OK + @connection.query 'SELECT 1' + true rescue PGError false end diff --git a/activerecord/lib/active_record/locking/optimistic.rb b/activerecord/lib/active_record/locking/optimistic.rb index 0e33cdb617..7deac2588a 100644 --- a/activerecord/lib/active_record/locking/optimistic.rb +++ b/activerecord/lib/active_record/locking/optimistic.rb @@ -170,7 +170,7 @@ module ActiveRecord # start the lock version at zero. Note we can't use # <tt>locking_enabled?</tt> at this point as # <tt>@attributes</tt> may not have been initialized yet. - def initialize_attributes(attributes) #:nodoc: + def initialize_attributes(attributes, options = {}) #:nodoc: if attributes.key?(locking_column) && lock_optimistically attributes[locking_column] ||= 0 end diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb index f6497d9bad..b065919310 100644 --- a/activerecord/test/cases/base_test.rb +++ b/activerecord/test/cases/base_test.rb @@ -1280,6 +1280,15 @@ class BasicsTest < ActiveRecord::TestCase assert_equal({ :foo => :bar }, t.content_before_type_cast) end + def test_serialized_attribute_calling_dup_method + klass = Class.new(ActiveRecord::Base) + klass.table_name = "topics" + klass.serialize :content, JSON + + t = klass.new(:content => { :foo => :bar }).dup + assert_equal({ :foo => :bar }, t.content_before_type_cast) + end + def test_serialized_attribute_declared_in_subclass hash = { 'important1' => 'value1', 'important2' => 'value2' } important_topic = ImportantTopic.create("important" => hash) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index 8d8a9d8ad8..fce7d34918 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -3,6 +3,9 @@ * Added #beginning_of_hour and #end_of_hour to Time and DateTime core extensions. *Mark J. Titorenko* +* ActiveSupport::JSON::Variable is deprecated. Define your own #as_json and #encode_json methods + for custom JSON string literals. *Erich Menge* + ## Rails 3.2.3 (March 30, 2012) ## diff --git a/activesupport/lib/active_support/json/encoding.rb b/activesupport/lib/active_support/json/encoding.rb index 4a19387511..91e4f07c6c 100644 --- a/activesupport/lib/active_support/json/encoding.rb +++ b/activesupport/lib/active_support/json/encoding.rb @@ -158,18 +158,18 @@ class Struct #:nodoc: end class TrueClass - AS_JSON = ActiveSupport::JSON::Variable.new('true').freeze - def as_json(options = nil) AS_JSON end #:nodoc: + def as_json(options = nil) self end #:nodoc: + def encode_json(encoder) to_s end #:nodoc: end class FalseClass - AS_JSON = ActiveSupport::JSON::Variable.new('false').freeze - def as_json(options = nil) AS_JSON end #:nodoc: + def as_json(options = nil) self end #:nodoc: + def encode_json(encoder) to_s end #:nodoc: end class NilClass - AS_JSON = ActiveSupport::JSON::Variable.new('null').freeze - def as_json(options = nil) AS_JSON end #:nodoc: + def as_json(options = nil) self end #:nodoc: + def encode_json(encoder) 'null' end #:nodoc: end class String diff --git a/activesupport/lib/active_support/json/variable.rb b/activesupport/lib/active_support/json/variable.rb index 5685ed18b7..17b709decc 100644 --- a/activesupport/lib/active_support/json/variable.rb +++ b/activesupport/lib/active_support/json/variable.rb @@ -1,7 +1,15 @@ +require 'active_support/deprecation' + module ActiveSupport module JSON - # A string that returns itself as its JSON-encoded form. + # Deprecated: A string that returns itself as its JSON-encoded form. class Variable < String + def initialize(*args) + ActiveSupport::Deprecation.warn 'ActiveSupport::JSON::Variable is deprecated and will be removed in Rails 4.0. ' \ + 'For your own custom JSON literals, define #as_json and #encode_json yourself.' + super + end + def as_json(options = nil) self end #:nodoc: def encode_json(encoder) self end #:nodoc: end diff --git a/activesupport/lib/active_support/testing/setup_and_teardown.rb b/activesupport/lib/active_support/testing/setup_and_teardown.rb index 22e41fa905..78d914f8cf 100644 --- a/activesupport/lib/active_support/testing/setup_and_teardown.rb +++ b/activesupport/lib/active_support/testing/setup_and_teardown.rb @@ -28,17 +28,22 @@ module ActiveSupport end module ForMiniTest + PASSTHROUGH_EXCEPTIONS = MiniTest::Unit::TestCase::PASSTHROUGH_EXCEPTIONS rescue [NoMemoryError, SignalException, Interrupt, SystemExit] def run(runner) result = '.' begin run_callbacks :setup do result = super end + rescue *PASSTHROUGH_EXCEPTIONS => e + raise e rescue Exception => e result = runner.puke(self.class, method_name, e) ensure begin run_callbacks :teardown + rescue *PASSTHROUGH_EXCEPTIONS => e + raise e rescue Exception => e result = runner.puke(self.class, method_name, e) end diff --git a/activesupport/test/json/encoding_test.rb b/activesupport/test/json/encoding_test.rb index 8cf1a54a99..d327f34140 100644 --- a/activesupport/test/json/encoding_test.rb +++ b/activesupport/test/json/encoding_test.rb @@ -3,7 +3,7 @@ require 'abstract_unit' require 'active_support/core_ext/string/inflections' require 'active_support/json' -class TestJSONEncoding < Test::Unit::TestCase +class TestJSONEncoding < ActiveSupport::TestCase class Foo def initialize(a, b) @a, @b = a, b @@ -46,8 +46,6 @@ class TestJSONEncoding < Test::Unit::TestCase HashlikeTests = [[ Hashlike.new, %({\"a\":1}) ]] CustomTests = [[ Custom.new, '"custom"' ]] - VariableTests = [[ ActiveSupport::JSON::Variable.new('foo'), 'foo'], - [ ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")']] RegexpTests = [[ /^a/, '"(?-mix:^a)"' ], [/^\w{1,2}[a-z]+/ix, '"(?ix-m:^\\\\w{1,2}[a-z]+)"']] DateTests = [[ Date.new(2005,2,1), %("2005/02/01") ]] @@ -79,6 +77,13 @@ class TestJSONEncoding < Test::Unit::TestCase end end + def test_json_variable + assert_deprecated do + assert_equal ActiveSupport::JSON::Variable.new('foo'), 'foo' + assert_equal ActiveSupport::JSON::Variable.new('alert("foo")'), 'alert("foo")' + end + end + def test_hash_encoding assert_equal %({\"a\":\"b\"}), ActiveSupport::JSON.encode(:a => :b) assert_equal %({\"a\":1}), ActiveSupport::JSON.encode('a' => 1) @@ -270,6 +275,12 @@ class TestJSONEncoding < Test::Unit::TestCase JSON.parse(json_string_and_date)) end + def test_nil_true_and_false_represented_as_themselves + assert_equal nil, nil.as_json + assert_equal true, true.as_json + assert_equal false, false.as_json + end + protected def object_keys(json_object) diff --git a/activesupport/test/test_case_test.rb b/activesupport/test/test_case_test.rb index 756d21b3e4..c4653b1ae6 100644 --- a/activesupport/test/test_case_test.rb +++ b/activesupport/test/test_case_test.rb @@ -19,7 +19,7 @@ module ActiveSupport end if defined?(MiniTest::Assertions) && TestCase < MiniTest::Assertions - def test_callback_with_exception + def test_standard_error_raised_within_setup_callback_is_puked tc = Class.new(TestCase) do setup :bad_callback def bad_callback; raise 'oh noes' end @@ -38,7 +38,7 @@ module ActiveSupport assert_equal 'oh noes', exception.message end - def test_teardown_callback_with_exception + def test_standard_error_raised_within_teardown_callback_is_puked tc = Class.new(TestCase) do teardown :bad_callback def bad_callback; raise 'oh noes' end @@ -56,6 +56,46 @@ module ActiveSupport assert_equal test_name, name assert_equal 'oh noes', exception.message end + + def test_passthrough_exception_raised_within_test_method_is_not_rescued + tc = Class.new(TestCase) do + def test_which_raises_interrupt; raise Interrupt; end + end + + test_name = 'test_which_raises_interrupt' + fr = FakeRunner.new + + test = tc.new test_name + assert_raises(Interrupt) { test.run fr } + end + + def test_passthrough_exception_raised_within_setup_callback_is_not_rescued + tc = Class.new(TestCase) do + setup :callback_which_raises_interrupt + def callback_which_raises_interrupt; raise Interrupt; end + def test_true; assert true end + end + + test_name = 'test_true' + fr = FakeRunner.new + + test = tc.new test_name + assert_raises(Interrupt) { test.run fr } + end + + def test_passthrough_exception_raised_within_teardown_callback_is_not_rescued + tc = Class.new(TestCase) do + teardown :callback_which_raises_interrupt + def callback_which_raises_interrupt; raise Interrupt; end + def test_true; assert true end + end + + test_name = 'test_true' + fr = FakeRunner.new + + test = tc.new test_name + assert_raises(Interrupt) { test.run fr } + end end end end diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 4b7decee5c..52a2df350f 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -234,7 +234,7 @@ module Rails if defined?(JRUBY_VERSION) "gem 'therubyrhino'\n" else - "# gem 'therubyracer', :platform => :ruby\n" + "# gem 'therubyracer', :platforms => :ruby\n" end end diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb index 2286e0477a..2e5f148862 100644 --- a/railties/lib/rails/source_annotation_extractor.rb +++ b/railties/lib/rails/source_annotation_extractor.rb @@ -53,7 +53,7 @@ class SourceAnnotationExtractor # Returns a hash that maps filenames under +dir+ (recursively) to arrays # with their annotations. Only files with annotations are included, and only - # those with extension +.builder+, +.rb+, +.erb+, +.haml+ and +.slim+ + # those with extension +.builder+, +.rb+, +.erb+, +.haml+, +.slim+ and +.coffee+ # are taken into account. def find_in(dir) results = {} @@ -63,7 +63,7 @@ class SourceAnnotationExtractor if File.directory?(item) results.update(find_in(item)) - elsif item =~ /\.(builder|rb)$/ + elsif item =~ /\.(builder|rb|coffee)$/ results.update(extract_annotations_from(item, /#\s*(#{tag}):?\s*(.*)$/)) elsif item =~ /\.erb$/ results.update(extract_annotations_from(item, /<%\s*#\s*(#{tag}):?\s*(.*?)\s*%>/)) diff --git a/railties/test/application/rake/notes_test.rb b/railties/test/application/rake/notes_test.rb index 659cbfec0f..dd401009f7 100644 --- a/railties/test/application/rake/notes_test.rb +++ b/railties/test/application/rake/notes_test.rb @@ -7,7 +7,7 @@ module ApplicationTests build_app require "rails/all" end - + def teardown teardown_app end @@ -17,6 +17,8 @@ module ApplicationTests app_file "app/views/home/index.html.erb", "<% # TODO: note in erb %>" app_file "app/views/home/index.html.haml", "-# TODO: note in haml" app_file "app/views/home/index.html.slim", "/ TODO: note in slim" + app_file "app/assets/javascripts/application.js.coffee", "# TODO: note in coffee" + app_file "app/controllers/application_controller.rb", 1000.times.map { "" }.join("\n") << "# TODO: note in ruby" boot_rails require 'rake' @@ -24,17 +26,19 @@ module ApplicationTests require 'rake/testtask' Rails.application.load_tasks - + Dir.chdir(app_path) do output = `bundle exec rake notes` - + assert_match /note in erb/, output assert_match /note in haml/, output assert_match /note in slim/, output + assert_match /note in ruby/, output + assert_match /note in coffee/, output end - + end - + private def boot_rails super diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 5bf1dbda8d..90a49e8085 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -253,7 +253,7 @@ class AppGeneratorTest < Rails::Generators::TestCase if defined?(JRUBY_VERSION) assert_file "Gemfile", /gem\s+["']therubyrhino["']$/ else - assert_file "Gemfile", /# gem\s+["']therubyracer["']+, :platform => :ruby$/ + assert_file "Gemfile", /# gem\s+["']therubyracer["']+, :platforms => :ruby$/ end end |