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
@@ -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