Skip to content

Commit

Permalink
refactor tests to provide details on failure
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel committed Nov 19, 2021
1 parent 64a8cb7 commit a7af855
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 126 deletions.
1 change: 0 additions & 1 deletion test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ICSharpCode.SharpZipLib.Tests.TestSupport
Expand Down
111 changes: 84 additions & 27 deletions test/ICSharpCode.SharpZipLib.Tests/TestSupport/ZipTesting.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using ICSharpCode.SharpZipLib.Zip;
using System.IO;
using NUnit.Framework.Constraints;
using NUnit.Framework;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace ICSharpCode.SharpZipLib.Tests.TestSupport
{
Expand All @@ -12,7 +14,13 @@ internal static class ZipTesting
{
public static void AssertValidZip(Stream stream, string password = null, bool usesAes = true)
{
Assert.That(TestArchive(stream, password), "Archive did not pass ZipFile.TestArchive");
using var zipFile = new ZipFile(stream)
{
IsStreamOwner = false,
Password = password,
};

Assert.That(zipFile, Does.PassTestArchive());

if (!string.IsNullOrEmpty(password) && usesAes)
{
Expand All @@ -30,37 +38,86 @@ public static void AssertValidZip(Stream stream, string password = null, bool us
}
}, "Archive could not be read by ZipInputStream");
}
}

public class TestArchiveReport
{
internal const string PassingArchive = "Passing Archive";

readonly List<string> _messages = new List<string>();
public void HandleTestResults(TestStatus status, string message)
{
if (string.IsNullOrWhiteSpace(message)) return;
_messages.Add(message);
}

/// <summary>
/// Tests the archive.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="password">The password.</param>
/// <returns></returns>
public static bool TestArchive(byte[] data, string password = null)
public override string ToString() => _messages.Any() ? string.Join(", ", _messages) : PassingArchive;
}

public class PassesTestArchiveConstraint : Constraint
{
private readonly string _password;
private readonly bool _testData;

public PassesTestArchiveConstraint(string password = null, bool testData = true)
{
using var ms = new MemoryStream(data);
return TestArchive(new MemoryStream(data), password);
_password = password;
_testData = testData;
}

/// <summary>
/// Tests the archive.
/// </summary>
/// <param name="stream">The data.</param>
/// <param name="password">The password.</param>
/// <returns>true if archive tests ok; false otherwise.</returns>
public static bool TestArchive(Stream stream, string password = null)
public override string Description => TestArchiveReport.PassingArchive;

public override ConstraintResult ApplyTo<TActual>(TActual actual)
{
using var zipFile = new ZipFile(stream)
MemoryStream ms = null;
try
{
IsStreamOwner = false,
Password = password,
};

return zipFile.TestArchive(true, TestStrategy.FindAllErrors, (status, message) =>
if (!(actual is ZipFile zipFile))
{
if (!(actual is byte[] rawArchive))
{
return new ConstraintResult(this, actual, ConstraintStatus.Failure);
}

ms = new MemoryStream(rawArchive);
zipFile = new ZipFile(ms){Password = _password};
}

var report = new TestArchiveReport();

return new ConstraintResult(
this, report, zipFile.TestArchive(
_testData,
TestStrategy.FindAllErrors,
report.HandleTestResults
)
? ConstraintStatus.Success
: ConstraintStatus.Failure);
}
finally
{
if (!string.IsNullOrWhiteSpace(message)) TestContext.Out.WriteLine(message);
});
ms?.Dispose();
}
}
}

public static class ZipTestingConstraintExtensions
{
public static IResolveConstraint PassTestArchive(this ConstraintExpression expression, string password = null, bool testData = true)
{
var constraint = new PassesTestArchiveConstraint(password, testData);
expression.Append(constraint);
return constraint;
}
}

/// <inheritdoc />
public class Does: NUnit.Framework.Does
{
public static IResolveConstraint PassTestArchive(string password = null, bool testData = true)
=> new PassesTestArchiveConstraint(password, testData);

public static IResolveConstraint PassTestArchive(bool testData)
=> new PassesTestArchiveConstraint(password: null, testData);
}
}
65 changes: 33 additions & 32 deletions test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.IO;
using System.Linq;
using System.Text;
using Does = ICSharpCode.SharpZipLib.Tests.TestSupport.Does;
using TimeSetting = ICSharpCode.SharpZipLib.Zip.ZipEntryFactory.TimeSetting;

namespace ICSharpCode.SharpZipLib.Tests.Zip
Expand Down Expand Up @@ -40,7 +41,7 @@ public void Basics()
ZipEntry entry = zf[0];
Assert.AreEqual(tempName1, entry.Name);
Assert.AreEqual(1, entry.Size);
Assert.IsTrue(zf.TestArchive(true));
Assert.That(zf, Does.PassTestArchive());

zf.Close();
}
Expand Down Expand Up @@ -128,7 +129,7 @@ public void CreateEmptyDirectories(string password)
var folderEntry = zipFile.GetEntry("floyd/");
Assert.That(folderEntry.IsDirectory, Is.True, "The entry must be a folder");

Assert.IsTrue(zipFile.TestArchive(testData: true));
Assert.That(zipFile, Does.PassTestArchive());
}
}
}
Expand Down Expand Up @@ -166,14 +167,15 @@ public void ContentEqualAfterAfterArchived([Values(0, 1, 64)]int contentSize)
public void Encryption(ZipEncryptionMethod encryptionMethod)
{
const string tempName1 = "a.dat";
const int tempSize = 1;

var target = new MemoryStream();

string tempFilePath = GetTempFilePath();
Assert.IsNotNull(tempFilePath, "No permission to execute this test?");

string addFile = Path.Combine(tempFilePath, tempName1);
MakeTempFile(addFile, 1);
MakeTempFile(addFile, tempSize);

try
{
Expand All @@ -189,17 +191,13 @@ public void Encryption(ZipEncryptionMethod encryptionMethod)
using (ZipFile zf = new ZipFile(archive))
{
zf.Password = "Ahoy";
Assert.AreEqual(1, zf.Count);
ZipEntry entry = zf[0];
Assert.AreEqual(tempName1, entry.Name);
Assert.AreEqual(1, entry.Size);
Assert.IsTrue(zf.TestArchive(true, TestStrategy.FindFirstError, (status, message) =>
{
if(!string.IsNullOrEmpty(message)) {
Console.WriteLine($"{message} ({status.Entry?.Name ?? "-"})");
}
}));
Assert.IsTrue(entry.IsCrypted);
Assert.That(zf.Count, Is.EqualTo(1));
var entry = zf[0];
Assert.That(entry.Name, Is.EqualTo(tempName1));
Assert.That(entry.Size, Is.EqualTo(tempSize));
Assert.That(entry.IsCrypted);

Assert.That(zf, Does.PassTestArchive());

switch (encryptionMethod)
{
Expand Down Expand Up @@ -363,14 +361,15 @@ public void ExtractExceptions()
public void ReadingOfLockedDataFiles()
{
const string tempName1 = "a.dat";
const int tempSize = 1;

var target = new MemoryStream();

string tempFilePath = GetTempFilePath();
Assert.IsNotNull(tempFilePath, "No permission to execute this test?");

string addFile = Path.Combine(tempFilePath, tempName1);
MakeTempFile(addFile, 1);
MakeTempFile(addFile, tempSize);

try
{
Expand All @@ -383,11 +382,11 @@ public void ReadingOfLockedDataFiles()
var archive = new MemoryStream(target.ToArray());
using (ZipFile zf = new ZipFile(archive))
{
Assert.AreEqual(1, zf.Count);
ZipEntry entry = zf[0];
Assert.AreEqual(tempName1, entry.Name);
Assert.AreEqual(1, entry.Size);
Assert.IsTrue(zf.TestArchive(true));
Assert.That(zf.Count, Is.EqualTo(1));
var entry = zf[0];
Assert.That(entry.Name, Is.EqualTo(tempName1));
Assert.That(entry.Size, Is.EqualTo(tempSize));
Assert.That(zf, Does.PassTestArchive());

zf.Close();
}
Expand All @@ -404,14 +403,15 @@ public void ReadingOfLockedDataFiles()
public void NonAsciiPasswords()
{
const string tempName1 = "a.dat";
const int tempSize = 1;

var target = new MemoryStream();

string tempFilePath = GetTempFilePath();
Assert.IsNotNull(tempFilePath, "No permission to execute this test?");

string addFile = Path.Combine(tempFilePath, tempName1);
MakeTempFile(addFile, 1);
MakeTempFile(addFile, tempSize);

string password = "abc\u0066\u0393";
try
Expand All @@ -425,12 +425,12 @@ public void NonAsciiPasswords()
using (ZipFile zf = new ZipFile(archive))
{
zf.Password = password;
Assert.AreEqual(1, zf.Count);
ZipEntry entry = zf[0];
Assert.AreEqual(tempName1, entry.Name);
Assert.AreEqual(1, entry.Size);
Assert.IsTrue(zf.TestArchive(true));
Assert.IsTrue(entry.IsCrypted);
Assert.That(zf.Count, Is.EqualTo(1));
var entry = zf[0];
Assert.That(entry.Name, Is.EqualTo(tempName1));
Assert.That(entry.Size, Is.EqualTo(tempSize));
Assert.That(zf, Does.PassTestArchive());
Assert.That(entry.IsCrypted);
}
}
finally
Expand Down Expand Up @@ -636,10 +636,11 @@ public void SetDirectoryModifiedDate()
public void CreateZipShouldLeaveOutputStreamOpenIfRequested(bool leaveOpen)
{
const string tempFileName = "a(2).dat";
const int tempSize = 16;

using var tempFolder = Utils.GetTempDir();
// Create test input file
tempFolder.CreateDummyFile(tempFileName, size: 16);
tempFolder.CreateDummyFile(tempFileName, tempSize);

// Create the zip with fast zip
var target = new TrackedMemoryStream();
Expand All @@ -653,11 +654,11 @@ public void CreateZipShouldLeaveOutputStreamOpenIfRequested(bool leaveOpen)
// Check that the file contents are correct in both cases
var archive = new MemoryStream(target.ToArray());
using var zf = new ZipFile(archive);
Assert.AreEqual(expected: 1, zf.Count);
Assert.That(zf.Count, Is.EqualTo(1));
var entry = zf[0];
Assert.AreEqual(tempFileName, entry.Name);
Assert.AreEqual(expected: 16, entry.Size);
Assert.IsTrue(zf.TestArchive(testData: true));
Assert.That(entry.Name, Is.EqualTo(tempFileName));
Assert.That(entry.Size, Is.EqualTo(tempSize));
Assert.That(zf, Does.PassTestArchive());
}

[Category("Zip")]
Expand Down
Loading

0 comments on commit a7af855

Please sign in to comment.