rspec-its 1.3.1 → 2.0.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.
@@ -1,393 +1,423 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
2
 
3
- module RSpec
4
- describe Its do
5
- describe "#its" do
6
- context "with implicit subject" do
7
- context "preserves described_class" do
8
- its(:symbol) { expect(described_class).to be Its }
9
- its([]) { expect(described_class).to be Its }
10
- end
11
- end
3
+ require 'spec_helper'
12
4
 
13
- context "with explicit subject" do
14
- subject do
15
- Class.new do
16
- def initialize
17
- @call_count = 0
18
- end
5
+ RSpec.describe RSpec::Its do
6
+ context "with implicit subject" do
7
+ context "preserves described_class" do
8
+ its(:symbol) { expect(described_class).to be RSpec::Its }
9
+ its([]) { expect(described_class).to be RSpec::Its }
10
+ end
11
+ end
19
12
 
20
- def call_count
21
- @call_count += 1
22
- end
23
- end.new
13
+ context "with explicit subject" do
14
+ subject do
15
+ Class.new do
16
+ def initialize
17
+ @call_count = 0
24
18
  end
25
19
 
26
- before(:each, :meta) do
27
- subject.call_count
20
+ def call_count
21
+ @call_count += 1
28
22
  end
23
+ end.new
24
+ end
29
25
 
30
- context "with some metadata" do
31
- its(:call_count, :meta) { should eq(2) }
32
- end
26
+ before(:each, :meta) do
27
+ subject.call_count
28
+ end
33
29
 
34
- context "with a call counter" do
35
- its(:call_count) { should eq(1) }
36
- end
30
+ context "with some metadata" do
31
+ its(:call_count, :meta) { is_expected.to eq(2) }
32
+ end
37
33
 
38
- context "with nil value" do
39
- subject do
40
- Class.new do
41
- def nil_value
42
- nil
43
- end
44
- end.new
45
- end
46
- its(:nil_value) { should be_nil }
47
- end
34
+ context "with a call counter" do
35
+ its(:call_count) { is_expected.to eq(1) }
36
+ end
48
37
 
49
- context "with nested attributes" do
50
- subject do
51
- Class.new do
52
- def name
53
- "John"
54
- end
55
- end.new
56
- end
57
- its("name") { should eq("John") }
58
- its("name.size") { should eq(4) }
59
- if RUBY_VERSION >= "2.4.0"
60
- its("name.size.class") { should eq(Integer) }
61
- else
62
- its("name.size.class") { should eq(Fixnum) }
38
+ context "with nil value" do
39
+ subject do
40
+ Class.new do
41
+ def nil_value
42
+ nil
63
43
  end
44
+ end.new
45
+ end
64
46
 
65
- context "using should_not" do
66
- its("name") { should_not eq("Paul") }
67
- end
47
+ its(:nil_value) { is_expected.to be_nil }
48
+ end
68
49
 
69
- context "using is_expected" do
70
- its("name") { is_expected.to eq("John") }
50
+ context "with nested attributes" do
51
+ subject do
52
+ Class.new do
53
+ def name
54
+ "John"
71
55
  end
56
+ end.new
57
+ end
72
58
 
73
- context "using will_not" do
74
- its("name") { will_not raise_error }
75
- end
59
+ its("name") { is_expected.to eq("John") }
60
+ its("name.size") { is_expected.to eq(4) }
61
+ its("name.size.class") { is_expected.to eq(Integer) }
62
+
63
+ context "using are_expected" do
64
+ its("name.chars.to_a") { are_expected.to eq(%w[J o h n]) }
65
+ end
66
+
67
+ context "using will_not" do
68
+ its("name") { will_not raise_error }
69
+ end
70
+
71
+ context "using should" do
72
+ its("name") { should eq("John") }
73
+ end
74
+
75
+ context "using should_not" do
76
+ its("name") { should_not eq("Paul") }
77
+ end
78
+ end
76
79
 
77
- context "using are_expected" do
78
- its("name.chars.to_a") { are_expected.to eq(%w[J o h n]) }
80
+ context "when it responds to #[]" do
81
+ subject do
82
+ Class.new do
83
+ def [](*objects)
84
+ objects.map do |object|
85
+ "#{object.class}: #{object}"
86
+ end.join("; ")
79
87
  end
80
- end
81
88
 
82
- context "when it responds to #[]" do
83
- subject do
84
- Class.new do
85
- def [](*objects)
86
- objects.map do |object|
87
- "#{object.class}: #{object.to_s}"
88
- end.join("; ")
89
- end
90
-
91
- def name
92
- "George"
93
- end
94
- end.new
89
+ def name
90
+ "George"
95
91
  end
96
- its([:a]) { should eq("Symbol: a") }
97
- its(['a']) { should eq("String: a") }
98
- if RUBY_VERSION >= "2.4.0"
99
- its([:b, 'c', 4]) { should eq("Symbol: b; String: c; Integer: 4") }
100
- else
101
- its([:b, 'c', 4]) { should eq("Symbol: b; String: c; Fixnum: 4") }
92
+ end.new
93
+ end
94
+
95
+ its([:a]) { is_expected.to eq("Symbol: a") }
96
+ its(['a']) { is_expected.to eq("String: a") }
97
+ its([:b, 'c', 4]) { is_expected.to eq("Symbol: b; String: c; Integer: 4") }
98
+ its(:name) { is_expected.to eq("George") }
99
+
100
+ context "when referring to an attribute that doesn't exist" do
101
+ context "it raises an error" do
102
+ its(:age) do
103
+ expect do
104
+ is_expected.to eq(64)
105
+ end.to raise_error(NoMethodError)
102
106
  end
103
- its(:name) { should eq("George") }
104
- context "when referring to an attribute that doesn't exist" do
105
- context "it raises an error" do
106
- its(:age) do
107
- expect do
108
- should eq(64)
109
- end.to raise_error(NoMethodError)
110
- end
111
-
112
- context "using will" do
113
- its(:age) { will raise_error(NoMethodError) }
114
- end
115
- end
107
+
108
+ context "using will" do
109
+ its(:age) { will raise_error(NoMethodError) }
116
110
  end
111
+ end
112
+ end
117
113
 
118
- context "when it's a hash" do
119
- subject { {:a => {:deep => {:key => "value"}}} }
114
+ context "when it's a hash" do
115
+ subject { { a: { deep: { key: "value" } } } }
120
116
 
121
- its([:a]) { should eq({:deep => {:key => "value"}}) }
122
- its([:a, :deep]) { should eq({:key => "value"}) }
123
- its([:a, :deep, :key]) { should eq("value") }
117
+ its([:a]) { is_expected.to eq({ deep: { key: "value" } }) }
118
+ its(%i[a deep]) { is_expected.to eq({ key: "value" }) }
119
+ its(%i[a deep key]) { is_expected.to eq("value") }
124
120
 
125
- context "when referring to a key that doesn't exist" do
126
- its([:not_here]) { should be_nil }
127
- its([:a, :ghost]) { should be_nil }
128
- its([:deep, :ghost]) { expect { should eq("missing") }.to raise_error(NoMethodError) }
121
+ context "when referring to a key that doesn't exist" do
122
+ its([:not_here]) { is_expected.to be_nil }
123
+ its(%i[a ghost]) { are_expected.to be_nil }
124
+ its(%i[deep ghost]) { expect { is_expected.to eq("missing") }.to raise_error(NoMethodError) }
129
125
 
130
- context "using will" do
131
- its([:deep, :ghost]) { will raise_error(NoMethodError) }
132
- end
133
- end
126
+ context "using will" do
127
+ its(%i[deep ghost]) { will raise_error(NoMethodError) }
134
128
  end
135
129
  end
130
+ end
131
+ end
136
132
 
137
- context "when it does not respond to #[]" do
138
- subject { Object.new }
139
-
140
- context "it raises an error" do
141
- its([:a]) do
142
- expect do
143
- should eq("Symbol: a")
144
- end.to raise_error(NoMethodError)
145
- end
133
+ context "when it does not respond to #[]" do
134
+ subject { Object.new }
146
135
 
147
- context "using will" do
148
- its([:a]) { will raise_error(NoMethodError) }
149
- end
150
- end
136
+ context "it raises an error" do
137
+ its([:a]) do
138
+ expect { is_expected.to eq("Symbol: a") }.to raise_error(NoMethodError)
151
139
  end
152
140
 
153
- context "calling and overriding super" do
154
- it "calls to the subject defined in the parent group" do
155
- group = RSpec::Core::ExampleGroup.describe(Array) do
156
- subject { [1, 'a'] }
141
+ context "using will" do
142
+ its([:a]) { will raise_error(NoMethodError) }
143
+ end
144
+ end
145
+ end
157
146
 
158
- its(:last) { should eq("a") }
147
+ context "calling and overriding super" do
148
+ it "calls to the subject defined in the parent group" do
149
+ group = RSpec::Core::ExampleGroup.describe(Array) do
150
+ subject { [1, 'a'] }
159
151
 
160
- describe '.first' do
161
- def subject;
162
- super().first;
163
- end
152
+ its(:last) { is_expected.to eq("a") }
164
153
 
165
- its(:next) { should eq(2) }
166
- end
154
+ describe '.first' do
155
+ def subject
156
+ super.first
167
157
  end
168
158
 
169
- expect(group.run(NullFormatter.new)).to be_truthy
159
+ its(:next) { is_expected.to eq(2) }
170
160
  end
171
161
  end
172
162
 
173
- context "with nil subject" do
174
- subject do
175
- Class.new do
176
- def initialize
177
- @counter = -1
178
- end
179
-
180
- def nil_if_first_time
181
- @counter += 1
182
- @counter == 0 ? nil : true
183
- end
184
- end.new
163
+ expect(group.run(NullFormatter.new)).to be_truthy
164
+ end
165
+ end
166
+
167
+ context "with nil subject" do
168
+ subject do
169
+ Class.new do
170
+ def initialize
171
+ @counter = -1
185
172
  end
186
- its(:nil_if_first_time) { should be(nil) }
187
- end
188
173
 
189
- context "with false subject" do
190
- subject do
191
- Class.new do
192
- def initialize
193
- @counter = -1
194
- end
195
-
196
- def false_if_first_time
197
- @counter += 1
198
- @counter > 0
199
- end
200
- end.new
174
+ def nil_if_first_time
175
+ @counter += 1
176
+ @counter == 0 ? nil : true
201
177
  end
202
- its(:false_if_first_time) { should be(false) }
203
- end
178
+ end.new
179
+ end
204
180
 
205
- describe 'accessing `subject` in `before` and `let`' do
206
- subject { 'my subject' }
207
- before { @subject_in_before = subject }
208
- let(:subject_in_let) { subject }
209
- let!(:eager_loaded_subject_in_let) { subject }
210
-
211
- # These examples read weird, because we're actually
212
- # specifying the behaviour of `its` itself
213
- its(nil) { expect(subject).to eq('my subject') }
214
- its(nil) { expect(@subject_in_before).to eq('my subject') }
215
- its(nil) { expect(subject_in_let).to eq('my subject') }
216
- its(nil) { expect(eager_loaded_subject_in_let).to eq('my subject') }
217
- end
181
+ its(:nil_if_first_time) { is_expected.to be(nil) }
182
+ end
218
183
 
219
- describe "in shared_context" do
220
- shared_context "shared stuff" do
221
- subject { Array }
222
- its(:name) { should eq "Array" }
184
+ context "with false subject" do
185
+ subject do
186
+ Class.new do
187
+ def initialize
188
+ @counter = -1
223
189
  end
224
190
 
225
- include_context "shared stuff"
226
- end
191
+ def false_if_first_time
192
+ @counter += 1
193
+ @counter > 0
194
+ end
195
+ end.new
196
+ end
227
197
 
228
- describe "when extending SharedContext" do
229
- it 'works with an implicit subject' do
230
- shared = Module.new do
231
- extend RSpec::SharedContext
232
- its(:size) { should eq 0 }
233
- end
234
- group = RSpec::Core::ExampleGroup.describe(Array) do
235
- include shared
236
- end
198
+ its(:false_if_first_time) { is_expected.to be(false) }
199
+ end
237
200
 
238
- group.run(NullFormatter.new)
201
+ describe 'accessing `subject` in `before` and `let`' do
202
+ subject { 'my subject' }
239
203
 
240
- result = group.children.first.examples.first.execution_result
241
- # Following conditional needed to work across mix of RSpec and ruby versions without warning
242
- status = result.respond_to?(:status) ? result.status : result[:status].to_sym
243
- expect(status).to eq(:passed)
244
- end
245
- end
246
- end
247
- context "with metadata" do
248
- context "preserves access to metadata that doesn't end in hash" do
249
- its([], :foo) do |example|
250
- expect(example.metadata[:foo]).to be(true)
251
- end
252
- end
253
- context "preserves access to metadata that ends in hash" do
254
- its([], :foo, :bar => 17) do |example|
255
- expect(example.metadata[:foo]).to be(true)
256
- expect(example.metadata[:bar]).to be(17)
257
- end
258
- end
259
- end
204
+ before { @subject_in_before = subject }
260
205
 
261
- context "when expecting errors" do
262
- subject do
263
- Class.new do
264
- def good; end
206
+ let(:subject_in_let) { subject }
207
+ let!(:eager_loaded_subject_in_let) { subject }
265
208
 
266
- def bad
267
- raise ArgumentError, "message"
268
- end
269
- end.new
270
- end
209
+ # These examples read weird, because we're actually
210
+ # specifying the behaviour of `its` itself
211
+ its(nil) { expect(subject).to eq('my subject') }
212
+ its(nil) { expect(@subject_in_before).to eq('my subject') }
213
+ its(nil) { expect(subject_in_let).to eq('my subject') }
214
+ its(nil) { expect(eager_loaded_subject_in_let).to eq('my subject') }
215
+ end
216
+
217
+ describe "in shared_context" do
218
+ shared_context "shared stuff" do
219
+ subject { Array }
271
220
 
272
- its(:good) { will_not raise_error }
273
- its(:bad) { will raise_error(ArgumentError) }
274
- its(:bad) { will raise_error("message") }
275
- its(:bad) { will raise_error(ArgumentError, "message") }
221
+ its(:name) { is_expected.to eq "Array" }
276
222
  end
277
223
 
278
- context "when expecting throws" do
279
- subject do
280
- Class.new do
281
- def good; end
224
+ include_context "shared stuff"
225
+ end
282
226
 
283
- def bad
284
- throw :abort, "message"
285
- end
286
- end.new
227
+ describe "when extending SharedContext" do
228
+ it 'works with an implicit subject' do
229
+ shared = Module.new do
230
+ extend RSpec::SharedContext
231
+ its(:size) { is_expected.to eq 0 }
232
+ end
233
+
234
+ group = RSpec::Core::ExampleGroup.describe(Array) do
235
+ include shared
287
236
  end
288
237
 
289
- its(:good) { will_not throw_symbol }
290
- its(:bad) { will throw_symbol }
291
- its(:bad) { will throw_symbol(:abort) }
292
- its(:bad) { will throw_symbol(:abort, "message") }
238
+ group.run(NullFormatter.new)
239
+
240
+ result = group.children.first.examples.first.execution_result
241
+ # Following conditional needed to work across mix of RSpec and ruby versions without warning
242
+ status = result.respond_to?(:status) ? result.status : result[:status].to_sym
243
+ expect(status).to eq(:passed)
293
244
  end
245
+ end
246
+ end
294
247
 
295
- context "with change observation" do
296
- subject do
297
- Class.new do
298
- attr_reader :count
248
+ context "with metadata" do
249
+ context "preserves access to metadata that doesn't end in hash" do
250
+ its([], :foo) do |example|
251
+ expect(example.metadata[:foo]).to be(true)
252
+ end
253
+ end
299
254
 
300
- def initialize
301
- @count = 0
302
- end
255
+ context "preserves access to metadata that ends in hash" do
256
+ its([], :foo, bar: 17) do |example|
257
+ expect(example.metadata[:foo]).to be(true)
258
+ expect(example.metadata[:bar]).to be(17)
259
+ end
260
+ end
261
+ end
303
262
 
304
- def increment
305
- @count += 1
306
- end
263
+ context "when expecting errors" do
264
+ subject do
265
+ Class.new do
266
+ def good; end
307
267
 
308
- def noop; end
309
- end.new
268
+ def bad
269
+ raise ArgumentError, "message"
310
270
  end
271
+ end.new
272
+ end
311
273
 
312
- its(:increment) { will change { subject.count }.by(1) }
313
- its(:increment) { will change { subject.count }.from(0) }
314
- its(:increment) { will change { subject.count }.from(0).to(1) }
315
- its(:increment) { will change { subject.count }.by_at_least(1) }
316
- its(:increment) { will change { subject.count }.by_at_most(1) }
274
+ its(:good) { will_not raise_error }
275
+ its(:bad) { will raise_error(ArgumentError) }
276
+ its(:bad) { will raise_error("message") }
277
+ its(:bad) { will raise_error(ArgumentError, "message") }
278
+ end
317
279
 
318
- its(:noop) { will_not change { subject.count } }
319
- its(:noop) { will_not change { subject.count }.from(0) }
280
+ context "when expecting throws" do
281
+ subject do
282
+ Class.new do
283
+ def good; end
320
284
 
321
- its(:increment) do
322
- expect { will_not change { subject.count }.by(0) }.to \
323
- raise_error(NotImplementedError, '`expect { }.not_to change { }.by()` is not supported')
285
+ def bad
286
+ throw :abort, "message"
324
287
  end
288
+ end.new
289
+ end
290
+
291
+ its(:good) { will_not throw_symbol }
292
+ its(:bad) { will throw_symbol }
293
+ its(:bad) { will throw_symbol(:abort) }
294
+ its(:bad) { will throw_symbol(:abort, "message") }
295
+ end
296
+
297
+ context "with change observation" do
298
+ subject do
299
+ Class.new do
300
+ attr_reader :count
325
301
 
326
- its(:increment) do
327
- expect { will_not change { subject.count }.by_at_least(2) }.to \
328
- raise_error(NotImplementedError, '`expect { }.not_to change { }.by_at_least()` is not supported')
302
+ def initialize
303
+ @count = 0
329
304
  end
330
305
 
331
- its(:increment) do
332
- expect { will_not change { subject.count }.by_at_most(3) }.to \
333
- raise_error(NotImplementedError, '`expect { }.not_to change { }.by_at_most()` is not supported')
306
+ def increment
307
+ @count += 1
334
308
  end
335
- end
336
309
 
337
- context "with output capture" do
338
- subject do
339
- Class.new do
340
- def stdout
341
- print "some output"
342
- end
310
+ def noop; end
311
+ end.new
312
+ end
343
313
 
344
- def stderr
345
- $stderr.print "some error"
346
- end
314
+ its(:increment) { will change { subject.count }.by(1) }
315
+ its(:increment) { will change { subject.count }.from(0) }
316
+ its(:increment) { will change { subject.count }.from(0).to(1) }
317
+ its(:increment) { will change { subject.count }.by_at_least(1) }
318
+ its(:increment) { will change { subject.count }.by_at_most(1) }
347
319
 
348
- def noop; end
349
- end.new
350
- end
320
+ its(:noop) { will_not(change { subject.count }) }
321
+ its(:noop) { will_not change { subject.count }.from(0) }
351
322
 
352
- its(:stdout) { will output("some output").to_stdout }
353
- its(:stderr) { will output("some error").to_stderr }
323
+ its(:increment) do
324
+ expect { will_not change { subject.count }.by(0) }.to \
325
+ raise_error(NotImplementedError, '`expect { }.not_to change { }.by()` is not supported')
326
+ end
354
327
 
355
- its(:noop) { will_not output("some error").to_stderr }
356
- its(:noop) { will_not output("some output").to_stdout }
357
- end
328
+ its(:increment) do
329
+ expect { will_not change { subject.count }.by_at_least(2) }.to \
330
+ raise_error(NotImplementedError, '`expect { }.not_to change { }.by_at_least()` is not supported')
331
+ end
358
332
 
359
- context "#will with non block expectations" do
360
- subject do
361
- Class.new do
362
- def terminator
363
- "back"
364
- end
365
- end.new
333
+ its(:increment) do
334
+ expect { will_not change { subject.count }.by_at_most(3) }.to \
335
+ raise_error(NotImplementedError, '`expect { }.not_to change { }.by_at_most()` is not supported')
336
+ end
337
+ end
338
+
339
+ context "with output capture" do
340
+ subject do
341
+ Class.new do
342
+ def stdout
343
+ print "some output"
366
344
  end
367
345
 
368
- its(:terminator) do
369
- expect { will be("back") }.to \
370
- raise_error(ArgumentError, '`will` only supports block expectations')
346
+ def stderr
347
+ $stderr.print "some error"
371
348
  end
372
349
 
373
- its(:terminator) do
374
- expect { will_not be("back") }.to \
375
- raise_error(ArgumentError, '`will_not` only supports block expectations')
350
+ def noop; end
351
+ end.new
352
+ end
353
+
354
+ its(:stdout) { will output("some output").to_stdout }
355
+ its(:stderr) { will output("some error").to_stderr }
356
+
357
+ its(:noop) { will_not output("some error").to_stderr }
358
+ its(:noop) { will_not output("some output").to_stdout }
359
+ end
360
+
361
+ context "#will with non block expectations" do
362
+ subject do
363
+ Class.new do
364
+ def terminator
365
+ "back"
376
366
  end
377
- end
367
+ end.new
368
+ end
369
+
370
+ its(:terminator) do
371
+ expect { will be("back") }.to \
372
+ raise_error(ArgumentError, '`will` only supports block expectations')
373
+ end
374
+
375
+ its(:terminator) do
376
+ expect { will_not be("back") }.to \
377
+ raise_error(ArgumentError, '`will_not` only supports block expectations')
378
+ end
379
+ end
380
+
381
+ context "when example is redefined" do
382
+ subject do
383
+ Class.new do
384
+ def will_still_work
385
+ true
386
+ end
387
+ end.new
388
+ end
389
+
390
+ def self.example(*_args)
391
+ raise
392
+ end
393
+
394
+ its(:will_still_work) { is_expected.to be true }
395
+ end
378
396
 
379
- context "when example is redefined" do
380
- subject do
381
- Class.new do
382
- def will_still_work; true; end
383
- end.new
397
+ context "with private method" do
398
+ subject(:klass) do
399
+ Class.new do
400
+ def name
401
+ private_name
384
402
  end
385
403
 
386
- def self.example(*_args)
387
- raise
404
+ private
405
+
406
+ def private_name
407
+ "John"
388
408
  end
409
+ end.new
410
+ end
411
+
412
+ context "when referring indirectly" do
413
+ its(:name) { is_expected.to eq "John" }
414
+ end
389
415
 
390
- its(:will_still_work) { is_expected.to be true }
416
+ context "when attempting to refer directly" do
417
+ context "it raises an error" do
418
+ its(:private_name) do
419
+ expect { is_expected.to eq("John") }.to raise_error(NoMethodError)
420
+ end
391
421
  end
392
422
  end
393
423
  end