cucumber-core 3.0.0 → 3.1.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/cucumber/core/version.rb +1 -1
  3. metadata +19 -85
  4. data/.coveralls.yml +0 -1
  5. data/.github/ISSUE_TEMPLATE.md +0 -48
  6. data/.github/PULL_REQUEST_TEMPLATE.md +0 -39
  7. data/.rspec +0 -1
  8. data/.ruby-gemset +0 -1
  9. data/.travis.yml +0 -30
  10. data/.yardopts +0 -6
  11. data/Gemfile +0 -2
  12. data/Rakefile +0 -28
  13. data/cucumber-core.gemspec +0 -36
  14. data/spec/capture_warnings.rb +0 -74
  15. data/spec/coverage.rb +0 -11
  16. data/spec/cucumber/core/ast/background_spec.rb +0 -11
  17. data/spec/cucumber/core/ast/data_table_spec.rb +0 -81
  18. data/spec/cucumber/core/ast/doc_string_spec.rb +0 -114
  19. data/spec/cucumber/core/ast/empty_multiline_argument_spec.rb +0 -28
  20. data/spec/cucumber/core/ast/examples_table_spec.rb +0 -113
  21. data/spec/cucumber/core/ast/location_spec.rb +0 -199
  22. data/spec/cucumber/core/ast/outline_step_spec.rb +0 -93
  23. data/spec/cucumber/core/ast/step_spec.rb +0 -174
  24. data/spec/cucumber/core/compiler_spec.rb +0 -267
  25. data/spec/cucumber/core/event_bus_spec.rb +0 -163
  26. data/spec/cucumber/core/event_spec.rb +0 -40
  27. data/spec/cucumber/core/filter_spec.rb +0 -101
  28. data/spec/cucumber/core/gherkin/parser_spec.rb +0 -261
  29. data/spec/cucumber/core/gherkin/writer_spec.rb +0 -333
  30. data/spec/cucumber/core/report/summary_spec.rb +0 -175
  31. data/spec/cucumber/core/test/action_spec.rb +0 -154
  32. data/spec/cucumber/core/test/case_spec.rb +0 -316
  33. data/spec/cucumber/core/test/duration_matcher.rb +0 -20
  34. data/spec/cucumber/core/test/filters/locations_filter_spec.rb +0 -405
  35. data/spec/cucumber/core/test/result_spec.rb +0 -474
  36. data/spec/cucumber/core/test/runner_spec.rb +0 -310
  37. data/spec/cucumber/core/test/step_spec.rb +0 -98
  38. data/spec/cucumber/core/test/timer_spec.rb +0 -25
  39. data/spec/cucumber/core_spec.rb +0 -262
  40. data/spec/readme_spec.rb +0 -37
  41. data/spec/report_api_spy.rb +0 -25
@@ -1,20 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- # frozen_string_literal: true
3
- require 'cucumber/core/test/result'
4
- require 'rspec/expectations'
5
-
6
- module Cucumber::Core::Test
7
- RSpec::Matchers.define :be_duration do |expected|
8
- match do |actual|
9
- actual.tap { |duration| @nanoseconds = duration.nanoseconds }
10
- @nanoseconds == expected
11
- end
12
- end
13
-
14
- RSpec::Matchers.define :an_unknown_duration do
15
- match do |actual|
16
- actual.tap { raise "#tap block was executed, not an UnknownDuration" }
17
- expect(actual).to respond_to(:nanoseconds)
18
- end
19
- end
20
- end
@@ -1,405 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
- require 'cucumber/core/gherkin/writer'
4
- require 'cucumber/core'
5
- require 'cucumber/core/test/filters/locations_filter'
6
- require 'timeout'
7
- require 'cucumber/core/ast/location'
8
-
9
- module Cucumber::Core
10
- describe Test::LocationsFilter do
11
- include Cucumber::Core::Gherkin::Writer
12
- include Cucumber::Core
13
-
14
- let(:receiver) { SpyReceiver.new }
15
-
16
- let(:doc) do
17
- gherkin('features/test.feature') do
18
- feature do
19
- scenario 'x' do
20
- step 'a step'
21
- end
22
-
23
- scenario 'y' do
24
- step 'a step'
25
- end
26
- end
27
- end
28
- end
29
-
30
- it "sorts by the given locations" do
31
- locations = [
32
- Ast::Location.new('features/test.feature', 6),
33
- Ast::Location.new('features/test.feature', 3)
34
- ]
35
- filter = Test::LocationsFilter.new(locations)
36
- compile [doc], receiver, [filter]
37
- expect(receiver.test_case_locations).to eq locations
38
- end
39
-
40
- it "works with wildcard locations" do
41
- locations = [
42
- Ast::Location.new('features/test.feature')
43
- ]
44
- filter = Test::LocationsFilter.new(locations)
45
- compile [doc], receiver, [filter]
46
- expect(receiver.test_case_locations).to eq [
47
- Ast::Location.new('features/test.feature', 3),
48
- Ast::Location.new('features/test.feature', 6)
49
- ]
50
- end
51
-
52
- it "filters out scenarios that don't match" do
53
- locations = [
54
- Ast::Location.new('features/test.feature', 3)
55
- ]
56
- filter = Test::LocationsFilter.new(locations)
57
- compile [doc], receiver, [filter]
58
- expect(receiver.test_case_locations).to eq locations
59
- end
60
-
61
- describe "matching location" do
62
- let(:file) { 'features/path/to/the.feature' }
63
-
64
- let(:test_cases) do
65
- receiver = double.as_null_object
66
- result = []
67
- allow(receiver).to receive(:test_case) { |test_case| result << test_case }
68
- compile [doc], receiver
69
- result
70
- end
71
-
72
- context "for a scenario" do
73
- let(:doc) do
74
- Gherkin::Document.new(file, <<-END)
75
- Feature:
76
-
77
- Scenario: one
78
- Given one a
79
-
80
- # comment
81
- @tags
82
- Scenario: two
83
- Given two a
84
- And two b
85
-
86
- Scenario: three
87
- Given three b
88
-
89
- Scenario: with docstring
90
- Given a docstring
91
- """
92
- this is a docstring
93
- """
94
-
95
- Scenario: with a table
96
- Given a table
97
- | a | b |
98
- | 1 | 2 |
99
- | 3 | 4 |
100
-
101
- END
102
- end
103
-
104
- def test_case_named(name)
105
- test_cases.find { |c| c.name == name }
106
- end
107
-
108
- it 'matches the precise location of the scenario' do
109
- location = test_case_named('two').location
110
- filter = Test::LocationsFilter.new([location])
111
- compile [doc], receiver, [filter]
112
- expect(receiver.test_case_locations).to eq [test_case_named('two').location]
113
- end
114
-
115
- it 'matches multiple locations' do
116
- good_location = Ast::Location.new(file, 8)
117
- bad_location = Ast::Location.new(file, 5)
118
- filter = Test::LocationsFilter.new([good_location, bad_location])
119
- compile [doc], receiver, [filter]
120
- expect(receiver.test_case_locations).to eq [test_case_named('two').location]
121
- end
122
-
123
- it 'matches a location on the last step of the scenario' do
124
- location = Ast::Location.new(file, 10)
125
- filter = Test::LocationsFilter.new([location])
126
- compile [doc], receiver, [filter]
127
- expect(receiver.test_case_locations).to eq [test_case_named('two').location]
128
- end
129
-
130
- it "matches a location on the scenario's comment" do
131
- location = Ast::Location.new(file, 6)
132
- filter = Test::LocationsFilter.new([location])
133
- compile [doc], receiver, [filter]
134
- expect(receiver.test_case_locations).to eq [test_case_named('two').location]
135
- end
136
-
137
- it "matches a location on the scenario's tags" do
138
- location = Ast::Location.new(file, 7)
139
- filter = Test::LocationsFilter.new([location])
140
- compile [doc], receiver, [filter]
141
- expect(receiver.test_case_locations).to eq [test_case_named('two').location]
142
- end
143
-
144
- it "doesn't match a location after the last step of the scenario" do
145
- location = Ast::Location.new(file, 11)
146
- filter = Test::LocationsFilter.new([location])
147
- compile [doc], receiver, [filter]
148
- expect(receiver.test_case_locations).to eq []
149
- end
150
-
151
- it "doesn't match a location before the scenario" do
152
- location = Ast::Location.new(file, 5)
153
- filter = Test::LocationsFilter.new([location])
154
- compile [doc], receiver, [filter]
155
- expect(receiver.test_case_locations).to eq []
156
- end
157
-
158
- context "with a docstring" do
159
- let(:test_case) do
160
- test_cases.find { |c| c.name == 'with docstring' }
161
- end
162
-
163
- it "matches a location at the start the docstring" do
164
- location = Ast::Location.new(file, 17)
165
- filter = Test::LocationsFilter.new([location])
166
- compile [doc], receiver, [filter]
167
- expect(receiver.test_case_locations).to eq [test_case.location]
168
- end
169
-
170
- it "matches a location in the middle of the docstring" do
171
- location = Ast::Location.new(file, 18)
172
- filter = Test::LocationsFilter.new([location])
173
- compile [doc], receiver, [filter]
174
- expect(receiver.test_case_locations).to eq [test_case.location]
175
- end
176
-
177
- it "matches a location at the end of the docstring" do
178
- location = Ast::Location.new(file, 19)
179
- filter = Test::LocationsFilter.new([location])
180
- compile [doc], receiver, [filter]
181
- expect(receiver.test_case_locations).to eq [test_case.location]
182
- end
183
-
184
- it "does not match a location after the docstring" do
185
- location = Ast::Location.new(file, 20)
186
- filter = Test::LocationsFilter.new([location])
187
- compile [doc], receiver, [filter]
188
- expect(receiver.test_case_locations).to eq []
189
- end
190
- end
191
-
192
- context "with a table" do
193
- let(:test_case) do
194
- test_cases.find { |c| c.name == 'with a table' }
195
- end
196
-
197
- it "matches a location at the start of the table" do
198
- location = Ast::Location.new(file, 23)
199
- expect( test_case.match_locations?([location]) ).to be_truthy
200
- end
201
-
202
- it "matches a location in the middle of the table" do
203
- location = Ast::Location.new(file, 24)
204
- expect( test_case.match_locations?([location]) ).to be_truthy
205
- end
206
-
207
- it "matches a location at the end of the table" do
208
- location = Ast::Location.new(file, 25)
209
- expect( test_case.match_locations?([location]) ).to be_truthy
210
- end
211
-
212
- it "does not match a location after the table" do
213
- location = Ast::Location.new(file, 26)
214
- expect( test_case.match_locations?([location]) ).to be_falsey
215
- end
216
- end
217
-
218
- context "with duplicate locations in the filter" do
219
- it "matches each test case only once" do
220
- location_tc_two = test_case_named('two').location
221
- location_tc_one = test_case_named('one').location
222
- location_last_step_tc_two = Ast::Location.new(file, 10)
223
- filter = Test::LocationsFilter.new([location_tc_two, location_tc_one, location_last_step_tc_two])
224
- compile [doc], receiver, [filter]
225
- expect(receiver.test_case_locations).to eq [test_case_named('two').location, location_tc_one = test_case_named('one').location]
226
- end
227
- end
228
- end
229
-
230
- context "for a scenario outline" do
231
- let(:doc) do
232
- Gherkin::Document.new(file, <<-END)
233
- Feature:
234
-
235
- Scenario: one
236
- Given one a
237
-
238
- # comment on line 6
239
- @tags-on-line-7
240
- Scenario Outline: two
241
- Given two a
242
- And two <arg>
243
- """
244
- docstring
245
- """
246
-
247
- # comment on line 15
248
- @tags-on-line-16
249
- Examples: x1
250
- | arg |
251
- | b |
252
-
253
- Examples: x2
254
- | arg |
255
- | c |
256
- | d |
257
-
258
- Scenario: three
259
- Given three b
260
- END
261
- end
262
-
263
- let(:test_case) do
264
- test_cases.find { |c| c.name == "two, x1 (#1)" }
265
- end
266
-
267
- it "matches row location to the test case of the row" do
268
- locations = [
269
- Ast::Location.new(file, 19),
270
- ]
271
- filter = Test::LocationsFilter.new(locations)
272
- compile [doc], receiver, [filter]
273
- expect(receiver.test_case_locations).to eq [test_case.location]
274
- end
275
-
276
- it "matches examples location with all test cases of the table" do
277
- locations = [
278
- Ast::Location.new(file, 21),
279
- ]
280
- filter = Test::LocationsFilter.new(locations)
281
- compile [doc], receiver, [filter]
282
- expect(receiver.test_case_locations.map(&:line)).to eq [23, 24]
283
- end
284
-
285
- it "matches outline location with the all test cases of all the tables" do
286
- locations = [
287
- Ast::Location.new(file, 8),
288
- ]
289
- filter = Test::LocationsFilter.new(locations)
290
- compile [doc], receiver, [filter]
291
- expect(receiver.test_case_locations.map(&:line)).to eq [19, 23, 24]
292
- end
293
-
294
- it "matches outline step location the all test cases of all the tables" do
295
- locations = [
296
- Ast::Location.new(file, 10)
297
- ]
298
- filter = Test::LocationsFilter.new(locations)
299
- compile [doc], receiver, [filter]
300
- expect(receiver.test_case_locations.map(&:line)).to eq [19, 23, 24]
301
- end
302
-
303
- it 'matches a location on a step of the scenario outline' do
304
- location = Ast::Location.new(file, 10)
305
- filter = Test::LocationsFilter.new([location])
306
- compile [doc], receiver, [filter]
307
- expect(receiver.test_case_locations).to include test_case.location
308
- end
309
-
310
- it 'matches a location on the docstring of a step of the scenario outline' do
311
- location = Ast::Location.new(file, 12)
312
- filter = Test::LocationsFilter.new([location])
313
- compile [doc], receiver, [filter]
314
- expect(receiver.test_case_locations).to include test_case.location
315
- end
316
-
317
- it "matches a location on the scenario outline's comment" do
318
- location = Ast::Location.new(file, 6)
319
- filter = Test::LocationsFilter.new([location])
320
- compile [doc], receiver, [filter]
321
- expect(receiver.test_case_locations).to include test_case.location
322
- end
323
-
324
- it "matches a location on the scenario outline's tags" do
325
- location = Ast::Location.new(file, 7)
326
- filter = Test::LocationsFilter.new([location])
327
- compile [doc], receiver, [filter]
328
- expect(receiver.test_case_locations).to include test_case.location
329
- end
330
-
331
- it "doesn't match a location after the last row of the examples table" do
332
- location = Ast::Location.new(file, 20)
333
- filter = Test::LocationsFilter.new([location])
334
- compile [doc], receiver, [filter]
335
- expect(receiver.test_case_locations).to eq []
336
- end
337
-
338
- it "doesn't match a location before the scenario outline" do
339
- location = Ast::Location.new(file, 5)
340
- filter = Test::LocationsFilter.new([location])
341
- compile [doc], receiver, [filter]
342
- expect(receiver.test_case_locations).to eq []
343
- end
344
- end
345
- end
346
-
347
- context "under load", slow: true do
348
- num_features = 50
349
- num_scenarios_per_feature = 50
350
-
351
- let(:docs) do
352
- (1..num_features).map do |i|
353
- gherkin("features/test_#{i}.feature") do
354
- feature do
355
- (1..num_scenarios_per_feature).each do |j|
356
- scenario "scenario #{j}" do
357
- step
358
- end
359
- end
360
- end
361
- end
362
- end
363
- end
364
-
365
- num_locations = num_features
366
- let(:locations) do
367
- (1..num_locations).map do |i|
368
- (1..num_scenarios_per_feature).map do |j|
369
- line = 3 + (j - 1) * 3
370
- Ast::Location.new("features/test_#{i}.feature", line)
371
- end
372
- end.flatten
373
- end
374
-
375
- max_duration_ms = 10000
376
- max_duration_ms = max_duration_ms * 2.5 if defined?(JRUBY_VERSION)
377
- it "filters #{num_features * num_scenarios_per_feature} test cases within #{max_duration_ms}ms" do
378
- filter = Test::LocationsFilter.new(locations)
379
- Timeout.timeout(max_duration_ms / 1000.0) do
380
- compile docs, receiver, [filter]
381
- end
382
- expect(receiver.test_cases.length).to eq num_features * num_scenarios_per_feature
383
- end
384
-
385
- end
386
- end
387
-
388
- class SpyReceiver
389
- def test_case(test_case)
390
- test_cases << test_case
391
- end
392
-
393
- def done
394
- end
395
-
396
- def test_case_locations
397
- test_cases.map(&:location)
398
- end
399
-
400
- def test_cases
401
- @test_cases ||= []
402
- end
403
-
404
- end
405
- end
@@ -1,474 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- # frozen_string_literal: true
3
- require 'cucumber/core/test/result'
4
- require 'cucumber/core/test/duration_matcher'
5
-
6
- module Cucumber::Core::Test
7
- describe Result do
8
-
9
- let(:visitor) { double('visitor') }
10
- let(:args) { double('args') }
11
-
12
- describe Result::Passed do
13
- subject(:result) { Result::Passed.new(duration) }
14
- let(:duration) { Result::Duration.new(1 * 1000 * 1000) }
15
-
16
- it "describes itself to a visitor" do
17
- expect( visitor ).to receive(:passed).with(args)
18
- expect( visitor ).to receive(:duration).with(duration, args)
19
- result.describe_to(visitor, args)
20
- end
21
-
22
- it "converts to a string" do
23
- expect( result.to_s ).to eq "✓"
24
- end
25
-
26
- it "has a duration" do
27
- expect( result.duration ).to eq duration
28
- end
29
-
30
- it "requires the constructor argument" do
31
- expect { Result::Passed.new }.to raise_error(ArgumentError)
32
- end
33
-
34
- it "does nothing when appending the backtrace" do
35
- expect( result.with_appended_backtrace(double) ).to equal result
36
- end
37
-
38
- it "does nothing when filtering the backtrace" do
39
- expect( result.with_filtered_backtrace(double) ).to equal result
40
- end
41
-
42
- specify { expect( result.to_sym ).to eq :passed }
43
-
44
- specify { expect( result ).to be_passed }
45
- specify { expect( result ).not_to be_failed }
46
- specify { expect( result ).not_to be_undefined }
47
- specify { expect( result ).not_to be_unknown }
48
- specify { expect( result ).not_to be_skipped }
49
- specify { expect( result ).not_to be_flaky }
50
-
51
- specify { expect( result ).to be_ok }
52
- specify { expect( result.ok? ).to be_truthy }
53
- end
54
-
55
- describe Result::Failed do
56
- subject(:result) { Result::Failed.new(duration, exception) }
57
- let(:duration) { Result::Duration.new(1 * 1000 * 1000) }
58
- let(:exception) { StandardError.new("error message") }
59
-
60
- it "describes itself to a visitor" do
61
- expect( visitor ).to receive(:failed).with(args)
62
- expect( visitor ).to receive(:duration).with(duration, args)
63
- expect( visitor ).to receive(:exception).with(exception, args)
64
- result.describe_to(visitor, args)
65
- end
66
-
67
- it "has a duration" do
68
- expect( result.duration ).to eq duration
69
- end
70
-
71
- it "requires both constructor arguments" do
72
- expect { Result::Failed.new }.to raise_error(ArgumentError)
73
- expect { Result::Failed.new(duration) }.to raise_error(ArgumentError)
74
- end
75
-
76
- it "does nothing if step has no backtrace line" do
77
- result.exception.set_backtrace("exception backtrace")
78
- step = "does not respond_to?(:backtrace_line)"
79
-
80
- expect( result.with_appended_backtrace(step).exception.backtrace ).to eq(["exception backtrace"])
81
- end
82
-
83
- it "appends the backtrace line of the step" do
84
- result.exception.set_backtrace("exception backtrace")
85
- step = double
86
- expect( step ).to receive(:backtrace_line).and_return("step_line")
87
-
88
- expect( result.with_appended_backtrace(step).exception.backtrace ).to eq(["exception backtrace", "step_line"])
89
- end
90
-
91
- it "apply filters to the exception" do
92
- filter_class = double
93
- filter = double
94
- filtered_exception = double
95
- expect( filter_class ).to receive(:new).with(result.exception).and_return(filter)
96
- expect( filter ).to receive(:exception).and_return(filtered_exception)
97
-
98
- expect( result.with_filtered_backtrace(filter_class).exception ).to equal filtered_exception
99
- end
100
-
101
- specify { expect( result.to_sym ).to eq :failed }
102
-
103
- specify { expect( result ).not_to be_passed }
104
- specify { expect( result ).to be_failed }
105
- specify { expect( result ).not_to be_undefined }
106
- specify { expect( result ).not_to be_unknown }
107
- specify { expect( result ).not_to be_skipped }
108
- specify { expect( result ).not_to be_flaky }
109
-
110
- specify { expect( result ).to_not be_ok }
111
- specify { expect( result.ok? ).to be_falsey }
112
- end
113
-
114
- describe Result::Unknown do
115
- subject(:result) { Result::Unknown.new }
116
-
117
- it "doesn't describe itself to a visitor" do
118
- visitor = double('never receives anything')
119
- result.describe_to(visitor, args)
120
- end
121
-
122
- it "defines a with_filtered_backtrace method" do
123
- expect(result.with_filtered_backtrace(double("filter"))).to eql result
124
- end
125
-
126
- specify { expect( result.to_sym ).to eq :unknown }
127
-
128
- specify { expect( result ).not_to be_passed }
129
- specify { expect( result ).not_to be_failed }
130
- specify { expect( result ).not_to be_undefined }
131
- specify { expect( result ).to be_unknown }
132
- specify { expect( result ).not_to be_skipped }
133
- specify { expect( result ).not_to be_flaky }
134
- end
135
-
136
- describe Result::Raisable do
137
- context "with or without backtrace" do
138
- subject(:result) { Result::Raisable.new }
139
-
140
- it "does nothing if step has no backtrace line" do
141
- step = "does not respond_to?(:backtrace_line)"
142
-
143
- expect( result.with_appended_backtrace(step).backtrace ).to eq(nil)
144
- end
145
- end
146
-
147
- context "without backtrace" do
148
- subject(:result) { Result::Raisable.new }
149
-
150
- it "set the backtrace to the backtrace line of the step" do
151
- step = double
152
- expect( step ).to receive(:backtrace_line).and_return("step_line")
153
-
154
- expect( result.with_appended_backtrace(step).backtrace ).to eq(["step_line"])
155
- end
156
-
157
- it "does nothing when filtering the backtrace" do
158
- expect( result.with_filtered_backtrace(double) ).to equal result
159
- end
160
- end
161
-
162
- context "with backtrace" do
163
- subject(:result) { Result::Raisable.new("message", 0, "backtrace") }
164
-
165
- it "appends the backtrace line of the step" do
166
- step = double
167
- expect( step ).to receive(:backtrace_line).and_return("step_line")
168
-
169
- expect( result.with_appended_backtrace(step).backtrace ).to eq(["backtrace", "step_line"])
170
- end
171
-
172
- it "apply filters to the backtrace" do
173
- filter_class = double
174
- filter = double
175
- filtered_result = double
176
- expect( filter_class ).to receive(:new).with(result.exception).and_return(filter)
177
- expect( filter ).to receive(:exception).and_return(filtered_result)
178
-
179
- expect( result.with_filtered_backtrace(filter_class) ).to equal filtered_result
180
- end
181
- end
182
- end
183
-
184
- describe Result::Undefined do
185
- subject(:result) { Result::Undefined.new }
186
-
187
- it "describes itself to a visitor" do
188
- expect( visitor ).to receive(:undefined).with(args)
189
- expect( visitor ).to receive(:duration).with(an_unknown_duration, args)
190
- result.describe_to(visitor, args)
191
- end
192
-
193
- specify { expect( result.to_sym ).to eq :undefined }
194
-
195
- specify { expect( result ).not_to be_passed }
196
- specify { expect( result ).not_to be_failed }
197
- specify { expect( result ).to be_undefined }
198
- specify { expect( result ).not_to be_unknown }
199
- specify { expect( result ).not_to be_skipped }
200
- specify { expect( result ).not_to be_flaky }
201
-
202
- specify { expect( result ).to be_ok }
203
- specify { expect( result.ok? ).to be_truthy }
204
- be_strict = Result::StrictConfiguration.new([:undefined])
205
- specify { expect( result.ok?(be_strict) ).to be_falsey }
206
- end
207
-
208
- describe Result::Skipped do
209
- subject(:result) { Result::Skipped.new }
210
-
211
- it "describes itself to a visitor" do
212
- expect( visitor ).to receive(:skipped).with(args)
213
- expect( visitor ).to receive(:duration).with(an_unknown_duration, args)
214
- result.describe_to(visitor, args)
215
- end
216
-
217
- specify { expect( result.to_sym ).to eq :skipped }
218
-
219
- specify { expect( result ).not_to be_passed }
220
- specify { expect( result ).not_to be_failed }
221
- specify { expect( result ).not_to be_undefined }
222
- specify { expect( result ).not_to be_unknown }
223
- specify { expect( result ).to be_skipped }
224
- specify { expect( result ).not_to be_flaky }
225
-
226
- specify { expect( result ).to be_ok }
227
- specify { expect( result.ok? ).to be_truthy }
228
- end
229
-
230
- describe Result::Pending do
231
- subject(:result) { Result::Pending.new }
232
-
233
- it "describes itself to a visitor" do
234
- expect( visitor ).to receive(:pending).with(result, args)
235
- expect( visitor ).to receive(:duration).with(an_unknown_duration, args)
236
- result.describe_to(visitor, args)
237
- end
238
-
239
- specify { expect( result.to_sym ).to eq :pending }
240
-
241
- specify { expect( result ).not_to be_passed }
242
- specify { expect( result ).not_to be_failed }
243
- specify { expect( result ).not_to be_undefined }
244
- specify { expect( result ).not_to be_unknown }
245
- specify { expect( result ).not_to be_skipped }
246
- specify { expect( result ).not_to be_flaky }
247
- specify { expect( result ).to be_pending }
248
-
249
- specify { expect( result ).to be_ok }
250
- specify { expect( result.ok? ).to be_truthy }
251
- be_strict = Result::StrictConfiguration.new([:pending])
252
- specify { expect( result.ok?(be_strict) ).to be_falsey }
253
- end
254
-
255
- describe Result::Flaky do
256
- specify { expect( Result::Flaky.ok?(false) ).to be_truthy }
257
- specify { expect( Result::Flaky.ok?(true) ).to be_falsey }
258
- end
259
-
260
- describe Result::StrictConfiguration do
261
- subject(:strict_configuration) { Result::StrictConfiguration.new}
262
-
263
- describe '#set_strict' do
264
- context 'no type argument' do
265
- it 'sets all result types to the setting argument' do
266
- strict_configuration.set_strict(true)
267
- expect( strict_configuration.strict?(:undefined) ).to be_truthy
268
- expect( strict_configuration.strict?(:pending) ).to be_truthy
269
- expect( strict_configuration.strict?(:flaky) ).to be_truthy
270
-
271
- strict_configuration.set_strict(false)
272
- expect( strict_configuration.strict?(:undefined) ).to be_falsey
273
- expect( strict_configuration.strict?(:pending) ).to be_falsey
274
- expect( strict_configuration.strict?(:flaky) ).to be_falsey
275
- end
276
- end
277
- context 'with type argument' do
278
- it 'sets the specified result type to the setting argument' do
279
- strict_configuration.set_strict(true, :undefined)
280
- expect( strict_configuration.strict?(:undefined) ).to be_truthy
281
- expect( strict_configuration.set?(:pending) ).to be_falsey
282
- expect( strict_configuration.set?(:flaky) ).to be_falsey
283
-
284
- strict_configuration.set_strict(false, :undefined)
285
- expect( strict_configuration.strict?(:undefined) ).to be_falsey
286
- expect( strict_configuration.set?(:pending) ).to be_falsey
287
- expect( strict_configuration.set?(:flaky) ).to be_falsey
288
- end
289
- end
290
- end
291
-
292
- describe '#strict?' do
293
- context 'no type argument' do
294
- it 'returns true if any result type is set to strict' do
295
- strict_configuration.set_strict(false, :pending)
296
- expect( strict_configuration.strict? ).to be_falsey
297
-
298
- strict_configuration.set_strict(true, :flaky)
299
- expect( strict_configuration.strict? ).to be_truthy
300
- end
301
- end
302
- context 'with type argument' do
303
- it 'returns true if the specified result type is set to strict' do
304
- strict_configuration.set_strict(false, :pending)
305
- strict_configuration.set_strict(true, :flaky)
306
-
307
- expect( strict_configuration.strict?(:undefined) ).to be_falsey
308
- expect( strict_configuration.strict?(:pending) ).to be_falsey
309
- expect( strict_configuration.strict?(:flaky) ).to be_truthy
310
- end
311
- end
312
- end
313
-
314
- describe '#merge!' do
315
- let(:merged_configuration) { Result::StrictConfiguration.new }
316
- it 'sets the not default values from the argument accordingly' do
317
- strict_configuration.set_strict(false, :undefined)
318
- strict_configuration.set_strict(false, :pending)
319
- strict_configuration.set_strict(true, :flaky)
320
- merged_configuration.set_strict(true, :pending)
321
- merged_configuration.set_strict(false, :flaky)
322
- strict_configuration.merge!(merged_configuration)
323
-
324
- expect( strict_configuration.strict?(:undefined) ).to be_falsey
325
- expect( strict_configuration.strict?(:pending) ).to be_truthy
326
- expect( strict_configuration.strict?(:flaky) ).to be_falsey
327
- end
328
- end
329
- end
330
-
331
- describe Result::Summary do
332
- let(:summary) { Result::Summary.new }
333
- let(:failed) { Result::Failed.new(Result::Duration.new(10), exception) }
334
- let(:passed) { Result::Passed.new(Result::Duration.new(11)) }
335
- let(:skipped) { Result::Skipped.new }
336
- let(:unknown) { Result::Unknown.new }
337
- let(:pending) { Result::Pending.new }
338
- let(:undefined) { Result::Undefined.new }
339
- let(:exception) { StandardError.new }
340
-
341
- it "counts failed results" do
342
- failed.describe_to summary
343
- expect( summary.total_failed ).to eq 1
344
- expect( summary.total(:failed) ).to eq 1
345
- expect( summary.total ).to eq 1
346
- end
347
-
348
- it "counts passed results" do
349
- passed.describe_to summary
350
- expect( summary.total_passed ).to eq 1
351
- expect( summary.total(:passed) ).to eq 1
352
- expect( summary.total ).to eq 1
353
- end
354
-
355
- it "counts skipped results" do
356
- skipped.describe_to summary
357
- expect( summary.total_skipped ).to eq 1
358
- expect( summary.total(:skipped) ).to eq 1
359
- expect( summary.total ).to eq 1
360
- end
361
-
362
- it "counts undefined results" do
363
- undefined.describe_to summary
364
- expect( summary.total_undefined ).to eq 1
365
- expect( summary.total(:undefined) ).to eq 1
366
- expect( summary.total ).to eq 1
367
- end
368
-
369
- it "counts abitrary raisable results" do
370
- flickering = Class.new(Result::Raisable) do
371
- def describe_to(visitor, *args)
372
- visitor.flickering(*args)
373
- end
374
- end
375
-
376
- flickering.new.describe_to summary
377
- expect( summary.total_flickering ).to eq 1
378
- expect( summary.total(:flickering) ).to eq 1
379
- expect( summary.total ).to eq 1
380
- end
381
-
382
- it "returns zero for a status where no messges have been received" do
383
- expect( summary.total_passed ).to eq 0
384
- expect( summary.total(:passed) ).to eq 0
385
- expect( summary.total_ponies ).to eq 0
386
- expect( summary.total(:ponies) ).to eq 0
387
- end
388
-
389
- it "doesn't count unknown results" do
390
- unknown.describe_to summary
391
- expect( summary.total ).to eq 0
392
- end
393
-
394
- it "counts combinations" do
395
- [passed, passed, failed, skipped, undefined].each { |r| r.describe_to summary }
396
- expect( summary.total ).to eq 5
397
- expect( summary.total_passed ).to eq 2
398
- expect( summary.total_failed ).to eq 1
399
- expect( summary.total_skipped ).to eq 1
400
- expect( summary.total_undefined ).to eq 1
401
- end
402
-
403
- it "records durations" do
404
- [passed, failed].each { |r| r.describe_to summary }
405
- expect( summary.durations[0] ).to be_duration 11
406
- expect( summary.durations[1] ).to be_duration 10
407
- end
408
-
409
- it "records exceptions" do
410
- [passed, failed].each { |r| r.describe_to summary }
411
- expect( summary.exceptions ).to eq [exception]
412
- end
413
-
414
- context "ok? result" do
415
- it "passed result is ok" do
416
- passed.describe_to summary
417
- expect( summary.ok? ).to be true
418
- end
419
-
420
- it "skipped result is ok" do
421
- skipped.describe_to summary
422
- expect( summary.ok? ).to be true
423
- end
424
-
425
- it "failed result is not ok" do
426
- failed.describe_to summary
427
- expect( summary.ok? ).to be false
428
- end
429
-
430
- it "pending result is ok if not strict" do
431
- pending.describe_to summary
432
- expect( summary.ok? ).to be true
433
- be_strict = Result::StrictConfiguration.new([:pending])
434
- expect( summary.ok?(be_strict) ).to be false
435
- end
436
-
437
- it "undefined result is ok if not strict" do
438
- undefined.describe_to summary
439
- expect( summary.ok? ).to be true
440
- be_strict = Result::StrictConfiguration.new([:undefined])
441
- expect( summary.ok?(be_strict) ).to be false
442
- end
443
-
444
- it "flaky result is ok if not strict" do
445
- summary.flaky
446
- expect( summary.ok? ).to be true
447
- be_strict = Result::StrictConfiguration.new([:flaky])
448
- expect( summary.ok?(be_strict) ).to be false
449
- end
450
- end
451
- end
452
-
453
- describe Result::Duration do
454
- subject(:duration) { Result::Duration.new(10) }
455
-
456
- it "#nanoseconds can be accessed in #tap" do
457
- expect( duration.tap { |duration| @duration = duration.nanoseconds } ).to eq duration
458
- expect( @duration ).to eq 10
459
- end
460
- end
461
-
462
- describe Result::UnknownDuration do
463
- subject(:duration) { Result::UnknownDuration.new }
464
-
465
- it "#tap does not execute the passed block" do
466
- expect( duration.tap { raise "tap executed block" } ).to eq duration
467
- end
468
-
469
- it "accessing #nanoseconds outside #tap block raises exception" do
470
- expect { duration.nanoseconds }.to raise_error(RuntimeError)
471
- end
472
- end
473
- end
474
- end