duck_puncher 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f945aea9eb0db7392e51aea5cda254eaad6d5815
4
- data.tar.gz: fa1e7a2565caee23e437d38b60358f9fbf382901
3
+ metadata.gz: 1cb44e09391f847e93e57bcf8440f2c2d15ed047
4
+ data.tar.gz: 3ce4e5424e681138720017420ac9acf62fb813d2
5
5
  SHA512:
6
- metadata.gz: 3c05f53aad5478fda527751c1cc3625cf6d0dad18397a08311610d56a13ada9fab6705623f7ae8fec63902636f78255cee3ad3fd892e9b0ada44c9132bba3d3e
7
- data.tar.gz: b7310b2c603075ce345f24805bb4d2dc7211515c86b69dc0df775d8aa362cf723c656b3a22a8a0696d0a2fd1b6294e7b96c6a91511d26eb35ea61956865f74c4
6
+ metadata.gz: 21f328e2955ba0a5d22edb8182ebba32707413aff62e0f788bc87fe5bf889317d601d44cc809cdfb1edb3e8029777080124e26f57b65e0a6b499e0b51c775960
7
+ data.tar.gz: 1de4fb69952aec16f29c3bfa6034cf4400b5aea73d64bbfee6f7b735c0149e4fb5cd278cacd2d45dfbd4bd7a27faf29117a2ef55393520f2cbbe95b8820b27e7
@@ -4,7 +4,7 @@ module DuckPuncher
4
4
  @decorators ||= ancestral_hash
5
5
  end
6
6
 
7
- def new_decorator(*ducks)
7
+ def build_decorator_class(*ducks)
8
8
  targets = ducks.sort.map(&:target)
9
9
  decorator_class = DelegateClass(targets.first)
10
10
  DuckPuncher.redefine_constant "#{targets.first.to_s.tr(':', '')}Delegator", decorator_class
@@ -12,6 +12,16 @@ module DuckPuncher
12
12
  decorator_class
13
13
  end
14
14
 
15
+ def decorate(context, target)
16
+ cached_decorators[target].inject(context) { |me, (_, decorator)| decorator.new(me) }
17
+ end
18
+
19
+ def cached_decorators
20
+ @cached_decorators ||= Hash.new do |me, target|
21
+ me[target] = DuckPuncher.decorators.select { |klass, _| klass >= target }.sort { |a, b| b[0] <=> a[0] }
22
+ end
23
+ end
24
+
15
25
  def undecorate(obj)
16
26
  obj = obj.__getobj__ while obj.respond_to? :__getobj__
17
27
  obj
@@ -11,16 +11,17 @@ module DuckPuncher
11
11
  end
12
12
  end
13
13
 
14
- # @description Returns a new decorated version of ourself with the punches mixed in
14
+ # @description Returns a new decorated version of ourself with the punches mixed in (adds ancestors decorators)
15
15
  # @return [<self.class>Delegator]
16
16
  def punch
17
- DuckPuncher.decorators[DuckPuncher.undecorate(self).class].new(self)
17
+ DuckPuncher.decorate self, DuckPuncher.undecorate(self).class
18
18
  end
19
19
 
20
20
  # @description Adds the duck punches to the current object (meant to be used on instances, careful with nil and numbers!)
21
21
  # @return self
22
22
  def punch!
23
- DuckPuncher::Ducks.load_mods(DuckPuncher.undecorate(self).class).each { |mod| self.extend mod }
23
+ target = DuckPuncher.undecorate(self).class
24
+ DuckPuncher::Ducks.load_mods(target).each { |mod| self.extend mod }
24
25
  self
25
26
  end
26
27
 
@@ -7,15 +7,15 @@ module DuckPuncher
7
7
  Array(mods).each do |mod|
8
8
  duck = Duck.new target, mod, options
9
9
  Ducks.list[target] << duck
10
- decorators[target] = new_decorator(duck, *Ducks[target])
10
+ decorators[target] = build_decorator_class(duck, *Ducks[target])
11
11
  end
12
- nil
12
+ @cached_decorators = nil
13
13
  end
14
14
 
15
15
  def deregister(*classes)
16
16
  classes.each &Ducks.list.method(:delete)
17
17
  classes.each &decorators.method(:delete)
18
- nil
18
+ @cached_decorators = nil
19
19
  end
20
20
  end
21
21
  end
@@ -1,3 +1,3 @@
1
1
  module DuckPuncher
2
- VERSION = '4.0.0'.freeze
2
+ VERSION = '4.1.0'.freeze
3
3
  end
@@ -57,4 +57,22 @@ class ObjectTest < MiniTest::Test
57
57
  assert_respond_to @kaia, :talk
58
58
  assert_respond_to @kaia, :quack
59
59
  end
60
+
61
+ def test_soft_punch_includes_all_ancestors
62
+ DuckPuncher.register Animal, CustomPunch2
63
+ DuckPuncher.register Dog, CustomPunch
64
+ DuckPuncher.register Kaia, CustomPunch3
65
+ @kaia = Kaia.new.punch
66
+ assert_respond_to @kaia, :wobble
67
+ assert_respond_to @kaia, :talk
68
+ assert_respond_to @kaia, :quack
69
+ end
70
+
71
+ def test_soft_punch_with_parent_override
72
+ DuckPuncher.register Animal, CustomPunch
73
+ DuckPuncher.register Kaia, ModWithOverride
74
+ @kaia = Kaia.new.punch
75
+ assert_respond_to @kaia, :talk
76
+ assert_equal @kaia.talk, 'talk is cheap'
77
+ end
60
78
  end
data/test/test_helper.rb CHANGED
@@ -25,6 +25,12 @@ module CustomPunch3
25
25
  end
26
26
  end
27
27
 
28
+ module ModWithOverride
29
+ def talk
30
+ 'talk is cheap'
31
+ end
32
+ end
33
+
28
34
  module ModWithNestedMod
29
35
  def instance_method_1
30
36
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: duck_puncher
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Buckley
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-17 00:00:00.000000000 Z
11
+ date: 2016-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: usable