decors 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2bb31ed84c4aa6d83763802dd3ffed2c76b3fdd8
4
- data.tar.gz: 60f07758499467ca63547d13bcff6354a845d3a9
2
+ SHA256:
3
+ metadata.gz: d902a52f74b8a1de84fe0a26df7130072acfb771ee854a5d6382ce4920979a43
4
+ data.tar.gz: eca2c708367d25e3172ca5fa8e948c97e8b18119e29740c1272a102c267ea6e7
5
5
  SHA512:
6
- metadata.gz: 8a2651655043a8bc0742fe60db5385989d7e415ae7a2728a3247b61934d7069af5a8b4b02cebde2523228433b0f278aa5805ab273886b7636dae829f725deb06
7
- data.tar.gz: ac7ee42f12a9945822fd48017e33977d7b1a364a2ab20b157d6293cbc0847f73254e4a54d0d2dee8f754c45b6e7147c03530dad9033c10ecd55fce356f6e8502
6
+ metadata.gz: 01c57e83cd0f5b2c3d543de6c06f97bcfd247c2478474d655a2ed0e9b05571ed85fce56e5590cd8a05b92bc16c25542fd21ffeb208fa0e3ff7f4577603d206f8
7
+ data.tar.gz: 182efe4fb2899bb5e58019249e4105966ce2b7dbdcff729dfb14e82e78e5561d6c0b0fa424900537d6b7ac522a1837f4fc5d7eb415598ec932469fa1e1248f70
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.7.1
@@ -1,5 +1,8 @@
1
1
  # Decors changelog
2
2
 
3
+ ## Version 0.4 (Released June 16, 2019)
4
+ - (compatibility) remove warning for ruby 2.7
5
+
3
6
  ## Version 0.3 (Released August 24, 2017)
4
7
 
5
8
  - (feature) expose decorated method before and after decoration (https://github.com/getbannerman/decors/issues/10)
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  ruby File.open('./.ruby-version').readline.split("\n").first
2
4
 
3
5
  source 'https://rubygems.org' do
@@ -1,43 +1,41 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- decors (0.1.0)
4
+ decors (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- coderay (1.1.1)
9
+ coderay (1.1.3)
10
10
  diff-lcs (1.3)
11
- method_source (0.8.2)
12
- pry (0.10.4)
13
- coderay (~> 1.1.0)
14
- method_source (~> 0.8.1)
15
- slop (~> 3.4)
16
- rspec (3.5.0)
17
- rspec-core (~> 3.5.0)
18
- rspec-expectations (~> 3.5.0)
19
- rspec-mocks (~> 3.5.0)
20
- rspec-core (3.5.4)
21
- rspec-support (~> 3.5.0)
22
- rspec-expectations (3.5.0)
11
+ method_source (1.0.0)
12
+ pry (0.13.1)
13
+ coderay (~> 1.1)
14
+ method_source (~> 1.0)
15
+ rspec (3.9.0)
16
+ rspec-core (~> 3.9.0)
17
+ rspec-expectations (~> 3.9.0)
18
+ rspec-mocks (~> 3.9.0)
19
+ rspec-core (3.9.2)
20
+ rspec-support (~> 3.9.3)
21
+ rspec-expectations (3.9.2)
23
22
  diff-lcs (>= 1.2.0, < 2.0)
24
- rspec-support (~> 3.5.0)
25
- rspec-mocks (3.5.0)
23
+ rspec-support (~> 3.9.0)
24
+ rspec-mocks (3.9.1)
26
25
  diff-lcs (>= 1.2.0, < 2.0)
27
- rspec-support (~> 3.5.0)
28
- rspec-support (3.5.0)
29
- slop (3.6.0)
26
+ rspec-support (~> 3.9.0)
27
+ rspec-support (3.9.3)
30
28
 
31
29
  PLATFORMS
32
30
  ruby
33
31
 
34
32
  DEPENDENCIES
35
33
  decors!
36
- pry!
34
+ pry (~> 0)!
37
35
  rspec (~> 3)!
38
36
 
39
37
  RUBY VERSION
40
- ruby 2.3.1p112
38
+ ruby 2.7.1p83
41
39
 
42
40
  BUNDLED WITH
43
- 1.14.6
41
+ 2.1.4
@@ -1,23 +1,25 @@
1
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
 
4
6
  require 'decors'
5
7
 
6
8
  Gem::Specification.new do |gem|
7
- gem.name = "decors"
8
- gem.version = ::Decors::VERSION
9
- gem.licenses = ['MIT']
10
- gem.authors = ['Vivien Meyet']
11
- gem.email = ['vivien@getbannerman.com']
12
- gem.description = "Ruby implementation of Python method decorators / Java annotations"
13
- gem.summary = gem.description
14
- gem.homepage = 'https://github.com/getbannerman/decors'
9
+ gem.name = 'decors'
10
+ gem.version = ::Decors::VERSION
11
+ gem.licenses = ['MIT']
12
+ gem.authors = ['Vivien Meyet']
13
+ gem.email = ['vivien@getbannerman.com']
14
+ gem.description = 'Ruby implementation of Python method decorators / Java annotations'
15
+ gem.summary = gem.description
16
+ gem.homepage = 'https://github.com/getbannerman/decors'
15
17
 
16
- gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
- gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
18
- gem.test_files = gem.files.grep(%r{^spec/})
19
- gem.require_paths = ['lib']
18
+ gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
19
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
20
+ gem.test_files = gem.files.grep(%r{^spec/})
21
+ gem.require_paths = ['lib']
20
22
 
21
- gem.add_development_dependency 'pry', '~> 0'
22
- gem.add_development_dependency 'rspec', '~> 3'
23
+ gem.add_development_dependency 'pry', '~> 0'
24
+ gem.add_development_dependency 'rspec', '~> 3'
23
25
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'decors/decorator_base'
2
4
  require 'decors/decorator_definition'
3
5
  require 'decors/method_added'
4
6
 
5
7
  module Decors
6
- VERSION = '0.3.0'
8
+ VERSION = '0.4.0'
7
9
  end
@@ -1,27 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Decors
2
- class DecoratorBase
3
- attr_reader :decorated_class, :undecorated_method, :decorated_method, :decorator_args,
4
- :decorator_kwargs, :decorator_block
4
+ class DecoratorBase
5
+ attr_reader :decorated_class, :undecorated_method, :decorated_method, :decorator_args,
6
+ :decorator_kwargs, :decorator_block
5
7
 
6
- def initialize(decorated_class, undecorated_method, decorated_method, *args, **kwargs, &block)
7
- @decorated_class = decorated_class
8
- @undecorated_method = undecorated_method
9
- @decorated_method = decorated_method
10
- @decorator_args = args
11
- @decorator_kwargs = kwargs
12
- @decorator_block = block
13
- end
8
+ def initialize(decorated_class, undecorated_method, decorated_method, *args, **kwargs, &block)
9
+ @decorated_class = decorated_class
10
+ @undecorated_method = undecorated_method
11
+ @decorated_method = decorated_method
12
+ @decorator_args = args
13
+ @decorator_kwargs = kwargs
14
+ @decorator_block = block
15
+ end
14
16
 
15
- def call(instance, *args, &block)
16
- undecorated_call(instance, *args, &block)
17
- end
17
+ def call(instance, *args, **kwargs, &block)
18
+ undecorated_call(instance, *args, **kwargs, &block)
19
+ end
18
20
 
19
- def undecorated_call(instance, *args, &block)
20
- undecorated_method.bind(instance).call(*args, &block)
21
- end
21
+ def undecorated_call(instance, *args, **kwargs, &block)
22
+ undecorated_method.bind(instance).call(*args, **kwargs, &block)
23
+ end
22
24
 
23
- def decorated_method_name
24
- decorated_method.name
25
- end
25
+ def decorated_method_name
26
+ decorated_method.name
26
27
  end
28
+ end
27
29
  end
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Decors
2
- module DecoratorDefinition
3
- def define_mixin_decorator(decorator_name, decorator_class)
4
- define_decorator(decorator_name, decorator_class, mixin: true)
5
- end
4
+ module DecoratorDefinition
5
+ def define_mixin_decorator(decorator_name, decorator_class)
6
+ define_decorator(decorator_name, decorator_class, mixin: true)
7
+ end
6
8
 
7
- def define_decorator(decorator_name, decorator_class, mixin: false)
8
- method_definer = mixin ? :define_method : :define_singleton_method
9
+ def define_decorator(decorator_name, decorator_class, mixin: false)
10
+ method_definer = mixin ? :define_method : :define_singleton_method
9
11
 
10
- send(method_definer, decorator_name) do |*params, &blk|
11
- extend(singleton_class? ? Decors::MethodAdded::SingletonListener : Decors::MethodAdded::StandardListener)
12
+ send(method_definer, decorator_name) do |*args, **kwargs, &blk|
13
+ extend(singleton_class? ? Decors::MethodAdded::SingletonListener : Decors::MethodAdded::StandardListener)
12
14
 
13
- declared_decorators << [decorator_class, params, blk]
14
- end
15
- end
15
+ declared_decorators << [decorator_class, args, kwargs, blk]
16
+ end
16
17
  end
18
+ end
17
19
  end
@@ -1,67 +1,75 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'decors/utils'
2
4
 
3
5
  module Decors
4
- module MethodAdded
5
- module Handler
6
- private
7
-
8
- METHOD_CALLED_TOO_EARLY_HANDLER = ->(*) {
9
- raise 'You cannot call a decorated method before its decorator is initialized'
10
- }
11
-
12
- def declared_decorators
13
- @declared_decorators ||= []
14
- end
15
-
16
- # method addition handling is the same for singleton and instance method
17
- def handle_method_addition(clazz, method_name)
18
- # @_ignore_additions allows to temporarily disable the hook
19
- return if @_ignore_additions || declared_decorators.empty?
20
- decorator_class, params, blk = declared_decorators.pop
21
-
22
- undecorated_method = clazz.instance_method(method_name)
23
- decorator = METHOD_CALLED_TOO_EARLY_HANDLER
24
- clazz.send(:define_method, method_name) { |*args, &block| decorator.call(self, *args, &block) }
25
- decorated_method = clazz.instance_method(method_name)
26
- @_ignore_additions = true
27
- decorator = decorator_class.new(clazz, undecorated_method, decorated_method, *params, &blk)
28
- @_ignore_additions = false
29
- clazz.send(Decors::Utils.method_visibility(undecorated_method), method_name)
30
- end
31
- end
6
+ module MethodAdded
7
+ module Handler
8
+ private
9
+
10
+ METHOD_CALLED_TOO_EARLY_HANDLER = lambda { |*|
11
+ raise 'You cannot call a decorated method before its decorator is initialized'
12
+ }
32
13
 
33
- module StandardListener
34
- include ::Decors::MethodAdded::Handler
14
+ def declared_decorators
15
+ @declared_decorators ||= []
16
+ end
35
17
 
36
- def method_added(meth)
37
- super
38
- handle_method_addition(self, meth)
39
- end
18
+ # method addition handling is the same for singleton and instance method
19
+ def handle_method_addition(clazz, method_name)
20
+ # @_ignore_additions allows to temporarily disable the hook
21
+ return if @_ignore_additions || declared_decorators.empty?
40
22
 
41
- def singleton_method_added(meth)
42
- super
43
- handle_method_addition(singleton_class, meth)
44
- end
23
+ decorator_class, params, kparams, blk = declared_decorators.pop
24
+
25
+ undecorated_method = clazz.instance_method(method_name)
26
+ decorator = METHOD_CALLED_TOO_EARLY_HANDLER
27
+
28
+ clazz.send(:define_method, method_name) do |*args, **kwargs, &block|
29
+ decorator.call(self, *args, **kwargs, &block)
45
30
  end
46
31
 
47
- module SingletonListener
48
- include ::Decors::MethodAdded::Handler
32
+ decorated_method = clazz.instance_method(method_name)
33
+ @_ignore_additions = true
34
+ decorator = decorator_class.new(clazz, undecorated_method, decorated_method, *params, **kparams, &blk)
35
+ @_ignore_additions = false
36
+
37
+ clazz.send(Decors::Utils.method_visibility(undecorated_method), method_name)
38
+ end
39
+ end
40
+
41
+ module StandardListener
42
+ include ::Decors::MethodAdded::Handler
43
+
44
+ def method_added(meth)
45
+ super
46
+ handle_method_addition(self, meth)
47
+ end
48
+
49
+ def singleton_method_added(meth)
50
+ super
51
+ handle_method_addition(singleton_class, meth)
52
+ end
53
+ end
54
+
55
+ module SingletonListener
56
+ include ::Decors::MethodAdded::Handler
49
57
 
50
- def singleton_method_added(meth)
51
- super
52
- handle_method_addition(singleton_class, meth)
53
- end
58
+ def singleton_method_added(meth)
59
+ super
60
+ handle_method_addition(singleton_class, meth)
61
+ end
54
62
 
55
- def self.extended(base)
56
- ObjectSpace.each_object(base).first.send(:extend, ForwardToSingletonListener)
57
- end
63
+ def self.extended(base)
64
+ ObjectSpace.each_object(base).first.send(:extend, ForwardToSingletonListener)
65
+ end
58
66
 
59
- module ForwardToSingletonListener
60
- def singleton_method_added(meth)
61
- super
62
- singleton_class.send(:handle_method_addition, singleton_class, meth)
63
- end
64
- end
67
+ module ForwardToSingletonListener
68
+ def singleton_method_added(meth)
69
+ super
70
+ singleton_class.send(:handle_method_addition, singleton_class, meth)
65
71
  end
72
+ end
66
73
  end
74
+ end
67
75
  end
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Decors
2
- module Utils
3
- class << self
4
- def method_visibility(method)
5
- if method.owner.private_method_defined?(method.name)
6
- :private
7
- elsif method.owner.protected_method_defined?(method.name)
8
- :protected
9
- elsif method.owner.public_method_defined?(method.name)
10
- :public
11
- else
12
- fail ArgumentError, 'Unkwnown method'
13
- end
14
- end
4
+ module Utils
5
+ class << self
6
+ def method_visibility(method)
7
+ if method.owner.private_method_defined?(method.name)
8
+ :private
9
+ elsif method.owner.protected_method_defined?(method.name)
10
+ :protected
11
+ elsif method.owner.public_method_defined?(method.name)
12
+ :public
13
+ else
14
+ raise ArgumentError, 'Unkwnown method'
15
15
  end
16
+ end
16
17
  end
18
+ end
17
19
  end
@@ -1,456 +1,458 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
4
 
3
5
  describe Decors do
4
- before { stub_class(:TestClass) { extend Decors::DecoratorDefinition } }
5
- before {
6
- stub_class(:Spy) {
7
- def self.passed_args(*args, **kwargs, &block)
8
- arguments(args: args, kwargs: kwargs, evald_block: block&.call)
9
- end
6
+ before { stub_class(:TestClass) { extend Decors::DecoratorDefinition } }
7
+ before do
8
+ stub_class(:Spy) do
9
+ def self.passed_args(*args, **kwargs, &block)
10
+ arguments(args: args, kwargs: kwargs, evald_block: block&.call)
11
+ end
12
+
13
+ def self.arguments(**); end
14
+ end
15
+ end
16
+
17
+ context 'Check decorated_method & undecorated_method' do
18
+ let(:instance) { TestClass.new }
19
+
20
+ before do
21
+ stub_class(:SimpleDecorator, inherits: [::Decors::DecoratorBase])
22
+ call_method = call_proc
23
+ SimpleDecorator.send(:define_method, :call) { |*| instance_eval(&call_method) }
24
+ TestClass.class_eval do
25
+ define_decorator :SimpleDecorator, SimpleDecorator
26
+ SimpleDecorator()
27
+ def test
28
+ 42
29
+ end
30
+ end
31
+ end
10
32
 
11
- def self.arguments(*); end
12
- }
13
- }
33
+ context 'Check decorated_method value' do
34
+ let(:call_proc) { proc { decorated_method } }
35
+ it { expect(instance.test).to eq TestClass.instance_method(:test) }
36
+ end
14
37
 
15
- context 'Check decorated_method & undecorated_method' do
16
- let(:instance) { TestClass.new }
17
-
18
- before {
19
- stub_class(:SimpleDecorator, inherits: [::Decors::DecoratorBase])
20
- call_method = call_proc
21
- SimpleDecorator.send(:define_method, :call){ |*| instance_eval(&call_method) }
22
- TestClass.class_eval {
23
- define_decorator :SimpleDecorator, SimpleDecorator
24
- SimpleDecorator()
25
- def test; 42 end
26
- }
27
- }
28
-
29
- context 'Check decorated_method value' do
30
- let(:call_proc) { proc { decorated_method } }
31
- it { expect(instance.test).to eq TestClass.instance_method(:test) }
38
+ context 'Check undecorated_method value' do
39
+ let(:call_proc) { proc { undecorated_method } }
40
+ it { expect(instance.test.bind(instance).call).to eq 42 }
41
+ it { expect(instance.test.bind(instance).call).not_to eq TestClass.instance_method(:test) }
42
+ end
43
+ end
44
+
45
+ context 'when simple case decorator' do
46
+ before do
47
+ stub_class(:SimpleDecorator, inherits: [::Decors::DecoratorBase]) do
48
+ def initialize(deco_class, undeco_method, deco_method, *deco_args, **deco_kwargs, &deco_block)
49
+ super
50
+ Spy.passed_args(*deco_args, **deco_kwargs, &deco_block)
32
51
  end
33
52
 
34
- context 'Check undecorated_method value' do
35
- let(:call_proc) { proc { undecorated_method } }
36
- it { expect(instance.test.bind(instance).call).to eq 42 }
37
- it { expect(instance.test.bind(instance).call).not_to eq TestClass.instance_method(:test) }
53
+ def call(instance, *args, **kwargs, &block)
54
+ super
55
+ Spy.passed_args(*args, **kwargs, &block)
56
+ end
57
+ end
58
+
59
+ TestClass.class_eval { define_decorator :SimpleDecorator, SimpleDecorator }
60
+ end
38
61
 
62
+ context 'It receive all the parameters at initialization' do
63
+ it { expect(SimpleDecorator).to receive(:new).with(TestClass, anything, anything, 1, 2, a: 3).and_call_original }
64
+ it { expect(Spy).to receive(:arguments).with(args: [1, 2], kwargs: { a: 3 }, evald_block: 'ok') }
65
+
66
+ after do
67
+ TestClass.class_eval do
68
+ SimpleDecorator(1, 2, a: 3) { 'ok' }
69
+ def test_method(*); end
70
+
71
+ def test_method_not_decorated(*); end
39
72
  end
73
+ end
40
74
  end
41
75
 
42
- context 'when simple case decorator' do
43
- before {
44
- stub_class(:SimpleDecorator, inherits: [::Decors::DecoratorBase]) {
45
- def initialize(decorated_class, undecorated_method, decorated_method, *deco_args, **deco_kwargs, &deco_block)
46
- super
47
- Spy.passed_args(*deco_args, **deco_kwargs, &deco_block)
48
- end
49
-
50
- def call(instance, *args, &block)
51
- super
52
- Spy.passed_args(*args, &block)
53
- end
54
- }
55
-
56
- TestClass.class_eval { define_decorator :SimpleDecorator, SimpleDecorator }
57
- }
58
-
59
- context 'It receive all the parameters at initialization' do
60
- it { expect(SimpleDecorator).to receive(:new).with(TestClass, anything, anything, 1, 2, a: 3).and_call_original }
61
- it { expect(Spy).to receive(:arguments).with(args: [1, 2], kwargs: { a: 3 }, evald_block: 'ok') }
62
-
63
- after {
64
- TestClass.class_eval {
65
- SimpleDecorator(1, 2, a: 3) { 'ok' }
66
- def test_method(*); end
67
-
68
- def test_method_not_decorated(*); end
69
- }
70
- }
76
+ context 'It receive the instance and the arguments passed to the method when called' do
77
+ let(:instance) { TestClass.new }
78
+ before do
79
+ TestClass.class_eval do
80
+ SimpleDecorator()
81
+ def test_method(*args, **kwargs, &block)
82
+ Spy.passed_args(*args, **kwargs, &block)
83
+ end
84
+
85
+ def test_method_not_decorated; end
71
86
  end
87
+ end
88
+
89
+ it { expect_any_instance_of(SimpleDecorator).to receive(:call).with(instance, 1, a: 2, b: 3, &proc { 'yes' }) }
90
+ it { expect(Spy).to receive(:arguments).with(args: [1], kwargs: { a: 2, b: 3 }, evald_block: 'yes').twice }
91
+
92
+ after do
93
+ instance.test_method(1, a: 2, b: 3) { 'yes' }
94
+ instance.test_method_not_decorated
95
+ end
96
+ end
97
+
98
+ context 'It keep the method visibility' do
99
+ before do
100
+ TestClass.class_eval do
101
+ SimpleDecorator()
102
+ public def public_test_method(*); end
103
+
104
+ SimpleDecorator()
105
+ private def private_test_method(*); end
72
106
 
73
- context 'It receive the instance and the arguments passed to the method when called' do
74
- let(:instance) { TestClass.new }
75
- before {
76
- TestClass.class_eval {
77
- SimpleDecorator()
78
- def test_method(*args, &block)
79
- Spy.passed_args(*args, &block)
80
- end
81
-
82
- def test_method_not_decorated; end
83
- }
84
- }
85
-
86
- it { expect_any_instance_of(SimpleDecorator).to receive(:call).with(instance, 1, a: 2, b: 3, &proc { 'yes' }) }
87
- it { expect(Spy).to receive(:arguments).with(args: [1], kwargs: { a: 2, b: 3 }, evald_block: 'yes').twice }
88
-
89
- after {
90
- instance.test_method(1, a: 2, b: 3) { 'yes' }
91
- instance.test_method_not_decorated
92
- }
107
+ SimpleDecorator()
108
+ protected def protected_test_method(*); end
93
109
  end
110
+ end
94
111
 
95
- context 'It keep the method visibility' do
96
- before {
97
- TestClass.class_eval {
98
- SimpleDecorator()
99
- public def public_test_method(*); end
112
+ it { expect(TestClass).to be_public_method_defined(:public_test_method) }
113
+ it { expect(TestClass).to be_protected_method_defined(:protected_test_method) }
114
+ it { expect(TestClass).to be_private_method_defined(:private_test_method) }
115
+ end
116
+ end
117
+
118
+ context 'when decorator is defining a method during initialization' do
119
+ before do
120
+ stub_class(:StrangeDecorator, inherits: [::Decors::DecoratorBase]) do
121
+ def initialize(decorated_class, undecorated_method, decorated_method, *deco_args, **deco_kwargs, &deco_block)
122
+ super
123
+ decorated_class.send(:define_method, :foo) { 42 }
124
+ end
100
125
 
101
- SimpleDecorator()
102
- private def private_test_method(*); end
126
+ def call(*)
127
+ super * 2
128
+ end
129
+ end
103
130
 
104
- SimpleDecorator()
105
- protected def protected_test_method(*); end
106
- }
107
- }
131
+ TestClass.class_eval { define_decorator :StrangeDecorator, StrangeDecorator }
132
+ end
108
133
 
109
- it { expect(TestClass).to be_public_method_defined(:public_test_method) }
110
- it { expect(TestClass).to be_protected_method_defined(:protected_test_method) }
111
- it { expect(TestClass).to be_private_method_defined(:private_test_method) }
134
+ before do
135
+ TestClass.class_eval do
136
+ StrangeDecorator()
137
+ StrangeDecorator()
138
+ def test_method
139
+ 5
112
140
  end
141
+ end
113
142
  end
114
143
 
115
- context 'when decorator is defining a method during initialization' do
116
- before {
117
- stub_class(:StrangeDecorator, inherits: [::Decors::DecoratorBase]) {
118
- def initialize(decorated_class, undecorated_method, decorated_method, *deco_args, **deco_kwargs, &deco_block)
119
- super
120
- decorated_class.send(:define_method, :foo) { 42 }
121
- end
122
-
123
- def call(*)
124
- super * 2
125
- end
126
- }
127
-
128
- TestClass.class_eval { define_decorator :StrangeDecorator, StrangeDecorator }
129
- }
130
-
131
- before {
132
- TestClass.class_eval {
133
- StrangeDecorator()
134
- StrangeDecorator()
135
- def test_method
136
- 5
137
- end
138
- }
139
- }
140
-
141
- it { expect(TestClass.new.test_method).to eq 5 * 2 * 2 }
142
- it { expect(TestClass.new.foo).to eq 42 }
144
+ it { expect(TestClass.new.test_method).to eq 5 * 2 * 2 }
145
+ it { expect(TestClass.new.foo).to eq 42 }
146
+ end
147
+
148
+ context 'when mutiple decorators' do
149
+ before do
150
+ Spy.class_eval do
151
+ @ordered_calls = []
152
+
153
+ class << self
154
+ attr_reader :ordered_calls
155
+
156
+ def calling(name)
157
+ ordered_calls << name
158
+ end
159
+ end
160
+ end
161
+
162
+ stub_class(:Deco1, inherits: [::Decors::DecoratorBase]) do
163
+ def call(*)
164
+ Spy.calling(:deco1_before)
165
+ super
166
+ Spy.calling(:deco1_after)
167
+ end
168
+ end
169
+
170
+ stub_class(:Deco2, inherits: [::Decors::DecoratorBase]) do
171
+ def call(*)
172
+ Spy.calling(:deco2_before)
173
+ super
174
+ Spy.calling(:deco2_after)
175
+ end
176
+ end
177
+
178
+ TestClass.class_eval do
179
+ define_decorator :Deco1, Deco1
180
+ define_decorator :Deco2, Deco2
181
+
182
+ Deco2()
183
+ Deco1()
184
+ def test_method(*)
185
+ Spy.calling(:inside)
186
+ end
187
+ end
143
188
  end
144
189
 
145
- context 'when mutiple decorators' do
146
- before {
147
- Spy.class_eval {
148
- @ordered_calls = []
149
-
150
- class << self
151
- attr_reader :ordered_calls
152
-
153
- def calling(name)
154
- self.ordered_calls << name
155
- end
156
- end
157
- }
158
-
159
- stub_class(:Deco1, inherits: [::Decors::DecoratorBase]) {
160
- def call(*)
161
- Spy.calling(:deco1_before)
162
- super
163
- Spy.calling(:deco1_after)
164
- end
165
- }
166
-
167
- stub_class(:Deco2, inherits: [::Decors::DecoratorBase]) {
168
- def call(*)
169
- Spy.calling(:deco2_before)
170
- super
171
- Spy.calling(:deco2_after)
172
- end
173
- }
174
-
175
- TestClass.class_eval {
176
- define_decorator :Deco1, Deco1
177
- define_decorator :Deco2, Deco2
178
-
179
- Deco2()
180
- Deco1()
181
- def test_method(*)
182
- Spy.calling(:inside)
183
- end
184
- }
185
- }
186
-
187
- before { TestClass.new.test_method }
188
- it { expect(Spy.ordered_calls).to eq [:deco2_before, :deco1_before, :inside, :deco1_after, :deco2_after] }
190
+ before { TestClass.new.test_method }
191
+ it { expect(Spy.ordered_calls).to eq %i[deco2_before deco1_before inside deco1_after deco2_after] }
192
+ end
193
+
194
+ context 'when method has return value' do
195
+ before do
196
+ stub_class(:ModifierDeco, inherits: [::Decors::DecoratorBase])
197
+
198
+ TestClass.class_eval do
199
+ define_decorator :ModifierDeco, ModifierDeco
200
+
201
+ ModifierDeco()
202
+ def test_method
203
+ :ok
204
+ end
205
+ end
189
206
  end
190
207
 
191
- context 'when method has return value' do
192
- before {
193
- stub_class(:ModifierDeco, inherits: [::Decors::DecoratorBase])
208
+ it { expect(TestClass.new.test_method).to eq :ok }
209
+ end
194
210
 
195
- TestClass.class_eval {
196
- define_decorator :ModifierDeco, ModifierDeco
211
+ context 'when method has arguments' do
212
+ before do
213
+ stub_class(:ModifierDeco, inherits: [::Decors::DecoratorBase])
197
214
 
198
- ModifierDeco()
199
- def test_method
200
- :ok
201
- end
202
- }
203
- }
215
+ TestClass.class_eval do
216
+ define_decorator :ModifierDeco, ModifierDeco
204
217
 
205
- it { expect(TestClass.new.test_method).to eq :ok }
218
+ ModifierDeco()
219
+ def test_method(*args, **kwargs, &block)
220
+ Spy.passed_args(*args, **kwargs, &block)
221
+ end
222
+ end
206
223
  end
207
224
 
208
- context 'when method has arguments' do
209
- before {
210
- stub_class(:ModifierDeco, inherits: [::Decors::DecoratorBase])
225
+ it { expect(Spy).to receive(:arguments).with(args: [1, 2, 3], kwargs: { a: :a }, evald_block: 'yay') }
226
+ after { TestClass.new.test_method(1, 2, 3, a: :a) { 'yay' } }
227
+ end
211
228
 
212
- TestClass.class_eval {
213
- define_decorator :ModifierDeco, ModifierDeco
229
+ context 'when changing arguments given to the method' do
230
+ before do
231
+ stub_class(:ModifierDeco, inherits: [::Decors::DecoratorBase]) do
232
+ def call(instance, *)
233
+ undecorated_call(instance, 1, 2, 3, a: :a, &proc { 'yay' })
234
+ end
235
+ end
214
236
 
215
- ModifierDeco()
216
- def test_method(*args, &block)
217
- Spy.passed_args(*args, &block)
218
- end
219
- }
220
- }
237
+ TestClass.class_eval do
238
+ define_decorator :ModifierDeco, ModifierDeco
221
239
 
222
- it { expect(Spy).to receive(:arguments).with(args: [1, 2, 3], kwargs: { a: :a }, evald_block: 'yay') }
223
- after { TestClass.new.test_method(1, 2, 3, a: :a) { 'yay' } }
240
+ ModifierDeco()
241
+ def test_method(*args, **kwargs, &block)
242
+ Spy.passed_args(*args, **kwargs, &block)
243
+ end
244
+ end
224
245
  end
225
246
 
226
- context 'when changing arguments given to the method' do
227
- before {
228
- stub_class(:ModifierDeco, inherits: [::Decors::DecoratorBase]) {
229
- def call(instance, *)
230
- undecorated_call(instance, 1, 2, 3, a: :a, &proc { 'yay' })
231
- end
232
- }
233
-
234
- TestClass.class_eval {
235
- define_decorator :ModifierDeco, ModifierDeco
236
-
237
- ModifierDeco()
238
- def test_method(*args, &block)
239
- Spy.passed_args(*args, &block)
240
- end
241
- }
242
- }
243
-
244
- it { expect(Spy).to receive(:arguments).with(args: [1, 2, 3], kwargs: { a: :a }, evald_block: 'yay') }
245
- after { TestClass.new.test_method }
247
+ it { expect(Spy).to receive(:arguments).with(args: [1, 2, 3], kwargs: { a: :a }, evald_block: 'yay') }
248
+ after { TestClass.new.test_method }
249
+ end
250
+
251
+ context 'when method is recursive' do
252
+ before do
253
+ stub_class(:AddOneToArg, inherits: [::Decors::DecoratorBase]) do
254
+ def call(instance, *args)
255
+ undecorated_call(instance, args.first + 1)
256
+ end
257
+ end
258
+
259
+ TestClass.class_eval do
260
+ define_decorator :AddOneToArg, AddOneToArg
261
+
262
+ AddOneToArg()
263
+ def test_method(n)
264
+ return 0 if n.zero?
265
+
266
+ n + test_method(n - 2)
267
+ end
268
+ end
269
+ end
270
+
271
+ it { expect(TestClass.new.test_method(4)).to eq 5 + 4 + 3 + 2 + 1 }
272
+ end
273
+
274
+ context 'when already has a method_added' do
275
+ before do
276
+ stub_module(:TestMixin) do
277
+ def method_added(*)
278
+ Spy.called
279
+ end
280
+ end
281
+ stub_class(:Deco, inherits: [::Decors::DecoratorBase])
246
282
  end
283
+ it { expect(Spy).to receive(:called) }
247
284
 
248
- context 'when method is recursive' do
249
- before {
250
- stub_class(:AddOneToArg, inherits: [::Decors::DecoratorBase]) {
251
- def call(instance, *args)
252
- undecorated_call(instance, args.first + 1)
253
- end
254
- }
255
-
256
- TestClass.class_eval {
257
- define_decorator :AddOneToArg, AddOneToArg
258
-
259
- AddOneToArg()
260
- def test_method(n)
261
- return 0 if n.zero?
262
- n + test_method(n - 2)
263
- end
264
- }
265
- }
266
-
267
- it { expect(TestClass.new.test_method(4)).to eq 5 + 4 + 3 + 2 + 1 }
285
+ after do
286
+ TestClass.class_eval do
287
+ extend TestMixin
288
+
289
+ define_decorator :Deco, Deco
290
+
291
+ def test_method; end
292
+ end
268
293
  end
294
+ end
295
+
296
+ context 'when inherited' do
297
+ before do
298
+ stub_class(:Deco, inherits: [::Decors::DecoratorBase])
269
299
 
270
- context 'when already has a method_added' do
271
- before {
272
- stub_module(:TestMixin) {
273
- def method_added(*)
274
- Spy.called
275
- end
276
- }
277
- stub_class(:Deco, inherits: [::Decors::DecoratorBase])
278
- }
279
- it { expect(Spy).to receive(:called) }
280
-
281
- after {
282
- TestClass.class_eval {
283
- extend TestMixin
284
-
285
- define_decorator :Deco, Deco
286
-
287
- def test_method; end
288
- }
289
- }
300
+ TestClass.class_eval do
301
+ define_decorator :Deco, Deco
302
+
303
+ Deco()
304
+ def test_method
305
+ :ok
306
+ end
307
+ end
290
308
  end
291
309
 
292
- context 'when inherited' do
293
- before {
294
- stub_class(:Deco, inherits: [::Decors::DecoratorBase])
295
-
296
- TestClass.class_eval {
297
- define_decorator :Deco, Deco
298
-
299
- Deco()
300
- def test_method
301
- :ok
302
- end
303
- }
304
- }
305
-
306
- it {
307
- stub_class(:TestClass2, inherits: [TestClass])
308
- TestClass2.class_eval {
309
- Deco()
310
- def test_method
311
- :ko
312
- end
313
- }
314
-
315
- expect(TestClass.new.test_method).to eq :ok
316
- expect(TestClass2.new.test_method).to eq :ko
317
- }
318
-
319
- it {
320
- stub_class(:TestClass3, inherits: [TestClass])
321
-
322
- TestClass3.class_eval {
323
- Deco()
324
- def test_method
325
- "this is #{super}"
326
- end
327
- }
328
-
329
- expect(TestClass3.new.test_method).to eq 'this is ok'
330
- }
310
+ it {
311
+ stub_class(:TestClass2, inherits: [TestClass])
312
+ TestClass2.class_eval do
313
+ Deco()
314
+ def test_method
315
+ :ko
316
+ end
317
+ end
318
+
319
+ expect(TestClass.new.test_method).to eq :ok
320
+ expect(TestClass2.new.test_method).to eq :ko
321
+ }
322
+
323
+ it {
324
+ stub_class(:TestClass3, inherits: [TestClass])
325
+
326
+ TestClass3.class_eval do
327
+ Deco()
328
+ def test_method
329
+ "this is #{super}"
330
+ end
331
+ end
332
+
333
+ expect(TestClass3.new.test_method).to eq 'this is ok'
334
+ }
335
+ end
336
+
337
+ context 'when decorating a class method' do
338
+ before do
339
+ stub_class(:Deco, inherits: [::Decors::DecoratorBase]) do
340
+ def call(*)
341
+ super
342
+ Spy.called
343
+ end
344
+ end
331
345
  end
332
346
 
333
- context 'when decorating a class method' do
334
- before {
335
- stub_class(:Deco, inherits: [::Decors::DecoratorBase]) {
336
- def call(*)
337
- super
338
- Spy.called
339
- end
340
- }
341
- }
342
-
343
- context 'when mixin extended on the class (singleton method in class)' do
344
- before {
345
- TestClass.class_eval {
346
- define_decorator :Deco, Deco
347
-
348
- Deco()
349
- def self.test_method
350
- :ok
351
- end
352
- }
353
- }
354
-
355
- it { expect(Spy).to receive(:called) }
356
- after { TestClass.test_method }
347
+ context 'when mixin extended on the class (singleton method in class)' do
348
+ before do
349
+ TestClass.class_eval do
350
+ define_decorator :Deco, Deco
351
+
352
+ Deco()
353
+ def self.test_method
354
+ :ok
355
+ end
357
356
  end
357
+ end
358
358
 
359
- context 'when mixin extended on the class (singleton method in singleton class)' do
360
- before {
361
- TestClass.class_eval {
362
- class << self
363
- extend Decors::DecoratorDefinition
359
+ it { expect(Spy).to receive(:called) }
360
+ after { TestClass.test_method }
361
+ end
364
362
 
365
- define_decorator :Deco, Deco
363
+ context 'when mixin extended on the class (singleton method in singleton class)' do
364
+ before do
365
+ TestClass.class_eval do
366
+ class << self
367
+ extend Decors::DecoratorDefinition
366
368
 
367
- Deco()
368
- def self.test_method
369
- :ok
370
- end
371
- end
372
- }
373
- }
369
+ define_decorator :Deco, Deco
374
370
 
375
- it { expect(Spy).to receive(:called) }
376
- after { TestClass.singleton_class.test_method }
371
+ Deco()
372
+ def self.test_method
373
+ :ok
374
+ end
375
+ end
377
376
  end
377
+ end
378
+
379
+ it { expect(Spy).to receive(:called) }
380
+ after { TestClass.singleton_class.test_method }
381
+ end
378
382
 
379
- context 'when mixin extended on the class (method in singleton class of singleton class)' do
380
- before {
381
- TestClass.class_eval {
382
- class << self
383
- class << self
384
- extend Decors::DecoratorDefinition
385
-
386
- define_decorator :Deco, Deco
387
-
388
- Deco()
389
- def test_method
390
- :ok
391
- end
392
- end
393
- end
394
- }
395
- }
396
-
397
- it { expect(Spy).to receive(:called) }
398
- after { TestClass.singleton_class.test_method }
383
+ context 'when mixin extended on the class (method in singleton class of singleton class)' do
384
+ before do
385
+ TestClass.class_eval do
386
+ class << self
387
+ class << self
388
+ extend Decors::DecoratorDefinition
389
+
390
+ define_decorator :Deco, Deco
391
+
392
+ Deco()
393
+ def test_method
394
+ :ok
395
+ end
396
+ end
397
+ end
399
398
  end
399
+ end
400
400
 
401
- context 'when mixin extended on the class (method in singleton class)' do
402
- before {
403
- TestClass.class_eval {
404
- class << self
405
- extend Decors::DecoratorDefinition
401
+ it { expect(Spy).to receive(:called) }
402
+ after { TestClass.singleton_class.test_method }
403
+ end
406
404
 
407
- define_decorator :Deco, Deco
405
+ context 'when mixin extended on the class (method in singleton class)' do
406
+ before do
407
+ TestClass.class_eval do
408
+ class << self
409
+ extend Decors::DecoratorDefinition
408
410
 
409
- Deco()
410
- def test_method
411
- :ok
412
- end
413
- end
414
- }
415
- }
411
+ define_decorator :Deco, Deco
416
412
 
417
- it { expect(Spy).to receive(:called) }
418
- after { TestClass.test_method }
413
+ Deco()
414
+ def test_method
415
+ :ok
416
+ end
417
+ end
419
418
  end
419
+ end
420
420
 
421
- context 'when mixin extended on the class (both method in singleton class and singleton method in class)' do
422
- before {
423
- TestClass.class_eval {
424
- define_decorator :Deco, Deco
421
+ it { expect(Spy).to receive(:called) }
422
+ after { TestClass.test_method }
423
+ end
425
424
 
426
- Deco()
427
- def self.test_method__in_class
428
- :ok
429
- end
425
+ context 'when mixin extended on the class (both method in singleton class and singleton method in class)' do
426
+ before do
427
+ TestClass.class_eval do
428
+ define_decorator :Deco, Deco
430
429
 
431
- def self.untest_method__in_class
432
- end
430
+ Deco()
431
+ def self.test_method__in_class
432
+ :ok
433
+ end
433
434
 
434
- class << self
435
- extend Decors::DecoratorDefinition
435
+ def self.untest_method__in_class; end
436
436
 
437
- define_decorator :Deco, Deco
437
+ class << self
438
+ extend Decors::DecoratorDefinition
438
439
 
439
- Deco()
440
- def test_method__in_singleton
441
- :ok
442
- end
440
+ define_decorator :Deco, Deco
443
441
 
444
- def untest_method__in_singleton
445
- end
446
- end
447
- }
448
- }
442
+ Deco()
443
+ def test_method__in_singleton
444
+ :ok
445
+ end
449
446
 
450
- it { expect(Spy).to receive(:called) and TestClass.test_method__in_class }
451
- it { expect(Spy).to receive(:called) and TestClass.test_method__in_singleton }
452
- it { expect(Spy).to_not receive(:called) and TestClass.untest_method__in_class }
453
- it { expect(Spy).to_not receive(:called) and TestClass.untest_method__in_singleton }
447
+ def untest_method__in_singleton; end
448
+ end
454
449
  end
450
+ end
451
+
452
+ it { expect(Spy).to receive(:called) and TestClass.test_method__in_class }
453
+ it { expect(Spy).to receive(:called) and TestClass.test_method__in_singleton }
454
+ it { expect(Spy).to_not receive(:called) and TestClass.untest_method__in_class }
455
+ it { expect(Spy).to_not receive(:called) and TestClass.untest_method__in_singleton }
455
456
  end
457
+ end
456
458
  end