Even better objects #39
@ -18,6 +18,8 @@ dotnet_analyzer_diagnostic.category-Usage.severity = warning
|
||||
|
||||
dotnet_diagnostic.IDE0010.severity = none
|
||||
dotnet_diagnostic.IDE0072.severity = none
|
||||
dotnet_diagnostic.CA1707.severity = none
|
||||
dotnet_diagnostic.CA1861.severity = none
|
||||
|
||||
#### Core EditorConfig Options ####
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract factory of test data.
|
||||
/// </summary>
|
||||
/// <typeparam name="TTestData">Type of test data.</typeparam>
|
||||
public abstract class AbstractTestDataFactory<TTestData>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AbstractTestDataFactory{TTestData}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="dataDirectory">Directory with test files.</param>
|
||||
/// <param name="testFilenameConvention">A convention used to filter test files.</param>
|
||||
protected AbstractTestDataFactory(string dataDirectory, ITestFilenameConvention testFilenameConvention)
|
||||
{
|
||||
DataDirectory = dataDirectory;
|
||||
TestFilenameConvention = testFilenameConvention;
|
||||
}
|
||||
|
||||
private string DataDirectory { get; }
|
||||
|
||||
private ITestFilenameConvention TestFilenameConvention { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get test data set by name.
|
||||
/// </summary>
|
||||
/// <param name="dataSet">Name of the data set.</param>
|
||||
/// <returns>Test data.</returns>
|
||||
public TTestData this[string dataSet] =>
|
||||
ReadTestData(FixPath(TestFilenameConvention.ConvertTestNameToFilename(dataSet)));
|
||||
|
||||
/// <summary>
|
||||
/// Get a sequence of all test data sets in the factory.
|
||||
/// </summary>
|
||||
/// <returns>A sequence of data sets.</returns>
|
||||
public IEnumerable<TTestData> GetAllTestData()
|
||||
{
|
||||
var files = Directory.EnumerateFiles(DataDirectory).Where(TestFilenameConvention.FilterFile);
|
||||
foreach (var filename in files)
|
||||
{
|
||||
yield return ReadTestData(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read test data from a stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">Input stream.</param>
|
||||
/// <returns>Test data.</returns>
|
||||
protected abstract TTestData ReadDataFromStream(Stream stream);
|
||||
|
||||
private string FixPath(string filename) => Path.Combine(DataDirectory, filename);
|
||||
|
||||
private TTestData ReadTestData(string filename)
|
||||
{
|
||||
using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
return ReadDataFromStream(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,50 +17,48 @@ namespace MatFileHandler.Tests
|
||||
/// <summary>
|
||||
/// Test writing various things.
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
/// <param name="bytes">Bytes to write.</param>
|
||||
[Theory]
|
||||
[MemberData(nameof(TestData))]
|
||||
public void Test(Action<Stream> action)
|
||||
public void Test(byte[] bytes)
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
var sut = new ChecksumCalculatingStream(stream);
|
||||
action(sut);
|
||||
sut.Write(bytes, 0, bytes.Length);
|
||||
var actual = sut.GetCrc();
|
||||
var expected = ReferenceCalculation(action);
|
||||
|
||||
var expected = ReferenceCalculation(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test data for <see cref="Test"/>.
|
||||
/// </summary>
|
||||
/// <returns>Test data.</returns>
|
||||
public static IEnumerable<object[]> TestData()
|
||||
public static TheoryData<byte[]> TestData()
|
||||
{
|
||||
foreach (var data in TestData_Typed())
|
||||
var empty = new byte[1234];
|
||||
var nonEmpty = new byte[12345];
|
||||
for (var i = 0; i < 1234; i++)
|
||||
{
|
||||
yield return new object[] { data };
|
||||
nonEmpty[i] = (byte)((i * i) % 256);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<Action<Stream>> TestData_Typed()
|
||||
return new TheoryData<byte[]>()
|
||||
{
|
||||
yield return BinaryWriterAction(w => w.Write(true));
|
||||
yield return BinaryWriterAction(w => w.Write(false));
|
||||
yield return BinaryWriterAction(w => w.Write(byte.MinValue));
|
||||
yield return BinaryWriterAction(w => w.Write(byte.MaxValue));
|
||||
yield return BinaryWriterAction(w => w.Write(short.MinValue));
|
||||
yield return BinaryWriterAction(w => w.Write(short.MaxValue));
|
||||
yield return BinaryWriterAction(w => w.Write(int.MinValue));
|
||||
yield return BinaryWriterAction(w => w.Write(int.MaxValue));
|
||||
yield return BinaryWriterAction(w => w.Write(long.MinValue));
|
||||
yield return BinaryWriterAction(w => w.Write(long.MaxValue));
|
||||
yield return BinaryWriterAction(w => w.Write(decimal.MinValue));
|
||||
yield return BinaryWriterAction(w => w.Write(decimal.MaxValue));
|
||||
yield return BinaryWriterAction(w => w.Write(double.MinValue));
|
||||
yield return BinaryWriterAction(w => w.Write(double.MaxValue));
|
||||
yield return BinaryWriterAction(w => w.Write(double.PositiveInfinity));
|
||||
yield return BinaryWriterAction(w => w.Write(double.NaN));
|
||||
yield return BinaryWriterAction(w => w.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7 }));
|
||||
yield return BinaryWriterAction(w => w.Write(Enumerable.Range(0, 255).SelectMany(x => Enumerable.Range(0, 255)).Select(x => (byte)x).ToArray()));
|
||||
new byte[] { 0x00 },
|
||||
new byte[] { 0x01 },
|
||||
new byte[] { 0xff },
|
||||
new byte[] { 0xff, 0xff },
|
||||
new byte[] { 0xff, 0xff, 0xff },
|
||||
new byte[] { 0xff, 0xff, 0xff, 0xff },
|
||||
new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
new byte[] { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
new byte[] { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
|
||||
new byte[] { 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13, 0x17, 0x1d },
|
||||
empty,
|
||||
nonEmpty,
|
||||
};
|
||||
}
|
||||
|
||||
private static Action<Stream> BinaryWriterAction(Action<BinaryWriter> action)
|
||||
@ -72,15 +70,15 @@ namespace MatFileHandler.Tests
|
||||
};
|
||||
}
|
||||
|
||||
private uint ReferenceCalculation(Action<Stream> action)
|
||||
private static uint ReferenceCalculation(byte[] bytes)
|
||||
{
|
||||
using var stream = new MemoryStream();
|
||||
action(stream);
|
||||
stream.Write(bytes, 0, bytes.Length);
|
||||
stream.Position = 0;
|
||||
return CalculateAdler32Checksum(stream);
|
||||
}
|
||||
|
||||
private static uint CalculateAdler32Checksum(Stream stream)
|
||||
private static uint CalculateAdler32Checksum(MemoryStream stream)
|
||||
{
|
||||
uint s1 = 1;
|
||||
uint s2 = 0;
|
||||
|
@ -1,43 +0,0 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// A filename convention based on file extensions.
|
||||
/// </summary>
|
||||
internal sealed class ExtensionTestFilenameConvention : ITestFilenameConvention
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ExtensionTestFilenameConvention"/> class.
|
||||
/// </summary>
|
||||
/// <param name="extension">File extension.</param>
|
||||
public ExtensionTestFilenameConvention(string extension)
|
||||
{
|
||||
Extension = extension;
|
||||
}
|
||||
|
||||
private string Extension { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Convert test name to filename by adding the extension.
|
||||
/// </summary>
|
||||
/// <param name="testName">Test name.</param>
|
||||
/// <returns>The corresponding filename.</returns>
|
||||
public string ConvertTestNameToFilename(string testName)
|
||||
{
|
||||
return Path.ChangeExtension(testName, Extension);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compare file's extension to the one specified during initialization.
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename.</param>
|
||||
/// <returns>True iff the file has the extension stored in the class.</returns>
|
||||
public bool FilterFile(string filename)
|
||||
{
|
||||
return Path.GetExtension(filename) == "." + Extension;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface for handling filtering tests based on filenames.
|
||||
/// </summary>
|
||||
public interface ITestFilenameConvention
|
||||
{
|
||||
/// <summary>
|
||||
/// Convert test name to a filename (e.g., by adding an appropriate extension).
|
||||
/// </summary>
|
||||
/// <param name="testName">Name of a test.</param>
|
||||
/// <returns>Filename.</returns>
|
||||
string ConvertTestNameToFilename(string testName);
|
||||
|
||||
/// <summary>
|
||||
/// Decide if a file contains a test based on the filename.
|
||||
/// </summary>
|
||||
/// <param name="filename">A filename.</param>
|
||||
/// <returns>True iff the file should contain a test.</returns>
|
||||
bool FilterFile(string filename);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
@ -19,9 +20,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading all files in a given test set.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestReader(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestReader(MatFileReadingMethod method)
|
||||
{
|
||||
foreach (var matFile in testFactory.GetAllTestData())
|
||||
foreach (var matFile in ReadAllTestFiles(method))
|
||||
{
|
||||
Assert.NotEmpty(matFile.Variables);
|
||||
}
|
||||
@ -31,9 +32,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading lower and upper limits of integer data types.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestLimits(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestLimits(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["limits"];
|
||||
var matFile = ReadTestFile("limits", method);
|
||||
IArray array;
|
||||
array = matFile["int8_"].Value;
|
||||
CheckLimits(array as IArrayOf<sbyte>, CommonData.Int8Limits);
|
||||
@ -65,9 +66,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test writing lower and upper limits of integer-based complex data types.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestComplexLimits(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestComplexLimits(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["limits_complex"];
|
||||
var matFile = ReadTestFile("limits_complex", method);
|
||||
IArray array;
|
||||
array = matFile["int8_complex"].Value;
|
||||
CheckComplexLimits(array as IArrayOf<ComplexOf<sbyte>>, CommonData.Int8Limits);
|
||||
@ -101,9 +102,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading an ASCII-encoded string.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestAscii(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestAscii(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["ascii"];
|
||||
var matFile = ReadTestFile("ascii", method);
|
||||
var arrayAscii = matFile["s"].Value as ICharArray;
|
||||
Assert.NotNull(arrayAscii);
|
||||
Assert.Equal(new[] { 1, 3 }, arrayAscii.Dimensions);
|
||||
@ -115,9 +116,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a Unicode string.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestUnicode(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestUnicode(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["unicode"];
|
||||
var matFile = ReadTestFile("unicode", method);
|
||||
var arrayUnicode = matFile["s"].Value as ICharArray;
|
||||
Assert.NotNull(arrayUnicode);
|
||||
Assert.Equal(new[] { 1, 2 }, arrayUnicode.Dimensions);
|
||||
@ -130,9 +131,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a wide Unicode string.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestUnicodeWide(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestUnicodeWide(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["unicode-wide"];
|
||||
var matFile = ReadTestFile("unicode-wide", method);
|
||||
var arrayUnicodeWide = matFile["s"].Value as ICharArray;
|
||||
Assert.NotNull(arrayUnicodeWide);
|
||||
Assert.Equal(new[] { 1, 2 }, arrayUnicodeWide.Dimensions);
|
||||
@ -143,9 +144,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test converting a structure array to a Double array.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestConvertToDoubleArray(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestConvertToDoubleArray(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["struct"];
|
||||
var matFile = ReadTestFile("struct", method);
|
||||
var array = matFile.Variables[0].Value;
|
||||
Assert.Null(array.ConvertToDoubleArray());
|
||||
}
|
||||
@ -155,9 +156,9 @@ namespace MatFileHandler.Tests
|
||||
/// </summary>
|
||||
/// <returns>Should return null.</returns>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestConvertToComplexArray(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestConvertToComplexArray(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["struct"];
|
||||
var matFile = ReadTestFile("struct", method);
|
||||
var array = matFile.Variables[0].Value;
|
||||
Assert.Null(array.ConvertToComplexArray());
|
||||
}
|
||||
@ -166,9 +167,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading an enumeration.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestEnum(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestEnum(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["enum"];
|
||||
var matFile = ReadTestFile("enum", method);
|
||||
var days = matFile["days"].Value;
|
||||
var enumeration = new EnumAdapter(days);
|
||||
Assert.Equal(5, enumeration.Values.Count);
|
||||
@ -183,9 +184,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a structure array.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestStruct(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestStruct(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["struct"];
|
||||
var matFile = ReadTestFile("struct", method);
|
||||
var structure = matFile["struct_"].Value as IStructureArray;
|
||||
Assert.NotNull(structure);
|
||||
Assert.Equal(new[] { "x", "y" }, structure.FieldNames);
|
||||
@ -237,9 +238,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a sparse array.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestSparse(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestSparse(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["sparse"];
|
||||
var matFile = ReadTestFile("sparse", method);
|
||||
var sparseArray = matFile["sparse_"].Value as ISparseArrayOf<double>;
|
||||
Assert.NotNull(sparseArray);
|
||||
Assert.Equal(new[] { 4, 5 }, sparseArray.Dimensions);
|
||||
@ -267,9 +268,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a logical array.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestLogical(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestLogical(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["logical"];
|
||||
var matFile = ReadTestFile("logical", method);
|
||||
var array = matFile["logical_"].Value;
|
||||
var logicalArray = array as IArrayOf<bool>;
|
||||
Assert.NotNull(logicalArray);
|
||||
@ -285,9 +286,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a sparse logical array.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestSparseLogical(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestSparseLogical(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["sparse_logical"];
|
||||
var matFile = ReadTestFile("sparse_logical", method);
|
||||
var array = matFile["sparse_logical"].Value;
|
||||
var sparseArray = array as ISparseArrayOf<bool>;
|
||||
Assert.NotNull (sparseArray);
|
||||
@ -304,9 +305,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a global variable.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestGlobal(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestGlobal(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["global"];
|
||||
var matFile = ReadTestFile("global", method);
|
||||
var variable = matFile.Variables.First();
|
||||
Assert.True(variable.IsGlobal);
|
||||
}
|
||||
@ -315,9 +316,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a sparse complex array.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TextSparseComplex(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TextSparseComplex(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["sparse_complex"];
|
||||
var matFile = ReadTestFile("sparse_complex", method);
|
||||
var array = matFile["sparse_complex"].Value;
|
||||
var sparseArray = array as ISparseArrayOf<Complex>;
|
||||
Assert.NotNull(sparseArray);
|
||||
@ -331,9 +332,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading an object.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestObject(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestObject(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["object"];
|
||||
var matFile = ReadTestFile("object", method);
|
||||
var obj = matFile["object_"].Value as IMatObject;
|
||||
Assert.NotNull(obj);
|
||||
Assert.Equal("Point", obj.ClassName);
|
||||
@ -348,9 +349,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading another object.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestObject2(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestObject2(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["object2"];
|
||||
var matFile = ReadTestFile("object2", method);
|
||||
var obj = matFile["object2"].Value as IMatObject;
|
||||
Assert.NotNull(obj);
|
||||
Assert.Equal("Point", obj.ClassName);
|
||||
@ -371,9 +372,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a table.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestTable(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestTable(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["table"];
|
||||
var matFile = ReadTestFile("table", method);
|
||||
var obj = matFile["table_"].Value as IMatObject;
|
||||
var table = new TableAdapter(obj);
|
||||
Assert.Equal(3, table.NumberOfRows);
|
||||
@ -392,9 +393,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a deeply nested table.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestDeepTable(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestDeepTable(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["table-deep"];
|
||||
var matFile = ReadTestFile("table-deep", method);
|
||||
var obj = matFile["t"].Value as IMatObject;
|
||||
var table = new TableAdapter(obj);
|
||||
Assert.Equal(1, table.NumberOfRows);
|
||||
@ -416,9 +417,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test reading a table with strings
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestTableWithStrings(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestTableWithStrings(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["table-with-strings"];
|
||||
var matFile = ReadTestFile("table-with-strings", method);
|
||||
var obj = matFile["t"].Value as IMatObject;
|
||||
var table = new TableAdapter(obj);
|
||||
Assert.Equal(5, table.NumberOfRows);
|
||||
@ -441,9 +442,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test subobjects within objects.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestSubobjects(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestSubobjects(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["pointWithSubpoints"];
|
||||
var matFile = ReadTestFile("pointWithSubpoints", method);
|
||||
var p = matFile["p"].Value as IMatObject;
|
||||
Assert.Equal("Point", p.ClassName);
|
||||
var x = p["x"] as IMatObject;
|
||||
@ -464,9 +465,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test nested objects.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestNestedObjects(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestNestedObjects(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["subsubPoint"];
|
||||
var matFile = ReadTestFile("subsubPoint", method);
|
||||
var p = matFile["p"].Value as IMatObject;
|
||||
Assert.Equal("Point", p.ClassName);
|
||||
Assert.Equal(new[] { 1.0 }, p["x"].ConvertToDoubleArray());
|
||||
@ -482,9 +483,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test datetime objects.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestDatetime(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestDatetime(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["datetime"];
|
||||
var matFile = ReadTestFile("datetime", method);
|
||||
var d = matFile["d"].Value as IMatObject;
|
||||
var datetime = new DatetimeAdapter(d);
|
||||
Assert.Equal(new[] { 1, 2 }, datetime.Dimensions);
|
||||
@ -496,9 +497,9 @@ namespace MatFileHandler.Tests
|
||||
/// Another test for datetime objects.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestDatetime2(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestDatetime2(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["datetime2"];
|
||||
var matFile = ReadTestFile("datetime2", method);
|
||||
var d = matFile["d"].Value as IMatObject;
|
||||
var datetime = new DatetimeAdapter(d);
|
||||
Assert.Equal(new[] { 1, 1 }, datetime.Dimensions);
|
||||
@ -511,9 +512,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test string objects.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestString(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestString(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["string"];
|
||||
var matFile = ReadTestFile("string", method);
|
||||
var s = matFile["s"].Value as IMatObject;
|
||||
var str = new StringAdapter(s);
|
||||
Assert.Equal(new[] { 4, 1 }, str.Dimensions);
|
||||
@ -527,9 +528,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test duration objects.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestDuration(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestDuration(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["duration"];
|
||||
var matFile = ReadTestFile("duration", method);
|
||||
var d = matFile["d"].Value as IMatObject;
|
||||
var duration = new DurationAdapter(d);
|
||||
Assert.Equal(new[] { 1, 3 }, duration.Dimensions);
|
||||
@ -542,9 +543,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test unrepresentable datetime.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void TestDatetime_Unrepresentable(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void TestDatetime_Unrepresentable(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["datetime-unrepresentable"];
|
||||
var matFile = ReadTestFile("datetime-unrepresentable", method);
|
||||
var obj = matFile["d"].Value as IMatObject;
|
||||
var datetime = new DatetimeAdapter(obj);
|
||||
var d0 = datetime[0];
|
||||
@ -555,9 +556,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test 3-dimensional arrays.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void Test_3DArrays(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void Test_3DArrays(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["issue20.mat"];
|
||||
var matFile = ReadTestFile("issue20", method);
|
||||
var obj = matFile["a3d"].Value;
|
||||
var values = obj.ConvertToDoubleArray();
|
||||
Assert.Equal(Enumerable.Range(1, 24).Select(x => (double)x).ToArray(), values);
|
||||
@ -590,9 +591,9 @@ namespace MatFileHandler.Tests
|
||||
/// Test four-dimensional arrays.
|
||||
/// </summary>
|
||||
[Theory, MemberData(nameof(TestDataFactories))]
|
||||
public void Test4DArrays(AbstractTestDataFactory<IMatFile> testFactory)
|
||||
public void Test4DArrays(MatFileReadingMethod method)
|
||||
{
|
||||
var matFile = testFactory["issue20.mat"];
|
||||
var matFile = ReadTestFile("issue20", method);
|
||||
var obj = matFile["a4d"].Value;
|
||||
Assert.Equal(Enumerable.Range(1, 120).Select(x => (double)x).ToArray(), obj.ConvertToDoubleArray());
|
||||
Assert.Null(obj.ConvertTo2dDoubleArray());
|
||||
@ -601,19 +602,36 @@ namespace MatFileHandler.Tests
|
||||
/// <summary>
|
||||
/// Returns the factories that provide test data in various configurations.
|
||||
/// </summary>
|
||||
public static TheoryData<AbstractTestDataFactory<IMatFile>> TestDataFactories
|
||||
public static TheoryData<MatFileReadingMethod> TestDataFactories
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TheoryData<AbstractTestDataFactory<IMatFile>>
|
||||
return new TheoryData<MatFileReadingMethod>
|
||||
{
|
||||
new MatTestDataFactory(Path.Combine(TestDirectory, "good")),
|
||||
new PartialReadMatTestDataFactory(Path.Combine(TestDirectory, "good")),
|
||||
new UnalignedMatTestDataFactory(Path.Combine(TestDirectory, "good")),
|
||||
MatFileReadingMethod.NormalStream,
|
||||
MatFileReadingMethod.PartialStream,
|
||||
MatFileReadingMethod.UnalignedStream,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static IMatFile ReadTestFile(string fileName, MatFileReadingMethod method)
|
||||
{
|
||||
var fullFileName = Path.Combine("test-data", "good", $"{fileName}.mat");
|
||||
return MatFileReadingMethods.ReadMatFile(method, fullFileName);
|
||||
}
|
||||
|
||||
private static IEnumerable<IMatFile> ReadAllTestFiles(MatFileReadingMethod method)
|
||||
{
|
||||
foreach (var fileName in Directory.EnumerateFiles(
|
||||
Path.Combine("test-data", "good"),
|
||||
"*.mat"))
|
||||
{
|
||||
var fullFileName = fileName;
|
||||
yield return MatFileReadingMethods.ReadMatFile(method, fullFileName);
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckLimits<T>(IArrayOf<T> array, T[] limits)
|
||||
where T : struct
|
||||
{
|
||||
|
29
MatFileHandler.Tests/MatFileReadingMethod.cs
Normal file
29
MatFileHandler.Tests/MatFileReadingMethod.cs
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
namespace MatFileHandler.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Method of reading .mat files for testing.
|
||||
/// </summary>
|
||||
public enum MatFileReadingMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined.
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Normal stream (like memory or file stream).
|
||||
/// </summary>
|
||||
NormalStream,
|
||||
|
||||
/// <summary>
|
||||
/// Partial stream (only is capable of reading one byte at a time).
|
||||
/// </summary>
|
||||
PartialStream,
|
||||
|
||||
/// <summary>
|
||||
/// Unaligned stream (what happens if the data don't start at the beginning?).
|
||||
/// </summary>
|
||||
UnalignedStream,
|
||||
}
|
38
MatFileHandler.Tests/MatFileReadingMethods.cs
Normal file
38
MatFileHandler.Tests/MatFileReadingMethods.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace MatFileHandler.Tests;
|
||||
|
||||
internal static class MatFileReadingMethods
|
||||
{
|
||||
public static IMatFile ReadMatFile(MatFileReadingMethod method, string fullFileName)
|
||||
{
|
||||
using var stream = File.OpenRead(fullFileName);
|
||||
switch (method)
|
||||
{
|
||||
case MatFileReadingMethod.NormalStream:
|
||||
return ReadFromStream(stream);
|
||||
case MatFileReadingMethod.PartialStream:
|
||||
{
|
||||
using var wrapper = new PartialUnseekableReadStream(stream);
|
||||
return ReadFromStream(wrapper);
|
||||
}
|
||||
case MatFileReadingMethod.UnalignedStream:
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
ms.Seek(3, SeekOrigin.Begin);
|
||||
stream.CopyTo(ms);
|
||||
ms.Seek(3, SeekOrigin.Begin);
|
||||
return ReadFromStream(ms);
|
||||
}
|
||||
default:
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private static IMatFile ReadFromStream(Stream stream)
|
||||
{
|
||||
var reader = new MatFileReader(stream);
|
||||
return reader.Read();
|
||||
}
|
||||
}
|
@ -1,9 +1,27 @@
|
||||
namespace MatFileHandler.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Options to give to MatFileWriter constructor for testing it.
|
||||
/// </summary>
|
||||
public enum MatFileWriterOptionsForTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Undefined.
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// No options.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Option to always use compression.
|
||||
/// </summary>
|
||||
Always,
|
||||
|
||||
/// <summary>
|
||||
/// Option to never use compression.
|
||||
/// </summary>
|
||||
Never,
|
||||
}
|
||||
|
@ -247,10 +247,7 @@ namespace MatFileHandler.Tests
|
||||
}
|
||||
}
|
||||
|
||||
private static AbstractTestDataFactory<IMatFile> GetMatTestData(string factoryName) =>
|
||||
new MatTestDataFactory(Path.Combine(TestDirectory, factoryName));
|
||||
|
||||
private void CompareSparseArrays<T>(ISparseArrayOf<T> expected, ISparseArrayOf<T> actual)
|
||||
private static void CompareSparseArrays<T>(ISparseArrayOf<T> expected, ISparseArrayOf<T> actual)
|
||||
where T : struct
|
||||
{
|
||||
Assert.NotNull(actual);
|
||||
@ -258,7 +255,7 @@ namespace MatFileHandler.Tests
|
||||
Assert.Equal(expected.Data, actual.Data);
|
||||
}
|
||||
|
||||
private void CompareStructureArrays(IStructureArray expected, IStructureArray actual)
|
||||
private static void CompareStructureArrays(IStructureArray expected, IStructureArray actual)
|
||||
{
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Dimensions, actual.Dimensions);
|
||||
@ -272,7 +269,7 @@ namespace MatFileHandler.Tests
|
||||
}
|
||||
}
|
||||
|
||||
private void CompareCellArrays(ICellArray expected, ICellArray actual)
|
||||
private static void CompareCellArrays(ICellArray expected, ICellArray actual)
|
||||
{
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Dimensions, actual.Dimensions);
|
||||
@ -282,21 +279,21 @@ namespace MatFileHandler.Tests
|
||||
}
|
||||
}
|
||||
|
||||
private void CompareNumericalArrays<T>(IArrayOf<T> expected, IArrayOf<T> actual)
|
||||
private static void CompareNumericalArrays<T>(IArrayOf<T> expected, IArrayOf<T> actual)
|
||||
{
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Dimensions, actual.Dimensions);
|
||||
Assert.Equal(expected.Data, actual.Data);
|
||||
}
|
||||
|
||||
private void CompareCharArrays(ICharArray expected, ICharArray actual)
|
||||
private static void CompareCharArrays(ICharArray expected, ICharArray actual)
|
||||
{
|
||||
Assert.NotNull(actual);
|
||||
Assert.Equal(expected.Dimensions, actual.Dimensions);
|
||||
Assert.Equal(expected.String, actual.String);
|
||||
}
|
||||
|
||||
private void CompareMatArrays(IArray expected, IArray actual)
|
||||
private static void CompareMatArrays(IArray expected, IArray actual)
|
||||
{
|
||||
switch (expected)
|
||||
{
|
||||
@ -387,7 +384,7 @@ namespace MatFileHandler.Tests
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
private void CompareMatFiles(IMatFile expected, IMatFile actual)
|
||||
private static void CompareMatFiles(IMatFile expected, IMatFile actual)
|
||||
{
|
||||
Assert.Equal(expected.Variables.Length, actual.Variables.Length);
|
||||
for (var i = 0; i < expected.Variables.Length; i++)
|
||||
@ -400,14 +397,17 @@ namespace MatFileHandler.Tests
|
||||
}
|
||||
}
|
||||
|
||||
private void MatCompareWithTestData(
|
||||
private static void MatCompareWithTestData(
|
||||
string factoryName,
|
||||
string testName,
|
||||
IMatFile actual,
|
||||
MatFileWritingMethod method,
|
||||
MatFileWriterOptionsForTests options)
|
||||
{
|
||||
var expected = GetMatTestData(factoryName)[testName];
|
||||
var fullFileName = Path.Combine("test-data", "good", $"{testName}.mat");
|
||||
var expected = MatFileReadingMethods.ReadMatFile(
|
||||
MatFileReadingMethod.NormalStream,
|
||||
fullFileName);
|
||||
var buffer = MatFileWritingMethods.WriteMatFile(method, options, actual);
|
||||
using var stream = new MemoryStream(buffer);
|
||||
var reader = new MatFileReader(stream);
|
||||
@ -415,7 +415,7 @@ namespace MatFileHandler.Tests
|
||||
CompareMatFiles(expected, actualRead);
|
||||
}
|
||||
|
||||
private ComplexOf<T>[] CreateComplexLimits<T>(T[] limits)
|
||||
private static ComplexOf<T>[] CreateComplexLimits<T>(T[] limits)
|
||||
where T : struct
|
||||
{
|
||||
return new[] { new ComplexOf<T>(limits[0], limits[1]), new ComplexOf<T>(limits[1], limits[0]) };
|
||||
|
@ -1,12 +1,29 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
namespace MatFileHandler.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Method of writing .mat files for testing.
|
||||
/// </summary>
|
||||
public enum MatFileWritingMethod
|
||||
{
|
||||
Undefined,
|
||||
/// <summary>
|
||||
/// Undefined.
|
||||
/// </summary>
|
||||
Undefined = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Normal stream (like memory or file stream).
|
||||
/// </summary>
|
||||
NormalStream,
|
||||
|
||||
/// <summary>
|
||||
/// A stream that cannot be seeked (like a deflate stream).
|
||||
/// </summary>
|
||||
UnseekableStream,
|
||||
|
||||
/// <summary>
|
||||
/// Unaligned stream (what happens if the data don't start at the beginning?).
|
||||
/// </summary>
|
||||
UnalignedStream,
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +0,0 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory providing the parsed contents of .mat files.
|
||||
/// </summary>
|
||||
public class MatTestDataFactory : AbstractTestDataFactory<IMatFile>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MatTestDataFactory"/> class.
|
||||
/// </summary>
|
||||
/// <param name="testDirectory">Directory containing test files.</param>
|
||||
public MatTestDataFactory(string testDirectory)
|
||||
: base(
|
||||
testDirectory,
|
||||
new ExtensionTestFilenameConvention("mat"))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read and parse data from a .mat file.
|
||||
/// </summary>
|
||||
/// <param name="stream">Input stream.</param>
|
||||
/// <returns>Parsed contents of the file.</returns>
|
||||
protected override IMatFile ReadDataFromStream(Stream stream)
|
||||
{
|
||||
var matFileReader = new MatFileReader(stream);
|
||||
var matFile = matFileReader.Read();
|
||||
return matFile;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory providing the parsed contents of .mat files,
|
||||
/// wrapped in a <see cref="PartialUnseekableReadStream"/>.
|
||||
/// </summary>
|
||||
public class PartialReadMatTestDataFactory : MatTestDataFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PartialReadMatTestDataFactory"/> class.
|
||||
/// </summary>
|
||||
/// <param name="testDirectory">Directory containing test files.</param>
|
||||
public PartialReadMatTestDataFactory(string testDirectory)
|
||||
: base(testDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read and parse data from a .mat file.
|
||||
/// </summary>
|
||||
/// <param name="stream">Input stream.</param>
|
||||
/// <returns>Parsed contents of the file.</returns>
|
||||
protected override IMatFile ReadDataFromStream(Stream stream)
|
||||
{
|
||||
using (var wrapper = new PartialUnseekableReadStream(stream))
|
||||
{
|
||||
return base.ReadDataFromStream(wrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
// Copyright 2017-2018 Alexander Luzgarev
|
||||
|
||||
using System.IO;
|
||||
|
||||
namespace MatFileHandler.Tests
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory providing the parsed contents of .mat files,
|
||||
/// which start at a non-8 byte-aligned offset in the stream.
|
||||
/// </summary>
|
||||
public class UnalignedMatTestDataFactory : MatTestDataFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PartialReadMatTestDataFactory"/> class.
|
||||
/// </summary>
|
||||
/// <param name="testDirectory">Directory containing test files.</param>
|
||||
public UnalignedMatTestDataFactory(string testDirectory)
|
||||
: base(testDirectory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IMatFile ReadDataFromStream(Stream stream)
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
ms.Seek(3, SeekOrigin.Begin);
|
||||
|
||||
stream.CopyTo(ms);
|
||||
|
||||
ms.Seek(3, SeekOrigin.Begin);
|
||||
|
||||
return base.ReadDataFromStream(ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user