Skip to content

Commit 2136635

Browse files
committed
Make specs faster
1 parent ed2b002 commit 2136635

File tree

2 files changed

+49
-42
lines changed

2 files changed

+49
-42
lines changed

spec/lib/rails/diff/rails_repo_spec.rb

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Helper indices for commits:
2-
# git_repo.commits[0] => 'add railties dir' (initial commit)
3-
# git_repo.commits[1] => 'commit1'
4-
# git_repo.commits.last => 'commit2'
2+
# @git_repo.commits[0] => 'add railties dir' (initial commit)
3+
# @git_repo.commits[1] => 'commit1'
4+
# @git_repo.commits.last => 'commit2'
55

66
require "rails/diff/rails_repo"
77
require "fileutils"
@@ -11,39 +11,40 @@
1111
let(:logger) { spy }
1212
let(:cache_dir) { Dir.mktmpdir }
1313
let(:rails_path) { File.join(cache_dir, "rails") }
14-
let(:git_repo) do
15-
GitRepo.new.tap do |repo|
14+
15+
before(:all) do
16+
@git_repo = GitRepo.new.tap do |repo|
1617
repo.add_commit("commit1")
1718
repo.add_commit("commit2")
1819
end
1920
end
2021

2122
after do
2223
FileUtils.rm_rf(cache_dir)
23-
git_repo.cleanup
24+
@git_repo.cleanup
2425
end
2526

2627
describe "#up_to_date?" do
2728
it "returns false when repo is not cloned yet" do
28-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
29+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
2930

3031
result = repo.up_to_date?
3132

3233
expect(result).to eq false
3334
end
3435

3536
it "returns true when repo is on the latest commit" do
36-
git_repo.clone_at_commit(git_repo.commits.last, rails_path)
37-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
37+
@git_repo.clone_at_commit(@git_repo.commits.last, rails_path)
38+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
3839

3940
result = repo.up_to_date?
4041

4142
expect(result).to eq true
4243
end
4344

4445
it "returns false and removes the repo when repo is on an old commit" do
45-
git_repo.clone_at_commit(git_repo.commits.first, rails_path)
46-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
46+
@git_repo.clone_at_commit(@git_repo.commits.first, rails_path)
47+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
4748

4849
result = repo.up_to_date?
4950

@@ -54,16 +55,16 @@
5455

5556
describe "#latest_commit" do
5657
it "returns the latest commit SHA from the remote repo" do
57-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
58+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
5859

5960
latest = repo.latest_commit
6061

61-
expect(latest).to eq git_repo.commits.last
62+
expect(latest).to eq @git_repo.commits.last
6263
end
6364

6465
it "returns the new latest commit after a new commit is pushed" do
65-
new_commit = git_repo.add_commit("commit3")
66-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
66+
new_commit = @git_repo.add_commit("commit3")
67+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
6768

6869
latest = repo.latest_commit
6970

@@ -73,32 +74,32 @@
7374

7475
describe "#checkout" do
7576
it "checks out the given commit in the repo" do
76-
git_repo.clone_at_commit(git_repo.commits.last, rails_path)
77-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
77+
@git_repo.clone_at_commit(@git_repo.commits.last, rails_path)
78+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
7879

7980
# Checkout the first file commit (not the initial railties commit)
80-
repo.checkout(git_repo.commits[1])
81+
repo.checkout(@git_repo.commits[1])
8182

8283
# Verify HEAD is now at the first file commit
8384
current = Dir.chdir(rails_path) { `git rev-parse HEAD`.strip }
84-
expect(current).to eq git_repo.commits[1]
85+
expect(current).to eq @git_repo.commits[1]
8586
end
8687

8788
it "logs the checkout info message" do
88-
git_repo.clone_at_commit(git_repo.commits.last, rails_path)
89-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
89+
@git_repo.clone_at_commit(@git_repo.commits.last, rails_path)
90+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
9091

91-
repo.checkout(git_repo.commits[1])
92+
repo.checkout(@git_repo.commits[1])
9293

9394
expect(logger).to have_received(:info)
94-
.with(/Checking out Rails \(at commit #{git_repo.commits[1][0..6]}\)/)
95+
.with(/Checking out Rails \(at commit #{@git_repo.commits[1][0..6]}\)/)
9596
end
9697
end
9798

9899
describe "#install_dependencies" do
99100
it "runs bundle check and bundle install if needed, and logs appropriately" do
100-
git_repo.clone_at_commit(git_repo.commits[0], rails_path)
101-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
101+
@git_repo.clone_at_commit(@git_repo.commits[0], rails_path)
102+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
102103

103104
# Simulate bundle check failing, so bundle install is needed
104105
allow(Rails::Diff).to receive(:system!).with("bundle check", abort: false, logger: logger).and_return(false)
@@ -111,8 +112,8 @@
111112
end
112113

113114
it "does not run bundle install if bundle check passes" do
114-
git_repo.clone_at_commit(git_repo.commits[0], rails_path)
115-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
115+
@git_repo.clone_at_commit(@git_repo.commits[0], rails_path)
116+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
116117

117118
# Simulate bundle check passing
118119
allow(Rails::Diff).to receive(:system!).with("bundle check", abort: false, logger: logger).and_return(true)
@@ -125,8 +126,8 @@
125126

126127
describe "#new_app" do
127128
it "runs the rails new command with the correct arguments and logs the command" do
128-
git_repo.clone_at_commit(git_repo.commits.last, rails_path)
129-
repo = described_class.new(logger:, cache_dir:, rails_repo: git_repo.remote_repo)
129+
@git_repo.clone_at_commit(@git_repo.commits.last, rails_path)
130+
repo = described_class.new(logger:, cache_dir:, rails_repo: @git_repo.remote_repo)
130131

131132
allow(Rails::Diff).to receive(:system!).and_return(true)
132133
app_name = "myapp"

spec/support/git_repo.rb

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,45 +8,51 @@ class GitRepo
88
def initialize
99
@remote_dir = Dir.mktmpdir
1010
@remote_repo = File.join(@remote_dir, "origin.git")
11-
Dir.chdir(@remote_dir) { `git init --bare origin.git > /dev/null 2>&1` }
11+
Dir.chdir(@remote_dir) { `git init --bare --initial-branch=main origin.git > /dev/null 2>&1` }
1212

1313
@commits = []
1414
@work_dir = Dir.mktmpdir
1515
Dir.chdir(@work_dir) do
1616
`git clone #{@remote_repo} . > /dev/null 2>&1`
1717
`git checkout -b main > /dev/null 2>&1`
18-
# Always create the 'railties' directory for test convenience
1918
FileUtils.mkdir_p("railties")
20-
File.write("railties/.keep", "keep")
19+
File.write("railties/README", "keep")
2120
`git add railties > /dev/null 2>&1`
22-
`git commit -m "add railties dir" > /dev/null 2>&1`
21+
22+
`git config user.email '[email protected]'`
23+
`git config user.name 'Test User'`
24+
25+
commit_result = `git commit -m "add railties dir" 2>&1`
26+
raise "Initial commit failed: #{commit_result}" unless $?.success?
2327
@commits << `git rev-parse HEAD`.strip
24-
`git push origin main > /dev/null 2>&1`
28+
`git push -u origin main > /dev/null 2>&1`
2529
end
2630
end
2731

28-
# Adds a commit with the given message and pushes to remote
2932
def add_commit(message)
3033
Dir.chdir(@work_dir) do
31-
filename = "file#{@commits.size}.txt"
32-
File.write(filename, message)
33-
`git add . > /dev/null 2>&1`
34-
`git commit -m "#{message}" > /dev/null 2>&1`
34+
`git commit --allow-empty -n -m "#{message}" > /dev/null 2>&1`
3535
sha = `git rev-parse HEAD`.strip
3636
@commits << sha
3737
`git push origin main > /dev/null 2>&1`
38+
`git fetch origin main > /dev/null 2>&1`
3839
end
3940

4041
@commits.last
4142
end
4243

4344
def clone_at_commit(commit_sha, dest_path)
4445
`git clone #{@remote_repo} #{dest_path} > /dev/null 2>&1`
45-
Dir.chdir(dest_path) { `git checkout #{commit_sha} > /dev/null 2>&1` }
46+
Dir.chdir(dest_path) do
47+
`git checkout #{commit_sha} > /dev/null 2>&1`
48+
`git fetch origin main > /dev/null 2>&1`
49+
end
4650
end
4751

4852
def cleanup
49-
FileUtils.rm_rf(@remote_dir)
50-
FileUtils.rm_rf(@work_dir)
53+
Dir.chdir(@work_dir) do
54+
`git reset --hard main > /dev/null 2>&1`
55+
`git clean -fdx > /dev/null 2>&1`
56+
end
5157
end
5258
end

0 commit comments

Comments
 (0)