From 530a1bdfd7cc2fd6587da864efab373ceecad961 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Fri, 21 Aug 2015 02:23:34 -0400 Subject: [PATCH 1/4] Compartmentalize test helper support --- test/support/rails_app.rb | 21 +++++++++ test/support/stream_capture.rb | 49 ++++++++++++++++++++ test/support/test_case.rb | 5 ++ test/test_helper.rb | 85 ++++------------------------------ 4 files changed, 83 insertions(+), 77 deletions(-) create mode 100644 test/support/rails_app.rb create mode 100644 test/support/stream_capture.rb create mode 100644 test/support/test_case.rb diff --git a/test/support/rails_app.rb b/test/support/rails_app.rb new file mode 100644 index 000000000..c567de2db --- /dev/null +++ b/test/support/rails_app.rb @@ -0,0 +1,21 @@ +class Foo < Rails::Application + if Rails::VERSION::MAJOR >= 4 + config.eager_load = false + config.secret_key_base = 'abc123' + config.action_controller.perform_caching = true + config.active_support.test_order = :random + config.logger = Logger.new(nil) + ActionController::Base.cache_store = :memory_store + end +end +Foo.initialize! + +module TestHelper + Routes = ActionDispatch::Routing::RouteSet.new + Routes.draw do + get ':controller(/:action(/:id))' + get ':controller(/:action)' + end + + ActionController::Base.send :include, Routes.url_helpers +end diff --git a/test/support/stream_capture.rb b/test/support/stream_capture.rb new file mode 100644 index 000000000..49e3a1454 --- /dev/null +++ b/test/support/stream_capture.rb @@ -0,0 +1,49 @@ +# Use cleaner stream testing interface from Rails 5 if available +# see https://github.com/rails/rails/blob/29959eb59d/activesupport/lib/active_support/testing/stream.rb +begin + require "active_support/testing/stream" +rescue LoadError + module ActiveSupport + module Testing + module Stream #:nodoc: + private + + def silence_stream(stream) + old_stream = stream.dup + stream.reopen(IO::NULL) + stream.sync = true + yield + ensure + stream.reopen(old_stream) + old_stream.close + end + + def quietly + silence_stream(STDOUT) do + silence_stream(STDERR) do + yield + end + end + end + + def capture(stream) + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}") + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + return captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end + end + end + end +end + diff --git a/test/support/test_case.rb b/test/support/test_case.rb new file mode 100644 index 000000000..66e8648d2 --- /dev/null +++ b/test/support/test_case.rb @@ -0,0 +1,5 @@ +ActionController::TestCase.class_eval do + def setup + @routes = TestHelper::Routes + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 68d844e69..e3eebae40 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -6,12 +6,15 @@ require 'action_controller/test_case' require 'action_controller/railtie' require 'active_support/json' -require 'minitest/autorun' require 'fileutils' +FileUtils.mkdir_p(File.expand_path('../../tmp/cache', __FILE__)) + +require 'minitest/autorun' # Ensure backward compatibility with Minitest 4 Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test) -require "capture_warnings" + +require 'capture_warnings' @capture_warnings = CaptureWarnings.new(fail_build = false) @capture_warnings.before_tests at_exit do @@ -19,82 +22,10 @@ end require 'active_model_serializers' -# Use cleaner stream testing interface from Rails 5 if available -# see https://github.com/rails/rails/blob/29959eb59d/activesupport/lib/active_support/testing/stream.rb -begin - require "active_support/testing/stream" -rescue LoadError - module ActiveSupport - module Testing - module Stream #:nodoc: - private +require 'support/stream_capture' - def silence_stream(stream) - old_stream = stream.dup - stream.reopen(IO::NULL) - stream.sync = true - yield - ensure - stream.reopen(old_stream) - old_stream.close - end - - def quietly - silence_stream(STDOUT) do - silence_stream(STDERR) do - yield - end - end - end - - def capture(stream) - stream = stream.to_s - captured_stream = Tempfile.new(stream) - stream_io = eval("$#{stream}") - origin_stream = stream_io.dup - stream_io.reopen(captured_stream) - - yield - - stream_io.rewind - return captured_stream.read - ensure - captured_stream.close - captured_stream.unlink - stream_io.reopen(origin_stream) - end - end - end - end -end - -class Foo < Rails::Application - if Rails::VERSION::MAJOR >= 4 - config.eager_load = false - config.secret_key_base = 'abc123' - config.action_controller.perform_caching = true - config.active_support.test_order = :random - config.logger = Logger.new(nil) - ActionController::Base.cache_store = :memory_store - end -end -FileUtils.mkdir_p(File.expand_path('../../tmp/cache', __FILE__)) -Foo.initialize! +require 'support/rails_app' require 'fixtures/poro' -module TestHelper - Routes = ActionDispatch::Routing::RouteSet.new - Routes.draw do - get ':controller(/:action(/:id))' - get ':controller(/:action)' - end - - ActionController::Base.send :include, Routes.url_helpers -end - -ActionController::TestCase.class_eval do - def setup - @routes = TestHelper::Routes - end -end +require 'support/test_case' From a8e9bb1c14cf5f05405761d8b9427f30a4ed27f2 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Fri, 21 Aug 2015 02:23:36 -0400 Subject: [PATCH 2/4] Remove uniq on warnings that confused output --- test/capture_warnings.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/capture_warnings.rb b/test/capture_warnings.rb index f7ea759ba..76e77b7bb 100644 --- a/test/capture_warnings.rb +++ b/test/capture_warnings.rb @@ -20,7 +20,7 @@ def before_tests def after_tests stderr_file.rewind - lines = stderr_file.read.split("\n").uniq + lines = stderr_file.read.split("\n") stderr_file.close! $stderr.reopen(STDERR) From 9aad8b4d298c130eebae00abe05aba431ec930b5 Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Fri, 21 Aug 2015 03:01:54 -0400 Subject: [PATCH 3/4] Cleanup CaptureWarnings after_run --- test/test_helper.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index e3eebae40..eee2d0490 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -17,9 +17,10 @@ require 'capture_warnings' @capture_warnings = CaptureWarnings.new(fail_build = false) @capture_warnings.before_tests -at_exit do +Minitest.after_run do @capture_warnings.after_tests end + require 'active_model_serializers' require 'support/stream_capture' From d315151e8a1a55cb1d46d80a56c6ad599c08a9ab Mon Sep 17 00:00:00 2001 From: Benjamin Fleischer Date: Fri, 21 Aug 2015 02:23:37 -0400 Subject: [PATCH 4/4] Fix warnings JRuby-specific: fix 'warning: (...) interpreted as grouped expression' --- lib/active_model/serializable_resource.rb | 4 ++- lib/active_model/serializer.rb | 5 ++-- lib/active_model/serializer/adapter.rb | 29 +++++++++---------- .../serializer/adapter/json/fragment_cache.rb | 3 +- .../adapter/json_api/fragment_cache.rb | 3 +- lib/active_model/serializer/associations.rb | 8 ++--- lib/active_model/serializer/fieldset.rb | 4 ++- lib/active_model_serializers.rb | 13 ++++++++- .../serialization_scope_name_test.rb | 14 +++++---- test/action_controller/serialization_test.rb | 11 +++---- test/adapter/json/belongs_to_test.rb | 1 - test/fixtures/poro.rb | 9 ++---- test/generators/serializer_generator_test.rb | 4 +-- test/serializers/associations_test.rb | 2 +- test/serializers/cache_test.rb | 8 ++--- test/test_helper.rb | 13 +++++++-- 16 files changed, 77 insertions(+), 54 deletions(-) diff --git a/lib/active_model/serializable_resource.rb b/lib/active_model/serializable_resource.rb index fa3fbe035..aa8f139a2 100644 --- a/lib/active_model/serializable_resource.rb +++ b/lib/active_model/serializable_resource.rb @@ -1,4 +1,4 @@ -require "set" +require 'set' module ActiveModel class SerializableResource @@ -76,7 +76,9 @@ def serializer? private + ActiveModelSerializers.silence_warnings do attr_reader :resource, :adapter_opts, :serializer_opts + end end end diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index 1395b7781..6472a4114 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -9,6 +9,7 @@ class Serializer autoload :Adapter autoload :Lint autoload :Associations + autoload :Fieldset include Configuration include Associations @@ -66,10 +67,10 @@ def self.attribute(attr, options = {}) @_attributes_keys[attr] = { key: key } if key != attr @_attributes << key unless @_attributes.include?(key) - unless respond_to?(key, false) || _fragmented.respond_to?(attr) + ActiveModelSerializers.silence_warnings do define_method key do object.read_attribute_for_serialization(attr) - end + end unless respond_to?(key, false) || _fragmented.respond_to?(attr) end end diff --git a/lib/active_model/serializer/adapter.rb b/lib/active_model/serializer/adapter.rb index 0b8118d60..69593828a 100644 --- a/lib/active_model/serializer/adapter.rb +++ b/lib/active_model/serializer/adapter.rb @@ -1,13 +1,23 @@ -require 'active_model/serializer/adapter/fragment_cache' - module ActiveModel class Serializer class Adapter extend ActiveSupport::Autoload - autoload :Json + require 'active_model/serializer/adapter/json' + require 'active_model/serializer/adapter/json_api' autoload :FlattenJson autoload :Null - autoload :JsonApi + autoload :FragmentCache + + def self.create(resource, options = {}) + override = options.delete(:adapter) + klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter + klass.new(resource, options) + end + + def self.adapter_class(adapter) + adapter_name = adapter.to_s.classify.sub("API", "Api") + "ActiveModel::Serializer::Adapter::#{adapter_name}".safe_constantize + end attr_reader :serializer @@ -26,17 +36,6 @@ def as_json(options = nil) hash end - def self.create(resource, options = {}) - override = options.delete(:adapter) - klass = override ? adapter_class(override) : ActiveModel::Serializer.adapter - klass.new(resource, options) - end - - def self.adapter_class(adapter) - adapter_name = adapter.to_s.classify.sub("API", "Api") - "ActiveModel::Serializer::Adapter::#{adapter_name}".safe_constantize - end - def fragment_cache(*args) raise NotImplementedError, 'This is an abstract method. Should be implemented at the concrete adapter.' end diff --git a/lib/active_model/serializer/adapter/json/fragment_cache.rb b/lib/active_model/serializer/adapter/json/fragment_cache.rb index 761a6e548..0d01b87a2 100644 --- a/lib/active_model/serializer/adapter/json/fragment_cache.rb +++ b/lib/active_model/serializer/adapter/json/fragment_cache.rb @@ -1,3 +1,4 @@ +require 'active_model/serializer/adapter/fragment_cache' module ActiveModel class Serializer class Adapter @@ -12,4 +13,4 @@ def fragment_cache(cached_hash, non_cached_hash) end end end -end \ No newline at end of file +end diff --git a/lib/active_model/serializer/adapter/json_api/fragment_cache.rb b/lib/active_model/serializer/adapter/json_api/fragment_cache.rb index 6ce1c1848..d266801fe 100644 --- a/lib/active_model/serializer/adapter/json_api/fragment_cache.rb +++ b/lib/active_model/serializer/adapter/json_api/fragment_cache.rb @@ -1,3 +1,4 @@ +require 'active_model/serializer/adapter/fragment_cache' module ActiveModel class Serializer class Adapter @@ -20,4 +21,4 @@ def fragment_cache(root, cached_hash, non_cached_hash) end end end -end \ No newline at end of file +end diff --git a/lib/active_model/serializer/associations.rb b/lib/active_model/serializer/associations.rb index f864a0f0a..1320eae3e 100644 --- a/lib/active_model/serializer/associations.rb +++ b/lib/active_model/serializer/associations.rb @@ -73,11 +73,9 @@ def has_one(name, options = {}) def associate(reflection) self._reflections = _reflections.dup - unless method_defined?(reflection.name) - define_method reflection.name do - object.send reflection.name - end - end + define_method reflection.name do + object.send reflection.name + end unless method_defined?(reflection.name) self._reflections << reflection end diff --git a/lib/active_model/serializer/fieldset.rb b/lib/active_model/serializer/fieldset.rb index 3ff42bedd..63333cf27 100644 --- a/lib/active_model/serializer/fieldset.rb +++ b/lib/active_model/serializer/fieldset.rb @@ -18,7 +18,9 @@ def fields_for(serializer) private + ActiveModelSerializers.silence_warnings do attr_reader :raw_fields, :root + end def parsed_fields if raw_fields.is_a?(Hash) @@ -37,4 +39,4 @@ def parsed_fields end end -end \ No newline at end of file +end diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb index 211a2870e..01c23e5f7 100644 --- a/lib/active_model_serializers.rb +++ b/lib/active_model_serializers.rb @@ -1,7 +1,18 @@ +module ActiveModelSerializers + module_function + + def silence_warnings + verbose = $VERBOSE + $VERBOSE = nil + yield + ensure + $VERBOSE = verbose + end + +end require 'active_model' require 'active_model/serializer/version' require 'active_model/serializer' -require 'active_model/serializer/fieldset' require 'active_model/serializable_resource' begin diff --git a/test/action_controller/serialization_scope_name_test.rb b/test/action_controller/serialization_scope_name_test.rb index 2af0a1fa9..6e2b15e6e 100644 --- a/test/action_controller/serialization_scope_name_test.rb +++ b/test/action_controller/serialization_scope_name_test.rb @@ -4,8 +4,10 @@ class DefaultScopeNameTest < ActionController::TestCase class UserSerializer < ActiveModel::Serializer attributes :admin? - def admin? - current_user.admin + ActiveModelSerializers.silence_warnings do + def admin? + current_user.admin + end end end @@ -34,8 +36,10 @@ def test_default_scope_name class SerializationScopeNameTest < ActionController::TestCase class AdminUserSerializer < ActiveModel::Serializer attributes :admin? - def admin? - current_admin.admin + ActiveModelSerializers.silence_warnings do + def admin? + current_admin.admin + end end end @@ -60,4 +64,4 @@ def test_override_scope_name_with_controller get :render_new_user assert_equal '{"data":{"id":"1","type":"users","attributes":{"admin?":true}}}', @response.body end -end \ No newline at end of file +end diff --git a/test/action_controller/serialization_test.rb b/test/action_controller/serialization_test.rb index 8c89ceac0..fab43af07 100644 --- a/test/action_controller/serialization_test.rb +++ b/test/action_controller/serialization_test.rb @@ -129,7 +129,6 @@ def render_fragment_changed_object_with_except_cache_enabled def render_fragment_changed_object_with_relationship comment = Comment.new({ id: 1, body: 'ZOMG A COMMENT' }) comment2 = Comment.new({ id: 1, body: 'ZOMG AN UPDATED-BUT-NOT-CACHE-EXPIRED COMMENT' }) - author = Author.new(id: 1, name: 'Joao Moura.') like = Like.new({ id: 1, likeable: comment, time: 3.days.ago }) generate_cached_serializer(like) @@ -215,14 +214,16 @@ def test_render_json_object_without_serializer get :render_json_object_without_serializer assert_equal 'application/json', @response.content_type - assert_equal ({error: 'Result is Invalid'}).to_json, @response.body + expected_body = {error: 'Result is Invalid'} + assert_equal expected_body.to_json, @response.body end def test_render_json_array_object_without_serializer get :render_json_array_object_without_serializer assert_equal 'application/json', @response.content_type - assert_equal ([{error: 'Result is Invalid'}]).to_json, @response.body + expected_body = [{error: 'Result is Invalid'}] + assert_equal expected_body.to_json, @response.body end def test_render_array_using_implicit_serializer @@ -405,9 +406,9 @@ def use_adapter? false end }.new - assert_match /adapter: false/, (capture(:stderr) { + assert_match(/adapter: false/, (capture(:stderr) { controller.get_serializer(Profile.new) - }) + })) end def test_dont_warn_overridding_use_adapter_as_truthy_on_controller_instance diff --git a/test/adapter/json/belongs_to_test.rb b/test/adapter/json/belongs_to_test.rb index a5dbfe14d..f39080fd5 100644 --- a/test/adapter/json/belongs_to_test.rb +++ b/test/adapter/json/belongs_to_test.rb @@ -11,7 +11,6 @@ def setup @comment = Comment.new(id: 1, body: 'ZOMG A COMMENT') @post.comments = [@comment] @anonymous_post.comments = [] - @post.author = @author @comment.post = @post @comment.author = nil @anonymous_post.author = nil diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index 2b281049c..0c0e3a587 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -1,3 +1,5 @@ +verbose = $VERBOSE +$VERBOSE = nil class Model FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read) @@ -260,9 +262,4 @@ def maker cache only: [:id] attributes :id end - -RaiseErrorSerializer = Class.new(ActiveModel::Serializer) do - def json_key - raise StandardError, 'Intentional error for rescue_from test' - end -end +$VERBOSE = verbose diff --git a/test/generators/serializer_generator_test.rb b/test/generators/serializer_generator_test.rb index e5c87d401..7af39ed12 100644 --- a/test/generators/serializer_generator_test.rb +++ b/test/generators/serializer_generator_test.rb @@ -47,9 +47,9 @@ def test_with_no_attributes_does_not_add_extra_space run_generator ["account"] assert_file "app/serializers/account_serializer.rb" do |content| if RUBY_PLATFORM =~ /mingw/ - assert_no_match /\r\n\r\nend/, content + assert_no_match(/\r\n\r\nend/, content) else - assert_no_match /\n\nend/, content + assert_no_match(/\n\nend/, content) end end end diff --git a/test/serializers/associations_test.rb b/test/serializers/associations_test.rb index 89afdcc67..b7b77cf95 100644 --- a/test/serializers/associations_test.rb +++ b/test/serializers/associations_test.rb @@ -81,7 +81,7 @@ def test_has_many_with_no_serializer def test_serializer_options_are_passed_into_associations_serializers association = @post_serializer .associations - .detect { |association| association.key == :comments } + .detect { |assoc| assoc.key == :comments } assert association.serializer.first.custom_options[:custom_options] end diff --git a/test/serializers/cache_test.rb b/test/serializers/cache_test.rb index a57faa2d1..afa583270 100644 --- a/test/serializers/cache_test.rb +++ b/test/serializers/cache_test.rb @@ -47,13 +47,13 @@ def test_cache_key_definition end def test_cache_key_interpolation_with_updated_at - author = render_object_with_cache(@author) + render_object_with_cache(@author) assert_equal(nil, ActionController::Base.cache_store.fetch(@author.cache_key)) assert_equal(@author_serializer.attributes.to_json, ActionController::Base.cache_store.fetch("#{@author_serializer.class._cache_key}/#{@author_serializer.object.id}-#{@author_serializer.object.updated_at.strftime("%Y%m%d%H%M%S%9N")}").to_json) end def test_default_cache_key_fallback - comment = render_object_with_cache(@comment) + render_object_with_cache(@comment) assert_equal(@comment_serializer.attributes.to_json, ActionController::Base.cache_store.fetch(@comment.cache_key).to_json) end @@ -74,7 +74,7 @@ def test_associations_separately_cache assert_equal(nil, ActionController::Base.cache_store.fetch(@comment.cache_key)) Timecop.freeze(Time.now) do - post = render_object_with_cache(@post) + render_object_with_cache(@post) assert_equal(@post_serializer.attributes, ActionController::Base.cache_store.fetch(@post.cache_key)) assert_equal(@comment_serializer.attributes, ActionController::Base.cache_store.fetch(@comment.cache_key)) @@ -122,7 +122,7 @@ def test_fragment_fetch_with_virtual_associations end def test_uses_file_digest_in_cache_key - blog = render_object_with_cache(@blog) + render_object_with_cache(@blog) assert_equal(@blog_serializer.attributes, ActionController::Base.cache_store.fetch(@blog.cache_key_with_digest)) end diff --git a/test/test_helper.rb b/test/test_helper.rb index eee2d0490..1327188e2 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -15,10 +15,17 @@ require 'capture_warnings' -@capture_warnings = CaptureWarnings.new(fail_build = false) +@capture_warnings = CaptureWarnings.new(fail_build = true) @capture_warnings.before_tests -Minitest.after_run do - @capture_warnings.after_tests +if Minitest.respond_to?(:after_run) + Minitest.after_run do + @capture_warnings.after_tests + end +else + at_exit do + STDOUT.puts "Minitest.after_run not available." + @capture_warnings.after_tests + end end require 'active_model_serializers'