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

Commit 3f2b5dd

Browse files
committed
Load spec files in the order that files and dirs were specified in the CLI.
This fixes #2247 and addresses some of the feedback from #2251.
1 parent ab20006 commit 3f2b5dd

File tree

3 files changed

+44
-45
lines changed

3 files changed

+44
-45
lines changed

Changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ Enhancements:
88
by using `bundle exec`. (Myron Marston, #2240)
99
* HTML Formatter uses exception presenter to get failure message
1010
for consistency with other formatters. (@mrageh, #2222)
11+
* Load spec files in the order of the directories or files passed
12+
at the command line, making it easy to make some specs run before
13+
others in a one-off manner. For example, `rspec spec/unit
14+
spec/acceptance --order defined` will run unit specs before acceptance
15+
specs. (Myron Marston, #2253)
1116

1217
Bug Fixes:
1318

lib/rspec/core/configuration.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,7 +1782,7 @@ def get_files_to_run(paths)
17821782
files = FlatMap.flat_map(paths_to_check(paths)) do |path|
17831783
path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
17841784
File.directory?(path) ? gather_directories(path) : extract_location(path)
1785-
end.sort.uniq
1785+
end.uniq
17861786

17871787
return files unless only_failures?
17881788
relative_files = files.map { |f| Metadata.relative_path(File.expand_path f) }
@@ -1802,11 +1802,12 @@ def pattern_might_load_specs_from_vendored_dirs?
18021802
def gather_directories(path)
18031803
include_files = get_matching_files(path, pattern)
18041804
exclude_files = get_matching_files(path, exclude_pattern)
1805-
(include_files - exclude_files).sort.uniq
1805+
(include_files - exclude_files).uniq
18061806
end
18071807

18081808
def get_matching_files(path, pattern)
1809-
Dir[file_glob_from(path, pattern)].map { |file| File.expand_path(file) }
1809+
raw_files = Dir[file_glob_from(path, pattern)]
1810+
raw_files.map { |file| File.expand_path(file) }.sort
18101811
end
18111812

18121813
def file_glob_from(path, pattern)

spec/rspec/core/configuration_spec.rb

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -554,58 +554,51 @@ def loaded_files
554554
end
555555
end
556556

557-
def specify_consistent_ordering_of_files_to_run
558-
allow(File).to receive(:directory?).and_call_original
559-
allow(File).to receive(:directory?).with('a') { true }
560-
globbed_files = nil
561-
allow(Dir).to receive(:[]).with(/^\{?a/) { globbed_files }
562-
allow(Dir).to receive(:[]).with(a_string_starting_with(Dir.getwd)) { [] }
563-
564-
orderings = [
565-
%w[ a/1.rb a/2.rb a/3.rb ],
566-
%w[ a/2.rb a/1.rb a/3.rb ],
567-
%w[ a/3.rb a/2.rb a/1.rb ]
568-
].map do |files|
569-
globbed_files = files
570-
yield
571-
config.files_to_run
572-
end
557+
it 'loads files in passed directories in alphabetical order to avoid OS-specific file-globbing non-determinism' do
558+
define_dirs "spec/unit" => [
559+
["spec/unit/b_spec.rb", "spec/unit/a_spec.rb"],
560+
["spec/unit/a_spec.rb", "spec/unit/b_spec.rb"]
561+
]
573562

574-
expect(orderings.uniq.size).to eq(1)
563+
expect(assign_files_or_directories_to_run "spec/unit").to match [
564+
file_at("spec/unit/a_spec.rb"),
565+
file_at("spec/unit/b_spec.rb")
566+
]
567+
expect(assign_files_or_directories_to_run "spec/unit").to match [
568+
file_at("spec/unit/a_spec.rb"),
569+
file_at("spec/unit/b_spec.rb")
570+
]
575571
end
576572

577-
context 'when the given directories match the pattern' do
578-
it 'orders the files in a consistent ordering, regardless of the underlying OS ordering' do
579-
specify_consistent_ordering_of_files_to_run do
580-
config.pattern = 'a/*.rb'
581-
assign_files_or_directories_to_run 'a'
582-
end
583-
end
584-
end
573+
it 'respects the user-specified order of files and directories passed at the command line' do
574+
define_dirs "spec/b" => [["spec/b/1_spec.rb", "spec/b/2_spec.rb"]],
575+
"spec/c" => [["spec/c/1_spec.rb", "spec/c/2_spec.rb"]]
585576

586-
context 'when the pattern is given relative to the given directories' do
587-
it 'orders the files in a consistent ordering, regardless of the underlying OS ordering' do
588-
specify_consistent_ordering_of_files_to_run do
589-
config.pattern = '*.rb'
590-
assign_files_or_directories_to_run 'a'
591-
end
592-
end
577+
expect(assign_files_or_directories_to_run "spec/b", "spec/a1_spec.rb", "spec/c", "spec/a2_spec.rb").to match [
578+
file_at("spec/b/1_spec.rb"), file_at("spec/b/2_spec.rb"),
579+
file_at("spec/a1_spec.rb"),
580+
file_at("spec/c/1_spec.rb"), file_at("spec/c/2_spec.rb"),
581+
file_at("spec/a2_spec.rb")
582+
]
593583
end
594584

595-
context 'when given multiple file paths' do
596-
it 'orders the files in a consistent ordering, regardless of the given order' do
597-
allow(File).to receive(:directory?) { false } # fake it into thinking these a full file paths
598-
599-
files = ['a/b/c_spec.rb', 'c/b/a_spec.rb']
600-
assign_files_or_directories_to_run(*files)
601-
ordering_1 = config.files_to_run
585+
def define_dirs(dirs_hash)
586+
allow(File).to receive(:directory?) do |path|
587+
!path.end_with?(".rb")
588+
end
602589

603-
assign_files_or_directories_to_run(*files.reverse)
604-
ordering_2 = config.files_to_run
590+
allow(Dir).to receive(:[]).and_return([])
605591

606-
expect(ordering_1).to eq(ordering_2)
592+
dirs_hash.each do |dir, sequential_glob_return_values|
593+
allow(Dir).to receive(:[]).with(
594+
a_string_including(dir, config.pattern)
595+
).and_return(*sequential_glob_return_values)
607596
end
608597
end
598+
599+
def file_at(relative_path)
600+
eq(relative_path).or eq(File.expand_path(relative_path))
601+
end
609602
end
610603

611604
describe "#pattern" do

0 commit comments

Comments
 (0)