sinclair 1.6.2 → 1.6.7

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -11,6 +11,10 @@ describe Sinclair::Options::Builder do
11
11
  let(:klass) { Class.new(Sinclair::Options) }
12
12
  let(:options) { klass.new }
13
13
 
14
+ let(:test_keys) do
15
+ %i[timeout retries invalid]
16
+ end
17
+
14
18
  context 'when calling with keys' do
15
19
  let(:args) { [:timeout, 'retries'] }
16
20
 
@@ -26,14 +30,14 @@ describe Sinclair::Options::Builder do
26
30
 
27
31
  it do
28
32
  expect { builder.build }
29
- .to change(klass, :allowed_options)
30
- .from([])
31
- .to(%i[timeout retries])
33
+ .to change { klass.invalid_options_in(test_keys) }
34
+ .from(test_keys)
35
+ .to([:invalid])
32
36
  end
33
37
 
34
38
  it do
35
39
  expect { builder.build }
36
- .not_to change(Sinclair::Options, :allowed_options)
40
+ .not_to change { Sinclair::Options.invalid_options_in(test_keys) }
37
41
  end
38
42
 
39
43
  context 'when when calling method after building' do
@@ -67,6 +71,10 @@ describe Sinclair::Options::Builder do
67
71
  [:protocol, { 'port' => 443 }]
68
72
  end
69
73
 
74
+ let(:test_keys) do
75
+ %i[timeout retries protocol port invalid]
76
+ end
77
+
70
78
  let(:super_builder) do
71
79
  described_class.new(super_class, :timeout, 'retries')
72
80
  end
@@ -85,14 +93,14 @@ describe Sinclair::Options::Builder do
85
93
 
86
94
  it do
87
95
  expect { builder.build }
88
- .to change(klass, :allowed_options)
89
- .from(%i[timeout retries])
90
- .to(%i[timeout retries protocol port])
96
+ .to change { klass.invalid_options_in(test_keys) }
97
+ .from(%i[protocol port invalid])
98
+ .to(%i[invalid])
91
99
  end
92
100
 
93
101
  it do
94
102
  expect { builder.build }
95
- .not_to change(super_class, :allowed_options)
103
+ .not_to change { super_class.invalid_options_in(test_keys) }
96
104
  end
97
105
  end
98
106
  end
@@ -0,0 +1,255 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Sinclair::Options::ClassMethods do
6
+ subject(:options) { klass.new }
7
+
8
+ describe '.with_options' do
9
+ let(:klass) { Class.new(Sinclair::Options) }
10
+ let(:test_keys) { %i[timeout retries invalid] }
11
+
12
+ context 'when calling with keys' do
13
+ it 'add first method' do
14
+ expect { klass.send(:with_options, :timeout, 'retries') }
15
+ .to add_method(:timeout).to(klass)
16
+ end
17
+
18
+ it 'add second method' do
19
+ expect { klass.send(:with_options, :timeout, 'retries') }
20
+ .to add_method(:retries).to(klass)
21
+ end
22
+
23
+ it 'adds options to allowed' do
24
+ expect { klass.send(:with_options, :timeout, 'retries') }
25
+ .to change { klass.invalid_options_in(test_keys) }
26
+ .from(%i[timeout retries invalid])
27
+ .to([:invalid])
28
+ end
29
+
30
+ it do
31
+ expect { klass.send(:with_options, :timeout, 'retries') }
32
+ .not_to change {
33
+ Sinclair::Options.invalid_options_in(%i[timeout retries invalid])
34
+ }
35
+ end
36
+
37
+ context 'when when calling method after building' do
38
+ before { klass.send(:with_options, :timeout, 'retries') }
39
+
40
+ it { expect(options.timeout).to be_nil }
41
+ end
42
+
43
+ context 'when calling method twice' do
44
+ before { klass.send(:with_options, :timeout, retries: 10) }
45
+
46
+ it do
47
+ expect { klass.send(:with_options, :timeout, :retries) }
48
+ .not_to change {
49
+ klass.invalid_options_in(%i[timeout retries invalid])
50
+ }
51
+ end
52
+ end
53
+ end
54
+
55
+ context 'when calling with a hash' do
56
+ it 'adds method' do
57
+ expect { klass.send(:with_options, timeout_sec: 10, 'retries' => 20) }
58
+ .to add_method(:timeout_sec).to(klass)
59
+ end
60
+
61
+ context 'when when calling method after building' do
62
+ before { klass.send(:with_options, timeout_sec: 10, 'retries' => 20) }
63
+
64
+ it 'returns default value' do
65
+ expect(options.retries).to eq(20)
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'when calling on subclass' do
71
+ let(:super_class) { Class.new(Sinclair::Options) }
72
+ let(:klass) { Class.new(super_class) }
73
+
74
+ let(:test_keys) do
75
+ %i[timeout retries name protocol port invalid]
76
+ end
77
+
78
+ before { super_class.send(:with_options, :timeout, 'retries', name: 'My Connector') }
79
+
80
+ it 'add first method' do
81
+ expect { klass.send(:with_options, :protocol, 'port' => 443) }
82
+ .to add_method(:protocol).to(klass)
83
+ end
84
+
85
+ it 'add second method' do
86
+ expect { klass.send(:with_options, :protocol, 'port' => 443) }
87
+ .to add_method(:port).to(klass)
88
+ end
89
+
90
+ it do
91
+ expect { klass.send(:with_options, 'protocol', port: 443) }
92
+ .to change {
93
+ klass.invalid_options_in(test_keys)
94
+ }.from(%i[protocol port invalid])
95
+ .to([:invalid])
96
+ end
97
+
98
+ it do
99
+ expect { klass.send(:with_options, 'protocol', port: 443) }
100
+ .not_to change {
101
+ super_class.invalid_options_in(%i[protocol port])
102
+ }
103
+ end
104
+
105
+ context 'when overriding a method' do
106
+ it do
107
+ expect { klass.send(:with_options, :name, timeout: 10) }
108
+ .not_to change { klass.invalid_options_in(%i[name timeout]) }
109
+ end
110
+
111
+ it 'change methods to return new default' do
112
+ expect { klass.send(:with_options, :name, timeout: 10) }
113
+ .to change { klass.new.timeout }
114
+ .from(nil).to(10)
115
+ end
116
+
117
+ it 'change methods to return without default' do
118
+ expect { klass.send(:with_options, :name, timeout: 10) }
119
+ .to change { klass.new.name }
120
+ .from('My Connector').to(nil)
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ describe '.invalid_options_in' do
127
+ let(:klass) { Class.new(Sinclair::Options) }
128
+ let(:test_keys) { %i[timeout invalid] }
129
+
130
+ it 'returns alls keys as invalid' do
131
+ expect(klass.invalid_options_in(test_keys))
132
+ .to eq(test_keys)
133
+ end
134
+
135
+ context 'when allowed options was never set' do
136
+ before { klass.allow(:timeout) }
137
+
138
+ it 'returns keys that are not allowed by the input' do
139
+ expect(klass.invalid_options_in(test_keys))
140
+ .to eq([:invalid])
141
+ end
142
+ end
143
+
144
+ context 'when calling on subclass' do
145
+ let(:super_class) { Class.new(Sinclair::Options) }
146
+ let(:klass) { Class.new(super_class) }
147
+ let(:test_keys) { %i[timeout invalid] }
148
+
149
+ before { super_class.allow(:timeout) }
150
+
151
+ context 'when not adding allowed options' do
152
+ it 'returns keys that are not allowed by the input' do
153
+ expect(klass.invalid_options_in(test_keys))
154
+ .to eq([:invalid])
155
+ end
156
+ end
157
+
158
+ context 'when adding keys' do
159
+ before { super_class.allow(:retries) }
160
+
161
+ it 'returns keys that are not allowed by the input' do
162
+ expect(klass.invalid_options_in(test_keys))
163
+ .to eq([:invalid])
164
+ end
165
+
166
+ it 'adds new key to accepted' do
167
+ expect(klass.invalid_options_in([:retries]))
168
+ .to be_empty
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ describe '.allow' do
175
+ let(:klass) { Class.new(Sinclair::Options) }
176
+ let(:test_keys) { %i[timeout retries invalid] }
177
+
178
+ it 'adds options to allowed' do
179
+ expect { klass.allow(:timeout) }
180
+ .to change { klass.invalid_options_in(test_keys) }
181
+ .from(%i[timeout retries invalid])
182
+ .to(%i[retries invalid])
183
+ end
184
+
185
+ context 'when calling on subclass' do
186
+ let(:super_class) { Class.new(Sinclair::Options) }
187
+ let(:klass) { Class.new(super_class) }
188
+
189
+ before { super_class.allow(:timeout) }
190
+
191
+ it 'adds options to allowed' do
192
+ expect { klass.allow(:retries) }
193
+ .to change { klass.invalid_options_in(test_keys) }
194
+ .from(%i[retries invalid])
195
+ .to(%i[invalid])
196
+ end
197
+ end
198
+ end
199
+
200
+ describe '.allowed_options' do
201
+ let(:klass) { Class.new(Sinclair::Options) }
202
+
203
+ context 'when class has not been changed' do
204
+ it { expect(klass.allowed_options).to be_a(Set) }
205
+ end
206
+
207
+ context 'when initializing with with options' do
208
+ let(:expected) do
209
+ Set.new %i[timeout retries port protocol]
210
+ end
211
+
212
+ before do
213
+ klass.send(
214
+ :with_options,
215
+ :timeout, :retries, port: 443, protocol: 'https'
216
+ )
217
+ end
218
+
219
+ it do
220
+ expect(klass.allowed_options)
221
+ .to eq(expected)
222
+ end
223
+
224
+ context 'when class is descendent' do
225
+ let(:descendent_class) { Class.new(klass) }
226
+ let(:expected) do
227
+ Set.new %i[timeout retries port protocol name]
228
+ end
229
+
230
+ before do
231
+ descendent_class.send(
232
+ :with_options,
233
+ :name
234
+ )
235
+ end
236
+
237
+ it do
238
+ expect(descendent_class.allowed_options)
239
+ .to eq(expected)
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ describe '.skip_validation' do
246
+ let(:klass) { Class.new(Sinclair::Options) }
247
+
248
+ it 'skip initialization validation' do
249
+ klass.send(:skip_validation)
250
+
251
+ expect { klass.new(invalid: 10) }
252
+ .not_to raise_error
253
+ end
254
+ end
255
+ end
@@ -5,84 +5,6 @@ require 'spec_helper'
5
5
  describe Sinclair::Options do
6
6
  subject(:options) { klass.new }
7
7
 
8
- describe '.with_options' do
9
- let(:klass) { Class.new(described_class) }
10
-
11
- context 'when calling with keys' do
12
- it 'add first method' do
13
- expect { klass.send(:with_options, :timeout, 'retries') }
14
- .to add_method(:timeout).to(klass)
15
- end
16
-
17
- it 'add second method' do
18
- expect { klass.send(:with_options, :timeout, 'retries') }
19
- .to add_method(:retries).to(klass)
20
- end
21
-
22
- it do
23
- expect { klass.send(:with_options, :timeout, 'retries') }
24
- .to change(klass, :allowed_options)
25
- .from([])
26
- .to(%i[timeout retries])
27
- end
28
-
29
- it do
30
- expect { klass.send(:with_options, :timeout, 'retries') }
31
- .not_to change(described_class, :allowed_options)
32
- end
33
-
34
- context 'when when calling method after building' do
35
- before { klass.send(:with_options, :timeout, 'retries') }
36
-
37
- it { expect(options.timeout).to be_nil }
38
- end
39
- end
40
-
41
- context 'when calling with a hash' do
42
- it 'adds method' do
43
- expect { klass.send(:with_options, timeout_sec: 10, 'retries' => 20) }
44
- .to add_method(:timeout_sec).to(klass)
45
- end
46
-
47
- context 'when when calling method after building' do
48
- before { klass.send(:with_options, timeout_sec: 10, 'retries' => 20) }
49
-
50
- it 'returns default value' do
51
- expect(options.retries).to eq(20)
52
- end
53
- end
54
- end
55
-
56
- context 'when calling on subclass' do
57
- let(:super_class) { Class.new(described_class) }
58
- let(:klass) { Class.new(super_class) }
59
-
60
- before { super_class.send(:with_options, :timeout, 'retries') }
61
-
62
- it 'add first method' do
63
- expect { klass.send(:with_options, :protocol, 'port' => 443) }
64
- .to add_method(:protocol).to(klass)
65
- end
66
-
67
- it 'add second method' do
68
- expect { klass.send(:with_options, :protocol, 'port' => 443) }
69
- .to add_method(:port).to(klass)
70
- end
71
-
72
- it do
73
- expect { klass.send(:with_options, 'protocol', port: 443) }
74
- .to change(klass, :allowed_options)
75
- .from(%i[timeout retries])
76
- .to(%i[timeout retries protocol port])
77
- end
78
-
79
- it do
80
- expect { klass.send(:with_options, 'protocol', port: 443) }
81
- .not_to change(super_class, :allowed_options)
82
- end
83
- end
84
- end
85
-
86
8
  describe '#initialize' do
87
9
  let(:klass) { ConnectionOptions }
88
10
 
@@ -164,6 +86,34 @@ describe Sinclair::Options do
164
86
  end
165
87
  end
166
88
 
89
+ context 'when initializing with invalid args a class that skips validation' do
90
+ let(:klass) { OpenOptions }
91
+
92
+ it do
93
+ expect { klass.new(valid_option: 20, invalid: 10) }
94
+ .not_to raise_error
95
+ end
96
+
97
+ it 'initialize option' do
98
+ expect(klass.new(valid_option: 20, invalid: 10).valid_option)
99
+ .to eq(20)
100
+ end
101
+
102
+ context 'when initializing a subclass' do
103
+ let(:klass) { Class.new(OpenOptions) }
104
+
105
+ it do
106
+ expect { klass.new(valid_option: 20, invalid: 10) }
107
+ .not_to raise_error
108
+ end
109
+
110
+ it 'initialize option' do
111
+ expect(klass.new(valid_option: 20, invalid: 10).valid_option)
112
+ .to eq(20)
113
+ end
114
+ end
115
+ end
116
+
167
117
  context 'when initializing with string or symbol keys' do
168
118
  it do
169
119
  expect { klass.new('timeout' => 20, retries: 30) }
@@ -195,4 +145,66 @@ describe Sinclair::Options do
195
145
  it { expect(options.protocol).to eq(false) }
196
146
  end
197
147
  end
148
+
149
+ describe '#to_h' do
150
+ let(:klass) { Class.new(described_class) }
151
+
152
+ context 'without defined options' do
153
+ it { expect(options.to_h).to be_a(Hash) }
154
+
155
+ it { expect(options.to_h).to be_empty }
156
+ end
157
+
158
+ context 'with defined options' do
159
+ before do
160
+ klass.send(:with_options, :timeout, retries: 10, 'protocol' => 'https')
161
+ end
162
+
163
+ it { expect(options.to_h).to be_a(Hash) }
164
+
165
+ it { expect(options.to_h).not_to be_empty }
166
+
167
+ it do
168
+ expect(options.to_h)
169
+ .to eq(timeout: nil, retries: 10, protocol: 'https')
170
+ end
171
+
172
+ context 'when initialized with values' do
173
+ subject(:options) { klass.new(retries: 20, timeout: 5) }
174
+
175
+ it { expect(options.to_h).to be_a(Hash) }
176
+
177
+ it { expect(options.to_h).not_to be_empty }
178
+
179
+ it 'uses values from initialization' do
180
+ expect(options.to_h)
181
+ .to eq(timeout: 5, retries: 20, protocol: 'https')
182
+ end
183
+ end
184
+ end
185
+ end
186
+
187
+ describe '#==' do
188
+ let(:klass) { ConnectionOptions }
189
+
190
+ context 'with black initialization' do
191
+ it do
192
+ expect(klass.new).to eq(klass.new)
193
+ end
194
+ end
195
+
196
+ context 'when initializing with same values' do
197
+ let(:first_option) { klass.new(protocol: nil) }
198
+ let(:second_option) { klass.new(protocol: nil) }
199
+
200
+ it { expect(first_option).to eq(second_option) }
201
+ end
202
+
203
+ context 'when initializing with different values' do
204
+ let(:first_option) { klass.new(protocol: nil) }
205
+ let(:second_option) { klass.new }
206
+
207
+ it { expect(first_option).not_to eq(second_option) }
208
+ end
209
+ end
198
210
  end