Handle nested item comparisons, add Equals tests

This commit is contained in:
Matt Nadareski
2025-01-08 11:36:43 -05:00
parent 8cf360a747
commit 5b430804d7
12 changed files with 501 additions and 4 deletions

View File

@@ -18,7 +18,142 @@ namespace SabreTools.Core.Test
/// <summary>
/// Testing implementation of ModelBackedItem
/// </summary>
private class TestModelBackedItem : ModelBackedItem<TestDictionaryBase> { }
private class TestModelBackedItem : ModelBackedItem<TestDictionaryBase>
{
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not TestModelBackedItem otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<TestDictionaryBase>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not TestModelBackedItem otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
#endregion
}
/// <summary>
/// Alternate testing implementation of ModelBackedItem
/// </summary>
private class TestModelAltBackedItem : ModelBackedItem<TestDictionaryBase>
{
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not TestModelAltBackedItem otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<TestDictionaryBase>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not TestModelAltBackedItem otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
#endregion
}
#endregion
#region Equals
[Fact]
public void Equals_NullOther_False()
{
ModelBackedItem self = new TestModelBackedItem();
ModelBackedItem? other = null;
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_MismatchedType_False()
{
ModelBackedItem self = new TestModelBackedItem();
ModelBackedItem? other = new TestModelAltBackedItem();
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_MismatchedTypeAlt_False()
{
ModelBackedItem self = new TestModelAltBackedItem();
ModelBackedItem? other = new TestModelBackedItem();
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_DifferentModels_False()
{
ModelBackedItem<TestDictionaryBase> self = new TestModelBackedItem();
self.SetFieldValue(TestDictionaryBase.NameKey, "self");
ModelBackedItem<TestDictionaryBase>? other = new TestModelBackedItem();
other.SetFieldValue(TestDictionaryBase.NameKey, "other");
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_EqualModels_True()
{
ModelBackedItem<TestDictionaryBase> self = new TestModelBackedItem();
self.SetFieldValue(TestDictionaryBase.NameKey, "name");
ModelBackedItem<TestDictionaryBase>? other = new TestModelBackedItem();
other.SetFieldValue(TestDictionaryBase.NameKey, "name");
bool actual = self.Equals(other);
Assert.True(actual);
}
#endregion

View File

@@ -163,6 +163,11 @@ namespace SabreTools.Core
return false;
break;
case (ModelBackedItem selfMbi, ModelBackedItem otherMbi):
if (!selfMbi.Equals(otherMbi))
return false;
break;
case (DictionaryBase selfDb, DictionaryBase otherDb):
if (!selfDb.Equals(otherDb))
return false;

View File

@@ -8,7 +8,20 @@ namespace SabreTools.Core
/// <summary>
/// Represents an item that's backed by a DictionaryBase item
/// </summary>
public abstract class ModelBackedItem<T> where T : Models.Metadata.DictionaryBase
public abstract class ModelBackedItem : IEquatable<ModelBackedItem>
{
#region Comparision Methods
/// <inheritdoc/>
public abstract bool Equals(ModelBackedItem? other);
#endregion
}
/// <summary>
/// Represents an item that's backed by a DictionaryBase item
/// </summary>
public abstract class ModelBackedItem<T> : ModelBackedItem, IEquatable<ModelBackedItem<T>> where T : Models.Metadata.DictionaryBase
{
/// <summary>
/// Internal model wrapped by this DatItem
@@ -150,6 +163,13 @@ namespace SabreTools.Core
#endregion
#region Comparision Methods
/// <inheritdoc/>
public abstract bool Equals(ModelBackedItem<T>? other);
#endregion
#region Manipulation
/// <summary>

View File

@@ -370,6 +370,40 @@ namespace SabreTools.DatFiles
#endregion
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatHeader otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.Header>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatHeader otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
#endregion
#region Manipulation
/// <summary>

View File

@@ -5,6 +5,28 @@ namespace SabreTools.DatItems.Test
{
public class DatItemTests
{
#region Private Testing Classes
/// <summary>
/// Testing implementation of Models.Metadata.DatItem
/// </summary>
private class TestDatItemModel : Models.Metadata.DatItem
{
public const string NameKey = "__NAME__";
}
/// <summary>
/// Testing implementation of DatItem
/// </summary>
private class TestDatItem : DatItem<TestDatItemModel>
{
protected override string? NameKey => TestDatItemModel.NameKey;
protected override ItemType ItemType => ItemType.Blank;
}
#endregion
#region CopyMachineInformation
[Fact]
@@ -186,7 +208,61 @@ namespace SabreTools.DatItems.Test
#region Equals
// TODO: Implement Equals tests
[Fact]
public void Equals_Null_False()
{
DatItem self = new TestDatItem();
DatItem? other = null;
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_MismatchedType_False()
{
DatItem self = new TestDatItem();
DatItem? other = new Rom();
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_DefaultInternal_True()
{
DatItem self = new TestDatItem();
DatItem? other = new TestDatItem();
bool actual = self.Equals(other);
Assert.True(actual);
}
[Fact]
public void Equals_MismatchedInternal_False()
{
DatItem self = new TestDatItem();
self.SetName("self");
DatItem? other = new TestDatItem();
other.SetName("other");
bool actual = self.Equals(other);
Assert.False(actual);
}
[Fact]
public void Equals_EqualInternal_True()
{
DatItem self = new TestDatItem();
self.SetName("name");
DatItem? other = new TestDatItem();
other.SetName("name");
bool actual = self.Equals(other);
Assert.True(actual);
}
#endregion

View File

@@ -181,8 +181,16 @@ namespace SabreTools.DatItems
/// <returns>True if the items are duplicates, false otherwise</returns>
public virtual bool Equals(DatItem? other)
{
// If the other item is null
if (other == null)
return false;
// Get the types for comparison
ItemType selfType = GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue<ItemType>();
ItemType otherType = other.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue<ItemType>();
// If we don't have a matched type, return false
if (GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue<ItemType>() != other?.GetStringFieldValue(Models.Metadata.DatItem.TypeKey).AsEnumValue<ItemType>())
if (selfType != otherType)
return false;
// Compare the internal models
@@ -564,6 +572,36 @@ namespace SabreTools.DatItems
return string.Compare(selfName, otherName, StringComparison.Ordinal);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem<T> otherItem)
return false;
// Compare internal models
return _internal.Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.DatItem>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem<T> otherItem)
return false;
// Compare internal models
return _internal.Equals(otherItem);
}
/// <summary>
/// Determine if an item is a duplicate using partial matching logic
/// </summary>

View File

@@ -1,5 +1,6 @@
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Core;
using SabreTools.Core.Tools;
namespace SabreTools.DatItems.Formats
@@ -47,6 +48,36 @@ namespace SabreTools.DatItems.Formats
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.DatItem>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{

View File

@@ -1,6 +1,7 @@
using System.Linq;
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Core;
using SabreTools.Core.Tools;
using SabreTools.Hashing;
using SabreTools.IO.Extensions;
@@ -154,6 +155,36 @@ namespace SabreTools.DatItems.Formats
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.DatItem>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{

View File

@@ -1,5 +1,6 @@
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Core;
using SabreTools.Core.Tools;
// TODO: Add item mappings for all fields
@@ -157,6 +158,36 @@ namespace SabreTools.DatItems.Formats
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.DatItem>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{

View File

@@ -1,5 +1,6 @@
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Core;
using SabreTools.Core.Tools;
// TODO: Add item mappings for all fields
@@ -149,6 +150,36 @@ namespace SabreTools.DatItems.Formats
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.DatItem>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{

View File

@@ -1,5 +1,6 @@
using System.Xml.Serialization;
using Newtonsoft.Json;
using SabreTools.Core;
using SabreTools.Core.Tools;
// TODO: Add item mappings for all fields
@@ -192,6 +193,36 @@ namespace SabreTools.DatItems.Formats
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.DatItem>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not DatItem otherItem)
return false;
// Compare internal models
return Equals(otherItem);
}
/// <inheritdoc/>
public override bool Equals(DatItem? other)
{

View File

@@ -82,6 +82,40 @@ namespace SabreTools.DatItems
#endregion
#region Comparision Methods
/// <inheritdoc/>
public override bool Equals(ModelBackedItem? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not Machine otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
/// <inheritdoc/>
public override bool Equals(ModelBackedItem<Models.Metadata.Machine>? other)
{
// If other is null
if (other == null)
return false;
// If the type is mismatched
if (other is not Machine otherItem)
return false;
// Compare internal models
return _internal.EqualTo(otherItem._internal);
}
#endregion
#region Manipulation
/// <summary>