Make test attributes explicit

- Organize test poros with associations and by serializer
- Freeze derived attributes/associations against mutation
- Cleanup PORO fixtures
This commit is contained in:
Benjamin Fleischer
2016-11-21 09:31:11 -06:00
parent 095ad9c82c
commit 80af763d2e
20 changed files with 380 additions and 278 deletions

View File

@@ -38,6 +38,14 @@ module ActiveModelSerializers
@default_include_directive ||= JSONAPI::IncludeDirective.new(config.default_includes, allow_wildcard: true)
end
def self.silence_warnings
original_verbose = $VERBOSE
$VERBOSE = nil
yield
ensure
$VERBOSE = original_verbose
end
require 'active_model/serializer/version'
require 'active_model/serializer'
require 'active_model/serializable_resource'

View File

@@ -3,42 +3,58 @@
# serializable non-activerecord objects.
module ActiveModelSerializers
class Model
include ActiveModel::Model
include ActiveModel::Serializers::JSON
include ActiveModel::Model
class_attribute :attribute_names
# Initialize +attribute_names+ for all subclasses. The array is usually
# mutated in the +attributes+ method, but can be set directly, as well.
self.attribute_names = []
def self.attributes(*names)
attr_accessor(*names)
self.attribute_names |= names.map(&:to_sym)
# Silence redefinition of methods warnings
ActiveModelSerializers.silence_warnings do
attr_accessor(*names)
end
end
attr_reader :attributes, :errors
attr_reader :errors
# NOTE that +updated_at+ isn't included in +attribute_names+,
# which means it won't show up in +attributes+ unless a subclass has
# either <tt>attributes :updated_at</tt> which will redefine the methods
# or <tt>attribute_names << :updated_at</tt>.
attr_writer :updated_at
# NOTE that +id+ will always be in +attributes+.
attributes :id
def initialize(attributes = {})
@attributes = attributes && attributes.symbolize_keys
@errors = ActiveModel::Errors.new(self)
super
end
# Defaults to the downcased model name.
def id
attributes.fetch(:id) { self.class.name.downcase }
# The the fields in +attribute_names+ determines the returned hash.
# +attributes+ are returned frozen to prevent any expectations that mutation affects
# the actual values in the model.
def attributes
attribute_names.each_with_object({}) do |attribute_name, result|
result[attribute_name] = public_send(attribute_name).freeze
end.with_indifferent_access.freeze
end
# Defaults to the downcased model name and updated_at
# To customize model behavior, this method must be redefined. However,
# there are other ways of setting the +cache_key+ a serializer uses.
def cache_key
attributes.fetch(:cache_key) { "#{self.class.name.downcase}/#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}" }
ActiveSupport::Cache.expand_cache_key([
self.class.model_name.name.downcase,
"#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}"
].compact)
end
# Defaults to the time the serializer file was modified.
# When no set, defaults to the time the file was modified.
# See NOTE by attr_writer :updated_at
def updated_at
attributes.fetch(:updated_at) { File.mtime(__FILE__) }
end
def read_attribute_for_serialization(key)
if key == :id || key == 'id'
attributes.fetch(key) { id }
else
attributes[key]
end
defined?(@updated_at) ? @updated_at : File.mtime(__FILE__)
end
# The following methods are needed to be minimally implemented for ActiveModel::Errors