decors 0.3.0 → 0.4.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
- 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