-
Notifications
You must be signed in to change notification settings - Fork 256
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull Request #352 introduces breaking change while NuGet package only increases patch version #404
Comments
We're trying to follow semver, but obviously missed out on this one, sorry about that :/ Can you share some details on the failures you are seeing after the upgrade? |
@fgreinacher, as I said, this change causes compile-time errors, because a previously parameter-less constructor now takes a parameter. After fixing the compile-time errors, some unit tests fail, which is likely due to an issue with the private void SerializeToCacheFile()
{
lock (FileLock)
{
try
{
using (Stream stream = _fileSystem.File.OpenWrite(_cacheFilePath))
{
// Do stuff
}
}
catch (Exception ex)
{
// Log exception
}
}
} The public FileServiceInformationCache(string cacheFileName, IFileSystem fileSystem)
{
if (cacheFileName == null) throw new ArgumentNullException(nameof(cacheFileName));
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_cacheFilePath = _fileSystem.FileInfo.FromFileName(cacheFileName).FullName;
// Do other stuff
} This constructor is called from the unit test class' constructor: public FileServiceInformationCacheTests(ITestOutputHelper output) : base(output)
{
_fileSystem = new MockFileSystem();
_cacheFileName = _fileSystem.Path.GetRandomFileName();
}
_cacheFilePath = _fileSystem.FileInfo.FromFileName(cacheFileName).FullName Did you change the behavior of those testing helpers as well? |
@fgreinacher, I have produced another unit test, which uses the same features and also fails to open the file for writing (and creating) in v2.1.0.256. [Fact]
public void CanUseMockFileSystem()
{
var fileSystem = new MockFileSystem();
string fileName = _fileSystem.Path.GetRandomFileName();
using (Stream stream = fileSystem.File.OpenWrite(fileName))
using (var writer = new StreamWriter(stream))
{
writer.WriteLine("Hello World!");
}
using (Stream stream = fileSystem.File.OpenRead(fileName))
using (var reader = new StreamReader(stream))
{
string line = reader.ReadLine();
Assert.Equal("Hello World!", line);
}
} Here's the relevant portion of the exception: System.IO.DirectoryNotFoundException
Could not find a part of the path 'cuylzl0q.non'.
at System.IO.Abstractions.TestingHelpers.MockFile.CreateInternal(String path, Int32 bufferSize, FileOptions options, FileSecurity fileSecurity)
at System.IO.Abstractions.TestingHelpers.MockFile.Create(String path, Int32 bufferSize, FileOptions options)
at System.IO.Abstractions.TestingHelpers.MockFile.OpenWriteInternal(String path, FileOptions options) |
Having looked at #401, I made some changes to my unit test above. With those changes, it now works. However, as pointed out in #401, the current behavior is not expected and different from the previous behavior. [Fact]
public void CanUseMockFileSystem2()
{
var fileSystem = new MockFileSystem();
// Added to explicitly create and set working directory.
const string workingDirectory = "C:\\Temp";
fileSystem.Directory.CreateDirectory(workingDirectory);
fileSystem.Directory.SetCurrentDirectory(workingDirectory);
// Changed to create absolute instead of relative path.
string fileName = fileSystem.Path.Combine(workingDirectory, _fileSystem.Path.GetRandomFileName());
using (Stream stream = fileSystem.File.OpenWrite(fileName))
using (var writer = new StreamWriter(stream))
{
writer.WriteLine("Hello World!");
}
using (Stream stream = fileSystem.File.OpenRead(fileName))
using (var reader = new StreamReader(stream))
{
string line = reader.ReadLine();
Assert.Equal("Hello World!", line);
}
} |
Thanks for investigating deeper - I’ll try to find some time within the next couple of days! |
Root cause for the problems is wleader@95ead3a#diff-e76db4b13ed41e41943b80f8f1075287 where we started using `Path.GetDirectoryName` to get the parent directory, but unfortunately this method returns an empty string when the path does not contain directory information (e.g. a plain file name). The changes here make the paths absolute before passing them on to `Path.GetDirectoryName`. Fixes #404 and #401
@ThomasBarnekow The problem is fixed with ec1b673. Could you verify your use case with the prerelease version https://www.nuget.org/packages/System.IO.Abstractions/2.2.10-beta? |
@fgreinacher Just installed the above prerelease NuGet package in my solution and ran all unit tests. I can confirm the bug is fixed. All my unit tests pass again. |
Today, I tried to update to the latest NuGet package, which is v2.1.0.256 at the time of writing. I was using v2.1.0.178 and did not expect any breaking changes, since only the patch number was updated. However, the projects using the previously parameterless
PathWrapper
constructor no longer compiled.Further, even after providing a
FileSystem
object to the constructor, some of my unit tests then failed. They have been passing with all the previous versions, including v2.1.0.178. This might or might not be related to the breaking API change.Are you using semantic versioning for your NuGet packages?
The text was updated successfully, but these errors were encountered: