Skip to content

Commit

Permalink
Add support for module prepended blocks
Browse files Browse the repository at this point in the history
- Added `prepend_features` method to Tins concern
- Updated ConcernTest to test prepend feature
- Raise StandardError for duplicate block definitions for included and
  prepended blocks
  • Loading branch information
flori committed Oct 19, 2024
1 parent fbecd3c commit 8877426
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
27 changes: 27 additions & 0 deletions lib/tins/concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,41 @@ def append_features(base)
end
end

def prepend_features(base)
if base.instance_variable_defined?("@_dependencies")
base.instance_variable_get("@_dependencies") << self
false
else
return false if base < self
@_dependencies.each { |dep| base.send(:include, dep) }
super
base.extend const_get("ClassMethods") if const_defined?("ClassMethods")
base.class_eval(&@_prepended_block) if instance_variable_defined?("@_prepended_block")
Thread.current[:tin_concern_args] = nil
true
end
end

def included(base = nil, &block)
if base.nil?
instance_variable_defined?(:@_included_block) and
raise StandardError, "included block already defined"
@_included_block = block
else
super
end
end

def prepended(base = nil, &block)
if base.nil?
instance_variable_defined?(:@_prepended_block) and
raise StandardError, "prepended block already defined"
@_prepended_block = block
else
super
end
end

def class_methods(&block)
modul = const_get(:ClassMethods) if const_defined?(:ClassMethods, false)
unless modul
Expand Down
26 changes: 25 additions & 1 deletion tests/concern_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ module AC
$included = self
end

prepended do
$prepended = self
end

def foo
:foo
end
Expand All @@ -32,17 +36,37 @@ def baz2
end

$included = nil
$prepended = nil

class A
include AC
end

def test_concern
class B
prepend AC
end

def test_concern_include
a = A.new
assert_equal A, $included
assert_equal :foo, a.foo
assert_equal :bar, A.bar
assert_equal :baz1, A.baz1
assert_equal :baz2, A.baz2
assert_raise(StandardError) do
AC.module_eval { included {} }
end
end

def test_concern_prepend
a = B.new
assert_equal B, $prepended
assert_equal :foo, a.foo
assert_equal :bar, B.bar
assert_equal :baz1, B.baz1
assert_equal :baz2, B.baz2
assert_raise(StandardError) do
AC.module_eval { prepended {} }
end
end
end

0 comments on commit 8877426

Please # to comment.