Skip to content

Conversation

@rkoeninger
Copy link
Contributor

@rkoeninger rkoeninger commented Jul 12, 2018

Fixes #208
Fixes #223
Fixes #318

Effects of this PR:

  • Can no longer have a file and a directory with the same name exist at the same time.
  • Trailing slashes are acceptable but not required.
  • Directories can be created, removed and queried with a trailing slash without any difference in behavior.
  • Tests that assumed directories would have trailing slashes have been fixed.
  • Keys in the dictionary in MockFileSystem no longer have trailing slashes unless:
    • It's a Windows drive root.
    • Or the Unix file system root.
  • Files enumerated by Directory.GetFiles() won't have trailing slashes.
  • Incidentally, UnixOnlyAttribute/UnixSpecifics were added to mirror WindowsOnlyAttribute/WindowsSpecifics.
  • 14 unit tests added to cover the TrimSlashes helper, increase coverage of existing functionality and confirm that issues MockFileSystem should not require trailing slash for directories #208 and MockFileSystem.File.Exists throws NullReferenceException #233 have been addressed as well.

@rkoeninger rkoeninger changed the title Don't allow files and directories with the same name [WIP] Don't allow files and directories with the same name Jul 12, 2018
[Test]
public void CleanPath_DriveRoot_PreserveTrailingSlash()
{
Assert.AreEqual(@"c:\", @"c:\".CleanPath());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may seem a little silly / overly verbose, but I think I'd prefer if this was broken up into three lines for AAA (no comments for each section though).

You'll also need XFS.Path for Linux shenanigans.

Copy link
Contributor Author

@rkoeninger rkoeninger Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AAA really only makes sense in situations where you're testing mutable state. Arrange the state. Act on state with impure operation. Assert result.

This is the closest approximation I can make:

// Arrange
var x = @"c:\";

// Act
var y = x.CleanPath();

// Assert
Assert.AreEqual(@"c:\", y);

XFS.Path noted.


private void SetEntry(string path, MockFileData mockFile)
{
path = FixPath(path, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm personally a fan of pure/functional methods where possible, so I think I'd rather see this be immutable.

Copy link
Contributor Author

@rkoeninger rkoeninger Jul 13, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean overwriting the value of the local variable? I'm not a fan of that either. I've inline-ed those in places and will continue to.

@jpreese
Copy link
Member

jpreese commented Jul 12, 2018

Thanks for working on this @rkoeninger. I'm really curious what you come up for this one. In the spirit of rapid feedback, I left a couple comments.

@rkoeninger
Copy link
Contributor Author

Re: 0c6879a
Did this test make sense originally? It was making a directory with the name of the destination we want to rename/move a file to.

@rkoeninger
Copy link
Contributor Author

Got the tests passing on Windows, but plenty of failures on Linux.

How does one normally work on Unix-specific failures? Startup a VM?

I'll try that tomorrow.

@jpreese
Copy link
Member

jpreese commented Jul 13, 2018

Re: 0c6879a
Did this test make sense originally? It was making a directory with the name of the destination we want to rename/move a file to.

I think the test is OK. Given what it's doing, and the name of the test, it's verifying that MoveTo does a replace, which is a valuable test.

I do not however see a test that just simply test moving a file to another directory where the file does not already exist.

How does one normally work on Unix-specific failures? Startup a VM?

I have always used a docker container to text Linux tests locally. You can mount the System.IO.Abstractions source folder and run dotnet test.

@rkoeninger
Copy link
Contributor Author

rkoeninger commented Jul 13, 2018

@jpreese About that test (0c6879a): I wasn't questioning the existence of the test, but the way it was written. It started to fail after I made my changes, I believe because it was depending on the ability to have a file and directory with the same name exist at the same time. That commit contains the one-line fix that fixes what may have just been a typo.

I get worried when I have to change tests to make them pass, and they're not changes I expected to have to make.

@jpreese
Copy link
Member

jpreese commented Jul 13, 2018

For that test, yeah I was agreeing with the name and how it was written.

  1. Add a file at c:\temp\file.txt
  2. Add a directory at c:\temp2\file.txt
  3. Move c:\temp\file.txt to c:\temp2\file.txt
  4. Validate the move overwrote c:\temp2\file.txt

So if I'm understanding this right, the fault here is that we're doing .AddDirectory and not adding a File. The test is validating that we can replace a file, and the way its written now (in the PR), does not do that since destinationFolder is empty.

The test you've written validates that we can Move a file (which I think we need, because for some reason we don't have it).

There should be a test for move to an empty directory, and a test for a move to a source that already exists.

@rkoeninger
Copy link
Contributor Author

@jpreese Ok, so the original test was split into 3 tests, and added Copy/Move tests for MockFile.

@rkoeninger
Copy link
Contributor Author

I think this is pretty much ready. Does anyone have any other comments/concerns?

@rkoeninger rkoeninger changed the title [WIP] Don't allow files and directories with the same name Don't allow files and directories with the same name Jul 15, 2018
Copy link
Contributor

@fgreinacher fgreinacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some minor nits – otherwise LGTM

var fileSystem = new MockFileSystem();
var path2 = XFS.Path(path);
fileSystem.AddDirectory(path2);
fileSystem.FileExists(path2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert on return value here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, assert added

using XFS = MockUnixSupport;

[TestFixture]
public class StringExtensions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add Tests suffix?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure


if (MockUnixSupport.IsUnixPlatform()
&& (path[0] == Path.DirectorySeparatorChar || path[0] == Path.AltDirectorySeparatorChar)
&& trimmed == "")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string.Empty?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, I prefer "" to string.Empty. 2 chars vs 12.

@fgreinacher
Copy link
Contributor

fgreinacher commented Jul 16, 2018

@jpreese for a last pair of eyes 👀

Used WindowsOnly on existing tests
@rkoeninger
Copy link
Contributor Author

I had copy/paste/modified the MockFileInfo tests for Copy/Move over to MockFile because I thought they were missing, but just noticed while looking at the next issue that they already existed in MockFileCopyTests.cs and MockFileMoveTests.cs.

Minor improvement would be to name the files like MockFile.Copy.cs so they get sorted in proper alpha order. Or in nested classes, not sure what the best approach would be.

fileSystem.AddFile(additionalFilePath, new MockFileData(string.Empty));
fileSystem.AddFile(XFS.Path(@"c:\a\a\c.gifx.xyz"), new MockFileData(string.Empty));
fileSystem.AddFile(XFS.Path(@"c:\a\a\c.gifx\xyz"), new MockFileData(string.Empty));
fileSystem.AddFile(XFS.Path(@"c:\a\a\c.gifz\xyz"), new MockFileData(string.Empty));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we change the test data for this?

Copy link
Contributor Author

@rkoeninger rkoeninger Jul 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That test depended on the ability to have a file and directory with the same name, perhaps unintentionally (?) But that's no longer allowed, per this PR. Specific commit: 9fad978

}

[Test]
[WindowsOnly(WindowsSpecifics.StrictPathRules + "; Path.GetInvalidChars() does not return anything on Mono")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the StrictPathRules const is good enough here (and the others)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'll cut of the rest.

@jpreese
Copy link
Member

jpreese commented Jul 16, 2018

Well, I started a review but then realized this PR is pretty large.. and I'm a little uneasy with how many tests were changing. It's going to take me a bit to look this over.

@rkoeninger
Copy link
Contributor Author

@jpreese @fgreinacher I understand if the size of this PR is discomforting, but it's been 6 weeks and I've had to back merge 6 times. If we're not going to merge it soon, it will likely never get merged and we might as well close it. Same for #327.

I don't want to throw away my work, but there's a point where I'd rather just not be hanging.

Copy link
Contributor

@fgreinacher fgreinacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t like that we have to adapt so many tests, but all of the adaptations seem to be OK to me.

@fgreinacher
Copy link
Contributor

fgreinacher commented Aug 27, 2018

Sorry @rkoeninger and thanks for the trigger :) @jpreese I’m fine merging this as it simplifies and fixes several things.

@fgreinacher
Copy link
Contributor

@jpreese :shipit: ?

@rkoeninger
Copy link
Contributor Author

@fgreinacher @jpreese 🚢 ?

@fgreinacher
Copy link
Contributor

OK, I’m gonna merge this now - we have no negative feedback except the amount of tests this impacts - but as I mentioned above all the changes look unproblematic to me.

Thanks again for working on this @rkoeninger!

@fgreinacher fgreinacher merged commit 55a82b0 into TestableIO:master Sep 19, 2018
@rkoeninger
Copy link
Contributor Author

@fgreinacher No prob, thanks for getting this merged

@rkoeninger rkoeninger deleted the remove-trailing-slashes branch December 1, 2018 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants