Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TheVerifiedValue
24 changes: 24 additions & 0 deletions src/Verify.Tests/Comparer/HandleStreamTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// A FileStream built from a handle may have no usable Name: .NET Framework reports
// "[Unknown]", and modern .NET falls back to that when the path cannot be resolved
// from the handle. The New path already copes, so only a mismatch exercised it.
public class HandleStreamTests
{
[Fact]
public async Task Mismatch()
{
using var directory = new TempDirectory();
var path = directory.BuildPath("source.txt");
File.WriteAllText(path, "TheReceivedValue");

using var source = File.OpenRead(path);
using var stream = new FileStream(source.SafeFileHandle, FileAccess.Read);

var settings = new VerifySettings();
settings.DisableDiff();

await Assert.ThrowsAsync<VerifyException>(() => Verify(stream, "bin", settings));

var received = CurrentFile.Relative($"HandleStreamTests.Mismatch.{Namer.RuntimeAndVersion}.received.bin");
Assert.Equal("TheReceivedValue", File.ReadAllText(received));
}
}
5 changes: 4 additions & 1 deletion src/Verify/Compare/FileComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ static async Task<EqualityResult> InnerCompare(FilePair file, Stream receivedStr
return new(Equality.Equal, compareResult.Message, null, null);
}

IoHelpers.CopyFile(fileStream.Name, file.ReceivedPath);
// Not CopyFile(fileStream.Name): a FileStream built from a handle has no
// usable Name. WriteStream keeps the copy-by-path fast path and falls back
// to the handle, which is what the New and empty paths above already do.
await IoHelpers.WriteStream(file.ReceivedPath, fileStream);
return new(Equality.NotEqual, compareResult.Message, null, null);
}

Expand Down
2 changes: 1 addition & 1 deletion src/todo.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ All six resolved 2026-08-16 (five fixed here; the inline item resolved as by-des
- [ ] **Negative sub-hour offsets render unsigned.**
`Verify/Serialization/DateFormatter_DateTimeOffset.cs:74-82` — `TimeSpan.FromMinutes(-30)` renders `0-30` (positive twin is `+0-30`). No real timezone in that range; constructed offsets only.

- [ ] **Mismatch crash for handle-based `FileStream` received streams.**
- [x] **Mismatch crash for handle-based `FileStream` received streams.**
`Verify/Compare/FileComparer.cs:50` — NotEqual fast path copies by `fileStream.Name` with no fallback; handle-based streams have `Name == "[Unknown]"`. First (New) run succeeds via the guarded `IoHelpers.WriteStream` path; later mismatches throw the generic "Failed to compare files".

- [ ] **`PrefixUnique` set is case-sensitive on case-insensitive filesystems.**
Expand Down
Loading