rspec-core 3.7.0 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +80 -2
  5. data/README.md +16 -16
  6. data/lib/rspec/core.rb +1 -0
  7. data/lib/rspec/core/bisect/coordinator.rb +26 -30
  8. data/lib/rspec/core/bisect/example_minimizer.rb +12 -8
  9. data/lib/rspec/core/bisect/fork_runner.rb +134 -0
  10. data/lib/rspec/core/bisect/server.rb +5 -14
  11. data/lib/rspec/core/bisect/{runner.rb → shell_command.rb} +27 -70
  12. data/lib/rspec/core/bisect/shell_runner.rb +73 -0
  13. data/lib/rspec/core/bisect/utilities.rb +58 -0
  14. data/lib/rspec/core/configuration.rb +219 -62
  15. data/lib/rspec/core/configuration_options.rb +41 -4
  16. data/lib/rspec/core/did_you_mean.rb +46 -0
  17. data/lib/rspec/core/example.rb +8 -5
  18. data/lib/rspec/core/example_group.rb +8 -3
  19. data/lib/rspec/core/formatters.rb +13 -6
  20. data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
  21. data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
  22. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +29 -16
  23. data/lib/rspec/core/formatters/deprecation_formatter.rb +3 -1
  24. data/lib/rspec/core/formatters/documentation_formatter.rb +35 -3
  25. data/lib/rspec/core/formatters/exception_presenter.rb +13 -1
  26. data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
  27. data/lib/rspec/core/formatters/html_printer.rb +0 -2
  28. data/lib/rspec/core/formatters/protocol.rb +17 -17
  29. data/lib/rspec/core/formatters/syntax_highlighter.rb +19 -19
  30. data/lib/rspec/core/hooks.rb +15 -9
  31. data/lib/rspec/core/invocations.rb +8 -6
  32. data/lib/rspec/core/memoized_helpers.rb +33 -14
  33. data/lib/rspec/core/metadata.rb +2 -3
  34. data/lib/rspec/core/option_parser.rb +8 -0
  35. data/lib/rspec/core/profiler.rb +3 -1
  36. data/lib/rspec/core/rake_task.rb +21 -1
  37. data/lib/rspec/core/reporter.rb +11 -6
  38. data/lib/rspec/core/runner.rb +25 -14
  39. data/lib/rspec/core/shared_example_group.rb +2 -4
  40. data/lib/rspec/core/shell_escape.rb +2 -2
  41. data/lib/rspec/core/version.rb +1 -1
  42. data/lib/rspec/core/world.rb +11 -0
  43. metadata +22 -13
  44. metadata.gz.sig +0 -0
  45. data/lib/rspec/core/formatters/bisect_formatter.rb +0 -69
@@ -81,7 +81,7 @@ module RSpec
81
81
 
82
82
  def fully_formatted_lines(failure_number, colorizer)
83
83
  lines = [
84
- description,
84
+ encoded_description(description),
85
85
  detail_formatter.call(example, colorizer),
86
86
  formatted_message_and_backtrace(colorizer),
87
87
  extra_detail_formatter.call(failure_number, colorizer),
@@ -244,6 +244,17 @@ module RSpec
244
244
  end
245
245
  end
246
246
 
247
+ if String.method_defined?(:encoding)
248
+ def encoded_description(description)
249
+ return if description.nil?
250
+ encoded_string(description)
251
+ end
252
+ else # for 1.8.7
253
+ def encoded_description(description)
254
+ description
255
+ end
256
+ end
257
+
247
258
  def exception_backtrace
248
259
  exception.backtrace || []
249
260
  end
@@ -379,6 +390,7 @@ module RSpec
379
390
  parent_bt[index] != child_bt[index]
380
391
  end
381
392
 
393
+ return child if index_before_first_common_frame.nil?
382
394
  return child if index_before_first_common_frame == -1
383
395
 
384
396
  child = child.dup
@@ -0,0 +1,23 @@
1
+ RSpec::Support.require_rspec_core "formatters/base_formatter"
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+ # @private
7
+ class FailureListFormatter < BaseFormatter
8
+ Formatters.register self, :example_failed, :dump_profile, :message
9
+
10
+ def example_failed(failure)
11
+ output.puts "#{failure.example.location}:#{failure.example.description}"
12
+ end
13
+
14
+ # Discard profile and messages
15
+ #
16
+ # These outputs are not really relevant in the context of this failure
17
+ # list formatter.
18
+ def dump_profile(_profile); end
19
+ def message(_message); end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -115,7 +115,6 @@ module RSpec
115
115
  "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\""
116
116
  end
117
117
 
118
- # rubocop:disable LineLength
119
118
  REPORT_HEADER = <<-EOF
120
119
  <div class="rspec-report">
121
120
 
@@ -139,7 +138,6 @@ module RSpec
139
138
 
140
139
  <div class="results">
141
140
  EOF
142
- # rubocop:enable LineLength
143
141
 
144
142
  GLOBAL_SCRIPTS = <<-EOF
145
143
 
@@ -17,12 +17,12 @@ module RSpec
17
17
  # @see RSpec::Core::Formatters::BaseTextFormatter
18
18
  # @see RSpec::Core::Reporter
19
19
  class Protocol
20
- # @method initialize
20
+ # @method initialize(output)
21
21
  # @api public
22
22
  #
23
23
  # @param output [IO] the formatter output
24
24
 
25
- # @method start
25
+ # @method start(notification)
26
26
  # @api public
27
27
  # @group Suite Notifications
28
28
  #
@@ -35,7 +35,7 @@ module RSpec
35
35
  #
36
36
  # @param notification [Notifications::StartNotification]
37
37
 
38
- # @method example_group_started
38
+ # @method example_group_started(notification)
39
39
  # @api public
40
40
  # @group Group Notifications
41
41
  #
@@ -48,7 +48,7 @@ module RSpec
48
48
  # @param notification [Notifications::GroupNotification] containing example_group
49
49
  # subclass of {ExampleGroup}
50
50
 
51
- # @method example_group_finished
51
+ # @method example_group_finished(notification)
52
52
  # @api public
53
53
  # @group Group Notifications
54
54
  #
@@ -57,7 +57,7 @@ module RSpec
57
57
  # @param notification [Notifications::GroupNotification] containing example_group
58
58
  # subclass of {ExampleGroup}
59
59
 
60
- # @method example_started
60
+ # @method example_started(notification)
61
61
  # @api public
62
62
  # @group Example Notifications
63
63
  #
@@ -66,7 +66,7 @@ module RSpec
66
66
  # @param notification [Notifications::ExampleNotification] containing example subclass
67
67
  # of {Example}
68
68
 
69
- # @method example_finished
69
+ # @method example_finished(notification)
70
70
  # @api public
71
71
  # @group Example Notifications
72
72
  #
@@ -75,7 +75,7 @@ module RSpec
75
75
  # @param notification [Notifications::ExampleNotification] containing example subclass
76
76
  # of {Example}
77
77
 
78
- # @method example_passed
78
+ # @method example_passed(notification)
79
79
  # @api public
80
80
  # @group Example Notifications
81
81
  #
@@ -84,7 +84,7 @@ module RSpec
84
84
  # @param notification [Notifications::ExampleNotification] containing example subclass
85
85
  # of {Example}
86
86
 
87
- # @method example_pending
87
+ # @method example_pending(notification)
88
88
  # @api public
89
89
  # @group Example Notifications
90
90
  #
@@ -93,7 +93,7 @@ module RSpec
93
93
  # @param notification [Notifications::ExampleNotification] containing example subclass
94
94
  # of {Example}
95
95
 
96
- # @method example_failed
96
+ # @method example_failed(notification)
97
97
  # @api public
98
98
  # @group Example Notifications
99
99
  #
@@ -102,7 +102,7 @@ module RSpec
102
102
  # @param notification [Notifications::ExampleNotification] containing example subclass
103
103
  # of {Example}
104
104
 
105
- # @method message
105
+ # @method message(notification)
106
106
  # @api public
107
107
  # @group Suite Notifications
108
108
  #
@@ -110,7 +110,7 @@ module RSpec
110
110
  #
111
111
  # @param notification [Notifications::MessageNotification] containing message
112
112
 
113
- # @method stop
113
+ # @method stop(notification)
114
114
  # @api public
115
115
  # @group Suite Notifications
116
116
  #
@@ -119,7 +119,7 @@ module RSpec
119
119
  #
120
120
  # @param notification [Notifications::NullNotification]
121
121
 
122
- # @method start_dump
122
+ # @method start_dump(notification)
123
123
  # @api public
124
124
  # @group Suite Notifications
125
125
  #
@@ -130,7 +130,7 @@ module RSpec
130
130
  #
131
131
  # @param notification [Notifications::NullNotification]
132
132
 
133
- # @method dump_failures
133
+ # @method dump_failures(notification)
134
134
  # @api public
135
135
  # @group Suite Notifications
136
136
  #
@@ -138,7 +138,7 @@ module RSpec
138
138
  #
139
139
  # @param notification [Notifications::NullNotification]
140
140
 
141
- # @method dump_summary
141
+ # @method dump_summary(summary)
142
142
  # @api public
143
143
  # @group Suite Notifications
144
144
  #
@@ -148,7 +148,7 @@ module RSpec
148
148
  # @param summary [Notifications::SummaryNotification] containing duration,
149
149
  # example_count, failure_count and pending_count
150
150
 
151
- # @method dump_profile
151
+ # @method dump_profile(profile)
152
152
  # @api public
153
153
  # @group Suite Notifications
154
154
  #
@@ -158,7 +158,7 @@ module RSpec
158
158
  # @param profile [Notifications::ProfileNotification] containing duration,
159
159
  # slowest_examples and slowest_example_groups
160
160
 
161
- # @method dump_pending
161
+ # @method dump_pending(notification)
162
162
  # @api public
163
163
  # @group Suite Notifications
164
164
  #
@@ -167,7 +167,7 @@ module RSpec
167
167
  #
168
168
  # @param notification [Notifications::NullNotification]
169
169
 
170
- # @method close
170
+ # @method close(notification)
171
171
  # @api public
172
172
  # @group Suite Notifications
173
173
  #
@@ -13,6 +13,25 @@ module RSpec
13
13
  implementation.highlight_syntax(lines)
14
14
  end
15
15
 
16
+ # rubocop:disable Lint/RescueException
17
+ # rubocop:disable Lint/HandleExceptions
18
+ def self.attempt_to_add_rspec_terms_to_coderay_keywords
19
+ CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[
20
+ describe context
21
+ it specify
22
+ before after around
23
+ let subject
24
+ expect allow
25
+ ], :keyword)
26
+ rescue Exception
27
+ # Mutating CodeRay's contants like this is not a public API
28
+ # and might not always work. If we cannot add our keywords
29
+ # to CodeRay it is not a big deal and not worth raising an
30
+ # error over, so we ignore it.
31
+ end
32
+ # rubocop:enable Lint/HandleExceptions
33
+ # rubocop:enable Lint/RescueException
34
+
16
35
  private
17
36
 
18
37
  if RSpec::Support::OS.windows?
@@ -38,25 +57,6 @@ module RSpec
38
57
  end
39
58
  end
40
59
 
41
- # rubocop:disable Lint/RescueException
42
- # rubocop:disable Lint/HandleExceptions
43
- def self.attempt_to_add_rspec_terms_to_coderay_keywords
44
- CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[
45
- describe context
46
- it specify
47
- before after around
48
- let subject
49
- expect allow
50
- ], :keyword)
51
- rescue Exception
52
- # Mutating CodeRay's contants like this is not a public API
53
- # and might not always work. If we cannot add our keywords
54
- # to CodeRay it is not a big deal and not worth raising an
55
- # error over, so we ignore it.
56
- end
57
- # rubocop:enable Lint/HandleExceptions
58
- # rubocop:enable Lint/RescueException
59
-
60
60
  # @private
61
61
  module CodeRayImplementation
62
62
  RESET_CODE = "\e[0m"
@@ -60,7 +60,8 @@ module RSpec
60
60
  # before(:example) # Declared in the current group.
61
61
  #
62
62
  # If more than one `before` is declared within any one scope, they are run
63
- # in the order in which they are declared.
63
+ # in the order in which they are declared. Any `around` hooks will execute
64
+ # later than any `before` hook regardless of scope.
64
65
  #
65
66
  # ### Conditions
66
67
  #
@@ -74,11 +75,11 @@ module RSpec
74
75
  # end
75
76
  # end
76
77
  #
77
- # describe Something, :authorized => true do
78
+ # RSpec.describe Something, :authorized => true do
78
79
  # # The before hook will run in before each example in this group.
79
80
  # end
80
81
  #
81
- # describe SomethingElse do
82
+ # RSpec.describe SomethingElse do
82
83
  # it "does something", :authorized => true do
83
84
  # # The before hook will run before this example.
84
85
  # end
@@ -159,7 +160,7 @@ module RSpec
159
160
  #
160
161
  # @example before(:example) declared in an {ExampleGroup}
161
162
  #
162
- # describe Thing do
163
+ # RSpec.describe Thing do
163
164
  # before(:example) do
164
165
  # @thing = Thing.new
165
166
  # end
@@ -171,7 +172,7 @@ module RSpec
171
172
  #
172
173
  # @example before(:context) declared in an {ExampleGroup}
173
174
  #
174
- # describe Parser do
175
+ # RSpec.describe Parser do
175
176
  # before(:context) do
176
177
  # File.open(file_to_parse, 'w') do |f|
177
178
  # f.write <<-CONTENT
@@ -261,7 +262,8 @@ module RSpec
261
262
  #
262
263
  # This is the reverse of the order in which `before` hooks are run.
263
264
  # Similarly, if more than one `after` is declared within any one scope,
264
- # they are run in reverse order of that in which they are declared.
265
+ # they are run in reverse order of that in which they are declared. Also
266
+ # `around` hooks will all have run before any after hooks are invoked.
265
267
  #
266
268
  # @note The `:example` and `:context` scopes are also available as
267
269
  # `:each` and `:all`, respectively. Use whichever you prefer.
@@ -322,13 +324,19 @@ module RSpec
322
324
  # end
323
325
  #
324
326
  # The yielded example aliases `run` with `call`, which lets you treat it
325
- # like a `Proc`. This is especially handy when working with libaries
327
+ # like a `Proc`. This is especially handy when working with libraries
326
328
  # that manage their own setup and teardown using a block or proc syntax,
327
329
  # e.g.
328
330
  #
329
331
  # around(:example) {|ex| Database.transaction(&ex)}
330
332
  # around(:example) {|ex| FakeFS(&ex)}
331
333
  #
334
+ # ### Order
335
+ #
336
+ # All `around` hooks execute immediately surrounding an example, this means
337
+ # that all `before` hooks will have run and no `after` hooks will have run yet.
338
+ #
339
+ # They are not a synonym for `before`/`after`.
332
340
  def around(*args, &block)
333
341
  hooks.register :prepend, :around, *args, &block
334
342
  end
@@ -339,8 +347,6 @@ module RSpec
339
347
  @hooks ||= HookCollections.new(self, FilterableItemRepository::UpdateOptimized)
340
348
  end
341
349
 
342
- private
343
-
344
350
  # @private
345
351
  Hook = Struct.new(:block, :options)
346
352
 
@@ -26,21 +26,23 @@ module RSpec
26
26
 
27
27
  # @private
28
28
  class Bisect
29
- def call(options, _err, _out)
29
+ def call(options, err, out)
30
30
  RSpec::Support.require_rspec_core "bisect/coordinator"
31
+ runner = Runner.new(options).tap { |r| r.configure(err, out) }
32
+ formatter = bisect_formatter_klass_for(options.options[:bisect]).new(
33
+ out, runner.configuration.bisect_runner
34
+ )
31
35
 
32
36
  success = RSpec::Core::Bisect::Coordinator.bisect_with(
33
- options.args,
34
- RSpec.configuration,
35
- bisect_formatter_for(options.options[:bisect])
37
+ runner, options.args, formatter
36
38
  )
37
39
 
38
40
  success ? 0 : 1
39
41
  end
40
42
 
41
- private
43
+ private
42
44
 
43
- def bisect_formatter_for(argument)
45
+ def bisect_formatter_klass_for(argument)
44
46
  return Formatters::BisectDebugFormatter if argument == "verbose"
45
47
  Formatters::BisectProgressFormatter
46
48
  end
@@ -10,7 +10,7 @@ module RSpec
10
10
  # @note `subject` was contributed by Joe Ferris to support the one-liner
11
11
  # syntax embraced by shoulda matchers:
12
12
  #
13
- # describe Widget do
13
+ # RSpec.describe Widget do
14
14
  # it { is_expected.to validate_presence_of(:name) }
15
15
  # # or
16
16
  # it { should validate_presence_of(:name) }
@@ -23,7 +23,7 @@ module RSpec
23
23
  # @example
24
24
  #
25
25
  # # Explicit declaration of subject.
26
- # describe Person do
26
+ # RSpec.describe Person do
27
27
  # subject { Person.new(:birthdate => 19.years.ago) }
28
28
  # it "should be eligible to vote" do
29
29
  # subject.should be_eligible_to_vote
@@ -32,7 +32,7 @@ module RSpec
32
32
  # end
33
33
  #
34
34
  # # Implicit subject => { Person.new }.
35
- # describe Person do
35
+ # RSpec.describe Person do
36
36
  # it "should be eligible to vote" do
37
37
  # subject.should be_eligible_to_vote
38
38
  # # ^ ^ explicit reference to subject not recommended
@@ -40,7 +40,7 @@ module RSpec
40
40
  # end
41
41
  #
42
42
  # # One-liner syntax - expectation is set on the subject.
43
- # describe Person do
43
+ # RSpec.describe Person do
44
44
  # it { is_expected.to be_eligible_to_vote }
45
45
  # # or
46
46
  # it { should be_eligible_to_vote }
@@ -67,7 +67,7 @@ module RSpec
67
67
  #
68
68
  # @example
69
69
  #
70
- # describe Person do
70
+ # RSpec.describe Person do
71
71
  # it { should be_eligible_to_vote }
72
72
  # end
73
73
  #
@@ -86,7 +86,7 @@ module RSpec
86
86
  #
87
87
  # @example
88
88
  #
89
- # describe Person do
89
+ # RSpec.describe Person do
90
90
  # it { should_not be_eligible_to_vote }
91
91
  # end
92
92
  #
@@ -270,7 +270,7 @@ EOS
270
270
  #
271
271
  # @example
272
272
  #
273
- # describe Thing do
273
+ # RSpec.describe Thing do
274
274
  # let(:thing) { Thing.new }
275
275
  #
276
276
  # it "does something" do
@@ -288,7 +288,26 @@ EOS
288
288
  raise(
289
289
  "#let or #subject called with a reserved name #initialize"
290
290
  ) if :initialize == name
291
- MemoizedHelpers.module_for(self).__send__(:define_method, name, &block)
291
+ our_module = MemoizedHelpers.module_for(self)
292
+
293
+ # If we have a module clash in our helper module
294
+ # then we need to remove it to prevent a warning.
295
+ #
296
+ # Note we do not check ancestor modules (see: `instance_methods(false)`)
297
+ # as we can override them.
298
+ if our_module.instance_methods(false).include?(name)
299
+ our_module.__send__(:remove_method, name)
300
+ end
301
+ our_module.__send__(:define_method, name, &block)
302
+
303
+ # If we have a module clash in the example module
304
+ # then we need to remove it to prevent a warning.
305
+ #
306
+ # Note we do not check ancestor modules (see: `instance_methods(false)`)
307
+ # as we can override them.
308
+ if instance_methods(false).include?(name)
309
+ remove_method(name)
310
+ end
292
311
 
293
312
  # Apply the memoization. The method has been defined in an ancestor
294
313
  # module so we can use `super` here to get the value.
@@ -323,7 +342,7 @@ EOS
323
342
  # end
324
343
  # end
325
344
  #
326
- # describe Thing do
345
+ # RSpec.describe Thing do
327
346
  # after(:example) { Thing.reset_count }
328
347
  #
329
348
  # context "using let" do
@@ -379,13 +398,13 @@ EOS
379
398
  #
380
399
  # @example
381
400
  #
382
- # describe CheckingAccount, "with $50" do
401
+ # RSpec.describe CheckingAccount, "with $50" do
383
402
  # subject { CheckingAccount.new(Money.new(50, :USD)) }
384
403
  # it { is_expected.to have_a_balance_of(Money.new(50, :USD)) }
385
404
  # it { is_expected.not_to be_overdrawn }
386
405
  # end
387
406
  #
388
- # describe CheckingAccount, "with a non-zero starting balance" do
407
+ # RSpec.describe CheckingAccount, "with a non-zero starting balance" do
389
408
  # subject(:account) { CheckingAccount.new(Money.new(50, :USD)) }
390
409
  # it { is_expected.not_to be_overdrawn }
391
410
  # it "has a balance equal to the starting balance" do
@@ -433,7 +452,7 @@ EOS
433
452
  # end
434
453
  # end
435
454
  #
436
- # describe Thing do
455
+ # RSpec.describe Thing do
437
456
  # after(:example) { Thing.reset_count }
438
457
  #
439
458
  # context "using subject" do
@@ -483,9 +502,9 @@ EOS
483
502
  def self.module_for(example_group)
484
503
  get_constant_or_yield(example_group, :LetDefinitions) do
485
504
  mod = Module.new do
486
- include Module.new {
505
+ include(Module.new {
487
506
  example_group.const_set(:NamedSubjectPreventSuper, self)
488
- }
507
+ })
489
508
  end
490
509
 
491
510
  example_group.const_set(:LetDefinitions, mod)