[LOADED_DOCS: 2 files, no new loads]
Refactor tests to use _All_True model types throughout Replaced all usages of legacy test model types (e.g., TestOrder, TestOrderItem, SharedTag, etc.) with new, feature-complete _All_True variants across SignalR test infrastructure, data sources, and service handlers. Updated all generic constraints, method signatures, and test data to use the new types. Added SharedTestBaseModels.cs and SharedTestOrderModels.cs to define abstract bases and concrete _All_True models with full serialization attributes. This enables more thorough and realistic serialization/deserialization testing and future extensibility.
This commit is contained in:
parent
23f2f57fa7
commit
32f2de0db3
|
|
@ -24,7 +24,7 @@ namespace AyCode.Core.Benchmarks;
|
|||
[MemoryDiagnoser(displayGenColumns: false)]
|
||||
public class JitDisassemblyBenchmark
|
||||
{
|
||||
private TestOrder _order = null!;
|
||||
private TestOrder_All_True _order = null!;
|
||||
private AcBinarySerializerOptions _fastModeOptions = null!;
|
||||
private AcBinarySerializerOptions _defaultOptions = null!;
|
||||
private byte[] _serializedFastMode = null!;
|
||||
|
|
@ -34,7 +34,7 @@ public class JitDisassemblyBenchmark
|
|||
public void Setup()
|
||||
{
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
|
||||
// Medium data: enough properties to show loop behavior, not too large for disassembly
|
||||
|
|
@ -65,9 +65,9 @@ public class JitDisassemblyBenchmark
|
|||
/// FastMode deserialize.
|
||||
/// </summary>
|
||||
[Benchmark]
|
||||
public TestOrder Deserialize_FastMode()
|
||||
public TestOrder_All_True Deserialize_FastMode()
|
||||
{
|
||||
return AcBinaryDeserializer.Deserialize<TestOrder>(_serializedFastMode, _fastModeOptions);
|
||||
return AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_serializedFastMode, _fastModeOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -84,8 +84,8 @@ public class JitDisassemblyBenchmark
|
|||
/// Default deserialize — ref tracking + string interning.
|
||||
/// </summary>
|
||||
[Benchmark]
|
||||
public TestOrder Deserialize_Default()
|
||||
public TestOrder_All_True Deserialize_Default()
|
||||
{
|
||||
return AcBinaryDeserializer.Deserialize<TestOrder>(_serializedDefault, _defaultOptions);
|
||||
return AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_serializedDefault, _defaultOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ namespace AyCode.Benchmark
|
|||
|
||||
// Create test data with shared references
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
|
|
@ -247,19 +247,19 @@ namespace AyCode.Benchmark
|
|||
// AcBinary WithRef Deserialize
|
||||
sw.Restart();
|
||||
for (int i = 0; i < iterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryWithRef);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryWithRef);
|
||||
var acWithRefDeserialize = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// AcBinary NoRef Deserialize
|
||||
sw.Restart();
|
||||
for (int i = 0; i < iterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryNoRef);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryNoRef);
|
||||
var acNoRefDeserialize = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// MessagePack Deserialize
|
||||
sw.Restart();
|
||||
for (int i = 0; i < iterations; i++)
|
||||
_ = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, msgPackOptions);
|
||||
_ = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, msgPackOptions);
|
||||
var msgPackDeserialize = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
results.Add(("Deserialize", "WithRef", acWithRefDeserialize, msgPackDeserialize));
|
||||
|
|
@ -332,12 +332,12 @@ namespace AyCode.Benchmark
|
|||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static TestOrder CreatePopulateTarget(TestOrder source)
|
||||
static TestOrder_All_True CreatePopulateTarget(TestOrder_All_True source)
|
||||
{
|
||||
var target = new TestOrder { Id = source.Id };
|
||||
var target = new TestOrder_All_True { Id = source.Id };
|
||||
foreach (var item in source.Items)
|
||||
{
|
||||
target.Items.Add(new TestOrderItem { Id = item.Id });
|
||||
target.Items.Add(new TestOrderItem_All_True { Id = item.Id });
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ public class SimpleBinaryBenchmark
|
|||
[RankColumn]
|
||||
public class ComplexBinaryBenchmark
|
||||
{
|
||||
private TestOrder _testOrder = null!;
|
||||
private TestOrder_All_True _testOrder = null!;
|
||||
private byte[] _acBinaryData = null!;
|
||||
private string _jsonData = null!;
|
||||
|
||||
|
|
@ -130,10 +130,10 @@ public class ComplexBinaryBenchmark
|
|||
public string Serialize_Json() => AcJsonSerializer.Serialize(_testOrder, _jsonOptions);
|
||||
|
||||
[Benchmark(Description = "AcBinary Deserialize")]
|
||||
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryData);
|
||||
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryData);
|
||||
|
||||
[Benchmark(Description = "JSON Deserialize")]
|
||||
public TestOrder? Deserialize_Json() => AcJsonDeserializer.Deserialize<TestOrder>(_jsonData, _jsonOptions);
|
||||
public TestOrder_All_True? Deserialize_Json() => AcJsonDeserializer.Deserialize<TestOrder_All_True>(_jsonData, _jsonOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -144,7 +144,7 @@ public class ComplexBinaryBenchmark
|
|||
[RankColumn]
|
||||
public class MessagePackComparisonBenchmark
|
||||
{
|
||||
private TestOrder _testOrder = null!;
|
||||
private TestOrder_All_True _testOrder = null!;
|
||||
private byte[] _acBinaryData = null!;
|
||||
private byte[] _msgPackData = null!;
|
||||
private byte[] _bsonData = null!;
|
||||
|
|
@ -216,18 +216,18 @@ public class MessagePackComparisonBenchmark
|
|||
public byte[] Serialize_Bson() => _testOrder.ToBsonDocument().ToBson();
|
||||
|
||||
[Benchmark(Description = "AcBinary Deserialize")]
|
||||
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryData);
|
||||
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryData);
|
||||
|
||||
[Benchmark(Description = "MessagePack Deserialize")]
|
||||
public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder>(_msgPackData, _msgPackOptions);
|
||||
public TestOrder_All_True? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_msgPackData, _msgPackOptions);
|
||||
|
||||
[Benchmark(Description = "BSON Deserialize")]
|
||||
public TestOrder? Deserialize_Bson()
|
||||
public TestOrder_All_True? Deserialize_Bson()
|
||||
{
|
||||
if (_bsonData == null || _bsonData.Length == 0) return null;
|
||||
using var ms = new MemoryStream(_bsonData);
|
||||
using var reader = new BsonBinaryReader(ms);
|
||||
return BsonSerializer.Deserialize<TestOrder>(reader);
|
||||
return BsonSerializer.Deserialize<TestOrder_All_True>(reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,8 +241,8 @@ public class MessagePackComparisonBenchmark
|
|||
public class AcBinaryVsMessagePackFullBenchmark
|
||||
{
|
||||
// Test data
|
||||
private TestOrder _testOrder = null!;
|
||||
private TestOrder _populateTarget = null!;
|
||||
private TestOrder_All_True _testOrder = null!;
|
||||
private TestOrder_All_True _populateTarget = null!;
|
||||
|
||||
// Serialized data - AcBinary
|
||||
private byte[] _acBinaryWithRef = null!;
|
||||
|
|
@ -262,7 +262,7 @@ public class AcBinaryVsMessagePackFullBenchmark
|
|||
{
|
||||
// Create test data with shared references
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
|
|
@ -296,10 +296,10 @@ public class AcBinaryVsMessagePackFullBenchmark
|
|||
}
|
||||
|
||||
// Create populate target
|
||||
_populateTarget = new TestOrder { Id = _testOrder.Id };
|
||||
_populateTarget = new TestOrder_All_True { Id = _testOrder.Id };
|
||||
foreach (var item in _testOrder.Items)
|
||||
{
|
||||
_populateTarget.Items.Add(new TestOrderItem { Id = item.Id });
|
||||
_populateTarget.Items.Add(new TestOrderItem_All_True { Id = item.Id });
|
||||
}
|
||||
|
||||
// Print size comparison
|
||||
|
|
@ -340,21 +340,21 @@ public class AcBinaryVsMessagePackFullBenchmark
|
|||
#region Deserialize Benchmarks
|
||||
|
||||
[Benchmark(Description = "AcBinary Deserialize WithRef")]
|
||||
public TestOrder? Deserialize_AcBinary_WithRef() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryWithRef);
|
||||
public TestOrder_All_True? Deserialize_AcBinary_WithRef() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryWithRef);
|
||||
|
||||
[Benchmark(Description = "AcBinary Deserialize NoRef")]
|
||||
public TestOrder? Deserialize_AcBinary_NoRef() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryNoRef);
|
||||
public TestOrder_All_True? Deserialize_AcBinary_NoRef() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryNoRef);
|
||||
|
||||
[Benchmark(Description = "MessagePack Deserialize")]
|
||||
public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder>(_msgPackData, _msgPackOptions);
|
||||
public TestOrder_All_True? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_msgPackData, _msgPackOptions);
|
||||
|
||||
[Benchmark(Description = "BSON Deserialize")]
|
||||
public TestOrder? Deserialize_Bson()
|
||||
public TestOrder_All_True? Deserialize_Bson()
|
||||
{
|
||||
if (_bsonData == null || _bsonData.Length == 0) return null;
|
||||
using var ms = new MemoryStream(_bsonData);
|
||||
using var reader = new BsonBinaryReader(ms);
|
||||
return BsonSerializer.Deserialize<TestOrder>(reader);
|
||||
return BsonSerializer.Deserialize<TestOrder_All_True>(reader);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -391,12 +391,12 @@ public class AcBinaryVsMessagePackFullBenchmark
|
|||
AcBinaryDeserializer.PopulateMerge(_acBinaryNoRef, target);
|
||||
}
|
||||
|
||||
private TestOrder CreatePopulateTarget()
|
||||
private TestOrder_All_True CreatePopulateTarget()
|
||||
{
|
||||
var target = new TestOrder { Id = _testOrder.Id };
|
||||
var target = new TestOrder_All_True { Id = _testOrder.Id };
|
||||
foreach (var item in _testOrder.Items)
|
||||
{
|
||||
target.Items.Add(new TestOrderItem { Id = item.Id });
|
||||
target.Items.Add(new TestOrderItem_All_True { Id = item.Id });
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
|
@ -412,9 +412,9 @@ public class AcBinaryVsMessagePackFullBenchmark
|
|||
[MemoryDiagnoser]
|
||||
public class SizeComparisonBenchmark
|
||||
{
|
||||
private TestOrder _smallOrder = null!;
|
||||
private TestOrder _mediumOrder = null!;
|
||||
private TestOrder _largeOrder = null!;
|
||||
private TestOrder_All_True _smallOrder = null!;
|
||||
private TestOrder_All_True _mediumOrder = null!;
|
||||
private TestOrder_All_True _largeOrder = null!;
|
||||
|
||||
private MessagePackSerializerOptions _msgPackOptions = null!;
|
||||
private AcBinarySerializerOptions _withRefOptions = null!;
|
||||
|
|
@ -464,7 +464,7 @@ public class SizeComparisonBenchmark
|
|||
Console.WriteLine(new string('=', 80) + "\n");
|
||||
}
|
||||
|
||||
private void PrintOrderSize(string name, TestOrder order)
|
||||
private void PrintOrderSize(string name, TestOrder_All_True order)
|
||||
{
|
||||
var acWithRef = AcBinarySerializer.Serialize(order, _withRefOptions);
|
||||
var acNoRef = AcBinarySerializer.Serialize(order, _noRefOptions);
|
||||
|
|
@ -499,7 +499,7 @@ public enum BinaryBenchmarkMode
|
|||
|
||||
public abstract class AcBinaryOptionsBenchmarkBase
|
||||
{
|
||||
protected TestOrder TestOrder = null!;
|
||||
protected TestOrder_All_True TestOrder = null!;
|
||||
protected AcBinarySerializerOptions BinaryOptions = null!;
|
||||
protected MessagePackSerializerOptions MsgPackOptions = null!;
|
||||
protected byte[] AcBinaryData = null!;
|
||||
|
|
@ -560,10 +560,10 @@ public class AcBinaryOptionsSerializeBenchmark : AcBinaryOptionsBenchmarkBase
|
|||
public class AcBinaryOptionsDeserializeBenchmark : AcBinaryOptionsBenchmarkBase
|
||||
{
|
||||
[Benchmark(Description = "MessagePack Deserialize", Baseline = true)]
|
||||
public TestOrder? Deserialize_MessagePack() => MessagePackSerializer.Deserialize<TestOrder>(MsgPackData, MsgPackOptions);
|
||||
public TestOrder_All_True? Deserialize_MessagePack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(MsgPackData, MsgPackOptions);
|
||||
|
||||
[Benchmark(Description = "AcBinary Deserialize")]
|
||||
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(AcBinaryData);
|
||||
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(AcBinaryData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -578,8 +578,8 @@ public class LargeScaleBinaryBenchmark
|
|||
{
|
||||
// Test data - smaller scale for benchmark (500 items ? 25K objects)
|
||||
// Production would be 2200 items ? 100K+ objects
|
||||
private TestOrder _testOrder = null!;
|
||||
private TestOrder _populateTarget = null!;
|
||||
private TestOrder_All_True _testOrder = null!;
|
||||
private TestOrder_All_True _populateTarget = null!;
|
||||
|
||||
// Serialized data
|
||||
private byte[] _acBinaryData = null!;
|
||||
|
|
@ -619,10 +619,10 @@ public class LargeScaleBinaryBenchmark
|
|||
_msgPackData = MessagePackSerializer.Serialize(_testOrder, _msgPackOptions);
|
||||
|
||||
// Create populate target
|
||||
_populateTarget = new TestOrder { Id = _testOrder.Id };
|
||||
_populateTarget = new TestOrder_All_True { Id = _testOrder.Id };
|
||||
foreach (var item in _testOrder.Items.Take(10)) // Only first 10 for populate target
|
||||
{
|
||||
_populateTarget.Items.Add(new TestOrderItem { Id = item.Id });
|
||||
_populateTarget.Items.Add(new TestOrderItem_All_True { Id = item.Id });
|
||||
}
|
||||
|
||||
PrintStats();
|
||||
|
|
@ -642,10 +642,10 @@ public class LargeScaleBinaryBenchmark
|
|||
}
|
||||
|
||||
[Benchmark(Description = "LargeScale AcBinary Deserialize")]
|
||||
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryData);
|
||||
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryData);
|
||||
|
||||
[Benchmark(Description = "LargeScale MsgPack Deserialize", Baseline = true)]
|
||||
public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder>(_msgPackData, _msgPackOptions);
|
||||
public TestOrder_All_True? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_msgPackData, _msgPackOptions);
|
||||
|
||||
[Benchmark(Description = "LargeScale AcBinary Serialize")]
|
||||
public byte[] Serialize_AcBinary() => AcBinarySerializer.Serialize(_testOrder, _binaryOptions);
|
||||
|
|
|
|||
|
|
@ -107,18 +107,18 @@ public class SignalRCommunicationBenchmarks
|
|||
|
||||
[Benchmark(Description = "Server: Deserialize complex OrderItem")]
|
||||
[BenchmarkCategory("Server", "Deserialize")]
|
||||
public TestOrderItem Server_DeserializeComplexOrderItem()
|
||||
public TestOrderItem_All_True Server_DeserializeComplexOrderItem()
|
||||
{
|
||||
var postMessage = MessagePackSerializer.Deserialize<SignalRPostMessageDto>(_complexOrderItemMessage, SignalRMessageFactory.ContractlessOptions);
|
||||
return postMessage.PostDataJson!.JsonTo<TestOrderItem>()!;
|
||||
return postMessage.PostDataJson!.JsonTo<TestOrderItem_All_True>()!;
|
||||
}
|
||||
|
||||
[Benchmark(Description = "Server: Deserialize complex Order")]
|
||||
[BenchmarkCategory("Server", "Deserialize")]
|
||||
public TestOrder Server_DeserializeComplexOrder()
|
||||
public TestOrder_All_True Server_DeserializeComplexOrder()
|
||||
{
|
||||
var postMessage = MessagePackSerializer.Deserialize<SignalRPostMessageDto>(_complexOrderMessage, SignalRMessageFactory.ContractlessOptions);
|
||||
return postMessage.PostDataJson!.JsonTo<TestOrder>()!;
|
||||
return postMessage.PostDataJson!.JsonTo<TestOrder_All_True>()!;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -144,10 +144,10 @@ public class SignalRCommunicationBenchmarks
|
|||
|
||||
[Benchmark(Description = "Client: Deserialize complex Order response")]
|
||||
[BenchmarkCategory("Client", "Response")]
|
||||
public TestOrder? Client_DeserializeOrderResponse()
|
||||
public TestOrder_All_True? Client_DeserializeOrderResponse()
|
||||
{
|
||||
var response = SignalRMessageFactory.DeserializeResponse(_complexResponseMessage);
|
||||
return response?.ResponseData?.JsonTo<TestOrder>();
|
||||
return response?.ResponseData?.JsonTo<TestOrder_All_True>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -171,19 +171,19 @@ public class SignalRCommunicationBenchmarks
|
|||
|
||||
[Benchmark(Description = "Full: Complex Order round-trip")]
|
||||
[BenchmarkCategory("Full")]
|
||||
public TestOrder? Full_ComplexOrderRoundTrip()
|
||||
public TestOrder_All_True? Full_ComplexOrderRoundTrip()
|
||||
{
|
||||
// Client creates message
|
||||
var requestBytes = SignalRMessageFactory.CreateComplexObjectMessage(_data.TestOrder);
|
||||
// Server deserializes
|
||||
var postMessage = MessagePackSerializer.Deserialize<SignalRPostMessageDto>(requestBytes, SignalRMessageFactory.ContractlessOptions);
|
||||
var order = postMessage.PostDataJson!.JsonTo<TestOrder>()!;
|
||||
var order = postMessage.PostDataJson!.JsonTo<TestOrder_All_True>()!;
|
||||
// Server modifies and creates response
|
||||
order.OrderNumber = "PROCESSED-" + order.OrderNumber;
|
||||
var responseBytes = SignalRMessageFactory.CreateSuccessResponse(CommonSignalRTags.TestOrderParam, order);
|
||||
// Client deserializes response
|
||||
var response = SignalRMessageFactory.DeserializeResponse(responseBytes);
|
||||
return response?.ResponseData?.JsonTo<TestOrder>();
|
||||
return response?.ResponseData?.JsonTo<TestOrder_All_True>();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
@ -24,9 +24,9 @@ public class SignalRRoundTripBenchmarks
|
|||
private BenchmarkSignalRService _service = null!;
|
||||
|
||||
// Pre-created test data
|
||||
private TestOrderItem _testOrderItem = null!;
|
||||
private TestOrder _testOrder = null!;
|
||||
private SharedTag _sharedTag = null!;
|
||||
private TestOrderItem_All_True _testOrderItem = null!;
|
||||
private TestOrder_All_True _testOrder = null!;
|
||||
private SharedTag_All_True _sharedTag = null!;
|
||||
private int[] _intArray = null!;
|
||||
private List<string> _stringList = null!;
|
||||
private Guid _testGuid;
|
||||
|
|
@ -41,9 +41,9 @@ public class SignalRRoundTripBenchmarks
|
|||
_hub.RegisterService(_service, _client);
|
||||
|
||||
// Pre-create test data
|
||||
_testOrderItem = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
|
||||
_testOrderItem = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
|
||||
_testOrder = TestDataFactory.CreateOrder(itemCount: 3);
|
||||
_sharedTag = new SharedTag { Id = 1, Name = "Important", Color = "#FF0000" };
|
||||
_sharedTag = new SharedTag_All_True { Id = 1, Name = "Important", Color = "#FF0000" };
|
||||
_intArray = [1, 2, 3, 4, 5];
|
||||
_stringList = ["apple", "banana", "cherry"];
|
||||
_testGuid = Guid.NewGuid();
|
||||
|
|
@ -104,25 +104,25 @@ public class SignalRRoundTripBenchmarks
|
|||
|
||||
#region Complex Object Benchmarks
|
||||
|
||||
[Benchmark(Description = "RoundTrip: TestOrderItem")]
|
||||
[Benchmark(Description = "RoundTrip: TestOrderItem_All_True")]
|
||||
[BenchmarkCategory("Complex")]
|
||||
public TestOrderItem? RoundTrip_TestOrderItem()
|
||||
public TestOrderItem_All_True? RoundTrip_TestOrderItem()
|
||||
{
|
||||
return _client.PostDataSync<TestOrderItem, TestOrderItem>(BenchmarkSignalRTags.TestOrderItemParam, _testOrderItem);
|
||||
return _client.PostDataSync<TestOrderItem_All_True, TestOrderItem_All_True>(BenchmarkSignalRTags.TestOrderItemParam, _testOrderItem);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "RoundTrip: TestOrder (3 items)")]
|
||||
[Benchmark(Description = "RoundTrip: TestOrder_All_True (3 items)")]
|
||||
[BenchmarkCategory("Complex")]
|
||||
public TestOrder? RoundTrip_TestOrder()
|
||||
public TestOrder_All_True? RoundTrip_TestOrder()
|
||||
{
|
||||
return _client.PostDataSync<TestOrder, TestOrder>(BenchmarkSignalRTags.TestOrderParam, _testOrder);
|
||||
return _client.PostDataSync<TestOrder_All_True, TestOrder_All_True>(BenchmarkSignalRTags.TestOrderParam, _testOrder);
|
||||
}
|
||||
|
||||
[Benchmark(Description = "RoundTrip: SharedTag")]
|
||||
[Benchmark(Description = "RoundTrip: SharedTag_All_True")]
|
||||
[BenchmarkCategory("Complex")]
|
||||
public SharedTag? RoundTrip_SharedTag()
|
||||
public SharedTag_All_True? RoundTrip_SharedTag()
|
||||
{
|
||||
return _client.PostDataSync<SharedTag, SharedTag>(BenchmarkSignalRTags.SharedTagParam, _sharedTag);
|
||||
return _client.PostDataSync<SharedTag_All_True, SharedTag_All_True>(BenchmarkSignalRTags.SharedTagParam, _sharedTag);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -278,7 +278,7 @@ public class BenchmarkSignalRService
|
|||
public string HandleMultipleTypes(bool flag, string text, int number) => $"{flag}-{text}-{number}";
|
||||
|
||||
[SignalR(BenchmarkSignalRTags.TestOrderItemParam)]
|
||||
public TestOrderItem HandleTestOrderItem(TestOrderItem item) => new()
|
||||
public TestOrderItem_All_True HandleTestOrderItem(TestOrderItem_All_True item) => new()
|
||||
{
|
||||
Id = item.Id,
|
||||
ProductName = $"Processed: {item.ProductName}",
|
||||
|
|
@ -287,10 +287,10 @@ public class BenchmarkSignalRService
|
|||
};
|
||||
|
||||
[SignalR(BenchmarkSignalRTags.TestOrderParam)]
|
||||
public TestOrder HandleTestOrder(TestOrder order) => order;
|
||||
public TestOrder_All_True HandleTestOrder(TestOrder_All_True order) => order;
|
||||
|
||||
[SignalR(BenchmarkSignalRTags.SharedTagParam)]
|
||||
public SharedTag HandleSharedTag(SharedTag tag) => tag;
|
||||
public SharedTag_All_True HandleSharedTag(SharedTag_All_True tag) => tag;
|
||||
|
||||
[SignalR(BenchmarkSignalRTags.IntArrayParam)]
|
||||
public int[] HandleIntArray(int[] values) => values.Select(x => x * 2).ToArray();
|
||||
|
|
@ -299,7 +299,7 @@ public class BenchmarkSignalRService
|
|||
public List<string> HandleStringList(List<string> items) => items.Select(x => x.ToUpper()).ToList();
|
||||
|
||||
[SignalR(BenchmarkSignalRTags.IntAndDtoParam)]
|
||||
public string HandleIntAndDto(int id, TestOrderItem item) => $"{id}-{item?.ProductName}";
|
||||
public string HandleIntAndDto(int id, TestOrderItem_All_True item) => $"{id}-{item?.ProductName}";
|
||||
|
||||
[SignalR(BenchmarkSignalRTags.FiveParams)]
|
||||
public string HandleFiveParams(int a, string b, bool c, Guid d, decimal e) => $"{a}-{b}-{c}-{d}-{e}";
|
||||
|
|
|
|||
|
|
@ -739,12 +739,12 @@ internal static class BenchmarkLoop
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates MemoryPack setup at startup. Aborts the benchmark if TestOrder is not [MemoryPackable].
|
||||
/// Validates MemoryPack setup at startup. Aborts the benchmark if TestOrder_All_True is not [MemoryPackable].
|
||||
/// Without this attribute, MemoryPack falls back to runtime resolver (slower) — comparison would be INVALID.
|
||||
/// </summary>
|
||||
internal static void ValidateMemoryPackSetup()
|
||||
{
|
||||
var typesToCheck = new[] { typeof(TestOrder) };
|
||||
var typesToCheck = new[] { typeof(TestOrder_All_True) };
|
||||
|
||||
foreach (var type in typesToCheck)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ internal sealed class AcBinaryBenchmark : ISerializerBenchmark
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options);
|
||||
|
||||
public AcBinaryBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
_options = options;
|
||||
|
|
@ -35,12 +35,12 @@ internal sealed class AcBinaryBenchmark : ISerializerBenchmark
|
|||
public void Serialize() => AcBinarySerializer.Serialize(_order, _options);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder>(_serialized, _options);
|
||||
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_serialized, _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
var bytes = AcBinarySerializer.Serialize(_order, _options);
|
||||
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, _options);
|
||||
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
private readonly ArrayBufferWriter<byte> _bufferWriter;
|
||||
|
|
@ -25,7 +25,7 @@ internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options);
|
||||
|
||||
public AcBinaryBufferWriterBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryBufferWriterBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
_options = options;
|
||||
|
|
@ -55,14 +55,14 @@ internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
|
|||
// (the production-realistic surface for SignalR / Pipe consumers) rather than secretly testing
|
||||
// byte[] Deser under the BufWr label.
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
_bufferWriter.ResetWrittenCount();
|
||||
AcBinarySerializer.Serialize(_order, _bufferWriter, _options);
|
||||
|
||||
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
|
||||
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B");
|
||||
|
||||
public AcBinaryFreshBufferWriterBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryFreshBufferWriterBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
// BufferWriterChunkSize comes from the caller (central source of truth in CreateSerializers
|
||||
|
|
@ -51,13 +51,13 @@ internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
|
|||
// (the production-realistic surface for SignalR / Pipe consumers) rather than secretly testing
|
||||
// byte[] Deser under the BufWr label.
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
var abw = new ArrayBufferWriter<byte>();
|
||||
AcBinarySerializer.Serialize(_order, abw, _options);
|
||||
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
|
||||
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDisposable
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized; // for SerializedSize reporting only
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
|
|||
public bool IsRoundTripOnly => true;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=Pipe(in-memory,multiMessage,2-task)");
|
||||
|
||||
public AcBinaryInMemoryPipeBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryInMemoryPipeBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
_options = options;
|
||||
|
|
@ -106,7 +106,7 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
|
|||
|
||||
try
|
||||
{
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(_input, _options);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_input, _options);
|
||||
if (_captureResult) _lastResult = result;
|
||||
}
|
||||
catch
|
||||
|
|
@ -158,7 +158,7 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
|
|||
try
|
||||
{
|
||||
Serialize();
|
||||
var result = _lastResult as TestOrder;
|
||||
var result = _lastResult as TestOrder_All_True;
|
||||
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchmark, IDisposable
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized; // for SerializedSize reporting only
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
|
|||
public bool IsRoundTripOnly => true;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=in-memory(raw,2-task)");
|
||||
|
||||
public AcBinaryInMemoryRawByteArrayBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryInMemoryRawByteArrayBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
_options = options;
|
||||
|
|
@ -89,7 +89,7 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
|
|||
var bytes = _pendingBytes;
|
||||
if (bytes != null)
|
||||
{
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, _options);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, _options);
|
||||
if (_captureResult) _lastResult = result;
|
||||
}
|
||||
}
|
||||
|
|
@ -142,7 +142,7 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
|
|||
try
|
||||
{
|
||||
Serialize();
|
||||
var result = _lastResult as TestOrder;
|
||||
var result = _lastResult as TestOrder_All_True;
|
||||
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDisposable
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized; // for SerializedSize reporting only
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
|
|||
public bool IsRoundTripOnly => true;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=NamedPipe(long-lived,multiMessage,2-task)");
|
||||
|
||||
public AcBinaryNamedPipeBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryNamedPipeBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
// BufferWriterChunkSize comes from the caller (central source of truth in CreateSerializers
|
||||
|
|
@ -152,7 +152,7 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
|
|||
|
||||
try
|
||||
{
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(_input, _options);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_input, _options);
|
||||
if (_captureResult) _lastResult = result;
|
||||
}
|
||||
catch
|
||||
|
|
@ -203,7 +203,7 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
|
|||
try
|
||||
{
|
||||
Serialize();
|
||||
var result = _lastResult as TestOrder;
|
||||
var result = _lastResult as TestOrder_All_True;
|
||||
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchmark, IDisposable
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly AcBinarySerializerOptions _options;
|
||||
private readonly byte[] _serialized; // for SerializedSize reporting + receive-side size known upfront
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
|
|||
public bool IsRoundTripOnly => true;
|
||||
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=NamedPipe(raw,2-task)");
|
||||
|
||||
public AcBinaryNamedPipeRawByteArrayBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
public AcBinaryNamedPipeRawByteArrayBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
// BufferWriterChunkSize comes from the caller — same source-of-truth contract as
|
||||
|
|
@ -125,7 +125,7 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
|
|||
if (n == 0) break; // pipe closed / EOF — partial read swallowed
|
||||
totalRead += n;
|
||||
}
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, _options);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, _options);
|
||||
if (_captureResult) _lastResult = result;
|
||||
}
|
||||
catch
|
||||
|
|
@ -183,7 +183,7 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
|
|||
try
|
||||
{
|
||||
Serialize();
|
||||
var result = _lastResult as TestOrder;
|
||||
var result = _lastResult as TestOrder_All_True;
|
||||
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
|
||||
}
|
||||
finally
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class MemoryPackBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly MemoryPackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ internal sealed class MemoryPackBenchmark : ISerializerBenchmark
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
|
||||
|
||||
public MemoryPackBenchmark(TestOrder order, string optionsPreset)
|
||||
public MemoryPackBenchmark(TestOrder_All_True order, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
OptionsPreset = optionsPreset;
|
||||
|
|
@ -36,12 +36,12 @@ internal sealed class MemoryPackBenchmark : ISerializerBenchmark
|
|||
public void Serialize() => MemoryPackSerializer.Serialize(_order, _options);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder>(_serialized, _options);
|
||||
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder_All_True>(_serialized, _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
var bytes = MemoryPackSerializer.Serialize(_order, _options);
|
||||
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder>(bytes, _options);
|
||||
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder_All_True>(bytes, _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly MemoryPackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
private readonly ArrayBufferWriter<byte> _bufferWriter;
|
||||
|
|
@ -26,7 +26,7 @@ internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
|
||||
|
||||
public MemoryPackBufferWriterBenchmark(TestOrder order, string optionsPreset)
|
||||
public MemoryPackBufferWriterBenchmark(TestOrder_All_True order, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
OptionsPreset = optionsPreset;
|
||||
|
|
@ -51,13 +51,13 @@ internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
|
|||
// BufWr semantic: read from a ReadOnlySequence<byte> overload (apples-to-apples with AcBinary's
|
||||
// BufWr Deser path). MemoryPack's ROS overload also single-segment-fast-paths internally.
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
_bufferWriter.ResetWrittenCount();
|
||||
MemoryPackSerializer.Serialize(_bufferWriter, _order, _options);
|
||||
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
|
||||
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly MemoryPackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmar
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
|
||||
|
||||
public MemoryPackFreshBufferWriterBenchmark(TestOrder order, string optionsPreset)
|
||||
public MemoryPackFreshBufferWriterBenchmark(TestOrder_All_True order, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
OptionsPreset = optionsPreset;
|
||||
|
|
@ -42,13 +42,13 @@ internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmar
|
|||
// BufWr semantic: read from a ReadOnlySequence<byte> overload (apples-to-apples with AcBinary's
|
||||
// BufWr Deser path). MemoryPack's ROS overload also single-segment-fast-paths internally.
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
var abw = new ArrayBufferWriter<byte>();
|
||||
MemoryPackSerializer.Serialize(abw, _order, _options);
|
||||
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
|
||||
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
|
||||
/// <summary>
|
||||
/// MessagePack benchmark, Byte[] I/O mode. Excluded from NativeAOT build because v3's StandardResolver
|
||||
/// falls back to DynamicGenericResolver for closed-generic types (List<TestOrderItem> et al.),
|
||||
/// falls back to DynamicGenericResolver for closed-generic types (List<TestOrderItem_All_True> et al.),
|
||||
/// which uses Activator.CreateInstance on formatter types the AOT trimmer drops →
|
||||
/// MissingMethodException at runtime. Available for regular JIT runs (<c>dotnet run</c>) only.
|
||||
/// </summary>
|
||||
internal sealed class MessagePackBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly MessagePackSerializerOptions _options;
|
||||
private readonly byte[] _serialized;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ internal sealed class MessagePackBenchmark : ISerializerBenchmark
|
|||
public long SetupDeserializeAllocBytes => 0;
|
||||
public string OptionsDescription { get; }
|
||||
|
||||
public MessagePackBenchmark(TestOrder order, string optionsPreset)
|
||||
public MessagePackBenchmark(TestOrder_All_True order, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
OptionsPreset = optionsPreset;
|
||||
|
|
@ -46,12 +46,12 @@ internal sealed class MessagePackBenchmark : ISerializerBenchmark
|
|||
public void Serialize() => MessagePackSerializer.Serialize(_order, _options);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => MessagePackSerializer.Deserialize<TestOrder>(_serialized, _options);
|
||||
public void Deserialize() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_serialized, _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
var bytes = MessagePackSerializer.Serialize(_order, _options);
|
||||
var roundTripped = MessagePackSerializer.Deserialize<TestOrder>(bytes, _options);
|
||||
var roundTripped = MessagePackSerializer.Deserialize<TestOrder_All_True>(bytes, _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
|
|||
/// </summary>
|
||||
internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
|
||||
{
|
||||
private readonly TestOrder _order;
|
||||
private readonly TestOrder_All_True _order;
|
||||
private readonly JsonSerializerOptions _options;
|
||||
private readonly string _serialized;
|
||||
private readonly byte[] _serializedUtf8;
|
||||
|
|
@ -25,7 +25,7 @@ internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
|
|||
public long SetupSerializeAllocBytes => 0;
|
||||
public long SetupDeserializeAllocBytes => 0;
|
||||
|
||||
public SystemTextJsonBenchmark(TestOrder order, string optionsPreset)
|
||||
public SystemTextJsonBenchmark(TestOrder_All_True order, string optionsPreset)
|
||||
{
|
||||
_order = order;
|
||||
OptionsPreset = optionsPreset;
|
||||
|
|
@ -43,12 +43,12 @@ internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
|
|||
public void Serialize() => JsonSerializer.Serialize(_order, _options);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public void Deserialize() => JsonSerializer.Deserialize<TestOrder>(_serialized, _options);
|
||||
public void Deserialize() => JsonSerializer.Deserialize<TestOrder_All_True>(_serialized, _options);
|
||||
|
||||
public bool VerifyRoundTrip()
|
||||
{
|
||||
var json = JsonSerializer.Serialize(_order, _options);
|
||||
var roundTripped = JsonSerializer.Deserialize<TestOrder>(json, _options);
|
||||
var roundTripped = JsonSerializer.Deserialize<TestOrder_All_True>(json, _options);
|
||||
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using AyCode.Core.Tests.TestModels;
|
|||
namespace AyCode.Core.Tests.GeneratedWriters;
|
||||
|
||||
/// <summary>
|
||||
/// Hand-written generated binary writer for TestOrder.
|
||||
/// Hand-written generated binary writer for TestOrder_All_True.
|
||||
/// Demonstrates the pattern that the source generator will produce.
|
||||
///
|
||||
/// Bypasses the runtime switch/delegate property loop:
|
||||
|
|
@ -27,15 +27,15 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter
|
|||
int depth)
|
||||
where TOutput : struct, IBinaryOutputBase
|
||||
{
|
||||
var obj = Unsafe.As<TestOrder>(value);
|
||||
var obj = Unsafe.As<TestOrder_All_True>(value);
|
||||
var nextDepth = depth;
|
||||
|
||||
// Properties in alphabetical order (matching runtime serializer):
|
||||
|
||||
// AuditMetadata: MetadataInfo? (complex, nullable)
|
||||
// AuditMetadata: MetadataInfo_All_True? (complex, nullable)
|
||||
WriteComplexOrNull(obj.AuditMetadata, context, nextDepth);
|
||||
|
||||
// Category: SharedCategory? (complex, nullable)
|
||||
// Category: SharedCategory_All_True? (complex, nullable)
|
||||
WriteComplexOrNull(obj.Category, context, nextDepth);
|
||||
|
||||
// CreatedAt: DateTime (markerless)
|
||||
|
|
@ -44,16 +44,16 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter
|
|||
// Id: int (markerless)
|
||||
context.WriteVarInt(obj.Id);
|
||||
|
||||
// Items: List<TestOrderItem> (collection)
|
||||
// Items: List<TestOrderItem_All_True> (collection)
|
||||
WriteComplexOrNull(obj.Items, context, nextDepth);
|
||||
|
||||
// MetadataList: List<MetadataInfo> (collection)
|
||||
// MetadataList: List<MetadataInfo_All_True> (collection)
|
||||
WriteComplexOrNull(obj.MetadataList, context, nextDepth);
|
||||
|
||||
// NoMergeItems: List<TestOrderItem> (collection)
|
||||
// NoMergeItems: List<TestOrderItem_All_True> (collection)
|
||||
WriteComplexOrNull(obj.NoMergeItems, context, nextDepth);
|
||||
|
||||
// OrderMetadata: MetadataInfo? (complex, nullable)
|
||||
// OrderMetadata: MetadataInfo_All_True? (complex, nullable)
|
||||
WriteComplexOrNull(obj.OrderMetadata, context, nextDepth);
|
||||
|
||||
// OrderNumber: string
|
||||
|
|
@ -74,16 +74,16 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter
|
|||
context.WriteByte(BinaryTypeCode.Null);
|
||||
}
|
||||
|
||||
// PrimaryTag: SharedTag? (complex, nullable)
|
||||
// PrimaryTag: SharedTag_All_True? (complex, nullable)
|
||||
WriteComplexOrNull(obj.PrimaryTag, context, nextDepth);
|
||||
|
||||
// SecondaryTag: SharedTag? (complex, nullable)
|
||||
// SecondaryTag: SharedTag_All_True? (complex, nullable)
|
||||
WriteComplexOrNull(obj.SecondaryTag, context, nextDepth);
|
||||
|
||||
// Status: TestStatus (enum, markerless)
|
||||
context.WriteVarInt((int)obj.Status);
|
||||
|
||||
// Tags: List<SharedTag> (collection)
|
||||
// Tags: List<SharedTag_All_True> (collection)
|
||||
WriteComplexOrNull(obj.Tags, context, nextDepth);
|
||||
|
||||
// TotalAmount: decimal (markerless)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ public sealed class JsonExtensionTests
|
|||
public void SemanticReference_SharedTag_SerializesWithSemanticId()
|
||||
{
|
||||
// Arrange
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var order = TestDataFactory.CreateOrder(itemCount: 2, sharedTag: sharedTag);
|
||||
|
||||
// Act
|
||||
|
|
@ -133,7 +133,7 @@ public sealed class JsonExtensionTests
|
|||
{
|
||||
// Arrange
|
||||
var sharedTag = TestDataFactory.CreateTag("OriginalKey");
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
|
|
@ -183,19 +183,19 @@ public sealed class JsonExtensionTests
|
|||
public void NewtonsoftReference_DeepNestedNonId_HandlesCorrectly()
|
||||
{
|
||||
// Arrange
|
||||
var rootMeta = new MetadataInfo
|
||||
var rootMeta = new MetadataInfo_All_True
|
||||
{
|
||||
Key = "Root",
|
||||
Value = "RootValue",
|
||||
ChildMetadata = new MetadataInfo
|
||||
ChildMetadata = new MetadataInfo_All_True
|
||||
{
|
||||
Key = "Child",
|
||||
Value = "ChildValue",
|
||||
ChildMetadata = new MetadataInfo { Key = "GrandChild", Value = "GrandChildValue" }
|
||||
ChildMetadata = new MetadataInfo_All_True { Key = "GrandChild", Value = "GrandChildValue" }
|
||||
}
|
||||
};
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
|
|
@ -225,7 +225,7 @@ public sealed class JsonExtensionTests
|
|||
var sharedMeta = TestDataFactory.CreateMetadata();
|
||||
sharedTag.Description = sharedMeta.Key; // Link them
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
|
|
@ -234,7 +234,7 @@ public sealed class JsonExtensionTests
|
|||
OrderMetadata = sharedMeta,
|
||||
AuditMetadata = sharedMeta,
|
||||
Tags = [sharedTag],
|
||||
Items = [new TestOrderItem { Id = 10, ProductName = "A", Tag = sharedTag, ItemMetadata = sharedMeta }]
|
||||
Items = [new TestOrderItem_All_True { Id = 10, ProductName = "A", Tag = sharedTag, ItemMetadata = sharedMeta }]
|
||||
};
|
||||
|
||||
var json = order.ToJson();
|
||||
|
|
@ -254,8 +254,8 @@ public sealed class JsonExtensionTests
|
|||
// Arrange
|
||||
var order = TestDataFactory.CreateOrder(itemCount: 1);
|
||||
order.NoMergeItems = [
|
||||
new TestOrderItem { Id = 100, ProductName = "NoMerge-A" },
|
||||
new TestOrderItem { Id = 101, ProductName = "NoMerge-B" }
|
||||
new TestOrderItem_All_True { Id = 100, ProductName = "NoMerge-A" },
|
||||
new TestOrderItem_All_True { Id = 101, ProductName = "NoMerge-B" }
|
||||
];
|
||||
|
||||
var originalRef = order.NoMergeItems;
|
||||
|
|
@ -284,13 +284,13 @@ public sealed class JsonExtensionTests
|
|||
public void NonIdCollection_ReplacesContent()
|
||||
{
|
||||
// Arrange
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
MetadataList = [
|
||||
new MetadataInfo { Key = "Old-A" },
|
||||
new MetadataInfo { Key = "Old-B" }
|
||||
new MetadataInfo_All_True { Key = "Old-A" },
|
||||
new MetadataInfo_All_True { Key = "Old-B" }
|
||||
]
|
||||
};
|
||||
|
||||
|
|
@ -367,7 +367,7 @@ public sealed class JsonExtensionTests
|
|||
|
||||
// Act
|
||||
var json = order.ToJson();
|
||||
var deserialized = json.JsonTo<TestOrder>();
|
||||
var deserialized = json.JsonTo<TestOrder_All_True>();
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(deserialized);
|
||||
|
|
@ -442,7 +442,7 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void WasmCompat_AcJsonSerializer_SimpleObject()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 99.99m, Status = TestStatus.Processing };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 99.99m, Status = TestStatus.Processing };
|
||||
|
||||
var json = AcJsonSerializer.Serialize(item);
|
||||
|
||||
|
|
@ -453,10 +453,10 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void WasmCompat_AcJsonDeserializer_RoundTrip()
|
||||
{
|
||||
var original = new TestOrderItem { Id = 42, ProductName = "WASM Test", Quantity = 5, UnitPrice = 25.50m, Status = TestStatus.Shipped };
|
||||
var original = new TestOrderItem_All_True { Id = 42, ProductName = "WASM Test", Quantity = 5, UnitPrice = 25.50m, Status = TestStatus.Shipped };
|
||||
var json = AcJsonSerializer.Serialize(original);
|
||||
|
||||
var deserialized = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
|
||||
var deserialized = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
|
||||
|
||||
Assert.IsNotNull(deserialized);
|
||||
Assert.AreEqual(42, deserialized.Id);
|
||||
|
|
@ -484,14 +484,14 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void WasmCompat_EmptyCollections_HandleCorrectly()
|
||||
{
|
||||
var order = new TestOrder { Id = 1, OrderNumber = "EMPTY-TEST", Items = [], Tags = [] };
|
||||
var order = new TestOrder_All_True { Id = 1, OrderNumber = "EMPTY-TEST", Items = [], Tags = [] };
|
||||
|
||||
var json = AcJsonSerializer.Serialize(order);
|
||||
|
||||
Assert.IsTrue(json.Contains("\"Items\":[]"), "Empty Items should serialize as []");
|
||||
Assert.IsTrue(json.Contains("\"Tags\":[]"), "Empty Tags should serialize as []");
|
||||
|
||||
var deserialized = AcJsonDeserializer.Deserialize<TestOrder>(json);
|
||||
var deserialized = AcJsonDeserializer.Deserialize<TestOrder_All_True>(json);
|
||||
|
||||
Assert.IsNotNull(deserialized?.Items);
|
||||
Assert.AreEqual(0, deserialized.Items.Count);
|
||||
|
|
@ -513,8 +513,8 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void WasmCompat_SharedReferences_IdRefResolution()
|
||||
{
|
||||
var sharedTag = new SharedTag { Id = 999, Name = "SharedKey" };
|
||||
var order = new TestOrder { Id = 1, OrderNumber = "REF-TEST", PrimaryTag = sharedTag, SecondaryTag = sharedTag, Tags = [sharedTag] };
|
||||
var sharedTag = new SharedTag_All_True { Id = 999, Name = "SharedKey" };
|
||||
var order = new TestOrder_All_True { Id = 1, OrderNumber = "REF-TEST", PrimaryTag = sharedTag, SecondaryTag = sharedTag, Tags = [sharedTag] };
|
||||
|
||||
var json = AcJsonSerializer.Serialize(order);
|
||||
|
||||
|
|
@ -528,7 +528,7 @@ public sealed class JsonExtensionTests
|
|||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
|
||||
var deserialized = JsonConvert.DeserializeObject<TestOrder>(json, nativeSettings);
|
||||
var deserialized = JsonConvert.DeserializeObject<TestOrder_All_True>(json, nativeSettings);
|
||||
|
||||
Assert.IsNotNull(deserialized);
|
||||
Assert.AreSame(deserialized.PrimaryTag, deserialized.SecondaryTag);
|
||||
|
|
@ -543,10 +543,10 @@ public sealed class JsonExtensionTests
|
|||
public void CrossSerializer_MixedReferences_CompatibleWithNewtonsoft()
|
||||
{
|
||||
// Arrange
|
||||
var sharedTag = new SharedTag { Id = 100, Name = "SharedKey", CreatedAt = DateTime.UtcNow };
|
||||
var sharedMeta = new MetadataInfo { Key = "SharedMeta", Value = "MetaValue", ChildMetadata = new MetadataInfo { Key = "Child" } };
|
||||
var sharedTag = new SharedTag_All_True { Id = 100, Name = "SharedKey", CreatedAt = DateTime.UtcNow };
|
||||
var sharedMeta = new MetadataInfo_All_True { Key = "SharedMeta", Value = "MetaValue", ChildMetadata = new MetadataInfo_All_True { Key = "Child" } };
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
|
|
@ -556,7 +556,7 @@ public sealed class JsonExtensionTests
|
|||
OrderMetadata = sharedMeta,
|
||||
AuditMetadata = sharedMeta,
|
||||
Tags = [sharedTag],
|
||||
Items = [new TestOrderItem { Id = 10, ProductName = "Product-A", Tag = sharedTag, ItemMetadata = sharedMeta }]
|
||||
Items = [new TestOrderItem_All_True { Id = 10, ProductName = "Product-A", Tag = sharedTag, ItemMetadata = sharedMeta }]
|
||||
};
|
||||
|
||||
// Act - Serialize with AyCode
|
||||
|
|
@ -570,7 +570,7 @@ public sealed class JsonExtensionTests
|
|||
NullValueHandling = NullValueHandling.Ignore
|
||||
};
|
||||
|
||||
var deserialized = JsonConvert.DeserializeObject<TestOrder>(json, nativeSettings);
|
||||
var deserialized = JsonConvert.DeserializeObject<TestOrder_All_True>(json, nativeSettings);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(deserialized);
|
||||
|
|
@ -589,11 +589,11 @@ public sealed class JsonExtensionTests
|
|||
var json = @"{
|
||||
""Id"": 1,
|
||||
""OrderNumber"": ""ORD-001"",
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" },
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" },
|
||||
""SecondaryTag"": { ""$ref"": ""1"" }
|
||||
}";
|
||||
|
||||
var order = new TestOrder { Id = 1, OrderNumber = "OLD" };
|
||||
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD" };
|
||||
|
||||
// Act
|
||||
json.JsonTo(order);
|
||||
|
|
@ -602,7 +602,7 @@ public sealed class JsonExtensionTests
|
|||
Assert.IsNotNull(order.PrimaryTag, "PrimaryTag should be set");
|
||||
Assert.IsNotNull(order.SecondaryTag, "SecondaryTag should be set from $ref");
|
||||
Assert.AreEqual(100, order.PrimaryTag.Id);
|
||||
Assert.AreEqual("SharedTag", order.PrimaryTag.Name);
|
||||
Assert.AreEqual("SharedTag_All_True", order.PrimaryTag.Name);
|
||||
Assert.AreSame(order.PrimaryTag, order.SecondaryTag,
|
||||
"SecondaryTag should reference the same object as PrimaryTag via $ref");
|
||||
}
|
||||
|
|
@ -613,14 +613,14 @@ public sealed class JsonExtensionTests
|
|||
var json = @"{
|
||||
""Id"": 1,
|
||||
""OrderNumber"": ""ORD-001"",
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" },
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" },
|
||||
""Tags"": [
|
||||
{ ""$ref"": ""1"" },
|
||||
{ ""$id"": ""2"", ""Id"": 200, ""Name"": ""OtherTag"" }
|
||||
]
|
||||
}";
|
||||
|
||||
var order = new TestOrder { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag>() };
|
||||
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag_All_True>() };
|
||||
|
||||
// Act
|
||||
json.JsonTo(order);
|
||||
|
|
@ -648,11 +648,11 @@ public sealed class JsonExtensionTests
|
|||
""PrimaryTag"": { ""$ref"": ""1"" }
|
||||
}";
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "OLD",
|
||||
Items = new List<TestOrderItem> { new TestOrderItem { Id = 10, ProductName = "OLD" } }
|
||||
Items = new List<TestOrderItem_All_True> { new TestOrderItem_All_True { Id = 10, ProductName = "OLD" } }
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -672,10 +672,10 @@ public sealed class JsonExtensionTests
|
|||
""Id"": 1,
|
||||
""OrderNumber"": ""ORD-001"",
|
||||
""SecondaryTag"": { ""$ref"": ""1"" },
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" }
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" }
|
||||
}";
|
||||
|
||||
var order = new TestOrder { Id = 1, OrderNumber = "OLD" };
|
||||
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD" };
|
||||
|
||||
// Act
|
||||
json.JsonTo(order);
|
||||
|
|
@ -693,7 +693,7 @@ public sealed class JsonExtensionTests
|
|||
var json = @"{
|
||||
""Id"": 1,
|
||||
""OrderNumber"": ""ORD-001"",
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" },
|
||||
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" },
|
||||
""SecondaryTag"": { ""$ref"": ""1"" },
|
||||
""Tags"": [
|
||||
{ ""$ref"": ""1"" },
|
||||
|
|
@ -702,7 +702,7 @@ public sealed class JsonExtensionTests
|
|||
]
|
||||
}";
|
||||
|
||||
var order = new TestOrder { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag>() };
|
||||
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag_All_True>() };
|
||||
|
||||
// Act
|
||||
json.JsonTo(order);
|
||||
|
|
@ -731,10 +731,10 @@ public sealed class JsonExtensionTests
|
|||
""PrimaryTag"": { ""$ref"": ""deep1"" }
|
||||
}";
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
Items = new List<TestOrderItem> { new TestOrderItem { Id = 10 } }
|
||||
Items = new List<TestOrderItem_All_True> { new TestOrderItem_All_True { Id = 10 } }
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -762,10 +762,10 @@ public sealed class JsonExtensionTests
|
|||
}]
|
||||
}";
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
Items = new List<TestOrderItem> { new TestOrderItem { Id = 10 } }
|
||||
Items = new List<TestOrderItem_All_True> { new TestOrderItem_All_True { Id = 10 } }
|
||||
};
|
||||
|
||||
// Act
|
||||
|
|
@ -789,7 +789,7 @@ public sealed class JsonExtensionTests
|
|||
}";
|
||||
|
||||
// Act
|
||||
var order = AcJsonDeserializer.Deserialize<TestOrder>(json);
|
||||
var order = AcJsonDeserializer.Deserialize<TestOrder_All_True>(json);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(order);
|
||||
|
|
@ -820,7 +820,7 @@ public sealed class JsonExtensionTests
|
|||
}";
|
||||
|
||||
// Act
|
||||
var order = AcJsonDeserializer.Deserialize<TestOrder>(json);
|
||||
var order = AcJsonDeserializer.Deserialize<TestOrder_All_True>(json);
|
||||
|
||||
// Assert
|
||||
Assert.IsNotNull(order);
|
||||
|
|
@ -841,8 +841,8 @@ public sealed class JsonExtensionTests
|
|||
""SecondaryTag"": { ""$ref"": ""1"" }
|
||||
}";
|
||||
|
||||
var existingTag = new SharedTag { Id = 999, Name = "ExistingTag" };
|
||||
var order = new TestOrder
|
||||
var existingTag = new SharedTag_All_True { Id = 999, Name = "ExistingTag" };
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
SecondaryTag = existingTag
|
||||
|
|
@ -1047,9 +1047,9 @@ public sealed class JsonExtensionTests
|
|||
{
|
||||
Id = 1,
|
||||
Name = "Test",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag" }
|
||||
};
|
||||
// Using existing Tag property with Guid in SharedTag's CreatedAt
|
||||
// Using existing Tag property with Guid in SharedTag_All_True's CreatedAt
|
||||
|
||||
var json = AcJsonSerializer.Serialize(obj);
|
||||
|
||||
|
|
@ -1240,8 +1240,8 @@ public sealed class JsonExtensionTests
|
|||
public void Populate_ObjectToObject_PopulatesProperties()
|
||||
{
|
||||
var json = "{\"Name\": \"Updated\", \"Id\": 99}";
|
||||
var obj = new SharedTag { Id = 1, Name = "Original" };
|
||||
AcJsonDeserializer.Populate(json, obj, typeof(SharedTag));
|
||||
var obj = new SharedTag_All_True { Id = 1, Name = "Original" };
|
||||
AcJsonDeserializer.Populate(json, obj, typeof(SharedTag_All_True));
|
||||
Assert.AreEqual(99, obj.Id);
|
||||
Assert.AreEqual("Updated", obj.Name);
|
||||
}
|
||||
|
|
@ -1249,14 +1249,14 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void Deserialize_NullJson_ReturnsDefault()
|
||||
{
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem>("null");
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>("null");
|
||||
Assert.IsNull(result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Deserialize_EmptyJson_ReturnsDefault()
|
||||
{
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem>("");
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>("");
|
||||
Assert.IsNull(result);
|
||||
}
|
||||
|
||||
|
|
@ -1312,7 +1312,7 @@ public sealed class JsonExtensionTests
|
|||
|
||||
try
|
||||
{
|
||||
AcJsonDeserializer.Deserialize<TestOrderItem>(invalidJson);
|
||||
AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(invalidJson);
|
||||
Assert.Fail("Expected AcJsonDeserializationException");
|
||||
}
|
||||
catch (AcJsonDeserializationException)
|
||||
|
|
@ -1329,7 +1329,7 @@ public sealed class JsonExtensionTests
|
|||
|
||||
try
|
||||
{
|
||||
AcJsonDeserializer.Deserialize<TestOrderItem>(doubleQuotedJson);
|
||||
AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(doubleQuotedJson);
|
||||
Assert.Fail("Expected AcJsonDeserializationException for double-serialized JSON");
|
||||
}
|
||||
catch (AcJsonDeserializationException ex)
|
||||
|
|
@ -1346,7 +1346,7 @@ public sealed class JsonExtensionTests
|
|||
|
||||
try
|
||||
{
|
||||
AcJsonDeserializer.Deserialize<TestOrderItem>(arrayJson);
|
||||
AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(arrayJson);
|
||||
Assert.Fail("Expected AcJsonDeserializationException");
|
||||
}
|
||||
catch (AcJsonDeserializationException ex)
|
||||
|
|
@ -1363,7 +1363,7 @@ public sealed class JsonExtensionTests
|
|||
|
||||
try
|
||||
{
|
||||
AcJsonDeserializer.Deserialize<List<TestOrderItem>>(objectJson);
|
||||
AcJsonDeserializer.Deserialize<List<TestOrderItem_All_True>>(objectJson);
|
||||
Assert.Fail("Expected AcJsonDeserializationException");
|
||||
}
|
||||
catch (AcJsonDeserializationException ex)
|
||||
|
|
@ -1376,7 +1376,7 @@ public sealed class JsonExtensionTests
|
|||
public void Populate_NullTarget_ThrowsArgumentNullException()
|
||||
{
|
||||
var json = "{\"Id\":1}";
|
||||
TestOrderItem? target = null;
|
||||
TestOrderItem_All_True? target = null;
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -1392,7 +1392,7 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void Populate_InvalidJson_ThrowsException()
|
||||
{
|
||||
var target = new TestOrderItem();
|
||||
var target = new TestOrderItem_All_True();
|
||||
var invalidJson = "{ not valid }";
|
||||
|
||||
try
|
||||
|
|
@ -1409,7 +1409,7 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void Populate_ArrayToNonList_ThrowsException()
|
||||
{
|
||||
var target = new TestOrderItem();
|
||||
var target = new TestOrderItem_All_True();
|
||||
var arrayJson = "[1,2,3]";
|
||||
|
||||
try
|
||||
|
|
@ -1432,7 +1432,7 @@ public sealed class JsonExtensionTests
|
|||
{
|
||||
var json = "{\"Id\":1,\"ProductName\":\"Test \\\"quoted\\\" and \\\\backslash\"}";
|
||||
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("Test \"quoted\" and \\backslash", result.ProductName);
|
||||
|
|
@ -1443,7 +1443,7 @@ public sealed class JsonExtensionTests
|
|||
{
|
||||
var json = "{\"Id\":1,\"ProductName\":\"中文日本語한국어🎉\"}";
|
||||
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual("中文日本語한국어🎉", result.ProductName);
|
||||
|
|
@ -1454,7 +1454,7 @@ public sealed class JsonExtensionTests
|
|||
{
|
||||
var json = "{\"Id\":999999999,\"ProductName\":\"Big\",\"Quantity\":2147483647}";
|
||||
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(999999999, result.Id);
|
||||
|
|
@ -1464,7 +1464,7 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void Serialize_ThenDeserialize_RoundTripPreservesData()
|
||||
{
|
||||
var original = new TestOrderItem
|
||||
var original = new TestOrderItem_All_True
|
||||
{
|
||||
Id = 42,
|
||||
ProductName = "Test with \"quotes\" and \\backslash",
|
||||
|
|
@ -1474,7 +1474,7 @@ public sealed class JsonExtensionTests
|
|||
};
|
||||
|
||||
var json = original.ToJson();
|
||||
var restored = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
|
||||
var restored = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
|
||||
|
||||
Assert.IsNotNull(restored);
|
||||
Assert.AreEqual(original.Id, restored.Id);
|
||||
|
|
@ -1491,12 +1491,12 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void Deserialize_TaskWrappedJson_DirectDeserialization_OnlyGetsRootProperties()
|
||||
{
|
||||
// This JSON represents a serialized Task<TestOrderItem> - the actual data is in "Result"
|
||||
// This JSON represents a serialized Task<TestOrderItem_All_True> - the actual data is in "Result"
|
||||
// This happens when someone forgets to await an async method before serializing
|
||||
var taskWrappedJson = "{\"Result\":{\"Id\":1,\"ProductName\":\"Processed: TestProduct\",\"Quantity\":10,\"UnitPrice\":20,\"TotalPrice\":200},\"Id\":1,\"Status\":5,\"IsCompleted\":true,\"IsCompletedSuccessfully\":true}";
|
||||
|
||||
// Direct deserialization to TestOrderItem only gets root-level properties
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(taskWrappedJson);
|
||||
// Direct deserialization to TestOrderItem_All_True only gets root-level properties
|
||||
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(taskWrappedJson);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
// Id=1 is at root level and matches
|
||||
|
|
@ -1509,11 +1509,11 @@ public sealed class JsonExtensionTests
|
|||
[TestMethod]
|
||||
public void Deserialize_TaskWrappedJson_UseWrapperClass_ExtractsCorrectly()
|
||||
{
|
||||
// This JSON represents a serialized Task<TestOrderItem> - the actual data is in "Result"
|
||||
// This JSON represents a serialized Task<TestOrderItem_All_True> - the actual data is in "Result"
|
||||
var taskWrappedJson = "{\"Result\":{\"Id\":1,\"ProductName\":\"Processed: TestProduct\",\"Quantity\":10,\"UnitPrice\":20,\"TotalPrice\":200},\"Id\":1,\"Status\":5,\"IsCompleted\":true,\"IsCompletedSuccessfully\":true}";
|
||||
|
||||
// Proper approach: deserialize to a wrapper type and extract Result
|
||||
var wrapper = AcJsonDeserializer.Deserialize<TaskResultWrapper<TestOrderItem>>(taskWrappedJson);
|
||||
var wrapper = AcJsonDeserializer.Deserialize<TaskResultWrapper<TestOrderItem_All_True>>(taskWrappedJson);
|
||||
|
||||
Assert.IsNotNull(wrapper);
|
||||
Assert.IsNotNull(wrapper.Result);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ public class AcBinarySerializerBenchmarkTests
|
|||
var binary = AcBinarySerializer.Serialize(order);
|
||||
Assert.IsTrue(binary.Length > 0, "Binary data should not be empty");
|
||||
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(binary);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binary);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(order.Id, result.Id);
|
||||
Assert.AreEqual(order.OrderNumber, result.OrderNumber);
|
||||
|
|
@ -29,7 +29,7 @@ public class AcBinarySerializerBenchmarkTests
|
|||
var binary = AcBinarySerializer.Serialize(order);
|
||||
Assert.IsTrue(binary.Length > 0);
|
||||
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(binary);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binary);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(order.Id, result.Id);
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ public class AcBinarySerializerBenchmarkTests
|
|||
var binary = AcBinarySerializer.Serialize(order);
|
||||
Assert.IsTrue(binary.Length > 0, "Binary data should not be empty");
|
||||
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder>(binary);
|
||||
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binary);
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(order.Id, result.Id);
|
||||
Assert.AreEqual(order.OrderNumber, result.OrderNumber);
|
||||
|
|
@ -69,8 +69,8 @@ public class AcBinarySerializerBenchmarkTests
|
|||
Console.WriteLine($"With interning: {binaryWithInterning.Length}, Without: {binaryWithoutInterning.Length}");
|
||||
|
||||
// Both should deserialize correctly regardless of size
|
||||
var result1 = AcBinaryDeserializer.Deserialize<TestOrder>(binaryWithInterning);
|
||||
var result2 = AcBinaryDeserializer.Deserialize<TestOrder>(binaryWithoutInterning);
|
||||
var result1 = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binaryWithInterning);
|
||||
var result2 = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binaryWithoutInterning);
|
||||
|
||||
Assert.IsNotNull(result1);
|
||||
Assert.IsNotNull(result2);
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ public class AcBinarySerializerChainReferenceTests
|
|||
public void ChainPopulate_IIdObjects_PreservesReferences()
|
||||
{
|
||||
// Setup: Create internal cache with 5 categories
|
||||
var internalCache = new List<SharedCategory>
|
||||
var internalCache = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 1, Name = "Category1", SortOrder = 1 },
|
||||
new() { Id = 2, Name = "Category2", SortOrder = 2 },
|
||||
|
|
@ -30,7 +30,7 @@ public class AcBinarySerializerChainReferenceTests
|
|||
};
|
||||
|
||||
// Server returns subset of categories (like grid pagination - page 2: items 3-5)
|
||||
var serverData = new List<SharedCategory>
|
||||
var serverData = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 3, Name = "Category3_Updated", SortOrder = 33 },
|
||||
new() { Id = 4, Name = "Category4_Updated", SortOrder = 44 },
|
||||
|
|
@ -41,10 +41,10 @@ public class AcBinarySerializerChainReferenceTests
|
|||
var binary = serverData.ToBinary();
|
||||
|
||||
// Grid's visible list (empty initially)
|
||||
var gridVisibleList = new List<SharedCategory>();
|
||||
var gridVisibleList = new List<SharedCategory_All_True>();
|
||||
|
||||
// CRITICAL: Use Chain API to parse once, populate both cache and grid
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory>>();
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
|
||||
|
||||
// First: Update internal cache (will become 3 items: 3-5 updated)
|
||||
chain.ThenPopulate(internalCache);
|
||||
|
|
@ -77,7 +77,7 @@ public class AcBinarySerializerChainReferenceTests
|
|||
public void JsonChainPopulate_IIdObjects_PreservesReferences()
|
||||
{
|
||||
// Setup: Create internal cache
|
||||
var internalCache = new List<SharedCategory>
|
||||
var internalCache = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 1, Name = "Category1", SortOrder = 1 },
|
||||
new() { Id = 2, Name = "Category2", SortOrder = 2 },
|
||||
|
|
@ -85,7 +85,7 @@ public class AcBinarySerializerChainReferenceTests
|
|||
};
|
||||
|
||||
// Server returns subset
|
||||
var serverData = new List<SharedCategory>
|
||||
var serverData = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 2, Name = "Category2_Updated", SortOrder = 22 },
|
||||
new() { Id = 3, Name = "Category3_Updated", SortOrder = 33 }
|
||||
|
|
@ -95,10 +95,10 @@ public class AcBinarySerializerChainReferenceTests
|
|||
var json = serverData.ToJson();
|
||||
|
||||
// Grid's visible list
|
||||
var gridVisibleList = new List<SharedCategory>();
|
||||
var gridVisibleList = new List<SharedCategory_All_True>();
|
||||
|
||||
// Use JSON Chain API
|
||||
using var chain = json.JsonToChain<List<SharedCategory>>();
|
||||
using var chain = json.JsonToChain<List<SharedCategory_All_True>>();
|
||||
|
||||
// Update internal cache (will replace with 2 items)
|
||||
chain.ThenPopulate(internalCache);
|
||||
|
|
@ -163,22 +163,22 @@ public class AcBinarySerializerChainReferenceTests
|
|||
{
|
||||
// Large internal cache
|
||||
var internalCache = Enumerable.Range(1, 10)
|
||||
.Select(i => new SharedCategory { Id = i, Name = $"Category{i}", SortOrder = i * 10 })
|
||||
.Select(i => new SharedCategory_All_True { Id = i, Name = $"Category{i}", SortOrder = i * 10 })
|
||||
.ToList();
|
||||
|
||||
// Server returns items 3-7
|
||||
var serverData = Enumerable.Range(3, 5)
|
||||
.Select(i => new SharedCategory { Id = i, Name = $"Category{i}_Updated", SortOrder = i * 11 })
|
||||
.Select(i => new SharedCategory_All_True { Id = i, Name = $"Category{i}_Updated", SortOrder = i * 11 })
|
||||
.ToList();
|
||||
|
||||
var binary = serverData.ToBinary();
|
||||
|
||||
// Three different grid pages/views
|
||||
var gridPage1 = new List<SharedCategory>();
|
||||
var gridPage2 = new List<SharedCategory>();
|
||||
var gridPage3 = new List<SharedCategory>();
|
||||
var gridPage1 = new List<SharedCategory_All_True>();
|
||||
var gridPage2 = new List<SharedCategory_All_True>();
|
||||
var gridPage3 = new List<SharedCategory_All_True>();
|
||||
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory>>();
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
|
||||
|
||||
// Update cache first
|
||||
chain.ThenPopulate(internalCache);
|
||||
|
|
@ -208,17 +208,17 @@ public class AcBinarySerializerChainReferenceTests
|
|||
[TestMethod]
|
||||
public void ChainPopulate_SimpleCase_Works()
|
||||
{
|
||||
var list1 = new List<SharedCategory>();
|
||||
var list2 = new List<SharedCategory>();
|
||||
var list1 = new List<SharedCategory_All_True>();
|
||||
var list2 = new List<SharedCategory_All_True>();
|
||||
|
||||
var serverData = new List<SharedCategory>
|
||||
var serverData = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 1, Name = "Cat1", SortOrder = 10 }
|
||||
};
|
||||
|
||||
var binary = serverData.ToBinary();
|
||||
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory>>();
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
|
||||
|
||||
// First populate
|
||||
chain.ThenPopulate(list1);
|
||||
|
|
|
|||
|
|
@ -96,9 +96,9 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
foreach (var mode in modes)
|
||||
{
|
||||
// Arrange: SAME instance used multiple times
|
||||
var userPreferences = new UserPreferences();
|
||||
var sharedTag = new SharedTag { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
|
||||
var sharedUser = new SharedUser { Id = 1, Preferences = userPreferences };
|
||||
var userPreferences = new UserPreferences_All_True();
|
||||
var sharedTag = new SharedTag_All_True { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
|
||||
var sharedUser = new SharedUser_All_True { Id = 1, Preferences = userPreferences };
|
||||
|
||||
var order = new TestOrder_Circ_Ref
|
||||
{
|
||||
|
|
@ -109,8 +109,8 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
Items =
|
||||
[
|
||||
new TestOrderItem_Circ_Ref { Id = 1, ProductName = "Product-A", Tag = sharedTag, Assignee = sharedUser },
|
||||
new TestOrderItem_Circ_Ref { Id = 2, ProductName = "Product-B", Tag = sharedTag, Assignee = new SharedUser { Id = 2, Preferences = userPreferences }},
|
||||
new TestOrderItem_Circ_Ref { Id = 3, ProductName = "Product-C", Tag = sharedTag, Assignee = new SharedUser { Id = 3, Preferences = userPreferences } }
|
||||
new TestOrderItem_Circ_Ref { Id = 2, ProductName = "Product-B", Tag = sharedTag, Assignee = new SharedUser_All_True { Id = 2, Preferences = userPreferences }},
|
||||
new TestOrderItem_Circ_Ref { Id = 3, ProductName = "Product-C", Tag = sharedTag, Assignee = new SharedUser_All_True { Id = 3, Preferences = userPreferences } }
|
||||
]
|
||||
};
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
break;
|
||||
|
||||
case ReferenceHandlingMode.All:
|
||||
// IId types + Non-IId (UserPreferences) should have ObjectRefs
|
||||
// IId types + Non-IId (UserPreferences_All_True) should have ObjectRefs
|
||||
Assert.IsTrue(objectRefCount >= 4, $"[{mode}] Expected at least 4 ObjectRefs, found {objectRefCount}");
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[0].Tag, $"[{mode}] Tag reference identity failed");
|
||||
Assert.AreSame(result.Owner, result.Items[0].Assignee, $"[{mode}] User reference identity failed");
|
||||
|
|
@ -176,7 +176,7 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
Assert.AreSame(result.Parent, result.Items[1]);
|
||||
|
||||
// Non-IId should also have reference identity in All mode
|
||||
Assert.AreSame(result.Owner.Preferences, result.Items[0].Assignee.Preferences, $"[{mode}] UserPreferences reference identity failed - Non-IId should work in All mode!");
|
||||
Assert.AreSame(result.Owner.Preferences, result.Items[0].Assignee.Preferences, $"[{mode}] UserPreferences_All_True reference identity failed - Non-IId should work in All mode!");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -207,44 +207,44 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
{
|
||||
// Arrange: DIFFERENT instances but SAME IId.Id
|
||||
// CRITICAL: Multiple DIFFERENT TYPES all have Id=1 - must not be confused!
|
||||
var sharedTag = new SharedTag { Id = 55, Name = "ImportantTag_55", Color = "#FF0000" };
|
||||
var order = new TestOrder
|
||||
var sharedTag = new SharedTag_All_True { Id = 55, Name = "ImportantTag_55", Color = "#FF0000" };
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
// All three types have Id=1 - tests (Type, Id) keying, not just Id
|
||||
PrimaryTag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Owner = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
|
||||
Category = new SharedCategory { Id = 1, Name = "Category_Id1", SortOrder = 10 },
|
||||
PrimaryTag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Owner = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
|
||||
Category = new SharedCategory_All_True { Id = 1, Name = "Category_Id1", SortOrder = 10 },
|
||||
Items =
|
||||
[
|
||||
new TestOrderItem
|
||||
new TestOrderItem_All_True
|
||||
{
|
||||
Id = 1,
|
||||
ProductName = "Product-A",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
},
|
||||
new TestOrderItem
|
||||
new TestOrderItem_All_True
|
||||
{
|
||||
Id = 2,
|
||||
ProductName = "Product-B",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
},
|
||||
new TestOrderItem
|
||||
new TestOrderItem_All_True
|
||||
{
|
||||
Id = 3,
|
||||
ProductName = "Product-C",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Act
|
||||
var binary = order.ToBinary();
|
||||
var result = binary.BinaryTo<TestOrder>();
|
||||
var result = binary.BinaryTo<TestOrder_All_True>();
|
||||
|
||||
// Assert 1: Check if ObjectRef is used (IId-based deduplication active)
|
||||
var objectRefCount = CountObjectRefs(binary);
|
||||
|
|
@ -254,11 +254,11 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
// Assert 3: Reference identity - same TYPE with same Id should be same reference
|
||||
// Tags with Id=1 should all be same reference
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[0].Tag,
|
||||
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
|
||||
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[1].Tag,
|
||||
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
|
||||
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[2].Tag,
|
||||
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
|
||||
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
|
||||
|
||||
// Users with Id=1 should all be same reference
|
||||
Assert.AreSame(result.Owner, result.Items[0].Assignee,
|
||||
|
|
@ -325,38 +325,38 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
public void DifferentInstances_SameIId_SmallerBinaryWithDataIntegrity()
|
||||
{
|
||||
// Arrange: 10 different instances with SAME IId
|
||||
var orderWithSameIId = new TestOrder
|
||||
var orderWithSameIId = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "SAME-IID",
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
|
||||
{
|
||||
Id = i,
|
||||
ProductName = $"Product-{i}",
|
||||
// All have SAME IId.Id = 1, but DIFFERENT instances
|
||||
Assignee = new SharedUser { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
// Arrange: 10 different instances with DIFFERENT IIds
|
||||
var orderWithDifferentIIds = new TestOrder
|
||||
var orderWithDifferentIIds = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "DIFF-IID",
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
|
||||
{
|
||||
Id = i,
|
||||
ProductName = $"Product-{i}",
|
||||
// All have DIFFERENT IId.Id
|
||||
Assignee = new SharedUser { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
|
||||
Assignee = new SharedUser_All_True { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
// Act
|
||||
var sameIIdBinary = orderWithSameIId.ToBinary();
|
||||
var diffIIdBinary = orderWithDifferentIIds.ToBinary();
|
||||
var sameIIdResult = sameIIdBinary.BinaryTo<TestOrder>();
|
||||
var diffIIdResult = diffIIdBinary.BinaryTo<TestOrder>();
|
||||
var sameIIdResult = sameIIdBinary.BinaryTo<TestOrder_All_True>();
|
||||
var diffIIdResult = diffIIdBinary.BinaryTo<TestOrder_All_True>();
|
||||
|
||||
// Assert 1: Size comparison
|
||||
Console.WriteLine($"Same IId binary size: {sameIIdBinary.Length} bytes");
|
||||
|
|
@ -506,15 +506,15 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
public void IIdDetection_Diagnostic()
|
||||
{
|
||||
// Test GetIdInfo directly
|
||||
var sharedTagType = typeof(SharedTag);
|
||||
var sharedTagType = typeof(SharedTag_All_True);
|
||||
var idInfo = AyCode.Core.Helpers.JsonUtilities.GetIdInfo(sharedTagType);
|
||||
|
||||
Console.WriteLine($"SharedTag GetIdInfo: IsId={idInfo.IsId}, IdType={idInfo.IdType?.Name}");
|
||||
Assert.IsTrue(idInfo.IsId, "SharedTag should be detected as IId<int>");
|
||||
Assert.AreEqual(typeof(int), idInfo.IdType, "SharedTag Id type should be int");
|
||||
Console.WriteLine($"SharedTag_All_True GetIdInfo: IsId={idInfo.IsId}, IdType={idInfo.IdType?.Name}");
|
||||
Assert.IsTrue(idInfo.IsId, "SharedTag_All_True should be detected as IId<int>");
|
||||
Assert.AreEqual(typeof(int), idInfo.IdType, "SharedTag_All_True Id type should be int");
|
||||
|
||||
// Test SharedUser
|
||||
var sharedUserType = typeof(SharedUser);
|
||||
var sharedUserType = typeof(SharedUser_All_True);
|
||||
var userIdInfo = AyCode.Core.Helpers.JsonUtilities.GetIdInfo(sharedUserType);
|
||||
Console.WriteLine($"SharedUser GetIdInfo: IsId={userIdInfo.IsId}, IdType={userIdInfo.IdType?.Name}");
|
||||
Assert.IsTrue(userIdInfo.IsId, "SharedUser should be detected as IId<int>");
|
||||
|
|
@ -532,7 +532,7 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
[TestMethod]
|
||||
public void SharedCategory_DataIntegrity()
|
||||
{
|
||||
var categories = new List<SharedCategory>
|
||||
var categories = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 1, Name = "Category1", SortOrder = 1, IsDefault = true },
|
||||
new() { Id = 2, Name = "Category2", SortOrder = 2, ParentCategoryId = 1 },
|
||||
|
|
@ -540,7 +540,7 @@ public class AcBinarySerializerIIdReferenceTests
|
|||
};
|
||||
|
||||
var binary = categories.ToBinary();
|
||||
var result = binary.BinaryTo<List<SharedCategory>>();
|
||||
var result = binary.BinaryTo<List<SharedCategory_All_True>>();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(3, result.Count);
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ public class AcBinarySerializerNamedPipeTests
|
|||
return await receiveTask.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder order)
|
||||
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder_All_True order)
|
||||
{
|
||||
var items = order.Items.Count;
|
||||
int pallets = 0, measurements = 0, points = 0;
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ public class AcBinarySerializerPipeParallelTests
|
|||
var pipe = new Pipe();
|
||||
using var input = new AsyncPipeReaderInput(initialCapacity: opts.BufferWriterChunkSize * 2);
|
||||
|
||||
var deserTask = Task.Run(() => AcBinaryDeserializer.Deserialize<TestOrder>(input, opts));
|
||||
var deserTask = Task.Run(() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(input, opts));
|
||||
var drainTask = input.DrainFromAsync(pipe.Reader);
|
||||
var serTask = Task.Run(async () =>
|
||||
{
|
||||
|
|
@ -541,7 +541,7 @@ public class AcBinarySerializerPipeParallelTests
|
|||
Assert.AreEqual(origCounts.points, resultCounts.points, "Points count mismatch");
|
||||
}
|
||||
|
||||
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder order)
|
||||
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder_All_True order)
|
||||
{
|
||||
var items = order.Items.Count;
|
||||
int pallets = 0, measurements = 0, points = 0;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class AcBinarySerializerSGenRuntimeCompatibilityTests
|
|||
var expectedJson = JsonSerializer.Serialize(dataSet.Order, StjOptions);
|
||||
|
||||
var bytes = AcBinarySerializer.Serialize(dataSet.Order, serializeOptions);
|
||||
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, deserializeOptions);
|
||||
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, deserializeOptions);
|
||||
var actualJson = JsonSerializer.Serialize(roundTrip, StjOptions);
|
||||
|
||||
Assert.AreEqual(expectedJson, actualJson, $"STJ mismatch. Dataset={dataSet.Name}, WireMode={serializeOptions.WireMode}, BaseOptions={serializeOptions.ReferenceHandling}/{serializeOptions.UseStringInterning}");
|
||||
|
|
@ -56,7 +56,7 @@ public class AcBinarySerializerSGenRuntimeCompatibilityTests
|
|||
var expectedJson = JsonSerializer.Serialize(dataSet.Order, StjOptions);
|
||||
|
||||
var bytes = AcBinarySerializer.Serialize(dataSet.Order, serializeOptions);
|
||||
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, deserializeOptions);
|
||||
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, deserializeOptions);
|
||||
var actualJson = JsonSerializer.Serialize(roundTrip, StjOptions);
|
||||
|
||||
Assert.AreEqual(expectedJson, actualJson, $"STJ mismatch. Dataset={dataSet.Name}, WireMode={serializeOptions.WireMode}, BaseOptions={serializeOptions.ReferenceHandling}/{serializeOptions.UseStringInterning}");
|
||||
|
|
@ -97,7 +97,7 @@ public class AcBinarySerializerSGenRuntimeCompatibilityTests
|
|||
};
|
||||
}
|
||||
|
||||
private static void AssertOrderEquivalent(TestOrder expected, TestOrder? actual, string context)
|
||||
private static void AssertOrderEquivalent(TestOrder_All_True expected, TestOrder_All_True? actual, string context)
|
||||
{
|
||||
Assert.IsNotNull(actual, context);
|
||||
Assert.AreEqual(expected.Id, actual.Id, context);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ public class AcExpressionNodeSerializationTests
|
|||
public void AcJsonSerializer_WithAcExpressionNode_RoundTrip_Works()
|
||||
{
|
||||
// Arrange - Create an expression with a constant value
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
|
||||
item => item.Quantity > 5;
|
||||
|
||||
var expressionNode = AcExpressionConverter.ToNode(filterExpression);
|
||||
|
|
@ -39,11 +39,11 @@ public class AcExpressionNodeSerializationTests
|
|||
Assert.IsNotNull(deserialized, "Deserialized node should not be null");
|
||||
|
||||
// Rebuild and test
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserialized);
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserialized);
|
||||
var compiled = rebuiltExpression.Compile();
|
||||
|
||||
var matchingItem = new TestOrderItem { Id = 1, Quantity = 10 };
|
||||
var nonMatchingItem = new TestOrderItem { Id = 2, Quantity = 3 };
|
||||
var matchingItem = new TestOrderItem_All_True { Id = 1, Quantity = 10 };
|
||||
var nonMatchingItem = new TestOrderItem_All_True { Id = 2, Quantity = 3 };
|
||||
|
||||
Assert.IsTrue(compiled(matchingItem), "Matching item should pass filter");
|
||||
Assert.IsFalse(compiled(nonMatchingItem), "Non-matching item should fail filter");
|
||||
|
|
@ -121,7 +121,7 @@ public class AcExpressionNodeSerializationTests
|
|||
public void AcBinarySerializer_WithAcExpressionNode_RoundTrip_Works()
|
||||
{
|
||||
// Arrange
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
|
||||
item => item.Quantity > 5;
|
||||
|
||||
var originalNode = AcExpressionConverter.ToNode(filterExpression);
|
||||
|
|
@ -137,11 +137,11 @@ public class AcExpressionNodeSerializationTests
|
|||
Assert.AreEqual(originalNode.NodeType, deserialized.NodeType);
|
||||
|
||||
// Rebuild and test
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserialized);
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserialized);
|
||||
var compiled = rebuiltExpression.Compile();
|
||||
|
||||
var matchingItem = new TestOrderItem { Id = 1, Quantity = 10 };
|
||||
var nonMatchingItem = new TestOrderItem { Id = 2, Quantity = 3 };
|
||||
var matchingItem = new TestOrderItem_All_True { Id = 1, Quantity = 10 };
|
||||
var nonMatchingItem = new TestOrderItem_All_True { Id = 2, Quantity = 3 };
|
||||
|
||||
Assert.IsTrue(compiled(matchingItem), "Matching item should pass filter");
|
||||
Assert.IsFalse(compiled(nonMatchingItem), "Non-matching item should fail filter");
|
||||
|
|
@ -183,7 +183,7 @@ public class AcExpressionNodeSerializationTests
|
|||
{
|
||||
// Arrange - Expression with captured decimal: item => item.UnitPrice > 99.99m
|
||||
var minPrice = 99.99m;
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
|
||||
item => item.UnitPrice > minPrice;
|
||||
|
||||
var originalNode = AcExpressionConverter.ToNode(filterExpression);
|
||||
|
|
@ -195,11 +195,11 @@ public class AcExpressionNodeSerializationTests
|
|||
// Assert - Rebuild and verify it still works with decimal comparison
|
||||
Assert.IsNotNull(deserializedNode);
|
||||
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserializedNode);
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserializedNode);
|
||||
var compiledFilter = rebuiltExpression.Compile();
|
||||
|
||||
var expensiveItem = new TestOrderItem { UnitPrice = 150m };
|
||||
var cheapItem = new TestOrderItem { UnitPrice = 50m };
|
||||
var expensiveItem = new TestOrderItem_All_True { UnitPrice = 150m };
|
||||
var cheapItem = new TestOrderItem_All_True { UnitPrice = 50m };
|
||||
|
||||
Assert.IsTrue(compiledFilter(expensiveItem), "Expensive item should pass filter");
|
||||
Assert.IsFalse(compiledFilter(cheapItem), "Cheap item should fail filter");
|
||||
|
|
@ -212,7 +212,7 @@ public class AcExpressionNodeSerializationTests
|
|||
public void AcBinarySerializer_WithEnumValue_PreservesType()
|
||||
{
|
||||
// Arrange - Expression with enum comparison
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
|
||||
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
|
||||
item => item.Status == TestStatus.Completed;
|
||||
|
||||
var originalNode = AcExpressionConverter.ToNode(filterExpression);
|
||||
|
|
@ -224,11 +224,11 @@ public class AcExpressionNodeSerializationTests
|
|||
// Assert
|
||||
Assert.IsNotNull(deserializedNode);
|
||||
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserializedNode);
|
||||
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserializedNode);
|
||||
var compiledFilter = rebuiltExpression.Compile();
|
||||
|
||||
var completedItem = new TestOrderItem { Status = TestStatus.Completed };
|
||||
var pendingItem = new TestOrderItem { Status = TestStatus.Pending };
|
||||
var completedItem = new TestOrderItem_All_True { Status = TestStatus.Completed };
|
||||
var pendingItem = new TestOrderItem_All_True { Status = TestStatus.Pending };
|
||||
|
||||
Assert.IsTrue(compiledFilter(completedItem), "Completed item should pass filter");
|
||||
Assert.IsFalse(compiledFilter(pendingItem), "Pending item should fail filter");
|
||||
|
|
|
|||
|
|
@ -46,25 +46,25 @@ public class AcJsonSerializerIIdReferenceTests
|
|||
public void SameInstance_Json_SerializeAndDeserialize()
|
||||
{
|
||||
// Arrange: SAME instance used 4 times
|
||||
var sharedTag = new SharedTag { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
|
||||
var sharedTag = new SharedTag_All_True { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
PrimaryTag = sharedTag,
|
||||
Items =
|
||||
[
|
||||
new TestOrderItem { Id = 1, ProductName = "Product-A", Tag = sharedTag },
|
||||
new TestOrderItem { Id = 2, ProductName = "Product-B", Tag = sharedTag },
|
||||
new TestOrderItem { Id = 3, ProductName = "Product-C", Tag = sharedTag }
|
||||
new TestOrderItem_All_True { Id = 1, ProductName = "Product-A", Tag = sharedTag },
|
||||
new TestOrderItem_All_True { Id = 2, ProductName = "Product-B", Tag = sharedTag },
|
||||
new TestOrderItem_All_True { Id = 3, ProductName = "Product-C", Tag = sharedTag }
|
||||
]
|
||||
};
|
||||
|
||||
// Act
|
||||
var json = order.ToJson();
|
||||
Console.WriteLine(json);
|
||||
var result = json.JsonTo<TestOrder>();
|
||||
var result = json.JsonTo<TestOrder_All_True>();
|
||||
|
||||
// Assert 1: JSON contains $ref markers (reference handling is active)
|
||||
var refCount = CountOccurrences(json, "{\"$ref\":\"1\"}");
|
||||
|
|
@ -118,43 +118,43 @@ public class AcJsonSerializerIIdReferenceTests
|
|||
{
|
||||
// Arrange: DIFFERENT instances but SAME IId.Id
|
||||
// CRITICAL: Multiple DIFFERENT TYPES all have Id=1 - must not be confused!
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "ORD-001",
|
||||
// All three types have Id=1 - tests (Type, Id) keying, not just Id
|
||||
PrimaryTag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Owner = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
|
||||
Category = new SharedCategory { Id = 1, Name = "Category_Id1", SortOrder = 10 },
|
||||
PrimaryTag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Owner = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
|
||||
Category = new SharedCategory_All_True { Id = 1, Name = "Category_Id1", SortOrder = 10 },
|
||||
Items =
|
||||
[
|
||||
new TestOrderItem
|
||||
new TestOrderItem_All_True
|
||||
{
|
||||
Id = 1,
|
||||
ProductName = "Product-A",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
},
|
||||
new TestOrderItem
|
||||
new TestOrderItem_All_True
|
||||
{
|
||||
Id = 2,
|
||||
ProductName = "Product-B",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
},
|
||||
new TestOrderItem
|
||||
new TestOrderItem_All_True
|
||||
{
|
||||
Id = 3,
|
||||
ProductName = "Product-C",
|
||||
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Act
|
||||
var json = order.ToJson();
|
||||
var result = json.JsonTo<TestOrder>();
|
||||
var result = json.JsonTo<TestOrder_All_True>();
|
||||
|
||||
// Assert 1: Check if $ref is used (IId-based deduplication active)
|
||||
var refCount = CountOccurrences(json, "\"$ref\"");
|
||||
|
|
@ -208,11 +208,11 @@ public class AcJsonSerializerIIdReferenceTests
|
|||
// Assert 3: Reference identity - same TYPE with same Id should be same reference
|
||||
// Tags with Id=1 should all be same reference
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[0].Tag,
|
||||
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
|
||||
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[1].Tag,
|
||||
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
|
||||
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
|
||||
Assert.AreSame(result.PrimaryTag, result.Items[2].Tag,
|
||||
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
|
||||
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
|
||||
|
||||
// Users with Id=1 should all be same reference
|
||||
Assert.AreSame(result.Owner, result.Items[0].Assignee,
|
||||
|
|
@ -238,36 +238,36 @@ public class AcJsonSerializerIIdReferenceTests
|
|||
public void DifferentInstances_SameIId_SmallerJsonWithDataIntegrity()
|
||||
{
|
||||
// Arrange: 10 different instances with SAME IId
|
||||
var orderWithSameIId = new TestOrder
|
||||
var orderWithSameIId = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "SAME-IID",
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
|
||||
{
|
||||
Id = i,
|
||||
ProductName = $"Product-{i}",
|
||||
Assignee = new SharedUser { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
|
||||
Assignee = new SharedUser_All_True { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
// Arrange: 10 different instances with DIFFERENT IIds
|
||||
var orderWithDifferentIIds = new TestOrder
|
||||
var orderWithDifferentIIds = new TestOrder_All_True
|
||||
{
|
||||
Id = 1,
|
||||
OrderNumber = "DIFF-IID",
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
|
||||
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
|
||||
{
|
||||
Id = i,
|
||||
ProductName = $"Product-{i}",
|
||||
Assignee = new SharedUser { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
|
||||
Assignee = new SharedUser_All_True { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
|
||||
}).ToList()
|
||||
};
|
||||
|
||||
// Act
|
||||
var sameIIdJson = orderWithSameIId.ToJson();
|
||||
var diffIIdJson = orderWithDifferentIIds.ToJson();
|
||||
var sameIIdResult = sameIIdJson.JsonTo<TestOrder>();
|
||||
var diffIIdResult = diffIIdJson.JsonTo<TestOrder>();
|
||||
var sameIIdResult = sameIIdJson.JsonTo<TestOrder_All_True>();
|
||||
var diffIIdResult = diffIIdJson.JsonTo<TestOrder_All_True>();
|
||||
|
||||
// Assert 1: Size comparison
|
||||
Console.WriteLine($"Same IId JSON size: {sameIIdJson.Length} chars");
|
||||
|
|
@ -416,7 +416,7 @@ public class AcJsonSerializerIIdReferenceTests
|
|||
[TestMethod]
|
||||
public void SharedCategory_DataIntegrity()
|
||||
{
|
||||
var categories = new List<SharedCategory>
|
||||
var categories = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 1, Name = "Category1", SortOrder = 1, IsDefault = true },
|
||||
new() { Id = 2, Name = "Category2", SortOrder = 2, ParentCategoryId = 1 },
|
||||
|
|
@ -424,7 +424,7 @@ public class AcJsonSerializerIIdReferenceTests
|
|||
};
|
||||
|
||||
var json = categories.ToJson();
|
||||
var result = json.JsonTo<List<SharedCategory>>();
|
||||
var result = json.JsonTo<List<SharedCategory_All_True>>();
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(3, result.Count);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ public class ChainReferenceDebugTest
|
|||
// Test ChainReferenceTracker directly
|
||||
var tracker = new AcSerializerCommon.ChainReferenceTracker();
|
||||
|
||||
var category = new SharedCategory { Id = 100, Name = "TestCategory" };
|
||||
var category = new SharedCategory_All_True { Id = 100, Name = "TestCategory" };
|
||||
|
||||
// Register using reflection (like ThenPopulate does)
|
||||
tracker.TryRegisterIIdObject(category);
|
||||
|
|
@ -32,17 +32,17 @@ public class ChainReferenceDebugTest
|
|||
[TestMethod]
|
||||
public void DebugSimpleChainPopulate()
|
||||
{
|
||||
var list1 = new List<SharedCategory>();
|
||||
var list2 = new List<SharedCategory>();
|
||||
var list1 = new List<SharedCategory_All_True>();
|
||||
var list2 = new List<SharedCategory_All_True>();
|
||||
|
||||
var serverData = new List<SharedCategory>
|
||||
var serverData = new List<SharedCategory_All_True>
|
||||
{
|
||||
new() { Id = 1, Name = "Cat1", SortOrder = 10 }
|
||||
};
|
||||
|
||||
var binary = serverData.ToBinary();
|
||||
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory>>();
|
||||
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
|
||||
|
||||
// First populate
|
||||
chain.ThenPopulate(list1);
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public class GeneratedSerializerIntegrationTests
|
|||
public void GeneratedWriter_ComplexHierarchy_RoundTrip()
|
||||
{
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
|
||||
var order = TestDataFactory.CreateOrder(
|
||||
|
|
@ -116,7 +116,7 @@ public class GeneratedSerializerIntegrationTests
|
|||
|
||||
var options = AcBinarySerializerOptions.FastMode;
|
||||
var bytes = AcBinarySerializer.Serialize(order, options);
|
||||
var deserialized = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, options);
|
||||
var deserialized = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, options);
|
||||
|
||||
Assert.IsNotNull(deserialized);
|
||||
Assert.AreEqual(order.Id, deserialized.Id);
|
||||
|
|
|
|||
|
|
@ -83,12 +83,12 @@ public class QuickBenchmark
|
|||
Console.WriteLine($"[WARN] Deserialize: AcBinary is {deserRatio:F2}x slower");
|
||||
}
|
||||
|
||||
private static TestOrder CreatePopulateTarget(TestOrder source)
|
||||
private static TestOrder_All_True CreatePopulateTarget(TestOrder_All_True source)
|
||||
{
|
||||
var target = new TestOrder { Id = source.Id };
|
||||
var target = new TestOrder_All_True { Id = source.Id };
|
||||
foreach (var item in source.Items)
|
||||
{
|
||||
target.Items.Add(new TestOrderItem { Id = item.Id });
|
||||
target.Items.Add(new TestOrderItem_All_True { Id = item.Id });
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ public class QuickBenchmark
|
|||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
var bytes = order.ToBinary();
|
||||
var result = bytes.BinaryTo<TestOrder>();
|
||||
var result = bytes.BinaryTo<TestOrder_All_True>();
|
||||
}
|
||||
|
||||
// Measure serialize
|
||||
|
|
@ -121,10 +121,10 @@ public class QuickBenchmark
|
|||
|
||||
// Measure deserialize
|
||||
sw.Restart();
|
||||
TestOrder? deserialized = null;
|
||||
TestOrder_All_True? deserialized = null;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
deserialized = serialized.BinaryTo<TestOrder>();
|
||||
deserialized = serialized.BinaryTo<TestOrder_All_True>();
|
||||
}
|
||||
sw.Stop();
|
||||
var deserializeMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
|
@ -143,7 +143,7 @@ public class QuickBenchmark
|
|||
sw.Restart();
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
var _ = json.JsonTo<TestOrder>(jsonOptions);
|
||||
var _ = json.JsonTo<TestOrder_All_True>(jsonOptions);
|
||||
}
|
||||
sw.Stop();
|
||||
var jsonDeserializeMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
|
@ -234,9 +234,9 @@ public class QuickBenchmark
|
|||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
var binBytes = AcBinarySerializer.Serialize(order, AcBinarySerializerOptions.Default);
|
||||
var binResult = AcBinaryDeserializer.Deserialize<TestOrder>(binBytes);
|
||||
var binResult = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binBytes);
|
||||
var msgBytes = MessagePackSerializer.Serialize(order, MsgPackOptions);
|
||||
var msgResult = MessagePackSerializer.Deserialize<TestOrder>(msgBytes, MsgPackOptions);
|
||||
var msgResult = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgBytes, MsgPackOptions);
|
||||
}
|
||||
|
||||
const int iterations = DefaultIterations;
|
||||
|
|
@ -263,20 +263,20 @@ public class QuickBenchmark
|
|||
|
||||
// === AcBinary Deserialize ===
|
||||
sw.Restart();
|
||||
TestOrder? acBinaryResult = null;
|
||||
TestOrder_All_True? acBinaryResult = null;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
acBinaryResult = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryData);
|
||||
acBinaryResult = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryData);
|
||||
}
|
||||
sw.Stop();
|
||||
var acBinaryDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// === MessagePack Deserialize ===
|
||||
sw.Restart();
|
||||
TestOrder? msgPackResult = null;
|
||||
TestOrder_All_True? msgPackResult = null;
|
||||
for (int i = 0; i < iterations; i++)
|
||||
{
|
||||
msgPackResult = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, MsgPackOptions);
|
||||
msgPackResult = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, MsgPackOptions);
|
||||
}
|
||||
sw.Stop();
|
||||
var msgPackDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
|
@ -382,7 +382,7 @@ public class QuickBenchmark
|
|||
public void GetAnalyzeStringInternCandidatesLog()
|
||||
{
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
|
|
@ -413,7 +413,7 @@ public class QuickBenchmark
|
|||
{
|
||||
// Create test data with shared references
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
|
|
@ -492,7 +492,7 @@ public class QuickBenchmark
|
|||
|
||||
// Create test data with shared references
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
|
|
@ -532,10 +532,10 @@ public class QuickBenchmark
|
|||
_ = MessagePackSerializer.Serialize(testOrder, MsgPackOptions);
|
||||
|
||||
Console.WriteLine("acBinaryWithRef");
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryWithRef);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryWithRef);
|
||||
Console.WriteLine("acBinaryNoRef");
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryNoRef);
|
||||
_ = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, MsgPackOptions);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryNoRef);
|
||||
_ = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, MsgPackOptions);
|
||||
}
|
||||
|
||||
// Wait for tiered JIT background compilation to complete
|
||||
|
|
@ -573,19 +573,19 @@ public class QuickBenchmark
|
|||
// === Deserialize WithRef ===
|
||||
sw.Restart();
|
||||
for (int i = 0; i < DefaultIterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryWithRef);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryWithRef);
|
||||
var acWithRefDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// === Deserialize NoRef ===
|
||||
sw.Restart();
|
||||
for (int i = 0; i < DefaultIterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryNoRef);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryNoRef);
|
||||
var acNoRefDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// === MessagePack Deserialize ===
|
||||
sw.Restart();
|
||||
for (int i = 0; i < DefaultIterations; i++)
|
||||
_ = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, MsgPackOptions);
|
||||
_ = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, MsgPackOptions);
|
||||
var msgPackDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// === Populate (AcBinary only) ===
|
||||
|
|
@ -632,7 +632,7 @@ public class QuickBenchmark
|
|||
|
||||
// Create test data WITH shared references (to show WithRef advantage)
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
|
|
@ -685,13 +685,13 @@ public class QuickBenchmark
|
|||
// Deserialize WithRef
|
||||
sw.Restart();
|
||||
for (int i = 0; i < DefaultIterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(withRefData);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(withRefData);
|
||||
var withRefDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// Deserialize NoRef
|
||||
sw.Restart();
|
||||
for (int i = 0; i < DefaultIterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(noRefData);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(noRefData);
|
||||
var noRefDeserMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
PrintBanner("PERFORMANCE COMPARISON (ms)");
|
||||
|
|
@ -709,8 +709,8 @@ public class QuickBenchmark
|
|||
}
|
||||
|
||||
// Verify correctness
|
||||
var resultWithRef = AcBinaryDeserializer.Deserialize<TestOrder>(withRefData);
|
||||
var resultNoRef = AcBinaryDeserializer.Deserialize<TestOrder>(noRefData);
|
||||
var resultWithRef = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(withRefData);
|
||||
var resultNoRef = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(noRefData);
|
||||
Assert.IsNotNull(resultWithRef);
|
||||
Assert.IsNotNull(resultNoRef);
|
||||
Assert.AreEqual(testOrder.Id, resultWithRef.Id);
|
||||
|
|
@ -755,7 +755,7 @@ public class QuickBenchmark
|
|||
// Deserialize (creates new object)
|
||||
sw.Restart();
|
||||
for (int i = 0; i < DefaultIterations; i++)
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder>(binaryData);
|
||||
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binaryData);
|
||||
var deserializeMs = sw.Elapsed.TotalMilliseconds;
|
||||
|
||||
// Populate (reuses existing object)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ namespace AyCode.Core.Tests.TestModels;
|
|||
/// </summary>
|
||||
public static class CharsetSuffixes
|
||||
{
|
||||
/// <summary>Empty suffix — short Hungarian baseline strings (e.g. "SharedTag") stay short, hitting
|
||||
/// <summary>Empty suffix — short Hungarian baseline strings (e.g. "SharedTag_All_True") stay short, hitting
|
||||
/// the FixStr fast-path. Stress-test for FixStr / short-string code paths. Note: the baseline
|
||||
/// property values remain Hungarian; only the suffix is empty. Despite the "FixAscii" name, this
|
||||
/// option does NOT change baseline values to ASCII — it suppresses the suffix that would otherwise
|
||||
|
|
@ -82,7 +82,7 @@ public static class BenchmarkTestDataProvider
|
|||
{
|
||||
if (resetId) TestDataFactory.ResetIdCounter();
|
||||
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
|
||||
var order = TestDataFactory.CreateOrder(
|
||||
|
|
@ -104,11 +104,11 @@ public static class BenchmarkTestDataProvider
|
|||
{
|
||||
if (resetId) TestDataFactory.ResetIdCounter();
|
||||
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
|
||||
|
||||
var sharedPreferences = new UserPreferences
|
||||
var sharedPreferences = new UserPreferences_All_True
|
||||
{
|
||||
Theme = "dark",
|
||||
Language = "hungarian",
|
||||
|
|
@ -138,10 +138,10 @@ public static class BenchmarkTestDataProvider
|
|||
{
|
||||
if (resetId) TestDataFactory.ResetIdCounter();
|
||||
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag");
|
||||
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
|
||||
var sharedUser = TestDataFactory.CreateUser("shareduser");
|
||||
|
||||
var sharedPreferences = new UserPreferences
|
||||
var sharedPreferences = new UserPreferences_All_True
|
||||
{
|
||||
Theme = "light",
|
||||
Language = "german",
|
||||
|
|
@ -173,7 +173,7 @@ public static class BenchmarkTestDataProvider
|
|||
var sharedTag = TestDataFactory.CreateTag("RepeatedTag");
|
||||
var sharedUser = TestDataFactory.CreateUser("repeateduser");
|
||||
|
||||
var sharedPreferences = new UserPreferences
|
||||
var sharedPreferences = new UserPreferences_All_True
|
||||
{
|
||||
Theme = "dark",
|
||||
Language = "hungarian",
|
||||
|
|
@ -223,7 +223,7 @@ public static class BenchmarkTestDataProvider
|
|||
var sharedUser = TestDataFactory.CreateUser("deepuser");
|
||||
var sharedCategory = TestDataFactory.CreateCategory("DeepCategory");
|
||||
|
||||
var sharedPreferences = new UserPreferences
|
||||
var sharedPreferences = new UserPreferences_All_True
|
||||
{
|
||||
Theme = "light",
|
||||
Language = "french",
|
||||
|
|
@ -249,7 +249,7 @@ public static class BenchmarkTestDataProvider
|
|||
return new TestDataSet("Deep Nested (2x4x4x8)", order, iidRefPercent: 20);
|
||||
}
|
||||
|
||||
private static void ClearDeepLevelRefs(TestOrder order)
|
||||
private static void ClearDeepLevelRefs(TestOrder_All_True order)
|
||||
{
|
||||
// Keep shared IId refs at the pallet level (Tag + Inspector) — these contribute the bulk of
|
||||
// the ~20% IId-ref share that the test data targets. Only Category is cleared at this level
|
||||
|
|
@ -338,10 +338,10 @@ public static class BenchmarkTestDataProvider
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class TestDataSet
|
||||
public class TestDataSet<TOrder>
|
||||
{
|
||||
public string Name { get; }
|
||||
public TestOrder Order { get; }
|
||||
public TOrder Order { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Percentage of IId shared references in the data (0-100).
|
||||
|
|
@ -349,7 +349,7 @@ public sealed class TestDataSet
|
|||
/// </summary>
|
||||
public int IIdRefPercent { get; }
|
||||
|
||||
public TestDataSet(string name, TestOrder order, int iidRefPercent = 0)
|
||||
public TestDataSet(string name, TOrder order, int iidRefPercent = 0)
|
||||
{
|
||||
Name = name;
|
||||
Order = order;
|
||||
|
|
@ -365,3 +365,11 @@ public sealed class TestDataSet
|
|||
? $"{Name} [{IIdRefPercent}% IId refs]"
|
||||
: Name;
|
||||
}
|
||||
|
||||
public sealed class TestDataSet : TestDataSet<TestOrder_All_True>
|
||||
{
|
||||
public TestDataSet(string name, TestOrder_All_True order, int iidRefPercent = 0)
|
||||
: base(name, order, iidRefPercent)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,303 @@
|
|||
using AyCode.Core.Extensions;
|
||||
using AyCode.Core.Interfaces;
|
||||
using AyCode.Core.Serializers.Attributes;
|
||||
using AyCode.Core.Serializers.Binaries;
|
||||
using AyCode.Core.Serializers.Jsons;
|
||||
using MemoryPack;
|
||||
using MessagePack;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace AyCode.Core.Tests.TestModels;
|
||||
|
||||
#region Shared Reference Base Types
|
||||
|
||||
public abstract class SharedTagBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Name { get; set; } = "";
|
||||
[AcStringIntern(true)]
|
||||
[Key(2)]
|
||||
public string Color { get; set; } = "#000000";
|
||||
[Key(3)]
|
||||
public int Priority { get; set; }
|
||||
[Key(4)]
|
||||
public bool IsActive { get; set; } = true;
|
||||
[Key(5)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(6)]
|
||||
public string? Description { get; set; }
|
||||
}
|
||||
|
||||
public abstract class SharedCategoryBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Name { get; set; } = "";
|
||||
[Key(2)]
|
||||
public string? Description { get; set; }
|
||||
[Key(3)]
|
||||
public int SortOrder { get; set; }
|
||||
[Key(4)]
|
||||
public bool IsDefault { get; set; }
|
||||
[Key(5)]
|
||||
public int? ParentCategoryId { get; set; }
|
||||
[Key(6)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(7)]
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
public abstract class SharedUserBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Username { get; set; } = "";
|
||||
[Key(2)]
|
||||
public string Email { get; set; } = "";
|
||||
[Key(3)]
|
||||
public string FirstName { get; set; } = "";
|
||||
[Key(4)]
|
||||
public string LastName { get; set; } = "";
|
||||
[Key(5)]
|
||||
public bool IsActive { get; set; } = true;
|
||||
[Key(6)]
|
||||
public TestUserRole Role { get; set; } = TestUserRole.User;
|
||||
[Key(7)]
|
||||
public DateTime? LastLoginAt { get; set; }
|
||||
[Key(8)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(9)]
|
||||
public UserPreferences_All_True? Preferences { get; set; }
|
||||
}
|
||||
|
||||
public abstract class UserPreferencesBase
|
||||
{
|
||||
[AcStringIntern(true)]
|
||||
[Key(0)]
|
||||
public string Theme { get; set; } = "light";
|
||||
[AcStringIntern(true)]
|
||||
[Key(1)]
|
||||
public string Language { get; set; } = "en-US";
|
||||
[Key(2)]
|
||||
public bool NotificationsEnabled { get; set; } = true;
|
||||
[AcStringIntern(true)]
|
||||
[Key(3)]
|
||||
public string? EmailDigestFrequency { get; set; }
|
||||
}
|
||||
|
||||
public abstract class MetadataInfoBase
|
||||
{
|
||||
[AcStringIntern(true)]
|
||||
[Key(0)]
|
||||
public string Key { get; set; } = "";
|
||||
[AcStringIntern(true)]
|
||||
[Key(1)]
|
||||
public string Value { get; set; } = "";
|
||||
[Key(2)]
|
||||
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Key(3)]
|
||||
public MetadataInfo_All_True? ChildMetadata { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Order Hierarchy Base Types
|
||||
|
||||
public abstract class TestOrderBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string OrderNumber { get; set; } = "";
|
||||
|
||||
[Key(2)]
|
||||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
|
||||
[Key(3)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Key(4)]
|
||||
public DateTime? PaidDateUtc { get; set; }
|
||||
|
||||
[Key(5)]
|
||||
public decimal TotalAmount { get; set; }
|
||||
|
||||
[Key(6)]
|
||||
public List<TestOrderItem_All_True> Items { get; set; } = [];
|
||||
|
||||
[Key(7)]
|
||||
public SharedTag_All_True? PrimaryTag { get; set; }
|
||||
|
||||
[Key(8)]
|
||||
public SharedTag_All_True? SecondaryTag { get; set; }
|
||||
|
||||
[Key(9)]
|
||||
public SharedUser_All_True? Owner { get; set; }
|
||||
|
||||
[Key(10)]
|
||||
public SharedCategory_All_True? Category { get; set; }
|
||||
|
||||
[Key(11)]
|
||||
public List<SharedTag_All_True> Tags { get; set; } = [];
|
||||
|
||||
[Key(12)]
|
||||
public MetadataInfo_All_True? OrderMetadata { get; set; }
|
||||
|
||||
[Key(13)]
|
||||
public MetadataInfo_All_True? AuditMetadata { get; set; }
|
||||
|
||||
[Key(14)]
|
||||
public List<MetadataInfo_All_True> MetadataList { get; set; } = [];
|
||||
|
||||
[JsonNoMergeCollection]
|
||||
[Key(15)]
|
||||
public List<TestOrderItem_All_True> NoMergeItems { get; set; } = [];
|
||||
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public object? Parent { get; set; }
|
||||
}
|
||||
|
||||
public abstract class TestOrderItemBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[AcStringIntern(true)]
|
||||
[Key(1)]
|
||||
public string ProductName { get; set; } = "";
|
||||
|
||||
[Key(2)]
|
||||
public int Quantity { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public decimal UnitPrice { get; set; }
|
||||
|
||||
[Key(4)]
|
||||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
|
||||
[Key(5)]
|
||||
public List<TestPallet_All_True> Pallets { get; set; } = [];
|
||||
|
||||
[Key(6)]
|
||||
public SharedTag_All_True? Tag { get; set; }
|
||||
|
||||
[Key(7)]
|
||||
public SharedUser_All_True? Assignee { get; set; }
|
||||
|
||||
[Key(8)]
|
||||
public MetadataInfo_All_True? ItemMetadata { get; set; }
|
||||
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestOrder_All_True? ParentOrder { get; set; }
|
||||
}
|
||||
|
||||
public abstract class TestPalletBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string PalletCode { get; set; } = "";
|
||||
|
||||
[Key(2)]
|
||||
public int TrayCount { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
|
||||
[Key(4)]
|
||||
public double Weight { get; set; }
|
||||
|
||||
[Key(5)]
|
||||
public List<TestMeasurement_All_True> Measurements { get; set; } = [];
|
||||
|
||||
[Key(6)]
|
||||
public SharedTag_All_True? Tag { get; set; }
|
||||
|
||||
[Key(7)]
|
||||
public SharedUser_All_True? Inspector { get; set; }
|
||||
|
||||
[Key(8)]
|
||||
public SharedCategory_All_True? Category { get; set; }
|
||||
|
||||
[Key(9)]
|
||||
public MetadataInfo_All_True? PalletMetadata { get; set; }
|
||||
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestOrderItem_All_True? ParentItem { get; set; }
|
||||
}
|
||||
|
||||
public abstract class TestMeasurementBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string Name { get; set; } = "";
|
||||
|
||||
[Key(2)]
|
||||
public double TotalWeight { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Key(4)]
|
||||
public List<TestMeasurementPoint_All_True> Points { get; set; } = [];
|
||||
|
||||
[Key(5)]
|
||||
public SharedTag_All_True? Tag { get; set; }
|
||||
|
||||
[Key(6)]
|
||||
public SharedUser_All_True? Operator { get; set; }
|
||||
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestPallet_All_True? ParentPallet { get; set; }
|
||||
}
|
||||
|
||||
public abstract class TestMeasurementPointBase : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string Label { get; set; } = "";
|
||||
|
||||
[Key(2)]
|
||||
public double Value { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public DateTime MeasuredAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
[Key(4)]
|
||||
public SharedTag_All_True? Tag { get; set; }
|
||||
|
||||
[Key(5)]
|
||||
public SharedUser_All_True? Verifier { get; set; }
|
||||
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestMeasurement_All_True? ParentMeasurement { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -48,208 +48,12 @@ public enum TestUserRole
|
|||
|
||||
#endregion
|
||||
|
||||
#region Shared Reference Types (IId-based for $id/$ref testing)
|
||||
|
||||
/// <summary>
|
||||
/// Shared tag/label - used across multiple entities for cross-reference testing.
|
||||
/// Implements IId<int> for semantic $id/$ref serialization.
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedTag : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Name { get; set; } = "";
|
||||
[AcStringIntern(true)]
|
||||
[Key(2)]
|
||||
public string Color { get; set; } = "#000000";
|
||||
[Key(3)]
|
||||
public int Priority { get; set; }
|
||||
[Key(4)]
|
||||
public bool IsActive { get; set; } = true;
|
||||
[Key(5)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(6)]
|
||||
public string? Description { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shared category - for hierarchical cross-reference testing.
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedCategory : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Name { get; set; } = "";
|
||||
[Key(2)]
|
||||
public string? Description { get; set; }
|
||||
[Key(3)]
|
||||
public int SortOrder { get; set; }
|
||||
[Key(4)]
|
||||
public bool IsDefault { get; set; }
|
||||
[Key(5)]
|
||||
public int? ParentCategoryId { get; set; }
|
||||
[Key(6)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(7)]
|
||||
public DateTime? UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shared user reference - appears in many places to test $ref deduplication.
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedUser : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Username { get; set; } = "";
|
||||
[Key(2)]
|
||||
public string Email { get; set; } = "";
|
||||
[Key(3)]
|
||||
public string FirstName { get; set; } = "";
|
||||
[Key(4)]
|
||||
public string LastName { get; set; } = "";
|
||||
[Key(5)]
|
||||
public bool IsActive { get; set; } = true;
|
||||
[Key(6)]
|
||||
public TestUserRole Role { get; set; } = TestUserRole.User;
|
||||
[Key(7)]
|
||||
public DateTime? LastLoginAt { get; set; }
|
||||
[Key(8)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(9)]
|
||||
public UserPreferences? Preferences { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// User preferences - non-IId nested object
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class UserPreferences
|
||||
{
|
||||
[AcStringIntern(true)]
|
||||
[Key(0)]
|
||||
public string Theme { get; set; } = "light";
|
||||
[AcStringIntern(true)]
|
||||
[Key(1)]
|
||||
public string Language { get; set; } = "en-US";
|
||||
[Key(2)]
|
||||
public bool NotificationsEnabled { get; set; } = true;
|
||||
[AcStringIntern(true)]
|
||||
[Key(3)]
|
||||
public string? EmailDigestFrequency { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Non-IId Metadata (Newtonsoft numeric $id/$ref testing)
|
||||
|
||||
/// <summary>
|
||||
/// Non-IId metadata class - uses Newtonsoft PreserveReferencesHandling (numeric $id/$ref).
|
||||
/// Does NOT implement IId, so uses standard Newtonsoft reference tracking.
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class MetadataInfo
|
||||
{
|
||||
[AcStringIntern(true)]
|
||||
[Key(0)]
|
||||
public string Key { get; set; } = "";
|
||||
[AcStringIntern(true)]
|
||||
[Key(1)]
|
||||
public string Value { get; set; } = "";
|
||||
[Key(2)]
|
||||
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
|
||||
|
||||
/// <summary>
|
||||
/// Nested metadata for deep Newtonsoft reference testing
|
||||
/// </summary>
|
||||
[Key(3)]
|
||||
public MetadataInfo? ChildMetadata { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 5-Level Test Hierarchy (Order -> Item -> Pallet -> Measurement -> Point)
|
||||
|
||||
/// <summary>
|
||||
/// Level 1: Main order - root of the hierarchy
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestOrder : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string OrderNumber { get; set; } = "";
|
||||
[Key(2)]
|
||||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
[Key(3)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
[Key(4)]
|
||||
public DateTime? PaidDateUtc { get; set; }
|
||||
[Key(5)]
|
||||
public decimal TotalAmount { get; set; }
|
||||
|
||||
// Level 2 collection
|
||||
[Key(6)]
|
||||
public List<TestOrderItem> Items { get; set; } = [];
|
||||
|
||||
// Shared reference properties (for $id/$ref testing)
|
||||
[Key(7)]
|
||||
public SharedTag? PrimaryTag { get; set; }
|
||||
[Key(8)]
|
||||
public SharedTag? SecondaryTag { get; set; }
|
||||
[Key(9)]
|
||||
public SharedUser? Owner { get; set; }
|
||||
[Key(10)]
|
||||
public SharedCategory? Category { get; set; }
|
||||
|
||||
// Collection of shared references
|
||||
[Key(11)]
|
||||
public List<SharedTag> Tags { get; set; } = [];
|
||||
|
||||
// Non-IId metadata (for Newtonsoft $ref testing)
|
||||
[Key(12)]
|
||||
public MetadataInfo? OrderMetadata { get; set; }
|
||||
[Key(13)]
|
||||
public MetadataInfo? AuditMetadata { get; set; }
|
||||
[Key(14)]
|
||||
public List<MetadataInfo> MetadataList { get; set; } = [];
|
||||
|
||||
// NoMerge collection for testing replace behavior
|
||||
[JsonNoMergeCollection]
|
||||
[Key(15)]
|
||||
public List<TestOrderItem> NoMergeItems { get; set; } = [];
|
||||
|
||||
// Parent reference - ignored by all serializers to prevent circular references
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public object? Parent { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 1: Main order - root of the hierarchy
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public partial class TestOrder_Circ_Ref : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -263,16 +67,16 @@ public partial class TestOrder_Circ_Ref : IId<int>
|
|||
public List<TestOrderItem_Circ_Ref> Items { get; set; } = [];
|
||||
|
||||
// Shared reference properties (for $id/$ref testing)
|
||||
public SharedTag? PrimaryTag { get; set; }
|
||||
public SharedTag? SecondaryTag { get; set; }
|
||||
public SharedUser? Owner { get; set; }
|
||||
public SharedCategory? Category { get; set; }
|
||||
|
||||
public SharedTag_All_True? PrimaryTag { get; set; }
|
||||
public SharedTag_All_True? SecondaryTag { get; set; }
|
||||
public SharedUser_All_True? Owner { get; set; }
|
||||
public SharedCategory_All_True? Category { get; set; }
|
||||
|
||||
// Collection of shared references
|
||||
public List<SharedTag> Tags { get; set; } = [];
|
||||
public MetadataInfo? OrderMetadata { get; set; }
|
||||
public MetadataInfo? AuditMetadata { get; set; }
|
||||
public List<MetadataInfo> MetadataList { get; set; } = [];
|
||||
public List<SharedTag_All_True> Tags { get; set; } = [];
|
||||
public MetadataInfo_All_True? OrderMetadata { get; set; }
|
||||
public MetadataInfo_All_True? AuditMetadata { get; set; }
|
||||
public List<MetadataInfo_All_True> MetadataList { get; set; } = [];
|
||||
|
||||
// NoMerge collection for testing replace behavior
|
||||
[JsonNoMergeCollection]
|
||||
|
|
@ -283,47 +87,7 @@ public partial class TestOrder_Circ_Ref : IId<int>
|
|||
/// <summary>
|
||||
/// Level 2: Order item with pallets
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestOrderItem : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[AcStringIntern(true)]
|
||||
[Key(1)]
|
||||
public string ProductName { get; set; } = "";
|
||||
[Key(2)]
|
||||
public int Quantity { get; set; }
|
||||
[Key(3)]
|
||||
public decimal UnitPrice { get; set; }
|
||||
[Key(4)]
|
||||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
|
||||
// Level 3 collection
|
||||
[Key(5)]
|
||||
public List<TestPallet> Pallets { get; set; } = [];
|
||||
|
||||
// Shared references
|
||||
[Key(6)]
|
||||
public SharedTag? Tag { get; set; }
|
||||
[Key(7)]
|
||||
public SharedUser? Assignee { get; set; }
|
||||
[Key(8)]
|
||||
public MetadataInfo? ItemMetadata { get; set; }
|
||||
|
||||
// Parent reference - ignored by all serializers to prevent circular references
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestOrder? ParentOrder { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 2: Order item with pallets
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public partial class TestOrderItem_Circ_Ref : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -334,124 +98,15 @@ public partial class TestOrderItem_Circ_Ref : IId<int>
|
|||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
|
||||
// Level 3 collection
|
||||
public List<TestPallet> Pallets { get; set; } = [];
|
||||
public List<TestPallet_All_True> Pallets { get; set; } = [];
|
||||
|
||||
// Shared references
|
||||
public SharedTag? Tag { get; set; }
|
||||
public SharedUser? Assignee { get; set; }
|
||||
public MetadataInfo? ItemMetadata { get; set; }
|
||||
public SharedTag_All_True? Tag { get; set; }
|
||||
public SharedUser_All_True? Assignee { get; set; }
|
||||
public MetadataInfo_All_True? ItemMetadata { get; set; }
|
||||
|
||||
public TestOrder_Circ_Ref? ParentOrder { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Level 3: Pallet containing measurements
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestPallet : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string PalletCode { get; set; } = "";
|
||||
[Key(2)]
|
||||
public int TrayCount { get; set; }
|
||||
[Key(3)]
|
||||
public TestStatus Status { get; set; } = TestStatus.Pending;
|
||||
[Key(4)]
|
||||
public double Weight { get; set; }
|
||||
|
||||
// Level 4 collection
|
||||
[Key(5)]
|
||||
public List<TestMeasurement> Measurements { get; set; } = [];
|
||||
|
||||
// Shared IId references for better reference testing
|
||||
[Key(6)]
|
||||
public SharedTag? Tag { get; set; }
|
||||
[Key(7)]
|
||||
public SharedUser? Inspector { get; set; }
|
||||
[Key(8)]
|
||||
public SharedCategory? Category { get; set; }
|
||||
|
||||
// Non-IId shared references
|
||||
[Key(9)]
|
||||
public MetadataInfo? PalletMetadata { get; set; }
|
||||
|
||||
// Parent reference - ignored by all serializers to prevent circular references
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestOrderItem? ParentItem { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 4: Measurement with multiple points
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestMeasurement : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Name { get; set; } = "";
|
||||
[Key(2)]
|
||||
public double TotalWeight { get; set; }
|
||||
[Key(3)]
|
||||
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Level 5 collection
|
||||
[Key(4)]
|
||||
public List<TestMeasurementPoint> Points { get; set; } = [];
|
||||
|
||||
// Shared IId references for better reference testing
|
||||
[Key(5)]
|
||||
public SharedTag? Tag { get; set; }
|
||||
[Key(6)]
|
||||
public SharedUser? Operator { get; set; }
|
||||
|
||||
// Parent reference - ignored by all serializers to prevent circular references
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestPallet? ParentPallet { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 5: Deepest level - measurement point
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestMeasurementPoint : IId<int>
|
||||
{
|
||||
[Key(0)]
|
||||
public int Id { get; set; }
|
||||
[Key(1)]
|
||||
public string Label { get; set; } = "";
|
||||
[Key(2)]
|
||||
public double Value { get; set; }
|
||||
[Key(3)]
|
||||
public DateTime MeasuredAt { get; set; } = DateTime.UtcNow;
|
||||
|
||||
// Shared IId reference for better reference testing (many points share same tag/user)
|
||||
[Key(4)]
|
||||
public SharedTag? Tag { get; set; }
|
||||
[Key(5)]
|
||||
public SharedUser? Verifier { get; set; }
|
||||
|
||||
// Parent reference - ignored by all serializers to prevent circular references
|
||||
[MemoryPackIgnore]
|
||||
[JsonIgnore]
|
||||
[IgnoreMember]
|
||||
[BsonIgnore]
|
||||
public TestMeasurement? ParentMeasurement { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Guid-based IId types
|
||||
|
|
@ -459,7 +114,7 @@ public partial class TestMeasurementPoint : IId<int>
|
|||
/// <summary>
|
||||
/// Order with Guid Id - for testing Guid-based IId
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class TestGuidOrder : IId<Guid>
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
|
@ -471,7 +126,7 @@ public class TestGuidOrder : IId<Guid>
|
|||
/// <summary>
|
||||
/// Item with Guid Id
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class TestGuidItem : IId<Guid>
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
|
|
@ -487,7 +142,7 @@ public class TestGuidItem : IId<Guid>
|
|||
/// Simulates NopCommerce GenericAttribute - stores key-value pairs where DateTime values
|
||||
/// are stored as strings in the database.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class TestGenericAttribute
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -499,7 +154,7 @@ public class TestGenericAttribute
|
|||
/// DTO with GenericAttributes collection - simulates OrderDto with string-stored DateTime values.
|
||||
/// This reproduces the production bug where Binary serialization was thought to corrupt DateTime strings.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class TestDtoWithGenericAttributes : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -510,12 +165,12 @@ public class TestDtoWithGenericAttributes : IId<int>
|
|||
/// <summary>
|
||||
/// Order with nullable collections for null vs empty testing
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class TestOrderWithNullableCollections
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string OrderNumber { get; set; } = "";
|
||||
public List<TestOrderItem>? Items { get; set; }
|
||||
public List<TestOrderItem_All_True>? Items { get; set; }
|
||||
public List<string>? Tags { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -523,7 +178,7 @@ public class TestOrderWithNullableCollections
|
|||
/// Class with all primitive types for WASM/serialization testing
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public partial class PrimitiveTestClass
|
||||
{
|
||||
public int IntValue { get; set; }
|
||||
|
|
@ -546,7 +201,7 @@ public partial class PrimitiveTestClass
|
|||
/// Class with extended primitive types for full serializer coverage.
|
||||
/// Includes DateTimeOffset, TimeSpan, Dictionary, null properties.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class ExtendedPrimitiveTestClass
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -567,16 +222,16 @@ public class ExtendedPrimitiveTestClass
|
|||
|
||||
// Nullable properties that will be null
|
||||
public string? NullString { get; set; }
|
||||
public TestOrderItem? NullObject { get; set; }
|
||||
public TestOrderItem_All_True? NullObject { get; set; }
|
||||
|
||||
// Nested object for complex serialization
|
||||
public SharedTag? Tag { get; set; }
|
||||
public SharedTag_All_True? Tag { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class with array of objects containing null items for WriteNull coverage
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class ObjectWithNullItems
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -591,7 +246,7 @@ public class ObjectWithNullItems
|
|||
/// "Server-side" DTO with extra properties that the "client" doesn't know about.
|
||||
/// Used to test SkipValue functionality when deserializing unknown properties.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class ServerCustomerDto : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -624,7 +279,7 @@ public class ServerCustomerDto : IId<int>
|
|||
/// the deserializer must skip unknown properties correctly
|
||||
/// while still maintaining string intern table consistency.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class ClientCustomerDto : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -638,7 +293,7 @@ public class ClientCustomerDto : IId<int>
|
|||
/// Server DTO with nested objects that client doesn't know about.
|
||||
/// Tests skipping complex nested structures.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class ServerOrderWithExtras : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
@ -659,7 +314,7 @@ public class ServerOrderWithExtras : IId<int>
|
|||
/// <summary>
|
||||
/// Client version of the order - doesn't have Customer/RelatedCustomers properties.
|
||||
/// </summary>
|
||||
[AcBinarySerializable(false)]
|
||||
[AcBinarySerializable(true)]
|
||||
public class ClientOrderSimple : IId<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
using AyCode.Core.Extensions;
|
||||
using AyCode.Core.Serializers.Attributes;
|
||||
using AyCode.Core.Serializers.Binaries;
|
||||
using MemoryPack;
|
||||
using MessagePack;
|
||||
|
||||
namespace AyCode.Core.Tests.TestModels;
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedTag_All_True : SharedTagBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedTag_All_False : SharedTagBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedCategory_All_True : SharedCategoryBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedCategory_All_False : SharedCategoryBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedUser_All_True : SharedUserBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class SharedUser_All_False : SharedUserBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class UserPreferences_All_True : UserPreferencesBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class UserPreferences_All_False : UserPreferencesBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class MetadataInfo_All_True : MetadataInfoBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class MetadataInfo_All_False : MetadataInfoBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 1: Main order - root of the hierarchy
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class TestOrder_All_True : TestOrderBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestOrder_All_False : TestOrderBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 2: Order item with pallets
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class TestOrderItem_All_True : TestOrderItemBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestOrderItem_All_False : TestOrderItemBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 3: Pallet containing measurements
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class TestPallet_All_True : TestPalletBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestPallet_All_False : TestPalletBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 4: Measurement with multiple points
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class TestMeasurement_All_True : TestMeasurementBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestMeasurement_All_False : TestMeasurementBase
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Level 5: Deepest level - measurement point
|
||||
/// </summary>
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(true)]
|
||||
[MessagePackObject]
|
||||
public partial class TestMeasurementPoint_All_True : TestMeasurementPointBase
|
||||
{
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
[AcBinarySerializable(false)]
|
||||
[MessagePackObject]
|
||||
public partial class TestMeasurementPoint_All_False : TestMeasurementPointBase
|
||||
{
|
||||
}
|
||||
|
|
@ -236,8 +236,8 @@ public class SignalRBenchmarkData
|
|||
public byte[] MixedParamsMessage { get; }
|
||||
|
||||
// Test data
|
||||
public TestOrderItem TestOrderItem { get; }
|
||||
public TestOrder TestOrder { get; }
|
||||
public TestOrderItem_All_True TestOrderItem { get; }
|
||||
public TestOrder_All_True TestOrder { get; }
|
||||
public int[] IntArray { get; }
|
||||
public Guid TestGuid { get; }
|
||||
|
||||
|
|
@ -246,7 +246,7 @@ public class SignalRBenchmarkData
|
|||
// Create test data
|
||||
TestGuid = Guid.NewGuid();
|
||||
IntArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
TestOrderItem = new TestOrderItem
|
||||
TestOrderItem = new TestOrderItem_All_True
|
||||
{
|
||||
Id = 42,
|
||||
ProductName = "Benchmark Product",
|
||||
|
|
|
|||
|
|
@ -27,10 +27,10 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create a shared tag for cross-reference testing
|
||||
/// </summary>
|
||||
public static SharedTag CreateTag(string? name = null, string? color = null)
|
||||
public static SharedTag_All_True CreateTag(string? name = null, string? color = null)
|
||||
{
|
||||
var id = _idCounter++;
|
||||
return new SharedTag
|
||||
return new SharedTag_All_True
|
||||
{
|
||||
Id = id,
|
||||
Name = name ?? $"Címke-{id}",
|
||||
|
|
@ -45,10 +45,10 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create a shared category
|
||||
/// </summary>
|
||||
public static SharedCategory CreateCategory(string? name = null, int? parentId = null)
|
||||
public static SharedCategory_All_True CreateCategory(string? name = null, int? parentId = null)
|
||||
{
|
||||
var id = _idCounter++;
|
||||
return new SharedCategory
|
||||
return new SharedCategory_All_True
|
||||
{
|
||||
Id = id,
|
||||
Name = name ?? $"Kategória-{id}",
|
||||
|
|
@ -64,10 +64,10 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create a shared user for cross-reference testing
|
||||
/// </summary>
|
||||
public static SharedUser CreateUser(string? username = null, TestUserRole role = TestUserRole.User)
|
||||
public static SharedUser_All_True CreateUser(string? username = null, TestUserRole role = TestUserRole.User)
|
||||
{
|
||||
var id = _idCounter++;
|
||||
return new SharedUser
|
||||
return new SharedUser_All_True
|
||||
{
|
||||
Id = id,
|
||||
Username = username ?? $"felhasználó{id}",
|
||||
|
|
@ -78,7 +78,7 @@ public static class TestDataFactory
|
|||
Role = role,
|
||||
LastLoginAt = DateTime.UtcNow.AddHours(-id),
|
||||
CreatedAt = DateTime.UtcNow.AddYears(-1),
|
||||
Preferences = new UserPreferences
|
||||
Preferences = new UserPreferences_All_True
|
||||
{
|
||||
Theme = id % 2 == 0 ? "sötét" : "világos",
|
||||
Language = "magyar",
|
||||
|
|
@ -91,10 +91,10 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create metadata info (non-IId)
|
||||
/// </summary>
|
||||
public static MetadataInfo CreateMetadata(string? key = null, bool withChild = false)
|
||||
public static MetadataInfo_All_True CreateMetadata(string? key = null, bool withChild = false)
|
||||
{
|
||||
var id = _idCounter++;
|
||||
return new MetadataInfo
|
||||
return new MetadataInfo_All_True
|
||||
{
|
||||
Key = key ?? $"Metaadat-{id}",
|
||||
Value = $"MetaÉrték-{id}",
|
||||
|
|
@ -109,23 +109,23 @@ public static class TestDataFactory
|
|||
|
||||
/// <summary>
|
||||
/// Create a deep order hierarchy with configurable depth.
|
||||
/// Supports both IId-based (SharedTag, SharedUser, SharedCategory) and Non-IId (UserPreferences) shared references.
|
||||
/// Supports both IId-based (SharedTag_All_True, SharedUser, SharedCategory_All_True) and Non-IId (UserPreferences_All_True) shared references.
|
||||
/// </summary>
|
||||
public static TestOrder CreateOrder(
|
||||
public static TestOrder_All_True CreateOrder(
|
||||
int itemCount = 2,
|
||||
int palletsPerItem = 2,
|
||||
int measurementsPerPallet = 2,
|
||||
int pointsPerMeasurement = 3,
|
||||
SharedTag? sharedTag = null,
|
||||
SharedUser? sharedUser = null,
|
||||
MetadataInfo? sharedMetadata = null,
|
||||
UserPreferences? sharedPreferences = null,
|
||||
SharedCategory? sharedCategory = null)
|
||||
SharedTag_All_True? sharedTag = null,
|
||||
SharedUser_All_True? sharedUser = null,
|
||||
MetadataInfo_All_True? sharedMetadata = null,
|
||||
UserPreferences_All_True? sharedPreferences = null,
|
||||
SharedCategory_All_True? sharedCategory = null)
|
||||
{
|
||||
// If sharedUser is provided but no sharedPreferences, use the user's preferences as shared
|
||||
sharedPreferences ??= sharedUser?.Preferences;
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
OrderNumber = $"Megrendelés-{_idCounter:D4}",
|
||||
|
|
@ -167,18 +167,18 @@ public static class TestDataFactory
|
|||
/// Create an order item with pallets.
|
||||
/// Supports both IId-based and Non-IId shared references.
|
||||
/// </summary>
|
||||
public static TestOrderItem CreateOrderItem(
|
||||
public static TestOrderItem_All_True CreateOrderItem(
|
||||
int palletCount = 2,
|
||||
int measurementsPerPallet = 2,
|
||||
int pointsPerMeasurement = 3,
|
||||
SharedTag? sharedTag = null,
|
||||
SharedUser? sharedUser = null,
|
||||
MetadataInfo? sharedMetadata = null,
|
||||
UserPreferences? sharedPreferences = null,
|
||||
SharedCategory? sharedCategory = null)
|
||||
SharedTag_All_True? sharedTag = null,
|
||||
SharedUser_All_True? sharedUser = null,
|
||||
MetadataInfo_All_True? sharedMetadata = null,
|
||||
UserPreferences_All_True? sharedPreferences = null,
|
||||
SharedCategory_All_True? sharedCategory = null)
|
||||
{
|
||||
// Create assignee - if sharedUser provided, use it. Otherwise create new user with sharedPreferences
|
||||
SharedUser? assignee = sharedUser;
|
||||
SharedUser_All_True? assignee = sharedUser;
|
||||
if (assignee == null && sharedPreferences != null)
|
||||
{
|
||||
// Create a new user but with shared preferences (Non-IId ref testing)
|
||||
|
|
@ -186,7 +186,7 @@ public static class TestDataFactory
|
|||
assignee.Preferences = sharedPreferences;
|
||||
}
|
||||
|
||||
var item = new TestOrderItem
|
||||
var item = new TestOrderItem_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
ProductName = $"Termék-{_idCounter}",
|
||||
|
|
@ -221,15 +221,15 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create a pallet with measurements
|
||||
/// </summary>
|
||||
public static TestPallet CreatePallet(
|
||||
public static TestPallet_All_True CreatePallet(
|
||||
int measurementCount = 2,
|
||||
int pointsPerMeasurement = 3,
|
||||
MetadataInfo? sharedMetadata = null,
|
||||
SharedTag? sharedTag = null,
|
||||
SharedUser? sharedInspector = null,
|
||||
SharedCategory? sharedCategory = null)
|
||||
MetadataInfo_All_True? sharedMetadata = null,
|
||||
SharedTag_All_True? sharedTag = null,
|
||||
SharedUser_All_True? sharedInspector = null,
|
||||
SharedCategory_All_True? sharedCategory = null)
|
||||
{
|
||||
var pallet = new TestPallet
|
||||
var pallet = new TestPallet_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
PalletCode = $"Raklapkód-{_idCounter:D4}",
|
||||
|
|
@ -255,12 +255,12 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create a measurement with points
|
||||
/// </summary>
|
||||
public static TestMeasurement CreateMeasurement(
|
||||
public static TestMeasurement_All_True CreateMeasurement(
|
||||
int pointCount = 3,
|
||||
SharedTag? sharedTag = null,
|
||||
SharedUser? sharedOperator = null)
|
||||
SharedTag_All_True? sharedTag = null,
|
||||
SharedUser_All_True? sharedOperator = null)
|
||||
{
|
||||
var measurement = new TestMeasurement
|
||||
var measurement = new TestMeasurement_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
Name = $"Mérés-{_idCounter}",
|
||||
|
|
@ -283,12 +283,12 @@ public static class TestDataFactory
|
|||
/// <summary>
|
||||
/// Create a measurement point
|
||||
/// </summary>
|
||||
public static TestMeasurementPoint CreateMeasurementPoint(
|
||||
SharedTag? sharedTag = null,
|
||||
SharedUser? sharedVerifier = null)
|
||||
public static TestMeasurementPoint_All_True CreateMeasurementPoint(
|
||||
SharedTag_All_True? sharedTag = null,
|
||||
SharedUser_All_True? sharedVerifier = null)
|
||||
{
|
||||
var id = _idCounter++;
|
||||
return new TestMeasurementPoint
|
||||
return new TestMeasurementPoint_All_True
|
||||
{
|
||||
Id = id,
|
||||
Label = $"MérőPont-{id}",
|
||||
|
|
@ -307,7 +307,7 @@ public static class TestDataFactory
|
|||
/// Create a large graph for benchmarking with many cross-references.
|
||||
/// Creates approximately (itemCount * palletsPerItem * measurementsPerPallet * pointsPerMeasurement) objects.
|
||||
/// </summary>
|
||||
public static TestOrder CreateBenchmarkOrder(
|
||||
public static TestOrder_All_True CreateBenchmarkOrder(
|
||||
int itemCount = 5,
|
||||
int palletsPerItem = 4,
|
||||
int measurementsPerPallet = 3,
|
||||
|
|
@ -320,7 +320,7 @@ public static class TestDataFactory
|
|||
var sharedUser = CreateUser("mérőfelhasználó", TestUserRole.Admin);
|
||||
var sharedMetadata = CreateMetadata("mérőteszt", withChild: true);
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
OrderNumber = $"MÉRŐTESZT-{_idCounter:D6}",
|
||||
|
|
@ -338,7 +338,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
var item = new TestOrderItem
|
||||
var item = new TestOrderItem_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
ProductName = $"MérőTermék-{i}",
|
||||
|
|
@ -353,7 +353,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int p = 0; p < palletsPerItem; p++)
|
||||
{
|
||||
var pallet = new TestPallet
|
||||
var pallet = new TestPallet_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
PalletCode = $"Raklapkód-{i}-{p}",
|
||||
|
|
@ -366,7 +366,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int m = 0; m < measurementsPerPallet; m++)
|
||||
{
|
||||
var measurement = new TestMeasurement
|
||||
var measurement = new TestMeasurement_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
Name = $"Mérés-{i}-{p}-{m}",
|
||||
|
|
@ -377,7 +377,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int pt = 0; pt < pointsPerMeasurement; pt++)
|
||||
{
|
||||
var point = new TestMeasurementPoint
|
||||
var point = new TestMeasurementPoint_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
Label = $"MérőPnt-{i}-{p}-{m}-{pt}",
|
||||
|
|
@ -405,8 +405,8 @@ public static class TestDataFactory
|
|||
/// <param name="palletsPerItem">Pallets per item</param>
|
||||
/// <param name="measurementsPerPallet">Measurements per pallet</param>
|
||||
/// <param name="pointsPerMeasurement">Points per measurement</param>
|
||||
/// <returns>Large TestOrder with many IId references</returns>
|
||||
public static TestOrder CreateLargeScaleBenchmarkOrder(
|
||||
/// <returns>Large TestOrder_All_True with many IId references</returns>
|
||||
public static TestOrder_All_True CreateLargeScaleBenchmarkOrder(
|
||||
int rootItemCount = 500,
|
||||
int palletsPerItem = 3,
|
||||
int measurementsPerPallet = 3,
|
||||
|
|
@ -420,7 +420,7 @@ public static class TestDataFactory
|
|||
var sharedMetadata = CreateMetadata("nagy-méretű", withChild: true);
|
||||
var sharedCategories = Enumerable.Range(1, 10).Select(i => CreateCategory($"Kategória-{i}")).ToList();
|
||||
|
||||
var order = new TestOrder
|
||||
var order = new TestOrder_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
OrderNumber = $"NAGYMÉRET-{_idCounter:D8}",
|
||||
|
|
@ -438,7 +438,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int i = 0; i < rootItemCount; i++)
|
||||
{
|
||||
var item = new TestOrderItem
|
||||
var item = new TestOrderItem_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
ProductName = $"Termék-{i}",
|
||||
|
|
@ -453,7 +453,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int p = 0; p < palletsPerItem; p++)
|
||||
{
|
||||
var pallet = new TestPallet
|
||||
var pallet = new TestPallet_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
PalletCode = $"Raklapkód-{i}-{p}",
|
||||
|
|
@ -466,7 +466,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int m = 0; m < measurementsPerPallet; m++)
|
||||
{
|
||||
var measurement = new TestMeasurement
|
||||
var measurement = new TestMeasurement_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
Name = $"Mérés-{i}-{p}-{m}",
|
||||
|
|
@ -477,7 +477,7 @@ public static class TestDataFactory
|
|||
|
||||
for (int pt = 0; pt < pointsPerMeasurement; pt++)
|
||||
{
|
||||
var point = new TestMeasurementPoint
|
||||
var point = new TestMeasurementPoint_All_True
|
||||
{
|
||||
Id = _idCounter++,
|
||||
Label = $"MérőPnt-{i}-{p}-{m}-{pt}",
|
||||
|
|
|
|||
|
|
@ -37,13 +37,13 @@ public class InvokeMethodExtensionTests
|
|||
{
|
||||
var service = new TestSignalRService2();
|
||||
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleAsyncTestOrderItem")!;
|
||||
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
|
||||
var result = methodInfo.InvokeMethod(service, input);
|
||||
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
|
||||
var item = (TestOrderItem)result;
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem_All_True> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
|
||||
var item = (TestOrderItem_All_True)result;
|
||||
Assert.AreEqual("Async: Widget", item.ProductName);
|
||||
Assert.AreEqual(15, item.Quantity);
|
||||
}
|
||||
|
|
@ -81,13 +81,13 @@ public class InvokeMethodExtensionTests
|
|||
{
|
||||
var service = new TestSignalRService2();
|
||||
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleTaskFromResultTestOrderItem")!;
|
||||
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
|
||||
var result = methodInfo.InvokeMethod(service, input);
|
||||
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
|
||||
var item = (TestOrderItem)result;
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem_All_True> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
|
||||
var item = (TestOrderItem_All_True)result;
|
||||
Assert.AreEqual("FromResult: Widget", item.ProductName);
|
||||
Assert.AreEqual(10, item.Quantity); // Doubled
|
||||
}
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Post_TestOrderItem_ReturnsProcessedItem()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
|
||||
|
||||
var result = await _client.PostDataAsync(TestSignalRTags.TestOrderItemParam, item);
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
{
|
||||
var order = TestDataFactory.CreateOrder(itemCount: 2);
|
||||
|
||||
var result = await _client.PostDataAsync<TestOrder, TestOrder>(TestSignalRTags.TestOrderParam, order);
|
||||
var result = await _client.PostDataAsync<TestOrder_All_True, TestOrder_All_True>(TestSignalRTags.TestOrderParam, order);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(order.Id, result.Id);
|
||||
|
|
@ -192,9 +192,9 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Post_SharedTag_ReturnsSameTag()
|
||||
{
|
||||
var tag = new SharedTag { Id = 1, Name = "Important", Color = "#FF0000" };
|
||||
var tag = new SharedTag_All_True { Id = 1, Name = "Important", Color = "#FF0000" };
|
||||
|
||||
var result = await _client.PostDataAsync<SharedTag, SharedTag>(TestSignalRTags.SharedTagParam, tag);
|
||||
var result = await _client.PostDataAsync<SharedTag_All_True, SharedTag_All_True>(TestSignalRTags.SharedTagParam, tag);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(1, result.Id);
|
||||
|
|
@ -242,13 +242,13 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Post_TestOrderItemList_ReturnsSameItems()
|
||||
{
|
||||
var items = new List<TestOrderItem>
|
||||
var items = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Item1" },
|
||||
new() { Id = 2, ProductName = "Item2" }
|
||||
};
|
||||
|
||||
var result = await _client.PostDataAsync<List<TestOrderItem>, List<TestOrderItem>>(TestSignalRTags.TestOrderItemListParam, items);
|
||||
var result = await _client.PostDataAsync<List<TestOrderItem_All_True>, List<TestOrderItem_All_True>>(TestSignalRTags.TestOrderItemListParam, items);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(2, result.Count);
|
||||
|
|
@ -399,11 +399,11 @@ public abstract class SignalRClientToHubTestBase
|
|||
{
|
||||
var input = new[]
|
||||
{
|
||||
new SharedTag { Id = 1, Name = "Tag1", Color = "#FF0000" },
|
||||
new SharedTag { Id = 2, Name = "Tag2", Color = "#00FF00" }
|
||||
new SharedTag_All_True { Id = 1, Name = "Tag1", Color = "#FF0000" },
|
||||
new SharedTag_All_True { Id = 2, Name = "Tag2", Color = "#00FF00" }
|
||||
};
|
||||
|
||||
var result = await _client.PostDataAsync<SharedTag[], SharedTag[]>(TestSignalRTags.SharedTagArrayParam, input);
|
||||
var result = await _client.PostDataAsync<SharedTag_All_True[], SharedTag_All_True[]>(TestSignalRTags.SharedTagArrayParam, input);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(2, result.Length);
|
||||
|
|
@ -437,7 +437,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Post_IntAndDto_ReturnsFormattedString()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Widget" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Widget" };
|
||||
|
||||
var result = await _client.PostAsync<string>(TestSignalRTags.IntAndDtoParam, [42, item]);
|
||||
|
||||
|
|
@ -447,7 +447,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Post_DtoAndList_ReturnsFormattedString()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Product" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Product" };
|
||||
var numbers = new List<int> { 1, 2, 3 };
|
||||
|
||||
var result = await _client.PostAsync<string>(TestSignalRTags.DtoAndListParam, [item, numbers]);
|
||||
|
|
@ -458,9 +458,9 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Post_ThreeComplexParams_ReturnsFormattedString()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Item" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Item" };
|
||||
var tags = new List<string> { "tag1", "tag2", "tag3" };
|
||||
var sharedTag = new SharedTag { Id = 1, Name = "Shared" };
|
||||
var sharedTag = new SharedTag_All_True { Id = 1, Name = "Shared" };
|
||||
|
||||
var result = await _client.PostAsync<string>(TestSignalRTags.ThreeComplexParams, [item, tags, sharedTag]);
|
||||
|
||||
|
|
@ -509,7 +509,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Async_TestOrderItem_ReturnsProcessedItem()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
|
||||
|
||||
var result = await _client.PostDataAsync(TestSignalRTags.AsyncTestOrderItemParam, item);
|
||||
|
||||
|
|
@ -553,7 +553,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task RoundTrip_ComplexObject_PreservesAllProperties()
|
||||
{
|
||||
var item = new TestOrderItem
|
||||
var item = new TestOrderItem_All_True
|
||||
{
|
||||
Id = 999,
|
||||
ProductName = "RoundTrip Test Item",
|
||||
|
|
@ -576,7 +576,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
{
|
||||
var order = TestDataFactory.CreateOrder(itemCount: 3, palletsPerItem: 2, measurementsPerPallet: 1);
|
||||
|
||||
var result = await _client.PostDataAsync<TestOrder, TestOrder>(TestSignalRTags.TestOrderParam, order);
|
||||
var result = await _client.PostDataAsync<TestOrder_All_True, TestOrder_All_True>(TestSignalRTags.TestOrderParam, order);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
Assert.AreEqual(order.Id, result.Id);
|
||||
|
|
@ -646,7 +646,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task ResponseData_NotDoubleEscaped()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 20m };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 20m };
|
||||
|
||||
var result = await _client.PostDataAsync(TestSignalRTags.TestOrderItemParam, item);
|
||||
|
||||
|
|
@ -660,14 +660,14 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task CollectionResponse_DeserializesCorrectly()
|
||||
{
|
||||
var items = new List<TestOrderItem>
|
||||
var items = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Item1", Quantity = 10, UnitPrice = 1.1m },
|
||||
new() { Id = 2, ProductName = "Item2", Quantity = 20, UnitPrice = 2.2m },
|
||||
new() { Id = 3, ProductName = "Item3", Quantity = 30, UnitPrice = 3.3m }
|
||||
};
|
||||
|
||||
var result = await _client.PostDataAsync<List<TestOrderItem>, List<TestOrderItem>>(
|
||||
var result = await _client.PostDataAsync<List<TestOrderItem_All_True>, List<TestOrderItem_All_True>>(
|
||||
TestSignalRTags.TestOrderItemListParam, items);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
|
@ -683,7 +683,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task Async_Method_ReturnsActualResult_NotTaskWrapper()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
|
||||
var item = new TestOrderItem_All_True { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
|
||||
|
||||
var result = await _client.PostDataAsync(TestSignalRTags.AsyncTestOrderItemParam, item);
|
||||
|
||||
|
|
@ -712,7 +712,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
[TestMethod]
|
||||
public async Task TaskFromResult_ComplexObject_ReturnsActualResult_NotTaskWrapper()
|
||||
{
|
||||
var item = new TestOrderItem { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
|
||||
var item = new TestOrderItem_All_True { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
|
||||
|
||||
var result = await _client.PostDataAsync(TestSignalRTags.TaskFromResultTestOrderItemParam, item);
|
||||
|
||||
|
|
@ -769,13 +769,13 @@ public abstract class SignalRClientToHubTestBase
|
|||
{
|
||||
var service = new TestSignalRService2();
|
||||
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleAsyncTestOrderItem")!;
|
||||
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
|
||||
var result = methodInfo.InvokeMethod(service, input);
|
||||
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
|
||||
var item = (TestOrderItem)result;
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem_All_True> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
|
||||
var item = (TestOrderItem_All_True)result;
|
||||
Assert.AreEqual("Async: Widget", item.ProductName);
|
||||
Assert.AreEqual(15, item.Quantity);
|
||||
}
|
||||
|
|
@ -809,13 +809,13 @@ public abstract class SignalRClientToHubTestBase
|
|||
{
|
||||
var service = new TestSignalRService2();
|
||||
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleTaskFromResultTestOrderItem")!;
|
||||
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
|
||||
|
||||
var result = methodInfo.InvokeMethod(service, input);
|
||||
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
|
||||
var item = (TestOrderItem)result;
|
||||
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem_All_True> and return the result");
|
||||
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
|
||||
var item = (TestOrderItem_All_True)result;
|
||||
Assert.AreEqual("FromResult: Widget", item.ProductName);
|
||||
Assert.AreEqual(10, item.Quantity);
|
||||
}
|
||||
|
|
@ -1056,7 +1056,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
var dataSets = BenchmarkTestDataProvider.CreateTestDataSets(resetId: false);
|
||||
var orders = dataSets.Select(ds => ds.Order).ToList();
|
||||
|
||||
var result = await _client.PostDataAsync<List<TestOrder>, List<TestOrder>>(
|
||||
var result = await _client.PostDataAsync<List<TestOrder_All_True>, List<TestOrder_All_True>>(
|
||||
TestSignalRTags.TestOrderListParam, orders);
|
||||
|
||||
Assert.IsNotNull(result);
|
||||
|
|
@ -1077,7 +1077,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
public async Task RoundTrip_VeryLargeOrderList_250KB_PreservesAllData()
|
||||
{
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var orders = new List<TestOrder>();
|
||||
var orders = new List<TestOrder_All_True>();
|
||||
for (var i = 0; i < 100; i++)
|
||||
{
|
||||
var tag = TestDataFactory.CreateTag($"Tag_{i}");
|
||||
|
|
@ -1091,7 +1091,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
sharedUser: user));
|
||||
}
|
||||
|
||||
var result = await _client.PostDataAsync<List<TestOrder>, List<TestOrder>>(
|
||||
var result = await _client.PostDataAsync<List<TestOrder_All_True>, List<TestOrder_All_True>>(
|
||||
TestSignalRTags.TestOrderListParam, orders);
|
||||
|
||||
Assert.IsNotNull(result, "Deserialization returned null — likely BWO GetTotalPosition drift on large payload");
|
||||
|
|
@ -1131,7 +1131,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
};
|
||||
|
||||
TestDataFactory.ResetIdCounter();
|
||||
var orders = new List<TestOrder>();
|
||||
var orders = new List<TestOrder_All_True>();
|
||||
for (var i = 0; i < 80; i++)
|
||||
{
|
||||
var tag = TestDataFactory.CreateTag($"Cég_{i}_{hungarianNames[i % hungarianNames.Length]}");
|
||||
|
|
@ -1159,7 +1159,7 @@ public abstract class SignalRClientToHubTestBase
|
|||
orders.Add(order);
|
||||
}
|
||||
|
||||
var result = await _client.PostDataAsync<List<TestOrder>, List<TestOrder>>(
|
||||
var result = await _client.PostDataAsync<List<TestOrder_All_True>, List<TestOrder_All_True>>(
|
||||
TestSignalRTags.TestOrderListParam, orders);
|
||||
|
||||
Assert.IsNotNull(result,
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2" });
|
||||
dataSource.Clear();
|
||||
|
||||
Assert.AreEqual(0, dataSource.Count);
|
||||
|
|
@ -35,7 +35,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Clear(clearChangeTracking: false);
|
||||
|
||||
Assert.AreEqual(0, dataSource.Count);
|
||||
|
|
@ -55,7 +55,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual void Contains_ReturnsFalse_WhenItemNotExists()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
Assert.IsFalse(dataSource.Contains(new TestOrderItem { Id = 9999 }));
|
||||
Assert.IsFalse(dataSource.Contains(new TestOrderItem_All_True { Id = 9999 }));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
|
@ -74,7 +74,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 5, ProductName = "Item5" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 5, ProductName = "Item5" });
|
||||
Assert.AreEqual(0, dataSource.IndexOf(5));
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 10, ProductName = "Test" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 10, ProductName = "Test" });
|
||||
var result = dataSource.TryGetIndex(10, out var index);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
|
|
@ -119,7 +119,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
await dataSource.LoadDataSource();
|
||||
var array = new TestOrderItem[3];
|
||||
var array = new TestOrderItem_All_True[3];
|
||||
dataSource.CopyTo(array);
|
||||
|
||||
Assert.AreEqual("Product A", array[0].ProductName);
|
||||
|
|
@ -147,7 +147,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var readOnly = dataSource.AsReadOnly();
|
||||
|
||||
Assert.AreEqual(3, readOnly.Count);
|
||||
Assert.IsInstanceOfType(readOnly, typeof(System.Collections.ObjectModel.ReadOnlyCollection<TestOrderItem>));
|
||||
Assert.IsInstanceOfType(readOnly, typeof(System.Collections.ObjectModel.ReadOnlyCollection<TestOrderItem_All_True>));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
@ -217,7 +217,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual void IList_Add_ReturnsCorrectIndex()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
|
||||
var index = ((IList)dataSource).Add(item);
|
||||
|
||||
Assert.AreEqual(0, index);
|
||||
|
|
@ -228,7 +228,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
|
||||
dataSource.Add(item);
|
||||
|
||||
Assert.IsTrue(((IList)dataSource).Contains(item));
|
||||
|
|
@ -239,7 +239,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
|
||||
dataSource.Add(item);
|
||||
|
||||
Assert.AreEqual(0, ((IList)dataSource).IndexOf(item));
|
||||
|
|
@ -250,8 +250,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" });
|
||||
var newItem = new TestOrderItem { Id = 2, ProductName = "Inserted" };
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "First" });
|
||||
var newItem = new TestOrderItem_All_True { Id = 2, ProductName = "Inserted" };
|
||||
|
||||
((IList)dataSource).Insert(0, newItem);
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
|
||||
dataSource.Add(item);
|
||||
|
||||
((IList)dataSource).Remove(item);
|
||||
|
|
@ -275,8 +275,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Original" });
|
||||
((IList)dataSource)[0] = new TestOrderItem { Id = 1, ProductName = "Modified" };
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Original" });
|
||||
((IList)dataSource)[0] = new TestOrderItem_All_True { Id = 1, ProductName = "Modified" };
|
||||
|
||||
Assert.AreEqual("Modified", dataSource[0].ProductName);
|
||||
}
|
||||
|
|
@ -286,10 +286,10 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2" });
|
||||
|
||||
var array = new TestOrderItem[2];
|
||||
var array = new TestOrderItem_All_True[2];
|
||||
((ICollection)dataSource).CopyTo(array, 0);
|
||||
|
||||
Assert.AreEqual("Item1", array[0].ProductName);
|
||||
|
|
@ -341,7 +341,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual void Add_ThenRemove_ClearsTracking()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
var item = new TestOrderItem { Id = 1, ProductName = "Temporary" };
|
||||
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Temporary" };
|
||||
|
||||
dataSource.Add(item);
|
||||
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
|
||||
|
|
@ -356,8 +356,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
// Add items
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1", Quantity = 10 });
|
||||
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2", Quantity = 20 });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1", Quantity = 10 });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2", Quantity = 20 });
|
||||
Assert.AreEqual(2, dataSource.GetTrackingItems().Count);
|
||||
|
||||
// Save
|
||||
|
|
@ -365,7 +365,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
Assert.AreEqual(0, dataSource.GetTrackingItems().Count);
|
||||
|
||||
// Update
|
||||
dataSource[0] = new TestOrderItem { Id = 1, ProductName = "Updated1", Quantity = 100 };
|
||||
dataSource[0] = new TestOrderItem_All_True { Id = 1, ProductName = "Updated1", Quantity = 100 };
|
||||
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
|
||||
Assert.AreEqual(TrackingState.Update, dataSource.GetTrackingItems()[0].TrackingState);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, expressionCrudTags);
|
||||
|
||||
// Create filter as Expression - serializer automatically converts to AcExpressionNode
|
||||
Expression<Func<TestOrderItem, bool>> filter = item => item.Quantity > 15;
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.Quantity > 15;
|
||||
|
||||
// Set filter as ContextIds - serializer handles the conversion
|
||||
dataSource.ContextIds = [filter];
|
||||
|
|
@ -75,7 +75,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
|
||||
// Create filter as Expression - no manual conversion needed
|
||||
var minPrice = 150m;
|
||||
Expression<Func<TestOrderItem, bool>> filter = item => item.UnitPrice > minPrice;
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.UnitPrice > minPrice;
|
||||
|
||||
dataSource.ContextIds = [filter];
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, expressionCrudTags);
|
||||
|
||||
// Create filter as Expression
|
||||
Expression<Func<TestOrderItem, bool>> filter = item => item.ProductName!.Contains("A");
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.ProductName!.Contains("A");
|
||||
|
||||
dataSource.ContextIds = [filter];
|
||||
|
||||
|
|
@ -131,7 +131,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, expressionCrudTags);
|
||||
|
||||
// Create filter as Expression - complex condition
|
||||
Expression<Func<TestOrderItem, bool>> filter = item => item.Quantity >= 20 && item.UnitPrice < 250m;
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.Quantity >= 20 && item.UnitPrice < 250m;
|
||||
|
||||
dataSource.ContextIds = [filter];
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, queryableCrudTags);
|
||||
|
||||
// Create a lambda filter Expression - this gets wrapped in Where on the server
|
||||
Expression<Func<TestOrderItem, bool>> filter = x => x.Quantity > 15;
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = x => x.Quantity > 15;
|
||||
|
||||
// Convert to AcExpressionNode for sending
|
||||
var filterNode = AcExpressionConverter.ToNode(filter);
|
||||
|
|
@ -189,7 +189,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
|
||||
// Create a lambda filter with decimal comparison
|
||||
var minPrice = 150m;
|
||||
Expression<Func<TestOrderItem, bool>> filter = x => x.UnitPrice > minPrice;
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = x => x.UnitPrice > minPrice;
|
||||
|
||||
var filterNode = AcExpressionConverter.ToNode(filter);
|
||||
dataSource.ContextIds = [filterNode];
|
||||
|
|
@ -210,7 +210,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, queryableCrudTags);
|
||||
|
||||
// Create a filter with AND condition
|
||||
Expression<Func<TestOrderItem, bool>> filter = x => x.Quantity >= 20 && x.UnitPrice < 250m;
|
||||
Expression<Func<TestOrderItem_All_True, bool>> filter = x => x.Quantity >= 20 && x.UnitPrice < 250m;
|
||||
|
||||
var filterNode = AcExpressionConverter.ToNode(filter);
|
||||
dataSource.ContextIds = [filterNode];
|
||||
|
|
@ -232,7 +232,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
|
||||
// Create a query chain: Where(x => x.Id > 1).Count()
|
||||
// This tests the method call chain serialization
|
||||
var query = new List<TestOrderItem>().AsQueryable()
|
||||
var query = new List<TestOrderItem_All_True>().AsQueryable()
|
||||
.Where(x => x.Id > 1);
|
||||
|
||||
var queryNode = AcExpressionConverter.ToNode(query.Expression);
|
||||
|
|
@ -270,7 +270,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public void QueryableAggregate_CountWithWhere_ExecutesOnServer()
|
||||
{
|
||||
// Arrange - Server data
|
||||
var serverItems = new List<TestOrderItem>
|
||||
var serverItems = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Product A", Quantity = 10 },
|
||||
new() { Id = 2, ProductName = "Product B", Quantity = 20 },
|
||||
|
|
@ -279,14 +279,14 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
|
||||
// Build query: .Where(x => x.Id > 1).Count()
|
||||
// The Count() is an aggregate that should execute on the server!
|
||||
var clientQuery = new List<TestOrderItem>().AsQueryable()
|
||||
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable()
|
||||
.Where(x => x.Id > 1);
|
||||
|
||||
// Build the Count() call expression manually
|
||||
var countExpression = System.Linq.Expressions.Expression.Call(
|
||||
typeof(Queryable),
|
||||
nameof(Queryable.Count),
|
||||
[typeof(TestOrderItem)],
|
||||
[typeof(TestOrderItem_All_True)],
|
||||
clientQuery.Expression
|
||||
);
|
||||
|
||||
|
|
@ -304,7 +304,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public void QueryableAggregate_CountWithPredicate_ExecutesOnServer()
|
||||
{
|
||||
// Arrange - Server data
|
||||
var serverItems = new List<TestOrderItem>
|
||||
var serverItems = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Product A", Quantity = 10 },
|
||||
new() { Id = 2, ProductName = "Product B", Quantity = 20 },
|
||||
|
|
@ -312,13 +312,13 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
};
|
||||
|
||||
// Build query: .Count(x => x.Quantity > 15)
|
||||
var clientQuery = new List<TestOrderItem>().AsQueryable();
|
||||
Expression<Func<TestOrderItem, bool>> predicate = x => x.Quantity > 15;
|
||||
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable();
|
||||
Expression<Func<TestOrderItem_All_True, bool>> predicate = x => x.Quantity > 15;
|
||||
|
||||
var countExpression = System.Linq.Expressions.Expression.Call(
|
||||
typeof(Queryable),
|
||||
nameof(Queryable.Count),
|
||||
[typeof(TestOrderItem)],
|
||||
[typeof(TestOrderItem_All_True)],
|
||||
clientQuery.Expression,
|
||||
System.Linq.Expressions.Expression.Quote(predicate)
|
||||
);
|
||||
|
|
@ -337,7 +337,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public void QueryableAggregate_Any_ExecutesOnServer()
|
||||
{
|
||||
// Arrange - Server data
|
||||
var serverItems = new List<TestOrderItem>
|
||||
var serverItems = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Product A", Quantity = 10 },
|
||||
new() { Id = 2, ProductName = "Product B", Quantity = 20 },
|
||||
|
|
@ -345,13 +345,13 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
};
|
||||
|
||||
// Build query: .Any(x => x.Quantity > 25)
|
||||
var clientQuery = new List<TestOrderItem>().AsQueryable();
|
||||
Expression<Func<TestOrderItem, bool>> predicate = x => x.Quantity > 25;
|
||||
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable();
|
||||
Expression<Func<TestOrderItem_All_True, bool>> predicate = x => x.Quantity > 25;
|
||||
|
||||
var anyExpression = System.Linq.Expressions.Expression.Call(
|
||||
typeof(Queryable),
|
||||
nameof(Queryable.Any),
|
||||
[typeof(TestOrderItem)],
|
||||
[typeof(TestOrderItem_All_True)],
|
||||
clientQuery.Expression,
|
||||
System.Linq.Expressions.Expression.Quote(predicate)
|
||||
);
|
||||
|
|
@ -370,7 +370,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public void QueryableAggregate_Sum_ExecutesOnServer()
|
||||
{
|
||||
// Arrange - Server data
|
||||
var serverItems = new List<TestOrderItem>
|
||||
var serverItems = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Product A", Quantity = 10, UnitPrice = 100m },
|
||||
new() { Id = 2, ProductName = "Product B", Quantity = 20, UnitPrice = 200m },
|
||||
|
|
@ -378,13 +378,13 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
};
|
||||
|
||||
// Build query: .Sum(x => x.Quantity)
|
||||
var clientQuery = new List<TestOrderItem>().AsQueryable();
|
||||
Expression<Func<TestOrderItem, int>> selector = x => x.Quantity;
|
||||
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable();
|
||||
Expression<Func<TestOrderItem_All_True, int>> selector = x => x.Quantity;
|
||||
|
||||
var sumExpression = System.Linq.Expressions.Expression.Call(
|
||||
typeof(Queryable),
|
||||
nameof(Queryable.Sum),
|
||||
[typeof(TestOrderItem)],
|
||||
[typeof(TestOrderItem_All_True)],
|
||||
clientQuery.Expression,
|
||||
System.Linq.Expressions.Expression.Quote(selector)
|
||||
);
|
||||
|
|
@ -407,7 +407,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public void QueryableExpression_WhenSerialized_HasCorrectStructure()
|
||||
{
|
||||
// Arrange - Create an IQueryable with Where
|
||||
var query = new List<TestOrderItem>().AsQueryable().Where(x => x.Id > 1);
|
||||
var query = new List<TestOrderItem_All_True>().AsQueryable().Where(x => x.Id > 1);
|
||||
|
||||
// Act - Serialize the expression
|
||||
var queryNode = AcExpressionConverter.ToNode(query.Expression);
|
||||
|
|
@ -445,11 +445,11 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public void QueryableExpression_ApplyToServer_Works()
|
||||
{
|
||||
// Arrange - Client query
|
||||
var clientQuery = new List<TestOrderItem>().AsQueryable().Where(x => x.Id > 1);
|
||||
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable().Where(x => x.Id > 1);
|
||||
var queryNode = AcExpressionConverter.ToNode(clientQuery.Expression);
|
||||
|
||||
// Server data
|
||||
var serverItems = new List<TestOrderItem>
|
||||
var serverItems = new List<TestOrderItem_All_True>
|
||||
{
|
||||
new() { Id = 1, ProductName = "Product A" },
|
||||
new() { Id = 2, ProductName = "Product B" },
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual async Task Add_WithAutoSave_AddsItem()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
var newItem = new TestOrderItem { Id = 100, ProductName = "New Product", Quantity = 5, UnitPrice = 50m };
|
||||
var newItem = new TestOrderItem_All_True { Id = 100, ProductName = "New Product", Quantity = 5, UnitPrice = 50m };
|
||||
var result = await dataSource.Add(newItem, autoSave: true);
|
||||
|
||||
Assert.AreEqual(1, dataSource.Count);
|
||||
|
|
@ -23,7 +23,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual void Add_WithoutAutoSave_AddsToTrackingOnly()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
var newItem = new TestOrderItem { Id = 100, ProductName = "New Product" };
|
||||
var newItem = new TestOrderItem_All_True { Id = 100, ProductName = "New Product" };
|
||||
dataSource.Add(newItem);
|
||||
|
||||
Assert.AreEqual(1, dataSource.Count);
|
||||
|
|
@ -35,11 +35,11 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual void Add_DuplicateId_ThrowsException()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
dataSource.Add(new TestOrderItem { Id = 100, ProductName = "First" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 100, ProductName = "First" });
|
||||
|
||||
Assert.ThrowsExactly<ArgumentException>(() =>
|
||||
{
|
||||
dataSource.Add(new TestOrderItem { Id = 100, ProductName = "Duplicate" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 100, ProductName = "Duplicate" });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
|
||||
Assert.ThrowsExactly<ArgumentNullException>(() =>
|
||||
{
|
||||
dataSource.Add(new TestOrderItem { Id = 0, ProductName = "Invalid" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 0, ProductName = "Invalid" });
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -61,9 +61,9 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
|
||||
var items = new[]
|
||||
{
|
||||
new TestOrderItem { Id = 101, ProductName = "Item 1" },
|
||||
new TestOrderItem { Id = 102, ProductName = "Item 2" },
|
||||
new TestOrderItem { Id = 103, ProductName = "Item 3" }
|
||||
new TestOrderItem_All_True { Id = 101, ProductName = "Item 1" },
|
||||
new TestOrderItem_All_True { Id = 102, ProductName = "Item 2" },
|
||||
new TestOrderItem_All_True { Id = 103, ProductName = "Item 3" }
|
||||
};
|
||||
dataSource.AddRange(items);
|
||||
Assert.AreEqual(3, dataSource.Count);
|
||||
|
|
@ -77,7 +77,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual async Task AddOrUpdate_AddsNew_WhenNotExists()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
var newItem = new TestOrderItem { Id = 200, ProductName = "Brand New" };
|
||||
var newItem = new TestOrderItem_All_True { Id = 200, ProductName = "Brand New" };
|
||||
var result = await dataSource.AddOrUpdate(newItem, autoSave: true);
|
||||
|
||||
Assert.AreEqual(1, dataSource.Count);
|
||||
|
|
@ -91,7 +91,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
await dataSource.LoadDataSource();
|
||||
|
||||
var existingId = dataSource[0].Id;
|
||||
var updatedItem = new TestOrderItem { Id = existingId, ProductName = "Updated Name", Quantity = 999 };
|
||||
var updatedItem = new TestOrderItem_All_True { Id = existingId, ProductName = "Updated Name", Quantity = 999 };
|
||||
_ = await dataSource.AddOrUpdate(updatedItem, autoSave: true);
|
||||
|
||||
Assert.AreEqual(3, dataSource.Count);
|
||||
|
|
@ -107,9 +107,9 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" });
|
||||
dataSource.Add(new TestOrderItem { Id = 3, ProductName = "Third" });
|
||||
dataSource.Insert(1, new TestOrderItem { Id = 2, ProductName = "Second" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "First" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 3, ProductName = "Third" });
|
||||
dataSource.Insert(1, new TestOrderItem_All_True { Id = 2, ProductName = "Second" });
|
||||
|
||||
Assert.AreEqual(3, dataSource.Count);
|
||||
Assert.AreEqual("Second", dataSource[1].ProductName);
|
||||
|
|
@ -121,7 +121,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
var newItem = new TestOrderItem { Id = 500, ProductName = "Inserted" };
|
||||
var newItem = new TestOrderItem_All_True { Id = 500, ProductName = "Inserted" };
|
||||
_ = await dataSource.Insert(0, newItem, autoSave: true);
|
||||
|
||||
Assert.AreEqual(1, dataSource.Count);
|
||||
|
|
@ -138,7 +138,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
await dataSource.LoadDataSource();
|
||||
|
||||
var updatedItem = new TestOrderItem
|
||||
var updatedItem = new TestOrderItem_All_True
|
||||
{
|
||||
Id = dataSource[0].Id,
|
||||
ProductName = "Updated Product",
|
||||
|
|
@ -157,7 +157,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
await dataSource.LoadDataSource();
|
||||
|
||||
var updatedItem = new TestOrderItem
|
||||
var updatedItem = new TestOrderItem_All_True
|
||||
{
|
||||
Id = dataSource[1].Id,
|
||||
ProductName = "Updated B",
|
||||
|
|
@ -174,8 +174,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Original" });
|
||||
dataSource[0] = new TestOrderItem { Id = 1, ProductName = "Modified" };
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Original" });
|
||||
dataSource[0] = new TestOrderItem_All_True { Id = 1, ProductName = "Modified" };
|
||||
|
||||
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
|
||||
Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState);
|
||||
|
|
@ -216,7 +216,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "ToRemove" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "ToRemove" });
|
||||
|
||||
dataSource.GetTrackingItems().Clear();
|
||||
dataSource.Remove(dataSource[0]);
|
||||
|
|
@ -231,9 +231,9 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" });
|
||||
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Second" });
|
||||
dataSource.Add(new TestOrderItem { Id = 3, ProductName = "Third" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "First" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Second" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 3, ProductName = "Third" });
|
||||
|
||||
dataSource.GetTrackingItems().Clear();
|
||||
dataSource.RemoveAt(1);
|
||||
|
|
@ -260,7 +260,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Test" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Test" });
|
||||
var result = dataSource.TryRemove(1, out var removedItem);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual async Task LoadDataSource_ClearsChangeTracking_ByDefault()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
dataSource.Add(new TestOrderItem { Id = 999, ProductName = "Tracked" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 999, ProductName = "Tracked" });
|
||||
|
||||
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
await dataSource.LoadDataSource();
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 999, ProductName = "Tracked" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 999, ProductName = "Tracked" });
|
||||
await dataSource.LoadDataSource(clearChangeTracking: false);
|
||||
|
||||
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
ItemChangedEventArgs<TestOrderItem>? eventArgs = null;
|
||||
ItemChangedEventArgs<TestOrderItem_All_True>? eventArgs = null;
|
||||
|
||||
dataSource.OnDataSourceItemChanged = args => { eventArgs = args; return Task.CompletedTask; };
|
||||
await dataSource.LoadItem(1);
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 101, ProductName = "Item 1" });
|
||||
dataSource.Add(new TestOrderItem { Id = 102, ProductName = "Item 2" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 101, ProductName = "Item 1" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 102, ProductName = "Item 2" });
|
||||
|
||||
var unsaved = await dataSource.SaveChanges();
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
public virtual async Task SaveChangesAsync_ClearsTracking()
|
||||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
dataSource.Add(new TestOrderItem { Id = 103, ProductName = "Item 3" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 103, ProductName = "Item 3" });
|
||||
|
||||
await dataSource.SaveChangesAsync();
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 201, ProductName = "Specific" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 201, ProductName = "Specific" });
|
||||
var result = await dataSource.SaveItem(201);
|
||||
|
||||
Assert.AreEqual("Specific", result.ProductName);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Test" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Test" });
|
||||
|
||||
dataSource.SetTrackingStateToUpdate(dataSource[0]);
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "New Item" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "New Item" });
|
||||
dataSource.SetTrackingStateToUpdate(dataSource[0]);
|
||||
|
||||
Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState);
|
||||
|
|
@ -36,7 +36,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Tracked" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Tracked" });
|
||||
var result = dataSource.TryGetTrackingItem(1, out var trackingItem);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
|
|
@ -63,7 +63,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Added" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Added" });
|
||||
var result = dataSource.TryRollbackItem(1, out var originalValue);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
|
|
@ -78,7 +78,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
await dataSource.LoadDataSource();
|
||||
|
||||
var originalName = dataSource[0].ProductName;
|
||||
dataSource[0] = new TestOrderItem { Id = dataSource[0].Id, ProductName = "Changed" };
|
||||
dataSource[0] = new TestOrderItem_All_True { Id = dataSource[0].Id, ProductName = "Changed" };
|
||||
var result = dataSource.TryRollbackItem(dataSource[0].Id, out var originalValue);
|
||||
|
||||
Assert.IsTrue(result);
|
||||
|
|
@ -90,8 +90,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
|||
{
|
||||
var dataSource = CreateDataSource(_client, _crudTags);
|
||||
|
||||
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
|
||||
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2" });
|
||||
dataSource.Rollback();
|
||||
|
||||
Assert.AreEqual(0, dataSource.Count);
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
|||
/// <typeparam name="TDataSource">The concrete DataSource type</typeparam>
|
||||
/// <typeparam name="TIList">The inner list type (List or AcObservableCollection)</typeparam>
|
||||
public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
|
||||
where TDataSource : AcSignalRDataSource<TestOrderItem, int, TIList>
|
||||
where TIList : class, IList<TestOrderItem>
|
||||
where TDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, TIList>
|
||||
where TIList : class, IList<TestOrderItem_All_True>
|
||||
{
|
||||
protected abstract AcSerializerOptions SerializerOption { get; }
|
||||
protected abstract TDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using AyCode.Services.SignalRs;
|
|||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
[TestClass]
|
||||
public class SignalRDataSourceTests_List_Binary : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem>>
|
||||
public class SignalRDataSourceTests_List_Binary : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem_All_True>>
|
||||
{
|
||||
protected override AcSerializerOptions SerializerOption => new AcBinarySerializerOptions();
|
||||
protected override TestOrderItemListDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ using AyCode.Services.SignalRs;
|
|||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
[TestClass]
|
||||
public class SignalRDataSourceTests_List_Binary_NoRef : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem>>
|
||||
public class SignalRDataSourceTests_List_Binary_NoRef : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem_All_True>>
|
||||
{
|
||||
protected override AcSerializerOptions SerializerOption => new AcBinarySerializerOptions { ReferenceHandling = ReferenceHandlingMode.None };
|
||||
protected override TestOrderItemListDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using AyCode.Services.SignalRs;
|
|||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
[TestClass]
|
||||
public class SignalRDataSourceTests_List_Json : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem>>
|
||||
public class SignalRDataSourceTests_List_Json : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem_All_True>>
|
||||
{
|
||||
protected override AcSerializerOptions SerializerOption => new AcJsonSerializerOptions();
|
||||
protected override TestOrderItemListDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using AyCode.Services.SignalRs;
|
|||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
[TestClass]
|
||||
public class SignalRDataSourceTests_Observable_Binary : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem>>
|
||||
public class SignalRDataSourceTests_Observable_Binary : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem_All_True>>
|
||||
{
|
||||
protected override AcSerializerOptions SerializerOption => new AcBinarySerializerOptions();
|
||||
protected override TestOrderItemObservableDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using AyCode.Services.SignalRs;
|
|||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
[TestClass]
|
||||
public class SignalRDataSourceTests_Observable_Json : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem>>
|
||||
public class SignalRDataSourceTests_Observable_Json : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem_All_True>>
|
||||
{
|
||||
protected override AcSerializerOptions SerializerOption => new AcJsonSerializerOptions();
|
||||
protected override TestOrderItemObservableDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ using AyCode.Services.SignalRs;
|
|||
|
||||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
public class TestOrderItemListDataSource : AcSignalRDataSource<TestOrderItem, int, List<TestOrderItem>>
|
||||
public class TestOrderItemListDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, List<TestOrderItem_All_True>>
|
||||
{
|
||||
public TestOrderItemListDataSource(AcSignalRClientBase signalRClient, SignalRCrudTags crudTags)
|
||||
: base(signalRClient, crudTags) { }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ using AyCode.Services.SignalRs;
|
|||
|
||||
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
|
||||
|
||||
public class TestOrderItemObservableDataSource : AcSignalRDataSource<TestOrderItem, int, AcObservableCollection<TestOrderItem>>
|
||||
public class TestOrderItemObservableDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, AcObservableCollection<TestOrderItem_All_True>>
|
||||
{
|
||||
public TestOrderItemObservableDataSource(AcSignalRClientBase signalRClient, SignalRCrudTags crudTags)
|
||||
: base(signalRClient, crudTags) { }
|
||||
|
|
|
|||
|
|
@ -104,9 +104,9 @@ public class TestSignalRService2
|
|||
#region Complex Object Handlers (using shared DTOs)
|
||||
|
||||
[SignalR(TestSignalRTags.TestOrderItemParam)]
|
||||
public TestOrderItem HandleTestOrderItem(TestOrderItem item)
|
||||
public TestOrderItem_All_True HandleTestOrderItem(TestOrderItem_All_True item)
|
||||
{
|
||||
return new TestOrderItem
|
||||
return new TestOrderItem_All_True
|
||||
{
|
||||
Id = item.Id,
|
||||
ProductName = $"Processed: {item.ProductName}",
|
||||
|
|
@ -116,13 +116,13 @@ public class TestSignalRService2
|
|||
}
|
||||
|
||||
[SignalR(TestSignalRTags.TestOrderParam)]
|
||||
public TestOrder HandleTestOrder(TestOrder order)
|
||||
public TestOrder_All_True HandleTestOrder(TestOrder_All_True order)
|
||||
{
|
||||
return order;
|
||||
}
|
||||
|
||||
[SignalR(TestSignalRTags.SharedTagParam)]
|
||||
public SharedTag HandleSharedTag(SharedTag tag)
|
||||
public SharedTag_All_True HandleSharedTag(SharedTag_All_True tag)
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ public class TestSignalRService2
|
|||
}
|
||||
|
||||
[SignalR(TestSignalRTags.TestOrderItemListParam)]
|
||||
public List<TestOrderItem> HandleTestOrderItemList(List<TestOrderItem> items)
|
||||
public List<TestOrderItem_All_True> HandleTestOrderItemList(List<TestOrderItem_All_True> items)
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
|
@ -214,7 +214,7 @@ public class TestSignalRService2
|
|||
}
|
||||
|
||||
[SignalR(TestSignalRTags.SharedTagArrayParam)]
|
||||
public SharedTag[] HandleSharedTagArray(SharedTag[] tags)
|
||||
public SharedTag_All_True[] HandleSharedTagArray(SharedTag_All_True[] tags)
|
||||
{
|
||||
return tags;
|
||||
}
|
||||
|
|
@ -236,19 +236,19 @@ public class TestSignalRService2
|
|||
#region Mixed Parameter Handlers
|
||||
|
||||
[SignalR(TestSignalRTags.IntAndDtoParam)]
|
||||
public string HandleIntAndDto(int id, TestOrderItem item)
|
||||
public string HandleIntAndDto(int id, TestOrderItem_All_True item)
|
||||
{
|
||||
return $"{id}-{item?.ProductName}";
|
||||
}
|
||||
|
||||
[SignalR(TestSignalRTags.DtoAndListParam)]
|
||||
public string HandleDtoAndList(TestOrderItem item, List<int> numbers)
|
||||
public string HandleDtoAndList(TestOrderItem_All_True item, List<int> numbers)
|
||||
{
|
||||
return $"{item?.ProductName}-[{string.Join(",", numbers ?? [])}]";
|
||||
}
|
||||
|
||||
[SignalR(TestSignalRTags.ThreeComplexParams)]
|
||||
public string HandleThreeComplexParams(TestOrderItem item, List<string> tags, SharedTag sharedTag)
|
||||
public string HandleThreeComplexParams(TestOrderItem_All_True item, List<string> tags, SharedTag_All_True sharedTag)
|
||||
{
|
||||
return $"{item?.ProductName}-{tags?.Count}-{sharedTag?.Name}";
|
||||
}
|
||||
|
|
@ -264,10 +264,10 @@ public class TestSignalRService2
|
|||
#region Async Task<T> Method Tests
|
||||
|
||||
[SignalR(TestSignalRTags.AsyncTestOrderItemParam)]
|
||||
public async Task<TestOrderItem> HandleAsyncTestOrderItem(TestOrderItem item)
|
||||
public async Task<TestOrderItem_All_True> HandleAsyncTestOrderItem(TestOrderItem_All_True item)
|
||||
{
|
||||
await Task.Delay(1); // Simulate async work
|
||||
return new TestOrderItem
|
||||
return new TestOrderItem_All_True
|
||||
{
|
||||
Id = item.Id,
|
||||
ProductName = $"Async: {item.ProductName}",
|
||||
|
|
@ -316,13 +316,13 @@ public class TestSignalRService2
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns Task<TestOrderItem> without async keyword.
|
||||
/// Returns Task<TestOrderItem_All_True> without async keyword.
|
||||
/// CRITICAL: This simulates the exact production bug scenario.
|
||||
/// </summary>
|
||||
[SignalR(TestSignalRTags.TaskFromResultTestOrderItemParam)]
|
||||
public Task<TestOrderItem> HandleTaskFromResultTestOrderItem(TestOrderItem item)
|
||||
public Task<TestOrderItem_All_True> HandleTaskFromResultTestOrderItem(TestOrderItem_All_True item)
|
||||
{
|
||||
return Task.FromResult(new TestOrderItem
|
||||
return Task.FromResult(new TestOrderItem_All_True
|
||||
{
|
||||
Id = item.Id,
|
||||
ProductName = $"FromResult: {item.ProductName}",
|
||||
|
|
@ -380,11 +380,11 @@ public class TestSignalRService2
|
|||
#region Large Dataset / List Tests
|
||||
|
||||
/// <summary>
|
||||
/// Tests Binary serialization with a list of TestOrder objects.
|
||||
/// Tests Binary serialization with a list of TestOrder_All_True objects.
|
||||
/// Used for testing string interning with deeply nested objects.
|
||||
/// </summary>
|
||||
[SignalR(TestSignalRTags.TestOrderListParam)]
|
||||
public List<TestOrder> HandleTestOrderList(List<TestOrder> orders)
|
||||
public List<TestOrder_All_True> HandleTestOrderList(List<TestOrder_All_True> orders)
|
||||
{
|
||||
return orders;
|
||||
}
|
||||
|
|
@ -440,7 +440,7 @@ public class TestSignalRService2
|
|||
|
||||
#region DataSource CRUD Tests
|
||||
|
||||
private readonly List<TestOrderItem> _dataSourceItems =
|
||||
private readonly List<TestOrderItem_All_True> _dataSourceItems =
|
||||
[
|
||||
new() { Id = 1, ProductName = "Product A", Quantity = 10, UnitPrice = 100m },
|
||||
new() { Id = 2, ProductName = "Product B", Quantity = 20, UnitPrice = 200m },
|
||||
|
|
@ -448,7 +448,7 @@ public class TestSignalRService2
|
|||
];
|
||||
|
||||
[SignalR(TestSignalRTags.DataSourceGetAll)]
|
||||
public List<TestOrderItem> DataSourceGetAll() => _dataSourceItems.ToList();
|
||||
public List<TestOrderItem_All_True> DataSourceGetAll() => _dataSourceItems.ToList();
|
||||
|
||||
/// <summary>
|
||||
/// DataSource GetAll with Expression filter.
|
||||
|
|
@ -456,7 +456,7 @@ public class TestSignalRService2
|
|||
/// Uses IQueryable.Where() instead of Compile() for EF Core compatibility.
|
||||
/// </summary>
|
||||
[SignalR(TestSignalRTags.ExpressionDataSourceGetAll)]
|
||||
public List<TestOrderItem> ExpressionDataSourceGetAll(Expression<Func<TestOrderItem, bool>>? filter = null)
|
||||
public List<TestOrderItem_All_True> ExpressionDataSourceGetAll(Expression<Func<TestOrderItem_All_True, bool>>? filter = null)
|
||||
{
|
||||
if (filter == null)
|
||||
return _dataSourceItems.ToList();
|
||||
|
|
@ -471,10 +471,10 @@ public class TestSignalRService2
|
|||
/// The expression is rebuilt and applied to the server's IQueryable.
|
||||
/// </summary>
|
||||
[SignalR(TestSignalRTags.QueryableDataSourceGetAll)]
|
||||
public List<TestOrderItem> QueryableDataSourceGetAll(AcExpressionNode? queryNode = null)
|
||||
public List<TestOrderItem_All_True> QueryableDataSourceGetAll(AcExpressionNode? queryNode = null)
|
||||
{
|
||||
// Simulate DbContext.Items (IQueryable<T>)
|
||||
IQueryable<TestOrderItem> serverQuery = _dataSourceItems.AsQueryable();
|
||||
IQueryable<TestOrderItem_All_True> serverQuery = _dataSourceItems.AsQueryable();
|
||||
|
||||
// If client sent a query node, rebuild and apply it
|
||||
if (queryNode != null)
|
||||
|
|
@ -482,7 +482,7 @@ public class TestSignalRService2
|
|||
// If it's a lambda expression, use it directly as a filter
|
||||
if (queryNode.NodeType == ExpressionType.Lambda)
|
||||
{
|
||||
var filter = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(queryNode);
|
||||
var filter = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(queryNode);
|
||||
serverQuery = serverQuery.Where(filter);
|
||||
}
|
||||
else
|
||||
|
|
@ -505,7 +505,7 @@ public class TestSignalRService2
|
|||
public object? QueryableDataSourceAggregate(AcExpressionNode queryNode)
|
||||
{
|
||||
// Build the query from the expression node
|
||||
IQueryable<TestOrderItem> serverQuery = _dataSourceItems.AsQueryable();
|
||||
IQueryable<TestOrderItem_All_True> serverQuery = _dataSourceItems.AsQueryable();
|
||||
|
||||
// Apply the full expression tree (including the aggregate method)
|
||||
var result = AcSerializerCommon.ExecuteQueryFromNode(serverQuery, queryNode);
|
||||
|
|
@ -514,17 +514,17 @@ public class TestSignalRService2
|
|||
}
|
||||
|
||||
[SignalR(TestSignalRTags.DataSourceGetItem)]
|
||||
public TestOrderItem? DataSourceGetItem(int id) => _dataSourceItems.FirstOrDefault(x => x.Id == id);
|
||||
public TestOrderItem_All_True? DataSourceGetItem(int id) => _dataSourceItems.FirstOrDefault(x => x.Id == id);
|
||||
|
||||
[SignalR(TestSignalRTags.DataSourceAdd)]
|
||||
public TestOrderItem DataSourceAdd(TestOrderItem item)
|
||||
public TestOrderItem_All_True DataSourceAdd(TestOrderItem_All_True item)
|
||||
{
|
||||
_dataSourceItems.Add(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
[SignalR(TestSignalRTags.DataSourceUpdate)]
|
||||
public TestOrderItem DataSourceUpdate(TestOrderItem item)
|
||||
public TestOrderItem_All_True DataSourceUpdate(TestOrderItem_All_True item)
|
||||
{
|
||||
var index = _dataSourceItems.FindIndex(x => x.Id == item.Id);
|
||||
if (index >= 0) _dataSourceItems[index] = item;
|
||||
|
|
@ -532,7 +532,7 @@ public class TestSignalRService2
|
|||
}
|
||||
|
||||
[SignalR(TestSignalRTags.DataSourceRemove)]
|
||||
public TestOrderItem? DataSourceRemove(TestOrderItem item)
|
||||
public TestOrderItem_All_True? DataSourceRemove(TestOrderItem_All_True item)
|
||||
{
|
||||
var existing = _dataSourceItems.FirstOrDefault(x => x.Id == item.Id);
|
||||
if (existing != null) _dataSourceItems.Remove(existing);
|
||||
|
|
|
|||
Loading…
Reference in New Issue