sinclair 1.6.5 → 1.7.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 +4 -4
- data/.circleci/config.yml +2 -2
- data/Dockerfile +2 -2
- data/README.md +3 -1
- data/config/check_specs.yml +3 -0
- data/config/yardstick.yml +7 -1
- data/lib/sinclair/config.rb +46 -0
- data/lib/sinclair/config_class.rb +15 -0
- data/lib/sinclair/configurable.rb +8 -0
- 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 +39 -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/matchers.rb +38 -30
- data/lib/sinclair/options/class_methods.rb +95 -0
- data/lib/sinclair/options.rb +10 -60
- data/lib/sinclair/version.rb +1 -1
- data/sinclair.gemspec +12 -12
- data/spec/integration/readme/my_class_spec.rb +1 -1
- data/spec/integration/yard/sinclair/config_spec.rb +27 -0
- data/spec/integration/yard/sinclair/options_parser_spec.rb +9 -0
- data/spec/lib/sinclair/config_class_spec.rb +1 -33
- data/spec/lib/sinclair/config_spec.rb +71 -0
- 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/class_methods_spec.rb +255 -0
- data/spec/lib/sinclair/options_spec.rb +28 -237
- data/spec/support/models/builder_options.rb +7 -0
- data/spec/support/models/login_configurable.rb +7 -0
- data/spec/support/models/open_options.rb +7 -0
- data/spec/support/shared_examples/config.rb +48 -0
- metadata +43 -28
@@ -13,5 +13,14 @@ describe Sinclair::OptionsParser do
|
|
13
13
|
expect(model.the_method).to eq('The value is not 10 but 20')
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
describe '.skip_validation' do
|
18
|
+
it 'accepts options' do
|
19
|
+
options = BuilderOptions.new(name: 'Joe', age: 10)
|
20
|
+
|
21
|
+
expect(options.name).to eq('Joe')
|
22
|
+
expect(options.try(:age)).to be_nil
|
23
|
+
end
|
24
|
+
end
|
16
25
|
end
|
17
26
|
end
|
@@ -16,38 +16,6 @@ describe Sinclair::ConfigClass do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
describe '.add_configs' do
|
19
|
-
|
20
|
-
proc { |value| config.instance_variable_set(:@name, value) }
|
21
|
-
end
|
22
|
-
|
23
|
-
it_behaves_like 'a config methods builder adding config' do
|
24
|
-
let(:code_block) { proc { klass.add_configs(:name) } }
|
25
|
-
|
26
|
-
it 'sets nil value by default' do
|
27
|
-
code_block.call
|
28
|
-
expect(config.name).to be_nil
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'adds attributes to class' do
|
32
|
-
expect(&code_block).to change(klass, :config_attributes)
|
33
|
-
.from([]).to(%i[name])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'when giving defaults' do
|
38
|
-
it_behaves_like 'a config methods builder adding config' do
|
39
|
-
let(:code_block) { proc { klass.add_configs(name: 'Bob') } }
|
40
|
-
|
41
|
-
it 'sets default value' do
|
42
|
-
code_block.call
|
43
|
-
expect(config.name).to eq('Bob')
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'adds attributes to class' do
|
47
|
-
expect(&code_block).to change(klass, :config_attributes)
|
48
|
-
.from([]).to(%i[name])
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
19
|
+
it_behaves_like 'a config class with .add_configs method'
|
52
20
|
end
|
53
21
|
end
|
@@ -13,6 +13,10 @@ describe Sinclair::Config do
|
|
13
13
|
it_behaves_like 'a config class with .config_attributes method'
|
14
14
|
end
|
15
15
|
|
16
|
+
describe '.add_configs' do
|
17
|
+
it_behaves_like 'a config class with .add_configs method'
|
18
|
+
end
|
19
|
+
|
16
20
|
describe '#to_hash' do
|
17
21
|
it 'returns empty hash' do
|
18
22
|
expect(config.as_json).to eq({})
|
@@ -104,4 +108,71 @@ describe Sinclair::Config do
|
|
104
108
|
end
|
105
109
|
end
|
106
110
|
end
|
111
|
+
|
112
|
+
describe '#options' do
|
113
|
+
let(:expected_options) do
|
114
|
+
klass.options_class.new(username: :user, password: nil)
|
115
|
+
end
|
116
|
+
|
117
|
+
before do
|
118
|
+
klass.add_configs(:password, username: :user)
|
119
|
+
end
|
120
|
+
|
121
|
+
it do
|
122
|
+
expect(config.options).to be_a(Sinclair::Options)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'returns an option with default values' do
|
126
|
+
expect(config.options)
|
127
|
+
.to eq(expected_options)
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when config has been changed' do
|
131
|
+
let(:builder) do
|
132
|
+
Sinclair::ConfigBuilder.new(config, :username, :password)
|
133
|
+
end
|
134
|
+
|
135
|
+
let(:expected_options) do
|
136
|
+
klass.options_class.new(
|
137
|
+
username: :other_user, password: :some_password
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
before do
|
142
|
+
builder.username :other_user
|
143
|
+
builder.password :some_password
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'returns an option with values from config' do
|
147
|
+
expect(config.options)
|
148
|
+
.to eq(expected_options)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'when passing options_hash' do
|
153
|
+
let(:expected_options) do
|
154
|
+
klass.options_class.new(
|
155
|
+
username: :user, password: :some_password
|
156
|
+
)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'returns merged options' do
|
160
|
+
expect(config.options(password: :some_password))
|
161
|
+
.to eq(expected_options)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'when passing options_hash with string keys' do
|
166
|
+
let(:expected_options) do
|
167
|
+
klass.options_class.new(
|
168
|
+
username: :user, password: :some_password
|
169
|
+
)
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'returns merged options' do
|
173
|
+
expect(config.options('password' => :some_password))
|
174
|
+
.to eq(expected_options)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
107
178
|
end
|
@@ -13,22 +13,46 @@ describe Sinclair::Matchers::AddClassMethodTo do
|
|
13
13
|
proc { klass.send(:define_singleton_method, method) {} }
|
14
14
|
end
|
15
15
|
|
16
|
-
context 'when
|
17
|
-
|
18
|
-
|
16
|
+
context 'when class does not have the method yet' do
|
17
|
+
context 'when a method is added' do
|
18
|
+
it { expect(matcher).to be_matches(event_proc) }
|
19
|
+
end
|
19
20
|
|
20
|
-
|
21
|
-
|
21
|
+
context 'when a method is not added' do
|
22
|
+
let(:event_proc) { proc {} }
|
22
23
|
|
23
|
-
|
24
|
-
|
24
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when the wrong method is added' do
|
28
|
+
let(:event_proc) do
|
29
|
+
proc { klass.send(:define_singleton_method, :another_method) {} }
|
30
|
+
end
|
31
|
+
|
32
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
33
|
+
end
|
25
34
|
|
26
|
-
|
27
|
-
|
28
|
-
|
35
|
+
context 'when method already existed' do
|
36
|
+
before { event_proc.call }
|
37
|
+
|
38
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
29
39
|
end
|
30
40
|
|
31
|
-
|
41
|
+
context 'when method is added to instances' do
|
42
|
+
let(:event_proc) do
|
43
|
+
proc { klass.send(:define_method, method) {} }
|
44
|
+
end
|
45
|
+
|
46
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when class already has the method' do
|
51
|
+
before { klass.send(:define_singleton_method, method) {} }
|
52
|
+
|
53
|
+
context 'when a method is changed' do
|
54
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
55
|
+
end
|
32
56
|
end
|
33
57
|
|
34
58
|
context 'when a block is given' do
|
@@ -36,7 +60,7 @@ describe Sinclair::Matchers::AddClassMethodTo do
|
|
36
60
|
expect { matcher.matches?(event_proc) { 1 } }
|
37
61
|
.to raise_error(
|
38
62
|
SyntaxError, 'Block not received by the `add_class_method_to` matcher. ' \
|
39
|
-
|
63
|
+
'Perhaps you want to use `{ ... }` instead of do/end?'
|
40
64
|
)
|
41
65
|
end
|
42
66
|
end
|
@@ -45,7 +69,7 @@ describe Sinclair::Matchers::AddClassMethodTo do
|
|
45
69
|
describe '#failure_message_for_should' do
|
46
70
|
it 'returns information on the instance class and method' do
|
47
71
|
expect(matcher.failure_message_for_should)
|
48
|
-
.to eq("expected
|
72
|
+
.to eq("expected class method '#{method}' to be added to #{klass} but it didn't")
|
49
73
|
end
|
50
74
|
|
51
75
|
context 'when method already exited' do
|
@@ -56,7 +80,7 @@ describe Sinclair::Matchers::AddClassMethodTo do
|
|
56
80
|
|
57
81
|
it 'returns information on the instance class and method' do
|
58
82
|
expect(matcher.failure_message_for_should)
|
59
|
-
.to eq("expected
|
83
|
+
.to eq("expected class method '#{method}' to be added to #{klass} but it already existed")
|
60
84
|
end
|
61
85
|
end
|
62
86
|
end
|
@@ -64,14 +88,14 @@ describe Sinclair::Matchers::AddClassMethodTo do
|
|
64
88
|
describe '#failure_message_for_should_not' do
|
65
89
|
it 'returns information on the instance class and method' do
|
66
90
|
expect(matcher.failure_message_for_should_not)
|
67
|
-
.to eq("expected
|
91
|
+
.to eq("expected class method '#{method}' not to be added to #{klass} but it was")
|
68
92
|
end
|
69
93
|
end
|
70
94
|
|
71
95
|
describe 'description' do
|
72
96
|
it 'returns information on the instance class and method' do
|
73
97
|
expect(matcher.description)
|
74
|
-
.to eq("add method
|
98
|
+
.to eq("add class method '#{method}' to #{klass}")
|
75
99
|
end
|
76
100
|
end
|
77
101
|
end
|
@@ -14,22 +14,46 @@ describe Sinclair::Matchers::AddInstanceMethodTo do
|
|
14
14
|
proc { klass.send(:define_method, method) {} }
|
15
15
|
end
|
16
16
|
|
17
|
-
context 'when
|
18
|
-
|
19
|
-
|
17
|
+
context 'when class does not have the method yet' do
|
18
|
+
context 'when a method is added' do
|
19
|
+
it { expect(matcher).to be_matches(event_proc) }
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
context 'when a method is not added' do
|
23
|
+
let(:event_proc) { proc {} }
|
23
24
|
|
24
|
-
|
25
|
-
|
25
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when the wrong method is added' do
|
29
|
+
let(:event_proc) do
|
30
|
+
proc { klass.send(:define_method, :another_method) {} }
|
31
|
+
end
|
32
|
+
|
33
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when method already existed' do
|
37
|
+
before { event_proc.call }
|
38
|
+
|
39
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
40
|
+
end
|
26
41
|
|
27
|
-
|
28
|
-
|
29
|
-
|
42
|
+
context 'when method is added to the class' do
|
43
|
+
let(:event_proc) do
|
44
|
+
proc { klass.send(:define_singleton_method, method) {} }
|
45
|
+
end
|
46
|
+
|
47
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
30
48
|
end
|
49
|
+
end
|
31
50
|
|
32
|
-
|
51
|
+
context 'when class already has the method' do
|
52
|
+
before { klass.send(:define_method, method) {} }
|
53
|
+
|
54
|
+
context 'when a method is changed' do
|
55
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
56
|
+
end
|
33
57
|
end
|
34
58
|
|
35
59
|
context 'when initializing with class' do
|
@@ -45,7 +69,7 @@ describe Sinclair::Matchers::AddInstanceMethodTo do
|
|
45
69
|
expect { matcher.matches?(event_proc) { 1 } }
|
46
70
|
.to raise_error(
|
47
71
|
SyntaxError, 'Block not received by the `add_instance_method_to` matcher. ' \
|
48
|
-
|
72
|
+
'Perhaps you want to use `{ ... }` instead of do/end?'
|
49
73
|
)
|
50
74
|
end
|
51
75
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Matchers::ChangeClassMethodOn do
|
6
|
+
subject(:matcher) { described_class.new(klass, method) }
|
7
|
+
|
8
|
+
let(:method) { :the_method }
|
9
|
+
let(:klass) { Class.new }
|
10
|
+
|
11
|
+
describe '#matches?' do
|
12
|
+
let(:event_proc) do
|
13
|
+
proc { klass.send(:define_singleton_method, method) {} }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when class has the method' do
|
17
|
+
before { klass.send(:define_singleton_method, method) {} }
|
18
|
+
|
19
|
+
context 'when a method is changed' do
|
20
|
+
it { expect(matcher).to be_matches(event_proc) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when a method is not changed' do
|
24
|
+
let(:event_proc) { proc {} }
|
25
|
+
|
26
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when the wrong method is changed' do
|
30
|
+
let(:event_proc) do
|
31
|
+
proc { klass.send(:define_singleton_method, :another_method) {} }
|
32
|
+
end
|
33
|
+
|
34
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when method is changed on the class' do
|
38
|
+
let(:event_proc) do
|
39
|
+
proc { klass.send(:define_method, method) {} }
|
40
|
+
end
|
41
|
+
|
42
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when class does not have the method' do
|
47
|
+
context 'when a method is added' do
|
48
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when a block is given' do
|
53
|
+
it do
|
54
|
+
expect { matcher.matches?(event_proc) { 1 } }
|
55
|
+
.to raise_error(
|
56
|
+
SyntaxError, 'Block not received by the `change_class_method_on` matcher. ' \
|
57
|
+
'Perhaps you want to use `{ ... }` instead of do/end?'
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#failure_message_for_should' do
|
64
|
+
context 'when method already exited' do
|
65
|
+
before do
|
66
|
+
klass.send(:define_singleton_method, method) {}
|
67
|
+
matcher.matches?(proc {})
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'returns information on the instance class and method' do
|
71
|
+
expect(matcher.failure_message_for_should)
|
72
|
+
.to eq("expected class method '#{method}' to be changed on #{klass} but it didn't")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when method did not exite' do
|
77
|
+
it 'returns information on the instance class and method' do
|
78
|
+
expect(matcher.failure_message_for_should)
|
79
|
+
.to eq("expected class method '#{method}' to be changed on #{klass} but it didn't exist")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when initializing with class and method already existed' do
|
84
|
+
subject(:matcher) { described_class.new(klass, method) }
|
85
|
+
|
86
|
+
before do
|
87
|
+
klass.send(:define_singleton_method, method) {}
|
88
|
+
matcher.matches?(proc {})
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns information on the instance class and method' do
|
92
|
+
expect(matcher.failure_message_for_should)
|
93
|
+
.to eq("expected class method '#{method}' to be changed on #{klass} but it didn't")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when initializing with class and method didnt exist' do
|
98
|
+
subject(:matcher) { described_class.new(klass, method) }
|
99
|
+
|
100
|
+
it 'returns information on the instance class and method' do
|
101
|
+
expect(matcher.failure_message_for_should)
|
102
|
+
.to eq("expected class method '#{method}' to be changed on #{klass} but it didn't exist")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe '#failure_message_for_should_not' do
|
108
|
+
it 'returns information on the instance class and method' do
|
109
|
+
expect(matcher.failure_message_for_should_not)
|
110
|
+
.to eq("expected class method '#{method}' not to be changed on #{klass} but it was")
|
111
|
+
end
|
112
|
+
|
113
|
+
context 'when initializing with class' do
|
114
|
+
subject(:matcher) { described_class.new(klass, method) }
|
115
|
+
|
116
|
+
it 'returns information on the instance class and method' do
|
117
|
+
expect(matcher.failure_message_for_should_not)
|
118
|
+
.to eq("expected class method '#{method}' not to be changed on #{klass} but it was")
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe 'description' do
|
124
|
+
it 'returns information on the instance class and method' do
|
125
|
+
expect(matcher.description)
|
126
|
+
.to eq("change class method '#{method}' on #{klass}")
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'when initializing with class' do
|
130
|
+
subject(:matcher) { described_class.new(klass, method) }
|
131
|
+
|
132
|
+
it 'returns information on the instance class and method' do
|
133
|
+
expect(matcher.description)
|
134
|
+
.to eq("change class method '#{method}' on #{klass}")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Matchers::ChangeClassMethod do
|
6
|
+
subject(:matcher) { described_class.new(method) }
|
7
|
+
|
8
|
+
let(:method) { :the_method }
|
9
|
+
let(:klass) { Class.new }
|
10
|
+
|
11
|
+
describe '#on' do
|
12
|
+
it do
|
13
|
+
expect(matcher.on(klass.new))
|
14
|
+
.to be_a(Sinclair::Matchers::ChangeClassMethodOn)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns an add_class_method_to' do
|
18
|
+
expect(matcher.on(klass))
|
19
|
+
.to eq(Sinclair::Matchers::ChangeClassMethodOn.new(klass, method))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#matches?' do
|
24
|
+
it do
|
25
|
+
expect { matcher.matches?(proc {}) }
|
26
|
+
.to raise_error(
|
27
|
+
SyntaxError, 'You should specify which class the method is being changed on' \
|
28
|
+
"change_class_method(:#{method}).on(klass)"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#supports_block_expectations?' do
|
34
|
+
it do
|
35
|
+
expect(matcher).to be_supports_block_expectations
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Matchers::ChangeInstanceMethodOn do
|
6
|
+
subject(:matcher) { described_class.new(instance, method) }
|
7
|
+
|
8
|
+
let(:method) { :the_method }
|
9
|
+
let(:klass) { Class.new }
|
10
|
+
let(:instance) { klass.new }
|
11
|
+
|
12
|
+
describe '#matches?' do
|
13
|
+
let(:event_proc) do
|
14
|
+
proc { klass.send(:define_method, method) {} }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when class has the method' do
|
18
|
+
before { klass.send(:define_method, method) {} }
|
19
|
+
|
20
|
+
context 'when a method is changed' do
|
21
|
+
it { expect(matcher).to be_matches(event_proc) }
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'when a method is not changed' do
|
25
|
+
let(:event_proc) { proc {} }
|
26
|
+
|
27
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when the wrong method is changed' do
|
31
|
+
let(:event_proc) do
|
32
|
+
proc { klass.send(:define_method, :another_method) {} }
|
33
|
+
end
|
34
|
+
|
35
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when method is changed on the class' do
|
39
|
+
let(:event_proc) do
|
40
|
+
proc { klass.send(:define_singleton_method, method) {} }
|
41
|
+
end
|
42
|
+
|
43
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when class does not have the method' do
|
48
|
+
context 'when a method is added' do
|
49
|
+
it { expect(matcher).not_to be_matches(event_proc) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when initializing with class' do
|
54
|
+
subject(:matcher) { described_class.new(klass, method) }
|
55
|
+
|
56
|
+
before { klass.send(:define_method, method) {} }
|
57
|
+
|
58
|
+
context 'when a method is added' do
|
59
|
+
it { expect(matcher).to be_matches(event_proc) }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when a block is given' do
|
64
|
+
it do
|
65
|
+
expect { matcher.matches?(event_proc) { 1 } }
|
66
|
+
.to raise_error(
|
67
|
+
SyntaxError, 'Block not received by the `change_instance_method_on` matcher. ' \
|
68
|
+
'Perhaps you want to use `{ ... }` instead of do/end?'
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#failure_message_for_should' do
|
75
|
+
context 'when method already exited' do
|
76
|
+
before do
|
77
|
+
klass.send(:define_method, method) {}
|
78
|
+
matcher.matches?(proc {})
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'returns information on the instance class and method' do
|
82
|
+
expect(matcher.failure_message_for_should)
|
83
|
+
.to eq("expected '#{method}' to be changed on #{klass} but it didn't")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'when method did not exite' do
|
88
|
+
it 'returns information on the instance class and method' do
|
89
|
+
expect(matcher.failure_message_for_should)
|
90
|
+
.to eq("expected '#{method}' to be changed on #{klass} but it didn't exist")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when initializing with class and method already existed' do
|
95
|
+
subject(:matcher) { described_class.new(klass, method) }
|
96
|
+
|
97
|
+
before do
|
98
|
+
klass.send(:define_method, method) {}
|
99
|
+
matcher.matches?(proc {})
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns information on the instance class and method' do
|
103
|
+
expect(matcher.failure_message_for_should)
|
104
|
+
.to eq("expected '#{method}' to be changed on #{klass} but it didn't")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when initializing with class and method didnt exist' do
|
109
|
+
subject(:matcher) { described_class.new(klass, method) }
|
110
|
+
|
111
|
+
it 'returns information on the instance class and method' do
|
112
|
+
expect(matcher.failure_message_for_should)
|
113
|
+
.to eq("expected '#{method}' to be changed on #{klass} but it didn't exist")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#failure_message_for_should_not' do
|
119
|
+
it 'returns information on the instance class and method' do
|
120
|
+
expect(matcher.failure_message_for_should_not)
|
121
|
+
.to eq("expected '#{method}' not to be changed on #{klass} but it was")
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'when initializing with class' do
|
125
|
+
subject(:matcher) { described_class.new(klass, method) }
|
126
|
+
|
127
|
+
it 'returns information on the instance class and method' do
|
128
|
+
expect(matcher.failure_message_for_should_not)
|
129
|
+
.to eq("expected '#{method}' not to be changed on #{klass} but it was")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe 'description' do
|
135
|
+
it 'returns information on the instance class and method' do
|
136
|
+
expect(matcher.description)
|
137
|
+
.to eq("change method '#{method}' on #{klass} instances")
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'when initializing with class' do
|
141
|
+
subject(:matcher) { described_class.new(klass, method) }
|
142
|
+
|
143
|
+
it 'returns information on the instance class and method' do
|
144
|
+
expect(matcher.description)
|
145
|
+
.to eq("change method '#{method}' on #{klass} instances")
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe Sinclair::Matchers::ChangeInstanceMethod do
|
6
|
+
subject(:matcher) { described_class.new(method) }
|
7
|
+
|
8
|
+
let(:method) { :the_method }
|
9
|
+
let(:klass) { Class.new }
|
10
|
+
let(:instance) { klass.new }
|
11
|
+
|
12
|
+
describe '#on' do
|
13
|
+
it do
|
14
|
+
expect(matcher.on(klass.new)).to be_a(Sinclair::Matchers::ChangeInstanceMethodOn)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'returns an change_instance_method_on' do
|
18
|
+
expect(matcher.on(instance))
|
19
|
+
.to eq(Sinclair::Matchers::ChangeInstanceMethodOn.new(instance, method))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#matches?' do
|
24
|
+
it do
|
25
|
+
expect { matcher.matches?(proc {}) }
|
26
|
+
.to raise_error(
|
27
|
+
SyntaxError, 'You should specify which instance the method is being changed on' \
|
28
|
+
"change_method(:#{method}).on(instance)"
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#supports_block_expectations?' do
|
34
|
+
it do
|
35
|
+
expect(matcher).to be_supports_block_expectations
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|