sinclair 1.6.2 → 1.6.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +37 -2
- data/Dockerfile +2 -2
- data/README.md +6 -2
- data/config/check_specs.yml +3 -0
- data/config/yardstick.yml +8 -1
- data/lib/sinclair/matchers.rb +37 -10
- data/lib/sinclair/matchers/add_class_method.rb +16 -13
- data/lib/sinclair/matchers/add_class_method_to.rb +9 -23
- data/lib/sinclair/matchers/add_instance_method.rb +16 -18
- data/lib/sinclair/matchers/add_instance_method_to.rb +12 -16
- data/lib/sinclair/matchers/add_method.rb +13 -30
- data/lib/sinclair/matchers/add_method_to.rb +4 -56
- data/lib/sinclair/matchers/base.rb +45 -0
- data/lib/sinclair/matchers/change_class_method.rb +42 -0
- data/lib/sinclair/matchers/change_class_method_on.rb +64 -0
- data/lib/sinclair/matchers/change_instance_method.rb +42 -0
- data/lib/sinclair/matchers/change_instance_method_on.rb +98 -0
- data/lib/sinclair/matchers/change_method_on.rb +25 -0
- data/lib/sinclair/matchers/method_to.rb +82 -0
- data/lib/sinclair/options.rb +47 -46
- data/lib/sinclair/options/builder.rb +1 -1
- data/lib/sinclair/options/class_methods.rb +99 -0
- data/lib/sinclair/version.rb +1 -1
- data/spec/integration/readme/sinclair/options_spec.rb +8 -0
- data/spec/integration/yard/sinclair/options_parser_spec.rb +9 -0
- data/spec/integration/yard/sinclair/options_spec.rb +17 -6
- data/spec/lib/sinclair/matchers/add_class_method_to_spec.rb +40 -16
- data/spec/lib/sinclair/matchers/add_instance_method_to_spec.rb +36 -12
- data/spec/lib/sinclair/matchers/change_class_method_on_spec.rb +138 -0
- data/spec/lib/sinclair/matchers/change_class_method_spec.rb +38 -0
- data/spec/lib/sinclair/matchers/change_instance_method_on_spec.rb +149 -0
- data/spec/lib/sinclair/matchers/change_instance_method_spec.rb +38 -0
- data/spec/lib/sinclair/matchers_spec.rb +30 -0
- data/spec/lib/sinclair/options/builder_spec.rb +16 -8
- data/spec/lib/sinclair/options/class_methods_spec.rb +255 -0
- data/spec/lib/sinclair/options_spec.rb +90 -78
- data/spec/support/models/builder_options.rb +7 -0
- data/spec/support/models/open_options.rb +7 -0
- 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
|
-
#
|
10
|
-
|
11
|
-
# @
|
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
|
-
#
|
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 [
|
26
|
-
def
|
27
|
-
|
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
|
-
|
33
|
-
|
34
|
-
protected
|
35
|
-
|
36
|
-
# @method method
|
37
|
-
# @private
|
18
|
+
# @abstract
|
38
19
|
#
|
39
|
-
#
|
20
|
+
# Raise a warning on the usage as this is only a builder
|
40
21
|
#
|
41
|
-
# @
|
42
|
-
|
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 <
|
11
|
-
|
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
|
62
|
-
|
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
|