mirror of
https://github.com/claunia/SabreTools.git
synced 2025-12-16 19:14:27 +00:00
Add separated-value deserialization test
This commit is contained in:
9
SabreTools.Models/SeparatedValue/MetadataFile.cs
Normal file
9
SabreTools.Models/SeparatedValue/MetadataFile.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
namespace SabreTools.Models.SeparatedValue
|
||||||
|
{
|
||||||
|
public class MetadataFile
|
||||||
|
{
|
||||||
|
public string[] Header { get; set; }
|
||||||
|
|
||||||
|
public Row[]? Row { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
66
SabreTools.Models/SeparatedValue/Row.cs
Normal file
66
SabreTools.Models/SeparatedValue/Row.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
namespace SabreTools.Models.SeparatedValue
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Standardized variant of a row
|
||||||
|
/// </summary>
|
||||||
|
public class Row
|
||||||
|
{
|
||||||
|
/// <remarks>File Name</remarks>
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Internal Name</remarks>
|
||||||
|
public string InternalName { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Description</remarks>
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Game Name</remarks>
|
||||||
|
public string GameName { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Game Description</remarks>
|
||||||
|
public string GameDescription { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Type</remarks>
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Rom Name</remarks>
|
||||||
|
public string RomName { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Disk Name</remarks>
|
||||||
|
public string DiskName { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Size, Numeric</remarks>
|
||||||
|
public string Size { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>CRC</remarks>
|
||||||
|
public string CRC { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>MD5</remarks>
|
||||||
|
public string MD5 { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>SHA1</remarks>
|
||||||
|
public string SHA1 { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>SHA256</remarks>
|
||||||
|
public string SHA256 { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>SHA384, Optional</remarks>
|
||||||
|
public string SHA384 { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>SHA512, Optional</remarks>
|
||||||
|
public string SHA512 { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>SpamSum, Optional</remarks>
|
||||||
|
public string SpamSum { get; set; }
|
||||||
|
|
||||||
|
/// <remarks>Nodump</remarks>
|
||||||
|
public string Nodump { get; set; }
|
||||||
|
|
||||||
|
#region DO NOT USE IN PRODUCTION
|
||||||
|
|
||||||
|
/// <remarks>Should be empty</remarks>
|
||||||
|
public string[]? ADDITIONAL_ELEMENTS { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,7 +73,7 @@ namespace SabreTools.Serialization
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// Parse the line into a row
|
// Parse the line into a row
|
||||||
Row row = null;
|
Row? row = null;
|
||||||
if (reader.Line.Count < HeaderWithRomnameCount)
|
if (reader.Line.Count < HeaderWithRomnameCount)
|
||||||
{
|
{
|
||||||
row = new Row
|
row = new Row
|
||||||
|
|||||||
143
SabreTools.Serialization/SeparatedValue.cs
Normal file
143
SabreTools.Serialization/SeparatedValue.cs
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using SabreTools.IO.Readers;
|
||||||
|
using SabreTools.Models.SeparatedValue;
|
||||||
|
|
||||||
|
namespace SabreTools.Serialization
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serializer for separated-value variants
|
||||||
|
/// </summary>
|
||||||
|
public class SeparatedValue
|
||||||
|
{
|
||||||
|
private const int HeaderWithoutExtendedHashesCount = 14;
|
||||||
|
|
||||||
|
private const int HeaderWithExtendedHashesCount = 17;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deserializes a separated-value variant to the defined type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to the file to deserialize</param>
|
||||||
|
/// <param name="delim">Character delimiter between values</param>
|
||||||
|
/// <returns>Deserialized data on success, null on failure</returns>
|
||||||
|
public static MetadataFile? Deserialize(string path, char delim)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using var stream = PathProcessor.OpenStream(path);
|
||||||
|
return Deserialize(stream, delim);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// TODO: Handle logging the exception
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Deserializes a separated-value variant in a stream to the defined type
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Stream to deserialize</param>
|
||||||
|
/// <param name="delim">Character delimiter between values</param>
|
||||||
|
/// <returns>Deserialized data on success, null on failure</returns>
|
||||||
|
public static MetadataFile? Deserialize(Stream? stream, char delim)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// If the stream is null
|
||||||
|
if (stream == null)
|
||||||
|
return default;
|
||||||
|
|
||||||
|
// Setup the reader and output
|
||||||
|
var reader = new SeparatedValueReader(stream, Encoding.UTF8)
|
||||||
|
{
|
||||||
|
Header = true,
|
||||||
|
Separator = delim,
|
||||||
|
VerifyFieldCount = false,
|
||||||
|
};
|
||||||
|
var dat = new MetadataFile();
|
||||||
|
|
||||||
|
// Read the header values first
|
||||||
|
if (!reader.ReadHeader())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
dat.Header = reader.HeaderValues.ToArray();
|
||||||
|
|
||||||
|
// Loop through the rows and parse out values
|
||||||
|
var rows = new List<Row>();
|
||||||
|
while (!reader.EndOfStream)
|
||||||
|
{
|
||||||
|
// If we have no next line
|
||||||
|
if (!reader.ReadNextLine())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Parse the line into a row
|
||||||
|
Row? row = null;
|
||||||
|
if (reader.Line.Count < HeaderWithExtendedHashesCount)
|
||||||
|
{
|
||||||
|
row = new Row
|
||||||
|
{
|
||||||
|
FileName = reader.Line[0],
|
||||||
|
InternalName = reader.Line[1],
|
||||||
|
Description = reader.Line[2],
|
||||||
|
GameName = reader.Line[3],
|
||||||
|
GameDescription = reader.Line[4],
|
||||||
|
Type = reader.Line[5],
|
||||||
|
RomName = reader.Line[6],
|
||||||
|
DiskName = reader.Line[7],
|
||||||
|
Size = reader.Line[8],
|
||||||
|
CRC = reader.Line[9],
|
||||||
|
MD5 = reader.Line[10],
|
||||||
|
SHA1 = reader.Line[11],
|
||||||
|
SHA256 = reader.Line[12],
|
||||||
|
Nodump = reader.Line[13],
|
||||||
|
};
|
||||||
|
|
||||||
|
// If we have additional fields
|
||||||
|
if (reader.Line.Count > HeaderWithoutExtendedHashesCount)
|
||||||
|
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithoutExtendedHashesCount).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
row = new Row
|
||||||
|
{
|
||||||
|
FileName = reader.Line[0],
|
||||||
|
InternalName = reader.Line[1],
|
||||||
|
Description = reader.Line[2],
|
||||||
|
GameName = reader.Line[3],
|
||||||
|
GameDescription = reader.Line[4],
|
||||||
|
Type = reader.Line[5],
|
||||||
|
RomName = reader.Line[6],
|
||||||
|
DiskName = reader.Line[7],
|
||||||
|
Size = reader.Line[8],
|
||||||
|
CRC = reader.Line[9],
|
||||||
|
MD5 = reader.Line[10],
|
||||||
|
SHA1 = reader.Line[11],
|
||||||
|
SHA256 = reader.Line[12],
|
||||||
|
SHA384 = reader.Line[13],
|
||||||
|
SHA512 = reader.Line[14],
|
||||||
|
SpamSum = reader.Line[15],
|
||||||
|
Nodump = reader.Line[16],
|
||||||
|
};
|
||||||
|
|
||||||
|
// If we have additional fields
|
||||||
|
if (reader.Line.Count > HeaderWithExtendedHashesCount)
|
||||||
|
row.ADDITIONAL_ELEMENTS = reader.Line.Skip(HeaderWithExtendedHashesCount).ToArray();
|
||||||
|
}
|
||||||
|
rows.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the rows to the Dat and return
|
||||||
|
dat.Row = rows.ToArray();
|
||||||
|
return dat;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// TODO: Handle logging the exception
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -816,6 +816,32 @@ namespace SabreTools.Test.Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Theory]
|
||||||
|
[InlineData("test-csv-files1.csv", ',', 2)]
|
||||||
|
[InlineData("test-csv-files2.csv", ',', 2)]
|
||||||
|
[InlineData("test-ssv-files1.ssv", ';', 2)]
|
||||||
|
[InlineData("test-ssv-files2.ssv", ';', 2)]
|
||||||
|
[InlineData("test-tsv-files2.tsv", '\t', 2)]
|
||||||
|
[InlineData("test-tsv-files1.tsv", '\t', 2)]
|
||||||
|
public void SeparatedValueDeserializeTest(string path, char delim, long count)
|
||||||
|
{
|
||||||
|
// Open the file for reading
|
||||||
|
string filename = System.IO.Path.Combine(Environment.CurrentDirectory, "TestData", path);
|
||||||
|
|
||||||
|
// Deserialize the file
|
||||||
|
var dat = Serialization.SeparatedValue.Deserialize(filename, delim);
|
||||||
|
|
||||||
|
// Validate the values
|
||||||
|
Assert.NotNull(dat);
|
||||||
|
Assert.Equal(count, dat.Row.Length);
|
||||||
|
|
||||||
|
// Validate we're not missing any attributes or elements
|
||||||
|
foreach (var rom in dat.Row ?? Array.Empty<Models.SeparatedValue.Row>())
|
||||||
|
{
|
||||||
|
Assert.Null(rom.ADDITIONAL_ELEMENTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData("test-softwarelist-files1.xml", 4531)]
|
[InlineData("test-softwarelist-files1.xml", 4531)]
|
||||||
[InlineData("test-softwarelist-files2.xml", 2797)]
|
[InlineData("test-softwarelist-files2.xml", 2797)]
|
||||||
|
|||||||
3
SabreTools.Test/TestData/test-csv-files1.csv
Normal file
3
SabreTools.Test/TestData/test-csv-files1.csv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
File Name,Internal Name,Description,Game Name,Game Description,Type,Rom Name,Disk Name,Size,CRC,MD5,SHA1,SHA256,Nodump
|
||||||
|
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Rom,file.bin,,12345,0,d41d8cd98f00b204e9800998ecf8427e,da39a3ee5e6b4b0d3255bfef95601890afd80709,ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad,No
|
||||||
|
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Disk,,file.chd,,,,da39a3ee5e6b4b0d3255bfef95601890afd80709,,No
|
||||||
|
3
SabreTools.Test/TestData/test-csv-files2.csv
Normal file
3
SabreTools.Test/TestData/test-csv-files2.csv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
File Name,Internal Name,Description,Game Name,Game Description,Type,Rom Name,Disk Name,Size,CRC,MD5,SHA1,SHA256,SHA384,SHA512,SpamSum,Nodump
|
||||||
|
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Rom,file.bin,,12345,0,d41d8cd98f00b204e9800998ecf8427e,da39a3ee5e6b4b0d3255bfef95601890afd80709,ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad,cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7,ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f,QXX,No
|
||||||
|
Original DatFile Name.xml,Original DatFile Name,Original DatFile,Game,A cool game,Disk,,file.chd,,,,da39a3ee5e6b4b0d3255bfef95601890afd80709,,,,,No
|
||||||
|
3
SabreTools.Test/TestData/test-ssv-files1.ssv
Normal file
3
SabreTools.Test/TestData/test-ssv-files1.ssv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
File Name;Internal Name;Description;Game Name;Game Description;Type;Rom Name;Disk Name;Size;CRC;MD5;SHA1;SHA256;Nodump
|
||||||
|
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Rom;file.bin;;12345;0;d41d8cd98f00b204e9800998ecf8427e;da39a3ee5e6b4b0d3255bfef95601890afd80709;ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad;No
|
||||||
|
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Disk;;file.chd;;;;da39a3ee5e6b4b0d3255bfef95601890afd80709;;No
|
||||||
3
SabreTools.Test/TestData/test-ssv-files2.ssv
Normal file
3
SabreTools.Test/TestData/test-ssv-files2.ssv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
File Name;Internal Name;Description;Game Name;Game Description;Type;Rom Name;Disk Name;Size;CRC;MD5;SHA1;SHA256;SHA384;SHA512;SpamSum;Nodump
|
||||||
|
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Rom;file.bin;;12345;0;d41d8cd98f00b204e9800998ecf8427e;da39a3ee5e6b4b0d3255bfef95601890afd80709;ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad;cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7;ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f;QXX;No
|
||||||
|
Original DatFile Name.xml;Original DatFile Name;Original DatFile;Game;A cool game;Disk;;file.chd;;;;da39a3ee5e6b4b0d3255bfef95601890afd80709;;;;;No
|
||||||
3
SabreTools.Test/TestData/test-tsv-files1.tsv
Normal file
3
SabreTools.Test/TestData/test-tsv-files1.tsv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
File Name Internal Name Description Game Name Game Description Type Rom Name Disk Name Size CRC MD5 SHA1 SHA256 Nodump
|
||||||
|
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Rom file.bin 12345 0 d41d8cd98f00b204e9800998ecf8427e da39a3ee5e6b4b0d3255bfef95601890afd80709 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad No
|
||||||
|
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Disk file.chd da39a3ee5e6b4b0d3255bfef95601890afd80709 No
|
||||||
|
3
SabreTools.Test/TestData/test-tsv-files2.tsv
Normal file
3
SabreTools.Test/TestData/test-tsv-files2.tsv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
File Name Internal Name Description Game Name Game Description Type Rom Name Disk Name Size CRC MD5 SHA1 SHA256 SHA384 SHA512 SpamSum Nodump
|
||||||
|
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Rom file.bin 12345 0 d41d8cd98f00b204e9800998ecf8427e da39a3ee5e6b4b0d3255bfef95601890afd80709 ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7 ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f QXX No
|
||||||
|
Original DatFile Name.xml Original DatFile Name Original DatFile Game A cool game Disk file.chd da39a3ee5e6b4b0d3255bfef95601890afd80709 No
|
||||||
|
Reference in New Issue
Block a user