Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 4d3a9d2

Browse files
committed
Merge pull request #2778 from MatheusRich/order-specs-by-modification-time
Allow ordering specs by modification time
1 parent 0e9f42c commit 4d3a9d2

File tree

5 files changed

+48
-5
lines changed

5 files changed

+48
-5
lines changed

features/command_line/order.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ order of groups at each level is randomized.
1313

1414
With `rand` you can also specify a seed.
1515

16+
Use `recently-modified` to run the most recently modified files first. You can
17+
combine it with `--only-failures` to find the most recent failing specs. Note
18+
that `recently-modified` and `rand` are mutually exclusive.
19+
1620
## Example usage
1721

1822
The `defined` option is only necessary when you have `--order rand` stored in a
@@ -22,4 +26,5 @@ config file (e.g. `.rspec`) and you want to override it from the command line.
2226
--order rand
2327
--order rand:123
2428
--seed 123 # same as --order rand:123
29+
--order recently-modified
2530
</code></pre>

lib/rspec/core/option_parser.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ def parser(options)
5858
end
5959

6060
parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.',
61-
' [defined] examples and groups are run in the order they are defined',
62-
' [rand] randomize the order of groups and examples',
63-
' [random] alias for rand',
64-
' [random:SEED] e.g. --order random:123') do |o|
61+
' [defined] examples and groups are run in the order they are defined',
62+
' [rand] randomize the order of groups and examples',
63+
' [random] alias for rand',
64+
' [random:SEED] e.g. --order random:123',
65+
' [recently-modified] run the most recently modified files first') do |o|
6566
options[:order] = o
6667
end
6768

lib/rspec/core/ordering.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ def jenkins_hash_digest(string)
5858
MAX_32_BIT = 4_294_967_295
5959
end
6060

61+
# @private
62+
# Orders items by modification time (most recent modified first).
63+
class RecentlyModified
64+
def order(list)
65+
list.sort_by { |item| -File.mtime(item.metadata[:absolute_file_path]).to_i }
66+
end
67+
end
68+
6169
# @private
6270
# Orders items based on a custom block.
6371
class Custom
@@ -77,7 +85,8 @@ def initialize(configuration)
7785
@configuration = configuration
7886
@strategies = {}
7987

80-
register(:random, Random.new(configuration))
88+
register(:random, Random.new(configuration))
89+
register(:recently_modified, RecentlyModified.new)
8190

8291
identity = Identity.new
8392
register(:defined, identity)
@@ -132,6 +141,8 @@ def order=(type)
132141
:random
133142
elsif order == 'defined'
134143
:defined
144+
elsif order == 'recently-modified'
145+
:recently_modified
135146
end
136147

137148
register_ordering(:global, ordering_registry.fetch(ordering_name)) if ordering_name

spec/integration/order_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,17 @@
130130
end
131131
end
132132

133+
describe '--order rand --order recently-modified' do
134+
it 'overrides random ordering with recently-modified option' do
135+
2.times { run_command 'spec/order_spec.rb --order rand --order recently-modified -f doc' }
136+
137+
expect(stdout.string).not_to match(/Randomized with seed/)
138+
139+
top_level_groups { |first_run, second_run| expect(first_run).to eq(second_run) }
140+
nested_groups { |first_run, second_run| expect(first_run).to eq(second_run) }
141+
end
142+
end
143+
133144
describe '--order defined on CLI with --order rand in .rspec' do
134145
after { remove '.rspec' }
135146

spec/rspec/core/ordering_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,21 @@ def order_with(seed)
8181
end
8282
end
8383

84+
RSpec.describe RecentlyModified do
85+
before do
86+
allow(File).to receive(:mtime).with('./file_1.rb').and_return(::Time.new)
87+
allow(File).to receive(:mtime).with('./file_2.rb').and_return(::Time.new + 1)
88+
end
89+
90+
it 'orders list by file modification time' do
91+
file_1 = instance_double(Example, :metadata => { :absolute_file_path => './file_1.rb' })
92+
file_2 = instance_double(Example, :metadata => { :absolute_file_path => './file_2.rb' })
93+
strategy = RecentlyModified.new
94+
95+
expect(strategy.order([file_1, file_2])).to eq([file_2, file_1])
96+
end
97+
end
98+
8499
RSpec.describe Custom do
85100
it 'uses the block to order the list' do
86101
strategy = Custom.new(proc { |list| list.reverse })

0 commit comments

Comments
 (0)