1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

More tests for concerning

This commit is contained in:
Jason Karns 2019-09-12 11:53:24 -04:00 committed by Kasper Timm Hansen
parent ba2bea5e07
commit 54ecc90d90
No known key found for this signature in database
GPG key ID: 191153215EDA53D8
4 changed files with 71 additions and 0 deletions

View file

@ -1,3 +1,23 @@
* Support `prepend` with `ActiveSupport::Concern`.
Allows a module with `extend ActiveSupport::Concern` to be prepended.
module Imposter
extend ActiveSupport::Concern
# Same as `included`, except only run when prepended.
prepended do
end
end
class Person
prepend Imposter
end
Concerning is also updated: `concerning :Imposter, prepend: true do`
*Jason Karns*
* Deprecate using `Range#include?` method to check the inclusion of a value
in a date time range. It is recommended to use `Range#cover?` method
instead of `Range#include?` to check the inclusion of a value

View file

@ -99,6 +99,14 @@ module ActiveSupport
# class Host
# include Bar # It works, now Bar takes care of its dependencies
# end
#
# === Prepending concerns
#
# Just like `include`, concerns also support `prepend` with a corresponding
# `prepended do` callback. `module ClassMethods` or `class_methods do` are
# still extended.
#
# `prepend` is also used for any dependencies.
module Concern
class MultipleIncludedBlocks < StandardError #:nodoc:
def initialize

View file

@ -104,6 +104,11 @@ class Module
# * grok the behavior of our class in one glance,
# * clean up monolithic junk-drawer classes by separating their concerns, and
# * stop leaning on protected/private for crude "this is internal stuff" modularity.
#
# === Prepending `concerning`
#
# `concerning` supports a `prepend: true` argument which will `prepend` the
# concern instead of using `include` for it.
module Concerning
# Define a new concern and mix it in.
def concerning(topic, prepend: false, &block)

View file

@ -7,6 +7,9 @@ class ModuleConcerningTest < ActiveSupport::TestCase
def test_concerning_declares_a_concern_and_includes_it_immediately
klass = Class.new { concerning(:Foo) { } }
assert_includes klass.ancestors, klass::Foo, klass.ancestors.inspect
klass = Class.new { concerning(:Foo, prepend: true) { } }
assert_includes klass.ancestors, klass::Foo, klass.ancestors.inspect
end
def test_concerning_can_prepend_concern
@ -27,6 +30,7 @@ class ModuleConcernTest < ActiveSupport::TestCase
klass = Class.new do
concern :Baz do
included { @foo = 1 }
prepended { @foo = 2 }
def should_be_public; end
end
end
@ -42,6 +46,9 @@ class ModuleConcernTest < ActiveSupport::TestCase
# Calls included hook
assert_equal 1, Class.new { include klass::Baz }.instance_variable_get("@foo")
# Calls prepended hook
assert_equal 2, Class.new { prepend klass::Baz }.instance_variable_get("@foo")
end
class Foo
@ -64,6 +71,26 @@ class ModuleConcernTest < ActiveSupport::TestCase
def doesnt_clobber; end
end
end
concerning :Baz, prepend:true do
module ClassMethods
def will_be_orphaned_also; end
end
const_set :ClassMethods, Module.new {
def hacked_on_also; end
}
# Doesn't overwrite existing ClassMethods module.
class_methods do
def nicer_dsl_also; end
end
# Doesn't overwrite previous class_methods definitions.
class_methods do
def doesnt_clobber_also; end
end
end
end
def test_using_class_methods_blocks_instead_of_ClassMethods_module
@ -76,4 +103,15 @@ class ModuleConcernTest < ActiveSupport::TestCase
assert Foo.const_defined?(:ClassMethods)
assert Foo::ClassMethods.method_defined?(:will_be_orphaned)
end
def test_using_class_methods_blocks_instead_of_ClassMethods_module_prepend
assert_not_respond_to Foo, :will_be_orphaned_also
assert_respond_to Foo, :hacked_on_also
assert_respond_to Foo, :nicer_dsl_also
assert_respond_to Foo, :doesnt_clobber_also
# Orphan in Foo::ClassMethods, not Bar::ClassMethods.
assert Foo.const_defined?(:ClassMethods)
assert Foo::ClassMethods.method_defined?(:will_be_orphaned_also)
end
end