New take on configuration

This commit is contained in:
Adrian Mugnolo and Santiago Pastorino 2014-01-10 19:25:43 -02:00
parent cf91146471
commit 0ba4830dee
6 changed files with 137 additions and 134 deletions

View File

@ -1,7 +1,7 @@
require 'active_model/array_serializer' require 'active_model/array_serializer'
require 'active_model/serializable' require 'active_model/serializable'
require 'active_model/serializer/associations' require 'active_model/serializer/associations'
require 'active_model/serializer/config' require 'active_model/serializer/configuration'
require 'active_model/serializer/dsl' require 'active_model/serializer/dsl'
require 'thread' require 'thread'
@ -22,22 +22,13 @@ module ActiveModel
def setup def setup
@mutex.synchronize do @mutex.synchronize do
yield CONFIG yield Configuration.global
end end
end end
def embed(type, options={}) def embed(type, options={})
CONFIG.embed = type Configuration.global.embed = type
CONFIG.embed_in_root = true if options[:embed_in_root] || options[:include] Configuration.global.embed_in_root = true if options[:embed_in_root] || options[:include]
ActiveSupport::Deprecation.warn <<-WARN
** Notice: embed is deprecated. **
The use of .embed method on a Serializer will be soon removed, as this should have a global scope and not a class scope.
Please use the global .setup method instead:
ActiveModel::Serializer.setup do |config|
config.embed = :#{type}
config.embed_in_root = #{CONFIG.embed_in_root || false}
end
WARN
end end
if RUBY_VERSION >= '2.0' if RUBY_VERSION >= '2.0'
@ -74,6 +65,10 @@ end
def_delegators :dsl, :attributes, :has_one, :has_many def_delegators :dsl, :attributes, :has_one, :has_many
def configuration
@configuration ||= Configuration.global.build
end
private private
def dsl def dsl
@ -81,6 +76,8 @@ end
end end
end end
attr_accessor :object, :scope, :root, :meta_key, :meta, :configuration
def initialize(object, options={}) def initialize(object, options={})
@object = object @object = object
@scope = options[:scope] @scope = options[:scope]
@ -88,8 +85,8 @@ end
@meta_key = options[:meta_key] || :meta @meta_key = options[:meta_key] || :meta
@meta = options[@meta_key] @meta = options[@meta_key]
@wrap_in_array = options[:_wrap_in_array] @wrap_in_array = options[:_wrap_in_array]
@configuration = self.class.configuration.build options
end end
attr_accessor :object, :scope, :root, :meta_key, :meta
def json_key def json_key
if root == true || root.nil? if root == true || root.nil?

View File

@ -4,7 +4,7 @@ require 'active_model/serializer'
module ActiveModel module ActiveModel
class Serializer class Serializer
class Association class Association
def initialize(name, options={}) def initialize(name, options = {})
if options.has_key?(:include) if options.has_key?(:include)
ActiveSupport::Deprecation.warn <<-WARN ActiveSupport::Deprecation.warn <<-WARN
** Notice: include was renamed to embed_in_root. ** ** Notice: include was renamed to embed_in_root. **
@ -13,8 +13,8 @@ module ActiveModel
@name = name.to_s @name = name.to_s
@options = options @options = options
self.embed = options.fetch(:embed) { CONFIG.embed } self.embed = options.fetch(:embed) { Configuration.global.embed }
@embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { CONFIG.embed_in_root } } @embed_in_root = options.fetch(:embed_in_root) { options.fetch(:include) { Configuration.global.embed_in_root } }
@embed_key = options[:embed_key] || :id @embed_key = options[:embed_key] || :id
@key = options[:key] @key = options[:key]
@embedded_key = options[:root] || name @embedded_key = options[:root] || name

View File

@ -1,31 +0,0 @@
module ActiveModel
class Serializer
class Config
def initialize(data = {})
@data = data
end
def each(&block)
@data.each(&block)
end
def clear
@data.clear
end
def method_missing(name, *args)
name = name.to_s
return @data[name] if @data.include?(name)
match = name.match(/\A(.*?)([?=]?)\Z/)
case match[2]
when "="
@data[match[1]] = args.first
when "?"
!!@data[match[1]]
end
end
end
CONFIG = Config.new('embed' => :objects) # :nodoc:
end
end

View File

@ -0,0 +1,82 @@
require 'singleton'
module ActiveModel
class Serializer
class Configuration
class Null
include Singleton
def method_missing(*)
nil
end
def respond_to?(*)
true
end
end
attr_accessor :parent
class << self
def global
@global ||= new default_options
end
def default_options
{ embed: :objects }
end
end
def build(options = {})
self.class.new options, self
end
def initialize(options = {}, parent = Null.instance)
@root = read_option options, :root
@embed = read_option options, :embed
@embed_in_root = read_option options, :embed_in_root
@parent = parent
end
def root
return_first @root, parent.root
end
def embed
return_first @embed, parent.embed
end
def embed_in_root
return_first @embed_in_root, parent.embed_in_root
end
# FIXME: Get rid of this mess.
def embed_objects=(value)
@embed = :objects if value
end
# FIXME: Get rid of this mess.
def embed_ids=(value)
@embed = :ids if value
end
def embed_objects
[:objects, :object].include? embed
end
def embed_ids
[:ids, :id].include? embed
end
private
def read_option(options, name)
options[name] || false if options.has_key? name
end
def return_first(*values)
values.compact.first
end
end
end
end

View File

@ -1,86 +0,0 @@
require 'test_helper'
module ActiveModel
class Serializer
class Config
class Test < Minitest::Test
def test_config_const_is_an_instance_of_config
assert_kind_of Config, CONFIG
end
def test_config_instance
config = Config.new
config.setting1 = 'value1'
assert_equal 'value1', config.setting1
end
def test_each_config
config = Config.new
config.setting1 = 'value1'
config.setting2 = 'value2'
actual = {}
config.each do |k, v|
actual[k] = v
end
assert_equal({ 'setting1' => 'value1', 'setting2' => 'value2' }, actual)
end
end
class ConfigTest < Minitest::Test
def test_setup
Serializer.setup do |config|
config.a = 'v1'
config.b = 'v2'
end
assert_equal 'v1', CONFIG.a
assert_equal 'v2', CONFIG.b
ensure
CONFIG.clear
end
def test_config_accessors
Serializer.setup do |config|
config.foo = 'v1'
config.bar = 'v2'
end
assert_equal 'v1', CONFIG.foo
assert_equal 'v2', CONFIG.bar
ensure
CONFIG.clear
end
def test_acessor_when_nil
assert_nil CONFIG.foo
CONFIG.foo = 1
assert_equal 1, CONFIG.foo
assert_nil CONFIG.bar
end
end
class ApplyConfigTest < Minitest::Test
def test_apply_config_to_associations
CONFIG.embed = :ids
CONFIG.embed_in_root = true
association = PostSerializer._associations[:comments]
old_association = association.dup
association.send :initialize, association.name, association.options
assert association.embed_ids?
assert !association.embed_objects?
assert association.embed_in_root
ensure
PostSerializer._associations[:comments] = old_association
CONFIG.clear
end
end
end
end
end

View File

@ -0,0 +1,41 @@
require 'test_helper'
module ActiveModel
class Serializer
class Configuration
class GlobalTest < Minitest::Test
def test_returns_global_configuration
assert_kind_of Configuration, Configuration.global
end
def test_global_configuration_returns_the_same_instance
assert_equal Configuration.global.object_id, Configuration.global.object_id
end
def test_global_configuration_has_default_options_set
assert Configuration.default_options.all? do |name, value|
Configuration.global.send(name) == value
end
end
end
class OptionsTest < Minitest::Test
def setup
@configuration = Configuration.global.build(root: 'root', embed: :ids, embed_in_root: false)
end
def test_configuration_has_root_option
assert_equal 'root', @configuration.root
end
def test_configuration_has_embed_option
assert_equal :ids, @configuration.embed
end
def test_configuration_has_embed_in_root_option
assert_equal false, @configuration.embed_in_root
end
end
end
end
end