sinclair 1.6.2 → 1.6.7

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +37 -2
  3. data/Dockerfile +2 -2
  4. data/README.md +6 -2
  5. data/config/check_specs.yml +3 -0
  6. data/config/yardstick.yml +8 -1
  7. data/lib/sinclair/matchers.rb +37 -10
  8. data/lib/sinclair/matchers/add_class_method.rb +16 -13
  9. data/lib/sinclair/matchers/add_class_method_to.rb +9 -23
  10. data/lib/sinclair/matchers/add_instance_method.rb +16 -18
  11. data/lib/sinclair/matchers/add_instance_method_to.rb +12 -16
  12. data/lib/sinclair/matchers/add_method.rb +13 -30
  13. data/lib/sinclair/matchers/add_method_to.rb +4 -56
  14. data/lib/sinclair/matchers/base.rb +45 -0
  15. data/lib/sinclair/matchers/change_class_method.rb +42 -0
  16. data/lib/sinclair/matchers/change_class_method_on.rb +64 -0
  17. data/lib/sinclair/matchers/change_instance_method.rb +42 -0
  18. data/lib/sinclair/matchers/change_instance_method_on.rb +98 -0
  19. data/lib/sinclair/matchers/change_method_on.rb +25 -0
  20. data/lib/sinclair/matchers/method_to.rb +82 -0
  21. data/lib/sinclair/options.rb +47 -46
  22. data/lib/sinclair/options/builder.rb +1 -1
  23. data/lib/sinclair/options/class_methods.rb +99 -0
  24. data/lib/sinclair/version.rb +1 -1
  25. data/spec/integration/readme/sinclair/options_spec.rb +8 -0
  26. data/spec/integration/yard/sinclair/options_parser_spec.rb +9 -0
  27. data/spec/integration/yard/sinclair/options_spec.rb +17 -6
  28. data/spec/lib/sinclair/matchers/add_class_method_to_spec.rb +40 -16
  29. data/spec/lib/sinclair/matchers/add_instance_method_to_spec.rb +36 -12
  30. data/spec/lib/sinclair/matchers/change_class_method_on_spec.rb +138 -0
  31. data/spec/lib/sinclair/matchers/change_class_method_spec.rb +38 -0
  32. data/spec/lib/sinclair/matchers/change_instance_method_on_spec.rb +149 -0
  33. data/spec/lib/sinclair/matchers/change_instance_method_spec.rb +38 -0
  34. data/spec/lib/sinclair/matchers_spec.rb +30 -0
  35. data/spec/lib/sinclair/options/builder_spec.rb +16 -8
  36. data/spec/lib/sinclair/options/class_methods_spec.rb +255 -0
  37. data/spec/lib/sinclair/options_spec.rb +90 -78
  38. data/spec/support/models/builder_options.rb +7 -0
  39. data/spec/support/models/open_options.rb +7 -0
  40. metadata +17 -2
@@ -3,43 +3,26 @@
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
+ # @return [Sinclair::Matchers::Base]
14
+ def to(target = nil)
15
+ add_method_to_class.new(target, method_name)
30
16
  end
31
17
 
32
- alias == equal?
33
-
34
- protected
35
-
36
- # @method method
37
- # @private
18
+ # @abstract
38
19
  #
39
- # The method, to be checked, name
20
+ # Raise a warning on the usage as this is only a builder
40
21
  #
41
- # @return [Symbol]
42
- attr_reader :method
22
+ # @raise SyntaxError
23
+ def matches?(_actual)
24
+ raise SyntaxError, matcher_error
25
+ end
43
26
  end
44
27
  end
45
28
  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
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ module Matchers
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Checks if a class method was changed
9
+ # by the call of a block
10
+ #
11
+ # This is used with a RSpec DSL method
12
+ # change_class_method(method_name).on(class_object)
13
+ class ChangeClassMethodOn < ChangeMethodOn
14
+ # @param [Class] klass
15
+ # Class where the class method should be added to
16
+ #
17
+ # @param method_name [SYmbol,String] method name
18
+ def initialize(target, method_name)
19
+ @klass = target
20
+ super(method_name)
21
+ end
22
+
23
+ # Return expectaton description
24
+ #
25
+ # @return [String]
26
+ def description
27
+ "change class method '#{method_name}' on #{klass}"
28
+ end
29
+
30
+ # Returns message on expectation failure
31
+ #
32
+ # @return [String]
33
+ def failure_message_for_should
34
+ "expected class method '#{method_name}' to be changed on #{klass} but " \
35
+ "#{initial_state ? "it didn't" : "it didn't exist"}"
36
+ end
37
+
38
+ # Returns message on expectation failure for negative expectation
39
+ #
40
+ # @return [String]
41
+ def failure_message_for_should_not
42
+ "expected class method '#{method_name}' not to be changed on #{klass} but it was"
43
+ end
44
+
45
+ private
46
+
47
+ # Checks if class has instance method defined
48
+ #
49
+ # @return [Boolean]
50
+ def state
51
+ klass.methods(false).include?(method_name.to_sym) \
52
+ && klass.method(method_name)
53
+ end
54
+
55
+ # Raises when block was not given
56
+ #
57
+ # @raise SyntaxError
58
+ def raise_block_syntax_error
59
+ raise SyntaxError, 'Block not received by the `change_class_method_on` matcher. ' \
60
+ 'Perhaps you want to use `{ ... }` instead of do/end?'
61
+ end
62
+ end
63
+ end
64
+ 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::ChangeInstanceMethodOn}
10
+ class ChangeInstanceMethod < Base
11
+ include AddMethod
12
+
13
+ # @api public
14
+ #
15
+ # Builds final matcher
16
+ #
17
+ # @return [Sinclair::Matchers::ChangeInstanceMethodOn]
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 instance the method is being changed on' \
29
+ "change_method(:#{method_name}).on(instance)"
30
+ end
31
+
32
+ # @private
33
+ #
34
+ # Class of the real matcher
35
+ #
36
+ # @return [Class<Sinclair::Matchers::Base>]
37
+ def add_method_to_class
38
+ ChangeInstanceMethodOn
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ module Matchers
5
+ # @api private
6
+ # @author darthjee
7
+ #
8
+ # Checks if a method was changed
9
+ # by the call of a block
10
+ #
11
+ # This is used with a RSpec DSL method
12
+ # change_method(method_name).on(class_object)
13
+ class ChangeInstanceMethodOn < ChangeMethodOn
14
+ # @overload initialize(klass, method_name)
15
+ # @param [Class] klass
16
+ # class where the method should be added to
17
+ #
18
+ # @overload initialize(instance, method_name)
19
+ # @param [Object] instance
20
+ # instance of the class where the method should be added to
21
+ #
22
+ # @param method_name [Symbol,String] method name
23
+ def initialize(target, method_name)
24
+ if target.is_a?(Class)
25
+ @klass = target
26
+ else
27
+ @instance = target
28
+ end
29
+
30
+ super(method_name)
31
+ end
32
+
33
+ # Returnst expectaton description
34
+ #
35
+ # @return [String]
36
+ def description
37
+ "change method '#{method_name}' on #{klass} instances"
38
+ end
39
+
40
+ # Returns message on expectation failure
41
+ #
42
+ # @return [String]
43
+ def failure_message_for_should
44
+ "expected '#{method_name}' to be changed on #{klass} but " \
45
+ "#{initial_state ? "it didn't" : "it didn't exist"}"
46
+ end
47
+
48
+ # Returns message on expectation failure for negative expectation
49
+ #
50
+ # @return [String]
51
+ def failure_message_for_should_not
52
+ "expected '#{method_name}' not to be changed on #{klass} but it was"
53
+ end
54
+
55
+ protected
56
+
57
+ # @method instance
58
+ # @api private
59
+ # @private
60
+ #
61
+ # Instance of the class where the method should be added
62
+ #
63
+ # @return [Object]
64
+ attr_reader :instance
65
+
66
+ # @private
67
+ #
68
+ # Class to be analised
69
+ #
70
+ # @return [Class]
71
+ def klass
72
+ @klass ||= instance.class
73
+ end
74
+
75
+ private
76
+
77
+ # @private
78
+ #
79
+ # Checks if class has instance method defined
80
+ #
81
+ # @return [Boolean]
82
+ def state
83
+ klass.method_defined?(method_name) &&
84
+ klass.instance_method(method_name)
85
+ end
86
+
87
+ # @private
88
+ #
89
+ # Raises when block was not given
90
+ #
91
+ # @raise SyntaxError
92
+ def raise_block_syntax_error
93
+ raise SyntaxError, 'Block not received by the `change_instance_method_on` matcher. ' \
94
+ 'Perhaps you want to use `{ ... }` instead of do/end?'
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Sinclair
4
+ module Matchers
5
+ # @api private
6
+ # @author darthjee
7
+ # @abstract
8
+ #
9
+ # Base class for change_method_on matcher
10
+ class ChangeMethodOn < Base
11
+ include MethodTo
12
+
13
+ private
14
+
15
+ # @private
16
+ #
17
+ # Checks if a method was changed
18
+ #
19
+ # @return Boolean
20
+ def check
21
+ initial_state && initial_state != final_state
22
+ end
23
+ end
24
+ end
25
+ end