[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:
Loretta 2026-05-13 08:40:42 +02:00
parent 23f2f57fa7
commit 32f2de0db3
55 changed files with 1092 additions and 964 deletions

View File

@ -24,7 +24,7 @@ namespace AyCode.Core.Benchmarks;
[MemoryDiagnoser(displayGenColumns: false)]
public class JitDisassemblyBenchmark
{
private TestOrder _order = null!;
private TestOrder_All_True _order = null!;
private AcBinarySerializerOptions _fastModeOptions = null!;
private AcBinarySerializerOptions _defaultOptions = null!;
private byte[] _serializedFastMode = null!;
@ -34,7 +34,7 @@ public class JitDisassemblyBenchmark
public void Setup()
{
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
// Medium data: enough properties to show loop behavior, not too large for disassembly
@ -65,9 +65,9 @@ public class JitDisassemblyBenchmark
/// FastMode deserialize.
/// </summary>
[Benchmark]
public TestOrder Deserialize_FastMode()
public TestOrder_All_True Deserialize_FastMode()
{
return AcBinaryDeserializer.Deserialize<TestOrder>(_serializedFastMode, _fastModeOptions);
return AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_serializedFastMode, _fastModeOptions);
}
/// <summary>
@ -84,8 +84,8 @@ public class JitDisassemblyBenchmark
/// Default deserialize — ref tracking + string interning.
/// </summary>
[Benchmark]
public TestOrder Deserialize_Default()
public TestOrder_All_True Deserialize_Default()
{
return AcBinaryDeserializer.Deserialize<TestOrder>(_serializedDefault, _defaultOptions);
return AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_serializedDefault, _defaultOptions);
}
}

View File

@ -169,7 +169,7 @@ namespace AyCode.Benchmark
// Create test data with shared references
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
@ -247,19 +247,19 @@ namespace AyCode.Benchmark
// AcBinary WithRef Deserialize
sw.Restart();
for (int i = 0; i < iterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryWithRef);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryWithRef);
var acWithRefDeserialize = sw.Elapsed.TotalMilliseconds;
// AcBinary NoRef Deserialize
sw.Restart();
for (int i = 0; i < iterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryNoRef);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryNoRef);
var acNoRefDeserialize = sw.Elapsed.TotalMilliseconds;
// MessagePack Deserialize
sw.Restart();
for (int i = 0; i < iterations; i++)
_ = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, msgPackOptions);
_ = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, msgPackOptions);
var msgPackDeserialize = sw.Elapsed.TotalMilliseconds;
results.Add(("Deserialize", "WithRef", acWithRefDeserialize, msgPackDeserialize));
@ -332,12 +332,12 @@ namespace AyCode.Benchmark
Console.WriteLine();
}
static TestOrder CreatePopulateTarget(TestOrder source)
static TestOrder_All_True CreatePopulateTarget(TestOrder_All_True source)
{
var target = new TestOrder { Id = source.Id };
var target = new TestOrder_All_True { Id = source.Id };
foreach (var item in source.Items)
{
target.Items.Add(new TestOrderItem { Id = item.Id });
target.Items.Add(new TestOrderItem_All_True { Id = item.Id });
}
return target;
}

View File

@ -88,7 +88,7 @@ public class SimpleBinaryBenchmark
[RankColumn]
public class ComplexBinaryBenchmark
{
private TestOrder _testOrder = null!;
private TestOrder_All_True _testOrder = null!;
private byte[] _acBinaryData = null!;
private string _jsonData = null!;
@ -130,10 +130,10 @@ public class ComplexBinaryBenchmark
public string Serialize_Json() => AcJsonSerializer.Serialize(_testOrder, _jsonOptions);
[Benchmark(Description = "AcBinary Deserialize")]
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryData);
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryData);
[Benchmark(Description = "JSON Deserialize")]
public TestOrder? Deserialize_Json() => AcJsonDeserializer.Deserialize<TestOrder>(_jsonData, _jsonOptions);
public TestOrder_All_True? Deserialize_Json() => AcJsonDeserializer.Deserialize<TestOrder_All_True>(_jsonData, _jsonOptions);
}
/// <summary>
@ -144,7 +144,7 @@ public class ComplexBinaryBenchmark
[RankColumn]
public class MessagePackComparisonBenchmark
{
private TestOrder _testOrder = null!;
private TestOrder_All_True _testOrder = null!;
private byte[] _acBinaryData = null!;
private byte[] _msgPackData = null!;
private byte[] _bsonData = null!;
@ -216,18 +216,18 @@ public class MessagePackComparisonBenchmark
public byte[] Serialize_Bson() => _testOrder.ToBsonDocument().ToBson();
[Benchmark(Description = "AcBinary Deserialize")]
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryData);
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryData);
[Benchmark(Description = "MessagePack Deserialize")]
public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder>(_msgPackData, _msgPackOptions);
public TestOrder_All_True? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_msgPackData, _msgPackOptions);
[Benchmark(Description = "BSON Deserialize")]
public TestOrder? Deserialize_Bson()
public TestOrder_All_True? Deserialize_Bson()
{
if (_bsonData == null || _bsonData.Length == 0) return null;
using var ms = new MemoryStream(_bsonData);
using var reader = new BsonBinaryReader(ms);
return BsonSerializer.Deserialize<TestOrder>(reader);
return BsonSerializer.Deserialize<TestOrder_All_True>(reader);
}
}
@ -241,8 +241,8 @@ public class MessagePackComparisonBenchmark
public class AcBinaryVsMessagePackFullBenchmark
{
// Test data
private TestOrder _testOrder = null!;
private TestOrder _populateTarget = null!;
private TestOrder_All_True _testOrder = null!;
private TestOrder_All_True _populateTarget = null!;
// Serialized data - AcBinary
private byte[] _acBinaryWithRef = null!;
@ -262,7 +262,7 @@ public class AcBinaryVsMessagePackFullBenchmark
{
// Create test data with shared references
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
@ -296,10 +296,10 @@ public class AcBinaryVsMessagePackFullBenchmark
}
// Create populate target
_populateTarget = new TestOrder { Id = _testOrder.Id };
_populateTarget = new TestOrder_All_True { Id = _testOrder.Id };
foreach (var item in _testOrder.Items)
{
_populateTarget.Items.Add(new TestOrderItem { Id = item.Id });
_populateTarget.Items.Add(new TestOrderItem_All_True { Id = item.Id });
}
// Print size comparison
@ -340,21 +340,21 @@ public class AcBinaryVsMessagePackFullBenchmark
#region Deserialize Benchmarks
[Benchmark(Description = "AcBinary Deserialize WithRef")]
public TestOrder? Deserialize_AcBinary_WithRef() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryWithRef);
public TestOrder_All_True? Deserialize_AcBinary_WithRef() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryWithRef);
[Benchmark(Description = "AcBinary Deserialize NoRef")]
public TestOrder? Deserialize_AcBinary_NoRef() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryNoRef);
public TestOrder_All_True? Deserialize_AcBinary_NoRef() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryNoRef);
[Benchmark(Description = "MessagePack Deserialize")]
public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder>(_msgPackData, _msgPackOptions);
public TestOrder_All_True? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_msgPackData, _msgPackOptions);
[Benchmark(Description = "BSON Deserialize")]
public TestOrder? Deserialize_Bson()
public TestOrder_All_True? Deserialize_Bson()
{
if (_bsonData == null || _bsonData.Length == 0) return null;
using var ms = new MemoryStream(_bsonData);
using var reader = new BsonBinaryReader(ms);
return BsonSerializer.Deserialize<TestOrder>(reader);
return BsonSerializer.Deserialize<TestOrder_All_True>(reader);
}
#endregion
@ -391,12 +391,12 @@ public class AcBinaryVsMessagePackFullBenchmark
AcBinaryDeserializer.PopulateMerge(_acBinaryNoRef, target);
}
private TestOrder CreatePopulateTarget()
private TestOrder_All_True CreatePopulateTarget()
{
var target = new TestOrder { Id = _testOrder.Id };
var target = new TestOrder_All_True { Id = _testOrder.Id };
foreach (var item in _testOrder.Items)
{
target.Items.Add(new TestOrderItem { Id = item.Id });
target.Items.Add(new TestOrderItem_All_True { Id = item.Id });
}
return target;
}
@ -412,9 +412,9 @@ public class AcBinaryVsMessagePackFullBenchmark
[MemoryDiagnoser]
public class SizeComparisonBenchmark
{
private TestOrder _smallOrder = null!;
private TestOrder _mediumOrder = null!;
private TestOrder _largeOrder = null!;
private TestOrder_All_True _smallOrder = null!;
private TestOrder_All_True _mediumOrder = null!;
private TestOrder_All_True _largeOrder = null!;
private MessagePackSerializerOptions _msgPackOptions = null!;
private AcBinarySerializerOptions _withRefOptions = null!;
@ -464,7 +464,7 @@ public class SizeComparisonBenchmark
Console.WriteLine(new string('=', 80) + "\n");
}
private void PrintOrderSize(string name, TestOrder order)
private void PrintOrderSize(string name, TestOrder_All_True order)
{
var acWithRef = AcBinarySerializer.Serialize(order, _withRefOptions);
var acNoRef = AcBinarySerializer.Serialize(order, _noRefOptions);
@ -499,7 +499,7 @@ public enum BinaryBenchmarkMode
public abstract class AcBinaryOptionsBenchmarkBase
{
protected TestOrder TestOrder = null!;
protected TestOrder_All_True TestOrder = null!;
protected AcBinarySerializerOptions BinaryOptions = null!;
protected MessagePackSerializerOptions MsgPackOptions = null!;
protected byte[] AcBinaryData = null!;
@ -560,10 +560,10 @@ public class AcBinaryOptionsSerializeBenchmark : AcBinaryOptionsBenchmarkBase
public class AcBinaryOptionsDeserializeBenchmark : AcBinaryOptionsBenchmarkBase
{
[Benchmark(Description = "MessagePack Deserialize", Baseline = true)]
public TestOrder? Deserialize_MessagePack() => MessagePackSerializer.Deserialize<TestOrder>(MsgPackData, MsgPackOptions);
public TestOrder_All_True? Deserialize_MessagePack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(MsgPackData, MsgPackOptions);
[Benchmark(Description = "AcBinary Deserialize")]
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(AcBinaryData);
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(AcBinaryData);
}
/// <summary>
@ -578,8 +578,8 @@ public class LargeScaleBinaryBenchmark
{
// Test data - smaller scale for benchmark (500 items ? 25K objects)
// Production would be 2200 items ? 100K+ objects
private TestOrder _testOrder = null!;
private TestOrder _populateTarget = null!;
private TestOrder_All_True _testOrder = null!;
private TestOrder_All_True _populateTarget = null!;
// Serialized data
private byte[] _acBinaryData = null!;
@ -619,10 +619,10 @@ public class LargeScaleBinaryBenchmark
_msgPackData = MessagePackSerializer.Serialize(_testOrder, _msgPackOptions);
// Create populate target
_populateTarget = new TestOrder { Id = _testOrder.Id };
_populateTarget = new TestOrder_All_True { Id = _testOrder.Id };
foreach (var item in _testOrder.Items.Take(10)) // Only first 10 for populate target
{
_populateTarget.Items.Add(new TestOrderItem { Id = item.Id });
_populateTarget.Items.Add(new TestOrderItem_All_True { Id = item.Id });
}
PrintStats();
@ -642,10 +642,10 @@ public class LargeScaleBinaryBenchmark
}
[Benchmark(Description = "LargeScale AcBinary Deserialize")]
public TestOrder? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder>(_acBinaryData);
public TestOrder_All_True? Deserialize_AcBinary() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_acBinaryData);
[Benchmark(Description = "LargeScale MsgPack Deserialize", Baseline = true)]
public TestOrder? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder>(_msgPackData, _msgPackOptions);
public TestOrder_All_True? Deserialize_MsgPack() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_msgPackData, _msgPackOptions);
[Benchmark(Description = "LargeScale AcBinary Serialize")]
public byte[] Serialize_AcBinary() => AcBinarySerializer.Serialize(_testOrder, _binaryOptions);

View File

@ -107,18 +107,18 @@ public class SignalRCommunicationBenchmarks
[Benchmark(Description = "Server: Deserialize complex OrderItem")]
[BenchmarkCategory("Server", "Deserialize")]
public TestOrderItem Server_DeserializeComplexOrderItem()
public TestOrderItem_All_True Server_DeserializeComplexOrderItem()
{
var postMessage = MessagePackSerializer.Deserialize<SignalRPostMessageDto>(_complexOrderItemMessage, SignalRMessageFactory.ContractlessOptions);
return postMessage.PostDataJson!.JsonTo<TestOrderItem>()!;
return postMessage.PostDataJson!.JsonTo<TestOrderItem_All_True>()!;
}
[Benchmark(Description = "Server: Deserialize complex Order")]
[BenchmarkCategory("Server", "Deserialize")]
public TestOrder Server_DeserializeComplexOrder()
public TestOrder_All_True Server_DeserializeComplexOrder()
{
var postMessage = MessagePackSerializer.Deserialize<SignalRPostMessageDto>(_complexOrderMessage, SignalRMessageFactory.ContractlessOptions);
return postMessage.PostDataJson!.JsonTo<TestOrder>()!;
return postMessage.PostDataJson!.JsonTo<TestOrder_All_True>()!;
}
#endregion
@ -144,10 +144,10 @@ public class SignalRCommunicationBenchmarks
[Benchmark(Description = "Client: Deserialize complex Order response")]
[BenchmarkCategory("Client", "Response")]
public TestOrder? Client_DeserializeOrderResponse()
public TestOrder_All_True? Client_DeserializeOrderResponse()
{
var response = SignalRMessageFactory.DeserializeResponse(_complexResponseMessage);
return response?.ResponseData?.JsonTo<TestOrder>();
return response?.ResponseData?.JsonTo<TestOrder_All_True>();
}
#endregion
@ -171,19 +171,19 @@ public class SignalRCommunicationBenchmarks
[Benchmark(Description = "Full: Complex Order round-trip")]
[BenchmarkCategory("Full")]
public TestOrder? Full_ComplexOrderRoundTrip()
public TestOrder_All_True? Full_ComplexOrderRoundTrip()
{
// Client creates message
var requestBytes = SignalRMessageFactory.CreateComplexObjectMessage(_data.TestOrder);
// Server deserializes
var postMessage = MessagePackSerializer.Deserialize<SignalRPostMessageDto>(requestBytes, SignalRMessageFactory.ContractlessOptions);
var order = postMessage.PostDataJson!.JsonTo<TestOrder>()!;
var order = postMessage.PostDataJson!.JsonTo<TestOrder_All_True>()!;
// Server modifies and creates response
order.OrderNumber = "PROCESSED-" + order.OrderNumber;
var responseBytes = SignalRMessageFactory.CreateSuccessResponse(CommonSignalRTags.TestOrderParam, order);
// Client deserializes response
var response = SignalRMessageFactory.DeserializeResponse(responseBytes);
return response?.ResponseData?.JsonTo<TestOrder>();
return response?.ResponseData?.JsonTo<TestOrder_All_True>();
}
#endregion
}

View File

@ -24,9 +24,9 @@ public class SignalRRoundTripBenchmarks
private BenchmarkSignalRService _service = null!;
// Pre-created test data
private TestOrderItem _testOrderItem = null!;
private TestOrder _testOrder = null!;
private SharedTag _sharedTag = null!;
private TestOrderItem_All_True _testOrderItem = null!;
private TestOrder_All_True _testOrder = null!;
private SharedTag_All_True _sharedTag = null!;
private int[] _intArray = null!;
private List<string> _stringList = null!;
private Guid _testGuid;
@ -41,9 +41,9 @@ public class SignalRRoundTripBenchmarks
_hub.RegisterService(_service, _client);
// Pre-create test data
_testOrderItem = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
_testOrderItem = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
_testOrder = TestDataFactory.CreateOrder(itemCount: 3);
_sharedTag = new SharedTag { Id = 1, Name = "Important", Color = "#FF0000" };
_sharedTag = new SharedTag_All_True { Id = 1, Name = "Important", Color = "#FF0000" };
_intArray = [1, 2, 3, 4, 5];
_stringList = ["apple", "banana", "cherry"];
_testGuid = Guid.NewGuid();
@ -104,25 +104,25 @@ public class SignalRRoundTripBenchmarks
#region Complex Object Benchmarks
[Benchmark(Description = "RoundTrip: TestOrderItem")]
[Benchmark(Description = "RoundTrip: TestOrderItem_All_True")]
[BenchmarkCategory("Complex")]
public TestOrderItem? RoundTrip_TestOrderItem()
public TestOrderItem_All_True? RoundTrip_TestOrderItem()
{
return _client.PostDataSync<TestOrderItem, TestOrderItem>(BenchmarkSignalRTags.TestOrderItemParam, _testOrderItem);
return _client.PostDataSync<TestOrderItem_All_True, TestOrderItem_All_True>(BenchmarkSignalRTags.TestOrderItemParam, _testOrderItem);
}
[Benchmark(Description = "RoundTrip: TestOrder (3 items)")]
[Benchmark(Description = "RoundTrip: TestOrder_All_True (3 items)")]
[BenchmarkCategory("Complex")]
public TestOrder? RoundTrip_TestOrder()
public TestOrder_All_True? RoundTrip_TestOrder()
{
return _client.PostDataSync<TestOrder, TestOrder>(BenchmarkSignalRTags.TestOrderParam, _testOrder);
return _client.PostDataSync<TestOrder_All_True, TestOrder_All_True>(BenchmarkSignalRTags.TestOrderParam, _testOrder);
}
[Benchmark(Description = "RoundTrip: SharedTag")]
[Benchmark(Description = "RoundTrip: SharedTag_All_True")]
[BenchmarkCategory("Complex")]
public SharedTag? RoundTrip_SharedTag()
public SharedTag_All_True? RoundTrip_SharedTag()
{
return _client.PostDataSync<SharedTag, SharedTag>(BenchmarkSignalRTags.SharedTagParam, _sharedTag);
return _client.PostDataSync<SharedTag_All_True, SharedTag_All_True>(BenchmarkSignalRTags.SharedTagParam, _sharedTag);
}
#endregion
@ -278,7 +278,7 @@ public class BenchmarkSignalRService
public string HandleMultipleTypes(bool flag, string text, int number) => $"{flag}-{text}-{number}";
[SignalR(BenchmarkSignalRTags.TestOrderItemParam)]
public TestOrderItem HandleTestOrderItem(TestOrderItem item) => new()
public TestOrderItem_All_True HandleTestOrderItem(TestOrderItem_All_True item) => new()
{
Id = item.Id,
ProductName = $"Processed: {item.ProductName}",
@ -287,10 +287,10 @@ public class BenchmarkSignalRService
};
[SignalR(BenchmarkSignalRTags.TestOrderParam)]
public TestOrder HandleTestOrder(TestOrder order) => order;
public TestOrder_All_True HandleTestOrder(TestOrder_All_True order) => order;
[SignalR(BenchmarkSignalRTags.SharedTagParam)]
public SharedTag HandleSharedTag(SharedTag tag) => tag;
public SharedTag_All_True HandleSharedTag(SharedTag_All_True tag) => tag;
[SignalR(BenchmarkSignalRTags.IntArrayParam)]
public int[] HandleIntArray(int[] values) => values.Select(x => x * 2).ToArray();
@ -299,7 +299,7 @@ public class BenchmarkSignalRService
public List<string> HandleStringList(List<string> items) => items.Select(x => x.ToUpper()).ToList();
[SignalR(BenchmarkSignalRTags.IntAndDtoParam)]
public string HandleIntAndDto(int id, TestOrderItem item) => $"{id}-{item?.ProductName}";
public string HandleIntAndDto(int id, TestOrderItem_All_True item) => $"{id}-{item?.ProductName}";
[SignalR(BenchmarkSignalRTags.FiveParams)]
public string HandleFiveParams(int a, string b, bool c, Guid d, decimal e) => $"{a}-{b}-{c}-{d}-{e}";

View File

@ -739,12 +739,12 @@ internal static class BenchmarkLoop
}
/// <summary>
/// Validates MemoryPack setup at startup. Aborts the benchmark if TestOrder is not [MemoryPackable].
/// Validates MemoryPack setup at startup. Aborts the benchmark if TestOrder_All_True is not [MemoryPackable].
/// Without this attribute, MemoryPack falls back to runtime resolver (slower) — comparison would be INVALID.
/// </summary>
internal static void ValidateMemoryPackSetup()
{
var typesToCheck = new[] { typeof(TestOrder) };
var typesToCheck = new[] { typeof(TestOrder_All_True) };
foreach (var type in typesToCheck)
{

View File

@ -10,7 +10,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized;
@ -23,7 +23,7 @@ internal sealed class AcBinaryBenchmark : ISerializerBenchmark
public long SetupDeserializeAllocBytes => 0;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options);
public AcBinaryBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
_options = options;
@ -35,12 +35,12 @@ internal sealed class AcBinaryBenchmark : ISerializerBenchmark
public void Serialize() => AcBinarySerializer.Serialize(_order, _options);
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder>(_serialized, _options);
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_serialized, _options);
public bool VerifyRoundTrip()
{
var bytes = AcBinarySerializer.Serialize(_order, _options);
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, _options);
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -11,7 +11,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized;
private readonly ArrayBufferWriter<byte> _bufferWriter;
@ -25,7 +25,7 @@ internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
public long SetupDeserializeAllocBytes => 0;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options);
public AcBinaryBufferWriterBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryBufferWriterBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
_options = options;
@ -55,14 +55,14 @@ internal sealed class AcBinaryBufferWriterBenchmark : ISerializerBenchmark
// (the production-realistic surface for SignalR / Pipe consumers) rather than secretly testing
// byte[] Deser under the BufWr label.
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
public bool VerifyRoundTrip()
{
_bufferWriter.ResetWrittenCount();
AcBinarySerializer.Serialize(_order, _bufferWriter, _options);
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -14,7 +14,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized;
@ -27,7 +27,7 @@ internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
public long SetupDeserializeAllocBytes => 0;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B");
public AcBinaryFreshBufferWriterBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryFreshBufferWriterBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
// BufferWriterChunkSize comes from the caller (central source of truth in CreateSerializers
@ -51,13 +51,13 @@ internal sealed class AcBinaryFreshBufferWriterBenchmark : ISerializerBenchmark
// (the production-realistic surface for SignalR / Pipe consumers) rather than secretly testing
// byte[] Deser under the BufWr label.
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
public void Deserialize() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
public bool VerifyRoundTrip()
{
var abw = new ArrayBufferWriter<byte>();
AcBinarySerializer.Serialize(_order, abw, _options);
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
var roundTripped = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -26,7 +26,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDisposable
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized; // for SerializedSize reporting only
@ -57,7 +57,7 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
public bool IsRoundTripOnly => true;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=Pipe(in-memory,multiMessage,2-task)");
public AcBinaryInMemoryPipeBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryInMemoryPipeBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
_options = options;
@ -106,7 +106,7 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
try
{
var result = AcBinaryDeserializer.Deserialize<TestOrder>(_input, _options);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_input, _options);
if (_captureResult) _lastResult = result;
}
catch
@ -158,7 +158,7 @@ internal sealed class AcBinaryInMemoryPipeBenchmark : ISerializerBenchmark, IDis
try
{
Serialize();
var result = _lastResult as TestOrder;
var result = _lastResult as TestOrder_All_True;
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
}
finally

View File

@ -23,7 +23,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchmark, IDisposable
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized; // for SerializedSize reporting only
@ -48,7 +48,7 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
public bool IsRoundTripOnly => true;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=in-memory(raw,2-task)");
public AcBinaryInMemoryRawByteArrayBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryInMemoryRawByteArrayBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
_options = options;
@ -89,7 +89,7 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
var bytes = _pendingBytes;
if (bytes != null)
{
var result = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, _options);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, _options);
if (_captureResult) _lastResult = result;
}
}
@ -142,7 +142,7 @@ internal sealed class AcBinaryInMemoryRawByteArrayBenchmark : ISerializerBenchma
try
{
Serialize();
var result = _lastResult as TestOrder;
var result = _lastResult as TestOrder_All_True;
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
}
finally

View File

@ -41,7 +41,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDisposable
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized; // for SerializedSize reporting only
@ -72,7 +72,7 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
public bool IsRoundTripOnly => true;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=NamedPipe(long-lived,multiMessage,2-task)");
public AcBinaryNamedPipeBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryNamedPipeBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
// BufferWriterChunkSize comes from the caller (central source of truth in CreateSerializers
@ -152,7 +152,7 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
try
{
var result = AcBinaryDeserializer.Deserialize<TestOrder>(_input, _options);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(_input, _options);
if (_captureResult) _lastResult = result;
}
catch
@ -203,7 +203,7 @@ internal sealed class AcBinaryNamedPipeBenchmark : ISerializerBenchmark, IDispos
try
{
Serialize();
var result = _lastResult as TestOrder;
var result = _lastResult as TestOrder_All_True;
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
}
finally

View File

@ -27,7 +27,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchmark, IDisposable
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly AcBinarySerializerOptions _options;
private readonly byte[] _serialized; // for SerializedSize reporting + receive-side size known upfront
@ -59,7 +59,7 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
public bool IsRoundTripOnly => true;
public string OptionsDescription => BenchmarkOptions.BuildAcBinary(_options, $", BufferSize={_options.BufferWriterChunkSize}B, Transport=NamedPipe(raw,2-task)");
public AcBinaryNamedPipeRawByteArrayBenchmark(TestOrder order, AcBinarySerializerOptions options, string optionsPreset)
public AcBinaryNamedPipeRawByteArrayBenchmark(TestOrder_All_True order, AcBinarySerializerOptions options, string optionsPreset)
{
_order = order;
// BufferWriterChunkSize comes from the caller — same source-of-truth contract as
@ -125,7 +125,7 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
if (n == 0) break; // pipe closed / EOF — partial read swallowed
totalRead += n;
}
var result = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, _options);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, _options);
if (_captureResult) _lastResult = result;
}
catch
@ -183,7 +183,7 @@ internal sealed class AcBinaryNamedPipeRawByteArrayBenchmark : ISerializerBenchm
try
{
Serialize();
var result = _lastResult as TestOrder;
var result = _lastResult as TestOrder_All_True;
return result != null && BenchmarkLoop.DeepEqualsViaJson(_order, result);
}
finally

View File

@ -11,7 +11,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class MemoryPackBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly MemoryPackSerializerOptions _options;
private readonly byte[] _serialized;
@ -24,7 +24,7 @@ internal sealed class MemoryPackBenchmark : ISerializerBenchmark
public long SetupDeserializeAllocBytes => 0;
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
public MemoryPackBenchmark(TestOrder order, string optionsPreset)
public MemoryPackBenchmark(TestOrder_All_True order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
@ -36,12 +36,12 @@ internal sealed class MemoryPackBenchmark : ISerializerBenchmark
public void Serialize() => MemoryPackSerializer.Serialize(_order, _options);
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder>(_serialized, _options);
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder_All_True>(_serialized, _options);
public bool VerifyRoundTrip()
{
var bytes = MemoryPackSerializer.Serialize(_order, _options);
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder>(bytes, _options);
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder_All_True>(bytes, _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -12,7 +12,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly MemoryPackSerializerOptions _options;
private readonly byte[] _serialized;
private readonly ArrayBufferWriter<byte> _bufferWriter;
@ -26,7 +26,7 @@ internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
public long SetupDeserializeAllocBytes => 0;
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
public MemoryPackBufferWriterBenchmark(TestOrder order, string optionsPreset)
public MemoryPackBufferWriterBenchmark(TestOrder_All_True order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
@ -51,13 +51,13 @@ internal sealed class MemoryPackBufferWriterBenchmark : ISerializerBenchmark
// BufWr semantic: read from a ReadOnlySequence<byte> overload (apples-to-apples with AcBinary's
// BufWr Deser path). MemoryPack's ROS overload also single-segment-fast-paths internally.
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
public bool VerifyRoundTrip()
{
_bufferWriter.ResetWrittenCount();
MemoryPackSerializer.Serialize(_bufferWriter, _order, _options);
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_bufferWriter.WrittenMemory), _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -11,7 +11,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly MemoryPackSerializerOptions _options;
private readonly byte[] _serialized;
@ -24,7 +24,7 @@ internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmar
public long SetupDeserializeAllocBytes => 0;
public string? OptionsDescription => $"StringEncoding={_options.StringEncoding}";
public MemoryPackFreshBufferWriterBenchmark(TestOrder order, string optionsPreset)
public MemoryPackFreshBufferWriterBenchmark(TestOrder_All_True order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
@ -42,13 +42,13 @@ internal sealed class MemoryPackFreshBufferWriterBenchmark : ISerializerBenchmar
// BufWr semantic: read from a ReadOnlySequence<byte> overload (apples-to-apples with AcBinary's
// BufWr Deser path). MemoryPack's ROS overload also single-segment-fast-paths internally.
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(_serialized), _options);
public void Deserialize() => MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(_serialized), _options);
public bool VerifyRoundTrip()
{
var abw = new ArrayBufferWriter<byte>();
MemoryPackSerializer.Serialize(abw, _order, _options);
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
var roundTripped = MemoryPackSerializer.Deserialize<TestOrder_All_True>(new ReadOnlySequence<byte>(abw.WrittenMemory), _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -8,13 +8,13 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// <summary>
/// MessagePack benchmark, Byte[] I/O mode. Excluded from NativeAOT build because v3's StandardResolver
/// falls back to DynamicGenericResolver for closed-generic types (List&lt;TestOrderItem&gt; et al.),
/// falls back to DynamicGenericResolver for closed-generic types (List&lt;TestOrderItem_All_True&gt; et al.),
/// which uses Activator.CreateInstance on formatter types the AOT trimmer drops →
/// MissingMethodException at runtime. Available for regular JIT runs (<c>dotnet run</c>) only.
/// </summary>
internal sealed class MessagePackBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly MessagePackSerializerOptions _options;
private readonly byte[] _serialized;
@ -27,7 +27,7 @@ internal sealed class MessagePackBenchmark : ISerializerBenchmark
public long SetupDeserializeAllocBytes => 0;
public string OptionsDescription { get; }
public MessagePackBenchmark(TestOrder order, string optionsPreset)
public MessagePackBenchmark(TestOrder_All_True order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
@ -46,12 +46,12 @@ internal sealed class MessagePackBenchmark : ISerializerBenchmark
public void Serialize() => MessagePackSerializer.Serialize(_order, _options);
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => MessagePackSerializer.Deserialize<TestOrder>(_serialized, _options);
public void Deserialize() => MessagePackSerializer.Deserialize<TestOrder_All_True>(_serialized, _options);
public bool VerifyRoundTrip()
{
var bytes = MessagePackSerializer.Serialize(_order, _options);
var roundTripped = MessagePackSerializer.Deserialize<TestOrder>(bytes, _options);
var roundTripped = MessagePackSerializer.Deserialize<TestOrder_All_True>(bytes, _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -12,7 +12,7 @@ namespace AyCode.Core.Serializers.Console.Benchmarks;
/// </summary>
internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
{
private readonly TestOrder _order;
private readonly TestOrder_All_True _order;
private readonly JsonSerializerOptions _options;
private readonly string _serialized;
private readonly byte[] _serializedUtf8;
@ -25,7 +25,7 @@ internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
public long SetupSerializeAllocBytes => 0;
public long SetupDeserializeAllocBytes => 0;
public SystemTextJsonBenchmark(TestOrder order, string optionsPreset)
public SystemTextJsonBenchmark(TestOrder_All_True order, string optionsPreset)
{
_order = order;
OptionsPreset = optionsPreset;
@ -43,12 +43,12 @@ internal sealed class SystemTextJsonBenchmark : ISerializerBenchmark
public void Serialize() => JsonSerializer.Serialize(_order, _options);
[MethodImpl(MethodImplOptions.NoInlining)]
public void Deserialize() => JsonSerializer.Deserialize<TestOrder>(_serialized, _options);
public void Deserialize() => JsonSerializer.Deserialize<TestOrder_All_True>(_serialized, _options);
public bool VerifyRoundTrip()
{
var json = JsonSerializer.Serialize(_order, _options);
var roundTripped = JsonSerializer.Deserialize<TestOrder>(json, _options);
var roundTripped = JsonSerializer.Deserialize<TestOrder_All_True>(json, _options);
return BenchmarkLoop.DeepEqualsViaJson(_order, roundTripped);
}
}

View File

@ -5,7 +5,7 @@ using AyCode.Core.Tests.TestModels;
namespace AyCode.Core.Tests.GeneratedWriters;
/// <summary>
/// Hand-written generated binary writer for TestOrder.
/// Hand-written generated binary writer for TestOrder_All_True.
/// Demonstrates the pattern that the source generator will produce.
///
/// Bypasses the runtime switch/delegate property loop:
@ -27,15 +27,15 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter
int depth)
where TOutput : struct, IBinaryOutputBase
{
var obj = Unsafe.As<TestOrder>(value);
var obj = Unsafe.As<TestOrder_All_True>(value);
var nextDepth = depth;
// Properties in alphabetical order (matching runtime serializer):
// AuditMetadata: MetadataInfo? (complex, nullable)
// AuditMetadata: MetadataInfo_All_True? (complex, nullable)
WriteComplexOrNull(obj.AuditMetadata, context, nextDepth);
// Category: SharedCategory? (complex, nullable)
// Category: SharedCategory_All_True? (complex, nullable)
WriteComplexOrNull(obj.Category, context, nextDepth);
// CreatedAt: DateTime (markerless)
@ -44,16 +44,16 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter
// Id: int (markerless)
context.WriteVarInt(obj.Id);
// Items: List<TestOrderItem> (collection)
// Items: List<TestOrderItem_All_True> (collection)
WriteComplexOrNull(obj.Items, context, nextDepth);
// MetadataList: List<MetadataInfo> (collection)
// MetadataList: List<MetadataInfo_All_True> (collection)
WriteComplexOrNull(obj.MetadataList, context, nextDepth);
// NoMergeItems: List<TestOrderItem> (collection)
// NoMergeItems: List<TestOrderItem_All_True> (collection)
WriteComplexOrNull(obj.NoMergeItems, context, nextDepth);
// OrderMetadata: MetadataInfo? (complex, nullable)
// OrderMetadata: MetadataInfo_All_True? (complex, nullable)
WriteComplexOrNull(obj.OrderMetadata, context, nextDepth);
// OrderNumber: string
@ -74,16 +74,16 @@ internal sealed class TestOrderWriter : IGeneratedBinaryWriter
context.WriteByte(BinaryTypeCode.Null);
}
// PrimaryTag: SharedTag? (complex, nullable)
// PrimaryTag: SharedTag_All_True? (complex, nullable)
WriteComplexOrNull(obj.PrimaryTag, context, nextDepth);
// SecondaryTag: SharedTag? (complex, nullable)
// SecondaryTag: SharedTag_All_True? (complex, nullable)
WriteComplexOrNull(obj.SecondaryTag, context, nextDepth);
// Status: TestStatus (enum, markerless)
context.WriteVarInt((int)obj.Status);
// Tags: List<SharedTag> (collection)
// Tags: List<SharedTag_All_True> (collection)
WriteComplexOrNull(obj.Tags, context, nextDepth);
// TotalAmount: decimal (markerless)

View File

@ -116,7 +116,7 @@ public sealed class JsonExtensionTests
public void SemanticReference_SharedTag_SerializesWithSemanticId()
{
// Arrange
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var order = TestDataFactory.CreateOrder(itemCount: 2, sharedTag: sharedTag);
// Act
@ -133,7 +133,7 @@ public sealed class JsonExtensionTests
{
// Arrange
var sharedTag = TestDataFactory.CreateTag("OriginalKey");
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
@ -183,19 +183,19 @@ public sealed class JsonExtensionTests
public void NewtonsoftReference_DeepNestedNonId_HandlesCorrectly()
{
// Arrange
var rootMeta = new MetadataInfo
var rootMeta = new MetadataInfo_All_True
{
Key = "Root",
Value = "RootValue",
ChildMetadata = new MetadataInfo
ChildMetadata = new MetadataInfo_All_True
{
Key = "Child",
Value = "ChildValue",
ChildMetadata = new MetadataInfo { Key = "GrandChild", Value = "GrandChildValue" }
ChildMetadata = new MetadataInfo_All_True { Key = "GrandChild", Value = "GrandChildValue" }
}
};
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
@ -225,7 +225,7 @@ public sealed class JsonExtensionTests
var sharedMeta = TestDataFactory.CreateMetadata();
sharedTag.Description = sharedMeta.Key; // Link them
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
@ -234,7 +234,7 @@ public sealed class JsonExtensionTests
OrderMetadata = sharedMeta,
AuditMetadata = sharedMeta,
Tags = [sharedTag],
Items = [new TestOrderItem { Id = 10, ProductName = "A", Tag = sharedTag, ItemMetadata = sharedMeta }]
Items = [new TestOrderItem_All_True { Id = 10, ProductName = "A", Tag = sharedTag, ItemMetadata = sharedMeta }]
};
var json = order.ToJson();
@ -254,8 +254,8 @@ public sealed class JsonExtensionTests
// Arrange
var order = TestDataFactory.CreateOrder(itemCount: 1);
order.NoMergeItems = [
new TestOrderItem { Id = 100, ProductName = "NoMerge-A" },
new TestOrderItem { Id = 101, ProductName = "NoMerge-B" }
new TestOrderItem_All_True { Id = 100, ProductName = "NoMerge-A" },
new TestOrderItem_All_True { Id = 101, ProductName = "NoMerge-B" }
];
var originalRef = order.NoMergeItems;
@ -284,13 +284,13 @@ public sealed class JsonExtensionTests
public void NonIdCollection_ReplacesContent()
{
// Arrange
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
MetadataList = [
new MetadataInfo { Key = "Old-A" },
new MetadataInfo { Key = "Old-B" }
new MetadataInfo_All_True { Key = "Old-A" },
new MetadataInfo_All_True { Key = "Old-B" }
]
};
@ -367,7 +367,7 @@ public sealed class JsonExtensionTests
// Act
var json = order.ToJson();
var deserialized = json.JsonTo<TestOrder>();
var deserialized = json.JsonTo<TestOrder_All_True>();
// Assert
Assert.IsNotNull(deserialized);
@ -442,7 +442,7 @@ public sealed class JsonExtensionTests
[TestMethod]
public void WasmCompat_AcJsonSerializer_SimpleObject()
{
var item = new TestOrderItem { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 99.99m, Status = TestStatus.Processing };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 99.99m, Status = TestStatus.Processing };
var json = AcJsonSerializer.Serialize(item);
@ -453,10 +453,10 @@ public sealed class JsonExtensionTests
[TestMethod]
public void WasmCompat_AcJsonDeserializer_RoundTrip()
{
var original = new TestOrderItem { Id = 42, ProductName = "WASM Test", Quantity = 5, UnitPrice = 25.50m, Status = TestStatus.Shipped };
var original = new TestOrderItem_All_True { Id = 42, ProductName = "WASM Test", Quantity = 5, UnitPrice = 25.50m, Status = TestStatus.Shipped };
var json = AcJsonSerializer.Serialize(original);
var deserialized = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
var deserialized = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
Assert.IsNotNull(deserialized);
Assert.AreEqual(42, deserialized.Id);
@ -484,14 +484,14 @@ public sealed class JsonExtensionTests
[TestMethod]
public void WasmCompat_EmptyCollections_HandleCorrectly()
{
var order = new TestOrder { Id = 1, OrderNumber = "EMPTY-TEST", Items = [], Tags = [] };
var order = new TestOrder_All_True { Id = 1, OrderNumber = "EMPTY-TEST", Items = [], Tags = [] };
var json = AcJsonSerializer.Serialize(order);
Assert.IsTrue(json.Contains("\"Items\":[]"), "Empty Items should serialize as []");
Assert.IsTrue(json.Contains("\"Tags\":[]"), "Empty Tags should serialize as []");
var deserialized = AcJsonDeserializer.Deserialize<TestOrder>(json);
var deserialized = AcJsonDeserializer.Deserialize<TestOrder_All_True>(json);
Assert.IsNotNull(deserialized?.Items);
Assert.AreEqual(0, deserialized.Items.Count);
@ -513,8 +513,8 @@ public sealed class JsonExtensionTests
[TestMethod]
public void WasmCompat_SharedReferences_IdRefResolution()
{
var sharedTag = new SharedTag { Id = 999, Name = "SharedKey" };
var order = new TestOrder { Id = 1, OrderNumber = "REF-TEST", PrimaryTag = sharedTag, SecondaryTag = sharedTag, Tags = [sharedTag] };
var sharedTag = new SharedTag_All_True { Id = 999, Name = "SharedKey" };
var order = new TestOrder_All_True { Id = 1, OrderNumber = "REF-TEST", PrimaryTag = sharedTag, SecondaryTag = sharedTag, Tags = [sharedTag] };
var json = AcJsonSerializer.Serialize(order);
@ -528,7 +528,7 @@ public sealed class JsonExtensionTests
NullValueHandling = NullValueHandling.Ignore
};
var deserialized = JsonConvert.DeserializeObject<TestOrder>(json, nativeSettings);
var deserialized = JsonConvert.DeserializeObject<TestOrder_All_True>(json, nativeSettings);
Assert.IsNotNull(deserialized);
Assert.AreSame(deserialized.PrimaryTag, deserialized.SecondaryTag);
@ -543,10 +543,10 @@ public sealed class JsonExtensionTests
public void CrossSerializer_MixedReferences_CompatibleWithNewtonsoft()
{
// Arrange
var sharedTag = new SharedTag { Id = 100, Name = "SharedKey", CreatedAt = DateTime.UtcNow };
var sharedMeta = new MetadataInfo { Key = "SharedMeta", Value = "MetaValue", ChildMetadata = new MetadataInfo { Key = "Child" } };
var sharedTag = new SharedTag_All_True { Id = 100, Name = "SharedKey", CreatedAt = DateTime.UtcNow };
var sharedMeta = new MetadataInfo_All_True { Key = "SharedMeta", Value = "MetaValue", ChildMetadata = new MetadataInfo_All_True { Key = "Child" } };
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
@ -556,7 +556,7 @@ public sealed class JsonExtensionTests
OrderMetadata = sharedMeta,
AuditMetadata = sharedMeta,
Tags = [sharedTag],
Items = [new TestOrderItem { Id = 10, ProductName = "Product-A", Tag = sharedTag, ItemMetadata = sharedMeta }]
Items = [new TestOrderItem_All_True { Id = 10, ProductName = "Product-A", Tag = sharedTag, ItemMetadata = sharedMeta }]
};
// Act - Serialize with AyCode
@ -570,7 +570,7 @@ public sealed class JsonExtensionTests
NullValueHandling = NullValueHandling.Ignore
};
var deserialized = JsonConvert.DeserializeObject<TestOrder>(json, nativeSettings);
var deserialized = JsonConvert.DeserializeObject<TestOrder_All_True>(json, nativeSettings);
// Assert
Assert.IsNotNull(deserialized);
@ -589,11 +589,11 @@ public sealed class JsonExtensionTests
var json = @"{
""Id"": 1,
""OrderNumber"": ""ORD-001"",
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" },
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" },
""SecondaryTag"": { ""$ref"": ""1"" }
}";
var order = new TestOrder { Id = 1, OrderNumber = "OLD" };
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD" };
// Act
json.JsonTo(order);
@ -602,7 +602,7 @@ public sealed class JsonExtensionTests
Assert.IsNotNull(order.PrimaryTag, "PrimaryTag should be set");
Assert.IsNotNull(order.SecondaryTag, "SecondaryTag should be set from $ref");
Assert.AreEqual(100, order.PrimaryTag.Id);
Assert.AreEqual("SharedTag", order.PrimaryTag.Name);
Assert.AreEqual("SharedTag_All_True", order.PrimaryTag.Name);
Assert.AreSame(order.PrimaryTag, order.SecondaryTag,
"SecondaryTag should reference the same object as PrimaryTag via $ref");
}
@ -613,14 +613,14 @@ public sealed class JsonExtensionTests
var json = @"{
""Id"": 1,
""OrderNumber"": ""ORD-001"",
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" },
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" },
""Tags"": [
{ ""$ref"": ""1"" },
{ ""$id"": ""2"", ""Id"": 200, ""Name"": ""OtherTag"" }
]
}";
var order = new TestOrder { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag>() };
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag_All_True>() };
// Act
json.JsonTo(order);
@ -648,11 +648,11 @@ public sealed class JsonExtensionTests
""PrimaryTag"": { ""$ref"": ""1"" }
}";
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "OLD",
Items = new List<TestOrderItem> { new TestOrderItem { Id = 10, ProductName = "OLD" } }
Items = new List<TestOrderItem_All_True> { new TestOrderItem_All_True { Id = 10, ProductName = "OLD" } }
};
// Act
@ -672,10 +672,10 @@ public sealed class JsonExtensionTests
""Id"": 1,
""OrderNumber"": ""ORD-001"",
""SecondaryTag"": { ""$ref"": ""1"" },
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" }
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" }
}";
var order = new TestOrder { Id = 1, OrderNumber = "OLD" };
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD" };
// Act
json.JsonTo(order);
@ -693,7 +693,7 @@ public sealed class JsonExtensionTests
var json = @"{
""Id"": 1,
""OrderNumber"": ""ORD-001"",
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag"" },
""PrimaryTag"": { ""$id"": ""1"", ""Id"": 100, ""Name"": ""SharedTag_All_True"" },
""SecondaryTag"": { ""$ref"": ""1"" },
""Tags"": [
{ ""$ref"": ""1"" },
@ -702,7 +702,7 @@ public sealed class JsonExtensionTests
]
}";
var order = new TestOrder { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag>() };
var order = new TestOrder_All_True { Id = 1, OrderNumber = "OLD", Tags = new List<SharedTag_All_True>() };
// Act
json.JsonTo(order);
@ -731,10 +731,10 @@ public sealed class JsonExtensionTests
""PrimaryTag"": { ""$ref"": ""deep1"" }
}";
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
Items = new List<TestOrderItem> { new TestOrderItem { Id = 10 } }
Items = new List<TestOrderItem_All_True> { new TestOrderItem_All_True { Id = 10 } }
};
// Act
@ -762,10 +762,10 @@ public sealed class JsonExtensionTests
}]
}";
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
Items = new List<TestOrderItem> { new TestOrderItem { Id = 10 } }
Items = new List<TestOrderItem_All_True> { new TestOrderItem_All_True { Id = 10 } }
};
// Act
@ -789,7 +789,7 @@ public sealed class JsonExtensionTests
}";
// Act
var order = AcJsonDeserializer.Deserialize<TestOrder>(json);
var order = AcJsonDeserializer.Deserialize<TestOrder_All_True>(json);
// Assert
Assert.IsNotNull(order);
@ -820,7 +820,7 @@ public sealed class JsonExtensionTests
}";
// Act
var order = AcJsonDeserializer.Deserialize<TestOrder>(json);
var order = AcJsonDeserializer.Deserialize<TestOrder_All_True>(json);
// Assert
Assert.IsNotNull(order);
@ -841,8 +841,8 @@ public sealed class JsonExtensionTests
""SecondaryTag"": { ""$ref"": ""1"" }
}";
var existingTag = new SharedTag { Id = 999, Name = "ExistingTag" };
var order = new TestOrder
var existingTag = new SharedTag_All_True { Id = 999, Name = "ExistingTag" };
var order = new TestOrder_All_True
{
Id = 1,
SecondaryTag = existingTag
@ -1047,9 +1047,9 @@ public sealed class JsonExtensionTests
{
Id = 1,
Name = "Test",
Tag = new SharedTag { Id = 1, Name = "Tag" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag" }
};
// Using existing Tag property with Guid in SharedTag's CreatedAt
// Using existing Tag property with Guid in SharedTag_All_True's CreatedAt
var json = AcJsonSerializer.Serialize(obj);
@ -1240,8 +1240,8 @@ public sealed class JsonExtensionTests
public void Populate_ObjectToObject_PopulatesProperties()
{
var json = "{\"Name\": \"Updated\", \"Id\": 99}";
var obj = new SharedTag { Id = 1, Name = "Original" };
AcJsonDeserializer.Populate(json, obj, typeof(SharedTag));
var obj = new SharedTag_All_True { Id = 1, Name = "Original" };
AcJsonDeserializer.Populate(json, obj, typeof(SharedTag_All_True));
Assert.AreEqual(99, obj.Id);
Assert.AreEqual("Updated", obj.Name);
}
@ -1249,14 +1249,14 @@ public sealed class JsonExtensionTests
[TestMethod]
public void Deserialize_NullJson_ReturnsDefault()
{
var result = AcJsonDeserializer.Deserialize<TestOrderItem>("null");
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>("null");
Assert.IsNull(result);
}
[TestMethod]
public void Deserialize_EmptyJson_ReturnsDefault()
{
var result = AcJsonDeserializer.Deserialize<TestOrderItem>("");
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>("");
Assert.IsNull(result);
}
@ -1312,7 +1312,7 @@ public sealed class JsonExtensionTests
try
{
AcJsonDeserializer.Deserialize<TestOrderItem>(invalidJson);
AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(invalidJson);
Assert.Fail("Expected AcJsonDeserializationException");
}
catch (AcJsonDeserializationException)
@ -1329,7 +1329,7 @@ public sealed class JsonExtensionTests
try
{
AcJsonDeserializer.Deserialize<TestOrderItem>(doubleQuotedJson);
AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(doubleQuotedJson);
Assert.Fail("Expected AcJsonDeserializationException for double-serialized JSON");
}
catch (AcJsonDeserializationException ex)
@ -1346,7 +1346,7 @@ public sealed class JsonExtensionTests
try
{
AcJsonDeserializer.Deserialize<TestOrderItem>(arrayJson);
AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(arrayJson);
Assert.Fail("Expected AcJsonDeserializationException");
}
catch (AcJsonDeserializationException ex)
@ -1363,7 +1363,7 @@ public sealed class JsonExtensionTests
try
{
AcJsonDeserializer.Deserialize<List<TestOrderItem>>(objectJson);
AcJsonDeserializer.Deserialize<List<TestOrderItem_All_True>>(objectJson);
Assert.Fail("Expected AcJsonDeserializationException");
}
catch (AcJsonDeserializationException ex)
@ -1376,7 +1376,7 @@ public sealed class JsonExtensionTests
public void Populate_NullTarget_ThrowsArgumentNullException()
{
var json = "{\"Id\":1}";
TestOrderItem? target = null;
TestOrderItem_All_True? target = null;
try
{
@ -1392,7 +1392,7 @@ public sealed class JsonExtensionTests
[TestMethod]
public void Populate_InvalidJson_ThrowsException()
{
var target = new TestOrderItem();
var target = new TestOrderItem_All_True();
var invalidJson = "{ not valid }";
try
@ -1409,7 +1409,7 @@ public sealed class JsonExtensionTests
[TestMethod]
public void Populate_ArrayToNonList_ThrowsException()
{
var target = new TestOrderItem();
var target = new TestOrderItem_All_True();
var arrayJson = "[1,2,3]";
try
@ -1432,7 +1432,7 @@ public sealed class JsonExtensionTests
{
var json = "{\"Id\":1,\"ProductName\":\"Test \\\"quoted\\\" and \\\\backslash\"}";
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
Assert.IsNotNull(result);
Assert.AreEqual("Test \"quoted\" and \\backslash", result.ProductName);
@ -1443,7 +1443,7 @@ public sealed class JsonExtensionTests
{
var json = "{\"Id\":1,\"ProductName\":\"中文日本語한국어🎉\"}";
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
Assert.IsNotNull(result);
Assert.AreEqual("中文日本語한국어🎉", result.ProductName);
@ -1454,7 +1454,7 @@ public sealed class JsonExtensionTests
{
var json = "{\"Id\":999999999,\"ProductName\":\"Big\",\"Quantity\":2147483647}";
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
Assert.IsNotNull(result);
Assert.AreEqual(999999999, result.Id);
@ -1464,7 +1464,7 @@ public sealed class JsonExtensionTests
[TestMethod]
public void Serialize_ThenDeserialize_RoundTripPreservesData()
{
var original = new TestOrderItem
var original = new TestOrderItem_All_True
{
Id = 42,
ProductName = "Test with \"quotes\" and \\backslash",
@ -1474,7 +1474,7 @@ public sealed class JsonExtensionTests
};
var json = original.ToJson();
var restored = AcJsonDeserializer.Deserialize<TestOrderItem>(json);
var restored = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(json);
Assert.IsNotNull(restored);
Assert.AreEqual(original.Id, restored.Id);
@ -1491,12 +1491,12 @@ public sealed class JsonExtensionTests
[TestMethod]
public void Deserialize_TaskWrappedJson_DirectDeserialization_OnlyGetsRootProperties()
{
// This JSON represents a serialized Task<TestOrderItem> - the actual data is in "Result"
// This JSON represents a serialized Task<TestOrderItem_All_True> - the actual data is in "Result"
// This happens when someone forgets to await an async method before serializing
var taskWrappedJson = "{\"Result\":{\"Id\":1,\"ProductName\":\"Processed: TestProduct\",\"Quantity\":10,\"UnitPrice\":20,\"TotalPrice\":200},\"Id\":1,\"Status\":5,\"IsCompleted\":true,\"IsCompletedSuccessfully\":true}";
// Direct deserialization to TestOrderItem only gets root-level properties
var result = AcJsonDeserializer.Deserialize<TestOrderItem>(taskWrappedJson);
// Direct deserialization to TestOrderItem_All_True only gets root-level properties
var result = AcJsonDeserializer.Deserialize<TestOrderItem_All_True>(taskWrappedJson);
Assert.IsNotNull(result);
// Id=1 is at root level and matches
@ -1509,11 +1509,11 @@ public sealed class JsonExtensionTests
[TestMethod]
public void Deserialize_TaskWrappedJson_UseWrapperClass_ExtractsCorrectly()
{
// This JSON represents a serialized Task<TestOrderItem> - the actual data is in "Result"
// This JSON represents a serialized Task<TestOrderItem_All_True> - the actual data is in "Result"
var taskWrappedJson = "{\"Result\":{\"Id\":1,\"ProductName\":\"Processed: TestProduct\",\"Quantity\":10,\"UnitPrice\":20,\"TotalPrice\":200},\"Id\":1,\"Status\":5,\"IsCompleted\":true,\"IsCompletedSuccessfully\":true}";
// Proper approach: deserialize to a wrapper type and extract Result
var wrapper = AcJsonDeserializer.Deserialize<TaskResultWrapper<TestOrderItem>>(taskWrappedJson);
var wrapper = AcJsonDeserializer.Deserialize<TaskResultWrapper<TestOrderItem_All_True>>(taskWrappedJson);
Assert.IsNotNull(wrapper);
Assert.IsNotNull(wrapper.Result);

View File

@ -14,7 +14,7 @@ public class AcBinarySerializerBenchmarkTests
var binary = AcBinarySerializer.Serialize(order);
Assert.IsTrue(binary.Length > 0, "Binary data should not be empty");
var result = AcBinaryDeserializer.Deserialize<TestOrder>(binary);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binary);
Assert.IsNotNull(result);
Assert.AreEqual(order.Id, result.Id);
Assert.AreEqual(order.OrderNumber, result.OrderNumber);
@ -29,7 +29,7 @@ public class AcBinarySerializerBenchmarkTests
var binary = AcBinarySerializer.Serialize(order);
Assert.IsTrue(binary.Length > 0);
var result = AcBinaryDeserializer.Deserialize<TestOrder>(binary);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binary);
Assert.IsNotNull(result);
Assert.AreEqual(order.Id, result.Id);
}
@ -42,7 +42,7 @@ public class AcBinarySerializerBenchmarkTests
var binary = AcBinarySerializer.Serialize(order);
Assert.IsTrue(binary.Length > 0, "Binary data should not be empty");
var result = AcBinaryDeserializer.Deserialize<TestOrder>(binary);
var result = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binary);
Assert.IsNotNull(result);
Assert.AreEqual(order.Id, result.Id);
Assert.AreEqual(order.OrderNumber, result.OrderNumber);
@ -69,8 +69,8 @@ public class AcBinarySerializerBenchmarkTests
Console.WriteLine($"With interning: {binaryWithInterning.Length}, Without: {binaryWithoutInterning.Length}");
// Both should deserialize correctly regardless of size
var result1 = AcBinaryDeserializer.Deserialize<TestOrder>(binaryWithInterning);
var result2 = AcBinaryDeserializer.Deserialize<TestOrder>(binaryWithoutInterning);
var result1 = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binaryWithInterning);
var result2 = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binaryWithoutInterning);
Assert.IsNotNull(result1);
Assert.IsNotNull(result2);

View File

@ -20,7 +20,7 @@ public class AcBinarySerializerChainReferenceTests
public void ChainPopulate_IIdObjects_PreservesReferences()
{
// Setup: Create internal cache with 5 categories
var internalCache = new List<SharedCategory>
var internalCache = new List<SharedCategory_All_True>
{
new() { Id = 1, Name = "Category1", SortOrder = 1 },
new() { Id = 2, Name = "Category2", SortOrder = 2 },
@ -30,7 +30,7 @@ public class AcBinarySerializerChainReferenceTests
};
// Server returns subset of categories (like grid pagination - page 2: items 3-5)
var serverData = new List<SharedCategory>
var serverData = new List<SharedCategory_All_True>
{
new() { Id = 3, Name = "Category3_Updated", SortOrder = 33 },
new() { Id = 4, Name = "Category4_Updated", SortOrder = 44 },
@ -41,10 +41,10 @@ public class AcBinarySerializerChainReferenceTests
var binary = serverData.ToBinary();
// Grid's visible list (empty initially)
var gridVisibleList = new List<SharedCategory>();
var gridVisibleList = new List<SharedCategory_All_True>();
// CRITICAL: Use Chain API to parse once, populate both cache and grid
using var chain = binary.BinaryToChain<List<SharedCategory>>();
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
// First: Update internal cache (will become 3 items: 3-5 updated)
chain.ThenPopulate(internalCache);
@ -77,7 +77,7 @@ public class AcBinarySerializerChainReferenceTests
public void JsonChainPopulate_IIdObjects_PreservesReferences()
{
// Setup: Create internal cache
var internalCache = new List<SharedCategory>
var internalCache = new List<SharedCategory_All_True>
{
new() { Id = 1, Name = "Category1", SortOrder = 1 },
new() { Id = 2, Name = "Category2", SortOrder = 2 },
@ -85,7 +85,7 @@ public class AcBinarySerializerChainReferenceTests
};
// Server returns subset
var serverData = new List<SharedCategory>
var serverData = new List<SharedCategory_All_True>
{
new() { Id = 2, Name = "Category2_Updated", SortOrder = 22 },
new() { Id = 3, Name = "Category3_Updated", SortOrder = 33 }
@ -95,10 +95,10 @@ public class AcBinarySerializerChainReferenceTests
var json = serverData.ToJson();
// Grid's visible list
var gridVisibleList = new List<SharedCategory>();
var gridVisibleList = new List<SharedCategory_All_True>();
// Use JSON Chain API
using var chain = json.JsonToChain<List<SharedCategory>>();
using var chain = json.JsonToChain<List<SharedCategory_All_True>>();
// Update internal cache (will replace with 2 items)
chain.ThenPopulate(internalCache);
@ -163,22 +163,22 @@ public class AcBinarySerializerChainReferenceTests
{
// Large internal cache
var internalCache = Enumerable.Range(1, 10)
.Select(i => new SharedCategory { Id = i, Name = $"Category{i}", SortOrder = i * 10 })
.Select(i => new SharedCategory_All_True { Id = i, Name = $"Category{i}", SortOrder = i * 10 })
.ToList();
// Server returns items 3-7
var serverData = Enumerable.Range(3, 5)
.Select(i => new SharedCategory { Id = i, Name = $"Category{i}_Updated", SortOrder = i * 11 })
.Select(i => new SharedCategory_All_True { Id = i, Name = $"Category{i}_Updated", SortOrder = i * 11 })
.ToList();
var binary = serverData.ToBinary();
// Three different grid pages/views
var gridPage1 = new List<SharedCategory>();
var gridPage2 = new List<SharedCategory>();
var gridPage3 = new List<SharedCategory>();
var gridPage1 = new List<SharedCategory_All_True>();
var gridPage2 = new List<SharedCategory_All_True>();
var gridPage3 = new List<SharedCategory_All_True>();
using var chain = binary.BinaryToChain<List<SharedCategory>>();
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
// Update cache first
chain.ThenPopulate(internalCache);
@ -208,17 +208,17 @@ public class AcBinarySerializerChainReferenceTests
[TestMethod]
public void ChainPopulate_SimpleCase_Works()
{
var list1 = new List<SharedCategory>();
var list2 = new List<SharedCategory>();
var list1 = new List<SharedCategory_All_True>();
var list2 = new List<SharedCategory_All_True>();
var serverData = new List<SharedCategory>
var serverData = new List<SharedCategory_All_True>
{
new() { Id = 1, Name = "Cat1", SortOrder = 10 }
};
var binary = serverData.ToBinary();
using var chain = binary.BinaryToChain<List<SharedCategory>>();
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
// First populate
chain.ThenPopulate(list1);

View File

@ -96,9 +96,9 @@ public class AcBinarySerializerIIdReferenceTests
foreach (var mode in modes)
{
// Arrange: SAME instance used multiple times
var userPreferences = new UserPreferences();
var sharedTag = new SharedTag { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
var sharedUser = new SharedUser { Id = 1, Preferences = userPreferences };
var userPreferences = new UserPreferences_All_True();
var sharedTag = new SharedTag_All_True { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
var sharedUser = new SharedUser_All_True { Id = 1, Preferences = userPreferences };
var order = new TestOrder_Circ_Ref
{
@ -109,8 +109,8 @@ public class AcBinarySerializerIIdReferenceTests
Items =
[
new TestOrderItem_Circ_Ref { Id = 1, ProductName = "Product-A", Tag = sharedTag, Assignee = sharedUser },
new TestOrderItem_Circ_Ref { Id = 2, ProductName = "Product-B", Tag = sharedTag, Assignee = new SharedUser { Id = 2, Preferences = userPreferences }},
new TestOrderItem_Circ_Ref { Id = 3, ProductName = "Product-C", Tag = sharedTag, Assignee = new SharedUser { Id = 3, Preferences = userPreferences } }
new TestOrderItem_Circ_Ref { Id = 2, ProductName = "Product-B", Tag = sharedTag, Assignee = new SharedUser_All_True { Id = 2, Preferences = userPreferences }},
new TestOrderItem_Circ_Ref { Id = 3, ProductName = "Product-C", Tag = sharedTag, Assignee = new SharedUser_All_True { Id = 3, Preferences = userPreferences } }
]
};
@ -167,7 +167,7 @@ public class AcBinarySerializerIIdReferenceTests
break;
case ReferenceHandlingMode.All:
// IId types + Non-IId (UserPreferences) should have ObjectRefs
// IId types + Non-IId (UserPreferences_All_True) should have ObjectRefs
Assert.IsTrue(objectRefCount >= 4, $"[{mode}] Expected at least 4 ObjectRefs, found {objectRefCount}");
Assert.AreSame(result.PrimaryTag, result.Items[0].Tag, $"[{mode}] Tag reference identity failed");
Assert.AreSame(result.Owner, result.Items[0].Assignee, $"[{mode}] User reference identity failed");
@ -176,7 +176,7 @@ public class AcBinarySerializerIIdReferenceTests
Assert.AreSame(result.Parent, result.Items[1]);
// Non-IId should also have reference identity in All mode
Assert.AreSame(result.Owner.Preferences, result.Items[0].Assignee.Preferences, $"[{mode}] UserPreferences reference identity failed - Non-IId should work in All mode!");
Assert.AreSame(result.Owner.Preferences, result.Items[0].Assignee.Preferences, $"[{mode}] UserPreferences_All_True reference identity failed - Non-IId should work in All mode!");
break;
}
@ -207,44 +207,44 @@ public class AcBinarySerializerIIdReferenceTests
{
// Arrange: DIFFERENT instances but SAME IId.Id
// CRITICAL: Multiple DIFFERENT TYPES all have Id=1 - must not be confused!
var sharedTag = new SharedTag { Id = 55, Name = "ImportantTag_55", Color = "#FF0000" };
var order = new TestOrder
var sharedTag = new SharedTag_All_True { Id = 55, Name = "ImportantTag_55", Color = "#FF0000" };
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
// All three types have Id=1 - tests (Type, Id) keying, not just Id
PrimaryTag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Owner = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
Category = new SharedCategory { Id = 1, Name = "Category_Id1", SortOrder = 10 },
PrimaryTag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Owner = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
Category = new SharedCategory_All_True { Id = 1, Name = "Category_Id1", SortOrder = 10 },
Items =
[
new TestOrderItem
new TestOrderItem_All_True
{
Id = 1,
ProductName = "Product-A",
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
},
new TestOrderItem
new TestOrderItem_All_True
{
Id = 2,
ProductName = "Product-B",
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
},
new TestOrderItem
new TestOrderItem_All_True
{
Id = 3,
ProductName = "Product-C",
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
}
]
};
// Act
var binary = order.ToBinary();
var result = binary.BinaryTo<TestOrder>();
var result = binary.BinaryTo<TestOrder_All_True>();
// Assert 1: Check if ObjectRef is used (IId-based deduplication active)
var objectRefCount = CountObjectRefs(binary);
@ -254,11 +254,11 @@ public class AcBinarySerializerIIdReferenceTests
// Assert 3: Reference identity - same TYPE with same Id should be same reference
// Tags with Id=1 should all be same reference
Assert.AreSame(result.PrimaryTag, result.Items[0].Tag,
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
Assert.AreSame(result.PrimaryTag, result.Items[1].Tag,
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
Assert.AreSame(result.PrimaryTag, result.Items[2].Tag,
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
// Users with Id=1 should all be same reference
Assert.AreSame(result.Owner, result.Items[0].Assignee,
@ -325,38 +325,38 @@ public class AcBinarySerializerIIdReferenceTests
public void DifferentInstances_SameIId_SmallerBinaryWithDataIntegrity()
{
// Arrange: 10 different instances with SAME IId
var orderWithSameIId = new TestOrder
var orderWithSameIId = new TestOrder_All_True
{
Id = 1,
OrderNumber = "SAME-IID",
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
{
Id = i,
ProductName = $"Product-{i}",
// All have SAME IId.Id = 1, but DIFFERENT instances
Assignee = new SharedUser { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
Assignee = new SharedUser_All_True { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
}).ToList()
};
// Arrange: 10 different instances with DIFFERENT IIds
var orderWithDifferentIIds = new TestOrder
var orderWithDifferentIIds = new TestOrder_All_True
{
Id = 1,
OrderNumber = "DIFF-IID",
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
{
Id = i,
ProductName = $"Product-{i}",
// All have DIFFERENT IId.Id
Assignee = new SharedUser { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
Assignee = new SharedUser_All_True { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
}).ToList()
};
// Act
var sameIIdBinary = orderWithSameIId.ToBinary();
var diffIIdBinary = orderWithDifferentIIds.ToBinary();
var sameIIdResult = sameIIdBinary.BinaryTo<TestOrder>();
var diffIIdResult = diffIIdBinary.BinaryTo<TestOrder>();
var sameIIdResult = sameIIdBinary.BinaryTo<TestOrder_All_True>();
var diffIIdResult = diffIIdBinary.BinaryTo<TestOrder_All_True>();
// Assert 1: Size comparison
Console.WriteLine($"Same IId binary size: {sameIIdBinary.Length} bytes");
@ -506,15 +506,15 @@ public class AcBinarySerializerIIdReferenceTests
public void IIdDetection_Diagnostic()
{
// Test GetIdInfo directly
var sharedTagType = typeof(SharedTag);
var sharedTagType = typeof(SharedTag_All_True);
var idInfo = AyCode.Core.Helpers.JsonUtilities.GetIdInfo(sharedTagType);
Console.WriteLine($"SharedTag GetIdInfo: IsId={idInfo.IsId}, IdType={idInfo.IdType?.Name}");
Assert.IsTrue(idInfo.IsId, "SharedTag should be detected as IId<int>");
Assert.AreEqual(typeof(int), idInfo.IdType, "SharedTag Id type should be int");
Console.WriteLine($"SharedTag_All_True GetIdInfo: IsId={idInfo.IsId}, IdType={idInfo.IdType?.Name}");
Assert.IsTrue(idInfo.IsId, "SharedTag_All_True should be detected as IId<int>");
Assert.AreEqual(typeof(int), idInfo.IdType, "SharedTag_All_True Id type should be int");
// Test SharedUser
var sharedUserType = typeof(SharedUser);
var sharedUserType = typeof(SharedUser_All_True);
var userIdInfo = AyCode.Core.Helpers.JsonUtilities.GetIdInfo(sharedUserType);
Console.WriteLine($"SharedUser GetIdInfo: IsId={userIdInfo.IsId}, IdType={userIdInfo.IdType?.Name}");
Assert.IsTrue(userIdInfo.IsId, "SharedUser should be detected as IId<int>");
@ -532,7 +532,7 @@ public class AcBinarySerializerIIdReferenceTests
[TestMethod]
public void SharedCategory_DataIntegrity()
{
var categories = new List<SharedCategory>
var categories = new List<SharedCategory_All_True>
{
new() { Id = 1, Name = "Category1", SortOrder = 1, IsDefault = true },
new() { Id = 2, Name = "Category2", SortOrder = 2, ParentCategoryId = 1 },
@ -540,7 +540,7 @@ public class AcBinarySerializerIIdReferenceTests
};
var binary = categories.ToBinary();
var result = binary.BinaryTo<List<SharedCategory>>();
var result = binary.BinaryTo<List<SharedCategory_All_True>>();
Assert.IsNotNull(result);
Assert.AreEqual(3, result.Count);

View File

@ -150,7 +150,7 @@ public class AcBinarySerializerNamedPipeTests
return await receiveTask.ConfigureAwait(false);
}
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder order)
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder_All_True order)
{
var items = order.Items.Count;
int pallets = 0, measurements = 0, points = 0;

View File

@ -515,7 +515,7 @@ public class AcBinarySerializerPipeParallelTests
var pipe = new Pipe();
using var input = new AsyncPipeReaderInput(initialCapacity: opts.BufferWriterChunkSize * 2);
var deserTask = Task.Run(() => AcBinaryDeserializer.Deserialize<TestOrder>(input, opts));
var deserTask = Task.Run(() => AcBinaryDeserializer.Deserialize<TestOrder_All_True>(input, opts));
var drainTask = input.DrainFromAsync(pipe.Reader);
var serTask = Task.Run(async () =>
{
@ -541,7 +541,7 @@ public class AcBinarySerializerPipeParallelTests
Assert.AreEqual(origCounts.points, resultCounts.points, "Points count mismatch");
}
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder order)
private static (int items, int pallets, int measurements, int points) CountTestOrderHierarchy(TestOrder_All_True order)
{
var items = order.Items.Count;
int pallets = 0, measurements = 0, points = 0;

View File

@ -30,7 +30,7 @@ public class AcBinarySerializerSGenRuntimeCompatibilityTests
var expectedJson = JsonSerializer.Serialize(dataSet.Order, StjOptions);
var bytes = AcBinarySerializer.Serialize(dataSet.Order, serializeOptions);
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, deserializeOptions);
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, deserializeOptions);
var actualJson = JsonSerializer.Serialize(roundTrip, StjOptions);
Assert.AreEqual(expectedJson, actualJson, $"STJ mismatch. Dataset={dataSet.Name}, WireMode={serializeOptions.WireMode}, BaseOptions={serializeOptions.ReferenceHandling}/{serializeOptions.UseStringInterning}");
@ -56,7 +56,7 @@ public class AcBinarySerializerSGenRuntimeCompatibilityTests
var expectedJson = JsonSerializer.Serialize(dataSet.Order, StjOptions);
var bytes = AcBinarySerializer.Serialize(dataSet.Order, serializeOptions);
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, deserializeOptions);
var roundTrip = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, deserializeOptions);
var actualJson = JsonSerializer.Serialize(roundTrip, StjOptions);
Assert.AreEqual(expectedJson, actualJson, $"STJ mismatch. Dataset={dataSet.Name}, WireMode={serializeOptions.WireMode}, BaseOptions={serializeOptions.ReferenceHandling}/{serializeOptions.UseStringInterning}");
@ -97,7 +97,7 @@ public class AcBinarySerializerSGenRuntimeCompatibilityTests
};
}
private static void AssertOrderEquivalent(TestOrder expected, TestOrder? actual, string context)
private static void AssertOrderEquivalent(TestOrder_All_True expected, TestOrder_All_True? actual, string context)
{
Assert.IsNotNull(actual, context);
Assert.AreEqual(expected.Id, actual.Id, context);

View File

@ -22,7 +22,7 @@ public class AcExpressionNodeSerializationTests
public void AcJsonSerializer_WithAcExpressionNode_RoundTrip_Works()
{
// Arrange - Create an expression with a constant value
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
item => item.Quantity > 5;
var expressionNode = AcExpressionConverter.ToNode(filterExpression);
@ -39,11 +39,11 @@ public class AcExpressionNodeSerializationTests
Assert.IsNotNull(deserialized, "Deserialized node should not be null");
// Rebuild and test
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserialized);
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserialized);
var compiled = rebuiltExpression.Compile();
var matchingItem = new TestOrderItem { Id = 1, Quantity = 10 };
var nonMatchingItem = new TestOrderItem { Id = 2, Quantity = 3 };
var matchingItem = new TestOrderItem_All_True { Id = 1, Quantity = 10 };
var nonMatchingItem = new TestOrderItem_All_True { Id = 2, Quantity = 3 };
Assert.IsTrue(compiled(matchingItem), "Matching item should pass filter");
Assert.IsFalse(compiled(nonMatchingItem), "Non-matching item should fail filter");
@ -121,7 +121,7 @@ public class AcExpressionNodeSerializationTests
public void AcBinarySerializer_WithAcExpressionNode_RoundTrip_Works()
{
// Arrange
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
item => item.Quantity > 5;
var originalNode = AcExpressionConverter.ToNode(filterExpression);
@ -137,11 +137,11 @@ public class AcExpressionNodeSerializationTests
Assert.AreEqual(originalNode.NodeType, deserialized.NodeType);
// Rebuild and test
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserialized);
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserialized);
var compiled = rebuiltExpression.Compile();
var matchingItem = new TestOrderItem { Id = 1, Quantity = 10 };
var nonMatchingItem = new TestOrderItem { Id = 2, Quantity = 3 };
var matchingItem = new TestOrderItem_All_True { Id = 1, Quantity = 10 };
var nonMatchingItem = new TestOrderItem_All_True { Id = 2, Quantity = 3 };
Assert.IsTrue(compiled(matchingItem), "Matching item should pass filter");
Assert.IsFalse(compiled(nonMatchingItem), "Non-matching item should fail filter");
@ -183,7 +183,7 @@ public class AcExpressionNodeSerializationTests
{
// Arrange - Expression with captured decimal: item => item.UnitPrice > 99.99m
var minPrice = 99.99m;
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
item => item.UnitPrice > minPrice;
var originalNode = AcExpressionConverter.ToNode(filterExpression);
@ -195,11 +195,11 @@ public class AcExpressionNodeSerializationTests
// Assert - Rebuild and verify it still works with decimal comparison
Assert.IsNotNull(deserializedNode);
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserializedNode);
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserializedNode);
var compiledFilter = rebuiltExpression.Compile();
var expensiveItem = new TestOrderItem { UnitPrice = 150m };
var cheapItem = new TestOrderItem { UnitPrice = 50m };
var expensiveItem = new TestOrderItem_All_True { UnitPrice = 150m };
var cheapItem = new TestOrderItem_All_True { UnitPrice = 50m };
Assert.IsTrue(compiledFilter(expensiveItem), "Expensive item should pass filter");
Assert.IsFalse(compiledFilter(cheapItem), "Cheap item should fail filter");
@ -212,7 +212,7 @@ public class AcExpressionNodeSerializationTests
public void AcBinarySerializer_WithEnumValue_PreservesType()
{
// Arrange - Expression with enum comparison
System.Linq.Expressions.Expression<Func<TestOrderItem, bool>> filterExpression =
System.Linq.Expressions.Expression<Func<TestOrderItem_All_True, bool>> filterExpression =
item => item.Status == TestStatus.Completed;
var originalNode = AcExpressionConverter.ToNode(filterExpression);
@ -224,11 +224,11 @@ public class AcExpressionNodeSerializationTests
// Assert
Assert.IsNotNull(deserializedNode);
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(deserializedNode);
var rebuiltExpression = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(deserializedNode);
var compiledFilter = rebuiltExpression.Compile();
var completedItem = new TestOrderItem { Status = TestStatus.Completed };
var pendingItem = new TestOrderItem { Status = TestStatus.Pending };
var completedItem = new TestOrderItem_All_True { Status = TestStatus.Completed };
var pendingItem = new TestOrderItem_All_True { Status = TestStatus.Pending };
Assert.IsTrue(compiledFilter(completedItem), "Completed item should pass filter");
Assert.IsFalse(compiledFilter(pendingItem), "Pending item should fail filter");

View File

@ -46,25 +46,25 @@ public class AcJsonSerializerIIdReferenceTests
public void SameInstance_Json_SerializeAndDeserialize()
{
// Arrange: SAME instance used 4 times
var sharedTag = new SharedTag { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
var sharedTag = new SharedTag_All_True { Id = 1, Name = "ImportantTag", Color = "#FF0000" };
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
PrimaryTag = sharedTag,
Items =
[
new TestOrderItem { Id = 1, ProductName = "Product-A", Tag = sharedTag },
new TestOrderItem { Id = 2, ProductName = "Product-B", Tag = sharedTag },
new TestOrderItem { Id = 3, ProductName = "Product-C", Tag = sharedTag }
new TestOrderItem_All_True { Id = 1, ProductName = "Product-A", Tag = sharedTag },
new TestOrderItem_All_True { Id = 2, ProductName = "Product-B", Tag = sharedTag },
new TestOrderItem_All_True { Id = 3, ProductName = "Product-C", Tag = sharedTag }
]
};
// Act
var json = order.ToJson();
Console.WriteLine(json);
var result = json.JsonTo<TestOrder>();
var result = json.JsonTo<TestOrder_All_True>();
// Assert 1: JSON contains $ref markers (reference handling is active)
var refCount = CountOccurrences(json, "{\"$ref\":\"1\"}");
@ -118,43 +118,43 @@ public class AcJsonSerializerIIdReferenceTests
{
// Arrange: DIFFERENT instances but SAME IId.Id
// CRITICAL: Multiple DIFFERENT TYPES all have Id=1 - must not be confused!
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = 1,
OrderNumber = "ORD-001",
// All three types have Id=1 - tests (Type, Id) keying, not just Id
PrimaryTag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Owner = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
Category = new SharedCategory { Id = 1, Name = "Category_Id1", SortOrder = 10 },
PrimaryTag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Owner = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" },
Category = new SharedCategory_All_True { Id = 1, Name = "Category_Id1", SortOrder = 10 },
Items =
[
new TestOrderItem
new TestOrderItem_All_True
{
Id = 1,
ProductName = "Product-A",
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
},
new TestOrderItem
new TestOrderItem_All_True
{
Id = 2,
ProductName = "Product-B",
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
},
new TestOrderItem
new TestOrderItem_All_True
{
Id = 3,
ProductName = "Product-C",
Tag = new SharedTag { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
Tag = new SharedTag_All_True { Id = 1, Name = "Tag_Id1", Color = "#FF0000" },
Assignee = new SharedUser_All_True { Id = 1, Username = "User_Id1", Email = "user1@test.com" }
}
]
};
// Act
var json = order.ToJson();
var result = json.JsonTo<TestOrder>();
var result = json.JsonTo<TestOrder_All_True>();
// Assert 1: Check if $ref is used (IId-based deduplication active)
var refCount = CountOccurrences(json, "\"$ref\"");
@ -208,11 +208,11 @@ public class AcJsonSerializerIIdReferenceTests
// Assert 3: Reference identity - same TYPE with same Id should be same reference
// Tags with Id=1 should all be same reference
Assert.AreSame(result.PrimaryTag, result.Items[0].Tag,
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
"CRITICAL: Item[0].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
Assert.AreSame(result.PrimaryTag, result.Items[1].Tag,
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
"CRITICAL: Item[1].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
Assert.AreSame(result.PrimaryTag, result.Items[2].Tag,
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag.Id=1)");
"CRITICAL: Item[2].Tag should be same reference as PrimaryTag (same SharedTag_All_True.Id=1)");
// Users with Id=1 should all be same reference
Assert.AreSame(result.Owner, result.Items[0].Assignee,
@ -238,36 +238,36 @@ public class AcJsonSerializerIIdReferenceTests
public void DifferentInstances_SameIId_SmallerJsonWithDataIntegrity()
{
// Arrange: 10 different instances with SAME IId
var orderWithSameIId = new TestOrder
var orderWithSameIId = new TestOrder_All_True
{
Id = 1,
OrderNumber = "SAME-IID",
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
{
Id = i,
ProductName = $"Product-{i}",
Assignee = new SharedUser { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
Assignee = new SharedUser_All_True { Id = 1, Username = "shared_user_name", Email = "shared@test.com" }
}).ToList()
};
// Arrange: 10 different instances with DIFFERENT IIds
var orderWithDifferentIIds = new TestOrder
var orderWithDifferentIIds = new TestOrder_All_True
{
Id = 1,
OrderNumber = "DIFF-IID",
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem
Items = Enumerable.Range(1, 10).Select(i => new TestOrderItem_All_True
{
Id = i,
ProductName = $"Product-{i}",
Assignee = new SharedUser { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
Assignee = new SharedUser_All_True { Id = i * 100, Username = "unique_user_name", Email = "unique@test.com" }
}).ToList()
};
// Act
var sameIIdJson = orderWithSameIId.ToJson();
var diffIIdJson = orderWithDifferentIIds.ToJson();
var sameIIdResult = sameIIdJson.JsonTo<TestOrder>();
var diffIIdResult = diffIIdJson.JsonTo<TestOrder>();
var sameIIdResult = sameIIdJson.JsonTo<TestOrder_All_True>();
var diffIIdResult = diffIIdJson.JsonTo<TestOrder_All_True>();
// Assert 1: Size comparison
Console.WriteLine($"Same IId JSON size: {sameIIdJson.Length} chars");
@ -416,7 +416,7 @@ public class AcJsonSerializerIIdReferenceTests
[TestMethod]
public void SharedCategory_DataIntegrity()
{
var categories = new List<SharedCategory>
var categories = new List<SharedCategory_All_True>
{
new() { Id = 1, Name = "Category1", SortOrder = 1, IsDefault = true },
new() { Id = 2, Name = "Category2", SortOrder = 2, ParentCategoryId = 1 },
@ -424,7 +424,7 @@ public class AcJsonSerializerIIdReferenceTests
};
var json = categories.ToJson();
var result = json.JsonTo<List<SharedCategory>>();
var result = json.JsonTo<List<SharedCategory_All_True>>();
Assert.IsNotNull(result);
Assert.AreEqual(3, result.Count);

View File

@ -13,7 +13,7 @@ public class ChainReferenceDebugTest
// Test ChainReferenceTracker directly
var tracker = new AcSerializerCommon.ChainReferenceTracker();
var category = new SharedCategory { Id = 100, Name = "TestCategory" };
var category = new SharedCategory_All_True { Id = 100, Name = "TestCategory" };
// Register using reflection (like ThenPopulate does)
tracker.TryRegisterIIdObject(category);
@ -32,17 +32,17 @@ public class ChainReferenceDebugTest
[TestMethod]
public void DebugSimpleChainPopulate()
{
var list1 = new List<SharedCategory>();
var list2 = new List<SharedCategory>();
var list1 = new List<SharedCategory_All_True>();
var list2 = new List<SharedCategory_All_True>();
var serverData = new List<SharedCategory>
var serverData = new List<SharedCategory_All_True>
{
new() { Id = 1, Name = "Cat1", SortOrder = 10 }
};
var binary = serverData.ToBinary();
using var chain = binary.BinaryToChain<List<SharedCategory>>();
using var chain = binary.BinaryToChain<List<SharedCategory_All_True>>();
// First populate
chain.ThenPopulate(list1);

View File

@ -103,7 +103,7 @@ public class GeneratedSerializerIntegrationTests
public void GeneratedWriter_ComplexHierarchy_RoundTrip()
{
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var order = TestDataFactory.CreateOrder(
@ -116,7 +116,7 @@ public class GeneratedSerializerIntegrationTests
var options = AcBinarySerializerOptions.FastMode;
var bytes = AcBinarySerializer.Serialize(order, options);
var deserialized = AcBinaryDeserializer.Deserialize<TestOrder>(bytes, options);
var deserialized = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(bytes, options);
Assert.IsNotNull(deserialized);
Assert.AreEqual(order.Id, deserialized.Id);

View File

@ -83,12 +83,12 @@ public class QuickBenchmark
Console.WriteLine($"[WARN] Deserialize: AcBinary is {deserRatio:F2}x slower");
}
private static TestOrder CreatePopulateTarget(TestOrder source)
private static TestOrder_All_True CreatePopulateTarget(TestOrder_All_True source)
{
var target = new TestOrder { Id = source.Id };
var target = new TestOrder_All_True { Id = source.Id };
foreach (var item in source.Items)
{
target.Items.Add(new TestOrderItem { Id = item.Id });
target.Items.Add(new TestOrderItem_All_True { Id = item.Id });
}
return target;
}
@ -105,7 +105,7 @@ public class QuickBenchmark
for (int i = 0; i < 10; i++)
{
var bytes = order.ToBinary();
var result = bytes.BinaryTo<TestOrder>();
var result = bytes.BinaryTo<TestOrder_All_True>();
}
// Measure serialize
@ -121,10 +121,10 @@ public class QuickBenchmark
// Measure deserialize
sw.Restart();
TestOrder? deserialized = null;
TestOrder_All_True? deserialized = null;
for (int i = 0; i < iterations; i++)
{
deserialized = serialized.BinaryTo<TestOrder>();
deserialized = serialized.BinaryTo<TestOrder_All_True>();
}
sw.Stop();
var deserializeMs = sw.Elapsed.TotalMilliseconds;
@ -143,7 +143,7 @@ public class QuickBenchmark
sw.Restart();
for (int i = 0; i < iterations; i++)
{
var _ = json.JsonTo<TestOrder>(jsonOptions);
var _ = json.JsonTo<TestOrder_All_True>(jsonOptions);
}
sw.Stop();
var jsonDeserializeMs = sw.Elapsed.TotalMilliseconds;
@ -234,9 +234,9 @@ public class QuickBenchmark
for (int i = 0; i < 20; i++)
{
var binBytes = AcBinarySerializer.Serialize(order, AcBinarySerializerOptions.Default);
var binResult = AcBinaryDeserializer.Deserialize<TestOrder>(binBytes);
var binResult = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binBytes);
var msgBytes = MessagePackSerializer.Serialize(order, MsgPackOptions);
var msgResult = MessagePackSerializer.Deserialize<TestOrder>(msgBytes, MsgPackOptions);
var msgResult = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgBytes, MsgPackOptions);
}
const int iterations = DefaultIterations;
@ -263,20 +263,20 @@ public class QuickBenchmark
// === AcBinary Deserialize ===
sw.Restart();
TestOrder? acBinaryResult = null;
TestOrder_All_True? acBinaryResult = null;
for (int i = 0; i < iterations; i++)
{
acBinaryResult = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryData);
acBinaryResult = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryData);
}
sw.Stop();
var acBinaryDeserMs = sw.Elapsed.TotalMilliseconds;
// === MessagePack Deserialize ===
sw.Restart();
TestOrder? msgPackResult = null;
TestOrder_All_True? msgPackResult = null;
for (int i = 0; i < iterations; i++)
{
msgPackResult = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, MsgPackOptions);
msgPackResult = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, MsgPackOptions);
}
sw.Stop();
var msgPackDeserMs = sw.Elapsed.TotalMilliseconds;
@ -382,7 +382,7 @@ public class QuickBenchmark
public void GetAnalyzeStringInternCandidatesLog()
{
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
@ -413,7 +413,7 @@ public class QuickBenchmark
{
// Create test data with shared references
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
@ -492,7 +492,7 @@ public class QuickBenchmark
// Create test data with shared references
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
@ -532,10 +532,10 @@ public class QuickBenchmark
_ = MessagePackSerializer.Serialize(testOrder, MsgPackOptions);
Console.WriteLine("acBinaryWithRef");
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryWithRef);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryWithRef);
Console.WriteLine("acBinaryNoRef");
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryNoRef);
_ = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, MsgPackOptions);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryNoRef);
_ = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, MsgPackOptions);
}
// Wait for tiered JIT background compilation to complete
@ -573,19 +573,19 @@ public class QuickBenchmark
// === Deserialize WithRef ===
sw.Restart();
for (int i = 0; i < DefaultIterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryWithRef);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryWithRef);
var acWithRefDeserMs = sw.Elapsed.TotalMilliseconds;
// === Deserialize NoRef ===
sw.Restart();
for (int i = 0; i < DefaultIterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(acBinaryNoRef);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(acBinaryNoRef);
var acNoRefDeserMs = sw.Elapsed.TotalMilliseconds;
// === MessagePack Deserialize ===
sw.Restart();
for (int i = 0; i < DefaultIterations; i++)
_ = MessagePackSerializer.Deserialize<TestOrder>(msgPackData, MsgPackOptions);
_ = MessagePackSerializer.Deserialize<TestOrder_All_True>(msgPackData, MsgPackOptions);
var msgPackDeserMs = sw.Elapsed.TotalMilliseconds;
// === Populate (AcBinary only) ===
@ -632,7 +632,7 @@ public class QuickBenchmark
// Create test data WITH shared references (to show WithRef advantage)
TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
@ -685,13 +685,13 @@ public class QuickBenchmark
// Deserialize WithRef
sw.Restart();
for (int i = 0; i < DefaultIterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(withRefData);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(withRefData);
var withRefDeserMs = sw.Elapsed.TotalMilliseconds;
// Deserialize NoRef
sw.Restart();
for (int i = 0; i < DefaultIterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(noRefData);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(noRefData);
var noRefDeserMs = sw.Elapsed.TotalMilliseconds;
PrintBanner("PERFORMANCE COMPARISON (ms)");
@ -709,8 +709,8 @@ public class QuickBenchmark
}
// Verify correctness
var resultWithRef = AcBinaryDeserializer.Deserialize<TestOrder>(withRefData);
var resultNoRef = AcBinaryDeserializer.Deserialize<TestOrder>(noRefData);
var resultWithRef = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(withRefData);
var resultNoRef = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(noRefData);
Assert.IsNotNull(resultWithRef);
Assert.IsNotNull(resultNoRef);
Assert.AreEqual(testOrder.Id, resultWithRef.Id);
@ -755,7 +755,7 @@ public class QuickBenchmark
// Deserialize (creates new object)
sw.Restart();
for (int i = 0; i < DefaultIterations; i++)
_ = AcBinaryDeserializer.Deserialize<TestOrder>(binaryData);
_ = AcBinaryDeserializer.Deserialize<TestOrder_All_True>(binaryData);
var deserializeMs = sw.Elapsed.TotalMilliseconds;
// Populate (reuses existing object)

View File

@ -18,7 +18,7 @@ namespace AyCode.Core.Tests.TestModels;
/// </summary>
public static class CharsetSuffixes
{
/// <summary>Empty suffix — short Hungarian baseline strings (e.g. "SharedTag") stay short, hitting
/// <summary>Empty suffix — short Hungarian baseline strings (e.g. "SharedTag_All_True") stay short, hitting
/// the FixStr fast-path. Stress-test for FixStr / short-string code paths. Note: the baseline
/// property values remain Hungarian; only the suffix is empty. Despite the "FixAscii" name, this
/// option does NOT change baseline values to ASCII — it suppresses the suffix that would otherwise
@ -82,7 +82,7 @@ public static class BenchmarkTestDataProvider
{
if (resetId) TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var order = TestDataFactory.CreateOrder(
@ -104,11 +104,11 @@ public static class BenchmarkTestDataProvider
{
if (resetId) TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedMeta = TestDataFactory.CreateMetadata("shared", withChild: true);
var sharedPreferences = new UserPreferences
var sharedPreferences = new UserPreferences_All_True
{
Theme = "dark",
Language = "hungarian",
@ -138,10 +138,10 @@ public static class BenchmarkTestDataProvider
{
if (resetId) TestDataFactory.ResetIdCounter();
var sharedTag = TestDataFactory.CreateTag("SharedTag");
var sharedTag = TestDataFactory.CreateTag("SharedTag_All_True");
var sharedUser = TestDataFactory.CreateUser("shareduser");
var sharedPreferences = new UserPreferences
var sharedPreferences = new UserPreferences_All_True
{
Theme = "light",
Language = "german",
@ -173,7 +173,7 @@ public static class BenchmarkTestDataProvider
var sharedTag = TestDataFactory.CreateTag("RepeatedTag");
var sharedUser = TestDataFactory.CreateUser("repeateduser");
var sharedPreferences = new UserPreferences
var sharedPreferences = new UserPreferences_All_True
{
Theme = "dark",
Language = "hungarian",
@ -223,7 +223,7 @@ public static class BenchmarkTestDataProvider
var sharedUser = TestDataFactory.CreateUser("deepuser");
var sharedCategory = TestDataFactory.CreateCategory("DeepCategory");
var sharedPreferences = new UserPreferences
var sharedPreferences = new UserPreferences_All_True
{
Theme = "light",
Language = "french",
@ -249,7 +249,7 @@ public static class BenchmarkTestDataProvider
return new TestDataSet("Deep Nested (2x4x4x8)", order, iidRefPercent: 20);
}
private static void ClearDeepLevelRefs(TestOrder order)
private static void ClearDeepLevelRefs(TestOrder_All_True order)
{
// Keep shared IId refs at the pallet level (Tag + Inspector) — these contribute the bulk of
// the ~20% IId-ref share that the test data targets. Only Category is cleared at this level
@ -338,10 +338,10 @@ public static class BenchmarkTestDataProvider
}
}
public sealed class TestDataSet
public class TestDataSet<TOrder>
{
public string Name { get; }
public TestOrder Order { get; }
public TOrder Order { get; }
/// <summary>
/// Percentage of IId shared references in the data (0-100).
@ -349,7 +349,7 @@ public sealed class TestDataSet
/// </summary>
public int IIdRefPercent { get; }
public TestDataSet(string name, TestOrder order, int iidRefPercent = 0)
public TestDataSet(string name, TOrder order, int iidRefPercent = 0)
{
Name = name;
Order = order;
@ -365,3 +365,11 @@ public sealed class TestDataSet
? $"{Name} [{IIdRefPercent}% IId refs]"
: Name;
}
public sealed class TestDataSet : TestDataSet<TestOrder_All_True>
{
public TestDataSet(string name, TestOrder_All_True order, int iidRefPercent = 0)
: base(name, order, iidRefPercent)
{
}
}

View File

@ -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

View File

@ -48,208 +48,12 @@ public enum TestUserRole
#endregion
#region Shared Reference Types (IId-based for $id/$ref testing)
/// <summary>
/// Shared tag/label - used across multiple entities for cross-reference testing.
/// Implements IId&lt;int&gt; for semantic $id/$ref serialization.
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class SharedTag : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string Name { get; set; } = "";
[AcStringIntern(true)]
[Key(2)]
public string Color { get; set; } = "#000000";
[Key(3)]
public int Priority { get; set; }
[Key(4)]
public bool IsActive { get; set; } = true;
[Key(5)]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
[Key(6)]
public string? Description { get; set; }
}
/// <summary>
/// Shared category - for hierarchical cross-reference testing.
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class SharedCategory : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string Name { get; set; } = "";
[Key(2)]
public string? Description { get; set; }
[Key(3)]
public int SortOrder { get; set; }
[Key(4)]
public bool IsDefault { get; set; }
[Key(5)]
public int? ParentCategoryId { get; set; }
[Key(6)]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
[Key(7)]
public DateTime? UpdatedAt { get; set; }
}
/// <summary>
/// Shared user reference - appears in many places to test $ref deduplication.
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class SharedUser : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string Username { get; set; } = "";
[Key(2)]
public string Email { get; set; } = "";
[Key(3)]
public string FirstName { get; set; } = "";
[Key(4)]
public string LastName { get; set; } = "";
[Key(5)]
public bool IsActive { get; set; } = true;
[Key(6)]
public TestUserRole Role { get; set; } = TestUserRole.User;
[Key(7)]
public DateTime? LastLoginAt { get; set; }
[Key(8)]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
[Key(9)]
public UserPreferences? Preferences { get; set; }
}
/// <summary>
/// User preferences - non-IId nested object
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class UserPreferences
{
[AcStringIntern(true)]
[Key(0)]
public string Theme { get; set; } = "light";
[AcStringIntern(true)]
[Key(1)]
public string Language { get; set; } = "en-US";
[Key(2)]
public bool NotificationsEnabled { get; set; } = true;
[AcStringIntern(true)]
[Key(3)]
public string? EmailDigestFrequency { get; set; }
}
#endregion
#region Non-IId Metadata (Newtonsoft numeric $id/$ref testing)
/// <summary>
/// Non-IId metadata class - uses Newtonsoft PreserveReferencesHandling (numeric $id/$ref).
/// Does NOT implement IId, so uses standard Newtonsoft reference tracking.
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class MetadataInfo
{
[AcStringIntern(true)]
[Key(0)]
public string Key { get; set; } = "";
[AcStringIntern(true)]
[Key(1)]
public string Value { get; set; } = "";
[Key(2)]
public DateTime Timestamp { get; set; } = DateTime.UtcNow;
/// <summary>
/// Nested metadata for deep Newtonsoft reference testing
/// </summary>
[Key(3)]
public MetadataInfo? ChildMetadata { get; set; }
}
#endregion
#region 5-Level Test Hierarchy (Order -> Item -> Pallet -> Measurement -> Point)
/// <summary>
/// Level 1: Main order - root of the hierarchy
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class TestOrder : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string OrderNumber { get; set; } = "";
[Key(2)]
public TestStatus Status { get; set; } = TestStatus.Pending;
[Key(3)]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
[Key(4)]
public DateTime? PaidDateUtc { get; set; }
[Key(5)]
public decimal TotalAmount { get; set; }
// Level 2 collection
[Key(6)]
public List<TestOrderItem> Items { get; set; } = [];
// Shared reference properties (for $id/$ref testing)
[Key(7)]
public SharedTag? PrimaryTag { get; set; }
[Key(8)]
public SharedTag? SecondaryTag { get; set; }
[Key(9)]
public SharedUser? Owner { get; set; }
[Key(10)]
public SharedCategory? Category { get; set; }
// Collection of shared references
[Key(11)]
public List<SharedTag> Tags { get; set; } = [];
// Non-IId metadata (for Newtonsoft $ref testing)
[Key(12)]
public MetadataInfo? OrderMetadata { get; set; }
[Key(13)]
public MetadataInfo? AuditMetadata { get; set; }
[Key(14)]
public List<MetadataInfo> MetadataList { get; set; } = [];
// NoMerge collection for testing replace behavior
[JsonNoMergeCollection]
[Key(15)]
public List<TestOrderItem> NoMergeItems { get; set; } = [];
// Parent reference - ignored by all serializers to prevent circular references
[MemoryPackIgnore]
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public object? Parent { get; set; }
}
/// <summary>
/// Level 1: Main order - root of the hierarchy
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public partial class TestOrder_Circ_Ref : IId<int>
{
public int Id { get; set; }
@ -263,16 +67,16 @@ public partial class TestOrder_Circ_Ref : IId<int>
public List<TestOrderItem_Circ_Ref> Items { get; set; } = [];
// Shared reference properties (for $id/$ref testing)
public SharedTag? PrimaryTag { get; set; }
public SharedTag? SecondaryTag { get; set; }
public SharedUser? Owner { get; set; }
public SharedCategory? Category { get; set; }
public SharedTag_All_True? PrimaryTag { get; set; }
public SharedTag_All_True? SecondaryTag { get; set; }
public SharedUser_All_True? Owner { get; set; }
public SharedCategory_All_True? Category { get; set; }
// Collection of shared references
public List<SharedTag> Tags { get; set; } = [];
public MetadataInfo? OrderMetadata { get; set; }
public MetadataInfo? AuditMetadata { get; set; }
public List<MetadataInfo> MetadataList { get; set; } = [];
public List<SharedTag_All_True> Tags { get; set; } = [];
public MetadataInfo_All_True? OrderMetadata { get; set; }
public MetadataInfo_All_True? AuditMetadata { get; set; }
public List<MetadataInfo_All_True> MetadataList { get; set; } = [];
// NoMerge collection for testing replace behavior
[JsonNoMergeCollection]
@ -283,47 +87,7 @@ public partial class TestOrder_Circ_Ref : IId<int>
/// <summary>
/// Level 2: Order item with pallets
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class TestOrderItem : IId<int>
{
[Key(0)]
public int Id { get; set; }
[AcStringIntern(true)]
[Key(1)]
public string ProductName { get; set; } = "";
[Key(2)]
public int Quantity { get; set; }
[Key(3)]
public decimal UnitPrice { get; set; }
[Key(4)]
public TestStatus Status { get; set; } = TestStatus.Pending;
// Level 3 collection
[Key(5)]
public List<TestPallet> Pallets { get; set; } = [];
// Shared references
[Key(6)]
public SharedTag? Tag { get; set; }
[Key(7)]
public SharedUser? Assignee { get; set; }
[Key(8)]
public MetadataInfo? ItemMetadata { get; set; }
// Parent reference - ignored by all serializers to prevent circular references
[MemoryPackIgnore]
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestOrder? ParentOrder { get; set; }
}
/// <summary>
/// Level 2: Order item with pallets
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public partial class TestOrderItem_Circ_Ref : IId<int>
{
public int Id { get; set; }
@ -334,124 +98,15 @@ public partial class TestOrderItem_Circ_Ref : IId<int>
public TestStatus Status { get; set; } = TestStatus.Pending;
// Level 3 collection
public List<TestPallet> Pallets { get; set; } = [];
public List<TestPallet_All_True> Pallets { get; set; } = [];
// Shared references
public SharedTag? Tag { get; set; }
public SharedUser? Assignee { get; set; }
public MetadataInfo? ItemMetadata { get; set; }
public SharedTag_All_True? Tag { get; set; }
public SharedUser_All_True? Assignee { get; set; }
public MetadataInfo_All_True? ItemMetadata { get; set; }
public TestOrder_Circ_Ref? ParentOrder { get; set; }
}
/// <summary>
/// Level 3: Pallet containing measurements
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class TestPallet : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string PalletCode { get; set; } = "";
[Key(2)]
public int TrayCount { get; set; }
[Key(3)]
public TestStatus Status { get; set; } = TestStatus.Pending;
[Key(4)]
public double Weight { get; set; }
// Level 4 collection
[Key(5)]
public List<TestMeasurement> Measurements { get; set; } = [];
// Shared IId references for better reference testing
[Key(6)]
public SharedTag? Tag { get; set; }
[Key(7)]
public SharedUser? Inspector { get; set; }
[Key(8)]
public SharedCategory? Category { get; set; }
// Non-IId shared references
[Key(9)]
public MetadataInfo? PalletMetadata { get; set; }
// Parent reference - ignored by all serializers to prevent circular references
[MemoryPackIgnore]
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestOrderItem? ParentItem { get; set; }
}
/// <summary>
/// Level 4: Measurement with multiple points
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class TestMeasurement : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string Name { get; set; } = "";
[Key(2)]
public double TotalWeight { get; set; }
[Key(3)]
public DateTime CreatedAt { get; set; } = DateTime.UtcNow;
// Level 5 collection
[Key(4)]
public List<TestMeasurementPoint> Points { get; set; } = [];
// Shared IId references for better reference testing
[Key(5)]
public SharedTag? Tag { get; set; }
[Key(6)]
public SharedUser? Operator { get; set; }
// Parent reference - ignored by all serializers to prevent circular references
[MemoryPackIgnore]
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestPallet? ParentPallet { get; set; }
}
/// <summary>
/// Level 5: Deepest level - measurement point
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[MessagePackObject]
public partial class TestMeasurementPoint : IId<int>
{
[Key(0)]
public int Id { get; set; }
[Key(1)]
public string Label { get; set; } = "";
[Key(2)]
public double Value { get; set; }
[Key(3)]
public DateTime MeasuredAt { get; set; } = DateTime.UtcNow;
// Shared IId reference for better reference testing (many points share same tag/user)
[Key(4)]
public SharedTag? Tag { get; set; }
[Key(5)]
public SharedUser? Verifier { get; set; }
// Parent reference - ignored by all serializers to prevent circular references
[MemoryPackIgnore]
[JsonIgnore]
[IgnoreMember]
[BsonIgnore]
public TestMeasurement? ParentMeasurement { get; set; }
}
#endregion
#region Guid-based IId types
@ -459,7 +114,7 @@ public partial class TestMeasurementPoint : IId<int>
/// <summary>
/// Order with Guid Id - for testing Guid-based IId
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class TestGuidOrder : IId<Guid>
{
public Guid Id { get; set; }
@ -471,7 +126,7 @@ public class TestGuidOrder : IId<Guid>
/// <summary>
/// Item with Guid Id
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class TestGuidItem : IId<Guid>
{
public Guid Id { get; set; }
@ -487,7 +142,7 @@ public class TestGuidItem : IId<Guid>
/// Simulates NopCommerce GenericAttribute - stores key-value pairs where DateTime values
/// are stored as strings in the database.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class TestGenericAttribute
{
public int Id { get; set; }
@ -499,7 +154,7 @@ public class TestGenericAttribute
/// DTO with GenericAttributes collection - simulates OrderDto with string-stored DateTime values.
/// This reproduces the production bug where Binary serialization was thought to corrupt DateTime strings.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class TestDtoWithGenericAttributes : IId<int>
{
public int Id { get; set; }
@ -510,12 +165,12 @@ public class TestDtoWithGenericAttributes : IId<int>
/// <summary>
/// Order with nullable collections for null vs empty testing
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class TestOrderWithNullableCollections
{
public int Id { get; set; }
public string OrderNumber { get; set; } = "";
public List<TestOrderItem>? Items { get; set; }
public List<TestOrderItem_All_True>? Items { get; set; }
public List<string>? Tags { get; set; }
}
@ -523,7 +178,7 @@ public class TestOrderWithNullableCollections
/// Class with all primitive types for WASM/serialization testing
/// </summary>
[MemoryPackable]
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public partial class PrimitiveTestClass
{
public int IntValue { get; set; }
@ -546,7 +201,7 @@ public partial class PrimitiveTestClass
/// Class with extended primitive types for full serializer coverage.
/// Includes DateTimeOffset, TimeSpan, Dictionary, null properties.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class ExtendedPrimitiveTestClass
{
public int Id { get; set; }
@ -567,16 +222,16 @@ public class ExtendedPrimitiveTestClass
// Nullable properties that will be null
public string? NullString { get; set; }
public TestOrderItem? NullObject { get; set; }
public TestOrderItem_All_True? NullObject { get; set; }
// Nested object for complex serialization
public SharedTag? Tag { get; set; }
public SharedTag_All_True? Tag { get; set; }
}
/// <summary>
/// Class with array of objects containing null items for WriteNull coverage
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class ObjectWithNullItems
{
public int Id { get; set; }
@ -591,7 +246,7 @@ public class ObjectWithNullItems
/// "Server-side" DTO with extra properties that the "client" doesn't know about.
/// Used to test SkipValue functionality when deserializing unknown properties.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class ServerCustomerDto : IId<int>
{
public int Id { get; set; }
@ -624,7 +279,7 @@ public class ServerCustomerDto : IId<int>
/// the deserializer must skip unknown properties correctly
/// while still maintaining string intern table consistency.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class ClientCustomerDto : IId<int>
{
public int Id { get; set; }
@ -638,7 +293,7 @@ public class ClientCustomerDto : IId<int>
/// Server DTO with nested objects that client doesn't know about.
/// Tests skipping complex nested structures.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class ServerOrderWithExtras : IId<int>
{
public int Id { get; set; }
@ -659,7 +314,7 @@ public class ServerOrderWithExtras : IId<int>
/// <summary>
/// Client version of the order - doesn't have Customer/RelatedCustomers properties.
/// </summary>
[AcBinarySerializable(false)]
[AcBinarySerializable(true)]
public class ClientOrderSimple : IId<int>
{
public int Id { get; set; }

View File

@ -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
{
}

View File

@ -236,8 +236,8 @@ public class SignalRBenchmarkData
public byte[] MixedParamsMessage { get; }
// Test data
public TestOrderItem TestOrderItem { get; }
public TestOrder TestOrder { get; }
public TestOrderItem_All_True TestOrderItem { get; }
public TestOrder_All_True TestOrder { get; }
public int[] IntArray { get; }
public Guid TestGuid { get; }
@ -246,7 +246,7 @@ public class SignalRBenchmarkData
// Create test data
TestGuid = Guid.NewGuid();
IntArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
TestOrderItem = new TestOrderItem
TestOrderItem = new TestOrderItem_All_True
{
Id = 42,
ProductName = "Benchmark Product",

View File

@ -27,10 +27,10 @@ public static class TestDataFactory
/// <summary>
/// Create a shared tag for cross-reference testing
/// </summary>
public static SharedTag CreateTag(string? name = null, string? color = null)
public static SharedTag_All_True CreateTag(string? name = null, string? color = null)
{
var id = _idCounter++;
return new SharedTag
return new SharedTag_All_True
{
Id = id,
Name = name ?? $"Címke-{id}",
@ -45,10 +45,10 @@ public static class TestDataFactory
/// <summary>
/// Create a shared category
/// </summary>
public static SharedCategory CreateCategory(string? name = null, int? parentId = null)
public static SharedCategory_All_True CreateCategory(string? name = null, int? parentId = null)
{
var id = _idCounter++;
return new SharedCategory
return new SharedCategory_All_True
{
Id = id,
Name = name ?? $"Kategória-{id}",
@ -64,10 +64,10 @@ public static class TestDataFactory
/// <summary>
/// Create a shared user for cross-reference testing
/// </summary>
public static SharedUser CreateUser(string? username = null, TestUserRole role = TestUserRole.User)
public static SharedUser_All_True CreateUser(string? username = null, TestUserRole role = TestUserRole.User)
{
var id = _idCounter++;
return new SharedUser
return new SharedUser_All_True
{
Id = id,
Username = username ?? $"felhasználó{id}",
@ -78,7 +78,7 @@ public static class TestDataFactory
Role = role,
LastLoginAt = DateTime.UtcNow.AddHours(-id),
CreatedAt = DateTime.UtcNow.AddYears(-1),
Preferences = new UserPreferences
Preferences = new UserPreferences_All_True
{
Theme = id % 2 == 0 ? "sötét" : "világos",
Language = "magyar",
@ -91,10 +91,10 @@ public static class TestDataFactory
/// <summary>
/// Create metadata info (non-IId)
/// </summary>
public static MetadataInfo CreateMetadata(string? key = null, bool withChild = false)
public static MetadataInfo_All_True CreateMetadata(string? key = null, bool withChild = false)
{
var id = _idCounter++;
return new MetadataInfo
return new MetadataInfo_All_True
{
Key = key ?? $"Metaadat-{id}",
Value = $"MetaÉrték-{id}",
@ -109,23 +109,23 @@ public static class TestDataFactory
/// <summary>
/// Create a deep order hierarchy with configurable depth.
/// Supports both IId-based (SharedTag, SharedUser, SharedCategory) and Non-IId (UserPreferences) shared references.
/// Supports both IId-based (SharedTag_All_True, SharedUser, SharedCategory_All_True) and Non-IId (UserPreferences_All_True) shared references.
/// </summary>
public static TestOrder CreateOrder(
public static TestOrder_All_True CreateOrder(
int itemCount = 2,
int palletsPerItem = 2,
int measurementsPerPallet = 2,
int pointsPerMeasurement = 3,
SharedTag? sharedTag = null,
SharedUser? sharedUser = null,
MetadataInfo? sharedMetadata = null,
UserPreferences? sharedPreferences = null,
SharedCategory? sharedCategory = null)
SharedTag_All_True? sharedTag = null,
SharedUser_All_True? sharedUser = null,
MetadataInfo_All_True? sharedMetadata = null,
UserPreferences_All_True? sharedPreferences = null,
SharedCategory_All_True? sharedCategory = null)
{
// If sharedUser is provided but no sharedPreferences, use the user's preferences as shared
sharedPreferences ??= sharedUser?.Preferences;
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = _idCounter++,
OrderNumber = $"Megrendelés-{_idCounter:D4}",
@ -167,18 +167,18 @@ public static class TestDataFactory
/// Create an order item with pallets.
/// Supports both IId-based and Non-IId shared references.
/// </summary>
public static TestOrderItem CreateOrderItem(
public static TestOrderItem_All_True CreateOrderItem(
int palletCount = 2,
int measurementsPerPallet = 2,
int pointsPerMeasurement = 3,
SharedTag? sharedTag = null,
SharedUser? sharedUser = null,
MetadataInfo? sharedMetadata = null,
UserPreferences? sharedPreferences = null,
SharedCategory? sharedCategory = null)
SharedTag_All_True? sharedTag = null,
SharedUser_All_True? sharedUser = null,
MetadataInfo_All_True? sharedMetadata = null,
UserPreferences_All_True? sharedPreferences = null,
SharedCategory_All_True? sharedCategory = null)
{
// Create assignee - if sharedUser provided, use it. Otherwise create new user with sharedPreferences
SharedUser? assignee = sharedUser;
SharedUser_All_True? assignee = sharedUser;
if (assignee == null && sharedPreferences != null)
{
// Create a new user but with shared preferences (Non-IId ref testing)
@ -186,7 +186,7 @@ public static class TestDataFactory
assignee.Preferences = sharedPreferences;
}
var item = new TestOrderItem
var item = new TestOrderItem_All_True
{
Id = _idCounter++,
ProductName = $"Termék-{_idCounter}",
@ -221,15 +221,15 @@ public static class TestDataFactory
/// <summary>
/// Create a pallet with measurements
/// </summary>
public static TestPallet CreatePallet(
public static TestPallet_All_True CreatePallet(
int measurementCount = 2,
int pointsPerMeasurement = 3,
MetadataInfo? sharedMetadata = null,
SharedTag? sharedTag = null,
SharedUser? sharedInspector = null,
SharedCategory? sharedCategory = null)
MetadataInfo_All_True? sharedMetadata = null,
SharedTag_All_True? sharedTag = null,
SharedUser_All_True? sharedInspector = null,
SharedCategory_All_True? sharedCategory = null)
{
var pallet = new TestPallet
var pallet = new TestPallet_All_True
{
Id = _idCounter++,
PalletCode = $"Raklapkód-{_idCounter:D4}",
@ -255,12 +255,12 @@ public static class TestDataFactory
/// <summary>
/// Create a measurement with points
/// </summary>
public static TestMeasurement CreateMeasurement(
public static TestMeasurement_All_True CreateMeasurement(
int pointCount = 3,
SharedTag? sharedTag = null,
SharedUser? sharedOperator = null)
SharedTag_All_True? sharedTag = null,
SharedUser_All_True? sharedOperator = null)
{
var measurement = new TestMeasurement
var measurement = new TestMeasurement_All_True
{
Id = _idCounter++,
Name = $"Mérés-{_idCounter}",
@ -283,12 +283,12 @@ public static class TestDataFactory
/// <summary>
/// Create a measurement point
/// </summary>
public static TestMeasurementPoint CreateMeasurementPoint(
SharedTag? sharedTag = null,
SharedUser? sharedVerifier = null)
public static TestMeasurementPoint_All_True CreateMeasurementPoint(
SharedTag_All_True? sharedTag = null,
SharedUser_All_True? sharedVerifier = null)
{
var id = _idCounter++;
return new TestMeasurementPoint
return new TestMeasurementPoint_All_True
{
Id = id,
Label = $"MérőPont-{id}",
@ -307,7 +307,7 @@ public static class TestDataFactory
/// Create a large graph for benchmarking with many cross-references.
/// Creates approximately (itemCount * palletsPerItem * measurementsPerPallet * pointsPerMeasurement) objects.
/// </summary>
public static TestOrder CreateBenchmarkOrder(
public static TestOrder_All_True CreateBenchmarkOrder(
int itemCount = 5,
int palletsPerItem = 4,
int measurementsPerPallet = 3,
@ -320,7 +320,7 @@ public static class TestDataFactory
var sharedUser = CreateUser("mérőfelhasználó", TestUserRole.Admin);
var sharedMetadata = CreateMetadata("mérőteszt", withChild: true);
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = _idCounter++,
OrderNumber = $"MÉRŐTESZT-{_idCounter:D6}",
@ -338,7 +338,7 @@ public static class TestDataFactory
for (int i = 0; i < itemCount; i++)
{
var item = new TestOrderItem
var item = new TestOrderItem_All_True
{
Id = _idCounter++,
ProductName = $"MérőTermék-{i}",
@ -353,7 +353,7 @@ public static class TestDataFactory
for (int p = 0; p < palletsPerItem; p++)
{
var pallet = new TestPallet
var pallet = new TestPallet_All_True
{
Id = _idCounter++,
PalletCode = $"Raklapkód-{i}-{p}",
@ -366,7 +366,7 @@ public static class TestDataFactory
for (int m = 0; m < measurementsPerPallet; m++)
{
var measurement = new TestMeasurement
var measurement = new TestMeasurement_All_True
{
Id = _idCounter++,
Name = $"Mérés-{i}-{p}-{m}",
@ -377,7 +377,7 @@ public static class TestDataFactory
for (int pt = 0; pt < pointsPerMeasurement; pt++)
{
var point = new TestMeasurementPoint
var point = new TestMeasurementPoint_All_True
{
Id = _idCounter++,
Label = $"MérőPnt-{i}-{p}-{m}-{pt}",
@ -405,8 +405,8 @@ public static class TestDataFactory
/// <param name="palletsPerItem">Pallets per item</param>
/// <param name="measurementsPerPallet">Measurements per pallet</param>
/// <param name="pointsPerMeasurement">Points per measurement</param>
/// <returns>Large TestOrder with many IId references</returns>
public static TestOrder CreateLargeScaleBenchmarkOrder(
/// <returns>Large TestOrder_All_True with many IId references</returns>
public static TestOrder_All_True CreateLargeScaleBenchmarkOrder(
int rootItemCount = 500,
int palletsPerItem = 3,
int measurementsPerPallet = 3,
@ -420,7 +420,7 @@ public static class TestDataFactory
var sharedMetadata = CreateMetadata("nagy-méretű", withChild: true);
var sharedCategories = Enumerable.Range(1, 10).Select(i => CreateCategory($"Kategória-{i}")).ToList();
var order = new TestOrder
var order = new TestOrder_All_True
{
Id = _idCounter++,
OrderNumber = $"NAGYMÉRET-{_idCounter:D8}",
@ -438,7 +438,7 @@ public static class TestDataFactory
for (int i = 0; i < rootItemCount; i++)
{
var item = new TestOrderItem
var item = new TestOrderItem_All_True
{
Id = _idCounter++,
ProductName = $"Termék-{i}",
@ -453,7 +453,7 @@ public static class TestDataFactory
for (int p = 0; p < palletsPerItem; p++)
{
var pallet = new TestPallet
var pallet = new TestPallet_All_True
{
Id = _idCounter++,
PalletCode = $"Raklapkód-{i}-{p}",
@ -466,7 +466,7 @@ public static class TestDataFactory
for (int m = 0; m < measurementsPerPallet; m++)
{
var measurement = new TestMeasurement
var measurement = new TestMeasurement_All_True
{
Id = _idCounter++,
Name = $"Mérés-{i}-{p}-{m}",
@ -477,7 +477,7 @@ public static class TestDataFactory
for (int pt = 0; pt < pointsPerMeasurement; pt++)
{
var point = new TestMeasurementPoint
var point = new TestMeasurementPoint_All_True
{
Id = _idCounter++,
Label = $"MérőPnt-{i}-{p}-{m}-{pt}",

View File

@ -37,13 +37,13 @@ public class InvokeMethodExtensionTests
{
var service = new TestSignalRService2();
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleAsyncTestOrderItem")!;
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var result = methodInfo.InvokeMethod(service, input);
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
var item = (TestOrderItem)result;
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem_All_True> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
var item = (TestOrderItem_All_True)result;
Assert.AreEqual("Async: Widget", item.ProductName);
Assert.AreEqual(15, item.Quantity);
}
@ -81,13 +81,13 @@ public class InvokeMethodExtensionTests
{
var service = new TestSignalRService2();
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleTaskFromResultTestOrderItem")!;
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var result = methodInfo.InvokeMethod(service, input);
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
var item = (TestOrderItem)result;
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem_All_True> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
var item = (TestOrderItem_All_True)result;
Assert.AreEqual("FromResult: Widget", item.ProductName);
Assert.AreEqual(10, item.Quantity); // Doubled
}

View File

@ -165,7 +165,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Post_TestOrderItem_ReturnsProcessedItem()
{
var item = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
var result = await _client.PostDataAsync(TestSignalRTags.TestOrderItemParam, item);
@ -181,7 +181,7 @@ public abstract class SignalRClientToHubTestBase
{
var order = TestDataFactory.CreateOrder(itemCount: 2);
var result = await _client.PostDataAsync<TestOrder, TestOrder>(TestSignalRTags.TestOrderParam, order);
var result = await _client.PostDataAsync<TestOrder_All_True, TestOrder_All_True>(TestSignalRTags.TestOrderParam, order);
Assert.IsNotNull(result);
Assert.AreEqual(order.Id, result.Id);
@ -192,9 +192,9 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Post_SharedTag_ReturnsSameTag()
{
var tag = new SharedTag { Id = 1, Name = "Important", Color = "#FF0000" };
var tag = new SharedTag_All_True { Id = 1, Name = "Important", Color = "#FF0000" };
var result = await _client.PostDataAsync<SharedTag, SharedTag>(TestSignalRTags.SharedTagParam, tag);
var result = await _client.PostDataAsync<SharedTag_All_True, SharedTag_All_True>(TestSignalRTags.SharedTagParam, tag);
Assert.IsNotNull(result);
Assert.AreEqual(1, result.Id);
@ -242,13 +242,13 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Post_TestOrderItemList_ReturnsSameItems()
{
var items = new List<TestOrderItem>
var items = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Item1" },
new() { Id = 2, ProductName = "Item2" }
};
var result = await _client.PostDataAsync<List<TestOrderItem>, List<TestOrderItem>>(TestSignalRTags.TestOrderItemListParam, items);
var result = await _client.PostDataAsync<List<TestOrderItem_All_True>, List<TestOrderItem_All_True>>(TestSignalRTags.TestOrderItemListParam, items);
Assert.IsNotNull(result);
Assert.AreEqual(2, result.Count);
@ -399,11 +399,11 @@ public abstract class SignalRClientToHubTestBase
{
var input = new[]
{
new SharedTag { Id = 1, Name = "Tag1", Color = "#FF0000" },
new SharedTag { Id = 2, Name = "Tag2", Color = "#00FF00" }
new SharedTag_All_True { Id = 1, Name = "Tag1", Color = "#FF0000" },
new SharedTag_All_True { Id = 2, Name = "Tag2", Color = "#00FF00" }
};
var result = await _client.PostDataAsync<SharedTag[], SharedTag[]>(TestSignalRTags.SharedTagArrayParam, input);
var result = await _client.PostDataAsync<SharedTag_All_True[], SharedTag_All_True[]>(TestSignalRTags.SharedTagArrayParam, input);
Assert.IsNotNull(result);
Assert.AreEqual(2, result.Length);
@ -437,7 +437,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Post_IntAndDto_ReturnsFormattedString()
{
var item = new TestOrderItem { Id = 1, ProductName = "Widget" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Widget" };
var result = await _client.PostAsync<string>(TestSignalRTags.IntAndDtoParam, [42, item]);
@ -447,7 +447,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Post_DtoAndList_ReturnsFormattedString()
{
var item = new TestOrderItem { Id = 1, ProductName = "Product" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Product" };
var numbers = new List<int> { 1, 2, 3 };
var result = await _client.PostAsync<string>(TestSignalRTags.DtoAndListParam, [item, numbers]);
@ -458,9 +458,9 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Post_ThreeComplexParams_ReturnsFormattedString()
{
var item = new TestOrderItem { Id = 1, ProductName = "Item" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Item" };
var tags = new List<string> { "tag1", "tag2", "tag3" };
var sharedTag = new SharedTag { Id = 1, Name = "Shared" };
var sharedTag = new SharedTag_All_True { Id = 1, Name = "Shared" };
var result = await _client.PostAsync<string>(TestSignalRTags.ThreeComplexParams, [item, tags, sharedTag]);
@ -509,7 +509,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Async_TestOrderItem_ReturnsProcessedItem()
{
var item = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10.50m };
var result = await _client.PostDataAsync(TestSignalRTags.AsyncTestOrderItemParam, item);
@ -553,7 +553,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task RoundTrip_ComplexObject_PreservesAllProperties()
{
var item = new TestOrderItem
var item = new TestOrderItem_All_True
{
Id = 999,
ProductName = "RoundTrip Test Item",
@ -576,7 +576,7 @@ public abstract class SignalRClientToHubTestBase
{
var order = TestDataFactory.CreateOrder(itemCount: 3, palletsPerItem: 2, measurementsPerPallet: 1);
var result = await _client.PostDataAsync<TestOrder, TestOrder>(TestSignalRTags.TestOrderParam, order);
var result = await _client.PostDataAsync<TestOrder_All_True, TestOrder_All_True>(TestSignalRTags.TestOrderParam, order);
Assert.IsNotNull(result);
Assert.AreEqual(order.Id, result.Id);
@ -646,7 +646,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task ResponseData_NotDoubleEscaped()
{
var item = new TestOrderItem { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 20m };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test", Quantity = 10, UnitPrice = 20m };
var result = await _client.PostDataAsync(TestSignalRTags.TestOrderItemParam, item);
@ -660,14 +660,14 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task CollectionResponse_DeserializesCorrectly()
{
var items = new List<TestOrderItem>
var items = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Item1", Quantity = 10, UnitPrice = 1.1m },
new() { Id = 2, ProductName = "Item2", Quantity = 20, UnitPrice = 2.2m },
new() { Id = 3, ProductName = "Item3", Quantity = 30, UnitPrice = 3.3m }
};
var result = await _client.PostDataAsync<List<TestOrderItem>, List<TestOrderItem>>(
var result = await _client.PostDataAsync<List<TestOrderItem_All_True>, List<TestOrderItem_All_True>>(
TestSignalRTags.TestOrderItemListParam, items);
Assert.IsNotNull(result);
@ -683,7 +683,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task Async_Method_ReturnsActualResult_NotTaskWrapper()
{
var item = new TestOrderItem { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
var item = new TestOrderItem_All_True { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
var result = await _client.PostDataAsync(TestSignalRTags.AsyncTestOrderItemParam, item);
@ -712,7 +712,7 @@ public abstract class SignalRClientToHubTestBase
[TestMethod]
public async Task TaskFromResult_ComplexObject_ReturnsActualResult_NotTaskWrapper()
{
var item = new TestOrderItem { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
var item = new TestOrderItem_All_True { Id = 42, ProductName = "TestProduct", Quantity = 5, UnitPrice = 10m };
var result = await _client.PostDataAsync(TestSignalRTags.TaskFromResultTestOrderItemParam, item);
@ -769,13 +769,13 @@ public abstract class SignalRClientToHubTestBase
{
var service = new TestSignalRService2();
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleAsyncTestOrderItem")!;
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var result = methodInfo.InvokeMethod(service, input);
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
var item = (TestOrderItem)result;
Assert.IsNotNull(result, "InvokeMethod should unwrap Task<TestOrderItem_All_True> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
var item = (TestOrderItem_All_True)result;
Assert.AreEqual("Async: Widget", item.ProductName);
Assert.AreEqual(15, item.Quantity);
}
@ -809,13 +809,13 @@ public abstract class SignalRClientToHubTestBase
{
var service = new TestSignalRService2();
var methodInfo = typeof(TestSignalRService2).GetMethod("HandleTaskFromResultTestOrderItem")!;
var input = new TestOrderItem { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var input = new TestOrderItem_All_True { Id = 1, ProductName = "Widget", Quantity = 5, UnitPrice = 10m };
var result = methodInfo.InvokeMethod(service, input);
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem));
var item = (TestOrderItem)result;
Assert.IsNotNull(result, "InvokeMethod should unwrap Task.FromResult<TestOrderItem_All_True> and return the result");
Assert.IsInstanceOfType(result, typeof(TestOrderItem_All_True));
var item = (TestOrderItem_All_True)result;
Assert.AreEqual("FromResult: Widget", item.ProductName);
Assert.AreEqual(10, item.Quantity);
}
@ -1056,7 +1056,7 @@ public abstract class SignalRClientToHubTestBase
var dataSets = BenchmarkTestDataProvider.CreateTestDataSets(resetId: false);
var orders = dataSets.Select(ds => ds.Order).ToList();
var result = await _client.PostDataAsync<List<TestOrder>, List<TestOrder>>(
var result = await _client.PostDataAsync<List<TestOrder_All_True>, List<TestOrder_All_True>>(
TestSignalRTags.TestOrderListParam, orders);
Assert.IsNotNull(result);
@ -1077,7 +1077,7 @@ public abstract class SignalRClientToHubTestBase
public async Task RoundTrip_VeryLargeOrderList_250KB_PreservesAllData()
{
TestDataFactory.ResetIdCounter();
var orders = new List<TestOrder>();
var orders = new List<TestOrder_All_True>();
for (var i = 0; i < 100; i++)
{
var tag = TestDataFactory.CreateTag($"Tag_{i}");
@ -1091,7 +1091,7 @@ public abstract class SignalRClientToHubTestBase
sharedUser: user));
}
var result = await _client.PostDataAsync<List<TestOrder>, List<TestOrder>>(
var result = await _client.PostDataAsync<List<TestOrder_All_True>, List<TestOrder_All_True>>(
TestSignalRTags.TestOrderListParam, orders);
Assert.IsNotNull(result, "Deserialization returned null — likely BWO GetTotalPosition drift on large payload");
@ -1131,7 +1131,7 @@ public abstract class SignalRClientToHubTestBase
};
TestDataFactory.ResetIdCounter();
var orders = new List<TestOrder>();
var orders = new List<TestOrder_All_True>();
for (var i = 0; i < 80; i++)
{
var tag = TestDataFactory.CreateTag($"Cég_{i}_{hungarianNames[i % hungarianNames.Length]}");
@ -1159,7 +1159,7 @@ public abstract class SignalRClientToHubTestBase
orders.Add(order);
}
var result = await _client.PostDataAsync<List<TestOrder>, List<TestOrder>>(
var result = await _client.PostDataAsync<List<TestOrder_All_True>, List<TestOrder_All_True>>(
TestSignalRTags.TestOrderListParam, orders);
Assert.IsNotNull(result,

View File

@ -22,8 +22,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2" });
dataSource.Clear();
Assert.AreEqual(0, dataSource.Count);
@ -35,7 +35,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
dataSource.Clear(clearChangeTracking: false);
Assert.AreEqual(0, dataSource.Count);
@ -55,7 +55,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual void Contains_ReturnsFalse_WhenItemNotExists()
{
var dataSource = CreateDataSource(_client, _crudTags);
Assert.IsFalse(dataSource.Contains(new TestOrderItem { Id = 9999 }));
Assert.IsFalse(dataSource.Contains(new TestOrderItem_All_True { Id = 9999 }));
}
[TestMethod]
@ -74,7 +74,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 5, ProductName = "Item5" });
dataSource.Add(new TestOrderItem_All_True { Id = 5, ProductName = "Item5" });
Assert.AreEqual(0, dataSource.IndexOf(5));
}
@ -83,7 +83,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 10, ProductName = "Test" });
dataSource.Add(new TestOrderItem_All_True { Id = 10, ProductName = "Test" });
var result = dataSource.TryGetIndex(10, out var index);
Assert.IsTrue(result);
@ -119,7 +119,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, _crudTags);
await dataSource.LoadDataSource();
var array = new TestOrderItem[3];
var array = new TestOrderItem_All_True[3];
dataSource.CopyTo(array);
Assert.AreEqual("Product A", array[0].ProductName);
@ -147,7 +147,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var readOnly = dataSource.AsReadOnly();
Assert.AreEqual(3, readOnly.Count);
Assert.IsInstanceOfType(readOnly, typeof(System.Collections.ObjectModel.ReadOnlyCollection<TestOrderItem>));
Assert.IsInstanceOfType(readOnly, typeof(System.Collections.ObjectModel.ReadOnlyCollection<TestOrderItem_All_True>));
}
#endregion
@ -217,7 +217,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual void IList_Add_ReturnsCorrectIndex()
{
var dataSource = CreateDataSource(_client, _crudTags);
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
var index = ((IList)dataSource).Add(item);
Assert.AreEqual(0, index);
@ -228,7 +228,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
dataSource.Add(item);
Assert.IsTrue(((IList)dataSource).Contains(item));
@ -239,7 +239,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
dataSource.Add(item);
Assert.AreEqual(0, ((IList)dataSource).IndexOf(item));
@ -250,8 +250,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" });
var newItem = new TestOrderItem { Id = 2, ProductName = "Inserted" };
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "First" });
var newItem = new TestOrderItem_All_True { Id = 2, ProductName = "Inserted" };
((IList)dataSource).Insert(0, newItem);
@ -263,7 +263,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
var item = new TestOrderItem { Id = 1, ProductName = "Test" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Test" };
dataSource.Add(item);
((IList)dataSource).Remove(item);
@ -275,8 +275,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Original" });
((IList)dataSource)[0] = new TestOrderItem { Id = 1, ProductName = "Modified" };
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Original" });
((IList)dataSource)[0] = new TestOrderItem_All_True { Id = 1, ProductName = "Modified" };
Assert.AreEqual("Modified", dataSource[0].ProductName);
}
@ -286,10 +286,10 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2" });
var array = new TestOrderItem[2];
var array = new TestOrderItem_All_True[2];
((ICollection)dataSource).CopyTo(array, 0);
Assert.AreEqual("Item1", array[0].ProductName);
@ -341,7 +341,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual void Add_ThenRemove_ClearsTracking()
{
var dataSource = CreateDataSource(_client, _crudTags);
var item = new TestOrderItem { Id = 1, ProductName = "Temporary" };
var item = new TestOrderItem_All_True { Id = 1, ProductName = "Temporary" };
dataSource.Add(item);
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
@ -356,8 +356,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, _crudTags);
// Add items
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1", Quantity = 10 });
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2", Quantity = 20 });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1", Quantity = 10 });
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2", Quantity = 20 });
Assert.AreEqual(2, dataSource.GetTrackingItems().Count);
// Save
@ -365,7 +365,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
Assert.AreEqual(0, dataSource.GetTrackingItems().Count);
// Update
dataSource[0] = new TestOrderItem { Id = 1, ProductName = "Updated1", Quantity = 100 };
dataSource[0] = new TestOrderItem_All_True { Id = 1, ProductName = "Updated1", Quantity = 100 };
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
Assert.AreEqual(TrackingState.Update, dataSource.GetTrackingItems()[0].TrackingState);

View File

@ -53,7 +53,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, expressionCrudTags);
// Create filter as Expression - serializer automatically converts to AcExpressionNode
Expression<Func<TestOrderItem, bool>> filter = item => item.Quantity > 15;
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.Quantity > 15;
// Set filter as ContextIds - serializer handles the conversion
dataSource.ContextIds = [filter];
@ -75,7 +75,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
// Create filter as Expression - no manual conversion needed
var minPrice = 150m;
Expression<Func<TestOrderItem, bool>> filter = item => item.UnitPrice > minPrice;
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.UnitPrice > minPrice;
dataSource.ContextIds = [filter];
@ -111,7 +111,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, expressionCrudTags);
// Create filter as Expression
Expression<Func<TestOrderItem, bool>> filter = item => item.ProductName!.Contains("A");
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.ProductName!.Contains("A");
dataSource.ContextIds = [filter];
@ -131,7 +131,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, expressionCrudTags);
// Create filter as Expression - complex condition
Expression<Func<TestOrderItem, bool>> filter = item => item.Quantity >= 20 && item.UnitPrice < 250m;
Expression<Func<TestOrderItem_All_True, bool>> filter = item => item.Quantity >= 20 && item.UnitPrice < 250m;
dataSource.ContextIds = [filter];
@ -166,7 +166,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, queryableCrudTags);
// Create a lambda filter Expression - this gets wrapped in Where on the server
Expression<Func<TestOrderItem, bool>> filter = x => x.Quantity > 15;
Expression<Func<TestOrderItem_All_True, bool>> filter = x => x.Quantity > 15;
// Convert to AcExpressionNode for sending
var filterNode = AcExpressionConverter.ToNode(filter);
@ -189,7 +189,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
// Create a lambda filter with decimal comparison
var minPrice = 150m;
Expression<Func<TestOrderItem, bool>> filter = x => x.UnitPrice > minPrice;
Expression<Func<TestOrderItem_All_True, bool>> filter = x => x.UnitPrice > minPrice;
var filterNode = AcExpressionConverter.ToNode(filter);
dataSource.ContextIds = [filterNode];
@ -210,7 +210,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, queryableCrudTags);
// Create a filter with AND condition
Expression<Func<TestOrderItem, bool>> filter = x => x.Quantity >= 20 && x.UnitPrice < 250m;
Expression<Func<TestOrderItem_All_True, bool>> filter = x => x.Quantity >= 20 && x.UnitPrice < 250m;
var filterNode = AcExpressionConverter.ToNode(filter);
dataSource.ContextIds = [filterNode];
@ -232,7 +232,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
// Create a query chain: Where(x => x.Id > 1).Count()
// This tests the method call chain serialization
var query = new List<TestOrderItem>().AsQueryable()
var query = new List<TestOrderItem_All_True>().AsQueryable()
.Where(x => x.Id > 1);
var queryNode = AcExpressionConverter.ToNode(query.Expression);
@ -270,7 +270,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public void QueryableAggregate_CountWithWhere_ExecutesOnServer()
{
// Arrange - Server data
var serverItems = new List<TestOrderItem>
var serverItems = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Product A", Quantity = 10 },
new() { Id = 2, ProductName = "Product B", Quantity = 20 },
@ -279,14 +279,14 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
// Build query: .Where(x => x.Id > 1).Count()
// The Count() is an aggregate that should execute on the server!
var clientQuery = new List<TestOrderItem>().AsQueryable()
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable()
.Where(x => x.Id > 1);
// Build the Count() call expression manually
var countExpression = System.Linq.Expressions.Expression.Call(
typeof(Queryable),
nameof(Queryable.Count),
[typeof(TestOrderItem)],
[typeof(TestOrderItem_All_True)],
clientQuery.Expression
);
@ -304,7 +304,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public void QueryableAggregate_CountWithPredicate_ExecutesOnServer()
{
// Arrange - Server data
var serverItems = new List<TestOrderItem>
var serverItems = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Product A", Quantity = 10 },
new() { Id = 2, ProductName = "Product B", Quantity = 20 },
@ -312,13 +312,13 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
};
// Build query: .Count(x => x.Quantity > 15)
var clientQuery = new List<TestOrderItem>().AsQueryable();
Expression<Func<TestOrderItem, bool>> predicate = x => x.Quantity > 15;
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable();
Expression<Func<TestOrderItem_All_True, bool>> predicate = x => x.Quantity > 15;
var countExpression = System.Linq.Expressions.Expression.Call(
typeof(Queryable),
nameof(Queryable.Count),
[typeof(TestOrderItem)],
[typeof(TestOrderItem_All_True)],
clientQuery.Expression,
System.Linq.Expressions.Expression.Quote(predicate)
);
@ -337,7 +337,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public void QueryableAggregate_Any_ExecutesOnServer()
{
// Arrange - Server data
var serverItems = new List<TestOrderItem>
var serverItems = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Product A", Quantity = 10 },
new() { Id = 2, ProductName = "Product B", Quantity = 20 },
@ -345,13 +345,13 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
};
// Build query: .Any(x => x.Quantity > 25)
var clientQuery = new List<TestOrderItem>().AsQueryable();
Expression<Func<TestOrderItem, bool>> predicate = x => x.Quantity > 25;
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable();
Expression<Func<TestOrderItem_All_True, bool>> predicate = x => x.Quantity > 25;
var anyExpression = System.Linq.Expressions.Expression.Call(
typeof(Queryable),
nameof(Queryable.Any),
[typeof(TestOrderItem)],
[typeof(TestOrderItem_All_True)],
clientQuery.Expression,
System.Linq.Expressions.Expression.Quote(predicate)
);
@ -370,7 +370,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public void QueryableAggregate_Sum_ExecutesOnServer()
{
// Arrange - Server data
var serverItems = new List<TestOrderItem>
var serverItems = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Product A", Quantity = 10, UnitPrice = 100m },
new() { Id = 2, ProductName = "Product B", Quantity = 20, UnitPrice = 200m },
@ -378,13 +378,13 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
};
// Build query: .Sum(x => x.Quantity)
var clientQuery = new List<TestOrderItem>().AsQueryable();
Expression<Func<TestOrderItem, int>> selector = x => x.Quantity;
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable();
Expression<Func<TestOrderItem_All_True, int>> selector = x => x.Quantity;
var sumExpression = System.Linq.Expressions.Expression.Call(
typeof(Queryable),
nameof(Queryable.Sum),
[typeof(TestOrderItem)],
[typeof(TestOrderItem_All_True)],
clientQuery.Expression,
System.Linq.Expressions.Expression.Quote(selector)
);
@ -407,7 +407,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public void QueryableExpression_WhenSerialized_HasCorrectStructure()
{
// Arrange - Create an IQueryable with Where
var query = new List<TestOrderItem>().AsQueryable().Where(x => x.Id > 1);
var query = new List<TestOrderItem_All_True>().AsQueryable().Where(x => x.Id > 1);
// Act - Serialize the expression
var queryNode = AcExpressionConverter.ToNode(query.Expression);
@ -445,11 +445,11 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public void QueryableExpression_ApplyToServer_Works()
{
// Arrange - Client query
var clientQuery = new List<TestOrderItem>().AsQueryable().Where(x => x.Id > 1);
var clientQuery = new List<TestOrderItem_All_True>().AsQueryable().Where(x => x.Id > 1);
var queryNode = AcExpressionConverter.ToNode(clientQuery.Expression);
// Server data
var serverItems = new List<TestOrderItem>
var serverItems = new List<TestOrderItem_All_True>
{
new() { Id = 1, ProductName = "Product A" },
new() { Id = 2, ProductName = "Product B" },

View File

@ -11,7 +11,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual async Task Add_WithAutoSave_AddsItem()
{
var dataSource = CreateDataSource(_client, _crudTags);
var newItem = new TestOrderItem { Id = 100, ProductName = "New Product", Quantity = 5, UnitPrice = 50m };
var newItem = new TestOrderItem_All_True { Id = 100, ProductName = "New Product", Quantity = 5, UnitPrice = 50m };
var result = await dataSource.Add(newItem, autoSave: true);
Assert.AreEqual(1, dataSource.Count);
@ -23,7 +23,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual void Add_WithoutAutoSave_AddsToTrackingOnly()
{
var dataSource = CreateDataSource(_client, _crudTags);
var newItem = new TestOrderItem { Id = 100, ProductName = "New Product" };
var newItem = new TestOrderItem_All_True { Id = 100, ProductName = "New Product" };
dataSource.Add(newItem);
Assert.AreEqual(1, dataSource.Count);
@ -35,11 +35,11 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual void Add_DuplicateId_ThrowsException()
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 100, ProductName = "First" });
dataSource.Add(new TestOrderItem_All_True { Id = 100, ProductName = "First" });
Assert.ThrowsExactly<ArgumentException>(() =>
{
dataSource.Add(new TestOrderItem { Id = 100, ProductName = "Duplicate" });
dataSource.Add(new TestOrderItem_All_True { Id = 100, ProductName = "Duplicate" });
});
}
@ -50,7 +50,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
Assert.ThrowsExactly<ArgumentNullException>(() =>
{
dataSource.Add(new TestOrderItem { Id = 0, ProductName = "Invalid" });
dataSource.Add(new TestOrderItem_All_True { Id = 0, ProductName = "Invalid" });
});
}
@ -61,9 +61,9 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var items = new[]
{
new TestOrderItem { Id = 101, ProductName = "Item 1" },
new TestOrderItem { Id = 102, ProductName = "Item 2" },
new TestOrderItem { Id = 103, ProductName = "Item 3" }
new TestOrderItem_All_True { Id = 101, ProductName = "Item 1" },
new TestOrderItem_All_True { Id = 102, ProductName = "Item 2" },
new TestOrderItem_All_True { Id = 103, ProductName = "Item 3" }
};
dataSource.AddRange(items);
Assert.AreEqual(3, dataSource.Count);
@ -77,7 +77,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual async Task AddOrUpdate_AddsNew_WhenNotExists()
{
var dataSource = CreateDataSource(_client, _crudTags);
var newItem = new TestOrderItem { Id = 200, ProductName = "Brand New" };
var newItem = new TestOrderItem_All_True { Id = 200, ProductName = "Brand New" };
var result = await dataSource.AddOrUpdate(newItem, autoSave: true);
Assert.AreEqual(1, dataSource.Count);
@ -91,7 +91,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
await dataSource.LoadDataSource();
var existingId = dataSource[0].Id;
var updatedItem = new TestOrderItem { Id = existingId, ProductName = "Updated Name", Quantity = 999 };
var updatedItem = new TestOrderItem_All_True { Id = existingId, ProductName = "Updated Name", Quantity = 999 };
_ = await dataSource.AddOrUpdate(updatedItem, autoSave: true);
Assert.AreEqual(3, dataSource.Count);
@ -107,9 +107,9 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" });
dataSource.Add(new TestOrderItem { Id = 3, ProductName = "Third" });
dataSource.Insert(1, new TestOrderItem { Id = 2, ProductName = "Second" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "First" });
dataSource.Add(new TestOrderItem_All_True { Id = 3, ProductName = "Third" });
dataSource.Insert(1, new TestOrderItem_All_True { Id = 2, ProductName = "Second" });
Assert.AreEqual(3, dataSource.Count);
Assert.AreEqual("Second", dataSource[1].ProductName);
@ -121,7 +121,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
var newItem = new TestOrderItem { Id = 500, ProductName = "Inserted" };
var newItem = new TestOrderItem_All_True { Id = 500, ProductName = "Inserted" };
_ = await dataSource.Insert(0, newItem, autoSave: true);
Assert.AreEqual(1, dataSource.Count);
@ -138,7 +138,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, _crudTags);
await dataSource.LoadDataSource();
var updatedItem = new TestOrderItem
var updatedItem = new TestOrderItem_All_True
{
Id = dataSource[0].Id,
ProductName = "Updated Product",
@ -157,7 +157,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, _crudTags);
await dataSource.LoadDataSource();
var updatedItem = new TestOrderItem
var updatedItem = new TestOrderItem_All_True
{
Id = dataSource[1].Id,
ProductName = "Updated B",
@ -174,8 +174,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Original" });
dataSource[0] = new TestOrderItem { Id = 1, ProductName = "Modified" };
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Original" });
dataSource[0] = new TestOrderItem_All_True { Id = 1, ProductName = "Modified" };
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState);
@ -216,7 +216,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "ToRemove" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "ToRemove" });
dataSource.GetTrackingItems().Clear();
dataSource.Remove(dataSource[0]);
@ -231,9 +231,9 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "First" });
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Second" });
dataSource.Add(new TestOrderItem { Id = 3, ProductName = "Third" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "First" });
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Second" });
dataSource.Add(new TestOrderItem_All_True { Id = 3, ProductName = "Third" });
dataSource.GetTrackingItems().Clear();
dataSource.RemoveAt(1);
@ -260,7 +260,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Test" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Test" });
var result = dataSource.TryRemove(1, out var removedItem);
Assert.IsTrue(result);

View File

@ -23,7 +23,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual async Task LoadDataSource_ClearsChangeTracking_ByDefault()
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 999, ProductName = "Tracked" });
dataSource.Add(new TestOrderItem_All_True { Id = 999, ProductName = "Tracked" });
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);
@ -37,7 +37,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
var dataSource = CreateDataSource(_client, _crudTags);
await dataSource.LoadDataSource();
dataSource.Add(new TestOrderItem { Id = 999, ProductName = "Tracked" });
dataSource.Add(new TestOrderItem_All_True { Id = 999, ProductName = "Tracked" });
await dataSource.LoadDataSource(clearChangeTracking: false);
Assert.AreEqual(1, dataSource.GetTrackingItems().Count);

View File

@ -49,7 +49,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
ItemChangedEventArgs<TestOrderItem>? eventArgs = null;
ItemChangedEventArgs<TestOrderItem_All_True>? eventArgs = null;
dataSource.OnDataSourceItemChanged = args => { eventArgs = args; return Task.CompletedTask; };
await dataSource.LoadItem(1);

View File

@ -12,8 +12,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 101, ProductName = "Item 1" });
dataSource.Add(new TestOrderItem { Id = 102, ProductName = "Item 2" });
dataSource.Add(new TestOrderItem_All_True { Id = 101, ProductName = "Item 1" });
dataSource.Add(new TestOrderItem_All_True { Id = 102, ProductName = "Item 2" });
var unsaved = await dataSource.SaveChanges();
@ -25,7 +25,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
public virtual async Task SaveChangesAsync_ClearsTracking()
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 103, ProductName = "Item 3" });
dataSource.Add(new TestOrderItem_All_True { Id = 103, ProductName = "Item 3" });
await dataSource.SaveChangesAsync();
@ -37,7 +37,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 201, ProductName = "Specific" });
dataSource.Add(new TestOrderItem_All_True { Id = 201, ProductName = "Specific" });
var result = await dataSource.SaveItem(201);
Assert.AreEqual("Specific", result.ProductName);

View File

@ -12,7 +12,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Test" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Test" });
dataSource.SetTrackingStateToUpdate(dataSource[0]);
@ -25,7 +25,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "New Item" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "New Item" });
dataSource.SetTrackingStateToUpdate(dataSource[0]);
Assert.AreEqual(TrackingState.Add, dataSource.GetTrackingItems()[0].TrackingState);
@ -36,7 +36,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Tracked" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Tracked" });
var result = dataSource.TryGetTrackingItem(1, out var trackingItem);
Assert.IsTrue(result);
@ -63,7 +63,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Added" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Added" });
var result = dataSource.TryRollbackItem(1, out var originalValue);
Assert.IsTrue(result);
@ -78,7 +78,7 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
await dataSource.LoadDataSource();
var originalName = dataSource[0].ProductName;
dataSource[0] = new TestOrderItem { Id = dataSource[0].Id, ProductName = "Changed" };
dataSource[0] = new TestOrderItem_All_True { Id = dataSource[0].Id, ProductName = "Changed" };
var result = dataSource.TryRollbackItem(dataSource[0].Id, out var originalValue);
Assert.IsTrue(result);
@ -90,8 +90,8 @@ public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
{
var dataSource = CreateDataSource(_client, _crudTags);
dataSource.Add(new TestOrderItem { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem { Id = 2, ProductName = "Item2" });
dataSource.Add(new TestOrderItem_All_True { Id = 1, ProductName = "Item1" });
dataSource.Add(new TestOrderItem_All_True { Id = 2, ProductName = "Item2" });
dataSource.Rollback();
Assert.AreEqual(0, dataSource.Count);

View File

@ -13,8 +13,8 @@ namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
/// <typeparam name="TDataSource">The concrete DataSource type</typeparam>
/// <typeparam name="TIList">The inner list type (List or AcObservableCollection)</typeparam>
public abstract partial class SignalRDataSourceTestBase<TDataSource, TIList>
where TDataSource : AcSignalRDataSource<TestOrderItem, int, TIList>
where TIList : class, IList<TestOrderItem>
where TDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, TIList>
where TIList : class, IList<TestOrderItem_All_True>
{
protected abstract AcSerializerOptions SerializerOption { get; }
protected abstract TDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags);

View File

@ -6,7 +6,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
[TestClass]
public class SignalRDataSourceTests_List_Binary : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem>>
public class SignalRDataSourceTests_List_Binary : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem_All_True>>
{
protected override AcSerializerOptions SerializerOption => new AcBinarySerializerOptions();
protected override TestOrderItemListDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)

View File

@ -6,7 +6,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
[TestClass]
public class SignalRDataSourceTests_List_Binary_NoRef : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem>>
public class SignalRDataSourceTests_List_Binary_NoRef : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem_All_True>>
{
protected override AcSerializerOptions SerializerOption => new AcBinarySerializerOptions { ReferenceHandling = ReferenceHandlingMode.None };
protected override TestOrderItemListDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)

View File

@ -7,7 +7,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
[TestClass]
public class SignalRDataSourceTests_List_Json : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem>>
public class SignalRDataSourceTests_List_Json : SignalRDataSourceTestBase<TestOrderItemListDataSource, List<TestOrderItem_All_True>>
{
protected override AcSerializerOptions SerializerOption => new AcJsonSerializerOptions();
protected override TestOrderItemListDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)

View File

@ -7,7 +7,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
[TestClass]
public class SignalRDataSourceTests_Observable_Binary : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem>>
public class SignalRDataSourceTests_Observable_Binary : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem_All_True>>
{
protected override AcSerializerOptions SerializerOption => new AcBinarySerializerOptions();
protected override TestOrderItemObservableDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)

View File

@ -7,7 +7,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
[TestClass]
public class SignalRDataSourceTests_Observable_Json : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem>>
public class SignalRDataSourceTests_Observable_Json : SignalRDataSourceTestBase<TestOrderItemObservableDataSource, AcObservableCollection<TestOrderItem_All_True>>
{
protected override AcSerializerOptions SerializerOption => new AcJsonSerializerOptions();
protected override TestOrderItemObservableDataSource CreateDataSource(TestableSignalRClient2 client, SignalRCrudTags crudTags)

View File

@ -4,7 +4,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
public class TestOrderItemListDataSource : AcSignalRDataSource<TestOrderItem, int, List<TestOrderItem>>
public class TestOrderItemListDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, List<TestOrderItem_All_True>>
{
public TestOrderItemListDataSource(AcSignalRClientBase signalRClient, SignalRCrudTags crudTags)
: base(signalRClient, crudTags) { }

View File

@ -5,7 +5,7 @@ using AyCode.Services.SignalRs;
namespace AyCode.Services.Server.Tests.SignalRs.SignalRDatasources;
public class TestOrderItemObservableDataSource : AcSignalRDataSource<TestOrderItem, int, AcObservableCollection<TestOrderItem>>
public class TestOrderItemObservableDataSource : AcSignalRDataSource<TestOrderItem_All_True, int, AcObservableCollection<TestOrderItem_All_True>>
{
public TestOrderItemObservableDataSource(AcSignalRClientBase signalRClient, SignalRCrudTags crudTags)
: base(signalRClient, crudTags) { }

View File

@ -104,9 +104,9 @@ public class TestSignalRService2
#region Complex Object Handlers (using shared DTOs)
[SignalR(TestSignalRTags.TestOrderItemParam)]
public TestOrderItem HandleTestOrderItem(TestOrderItem item)
public TestOrderItem_All_True HandleTestOrderItem(TestOrderItem_All_True item)
{
return new TestOrderItem
return new TestOrderItem_All_True
{
Id = item.Id,
ProductName = $"Processed: {item.ProductName}",
@ -116,13 +116,13 @@ public class TestSignalRService2
}
[SignalR(TestSignalRTags.TestOrderParam)]
public TestOrder HandleTestOrder(TestOrder order)
public TestOrder_All_True HandleTestOrder(TestOrder_All_True order)
{
return order;
}
[SignalR(TestSignalRTags.SharedTagParam)]
public SharedTag HandleSharedTag(SharedTag tag)
public SharedTag_All_True HandleSharedTag(SharedTag_All_True tag)
{
return tag;
}
@ -150,7 +150,7 @@ public class TestSignalRService2
}
[SignalR(TestSignalRTags.TestOrderItemListParam)]
public List<TestOrderItem> HandleTestOrderItemList(List<TestOrderItem> items)
public List<TestOrderItem_All_True> HandleTestOrderItemList(List<TestOrderItem_All_True> items)
{
return items;
}
@ -214,7 +214,7 @@ public class TestSignalRService2
}
[SignalR(TestSignalRTags.SharedTagArrayParam)]
public SharedTag[] HandleSharedTagArray(SharedTag[] tags)
public SharedTag_All_True[] HandleSharedTagArray(SharedTag_All_True[] tags)
{
return tags;
}
@ -236,19 +236,19 @@ public class TestSignalRService2
#region Mixed Parameter Handlers
[SignalR(TestSignalRTags.IntAndDtoParam)]
public string HandleIntAndDto(int id, TestOrderItem item)
public string HandleIntAndDto(int id, TestOrderItem_All_True item)
{
return $"{id}-{item?.ProductName}";
}
[SignalR(TestSignalRTags.DtoAndListParam)]
public string HandleDtoAndList(TestOrderItem item, List<int> numbers)
public string HandleDtoAndList(TestOrderItem_All_True item, List<int> numbers)
{
return $"{item?.ProductName}-[{string.Join(",", numbers ?? [])}]";
}
[SignalR(TestSignalRTags.ThreeComplexParams)]
public string HandleThreeComplexParams(TestOrderItem item, List<string> tags, SharedTag sharedTag)
public string HandleThreeComplexParams(TestOrderItem_All_True item, List<string> tags, SharedTag_All_True sharedTag)
{
return $"{item?.ProductName}-{tags?.Count}-{sharedTag?.Name}";
}
@ -264,10 +264,10 @@ public class TestSignalRService2
#region Async Task<T> Method Tests
[SignalR(TestSignalRTags.AsyncTestOrderItemParam)]
public async Task<TestOrderItem> HandleAsyncTestOrderItem(TestOrderItem item)
public async Task<TestOrderItem_All_True> HandleAsyncTestOrderItem(TestOrderItem_All_True item)
{
await Task.Delay(1); // Simulate async work
return new TestOrderItem
return new TestOrderItem_All_True
{
Id = item.Id,
ProductName = $"Async: {item.ProductName}",
@ -316,13 +316,13 @@ public class TestSignalRService2
}
/// <summary>
/// Returns Task&lt;TestOrderItem&gt; without async keyword.
/// Returns Task&lt;TestOrderItem_All_True&gt; without async keyword.
/// CRITICAL: This simulates the exact production bug scenario.
/// </summary>
[SignalR(TestSignalRTags.TaskFromResultTestOrderItemParam)]
public Task<TestOrderItem> HandleTaskFromResultTestOrderItem(TestOrderItem item)
public Task<TestOrderItem_All_True> HandleTaskFromResultTestOrderItem(TestOrderItem_All_True item)
{
return Task.FromResult(new TestOrderItem
return Task.FromResult(new TestOrderItem_All_True
{
Id = item.Id,
ProductName = $"FromResult: {item.ProductName}",
@ -380,11 +380,11 @@ public class TestSignalRService2
#region Large Dataset / List Tests
/// <summary>
/// Tests Binary serialization with a list of TestOrder objects.
/// Tests Binary serialization with a list of TestOrder_All_True objects.
/// Used for testing string interning with deeply nested objects.
/// </summary>
[SignalR(TestSignalRTags.TestOrderListParam)]
public List<TestOrder> HandleTestOrderList(List<TestOrder> orders)
public List<TestOrder_All_True> HandleTestOrderList(List<TestOrder_All_True> orders)
{
return orders;
}
@ -440,7 +440,7 @@ public class TestSignalRService2
#region DataSource CRUD Tests
private readonly List<TestOrderItem> _dataSourceItems =
private readonly List<TestOrderItem_All_True> _dataSourceItems =
[
new() { Id = 1, ProductName = "Product A", Quantity = 10, UnitPrice = 100m },
new() { Id = 2, ProductName = "Product B", Quantity = 20, UnitPrice = 200m },
@ -448,7 +448,7 @@ public class TestSignalRService2
];
[SignalR(TestSignalRTags.DataSourceGetAll)]
public List<TestOrderItem> DataSourceGetAll() => _dataSourceItems.ToList();
public List<TestOrderItem_All_True> DataSourceGetAll() => _dataSourceItems.ToList();
/// <summary>
/// DataSource GetAll with Expression filter.
@ -456,7 +456,7 @@ public class TestSignalRService2
/// Uses IQueryable.Where() instead of Compile() for EF Core compatibility.
/// </summary>
[SignalR(TestSignalRTags.ExpressionDataSourceGetAll)]
public List<TestOrderItem> ExpressionDataSourceGetAll(Expression<Func<TestOrderItem, bool>>? filter = null)
public List<TestOrderItem_All_True> ExpressionDataSourceGetAll(Expression<Func<TestOrderItem_All_True, bool>>? filter = null)
{
if (filter == null)
return _dataSourceItems.ToList();
@ -471,10 +471,10 @@ public class TestSignalRService2
/// The expression is rebuilt and applied to the server's IQueryable.
/// </summary>
[SignalR(TestSignalRTags.QueryableDataSourceGetAll)]
public List<TestOrderItem> QueryableDataSourceGetAll(AcExpressionNode? queryNode = null)
public List<TestOrderItem_All_True> QueryableDataSourceGetAll(AcExpressionNode? queryNode = null)
{
// Simulate DbContext.Items (IQueryable<T>)
IQueryable<TestOrderItem> serverQuery = _dataSourceItems.AsQueryable();
IQueryable<TestOrderItem_All_True> serverQuery = _dataSourceItems.AsQueryable();
// If client sent a query node, rebuild and apply it
if (queryNode != null)
@ -482,7 +482,7 @@ public class TestSignalRService2
// If it's a lambda expression, use it directly as a filter
if (queryNode.NodeType == ExpressionType.Lambda)
{
var filter = AcExpressionRebuilder.FromNode<TestOrderItem, bool>(queryNode);
var filter = AcExpressionRebuilder.FromNode<TestOrderItem_All_True, bool>(queryNode);
serverQuery = serverQuery.Where(filter);
}
else
@ -505,7 +505,7 @@ public class TestSignalRService2
public object? QueryableDataSourceAggregate(AcExpressionNode queryNode)
{
// Build the query from the expression node
IQueryable<TestOrderItem> serverQuery = _dataSourceItems.AsQueryable();
IQueryable<TestOrderItem_All_True> serverQuery = _dataSourceItems.AsQueryable();
// Apply the full expression tree (including the aggregate method)
var result = AcSerializerCommon.ExecuteQueryFromNode(serverQuery, queryNode);
@ -514,17 +514,17 @@ public class TestSignalRService2
}
[SignalR(TestSignalRTags.DataSourceGetItem)]
public TestOrderItem? DataSourceGetItem(int id) => _dataSourceItems.FirstOrDefault(x => x.Id == id);
public TestOrderItem_All_True? DataSourceGetItem(int id) => _dataSourceItems.FirstOrDefault(x => x.Id == id);
[SignalR(TestSignalRTags.DataSourceAdd)]
public TestOrderItem DataSourceAdd(TestOrderItem item)
public TestOrderItem_All_True DataSourceAdd(TestOrderItem_All_True item)
{
_dataSourceItems.Add(item);
return item;
}
[SignalR(TestSignalRTags.DataSourceUpdate)]
public TestOrderItem DataSourceUpdate(TestOrderItem item)
public TestOrderItem_All_True DataSourceUpdate(TestOrderItem_All_True item)
{
var index = _dataSourceItems.FindIndex(x => x.Id == item.Id);
if (index >= 0) _dataSourceItems[index] = item;
@ -532,7 +532,7 @@ public class TestSignalRService2
}
[SignalR(TestSignalRTags.DataSourceRemove)]
public TestOrderItem? DataSourceRemove(TestOrderItem item)
public TestOrderItem_All_True? DataSourceRemove(TestOrderItem_All_True item)
{
var existing = _dataSourceItems.FirstOrDefault(x => x.Id == item.Id);
if (existing != null) _dataSourceItems.Remove(existing);