Skip to content

Commit

Permalink
Improve abstraction by introducing MagicSequenace to wrap magic bytes…
Browse files Browse the repository at this point in the history
… logic. Add support for Webp. Refactor example apps
  • Loading branch information
ajmitev committed Oct 29, 2022
1 parent f446318 commit 82f6bf0
Show file tree
Hide file tree
Showing 29 changed files with 307 additions and 176 deletions.
140 changes: 70 additions & 70 deletions FileTypeChecker.Tests/FIleTypeValidatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@
{
using System;
using System.IO;
using System.Threading.Tasks;
using FileTypeChecker.Abstracts;
using FileTypeChecker.Exceptions;
using FileTypeChecker.Types;
using NUnit.Framework;

[TestFixture]
public class FileTypeValidatorTests
{
private const string FilesPath = "./files/";

[Test]
public void IsTypeRecognizable_ShouldThrowArgumentNullExceptionIfStreamIsNull()
=> Assert.Catch<ArgumentNullException>(() => FileTypeValidator.IsTypeRecognizable(null));

[Test]
public void IsTypeRecognizable_ShouldReturnFalseIfFormatIsUnknown()
{
using var fileStream = File.OpenRead("./files/test");
using var fileStream = File.OpenRead(Path.Combine(FilesPath, "test"));

var expected = false;

Expand All @@ -27,28 +29,29 @@ public void IsTypeRecognizable_ShouldReturnFalseIfFormatIsUnknown()
}

[Test]
[TestCase("./files/test.bmp")]
[TestCase("./files/test.jpg")]
[TestCase("./files/test.png")]
[TestCase("./files/test.gif")]
[TestCase("./files/test.tif")]
[TestCase("./files/test.psd")]
[TestCase("./files/test.pdf")]
[TestCase("./files/test.doc")]
[TestCase("./files/test.xml")]
[TestCase("./files/test.zip")]
[TestCase("./files/test.7z")]
[TestCase("./files/test.bz2")]
[TestCase("./files/test.gz")]
[TestCase("./files/test-bom.xml")]
[TestCase("./files/blob.mp3")]
[TestCase("./files/test.wmf")]
[TestCase("./files/test.ico")]
[TestCase("./files/365-doc.docx")]
[TestCase("./files/testwin10.zip")]
[TestCase("test.bmp")]
[TestCase("test.jpg")]
[TestCase("test.png")]
[TestCase("test.gif")]
[TestCase("test.tif")]
[TestCase("test.psd")]
[TestCase("test.pdf")]
[TestCase("test.doc")]
[TestCase("test.xml")]
[TestCase("test.zip")]
[TestCase("test.7z")]
[TestCase("test.bz2")]
[TestCase("test.gz")]
[TestCase("test-bom.xml")]
[TestCase("blob.mp3")]
[TestCase("test.wmf")]
[TestCase("test.ico")]
[TestCase("365-doc.docx")]
[TestCase("testwin10.zip")]
[TestCase("test.webp")]
public void IsTypeRecognizable_ShouldReturnTrueIfFileIsRecognized(string filePath)
{
using var fileStream = File.OpenRead(filePath);
using var fileStream = File.OpenRead(Path.Combine(FilesPath, filePath));

var expected = true;

Expand All @@ -58,71 +61,68 @@ public void IsTypeRecognizable_ShouldReturnTrueIfFileIsRecognized(string filePat
}

[Test]
[TestCase("./files/test.bmp", Bitmap.TypeExtension)]
[TestCase("./files/test.jpg", JointPhotographicExpertsGroup.TypeExtension)]
[TestCase("./files/test.png", PortableNetworkGraphic.TypeExtension)]
[TestCase("./files/test.gif", GraphicsInterchangeFormat87.TypeExtension)]
[TestCase("./files/test.tif", TaggedImageFileFormat.TypeExtension)]
[TestCase("./files/test.psd", PhotoshopDocumentFile.TypeExtension)]
[TestCase("./files/test.pdf", PortableDocumentFormat.TypeExtension)]
[TestCase("./files/test.doc", MicrosoftOfficeDocument.TypeExtension)]
[TestCase("./files/test.xml", ExtensibleMarkupLanguage.TypeExtension)]
[TestCase("./files/test.zip", ZipFile.TypeExtension)]
[TestCase("./files/test.7z", SevenZipFile.TypeExtension)]
[TestCase("./files/test.bz2", BZip2File.TypeExtension)]
[TestCase("./files/test.gz", Gzip.TypeExtension)]
[TestCase("./files/blob.mp3", Mp3.TypeExtension)]
[TestCase("./files/test.wmf", WindowsMetaFileType.TypeExtension)]
[TestCase("./files/test.ico", Icon.TypeExtension)]
[TestCase("./files/365-doc.docx", MicrosoftOffice365Document.TypeExtension)]
[TestCase("./files/testwin10.zip", ZipFile.TypeExtension)]
[TestCase("test.bmp", Bitmap.TypeExtension)]
[TestCase("test.jpg", JointPhotographicExpertsGroup.TypeExtension)]
[TestCase("test.png", PortableNetworkGraphic.TypeExtension)]
[TestCase("test.gif", GraphicsInterchangeFormat87.TypeExtension)]
[TestCase("test.tif", TaggedImageFileFormat.TypeExtension)]
[TestCase("test.psd", PhotoshopDocumentFile.TypeExtension)]
[TestCase("test.pdf", PortableDocumentFormat.TypeExtension)]
[TestCase("test.doc", MicrosoftOfficeDocument.TypeExtension)]
[TestCase("test.xml", ExtensibleMarkupLanguage.TypeExtension)]
[TestCase("test.zip", ZipFile.TypeExtension)]
[TestCase("test.7z", SevenZipFile.TypeExtension)]
[TestCase("test.bz2", BZip2File.TypeExtension)]
[TestCase("test.gz", Gzip.TypeExtension)]
[TestCase("blob.mp3", Mp3.TypeExtension)]
[TestCase("test.wmf", WindowsMetaFileType.TypeExtension)]
[TestCase("test.ico", Icon.TypeExtension)]
[TestCase("365-doc.docx", MicrosoftOffice365Document.TypeExtension)]
[TestCase("testwin10.zip", ZipFile.TypeExtension)]
[TestCase("test.webp", Webp.TypeExtension)]
public void GetFileType_ShouldReturnFileExtension(string filePath, string expectedFileExtension)
{
using var fileStream = File.OpenRead(filePath);
using var fileStream = File.OpenRead(Path.Combine(FilesPath, filePath));

var actualFileTypeExtension = FileTypeValidator.GetFileType(fileStream).Extension;

Assert.AreEqual(expectedFileExtension, actualFileTypeExtension);
}

[Test]
[TestCase("./files/test.bmp", Bitmap.TypeName)]
[TestCase("./files/test.jpg", JointPhotographicExpertsGroup.TypeName)]
[TestCase("./files/test.png", PortableNetworkGraphic.TypeName)]
[TestCase("./files/test.gif", GraphicsInterchangeFormat89.TypeName)]
[TestCase("./files/test.tif", TaggedImageFileFormat.TypeName)]
[TestCase("./files/test.psd", PhotoshopDocumentFile.TypeName)]
[TestCase("./files/test.pdf", PortableDocumentFormat.TypeName)]
[TestCase("./files/test.doc", MicrosoftOfficeDocument.TypeName)]
[TestCase("./files/test.xml", ExtensibleMarkupLanguage.TypeName)]
[TestCase("./files/test.zip", ZipFile.TypeName)]
[TestCase("./files/test.7z", SevenZipFile.TypeName)]
[TestCase("./files/test.bz2", BZip2File.TypeName)]
[TestCase("./files/test.gz", Gzip.TypeName)]
[TestCase("./files/blob.mp3", Mp3.TypeName)]
[TestCase("./files/test.wmf", WindowsMetaFileType.TypeName)]
[TestCase("./files/test.ico", Icon.TypeName)]
[TestCase("./files/365-doc.docx", MicrosoftOffice365Document.TypeName)]
[TestCase("./files/testwin10.zip", ZipFile.TypeName)]
[TestCase("test.bmp", Bitmap.TypeName)]
[TestCase("test.jpg", JointPhotographicExpertsGroup.TypeName)]
[TestCase("test.png", PortableNetworkGraphic.TypeName)]
[TestCase("test.gif", GraphicsInterchangeFormat89.TypeName)]
[TestCase("test.tif", TaggedImageFileFormat.TypeName)]
[TestCase("test.psd", PhotoshopDocumentFile.TypeName)]
[TestCase("test.pdf", PortableDocumentFormat.TypeName)]
[TestCase("test.doc", MicrosoftOfficeDocument.TypeName)]
[TestCase("test.xml", ExtensibleMarkupLanguage.TypeName)]
[TestCase("test.zip", ZipFile.TypeName)]
[TestCase("test.7z", SevenZipFile.TypeName)]
[TestCase("test.bz2", BZip2File.TypeName)]
[TestCase("test.gz", Gzip.TypeName)]
[TestCase("blob.mp3", Mp3.TypeName)]
[TestCase("test.wmf", WindowsMetaFileType.TypeName)]
[TestCase("test.ico", Icon.TypeName)]
[TestCase("365-doc.docx", MicrosoftOffice365Document.TypeName)]
[TestCase("testwin10.zip", ZipFile.TypeName)]
[TestCase("test.webp", Webp.TypeName)]
public void GetFileType_ShouldReturnFileName(string filePath, string expectedFileTypeName)
{
using var fileStream = File.OpenRead(filePath);
using var fileStream = File.OpenRead(Path.Combine(FilesPath, filePath));

var actualFileTypeName = FileTypeValidator.GetFileType(fileStream).Name;

Assert.AreEqual(expectedFileTypeName, actualFileTypeName);
}

[Test]
public void GetFileType_ShouldReturnNullIfTheTypeIsUnknown()
public void GetFileType_ShouldThrowTypeNotFoundExceptionWhenTypeIsNotRegistered()
{
using var fileStream = File.OpenRead("./files/test");

IFileType expected = null;

var actual = FileTypeValidator.GetFileType(fileStream);

Assert.AreEqual(expected, actual);
using var fileStream = File.OpenRead(Path.Combine(FilesPath, "test"));
Assert.Throws<TypeNotFoundException>(() => FileTypeValidator.GetFileType(fileStream));
}

[Test]
Expand All @@ -136,7 +136,7 @@ public void Is_ShouldThrowExceptionIfStreamIsNull()
[Test]
public void Is_ShouldReturnTrueIfTheTypesMatch()
{
using var fileStream = File.OpenRead("./files/test.bmp");
using var fileStream = File.OpenRead(Path.Combine(FilesPath, "test.bmp"));
var expected = true;
var actual = FileTypeValidator.Is<Bitmap>(fileStream);

Expand All @@ -146,7 +146,7 @@ public void Is_ShouldReturnTrueIfTheTypesMatch()
[Test]
public void Is_ShouldReturnFalseIfTypesDidNotMatch()
{
using var fileStream = File.OpenRead("./files/test.bmp");
using var fileStream = File.OpenRead(Path.Combine(FilesPath, "test.bmp"));
var expected = false;
var actual = FileTypeValidator.Is<Gzip>(fileStream);

Expand Down
11 changes: 7 additions & 4 deletions FileTypeChecker.Tests/FileTypeChecker.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net6.0</TargetFramework>

<IsPackable>false</IsPackable>

<LangVersion>8.0</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="nunit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
</ItemGroup>

<ItemGroup>
Expand Down Expand Up @@ -76,6 +76,9 @@
<None Update="Files\test.tif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="files\test.webp">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Files\test.wmf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
32 changes: 32 additions & 0 deletions FileTypeChecker.Tests/MagicSequenceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace FileTypeChecker.Tests
{
using NUnit.Framework;

[TestFixture]
public class MagicSequenceTests
{
[Test]
[TestCase(new byte[] { 0x49, 0x44, 0x33 }, new byte[] { 0x49, 0x44, 0x33 }, 3)]
[TestCase(new byte[] { 0x49, 0x44, 0x33, 0x44 }, new byte[] { 0x49, 0x44, 0x33 }, 3)]
[TestCase(new byte[] { 0x49, 0x44, 0x33, 0x44 }, new byte[] { 0x44, 0x49, 0x44, 0x33 }, 0)]
[TestCase(new byte[] { 0x44, 0x49, 0x44, 0x33, 0x44 }, new byte[] { 0x49, 0x44, 0x33 }, 0)]
public void CountMatchingBytesShouldReturnNumbersOfMachtingBytes(byte[] magicBytes, byte[] compareBytes, int matching)
{
var sequence = new MagicSequence(magicBytes);
var actual = sequence.CountMatchingBytes(compareBytes);

Assert.AreEqual(matching, actual);
}

[Test]
[TestCase(new byte[] { 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38 }, new byte[] { 0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 0x56, 0x50, 0x38 }, 11, 4, 5)]
public void CountMatchingBytesShouldReturnNumbersOfMachtingBytesWhenThereIsSkipInTheMiddle(byte[] magicBytes, byte[] compareBytes, int matching, int bytesToSkip, int startFrom)
{
var sequence = new MagicSequence(magicBytes, bytesToSkip, startFrom);
var actual = sequence.CountMatchingBytes(compareBytes);

Assert.AreEqual(matching, actual);
}

}
}
Binary file added FileTypeChecker.Tests/files/test.webp
Binary file not shown.
10 changes: 2 additions & 8 deletions FileTypeChecker.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29318.209
# Visual Studio Version 17
VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTypeChecker", "FileTypeChecker\FileTypeChecker.csproj", "{3508F73C-16CA-46E2-9BAA-77B21B99AE5A}"
EndProject
Expand All @@ -13,8 +13,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTypeChecker.App", "Samp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTypeChecker.App.MyCustomTypes", "Samples\FileTypeChecker.App.MyCustomTypes\FileTypeChecker.App.MyCustomTypes.csproj", "{2C49FF06-90FF-442B-8757-210521AB22EE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileTypeChecker.Common", "FileTypeChecker.Common\FileTypeChecker.Common.csproj", "{C4706C8E-30D1-4CEB-827E-4D4EBB253E6B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -37,10 +35,6 @@ Global
{2C49FF06-90FF-442B-8757-210521AB22EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C49FF06-90FF-442B-8757-210521AB22EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C49FF06-90FF-442B-8757-210521AB22EE}.Release|Any CPU.Build.0 = Release|Any CPU
{C4706C8E-30D1-4CEB-827E-4D4EBB253E6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4706C8E-30D1-4CEB-827E-4D4EBB253E6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4706C8E-30D1-4CEB-827E-4D4EBB253E6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4706C8E-30D1-4CEB-827E-4D4EBB253E6B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 82f6bf0

Please sign in to comment.