diff --git a/Gemfile b/Gemfile index bdfff856..e0a4364c 100644 --- a/Gemfile +++ b/Gemfile @@ -3,17 +3,32 @@ source 'https://rubygems.org' # Specify your gem's dependencies in active_model_serializers.gemspec gemspec -gem "minitest" +version = ENV['RAILS_VERSION'] || '4.2' -version = ENV["RAILS_VERSION"] || "4.2" - -if version == "master" - gem "rails", github: "rails/rails" - - # ugh https://github.com/rails/rails/issues/16063#issuecomment-48090125 - gem "arel", github: "rails/arel" +if version == 'master' + gem 'rack', github: 'rack/rack' + git 'https://github.com/rails/rails.git' do + gem 'railties' + gem 'activesupport' + gem 'activemodel' + gem 'actionpack' + # Rails 5 + gem 'actionview' + end + # Rails 5 + gem 'rails-controller-testing', github: 'rails/rails-controller-testing' else - gem "rails", "~> #{version}.0" + gem_version = "~> #{version}.0" + gem 'railties', gem_version + gem 'activesupport', gem_version + gem 'activemodel', gem_version + gem 'actionpack', gem_version +end + +group :test do + gem 'activerecord' + gem 'sqlite3', platform: :ruby + gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem diff --git a/active_model_serializers.gemspec b/active_model_serializers.gemspec index eff27ca9..de385a97 100644 --- a/active_model_serializers.gemspec +++ b/active_model_serializers.gemspec @@ -4,26 +4,47 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'active_model/serializer/version' Gem::Specification.new do |spec| - spec.name = "active_model_serializers" + spec.name = 'active_model_serializers' spec.version = ActiveModel::Serializer::VERSION - spec.authors = ["Steve Klabnik"] - spec.email = ["steve@steveklabnik.com"] + spec.platform = Gem::Platform::RUBY + spec.authors = ['Steve Klabnik'] + spec.email = ['steve@steveklabnik.com'] spec.summary = %q{Conventions-based JSON generation for Rails.} spec.description = %q{ActiveModel::Serializers allows you to generate your JSON in an object-oriented and convention-driven manner.} - spec.homepage = "https://github.com/rails-api/active_model_serializers" - spec.license = "MIT" + spec.homepage = 'https://github.com/rails-api/active_model_serializers' + spec.license = 'MIT' spec.files = `git ls-files -z`.split("\x0") - spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) - spec.require_paths = ["lib"] + spec.require_paths = ['lib'] - spec.add_dependency "activemodel", ">= 4.0" + spec.required_ruby_version = '>= 1.9.3' - spec.add_development_dependency "rails", ">= 4.0" - spec.add_development_dependency "bundler", "~> 1.6" - spec.add_development_dependency "timecop", ">= 0.7" - spec.add_development_dependency "rake" - spec.add_development_dependency "kaminari" - spec.add_development_dependency "will_paginate" + rails_versions = '>= 4.0' + spec.add_runtime_dependency 'activemodel', rails_versions + # 'activesupport', rails_versions + # 'builder' + + spec.add_runtime_dependency 'actionpack', rails_versions + # 'activesupport', rails_versions + # 'rack' + # 'rack-test', '~> 0.6.2' + + spec.add_runtime_dependency 'railties', rails_versions + # 'activesupport', rails_versions + # 'actionpack', rails_versions + # 'rake', '>= 0.8.7' + + # 'activesupport', rails_versions + # 'i18n, + # 'tzinfo' + # 'minitest' + # 'thread_safe' + + # Soft dependency for pagination + spec.add_development_dependency 'kaminari' + spec.add_development_dependency 'will_paginate' + + spec.add_development_dependency 'bundler', '~> 1.6' + spec.add_development_dependency 'timecop', '>= 0.7' end diff --git a/lib/active_model/serializer.rb b/lib/active_model/serializer.rb index a9f0e756..6e6833bb 100644 --- a/lib/active_model/serializer.rb +++ b/lib/active_model/serializer.rb @@ -70,7 +70,7 @@ module ActiveModel ActiveModelSerializers.silence_warnings do define_method key do object.read_attribute_for_serialization(attr) - end unless respond_to?(key, false) || _fragmented.respond_to?(attr) + end unless (key != :id && method_defined?(key)) || _fragmented.respond_to?(attr) end end diff --git a/lib/active_model/serializer/association.rb b/lib/active_model/serializer/association.rb index af1cb914..bca03665 100644 --- a/lib/active_model/serializer/association.rb +++ b/lib/active_model/serializer/association.rb @@ -7,7 +7,7 @@ module ActiveModel # @param [Hash{Symbol => Object}] options # # @example - # Association.new(:comments, CommentSummarySerializer, embed: :ids) + # Association.new(:comments, CommentSummarySerializer) # Association = Struct.new(:name, :serializer, :options) do diff --git a/lib/active_model/serializer/lint.rb b/lib/active_model/serializer/lint.rb index 97ffcd7f..bf3b7a37 100644 --- a/lib/active_model/serializer/lint.rb +++ b/lib/active_model/serializer/lint.rb @@ -36,7 +36,17 @@ module ActiveModel::Serializer::Lint # Typically, it is implemented by including ActiveModel::Serialization. def test_read_attribute_for_serialization assert_respond_to resource, :read_attribute_for_serialization, "The resource should respond to read_attribute_for_serialization" - assert_equal resource.method(:read_attribute_for_serialization).arity, 1 + actual_arity = resource.method(:read_attribute_for_serialization).arity + if defined?(::Rubinius) + # 1 for def read_attribute_for_serialization(name); end + # -2 for alias :read_attribute_for_serialization :send for rbx because :shrug: + assert_includes [1, -2], actual_arity, "expected #{actual_arity.inspect} to be 1 or -2" + else + # using absolute value since arity is: + # 1 for def read_attribute_for_serialization(name); end + # -1 for alias :read_attribute_for_serialization :send + assert_includes [1, -1], actual_arity, "expected #{actual_arity.inspect} to be 1 or -1" + end end # Passes if the object responds to as_json and if it takes @@ -68,7 +78,7 @@ module ActiveModel::Serializer::Lint end # Passes if the object responds to cache_key and if it takes no - # arguments. + # arguments (Rails 4.0) or a splat (Rails 4.1+). # Fails otherwise. # # cache_key returns a (self-expiring) unique key for the object, @@ -76,7 +86,11 @@ module ActiveModel::Serializer::Lint # It is not required unless caching is enabled. def test_cache_key assert_respond_to resource, :cache_key - assert_equal resource.method(:cache_key).arity, 0 + actual_arity = resource.method(:cache_key).arity + # using absolute value since arity is: + # 0 for Rails 4.1+, *timestamp_names + # -1 for Rails 4.0, no arguments + assert_includes [-1, 0], actual_arity, "expected #{actual_arity.inspect} to be 0 or -1" end # Passes if the object responds to id and if it takes no diff --git a/lib/active_model_serializers.rb b/lib/active_model_serializers.rb index 01c23e5f..8b90ba7a 100644 --- a/lib/active_model_serializers.rb +++ b/lib/active_model_serializers.rb @@ -10,22 +10,20 @@ module ActiveModelSerializers end end + require 'active_model' -require 'active_model/serializer/version' +require 'action_controller' + require 'active_model/serializer' require 'active_model/serializable_resource' +require 'active_model/serializer/version' -begin - require 'active_model/serializer/railtie' - require 'action_controller' - require 'action_controller/serialization' - - ActiveSupport.on_load(:action_controller) do - include ::ActionController::Serialization - ActionDispatch::Reloader.to_prepare do - ActiveModel::Serializer.serializers_cache.clear - end +require 'action_controller/serialization' +ActiveSupport.on_load(:action_controller) do + include ::ActionController::Serialization + ActionDispatch::Reloader.to_prepare do + ActiveModel::Serializer.serializers_cache.clear end -rescue LoadError - # rails not installed, continuing end + +require 'active_model/serializer/railtie' diff --git a/test/fixtures/active_record.rb b/test/fixtures/active_record.rb new file mode 100644 index 00000000..ab3e4d85 --- /dev/null +++ b/test/fixtures/active_record.rb @@ -0,0 +1,57 @@ +require 'active_record' + +ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:') +ActiveRecord::Schema.define do + create_table :posts, force: true do |t| + t.string :title + t.text :body + t.references :author + t.timestamps null: false + end + create_table :authors, force: true do |t| + t.string :name + t.timestamps null: false + end + create_table :comments, force: true do |t| + t.text :contents + t.references :author + t.references :post + t.timestamp null: false + end +end + +module ARModels + class Post < ActiveRecord::Base + has_many :comments + belongs_to :author + end + + class Comment < ActiveRecord::Base + belongs_to :post + belongs_to :author + end + + class Author < ActiveRecord::Base + has_many :posts + end + + class PostSerializer < ActiveModel::Serializer + attributes :id, :title, :body + + has_many :comments + belongs_to :author + url :comments + end + + class CommentSerializer < ActiveModel::Serializer + attributes :id, :contents + + belongs_to :author + end + + class AuthorSerializer < ActiveModel::Serializer + attributes :id, :name + + has_many :posts + end +end diff --git a/test/fixtures/poro.rb b/test/fixtures/poro.rb index 0c0e3a58..815205c4 100644 --- a/test/fixtures/poro.rb +++ b/test/fixtures/poro.rb @@ -134,10 +134,11 @@ end AuthorSerializer = Class.new(ActiveModel::Serializer) do cache key:'writer', skip_digest: true - attributes :id, :name + attribute :id + attribute :name - has_many :posts, embed: :ids - has_many :roles, embed: :ids + has_many :posts + has_many :roles has_one :bio end diff --git a/test/serializers/association_macros_test.rb b/test/serializers/association_macros_test.rb index f99e1980..30202f4a 100644 --- a/test/serializers/association_macros_test.rb +++ b/test/serializers/association_macros_test.rb @@ -6,7 +6,7 @@ module ActiveModel AuthorSummarySerializer = Class.new class AssociationsTestSerializer < Serializer belongs_to :author, serializer: AuthorSummarySerializer - has_many :comments, embed: :ids + has_many :comments has_one :category end @@ -21,7 +21,7 @@ module ActiveModel end def test_has_many_defines_reflection - has_many_reflection = HasManyReflection.new(:comments, embed: :ids) + has_many_reflection = HasManyReflection.new(:comments, {}) assert_includes(@reflections, has_many_reflection) end diff --git a/test/serializers/associations_test.rb b/test/serializers/associations_test.rb index b7b77cf9..bfc1b40c 100644 --- a/test/serializers/associations_test.rb +++ b/test/serializers/associations_test.rb @@ -52,13 +52,13 @@ module ActiveModel case key when :posts - assert_equal({ embed: :ids }, options) + assert_equal({}, options) assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer) when :bio assert_equal({}, options) assert_nil serializer when :roles - assert_equal({ embed: :ids }, options) + assert_equal({}, options) assert_kind_of(ActiveModel::Serializer.config.array_serializer, serializer) else flunk "Unknown association: #{key}" diff --git a/test/test_helper.rb b/test/test_helper.rb index 115972d6..7df3b118 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -34,8 +34,10 @@ require 'support/stream_capture' require 'support/rails_app' -require 'fixtures/poro' - require 'support/test_case' require 'support/serialization_testing' + +require 'fixtures/active_record' + +require 'fixtures/poro'