diff --git a/lib/sus/fixtures/temporary_directory_context.rb b/lib/sus/fixtures/temporary_directory_context.rb index c4875bf..697f278 100644 --- a/lib/sus/fixtures/temporary_directory_context.rb +++ b/lib/sus/fixtures/temporary_directory_context.rb @@ -4,6 +4,7 @@ # Copyright, 2025-2026, by Samuel Williams. require "tmpdir" +require "fileutils" module Sus module Fixtures @@ -12,10 +13,17 @@ module TemporaryDirectoryContext # Set up a temporary directory before the test and clean it up after. # @yields {|&block| ...} The test block to execute. def around(&block) - Dir.mktmpdir do |root| + root = Dir.mktmpdir + + begin @root = root + super(&block) + ensure @root = nil + + # Use forced removal so cleanup tolerates paths which were already removed by the test or an external process. + FileUtils.remove_entry(root, true) end end @@ -24,4 +32,3 @@ def around(&block) end end end - diff --git a/releases.md b/releases.md index 49beea8..93de578 100644 --- a/releases.md +++ b/releases.md @@ -1,5 +1,9 @@ # Releases +## Unreleased + + - Make `Sus::Fixtures::TemporaryDirectoryContext` ignore temporary directory cleanup failures. + ## v0.37.1 - Fixed `Sus::Mock#wrap` to forward blocks to the original method, and fixed `receive(...).with_block(...)` to use the supplied predicate. diff --git a/test/sus/fixtures/temporary_directory_context.rb b/test/sus/fixtures/temporary_directory_context.rb index 5ccd336..d7f27ed 100644 --- a/test/sus/fixtures/temporary_directory_context.rb +++ b/test/sus/fixtures/temporary_directory_context.rb @@ -8,6 +8,8 @@ describe Sus::Fixtures::TemporaryDirectoryContext do include Sus::Fixtures::TemporaryDirectoryContext + let(:assertions) {Sus::Assertions.new(output: Sus::Output.buffered)} + it "creates a temporary directory" do expect(root).not.to be(:nil?) expect(root).to be_a(String) @@ -26,4 +28,37 @@ expect(File.exist?(test_file)).to be == true expect(File.read(test_file)).to be == "test content" end + + it "removes the temporary directory after use" do + context = Sus.base("temporary directory") + context.include(Sus::Fixtures::TemporaryDirectoryContext) + instance = context.new(assertions) + + root = nil + + instance.around do + root = instance.root + + expect(File.directory?(root)).to be == true + end + + expect(File.exist?(root)).to be == false + end + + it "tolerates already removed temporary directories during cleanup" do + context = Sus.base("temporary directory") + context.include(Sus::Fixtures::TemporaryDirectoryContext) + instance = context.new(assertions) + + root = nil + + expect do + instance.around do + root = instance.root + FileUtils.remove_entry(root) + end + end.not.to raise_exception + + expect(File.exist?(root)).to be == false + end end