118 lines
3.4 KiB
Ruby
118 lines
3.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require_relative "../../abstract_unit"
|
|
require "active_support/core_ext/module/concerning"
|
|
|
|
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
|
|
klass = Class.new do
|
|
def hi; "self"; end
|
|
|
|
concerning(:Foo, prepend: true) do
|
|
def hi; "hello, #{super}"; end
|
|
end
|
|
end
|
|
|
|
assert_equal "hello, self", klass.new.hi
|
|
end
|
|
end
|
|
|
|
class ModuleConcernTest < ActiveSupport::TestCase
|
|
def test_concern_creates_a_module_extended_with_active_support_concern
|
|
klass = Class.new do
|
|
concern :Baz do
|
|
included { @foo = 1 }
|
|
prepended { @foo = 2 }
|
|
def should_be_public; end
|
|
end
|
|
end
|
|
|
|
# Declares a concern but doesn't include it
|
|
assert klass.const_defined?(:Baz, false)
|
|
assert_not ModuleConcernTest.const_defined?(:Baz)
|
|
assert_kind_of ActiveSupport::Concern, klass::Baz
|
|
assert_not_includes klass.ancestors, klass::Baz, klass.ancestors.inspect
|
|
|
|
# Public method visibility by default
|
|
assert_includes klass::Baz.public_instance_methods.map(&:to_s), "should_be_public"
|
|
|
|
# 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
|
|
concerning :Bar do
|
|
module ClassMethods
|
|
def will_be_orphaned; end
|
|
end
|
|
|
|
const_set :ClassMethods, Module.new {
|
|
def hacked_on; end
|
|
}
|
|
|
|
# Doesn't overwrite existing ClassMethods module.
|
|
class_methods do
|
|
def nicer_dsl; end
|
|
end
|
|
|
|
# Doesn't overwrite previous class_methods definitions.
|
|
class_methods do
|
|
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
|
|
assert_not_respond_to Foo, :will_be_orphaned
|
|
assert_respond_to Foo, :hacked_on
|
|
assert_respond_to Foo, :nicer_dsl
|
|
assert_respond_to Foo, :doesnt_clobber
|
|
|
|
# Orphan in Foo::ClassMethods, not Bar::ClassMethods.
|
|
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
|