Reformat / cleanup
This commit is contained in:
@@ -1,159 +1,187 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using ZB.MOM.WW.CBDD.Bson;
|
||||
using ZB.MOM.WW.CBDD.Shared;
|
||||
using ZB.MOM.WW.CBDD.Shared.TestDbContext_TestDbContext_Mappers;
|
||||
|
||||
namespace ZB.MOM.WW.CBDD.Tests
|
||||
namespace ZB.MOM.WW.CBDD.Tests;
|
||||
|
||||
public class AttributeTests
|
||||
{
|
||||
public class AttributeTests
|
||||
private readonly ConcurrentDictionary<string, ushort> _keyMap = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly ConcurrentDictionary<ushort, string> _keys = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes lookup maps used by attribute mapper tests.
|
||||
/// </summary>
|
||||
public AttributeTests()
|
||||
{
|
||||
// Use full path for mapper until we are sure of the namespace
|
||||
private ZB_MOM_WW_CBDD_Shared_AnnotatedUserMapper CreateMapper() => new();
|
||||
|
||||
private readonly System.Collections.Concurrent.ConcurrentDictionary<string, ushort> _keyMap = new(StringComparer.OrdinalIgnoreCase);
|
||||
private readonly System.Collections.Concurrent.ConcurrentDictionary<ushort, string> _keys = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes lookup maps used by attribute mapper tests.
|
||||
/// </summary>
|
||||
public AttributeTests()
|
||||
ushort id = 1;
|
||||
string[] keys = ["_id", "display_name", "age", "location", "0", "1"];
|
||||
foreach (string key in keys)
|
||||
{
|
||||
ushort id = 1;
|
||||
string[] keys = ["_id", "display_name", "age", "location", "0", "1"];
|
||||
foreach (var key in keys)
|
||||
{
|
||||
_keyMap[key] = id;
|
||||
_keys[id] = key;
|
||||
id++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies table attribute mapping resolves the expected collection name.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Table_Attribute_Mapping()
|
||||
{
|
||||
// Verify that the generated mapper has the correct collection name
|
||||
var mapper = CreateMapper();
|
||||
mapper.CollectionName.ShouldBe("test.custom_users");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies required attribute validation is enforced.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Required_Validation()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "" }; // Required name is empty
|
||||
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
||||
|
||||
bool thrown = false;
|
||||
try
|
||||
{
|
||||
mapper.Serialize(user, writer);
|
||||
}
|
||||
catch (ValidationException)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for empty Name.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies string length attribute validation is enforced.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_StringLength_Validation()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "Jo" }; // Too short
|
||||
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
||||
|
||||
bool thrown = false;
|
||||
try { mapper.Serialize(user, writer); } catch (ValidationException) { thrown = true; }
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for Name too short.");
|
||||
|
||||
user.Name = new string('A', 51); // Too long
|
||||
thrown = false;
|
||||
try { mapper.Serialize(user, writer); } catch (ValidationException) { thrown = true; }
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for Name too long.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies range attribute validation is enforced.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Range_Validation()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "John", Age = 200 }; // Out of range
|
||||
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
||||
|
||||
bool thrown = false;
|
||||
try { mapper.Serialize(user, writer); } catch (ValidationException) { thrown = true; }
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for Age out of range.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies column attribute maps to the expected BSON field name.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Column_Name_Mapping()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "John", Age = 30 };
|
||||
var buffer = new byte[1024];
|
||||
var writer = new BsonSpanWriter(buffer, _keyMap);
|
||||
|
||||
mapper.Serialize(user, writer);
|
||||
|
||||
var reader = new BsonSpanReader(buffer, _keys);
|
||||
reader.ReadDocumentSize();
|
||||
|
||||
bool foundDisplayName = false;
|
||||
while (reader.Remaining > 0)
|
||||
{
|
||||
var type = reader.ReadBsonType();
|
||||
if (type == BsonType.EndOfDocument) break;
|
||||
|
||||
var name = reader.ReadElementHeader();
|
||||
if (name == "display_name") foundDisplayName = true;
|
||||
reader.SkipValue(type);
|
||||
}
|
||||
|
||||
foundDisplayName.ShouldBeTrue("BSON field name should be 'display_name' from [Column] attribute.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies not-mapped attribute excludes properties from BSON serialization.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_NotMapped_Attribute()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "John", Age = 30 };
|
||||
var buffer = new byte[1024];
|
||||
var writer = new BsonSpanWriter(buffer, _keyMap);
|
||||
|
||||
mapper.Serialize(user, writer);
|
||||
|
||||
var reader = new BsonSpanReader(buffer, _keys);
|
||||
reader.ReadDocumentSize();
|
||||
|
||||
bool foundComputed = false;
|
||||
while (reader.Remaining > 0)
|
||||
{
|
||||
var type = reader.ReadBsonType();
|
||||
if (type == BsonType.EndOfDocument) break;
|
||||
|
||||
var name = reader.ReadElementHeader();
|
||||
if (name == "ComputedInfo") foundComputed = true;
|
||||
reader.SkipValue(type);
|
||||
}
|
||||
|
||||
foundComputed.ShouldBeFalse("ComputedInfo should not be mapped to BSON.");
|
||||
_keyMap[key] = id;
|
||||
_keys[id] = key;
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Use full path for mapper until we are sure of the namespace
|
||||
private ZB_MOM_WW_CBDD_Shared_AnnotatedUserMapper CreateMapper()
|
||||
{
|
||||
return new ZB_MOM_WW_CBDD_Shared_AnnotatedUserMapper();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies table attribute mapping resolves the expected collection name.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Table_Attribute_Mapping()
|
||||
{
|
||||
// Verify that the generated mapper has the correct collection name
|
||||
var mapper = CreateMapper();
|
||||
mapper.CollectionName.ShouldBe("test.custom_users");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies required attribute validation is enforced.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Required_Validation()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "" }; // Required name is empty
|
||||
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
||||
|
||||
var thrown = false;
|
||||
try
|
||||
{
|
||||
mapper.Serialize(user, writer);
|
||||
}
|
||||
catch (ValidationException)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for empty Name.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies string length attribute validation is enforced.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_StringLength_Validation()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "Jo" }; // Too short
|
||||
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
||||
|
||||
var thrown = false;
|
||||
try
|
||||
{
|
||||
mapper.Serialize(user, writer);
|
||||
}
|
||||
catch (ValidationException)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for Name too short.");
|
||||
|
||||
user.Name = new string('A', 51); // Too long
|
||||
thrown = false;
|
||||
try
|
||||
{
|
||||
mapper.Serialize(user, writer);
|
||||
}
|
||||
catch (ValidationException)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for Name too long.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies range attribute validation is enforced.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Range_Validation()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "John", Age = 200 }; // Out of range
|
||||
var writer = new BsonSpanWriter(new byte[1024], _keyMap);
|
||||
|
||||
var thrown = false;
|
||||
try
|
||||
{
|
||||
mapper.Serialize(user, writer);
|
||||
}
|
||||
catch (ValidationException)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
|
||||
thrown.ShouldBeTrue("Should throw ValidationException for Age out of range.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies column attribute maps to the expected BSON field name.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_Column_Name_Mapping()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "John", Age = 30 };
|
||||
var buffer = new byte[1024];
|
||||
var writer = new BsonSpanWriter(buffer, _keyMap);
|
||||
|
||||
mapper.Serialize(user, writer);
|
||||
|
||||
var reader = new BsonSpanReader(buffer, _keys);
|
||||
reader.ReadDocumentSize();
|
||||
|
||||
var foundDisplayName = false;
|
||||
while (reader.Remaining > 0)
|
||||
{
|
||||
var type = reader.ReadBsonType();
|
||||
if (type == BsonType.EndOfDocument) break;
|
||||
|
||||
string name = reader.ReadElementHeader();
|
||||
if (name == "display_name") foundDisplayName = true;
|
||||
reader.SkipValue(type);
|
||||
}
|
||||
|
||||
foundDisplayName.ShouldBeTrue("BSON field name should be 'display_name' from [Column] attribute.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies not-mapped attribute excludes properties from BSON serialization.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void Test_NotMapped_Attribute()
|
||||
{
|
||||
var mapper = CreateMapper();
|
||||
var user = new AnnotatedUser { Name = "John", Age = 30 };
|
||||
var buffer = new byte[1024];
|
||||
var writer = new BsonSpanWriter(buffer, _keyMap);
|
||||
|
||||
mapper.Serialize(user, writer);
|
||||
|
||||
var reader = new BsonSpanReader(buffer, _keys);
|
||||
reader.ReadDocumentSize();
|
||||
|
||||
var foundComputed = false;
|
||||
while (reader.Remaining > 0)
|
||||
{
|
||||
var type = reader.ReadBsonType();
|
||||
if (type == BsonType.EndOfDocument) break;
|
||||
|
||||
string name = reader.ReadElementHeader();
|
||||
if (name == "ComputedInfo") foundComputed = true;
|
||||
reader.SkipValue(type);
|
||||
}
|
||||
|
||||
foundComputed.ShouldBeFalse("ComputedInfo should not be mapped to BSON.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user