sinclair 1.6.5 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +2 -2
  3. data/Dockerfile +2 -2
  4. data/README.md +3 -1
  5. data/config/check_specs.yml +3 -0
  6. data/config/yardstick.yml +7 -1
  7. data/lib/sinclair/config.rb +46 -0
  8. data/lib/sinclair/config_class.rb +15 -0
  9. data/lib/sinclair/configurable.rb +8 -0
  10. data/lib/sinclair/matchers/add_class_method.rb +16 -13
  11. data/lib/sinclair/matchers/add_class_method_to.rb +9 -23
  12. data/lib/sinclair/matchers/add_instance_method.rb +16 -18
  13. data/lib/sinclair/matchers/add_instance_method_to.rb +12 -16
  14. data/lib/sinclair/matchers/add_method.rb +39 -30
  15. data/lib/sinclair/matchers/add_method_to.rb +4 -56
  16. data/lib/sinclair/matchers/base.rb +45 -0
  17. data/lib/sinclair/matchers/change_class_method.rb +42 -0
  18. data/lib/sinclair/matchers/change_class_method_on.rb +64 -0
  19. data/lib/sinclair/matchers/change_instance_method.rb +42 -0
  20. data/lib/sinclair/matchers/change_instance_method_on.rb +98 -0
  21. data/lib/sinclair/matchers/change_method_on.rb +25 -0
  22. data/lib/sinclair/matchers/method_to.rb +82 -0
  23. data/lib/sinclair/matchers.rb +38 -30
  24. data/lib/sinclair/options/class_methods.rb +95 -0
  25. data/lib/sinclair/options.rb +10 -60
  26. data/lib/sinclair/version.rb +1 -1
  27. data/sinclair.gemspec +12 -12
  28. data/spec/integration/readme/my_class_spec.rb +1 -1
  29. data/spec/integration/yard/sinclair/config_spec.rb +27 -0
  30. data/spec/integration/yard/sinclair/options_parser_spec.rb +9 -0
  31. data/spec/lib/sinclair/config_class_spec.rb +1 -33
  32. data/spec/lib/sinclair/config_spec.rb +71 -0
  33. data/spec/lib/sinclair/matchers/add_class_method_to_spec.rb +40 -16
  34. data/spec/lib/sinclair/matchers/add_instance_method_to_spec.rb +36 -12
  35. data/spec/lib/sinclair/matchers/change_class_method_on_spec.rb +138 -0
  36. data/spec/lib/sinclair/matchers/change_class_method_spec.rb +38 -0
  37. data/spec/lib/sinclair/matchers/change_instance_method_on_spec.rb +149 -0
  38. data/spec/lib/sinclair/matchers/change_instance_method_spec.rb +38 -0
  39. data/spec/lib/sinclair/matchers_spec.rb +30 -0
  40. data/spec/lib/sinclair/options/class_methods_spec.rb +255 -0
  41. data/spec/lib/sinclair/options_spec.rb +28 -237
  42. data/spec/support/models/builder_options.rb +7 -0
  43. data/spec/support/models/login_configurable.rb +7 -0
  44. data/spec/support/models/open_options.rb +7 -0
  45. data/spec/support/shared_examples/config.rb +48 -0
  46. metadata +43 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82dceb39442cd887b9188fd91bc0b225aedae2504e180a61ba3f5ec6d18b6de3
4
- data.tar.gz: '09dafbb7642c1021c47c7ab4db0732f5f514c881d61adba3a7d1cc3c6ac620ca'
3
+ metadata.gz: 4e9a5068ba9c9c0f3def716decd2cea72fbdea0e6a3255d2bd0d324462de4ef5
4
+ data.tar.gz: c067ae53d0320738e785675306dc7f8848851a3adb964217bd30593c15eaedbf
5
5
  SHA512:
6
- metadata.gz: 794343fe9272e52bd35a9b0a23c3b2e5e64d45a291f29b75d94335b6ff0f65e6d117585ca75562e9fad94b186d5cc1d66126caec9df3d06a4497cee5d6fe3fa8
7
- data.tar.gz: ac6e7f371357b46111d9eceaf0b5d6a06816d1bd537665d4824d96713762e59ce7eb986048ac18d4219d9fd860e165f200c8d5cbfea34e62f04a0d7e7c641959
6
+ metadata.gz: ddc575979d46b47983aa57083243e674ac1da951e1e8407b98ee188a17e60e7683d5a73ad829914e34d076764970fb93484f9da67b767a89b301f47d081aad47
7
+ data.tar.gz: 0052e1e9b9e86758cf2b35c215509d6d4946b5e8bd0fde994b2e8121b83807de04d8c4e84d3fa3ee47565e4a07f89313f0ef871d6156f93ebdd7e6c8df0a83c5
data/.circleci/config.yml CHANGED
@@ -18,7 +18,7 @@ workflows:
18
18
  jobs:
19
19
  test:
20
20
  docker:
21
- - image: darthjee/circleci_ruby_gems:0.5.3
21
+ - image: darthjee/circleci_ruby_270:1.1.0
22
22
  environment:
23
23
  PROJECT: sinclair
24
24
  steps:
@@ -52,7 +52,7 @@ jobs:
52
52
  command: check_specs
53
53
  build-and-release:
54
54
  docker:
55
- - image: darthjee/circleci_ruby_gems:0.5.3
55
+ - image: darthjee/circleci_ruby_270:1.1.0
56
56
  environment:
57
57
  PROJECT: sinclair
58
58
  steps:
data/Dockerfile CHANGED
@@ -1,6 +1,6 @@
1
- FROM darthjee/scripts:0.1.8 as scripts
1
+ FROM darthjee/scripts:0.3.1 as scripts
2
2
 
3
- FROM darthjee/ruby_gems:0.5.3 as base
3
+ FROM darthjee/ruby_270:1.1.0 as base
4
4
 
5
5
  COPY --chown=app:app ./ /home/app/app/
6
6
 
data/README.md CHANGED
@@ -15,7 +15,7 @@ methods
15
15
 
16
16
  Yard Documentation
17
17
  -------------------
18
- [https://www.rubydoc.info/gems/sinclair/1.6.5](https://www.rubydoc.info/gems/sinclair/1.6.5)
18
+ [https://www.rubydoc.info/gems/sinclair/1.7.0](https://www.rubydoc.info/gems/sinclair/1.7.0)
19
19
 
20
20
  Installation
21
21
  ---------------
@@ -452,6 +452,8 @@ Options allows projects to have an easy to configure option object
452
452
  ```ruby
453
453
  class ConnectionOptions < Sinclair::Options
454
454
  with_options :timeout, :retries, port: 443, protocol: 'https'
455
+
456
+ # skip_validation if you dont want to validate intialization arguments
455
457
  end
456
458
 
457
459
  options = ConnectionOptions.new(
@@ -4,3 +4,6 @@ ignore:
4
4
  - lib/sinclair/version.rb
5
5
  - lib/sinclair/method_builder/base.rb
6
6
  - lib/sinclair/exception.rb
7
+ - lib/sinclair/matchers/method_to.rb
8
+ - lib/sinclair/matchers/base.rb
9
+ - lib/sinclair/matchers/change_method_on.rb
data/config/yardstick.yml CHANGED
@@ -1,4 +1,4 @@
1
- threshold: 100
1
+ threshold: 99.8
2
2
  require_exact_threshold: false
3
3
  rules:
4
4
  ApiTag::Presence:
@@ -28,6 +28,8 @@ rules:
28
28
  - Sinclair::Matchers::AddClassMethodTo#raise_block_syntax_error
29
29
  - Sinclair::Matchers::AddInstanceMethodTo#raise_block_syntax_error
30
30
  - Sinclair::MethodBuilder#build_from_definition
31
+ - Sinclair::Matchers::ChangeClassMethodOn#raise_block_syntax_error
32
+ - Sinclair::Matchers::ChangeInstanceMethodOn#raise_block_syntax_error
31
33
  Summary::Presence:
32
34
  enabled: true
33
35
  exclude:
@@ -36,10 +38,14 @@ rules:
36
38
  - Sinclair::EnvSettable::Builder#initialize
37
39
  - Sinclair::Exception::InvalidOptions#initialize
38
40
  - Sinclair::InputHash#initialize
41
+ - Sinclair::Matchers::AddInstanceMethodTo#initialize
39
42
  - Sinclair::Matchers::AddClassMethodTo#initialize
40
43
  - Sinclair::Matchers::AddInstanceMethodTo#instance
41
44
  - Sinclair::Matchers::AddMethod#initialize
42
45
  - Sinclair::Matchers::AddMethodTo#initialize
46
+ - Sinclair::Matchers::Base#initialize
47
+ - Sinclair::Matchers::ChangeClassMethodOn#initialize
48
+ - Sinclair::Matchers::ChangeInstanceMethodOn#initialize
43
49
  - Sinclair::MethodBuilder
44
50
  - Sinclair::MethodBuilder::Base#initialize
45
51
  - Sinclair::MethodDefinition#initialize
@@ -37,5 +37,51 @@ class Sinclair
37
37
  hash[attribute.to_s] = public_send(attribute)
38
38
  end
39
39
  end
40
+
41
+ # Returns options with configurated values
42
+ #
43
+ # The returned options will use the values defined in
44
+ # the config merged with the extra attributes
45
+ #
46
+ # @param options_hash [Hash] optional values for the options
47
+ #
48
+ # @return [Sinclair::Option]
49
+ #
50
+ # @example returning default options
51
+ # class LoginConfig < Sinclair::Config
52
+ # add_configs :password, username: 'bob'
53
+ # end
54
+ #
55
+ # class LoginConfigurable
56
+ # extend Sinclair::Configurable
57
+ #
58
+ # configurable_by LoginConfig
59
+ # end
60
+ #
61
+ # LoginConfigurable.configure do |conf|
62
+ # conf.username :some_username
63
+ # conf.password :some_password
64
+ # end
65
+ #
66
+ # options = LoginConfigurable.config.options
67
+ #
68
+ # config.options.username # returns :some_username
69
+ # config.options.password # returns :some_password
70
+ #
71
+ # @example returning custom options
72
+ # LoginConfigurable.configure do |conf|
73
+ # conf.username :some_username
74
+ # conf.password :some_password
75
+ # end
76
+ #
77
+ # options = LoginConfigurable.config.options(
78
+ # password: :correct_password
79
+ # )
80
+ #
81
+ # config.options.username # returns :some_username
82
+ # config.options.password # returns :correct_password
83
+ def options(options_hash = {})
84
+ self.class.options_class.new(to_hash.merge(options_hash))
85
+ end
40
86
  end
41
87
  end
@@ -89,8 +89,23 @@ class Sinclair
89
89
  Config::MethodsBuilder.new(self, *args).tap do |builder|
90
90
  builder.build
91
91
 
92
+ Sinclair::InputHash.input_hash(*args).each do |name, value|
93
+ options_class.with_options(name => value)
94
+ end
95
+
92
96
  config_attributes(*builder.config_names)
93
97
  end
94
98
  end
99
+
100
+ # @api private
101
+ # Returns the options class exclusive to this configurable
102
+ #
103
+ # The returned class is configured in parallel with the
104
+ # configurable itself
105
+ #
106
+ # @return [Class<Sinclair::Options>]
107
+ def options_class
108
+ @options_class ||= Class.new(Sinclair::Options)
109
+ end
95
110
  end
96
111
  end
@@ -78,6 +78,14 @@ class Sinclair
78
78
  # @see ConfigFactory#configure
79
79
  delegate :config, :reset_config, :configure, to: :config_factory
80
80
 
81
+ # @method options(options_hash = {})
82
+ # @api public
83
+ #
84
+ # @param (see Sinclair::Config#options)
85
+ # @return (see Sinclair::Config#options)
86
+ # @example (see Sinclair::Config#options)
87
+ delegate :options, to: :config
88
+
81
89
  protected
82
90
 
83
91
  # @api private
@@ -31,25 +31,28 @@ class Sinclair
31
31
  #
32
32
  # # outputs
33
33
  # # should add method class_method 'new_method' to #<Class:0x000055b4d0a25c80>
34
- class AddClassMethod < AddMethod
35
- # @abstract
34
+ class AddClassMethod < Base
35
+ include AddMethod
36
+
37
+ private
38
+
39
+ # @private
36
40
  #
37
- # Raise a warning on the usage as this is only a builder for AddClassMethodTo
41
+ # Error description on wrong usage
38
42
  #
39
- # @raise SyntaxError
40
- def matches?(_actual)
41
- raise SyntaxError, 'You should specify which class the method is being added to' \
42
- "add_class_method(:#{method}).to(klass)"
43
+ # @return String
44
+ def matcher_error
45
+ 'You should specify which class the method is being added to' \
46
+ "add_class_method(:#{method_name}).to(klass)"
43
47
  end
44
48
 
45
- # Creates a matcher {AddClassMethodTo}
49
+ # @private
46
50
  #
47
- # @param target [Class]
48
- # class where the method should be added to
51
+ # Class of the real matcher
49
52
  #
50
- # @return [AddClassMethodTo] the correct matcher
51
- def to(target = nil)
52
- AddClassMethodTo.new(target, method)
53
+ # @return [Class<Sinclair::Matchers::Base>]
54
+ def add_method_to_class
55
+ AddClassMethodTo
53
56
  end
54
57
  end
55
58
  end
@@ -36,55 +36,41 @@ class Sinclair
36
36
  # @param [Class] klass
37
37
  # Class where the class method should be added to
38
38
  #
39
- # @param method [SYmbol,String] method name
40
- def initialize(klass, method)
39
+ # @param method_name [SYmbol,String] method name
40
+ def initialize(klass, method_name)
41
41
  @klass = klass
42
- super(method)
42
+ super(method_name)
43
43
  end
44
44
 
45
45
  # Return expectaton description
46
46
  #
47
47
  # @return [String]
48
48
  def description
49
- "add method class_method '#{method}' to #{klass}"
49
+ "add class method '#{method_name}' to #{klass}"
50
50
  end
51
51
 
52
52
  # Returns message on expectation failure
53
53
  #
54
54
  # @return [String]
55
55
  def failure_message_for_should
56
- "expected class_method '#{method}' to be added to #{klass} but " \
57
- "#{@initial_state ? 'it already existed' : "it didn't"}"
56
+ "expected class method '#{method_name}' to be added to #{klass} but " \
57
+ "#{initial_state ? 'it already existed' : "it didn't"}"
58
58
  end
59
59
 
60
60
  # Returns message on expectation failure for negative expectation
61
61
  #
62
62
  # @return [String]
63
63
  def failure_message_for_should_not
64
- "expected class_method '#{method}' not to be added to #{klass} but it was"
64
+ "expected class method '#{method_name}' not to be added to #{klass} but it was"
65
65
  end
66
66
 
67
- alias failure_message failure_message_for_should
68
- alias failure_message_when_negated failure_message_for_should_not
69
-
70
- protected
71
-
72
- # @method klass
73
- # @private
74
- # @api private
75
- #
76
- # Class where class method should be added to
77
- #
78
- # @return [Class]
79
- attr_reader :klass
80
-
81
67
  private
82
68
 
83
69
  # Checks if class has instance method defined
84
70
  #
85
71
  # @return [Boolean]
86
- def method_defined?
87
- klass.methods(false).include?(method.to_sym)
72
+ def state
73
+ klass.methods(false).include?(method_name.to_sym)
88
74
  end
89
75
 
90
76
  # Raises when block was not given
@@ -55,30 +55,28 @@ class Sinclair
55
55
  #
56
56
  # # Outputs
57
57
  # # 'should add method 'the_method' to #<Class:0x000056441bf46608> instances'
58
- class AddInstanceMethod < AddMethod
59
- # @abstract
58
+ class AddInstanceMethod < Base
59
+ include AddMethod
60
+
61
+ private
62
+
63
+ # @private
60
64
  #
61
- # Raise a warning on the usage as this is only a builder for {AddInstanceMethodTo}
65
+ # Error description on wrong usage
62
66
  #
63
- # @raise SyntaxError
64
- def matches?(_actual)
65
- raise SyntaxError, 'You should specify which instance the method is being added to' \
66
- "add_method(:#{method}).to(instance)"
67
+ # @return String
68
+ def matcher_error
69
+ 'You should specify which instance the method is being added to' \
70
+ "add_method(:#{method_name}).to(instance)"
67
71
  end
68
72
 
69
- # Creates a matcher AddInstanceMethodTo
70
- #
71
- # @overload to(klass)
72
- # @param [Class] klass
73
- # class where the method should be added to
73
+ # @private
74
74
  #
75
- # @overload to(instance)
76
- # @param [Object] instance
77
- # instance of the class where the method should be added to
75
+ # Class of the real matcher
78
76
  #
79
- # @return [AddInstanceMethodTo] the correct matcher
80
- def to(target = nil)
81
- AddInstanceMethodTo.new(target, method)
77
+ # @return [Class<Sinclair::Matchers::Base>]
78
+ def add_method_to_class
79
+ AddInstanceMethodTo
82
80
  end
83
81
  end
84
82
  end
@@ -30,54 +30,50 @@ class Sinclair
30
30
  # end
31
31
  # end
32
32
  class AddInstanceMethodTo < AddMethodTo
33
- # Returns a new instance of AddInstanceMethodTo
34
- #
35
- # @overload initialize(klass, method)
33
+ # @overload initialize(klass, method_name)
36
34
  # @param [Class] klass
37
35
  # class where the method should be added to
38
36
  #
39
- # @overload initialize(instance, method)
37
+ # @overload initialize(instance, method_name)
40
38
  # @param [Object] instance
41
39
  # instance of the class where the method should be added to
42
40
  #
43
- # @param method [Symbol,String] method name
44
- def initialize(target, method)
41
+ # @param method_name [Symbol,String] method name
42
+ def initialize(target, method_name)
45
43
  if target.is_a?(Class)
46
44
  @klass = target
47
45
  else
48
46
  @instance = target
49
47
  end
50
- super(method)
48
+ super(method_name)
51
49
  end
52
50
 
53
51
  # Returnst expectaton description
54
52
  #
55
53
  # @return [String]
56
54
  def description
57
- "add method '#{method}' to #{klass} instances"
55
+ "add method '#{method_name}' to #{klass} instances"
58
56
  end
59
57
 
60
58
  # Returns message on expectation failure
61
59
  #
62
60
  # @return [String]
63
61
  def failure_message_for_should
64
- "expected '#{method}' to be added to #{klass} but " \
65
- "#{@initial_state ? 'it already existed' : "it didn't"}"
62
+ "expected '#{method_name}' to be added to #{klass} but " \
63
+ "#{initial_state ? 'it already existed' : "it didn't"}"
66
64
  end
67
65
 
68
66
  # Returns message on expectation failure for negative expectation
69
67
  #
70
68
  # @return [String]
71
69
  def failure_message_for_should_not
72
- "expected '#{method}' not to be added to #{klass} but it was"
70
+ "expected '#{method_name}' not to be added to #{klass} but it was"
73
71
  end
74
72
 
75
- alias failure_message failure_message_for_should
76
- alias failure_message_when_negated failure_message_for_should_not
77
-
78
73
  protected
79
74
 
80
75
  # @method instance
76
+ # @api private
81
77
  # @private
82
78
  #
83
79
  # Instance of the class where the method should be added
@@ -101,8 +97,8 @@ class Sinclair
101
97
  # Checks if class has instance method defined
102
98
  #
103
99
  # @return [Boolean]
104
- def method_defined?
105
- klass.method_defined?(method)
100
+ def state
101
+ klass.method_defined?(method_name)
106
102
  end
107
103
 
108
104
  # @private
@@ -3,43 +3,52 @@
3
3
  class Sinclair
4
4
  module Matchers
5
5
  # @api private
6
- # @author darthjee
7
- # @abstract
8
6
  #
9
- # Base class for add_method matcher
10
- class AddMethod < RSpec::Matchers::BuiltIn::BaseMatcher
11
- # @param method [String,Symbol] the method, to be checked, name
12
- def initialize(method)
13
- @method = method.to_sym
14
- end
15
-
16
- # definition needed for block matchers
7
+ # Commone methods for matchers
8
+ module AddMethod
9
+ # @api public
17
10
  #
18
- # @return [Boolean]
19
- def supports_block_expectations?
20
- true
21
- end
22
-
23
- # Checkes if another instnce is equal self
11
+ # Builds final matcher
24
12
  #
25
- # @return [Boolean]
26
- def equal?(other)
27
- return unless other.class == self.class
28
-
29
- other.method == method
13
+ # The matcher checks if a method was added
14
+ # to a class or instance
15
+ #
16
+ # @param [target] target where the method will be added
17
+ #
18
+ # @return [Sinclair::Matchers::Base]
19
+ #
20
+ # @example
21
+ # RSpec.configure do |config|
22
+ # config.include Sinclair::Matchers
23
+ # end
24
+ #
25
+ # class MyModel
26
+ # end
27
+ #
28
+ # RSpec.describe 'my test' do
29
+ # let(:klass) { Class.new(MyModel) }
30
+ # let(:builder) { Sinclair.new(klass) }
31
+ #
32
+ # before do
33
+ # builder.add_method(:class_name, 'self.class.name')
34
+ # end
35
+ #
36
+ # it do
37
+ # expect { builder.build }.to add_method(:class_name).to(klass)
38
+ # end
39
+ # end
40
+ def to(target = nil)
41
+ add_method_to_class.new(target, method_name)
30
42
  end
31
43
 
32
- alias == equal?
33
-
34
- protected
35
-
36
- # @method method
37
- # @private
44
+ # @abstract
38
45
  #
39
- # The method, to be checked, name
46
+ # Raise a warning on the usage as this is only a builder
40
47
  #
41
- # @return [Symbol]
42
- attr_reader :method
48
+ # @raise SyntaxError
49
+ def matches?(_actual)
50
+ raise SyntaxError, matcher_error
51
+ end
43
52
  end
44
53
  end
45
54
  end
@@ -7,49 +7,8 @@ class Sinclair
7
7
  # @abstract
8
8
  #
9
9
  # Base class for add_method_to matcher
10
- class AddMethodTo < RSpec::Matchers::BuiltIn::BaseMatcher
11
- # @param method [SYmbol,String] method name
12
- def initialize(method)
13
- @method = method
14
- end
15
-
16
- # Checks if expectation is true or not
17
- #
18
- # @return [Boolean] expectation check
19
- def matches?(event_proc)
20
- return false unless event_proc.is_a?(Proc)
21
-
22
- raise_block_syntax_error if block_given?
23
- perform_change(event_proc)
24
- added?
25
- end
26
-
27
- # definition needed for block matchers
28
- def supports_block_expectations?
29
- true
30
- end
31
-
32
- # Checkes if another instnce is equal self
33
- #
34
- # @return [Boolean]
35
- def equal?(other)
36
- return unless other.class == self.class
37
-
38
- other.method == method &&
39
- other.klass == klass
40
- end
41
-
42
- alias == equal?
43
-
44
- protected
45
-
46
- # @method method
47
- # @private
48
- #
49
- # The method, to be checked, name
50
- #
51
- # @return [Symbol]
52
- attr_reader :method
10
+ class AddMethodTo < Base
11
+ include MethodTo
53
12
 
54
13
  private
55
14
 
@@ -58,19 +17,8 @@ class Sinclair
58
17
  # Checks if a method was added (didn't exist before)
59
18
  #
60
19
  # @return Boolean
61
- def added?
62
- !@initial_state && @final_state
63
- end
64
-
65
- # @private
66
- #
67
- # Call block to check if it aded a method or not
68
- #
69
- # @return [Boolan]
70
- def perform_change(event_proc)
71
- @initial_state = method_defined?
72
- event_proc.call
73
- @final_state = method_defined?
20
+ def check
21
+ !initial_state && final_state
74
22
  end
75
23
  end
76
24
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ module Matchers
5
+ # @abstract
6
+ # @api private
7
+ #
8
+ # Base class for all matchers
9
+ class Base < RSpec::Matchers::BuiltIn::BaseMatcher
10
+ # @param method_name [String,Symbol] the method, to be checked, name
11
+ def initialize(method_name)
12
+ @method_name = method_name.to_sym
13
+ end
14
+
15
+ # definition needed for block matchers
16
+ #
17
+ # @return [Boolean]
18
+ def supports_block_expectations?
19
+ true
20
+ end
21
+
22
+ # Checkes if another instnce is equal self
23
+ #
24
+ # @return [Boolean]
25
+ def equal?(other)
26
+ return unless other.class == self.class
27
+
28
+ other.method_name == method_name &&
29
+ other.try(:klass) == try(:klass)
30
+ end
31
+
32
+ alias == equal?
33
+
34
+ protected
35
+
36
+ # @method method_name
37
+ # @private
38
+ #
39
+ # The method, to be checked, name
40
+ #
41
+ # @return [Symbol]
42
+ attr_reader :method_name
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ module Matchers
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # AddInstanceMethod is able to build an instance of
9
+ # {Sinclair::Matchers::ChangeClassMethodOn}
10
+ class ChangeClassMethod < Base
11
+ include AddMethod
12
+
13
+ # @api public
14
+ #
15
+ # Builds final matcher
16
+ #
17
+ # @return [Sinclair::Matchers::ChangeClassMethodOn]
18
+ alias on to
19
+
20
+ private
21
+
22
+ # @private
23
+ #
24
+ # Error description on wrong usage
25
+ #
26
+ # @return String
27
+ def matcher_error
28
+ 'You should specify which class the method is being changed on' \
29
+ "change_class_method(:#{method_name}).on(klass)"
30
+ end
31
+
32
+ # @private
33
+ #
34
+ # Class of the real matcher
35
+ #
36
+ # @return [Class<ChangeClassMethodOn>]
37
+ def add_method_to_class
38
+ ChangeClassMethodOn
39
+ end
40
+ end
41
+ end
42
+ end