mutant-rspec 0.16.3 → 0.17.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ed162d6c71157f2c6c5c9758b2e56616aeddb60cdf245cbf7928a20a9872efe
4
- data.tar.gz: 053f85345daf93b3a9fb2be5986ebe96b1de88711af244dcfe6f5709689117d3
3
+ metadata.gz: '048a5d77aaec0aeb8cb8a3498b065a6d7e1fbc3691fc2913185a3c21698e98b7'
4
+ data.tar.gz: ae4405f217208163e6bf2822e5ebe313b8dde0a73989b1db3f674712439cc5ff
5
5
  SHA512:
6
- metadata.gz: 679b303dbd729051c2b15665905a8f9ef6bcf3bf6d4780cb9e94cda033be4f9baab044f30fe710e33ced8db320a8e0c20d59fd3df2b951ed16efc203e4daba84
7
- data.tar.gz: f300869bec5ad54080f693c586c62dbb4526130b59f4c8157702d7e97a393a32c41f85d4a16667a0f338a5b94bc0e72c4106d1c6edab290b5bf652cb50991319
6
+ metadata.gz: a2e47586585d3a592e0e3abd44056d6d454c81ef78eb9c192f9ecc44b4f118232815db1d3711bd8ecd7d3a007f65993892090b3ba4c769f77cf9609025912070
7
+ data.tar.gz: 3ee67f84ca7049f5bd6eda3e2abc7f055cdeeabf489c7378e830cef59249e98302e06114f60a01f50772ee114b7657d9a64c923d6d1b3725d53bc03ca4859e7e
@@ -29,6 +29,50 @@ module Mutant
29
29
 
30
30
  private_constant(*constants(false))
31
31
 
32
+ # Rspec ordering strategy driven by the order mutant selected the tests in
33
+ #
34
+ # Rspec runs one group at a time, so a group is ranked by the best test it
35
+ # holds, and the ranking survives as group order plus example order within
36
+ # a group. Anything rspec asks about that was not selected sorts last.
37
+ class Ordering
38
+ UNRANKED = Float::INFINITY
39
+
40
+ private_constant(*constants(false))
41
+
42
+ def initialize = @rank = {}
43
+
44
+ # Rank examples, best first
45
+ #
46
+ # @param [Enumerable<RSpec::Core::Example>] examples
47
+ #
48
+ # @return [self]
49
+ def call(examples)
50
+ @rank.clear
51
+
52
+ examples.each_with_index do |example, rank|
53
+ @rank[example] = rank
54
+
55
+ example.example_group.parent_groups.each do |group|
56
+ @rank[group] = rank if @rank.fetch(group, UNRANKED) > rank
57
+ end
58
+ end
59
+
60
+ self
61
+ end
62
+
63
+ # Order the groups or the examples rspec is about to run
64
+ #
65
+ # Rspec's own id breaks a tie, so the order does not depend on the order
66
+ # rspec happened to hand the list over in.
67
+ #
68
+ # @param [Array<Object>] list
69
+ #
70
+ # @return [Array<Object>]
71
+ def order(list)
72
+ list.sort_by { |item| [@rank.fetch(item, UNRANKED), item.id] }
73
+ end
74
+ end # Ordering
75
+
32
76
  def freeze = tap { super if @setup_elapsed }
33
77
 
34
78
  # Initialize rspec integration
@@ -36,6 +80,7 @@ module Mutant
36
80
  # @return [undefined]
37
81
  def initialize(*)
38
82
  super
83
+ @ordering = Ordering.new
39
84
  @runner = RSpec::Core::Runner.new(RSpec::Core::ConfigurationOptions.new(effective_arguments))
40
85
  @rspec_world = RSpec.world
41
86
  end
@@ -56,7 +101,7 @@ module Mutant
56
101
  end
57
102
  memoize :setup
58
103
 
59
- # Run a collection of tests
104
+ # Run a collection of tests, likeliest killer first
60
105
  #
61
106
  # @param [Enumerable<Mutant::Test>] tests
62
107
  #
@@ -65,8 +110,12 @@ module Mutant
65
110
  # rubocop:disable Metrics/AbcSize
66
111
  # rubocop:disable Metrics/MethodLength
67
112
  def call(tests)
113
+ examples = tests.map(&all_tests_index)
114
+
115
+ install_ordering
68
116
  reset_examples
69
- setup_examples(tests.map(&all_tests_index))
117
+ @ordering.call(examples)
118
+ setup_examples(examples)
70
119
  @runner.configuration.start_time = world.time.now - @setup_elapsed
71
120
  start = timer.now
72
121
  passed = @runner.run_specs(@rspec_world.ordered_example_groups).equal?(EXIT_SUCCESS)
@@ -96,6 +145,18 @@ module Mutant
96
145
 
97
146
  private
98
147
 
148
+ # Rspec picks its own order for groups and for the examples inside them,
149
+ # which would throw away the selector's ranking. Its ordering registry is
150
+ # the seam for that, but the public `register_ordering(:global)` is a noop
151
+ # once `--order` was forced from the command line or `.rspec`, which most
152
+ # suites do. Registering with the registry is the only way in.
153
+ #
154
+ # Registered per run rather than at setup: the strategy is the same object
155
+ # every time, and a run is the moment its ranking is known.
156
+ def install_ordering
157
+ @runner.configuration.ordering_registry.register(:global, @ordering)
158
+ end
159
+
99
160
  def rspec_setup_failure?
100
161
  @rspec_world.wants_to_quit || rspec_is_quitting?
101
162
  end
@@ -124,16 +185,19 @@ module Mutant
124
185
  def parse_example(example, index)
125
186
  metadata = example.metadata
126
187
 
127
- id = TEST_ID_FORMAT % {
188
+ Test.new(
189
+ expressions: parse_metadata(metadata),
190
+ id: test_id(metadata, index),
191
+ location: metadata.fetch(:location)
192
+ )
193
+ end
194
+
195
+ def test_id(metadata, index)
196
+ TEST_ID_FORMAT % {
128
197
  index:,
129
198
  location: metadata.fetch(:location),
130
199
  description: metadata.fetch(:full_description)
131
200
  }
132
-
133
- Test.new(
134
- expressions: parse_metadata(metadata),
135
- id:
136
- )
137
201
  end
138
202
 
139
203
  def example_group_map
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutant-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.3
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - '='
17
17
  - !ruby/object:Gem::Version
18
- version: 0.16.3
18
+ version: 0.17.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - '='
24
24
  - !ruby/object:Gem::Version
25
- version: 0.16.3
25
+ version: 0.17.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec-core
28
28
  requirement: !ruby/object:Gem::Requirement