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