Some updates #26

Merged
mahalex merged 5 commits from dev/updates into master 2024-07-24 18:49:56 +00:00
8 changed files with 335 additions and 280 deletions

View File

@ -1,32 +1,28 @@
// Copyright 2017-2018 Alexander Luzgarev // Copyright 2017-2018 Alexander Luzgarev
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Numerics; using System.Numerics;
using NUnit.Framework; using Xunit;
namespace MatFileHandler.Tests namespace MatFileHandler.Tests
{ {
/// <summary> /// <summary>
/// Tests of Matlab array manipulation. /// Tests of Matlab array manipulation.
/// </summary> /// </summary>
[TestFixture] public class ArrayHandlingTests : IDisposable
public class ArrayHandlingTests
{ {
private DataBuilder Builder { get; set; } public ArrayHandlingTests()
/// <summary>
/// Set up a DataBuilder.
/// </summary>
[SetUp]
public void Setup()
{ {
Builder = new DataBuilder(); Builder = new DataBuilder();
} }
private DataBuilder Builder { get; set; }
/// <summary> /// <summary>
/// Test numerical array creation. /// Test numerical array creation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestCreate() public void TestCreate()
{ {
TestCreateArrayOf<sbyte>(); TestCreateArrayOf<sbyte>();
@ -54,70 +50,74 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test numerical array manipulation. /// Test numerical array manipulation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestNumArray() public void TestNumArray()
{ {
var array = Builder.NewArray<int>(2, 3); var array = Builder.NewArray<int>(2, 3);
array[0, 1] = 2; array[0, 1] = 2;
Assert.That(array[0, 1], Is.EqualTo(2)); Assert.Equal(2, array[0, 1]);
} }
/// <summary> /// <summary>
/// Test cell array manipulation. /// Test cell array manipulation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestCellArray() public void TestCellArray()
{ {
var array = Builder.NewCellArray(2, 3); var array = Builder.NewCellArray(2, 3);
Assert.That(array.Dimensions, Is.EqualTo(new[] { 2, 3 })); Assert.Equal(new[] { 2, 3 }, array.Dimensions);
array[0, 1] = Builder.NewArray<int>(1, 2); array[0, 1] = Builder.NewArray<int>(1, 2);
Assert.That(array[1, 2].IsEmpty, Is.True); Assert.True(array[1, 2].IsEmpty);
Assert.That(array[0, 1].IsEmpty, Is.False); Assert.False(array[0, 1].IsEmpty);
var assigned = (IArrayOf<int>)array[0, 1]; var assigned = (IArrayOf<int>)array[0, 1];
Assert.That(assigned, Is.Not.Null); Assert.NotNull(assigned);
Assert.That(assigned.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, assigned.Dimensions);
} }
/// <summary> /// <summary>
/// Test structure array manipulation. /// Test structure array manipulation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestStructureArray() public void TestStructureArray()
{ {
var array = Builder.NewStructureArray(new[] { "x", "y" }, 2, 3); var array = Builder.NewStructureArray(new[] { "x", "y" }, 2, 3);
array["x", 0, 1] = Builder.NewArray<int>(1, 2); array["x", 0, 1] = Builder.NewArray<int>(1, 2);
Assert.That(array["y", 0, 1].IsEmpty, Is.True); Assert.True(array["y", 0, 1].IsEmpty);
Assert.That(array["x", 0, 1].IsEmpty, Is.False); Assert.False(array["x", 0, 1].IsEmpty);
var assigned = (IArrayOf<int>)array["x", 0, 1]; var assigned = (IArrayOf<int>)array["x", 0, 1];
Assert.That(assigned, Is.Not.Null); Assert.NotNull(assigned);
Assert.That(assigned.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, assigned.Dimensions);
} }
/// <summary> /// <summary>
/// Test character array manipulation. /// Test character array manipulation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestString() public void TestString()
{ {
var array = Builder.NewCharArray("🍆"); var array = Builder.NewCharArray("🍆");
Assert.That(array.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, array.Dimensions);
} }
/// <summary> /// <summary>
/// Test file creation. /// Test file creation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestFile() public void TestFile()
{ {
var file = Builder.NewFile(new List<IVariable>()); var file = Builder.NewFile(new List<IVariable>());
Assert.That(file, Is.Not.Null); Assert.NotNull(file);
} }
private static void TestCreateArrayOf<T>() private static void TestCreateArrayOf<T>()
where T : struct where T : struct
{ {
var array = new DataBuilder().NewArray<T>(2, 3); var array = new DataBuilder().NewArray<T>(2, 3);
Assert.That(array, Is.Not.Null); Assert.NotNull(array);
}
public void Dispose()
{
} }
} }
} }

View File

@ -1,51 +1,50 @@
// Copyright 2017-2018 Alexander Luzgarev // Copyright 2017-2018 Alexander Luzgarev
using NUnit.Framework; using Xunit;
namespace MatFileHandler.Tests namespace MatFileHandler.Tests
{ {
/// <summary> /// <summary>
/// Tests of the ComplexOf value type. /// Tests of the ComplexOf value type.
/// </summary> /// </summary>
[TestFixture]
public class ComplexOfTests public class ComplexOfTests
{ {
/// <summary> /// <summary>
/// Test getting real and imaginary parts. /// Test getting real and imaginary parts.
/// </summary> /// </summary>
[Test] [Fact]
public void TestAccessors() public void TestAccessors()
{ {
var c = new ComplexOf<byte>(1, 2); var c = new ComplexOf<byte>(1, 2);
Assert.That(c.Real, Is.EqualTo(1)); Assert.Equal(1, c.Real);
Assert.That(c.Imaginary, Is.EqualTo(2)); Assert.Equal(2, c.Imaginary);
} }
/// <summary> /// <summary>
/// Test equality operators. /// Test equality operators.
/// </summary> /// </summary>
[Test] [Fact]
public void TestEquals() public void TestEquals()
{ {
var c1 = new ComplexOf<byte>(1, 2); var c1 = new ComplexOf<byte>(1, 2);
var c2 = new ComplexOf<byte>(3, 4); var c2 = new ComplexOf<byte>(3, 4);
var c3 = new ComplexOf<byte>(1, 2); var c3 = new ComplexOf<byte>(1, 2);
Assert.That(c1 == c3, Is.True); Assert.True(c1 == c3);
Assert.That(c1 != c2, Is.True); Assert.True(c1 != c2);
Assert.That(c2 != c3, Is.True); Assert.True(c2 != c3);
} }
/// <summary> /// <summary>
/// Test hash code calculation. /// Test hash code calculation.
/// </summary> /// </summary>
[Test] [Fact]
public void TestGetHashCode() public void TestGetHashCode()
{ {
var c1 = new ComplexOf<byte>(1, 2); var c1 = new ComplexOf<byte>(1, 2);
var c2 = new ComplexOf<byte>(1, 2); var c2 = new ComplexOf<byte>(1, 2);
var h1 = c1.GetHashCode(); var h1 = c1.GetHashCode();
var h2 = c2.GetHashCode(); var h2 = c2.GetHashCode();
Assert.That(h1, Is.EqualTo(h2)); Assert.Equal(h1, h2);
} }
} }
} }

View File

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net5.0;net472</TargetFrameworks> <TargetFrameworks>net8.0;net472</TargetFrameworks>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
@ -12,8 +12,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="NUnit" Version="3.13.2" /> <PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.0.0" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\MatFileHandler\MatFileHandler.csproj" /> <ProjectReference Include="..\MatFileHandler\MatFileHandler.csproj" />

View File

@ -4,14 +4,13 @@ using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using NUnit.Framework; using Xunit;
namespace MatFileHandler.Tests namespace MatFileHandler.Tests
{ {
/// <summary> /// <summary>
/// Tests of file reading API. /// Tests of file reading API.
/// </summary> /// </summary>
[TestFixture]
public class MatFileReaderTests public class MatFileReaderTests
{ {
private const string TestDirectory = "test-data"; private const string TestDirectory = "test-data";
@ -20,26 +19,27 @@ namespace MatFileHandler.Tests
/// Test reading all files in a given test set. /// Test reading all files in a given test set.
/// </summary> /// </summary>
/// <param name="testSet">Name of the set.</param> /// <param name="testSet">Name of the set.</param>
[TestCase("good")] [Theory]
[InlineData("good")]
public void TestReader(string testSet) public void TestReader(string testSet)
{ {
foreach (var matFile in GetTests(testSet).GetAllTestData()) foreach (var matFile in GetTests(testSet).GetAllTestData())
{ {
Assert.That(matFile.Variables, Is.Not.Empty); Assert.NotEmpty(matFile.Variables);
} }
} }
/// <summary> /// <summary>
/// Test reading lower and upper limits of integer data types. /// Test reading lower and upper limits of integer data types.
/// </summary> /// </summary>
[Test] [Fact]
public void TestLimits() public void TestLimits()
{ {
var matFile = GetTests("good")["limits"]; var matFile = GetTests("good")["limits"];
IArray array; IArray array;
array = matFile["int8_"].Value; array = matFile["int8_"].Value;
CheckLimits(array as IArrayOf<sbyte>, CommonData.Int8Limits); CheckLimits(array as IArrayOf<sbyte>, CommonData.Int8Limits);
Assert.That(array.ConvertToDoubleArray(), Is.EqualTo(new[] { -128.0, 127.0 })); Assert.Equal(new[] { -128.0, 127.0 }, array.ConvertToDoubleArray());
array = matFile["uint8_"].Value; array = matFile["uint8_"].Value;
CheckLimits(array as IArrayOf<byte>, CommonData.UInt8Limits); CheckLimits(array as IArrayOf<byte>, CommonData.UInt8Limits);
@ -66,16 +66,16 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing lower and upper limits of integer-based complex data types. /// Test writing lower and upper limits of integer-based complex data types.
/// </summary> /// </summary>
[Test] [Fact]
public void TestComplexLimits() public void TestComplexLimits()
{ {
var matFile = GetTests("good")["limits_complex"]; var matFile = GetTests("good")["limits_complex"];
IArray array; IArray array;
array = matFile["int8_complex"].Value; array = matFile["int8_complex"].Value;
CheckComplexLimits(array as IArrayOf<ComplexOf<sbyte>>, CommonData.Int8Limits); CheckComplexLimits(array as IArrayOf<ComplexOf<sbyte>>, CommonData.Int8Limits);
Assert.That( Assert.Equal(
array.ConvertToComplexArray(), new[] { -128.0 + (127.0 * Complex.ImaginaryOne), 127.0 - (128.0 * Complex.ImaginaryOne) },
Is.EqualTo(new[] { -128.0 + (127.0 * Complex.ImaginaryOne), 127.0 - (128.0 * Complex.ImaginaryOne) })); array.ConvertToComplexArray());
array = matFile["uint8_complex"].Value; array = matFile["uint8_complex"].Value;
CheckComplexLimits(array as IArrayOf<ComplexOf<byte>>, CommonData.UInt8Limits); CheckComplexLimits(array as IArrayOf<ComplexOf<byte>>, CommonData.UInt8Limits);
@ -102,395 +102,398 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test reading an ASCII-encoded string. /// Test reading an ASCII-encoded string.
/// </summary> /// </summary>
[Test] [Fact]
public void TestAscii() public void TestAscii()
{ {
var matFile = GetTests("good")["ascii"]; var matFile = GetTests("good")["ascii"];
var arrayAscii = matFile["s"].Value as ICharArray; var arrayAscii = matFile["s"].Value as ICharArray;
Assert.That(arrayAscii, Is.Not.Null); Assert.NotNull(arrayAscii);
Assert.That(arrayAscii.Dimensions, Is.EqualTo(new[] { 1, 3 })); Assert.Equal(new[] { 1, 3 }, arrayAscii.Dimensions);
Assert.That(arrayAscii.String, Is.EqualTo("abc")); Assert.Equal("abc", arrayAscii.String);
Assert.That(arrayAscii[2], Is.EqualTo('c')); Assert.Equal('c', arrayAscii[2]);
} }
/// <summary> /// <summary>
/// Test reading a Unicode string. /// Test reading a Unicode string.
/// </summary> /// </summary>
[Test] [Fact]
public void TestUnicode() public void TestUnicode()
{ {
var matFile = GetTests("good")["unicode"]; var matFile = GetTests("good")["unicode"];
var arrayUnicode = matFile["s"].Value as ICharArray; var arrayUnicode = matFile["s"].Value as ICharArray;
Assert.That(arrayUnicode, Is.Not.Null); Assert.NotNull(arrayUnicode);
Assert.That(arrayUnicode.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, arrayUnicode.Dimensions);
Assert.That(arrayUnicode.String, Is.EqualTo("必フ")); Assert.Equal("必フ", arrayUnicode.String);
Assert.That(arrayUnicode[0], Is.EqualTo('必')); Assert.Equal('必', arrayUnicode[0]);
Assert.That(arrayUnicode[1], Is.EqualTo('フ')); Assert.Equal('フ', arrayUnicode[1]);
} }
/// <summary> /// <summary>
/// Test reading a wide Unicode string. /// Test reading a wide Unicode string.
/// </summary> /// </summary>
[Test] [Fact]
public void TestUnicodeWide() public void TestUnicodeWide()
{ {
var matFile = GetTests("good")["unicode-wide"]; var matFile = GetTests("good")["unicode-wide"];
var arrayUnicodeWide = matFile["s"].Value as ICharArray; var arrayUnicodeWide = matFile["s"].Value as ICharArray;
Assert.That(arrayUnicodeWide, Is.Not.Null); Assert.NotNull(arrayUnicodeWide);
Assert.That(arrayUnicodeWide.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, arrayUnicodeWide.Dimensions);
Assert.That(arrayUnicodeWide.String, Is.EqualTo("🍆")); Assert.Equal("🍆", arrayUnicodeWide.String);
} }
/// <summary> /// <summary>
/// Test converting a structure array to a Double array. /// Test converting a structure array to a Double array.
/// </summary> /// </summary>
/// <returns>Should return null.</returns> [Fact]
[Test(ExpectedResult = null)] public void TestConvertToDoubleArray()
public double[] TestConvertToDoubleArray()
{ {
var matFile = GetTests("good")["struct"]; var matFile = GetTests("good")["struct"];
var array = matFile.Variables[0].Value; var array = matFile.Variables[0].Value;
return array.ConvertToDoubleArray(); Assert.Null(array.ConvertToDoubleArray());
} }
/// <summary> /// <summary>
/// Test converting a structure array to a Complex array. /// Test converting a structure array to a Complex array.
/// </summary> /// </summary>
/// <returns>Should return null.</returns> /// <returns>Should return null.</returns>
[Test(ExpectedResult = null)] [Fact]
public Complex[] TestConvertToComplexArray() public void TestConvertToComplexArray()
{ {
var matFile = GetTests("good")["struct"]; var matFile = GetTests("good")["struct"];
var array = matFile.Variables[0].Value; var array = matFile.Variables[0].Value;
return array.ConvertToComplexArray(); Assert.Null(array.ConvertToComplexArray());
} }
/// <summary> /// <summary>
/// Test reading a structure array. /// Test reading a structure array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestStruct() public void TestStruct()
{ {
var matFile = GetTests("good")["struct"]; var matFile = GetTests("good")["struct"];
var structure = matFile["struct_"].Value as IStructureArray; var structure = matFile["struct_"].Value as IStructureArray;
Assert.That(structure, Is.Not.Null); Assert.NotNull(structure);
Assert.That(structure.FieldNames, Is.EquivalentTo(new[] { "x", "y" })); Assert.Equal(new[] { "x", "y" }, structure.FieldNames);
var element = structure[0, 0]; var element = structure[0, 0];
Assert.That(element.ContainsKey("x"), Is.True); Assert.True(element.ContainsKey("x"));
Assert.That(element.Count, Is.EqualTo(2)); Assert.Equal(2, element.Count);
Assert.That(element.TryGetValue("x", out var _), Is.True); Assert.True(element.TryGetValue("x", out var _));
Assert.That(element.TryGetValue("z", out var _), Is.False); Assert.False(element.TryGetValue("z", out var _));
Assert.That(element.Keys, Has.Exactly(2).Items); Assert.Equal(2, element.Keys.Count());
Assert.That(element.Values, Has.Exactly(2).Items); Assert.Equal(2, element.Values.Count());
var keys = element.Select(pair => pair.Key); var keys = element.Select(pair => pair.Key);
Assert.That(keys, Is.EquivalentTo(new[] { "x", "y" })); Assert.Equal(new[] { "x", "y" }, keys);
Assert.That((element["x"] as IArrayOf<double>)?[0], Is.EqualTo(12.345)); Assert.Equal(12.345, (element["x"] as IArrayOf<double>)?[0]);
Assert.That((structure["x", 0, 0] as IArrayOf<double>)?[0], Is.EqualTo(12.345)); Assert.Equal(12.345, (structure["x", 0, 0] as IArrayOf<double>)?[0]);
Assert.That((structure["y", 0, 0] as ICharArray)?.String, Is.EqualTo("abc")); Assert.Equal(2.0, (structure["x", 0, 1] as IArrayOf<double>)?[0]);
Assert.That((structure["x", 1, 0] as ICharArray)?.String, Is.EqualTo("xyz")); Assert.Equal("x", ((structure["x", 0, 2] as ICellArray)?[0] as ICharArray)?.String);
Assert.That(structure["y", 1, 0].IsEmpty, Is.True); Assert.Equal("yz", ((structure["x", 0, 2] as ICellArray)?[1] as ICharArray)?.String);
Assert.That((structure["x", 0, 1] as IArrayOf<double>)?[0], Is.EqualTo(2.0)); Assert.Equal("xyz", (structure["x", 1, 0] as ICharArray)?.String);
Assert.That((structure["y", 0, 1] as IArrayOf<double>)?[0], Is.EqualTo(13.0)); Assert.True(structure["x", 1, 1].IsEmpty);
Assert.That(structure["x", 1, 1].IsEmpty, Is.True); Assert.Equal(1.5f, (structure["x", 1, 2] as IArrayOf<float>)?[0]);
Assert.That((structure["y", 1, 1] as ICharArray)?[0, 0], Is.EqualTo('a'));
Assert.That(((structure["x", 0, 2] as ICellArray)?[0] as ICharArray)?.String, Is.EqualTo("x"));
Assert.That(((structure["x", 0, 2] as ICellArray)?[1] as ICharArray)?.String, Is.EqualTo("yz"));
Assert.That((structure["y", 0, 2] as IArrayOf<double>)?.Dimensions, Is.EqualTo(new[] { 2, 3 }));
Assert.That((structure["y", 0, 2] as IArrayOf<double>)?[0, 2], Is.EqualTo(3.0));
Assert.That((structure["x", 1, 2] as IArrayOf<float>)?[0], Is.EqualTo(1.5f));
Assert.That(structure["y", 1, 2].IsEmpty, Is.True);
Assert.That(structure["y", 0, 2].ConvertTo2dDoubleArray(), Is.EqualTo( Assert.Equal("abc", (structure["y", 0, 0] as ICharArray)?.String);
Assert.Equal(13.0, (structure["y", 0, 1] as IArrayOf<double>)?[0]);
Assert.Equal(new[] { 2, 3 }, (structure["y", 0, 2] as IArrayOf<double>)?.Dimensions);
Assert.Equal(3.0, (structure["y", 0, 2] as IArrayOf<double>)?[0, 2]);
Assert.True(structure["y", 1, 0].IsEmpty);
Assert.Equal('a', (structure["y", 1, 1] as ICharArray)?[0, 0]);
Assert.True(structure["y", 1, 2].IsEmpty);
Assert.Equal(
new double[,] new double[,]
{ {
{ 1, 2, 3 }, { 1, 2, 3 },
{ 4, 5, 6 }, { 4, 5, 6 },
})); },
Assert.That(structure["y", 0, 2].ConvertToMultidimensionalDoubleArray(), Is.EqualTo( structure["y", 0, 2].ConvertTo2dDoubleArray());
Assert.Equal(
new double[,] new double[,]
{ {
{ 1, 2, 3 }, { 1, 2, 3 },
{ 4, 5, 6 }, { 4, 5, 6 },
})); },
structure["y", 0, 2].ConvertToMultidimensionalDoubleArray());
} }
/// <summary> /// <summary>
/// Test reading a sparse array. /// Test reading a sparse array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestSparse() public void TestSparse()
{ {
var matFile = GetTests("good")["sparse"]; var matFile = GetTests("good")["sparse"];
var sparseArray = matFile["sparse_"].Value as ISparseArrayOf<double>; var sparseArray = matFile["sparse_"].Value as ISparseArrayOf<double>;
Assert.That(sparseArray, Is.Not.Null); Assert.NotNull(sparseArray);
Assert.That(sparseArray.Dimensions, Is.EqualTo(new[] { 4, 5 })); Assert.Equal(new[] { 4, 5 }, sparseArray.Dimensions);
Assert.That(sparseArray.Data[(1, 1)], Is.EqualTo(1.0)); Assert.Equal(1.0, sparseArray.Data[(1, 1)]);
Assert.That(sparseArray[1, 1], Is.EqualTo(1.0)); Assert.Equal(1.0, sparseArray[1, 1]);
Assert.That(sparseArray[1, 2], Is.EqualTo(2.0)); Assert.Equal(2.0, sparseArray[1, 2]);
Assert.That(sparseArray[2, 1], Is.EqualTo(3.0)); Assert.Equal(3.0, sparseArray[2, 1]);
Assert.That(sparseArray[2, 3], Is.EqualTo(4.0)); Assert.Equal(4.0, sparseArray[2, 3]);
Assert.That(sparseArray[0, 4], Is.EqualTo(0.0)); Assert.Equal(0.0, sparseArray[0, 4]);
Assert.That(sparseArray[3, 0], Is.EqualTo(0.0)); Assert.Equal(0.0, sparseArray[3, 0]);
Assert.That(sparseArray[3, 4], Is.EqualTo(0.0)); Assert.Equal(0.0, sparseArray[3, 4]);
Assert.That(sparseArray.ConvertTo2dDoubleArray(), Is.EqualTo( Assert.Equal(
new double[,] new double[,]
{ {
{ 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 },
{ 0, 1, 2, 0, 0 }, { 0, 1, 2, 0, 0 },
{ 0, 3, 0, 4, 0 }, { 0, 3, 0, 4, 0 },
{ 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 },
})); },
sparseArray.ConvertTo2dDoubleArray());
} }
/// <summary> /// <summary>
/// Test reading a logical array. /// Test reading a logical array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestLogical() public void TestLogical()
{ {
var matFile = GetTests("good")["logical"]; var matFile = GetTests("good")["logical"];
var array = matFile["logical_"].Value; var array = matFile["logical_"].Value;
var logicalArray = array as IArrayOf<bool>; var logicalArray = array as IArrayOf<bool>;
Assert.That(logicalArray, Is.Not.Null); Assert.NotNull(logicalArray);
Assert.That(logicalArray[0, 0], Is.True); Assert.True(logicalArray[0, 0]);
Assert.That(logicalArray[0, 1], Is.True); Assert.True(logicalArray[0, 1]);
Assert.That(logicalArray[0, 2], Is.False); Assert.False(logicalArray[0, 2]);
Assert.That(logicalArray[1, 0], Is.False); Assert.False(logicalArray[1, 0]);
Assert.That(logicalArray[1, 1], Is.True); Assert.True(logicalArray[1, 1]);
Assert.That(logicalArray[1, 2], Is.True); Assert.True(logicalArray[1, 2]);
} }
/// <summary> /// <summary>
/// Test reading a sparse logical array. /// Test reading a sparse logical array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestSparseLogical() public void TestSparseLogical()
{ {
var matFile = GetTests("good")["sparse_logical"]; var matFile = GetTests("good")["sparse_logical"];
var array = matFile["sparse_logical"].Value; var array = matFile["sparse_logical"].Value;
var sparseArray = array as ISparseArrayOf<bool>; var sparseArray = array as ISparseArrayOf<bool>;
Assert.That(sparseArray, Is.Not.Null); Assert.NotNull (sparseArray);
Assert.That(sparseArray.Data[(0, 0)], Is.True); Assert.True(sparseArray.Data[(0, 0)]);
Assert.That(sparseArray[0, 0], Is.True); Assert.True(sparseArray[0, 0]);
Assert.That(sparseArray[0, 1], Is.True); Assert.True(sparseArray[0, 1]);
Assert.That(sparseArray[0, 2], Is.False); Assert.False(sparseArray[0, 2]);
Assert.That(sparseArray[1, 0], Is.False); Assert.False(sparseArray[1, 0]);
Assert.That(sparseArray[1, 1], Is.True); Assert.True(sparseArray[1, 1]);
Assert.That(sparseArray[1, 2], Is.True); Assert.True(sparseArray[1, 2]);
} }
/// <summary> /// <summary>
/// Test reading a global variable. /// Test reading a global variable.
/// </summary> /// </summary>
[Test] [Fact]
public void TestGlobal() public void TestGlobal()
{ {
var matFile = GetTests("good")["global"]; var matFile = GetTests("good")["global"];
var variable = matFile.Variables.First(); var variable = matFile.Variables.First();
Assert.That(variable.IsGlobal, Is.True); Assert.True(variable.IsGlobal);
} }
/// <summary> /// <summary>
/// Test reading a sparse complex array. /// Test reading a sparse complex array.
/// </summary> /// </summary>
[Test] [Fact]
public void TextSparseComplex() public void TextSparseComplex()
{ {
var matFile = GetTests("good")["sparse_complex"]; var matFile = GetTests("good")["sparse_complex"];
var array = matFile["sparse_complex"].Value; var array = matFile["sparse_complex"].Value;
var sparseArray = array as ISparseArrayOf<Complex>; var sparseArray = array as ISparseArrayOf<Complex>;
Assert.That(sparseArray, Is.Not.Null); Assert.NotNull(sparseArray);
Assert.That(sparseArray[0, 0], Is.EqualTo(-1.5 + (2.5 * Complex.ImaginaryOne))); Assert.Equal(-1.5 + (2.5 * Complex.ImaginaryOne), sparseArray[0, 0]);
Assert.That(sparseArray[1, 0], Is.EqualTo(2 - (3 * Complex.ImaginaryOne))); Assert.Equal(2 - (3 * Complex.ImaginaryOne), sparseArray[1, 0]);
Assert.That(sparseArray[0, 1], Is.EqualTo(Complex.Zero)); Assert.Equal(Complex.Zero, sparseArray[0, 1]);
Assert.That(sparseArray[1, 1], Is.EqualTo(0.5 + (1.0 * Complex.ImaginaryOne))); Assert.Equal(0.5 + (1.0 * Complex.ImaginaryOne), sparseArray[1, 1]);
} }
/// <summary> /// <summary>
/// Test reading an object. /// Test reading an object.
/// </summary> /// </summary>
[Test] [Fact]
public void TestObject() public void TestObject()
{ {
var matFile = GetTests("good")["object"]; var matFile = GetTests("good")["object"];
var obj = matFile["object_"].Value as IMatObject; var obj = matFile["object_"].Value as IMatObject;
Assert.IsNotNull(obj); Assert.NotNull(obj);
Assert.That(obj.ClassName, Is.EqualTo("Point")); Assert.Equal("Point", obj.ClassName);
Assert.That(obj.FieldNames, Is.EquivalentTo(new[] { "x", "y" })); Assert.Equal(new[] { "x", "y" }, obj.FieldNames);
Assert.That(obj["x", 0].ConvertToDoubleArray(), Is.EqualTo(new[] { 3.0 })); Assert.Equal(new[] { 3.0 }, obj["x", 0].ConvertToDoubleArray());
Assert.That(obj["y", 0].ConvertToDoubleArray(), Is.EqualTo(new[] { 5.0 })); Assert.Equal(new[] { 5.0 }, obj["y", 0].ConvertToDoubleArray());
Assert.That(obj["x", 1].ConvertToDoubleArray(), Is.EqualTo(new[] { -2.0 })); Assert.Equal(new[] { -2.0 }, obj["x", 1].ConvertToDoubleArray());
Assert.That(obj["y", 1].ConvertToDoubleArray(), Is.EqualTo(new[] { 6.0 })); Assert.Equal(new[] { 6.0 }, obj["y", 1].ConvertToDoubleArray());
} }
/// <summary> /// <summary>
/// Test reading another object. /// Test reading another object.
/// </summary> /// </summary>
[Test] [Fact]
public void TestObject2() public void TestObject2()
{ {
var matFile = GetTests("good")["object2"]; var matFile = GetTests("good")["object2"];
var obj = matFile["object2"].Value as IMatObject; var obj = matFile["object2"].Value as IMatObject;
Assert.IsNotNull(obj); Assert.NotNull(obj);
Assert.That(obj.ClassName, Is.EqualTo("Point")); Assert.Equal("Point", obj.ClassName);
Assert.That(obj.FieldNames, Is.EquivalentTo(new[] { "x", "y" })); Assert.Equal(new[] { "x", "y" }, obj.FieldNames);
Assert.That(obj["x", 0, 0].ConvertToDoubleArray(), Is.EqualTo(new[] { 3.0 })); Assert.Equal(new[] { 3.0 }, obj["x", 0, 0].ConvertToDoubleArray());
Assert.That(obj["y", 0, 0].ConvertToDoubleArray(), Is.EqualTo(new[] { 5.0 })); Assert.Equal(new[] { -2.0 }, obj["x", 0, 1].ConvertToDoubleArray());
Assert.That(obj["x", 1, 0].ConvertToDoubleArray(), Is.EqualTo(new[] { 1.0 })); Assert.Equal(new[] { 1.0 }, obj["x", 1, 0].ConvertToDoubleArray());
Assert.That(obj["y", 1, 0].ConvertToDoubleArray(), Is.EqualTo(new[] { 0.0 })); Assert.Equal(new[] { 0.0 }, obj["x", 1, 1].ConvertToDoubleArray());
Assert.That(obj["x", 0, 1].ConvertToDoubleArray(), Is.EqualTo(new[] { -2.0 })); Assert.Equal(new[] { 5.0 }, obj["y", 0, 0].ConvertToDoubleArray());
Assert.That(obj["y", 0, 1].ConvertToDoubleArray(), Is.EqualTo(new[] { 6.0 })); Assert.Equal(new[] { 6.0 }, obj["y", 0, 1].ConvertToDoubleArray());
Assert.That(obj["x", 1, 1].ConvertToDoubleArray(), Is.EqualTo(new[] { 0.0 })); Assert.Equal(new[] { 0.0 }, obj["y", 1, 0].ConvertToDoubleArray());
Assert.That(obj["y", 1, 1].ConvertToDoubleArray(), Is.EqualTo(new[] { 1.0 })); Assert.Equal(new[] { 1.0 }, obj["y", 1, 1].ConvertToDoubleArray());
Assert.That(obj[0, 1]["x"].ConvertToDoubleArray(), Is.EqualTo(new[] { -2.0 })); Assert.Equal(new[] { -2.0 }, obj[0, 1]["x"].ConvertToDoubleArray());
Assert.That(obj[2]["x"].ConvertToDoubleArray(), Is.EqualTo(new[] { -2.0 })); Assert.Equal(new[] { -2.0 }, obj[2]["x"].ConvertToDoubleArray());
} }
/// <summary> /// <summary>
/// Test reading a table. /// Test reading a table.
/// </summary> /// </summary>
[Test] [Fact]
public void TestTable() public void TestTable()
{ {
var matFile = GetTests("good")["table"]; var matFile = GetTests("good")["table"];
var obj = matFile["table_"].Value as IMatObject; var obj = matFile["table_"].Value as IMatObject;
var table = new TableAdapter(obj); var table = new TableAdapter(obj);
Assert.That(table.NumberOfRows, Is.EqualTo(3)); Assert.Equal(3, table.NumberOfRows);
Assert.That(table.NumberOfVariables, Is.EqualTo(2)); Assert.Equal(2, table.NumberOfVariables);
Assert.That(table.Description, Is.EqualTo("Some table")); Assert.Equal("Some table", table.Description);
Assert.That(table.VariableNames, Is.EqualTo(new[] { "variable1", "variable2" })); Assert.Equal(new[] { "variable1", "variable2" }, table.VariableNames);
var variable1 = table["variable1"] as ICellArray; var variable1 = table["variable1"] as ICellArray;
Assert.That((variable1[0] as ICharArray).String, Is.EqualTo("First row")); Assert.Equal("First row", (variable1[0] as ICharArray).String);
Assert.That((variable1[1] as ICharArray).String, Is.EqualTo("Second row")); Assert.Equal("Second row", (variable1[1] as ICharArray).String);
Assert.That((variable1[2] as ICharArray).String, Is.EqualTo("Third row")); Assert.Equal("Third row", (variable1[2] as ICharArray).String);
var variable2 = table["variable2"]; var variable2 = table["variable2"];
Assert.That(variable2.ConvertToDoubleArray(), Is.EqualTo(new[] { 1.0, 3.0, 5.0, 2.0, 4.0, 6.0 })); Assert.Equal(new[] { 1.0, 3.0, 5.0, 2.0, 4.0, 6.0 }, variable2.ConvertToDoubleArray());
} }
/// <summary> /// <summary>
/// Test subobjects within objects. /// Test subobjects within objects.
/// </summary> /// </summary>
[Test] [Fact]
public void TestSubobjects() public void TestSubobjects()
{ {
var matFile = GetTests("good")["pointWithSubpoints"]; var matFile = GetTests("good")["pointWithSubpoints"];
var p = matFile["p"].Value as IMatObject; var p = matFile["p"].Value as IMatObject;
Assert.That(p.ClassName, Is.EqualTo("Point")); Assert.Equal("Point", p.ClassName);
var x = p["x"] as IMatObject; var x = p["x"] as IMatObject;
Assert.That(x.ClassName, Is.EqualTo("SubPoint")); Assert.Equal("SubPoint", x.ClassName);
Assert.That(x.FieldNames, Is.EquivalentTo(new[] { "a", "b", "c" })); Assert.Equal(new[] { "a", "b", "c" }, x.FieldNames);
var y = p["y"] as IMatObject; var y = p["y"] as IMatObject;
Assert.That(y.ClassName, Is.EqualTo("SubPoint")); Assert.Equal("SubPoint", y.ClassName);
Assert.That(y.FieldNames, Is.EquivalentTo(new[] { "a", "b", "c" })); Assert.Equal(new[] { "a", "b", "c" }, y.FieldNames);
Assert.That(x["a"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 1.0 })); Assert.Equal(new[] { 1.0 }, x["a"].ConvertToDoubleArray());
Assert.That(x["b"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 2.0 })); Assert.Equal(new[] { 2.0 }, x["b"].ConvertToDoubleArray());
Assert.That(x["c"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 3.0 })); Assert.Equal(new[] { 3.0 }, x["c"].ConvertToDoubleArray());
Assert.That(y["a"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 14.0 })); Assert.Equal(new[] { 14.0 }, y["a"].ConvertToDoubleArray());
Assert.That(y["b"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 15.0 })); Assert.Equal(new[] { 15.0 }, y["b"].ConvertToDoubleArray());
Assert.That(y["c"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 16.0 })); Assert.Equal(new[] { 16.0 }, y["c"].ConvertToDoubleArray());
} }
/// <summary> /// <summary>
/// Test nested objects. /// Test nested objects.
/// </summary> /// </summary>
[Test] [Fact]
public void TestNestedObjects() public void TestNestedObjects()
{ {
var matFile = GetTests("good")["subsubPoint"]; var matFile = GetTests("good")["subsubPoint"];
var p = matFile["p"].Value as IMatObject; var p = matFile["p"].Value as IMatObject;
Assert.That(p.ClassName, Is.EqualTo("Point")); Assert.Equal("Point", p.ClassName);
Assert.That(p["x"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 1.0 })); Assert.Equal(new[] { 1.0 }, p["x"].ConvertToDoubleArray());
var pp = p["y"] as IMatObject; var pp = p["y"] as IMatObject;
Assert.That(pp.ClassName == "Point"); Assert.True(pp.ClassName == "Point");
Assert.That(pp["x"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 10.0 })); Assert.Equal(new[] { 10.0 }, pp["x"].ConvertToDoubleArray());
var ppp = pp["y"] as IMatObject; var ppp = pp["y"] as IMatObject;
Assert.That(ppp["x"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 100.0 })); Assert.Equal(new[] { 100.0 }, ppp["x"].ConvertToDoubleArray());
Assert.That(ppp["y"].ConvertToDoubleArray(), Is.EquivalentTo(new[] { 200.0 })); Assert.Equal(new[] { 200.0 }, ppp["y"].ConvertToDoubleArray());
} }
/// <summary> /// <summary>
/// Test datetime objects. /// Test datetime objects.
/// </summary> /// </summary>
[Test] [Fact]
public void TestDatetime() public void TestDatetime()
{ {
var matFile = GetTests("good")["datetime"]; var matFile = GetTests("good")["datetime"];
var d = matFile["d"].Value as IMatObject; var d = matFile["d"].Value as IMatObject;
var datetime = new DatetimeAdapter(d); var datetime = new DatetimeAdapter(d);
Assert.That(datetime.Dimensions, Is.EquivalentTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, datetime.Dimensions);
Assert.That(datetime[0], Is.EqualTo(new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero))); Assert.Equal(new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero), datetime[0]);
Assert.That(datetime[1], Is.EqualTo(new DateTimeOffset(1987, 1, 2, 3, 4, 5, TimeSpan.Zero))); Assert.Equal(new DateTimeOffset(1987, 1, 2, 3, 4, 5, TimeSpan.Zero), datetime[1]);
} }
/// <summary> /// <summary>
/// Another test for datetime objects. /// Another test for datetime objects.
/// </summary> /// </summary>
[Test] [Fact]
public void TestDatetime2() public void TestDatetime2()
{ {
var matFile = GetTests("good")["datetime2"]; var matFile = GetTests("good")["datetime2"];
var d = matFile["d"].Value as IMatObject; var d = matFile["d"].Value as IMatObject;
var datetime = new DatetimeAdapter(d); var datetime = new DatetimeAdapter(d);
Assert.That(datetime.Dimensions, Is.EquivalentTo(new[] { 1, 1 })); Assert.Equal(new[] { 1, 1 }, datetime.Dimensions);
var diff = new DateTimeOffset(2, 1, 1, 1, 1, 1, 235, TimeSpan.Zero); var diff = new DateTimeOffset(2, 1, 1, 1, 1, 1, 235, TimeSpan.Zero);
Assert.That(datetime[0] - diff < TimeSpan.FromMilliseconds(1)); Assert.True(datetime[0] - diff < TimeSpan.FromMilliseconds(1));
Assert.That(diff - datetime[0] < TimeSpan.FromMilliseconds(1)); Assert.True(diff - datetime[0] < TimeSpan.FromMilliseconds(1));
} }
/// <summary> /// <summary>
/// Test string objects. /// Test string objects.
/// </summary> /// </summary>
[Test] [Fact]
public void TestString() public void TestString()
{ {
var matFile = GetTests("good")["string"]; var matFile = GetTests("good")["string"];
var s = matFile["s"].Value as IMatObject; var s = matFile["s"].Value as IMatObject;
var str = new StringAdapter(s); var str = new StringAdapter(s);
Assert.That(str.Dimensions, Is.EquivalentTo(new[] { 4, 1 })); Assert.Equal(new[] { 4, 1 }, str.Dimensions);
Assert.That(str[0], Is.EqualTo("abc")); Assert.Equal("abc", str[0]);
Assert.That(str[1], Is.EqualTo("defgh")); Assert.Equal("defgh", str[1]);
Assert.That(str[2], Is.EqualTo("абвгд")); Assert.Equal("абвгд", str[2]);
Assert.That(str[3], Is.EqualTo("æøå")); Assert.Equal("æøå", str[3]);
} }
/// <summary> /// <summary>
/// Test duration objects. /// Test duration objects.
/// </summary> /// </summary>
[Test] [Fact]
public void TestDuration() public void TestDuration()
{ {
var matFile = GetTests("good")["duration"]; var matFile = GetTests("good")["duration"];
var d = matFile["d"].Value as IMatObject; var d = matFile["d"].Value as IMatObject;
var duration = new DurationAdapter(d); var duration = new DurationAdapter(d);
Assert.That(duration.Dimensions, Is.EquivalentTo(new[] { 1, 3 })); Assert.Equal(new[] { 1, 3 }, duration.Dimensions);
Assert.That(duration[0], Is.EqualTo(TimeSpan.FromTicks(12345678L))); Assert.Equal(TimeSpan.FromTicks(12345678L), duration[0]);
Assert.That(duration[1], Is.EqualTo(new TimeSpan(0, 2, 4))); Assert.Equal(new TimeSpan(0, 2, 4), duration[1]);
Assert.That(duration[2], Is.EqualTo(new TimeSpan(1, 3, 5))); Assert.Equal(new TimeSpan(1, 3, 5), duration[2]);
} }
/// <summary> /// <summary>
/// Test unrepresentable datetime. /// Test unrepresentable datetime.
/// </summary> /// </summary>
[Test] [Fact]
public void TestDatetime_Unrepresentable() public void TestDatetime_Unrepresentable()
{ {
var matFile = GetTests("good")["datetime-unrepresentable"]; var matFile = GetTests("good")["datetime-unrepresentable"];
var obj = matFile["d"].Value as IMatObject; var obj = matFile["d"].Value as IMatObject;
var datetime = new DatetimeAdapter(obj); var datetime = new DatetimeAdapter(obj);
var d0 = datetime[0]; var d0 = datetime[0];
Assert.That(d0, Is.Null); Assert.Null(d0);
} }
[Test] [Fact]
public void Test_3DArrays() public void Test_3DArrays()
{ {
var matFile = GetTests("good")["issue20.mat"]; var matFile = GetTests("good")["issue20.mat"];
var obj = matFile["a3d"].Value; var obj = matFile["a3d"].Value;
var values = obj.ConvertToDoubleArray(); var values = obj.ConvertToDoubleArray();
Assert.That(values, Is.EqualTo(Enumerable.Range(1, 24))); Assert.Equal(Enumerable.Range(1, 24).Select(x => (double)x).ToArray(), values);
var expected = new double[3, 4, 2] var expected = new double[3, 4, 2]
{ {
{ {
@ -512,17 +515,17 @@ namespace MatFileHandler.Tests
{ 12, 24 }, { 12, 24 },
}, },
}; };
Assert.That(obj.ConvertToMultidimensionalDoubleArray(), Is.EqualTo(expected)); Assert.Equal(expected, obj.ConvertToMultidimensionalDoubleArray());
Assert.That(obj.ConvertTo2dDoubleArray(), Is.EqualTo(null)); Assert.Null(obj.ConvertTo2dDoubleArray());
} }
[Test] [Fact]
public void Test_4DArrays() public void Test_4DArrays()
{ {
var matFile = GetTests("good")["issue20.mat"]; var matFile = GetTests("good")["issue20.mat"];
var obj = matFile["a4d"].Value; var obj = matFile["a4d"].Value;
Assert.That(obj.ConvertToDoubleArray(), Is.EqualTo(Enumerable.Range(1, 120))); Assert.Equal(Enumerable.Range(1, 120).Select(x => (double)x).ToArray(), obj.ConvertToDoubleArray());
Assert.That(obj.ConvertTo2dDoubleArray(), Is.EqualTo(null)); Assert.Null(obj.ConvertTo2dDoubleArray());
} }
private static AbstractTestDataFactory<IMatFile> GetTests(string factoryName) => private static AbstractTestDataFactory<IMatFile> GetTests(string factoryName) =>
@ -531,18 +534,18 @@ namespace MatFileHandler.Tests
private static void CheckLimits<T>(IArrayOf<T> array, T[] limits) private static void CheckLimits<T>(IArrayOf<T> array, T[] limits)
where T : struct where T : struct
{ {
Assert.That(array, Is.Not.Null); Assert.NotNull(array);
Assert.That(array.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, array.Dimensions);
Assert.That(array.Data, Is.EqualTo(limits)); Assert.Equal(limits, array.Data);
} }
private static void CheckComplexLimits<T>(IArrayOf<ComplexOf<T>> array, T[] limits) private static void CheckComplexLimits<T>(IArrayOf<ComplexOf<T>> array, T[] limits)
where T : struct where T : struct
{ {
Assert.That(array, Is.Not.Null); Assert.NotNull(array);
Assert.That(array.Dimensions, Is.EqualTo(new[] { 1, 2 })); Assert.Equal(new[] { 1, 2 }, array.Dimensions);
Assert.That(array[0], Is.EqualTo(new ComplexOf<T>(limits[0], limits[1]))); Assert.Equal(new ComplexOf<T>(limits[0], limits[1]), array[0]);
Assert.That(array[1], Is.EqualTo(new ComplexOf<T>(limits[1], limits[0]))); Assert.Equal(new ComplexOf<T>(limits[1], limits[0]), array[1]);
} }
} }
} }

View File

@ -3,14 +3,13 @@
using System; using System;
using System.IO; using System.IO;
using System.Numerics; using System.Numerics;
using NUnit.Framework; using Xunit;
namespace MatFileHandler.Tests namespace MatFileHandler.Tests
{ {
/// <summary> /// <summary>
/// Tests of file writing API. /// Tests of file writing API.
/// </summary> /// </summary>
[TestFixture]
public class MatFileWriterTests public class MatFileWriterTests
{ {
private const string TestDirectory = "test-data"; private const string TestDirectory = "test-data";
@ -18,7 +17,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a simple Double array. /// Test writing a simple Double array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestWrite() public void TestWrite()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -33,7 +32,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a large file. /// Test writing a large file.
/// </summary> /// </summary>
[Test] [Fact]
public void TestHuge() public void TestHuge()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -52,7 +51,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing lower and upper limits of integer data types. /// Test writing lower and upper limits of integer data types.
/// </summary> /// </summary>
[Test] [Fact]
public void TestLimits() public void TestLimits()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -71,7 +70,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing lower and upper limits of integer-based complex data types. /// Test writing lower and upper limits of integer-based complex data types.
/// </summary> /// </summary>
[Test] [Fact]
public void TestLimitsComplex() public void TestLimitsComplex()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -110,7 +109,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a wide-Unicode symbol. /// Test writing a wide-Unicode symbol.
/// </summary> /// </summary>
[Test] [Fact]
public void TestUnicodeWide() public void TestUnicodeWide()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -122,7 +121,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a sparse array. /// Test writing a sparse array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestSparseArray() public void TestSparseArray()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -139,7 +138,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a structure array. /// Test writing a structure array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestStructure() public void TestStructure()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -167,7 +166,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a logical array. /// Test writing a logical array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestLogical() public void TestLogical()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -180,7 +179,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a sparse logical array. /// Test writing a sparse logical array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestSparseLogical() public void TestSparseLogical()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -197,7 +196,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a sparse complex array. /// Test writing a sparse complex array.
/// </summary> /// </summary>
[Test] [Fact]
public void TestSparseComplex() public void TestSparseComplex()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -213,7 +212,7 @@ namespace MatFileHandler.Tests
/// <summary> /// <summary>
/// Test writing a global variable. /// Test writing a global variable.
/// </summary> /// </summary>
[Test] [Fact]
public void TestGlobal() public void TestGlobal()
{ {
var builder = new DataBuilder(); var builder = new DataBuilder();
@ -229,16 +228,16 @@ namespace MatFileHandler.Tests
private void CompareSparseArrays<T>(ISparseArrayOf<T> expected, ISparseArrayOf<T> actual) private void CompareSparseArrays<T>(ISparseArrayOf<T> expected, ISparseArrayOf<T> actual)
where T : struct where T : struct
{ {
Assert.That(actual, Is.Not.Null); Assert.NotNull(actual);
Assert.That(expected.Dimensions, Is.EqualTo(actual.Dimensions)); Assert.Equal(expected.Dimensions, actual.Dimensions);
Assert.That(expected.Data, Is.EquivalentTo(actual.Data)); Assert.Equal(expected.Data, actual.Data);
} }
private void CompareStructureArrays(IStructureArray expected, IStructureArray actual) private void CompareStructureArrays(IStructureArray expected, IStructureArray actual)
{ {
Assert.That(actual, Is.Not.Null); Assert.NotNull(actual);
Assert.That(expected.Dimensions, Is.EqualTo(actual.Dimensions)); Assert.Equal(expected.Dimensions, actual.Dimensions);
Assert.That(expected.FieldNames, Is.EquivalentTo(actual.FieldNames)); Assert.Equal(expected.FieldNames, actual.FieldNames);
foreach (var name in expected.FieldNames) foreach (var name in expected.FieldNames)
{ {
for (var i = 0; i < expected.Count; i++) for (var i = 0; i < expected.Count; i++)
@ -250,8 +249,8 @@ namespace MatFileHandler.Tests
private void CompareCellArrays(ICellArray expected, ICellArray actual) private void CompareCellArrays(ICellArray expected, ICellArray actual)
{ {
Assert.That(actual, Is.Not.Null); Assert.NotNull(actual);
Assert.That(expected.Dimensions, Is.EqualTo(actual.Dimensions)); Assert.Equal(expected.Dimensions, actual.Dimensions);
for (var i = 0; i < expected.Count; i++) for (var i = 0; i < expected.Count; i++)
{ {
CompareMatArrays(expected[i], actual[i]); CompareMatArrays(expected[i], actual[i]);
@ -260,16 +259,16 @@ namespace MatFileHandler.Tests
private void CompareNumericalArrays<T>(IArrayOf<T> expected, IArrayOf<T> actual) private void CompareNumericalArrays<T>(IArrayOf<T> expected, IArrayOf<T> actual)
{ {
Assert.That(actual, Is.Not.Null); Assert.NotNull(actual);
Assert.That(expected.Dimensions, Is.EqualTo(actual.Dimensions)); Assert.Equal(expected.Dimensions, actual.Dimensions);
Assert.That(expected.Data, Is.EqualTo(actual.Data)); Assert.Equal(expected.Data, actual.Data);
} }
private void CompareCharArrays(ICharArray expected, ICharArray actual) private void CompareCharArrays(ICharArray expected, ICharArray actual)
{ {
Assert.That(actual, Is.Not.Null); Assert.NotNull(actual);
Assert.That(expected.Dimensions, Is.EqualTo(actual.Dimensions)); Assert.Equal(expected.Dimensions, actual.Dimensions);
Assert.That(expected.String, Is.EqualTo(actual.String)); Assert.Equal(expected.String, actual.String);
} }
private void CompareMatArrays(IArray expected, IArray actual) private void CompareMatArrays(IArray expected, IArray actual)
@ -357,7 +356,7 @@ namespace MatFileHandler.Tests
} }
if (expected.IsEmpty) if (expected.IsEmpty)
{ {
Assert.That(actual.IsEmpty, Is.True); Assert.True(actual.IsEmpty);
return; return;
} }
throw new NotSupportedException(); throw new NotSupportedException();
@ -365,13 +364,13 @@ namespace MatFileHandler.Tests
private void CompareMatFiles(IMatFile expected, IMatFile actual) private void CompareMatFiles(IMatFile expected, IMatFile actual)
{ {
Assert.That(expected.Variables.Length, Is.EqualTo(actual.Variables.Length)); Assert.Equal(expected.Variables.Length, actual.Variables.Length);
for (var i = 0; i < expected.Variables.Length; i++) for (var i = 0; i < expected.Variables.Length; i++)
{ {
var expectedVariable = expected.Variables[i]; var expectedVariable = expected.Variables[i];
var actualVariable = actual.Variables[i]; var actualVariable = actual.Variables[i];
Assert.That(expectedVariable.Name, Is.EqualTo(actualVariable.Name)); Assert.Equal(expectedVariable.Name, actualVariable.Name);
Assert.That(expectedVariable.IsGlobal, Is.EqualTo(actualVariable.IsGlobal)); Assert.Equal(expectedVariable.IsGlobal, actualVariable.IsGlobal);
CompareMatArrays(expectedVariable.Value, actualVariable.Value); CompareMatArrays(expectedVariable.Value, actualVariable.Value);
} }
} }

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks> <TargetFrameworks>netstandard2.0;net461;net472</TargetFrameworks>
<PackageVersion>1.4.0-beta1</PackageVersion> <PackageVersion>1.4.0-beta2</PackageVersion>
<PackageId>MatFileHandler</PackageId> <PackageId>MatFileHandler</PackageId>
<Title>A library for reading and writing MATLAB .mat files.</Title> <Title>A library for reading and writing MATLAB .mat files.</Title>
<Authors>Alexander Luzgarev</Authors> <Authors>Alexander Luzgarev</Authors>

View File

@ -42,7 +42,7 @@ namespace MatFileHandler
var embeddedObjectPositionsToValues = ReadEmbeddedObjectPositionsToValues(info, offsets, numberOfEmbeddedObjects); var embeddedObjectPositionsToValues = ReadEmbeddedObjectPositionsToValues(info, offsets, numberOfEmbeddedObjects);
var numberOfObjects = ((offsets[5] - offsets[4]) / 24) - 1; var numberOfObjects = ((offsets[5] - offsets[4]) / 24) - 1;
var objectClasses = ReadObjectClassInformations(info, offsets, numberOfObjects); var objectClasses = ReadObjectClassInformations(info, offsets, numberOfObjects);
var numberOfObjectPositions = objectClasses.Values.Count(x => x.ObjectPosition != 0); var numberOfObjectPositions = objectClasses.NumberOfObjectPositions;
var objectPositionsToValues = ReadObjectPositionsToValues(info, offsets, numberOfObjectPositions); var objectPositionsToValues = ReadObjectPositionsToValues(info, offsets, numberOfObjectPositions);
var (classInformation, objectInformation) = var (classInformation, objectInformation) =
GatherClassAndObjectInformation( GatherClassAndObjectInformation(
@ -68,7 +68,7 @@ namespace MatFileHandler
return ReadObjectPositionsToValuesMapping(reader, numberOfObjectPositions); return ReadObjectPositionsToValuesMapping(reader, numberOfObjectPositions);
} }
private static Dictionary<int, ObjectClassInformation> ReadObjectClassInformations(byte[] info, int[] offsets, int numberOfObjects) private static ObjectClasses ReadObjectClassInformations(byte[] info, int[] offsets, int numberOfObjects)
{ {
using var stream = new MemoryStream(info, offsets[4], offsets[5] - offsets[4]); using var stream = new MemoryStream(info, offsets[4], offsets[5] - offsets[4]);
using var reader = new BinaryReader(stream); using var reader = new BinaryReader(stream);
@ -102,7 +102,7 @@ namespace MatFileHandler
GatherClassAndObjectInformation( GatherClassAndObjectInformation(
Dictionary<int, string> classIdToName, Dictionary<int, string> classIdToName,
string[] fieldNames, string[] fieldNames,
Dictionary<int, ObjectClassInformation> objectClasses, ObjectClasses objectClasses,
Dictionary<int, Dictionary<int, int>> objectPositionsToValues, Dictionary<int, Dictionary<int, int>> objectPositionsToValues,
Dictionary<int, Dictionary<int, int>> embeddedObjectPositionsToValues) Dictionary<int, Dictionary<int, int>> embeddedObjectPositionsToValues)
{ {
@ -113,8 +113,8 @@ namespace MatFileHandler
var fieldIds = new SortedSet<int>(); var fieldIds = new SortedSet<int>();
foreach (var objectPosition in objectPositionsToValues.Keys) foreach (var objectPosition in objectPositionsToValues.Keys)
{ {
var keyValuePair = objectClasses.First(pair => pair.Value.ObjectPosition == objectPosition); var foundClassId = objectClasses.GetClassIdByObjectPosition(objectPosition);
if (keyValuePair.Value.ClassId != classId) if (foundClassId != classId)
{ {
continue; continue;
} }
@ -127,8 +127,8 @@ namespace MatFileHandler
foreach (var objectPosition in embeddedObjectPositionsToValues.Keys) foreach (var objectPosition in embeddedObjectPositionsToValues.Keys)
{ {
var keyValuePair = objectClasses.First(pair => pair.Value.EmbeddedObjectPosition == objectPosition); var foundClassId = objectClasses.GetClassIdByEmbeddedObjectPosition(objectPosition);
if (keyValuePair.Value.ClassId != classId) if (foundClassId != classId)
{ {
continue; continue;
} }
@ -151,15 +151,14 @@ namespace MatFileHandler
var objectInfos = new Dictionary<int, SubsystemData.ObjectInfo>(); var objectInfos = new Dictionary<int, SubsystemData.ObjectInfo>();
foreach (var objectPosition in objectPositionsToValues.Keys) foreach (var objectPosition in objectPositionsToValues.Keys)
{ {
var keyValuePair = objectClasses.First(pair => pair.Value.ObjectPosition == objectPosition); var foundKey = objectClasses.GetKeyByObjectPosition(objectPosition);
objectInfos[keyValuePair.Key] = new SubsystemData.ObjectInfo(objectPositionsToValues[objectPosition]); objectInfos[foundKey] = new SubsystemData.ObjectInfo(objectPositionsToValues[objectPosition]);
} }
foreach (var objectPosition in embeddedObjectPositionsToValues.Keys) foreach (var embeddedObjectPosition in embeddedObjectPositionsToValues.Keys)
{ {
var keyValuePair = objectClasses.First(pair => pair.Value.EmbeddedObjectPosition == objectPosition); var foundKey = objectClasses.GetKeyByEmbeddedObjectPosition(embeddedObjectPosition);
objectInfos[keyValuePair.Key] = objectInfos[foundKey] = new SubsystemData.ObjectInfo(embeddedObjectPositionsToValues[embeddedObjectPosition]);
new SubsystemData.ObjectInfo(embeddedObjectPositionsToValues[objectPosition]);
} }
return (classInfos, objectInfos); return (classInfos, objectInfos);
@ -241,24 +240,40 @@ namespace MatFileHandler
return result; return result;
} }
private static Dictionary<int, ObjectClassInformation> ReadObjectClasses( private static ObjectClasses ReadObjectClasses(
BinaryReader reader, BinaryReader reader,
int numberOfObjects) int numberOfObjects)
{ {
var result = new Dictionary<int, ObjectClassInformation>(); var result = new Dictionary<int, ObjectClassInformation>();
var classIdFromObjectPosition = new Dictionary<int, int>();
var classIdFromEmbeddedObjectPosition = new Dictionary<int, int>();
var keyFromObjectPosition = new Dictionary<int, int>();
var keyFromEmbeddedObjectPosition = new Dictionary<int, int>();
reader.ReadBytes(24); reader.ReadBytes(24);
var numberOfObjectPositions = 0;
for (var i = 0; i < numberOfObjects; i++) for (var i = 0; i < numberOfObjects; i++)
{ {
var classId = reader.ReadInt32(); var classId = reader.ReadInt32();
reader.ReadBytes(8); reader.ReadBytes(8);
var embeddedObjectPosition = reader.ReadInt32(); var embeddedObjectPosition = reader.ReadInt32();
var objectPosition = reader.ReadInt32(); var objectPosition = reader.ReadInt32();
var loadingOrder = reader.ReadInt32(); var loadingOrder = reader.ReadInt32(); // Not used.
result[i + 1] = classIdFromObjectPosition[objectPosition] = classId;
new ObjectClassInformation(embeddedObjectPosition, objectPosition, loadingOrder, classId); classIdFromEmbeddedObjectPosition[embeddedObjectPosition] = classId;
keyFromObjectPosition[objectPosition] = i + 1;
keyFromEmbeddedObjectPosition[embeddedObjectPosition] = i + 1;
if (objectPosition != 0)
{
numberOfObjectPositions++;
}
} }
return result; return new ObjectClasses(
classIdFromObjectPosition,
classIdFromEmbeddedObjectPosition,
keyFromObjectPosition,
keyFromEmbeddedObjectPosition,
numberOfObjectPositions);
} }
private static Dictionary<int, Dictionary<int, int>> ReadObjectPositionsToValuesMapping( private static Dictionary<int, Dictionary<int, int>> ReadObjectPositionsToValuesMapping(
@ -344,5 +359,41 @@ namespace MatFileHandler
public int ObjectPosition { get; } public int ObjectPosition { get; }
} }
private class ObjectClasses
{
private readonly Dictionary<int, int> _classIdFromObjectPosition;
private readonly Dictionary<int, int> _classIdFromEmbeddedObjectPosition;
private readonly Dictionary<int, int> _keyFromObjectPosition;
private readonly Dictionary<int, int> _keyFromEmbeddedObjectPosition;
public ObjectClasses(
Dictionary<int, int> classIdFromObjectPosition,
Dictionary<int, int> classIdFromEmbeddedObjectPosition,
Dictionary<int, int> keyFromObjectPosition,
Dictionary<int, int> keyFromEmbeddedObjectPosition,
int numberOfObjectPositions)
{
_classIdFromObjectPosition = classIdFromObjectPosition;
_classIdFromEmbeddedObjectPosition = classIdFromEmbeddedObjectPosition;
_keyFromObjectPosition = keyFromObjectPosition;
_keyFromEmbeddedObjectPosition = keyFromEmbeddedObjectPosition;
NumberOfObjectPositions = numberOfObjectPositions;
}
public int NumberOfObjectPositions { get; }
public int GetClassIdByObjectPosition(int objectPosition)
=> _classIdFromObjectPosition[objectPosition];
public int GetClassIdByEmbeddedObjectPosition(int embeddedObjectPosition)
=> _classIdFromEmbeddedObjectPosition[embeddedObjectPosition];
public int GetKeyByObjectPosition(int objectPosition)
=> _keyFromObjectPosition[objectPosition];
public int GetKeyByEmbeddedObjectPosition(int embeddedObjectPosition)
=> _keyFromEmbeddedObjectPosition[embeddedObjectPosition];
}
} }
} }

View File

@ -11,9 +11,9 @@ variables:
steps: steps:
- task: UseDotNet@2 - task: UseDotNet@2
displayName: 'Use .NET Core SDK 5.x' displayName: 'Use .NET Core SDK 8.x'
inputs: inputs:
version: 5.x version: 8.x
- script: dotnet build --configuration $(buildConfiguration) - script: dotnet build --configuration $(buildConfiguration)
displayName: 'dotnet build $(buildConfiguration)' displayName: 'dotnet build $(buildConfiguration)'