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

Commit aed8a07

Browse files
committed
Merge pull request #2253 from rspec/myron/load-spec-files-in-cli-order
Load spec files in the order that files and dirs were specified in the CLI.
2 parents ab20006 + b6c84bc commit aed8a07

File tree

4 files changed

+69
-50
lines changed

4 files changed

+69
-50
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: 5 additions & 4 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)
@@ -1846,7 +1847,7 @@ def extract_location(path)
18461847
end
18471848

18481849
return [] if path == default_path
1849-
path
1850+
File.expand_path(path)
18501851
end
18511852

18521853
def command

spec/rspec/core/configuration_spec.rb

Lines changed: 57 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ def stub_expectation_adapters
483483

484484
it 'attempts to load the provided file names' do
485485
assign_files_or_directories_to_run "path/to/some/file.rb"
486-
expect(config.files_to_run).to eq(["path/to/some/file.rb"])
486+
expect(config.files_to_run).to contain_files("path/to/some/file.rb")
487487
end
488488

489489
it 'does not attempt to load a file at the `default_path`' do
@@ -554,58 +554,71 @@ 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
585+
it 'deduplicates spec files that are listed individually and present in a passed dir' do
586+
define_dirs "spec/unit" => [[
587+
"spec/unit/a_spec.rb",
588+
"spec/unit/b_spec.rb",
589+
"spec/unit/c_spec.rb"
590+
]]
591+
592+
expect(assign_files_or_directories_to_run "spec/unit/b_spec.rb", "spec/unit").to match [
593+
file_at("spec/unit/b_spec.rb"),
594+
file_at("spec/unit/a_spec.rb"),
595+
file_at("spec/unit/c_spec.rb")
596+
]
597+
598+
expect(assign_files_or_directories_to_run "spec/unit", "spec/unit/b_spec.rb").to match [
599+
file_at("spec/unit/a_spec.rb"),
600+
file_at("spec/unit/b_spec.rb"),
601+
file_at("spec/unit/c_spec.rb")
602+
]
603+
end
598604

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
605+
def define_dirs(dirs_hash)
606+
allow(File).to receive(:directory?) do |path|
607+
!path.end_with?(".rb")
608+
end
602609

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

606-
expect(ordering_1).to eq(ordering_2)
612+
dirs_hash.each do |dir, sequential_glob_return_values|
613+
allow(Dir).to receive(:[]).with(
614+
a_string_including(dir, config.pattern)
615+
).and_return(*sequential_glob_return_values)
607616
end
608617
end
618+
619+
def file_at(relative_path)
620+
eq(relative_path).or eq(File.expand_path(relative_path))
621+
end
609622
end
610623

611624
describe "#pattern" do
@@ -819,10 +832,10 @@ def specify_consistent_ordering_of_files_to_run
819832

820833
it "allows file names with brackets" do
821834
assign_files_or_directories_to_run "./path/to/a_[1:2]spec.rb"
822-
expect(config.files_to_run).to eq(["./path/to/a_[1:2]spec.rb"])
835+
expect(config.files_to_run).to contain_files("./path/to/a_[1:2]spec.rb")
823836

824837
assign_files_or_directories_to_run "./path/to/a_spec.rb[foo]"
825-
expect(config.files_to_run).to eq(["./path/to/a_spec.rb[foo]"])
838+
expect(config.files_to_run).to contain_files("./path/to/a_spec.rb[foo]")
826839
end
827840

828841
context "with an example id" do

spec/rspec/core/rake_task_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def specify_consistent_ordering_of_files_to_run(pattern, file_searcher)
167167
context "with SPEC env var set" do
168168
it "sets files to run" do
169169
with_env_vars 'SPEC' => 'path/to/file' do
170-
expect(loaded_files).to eq(["path/to/file"])
170+
expect(loaded_files).to contain_files("path/to/file")
171171
end
172172
end
173173

@@ -346,7 +346,7 @@ def self.it_configures_rspec_load_path(description, path_template)
346346
it "loads the files from the FileList" do
347347
task.pattern = FileList["spec/rspec/core/resources/**/*_spec.rb"]
348348

349-
expect(loaded_files).to contain_exactly(
349+
expect(loaded_files).to contain_files(
350350
"spec/rspec/core/resources/a_spec.rb",
351351
"spec/rspec/core/resources/acceptance/foo_spec.rb"
352352
)

0 commit comments

Comments
 (0)