using AyCode.Core.Extensions; using AyCode.Core.Serializers.Attributes; using AyCode.Core.Serializers.Binaries; using MemoryPack; using MessagePack; namespace AyCode.Core.Tests.TestModels; // ============================================================================ // _All_True family — every leaf marked [AcBinarySerializable(true)] (opt-out). // All sub-references are _All_True-typed via the generic closing. // `sealed` to enable AcBinary's non-polymorphic fast-path (no type-discriminator). // ============================================================================ [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class SharedTag_All_True : SharedTagBase { } [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class SharedCategory_All_True : SharedCategoryBase { } [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class SharedUser_All_True : SharedUserBase { } [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class UserPreferences_All_True : UserPreferencesBase { } [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class MetadataInfo_All_True : MetadataInfoBase { } /// /// Level 1: Main order - root of the hierarchy /// [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class TestOrder_All_True : TestOrderBase { } /// /// Level 2: Order item with pallets /// [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class TestOrderItem_All_True : TestOrderItemBase { } /// /// Level 3: Pallet containing measurements /// [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class TestPallet_All_True : TestPalletBase { } /// /// Level 4: Measurement with multiple points /// [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class TestMeasurement_All_True : TestMeasurementBase { } /// /// Level 5: Deepest level - measurement point /// [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class TestMeasurementPoint_All_True : TestMeasurementPointBase { } // ============================================================================ // _All_False family — every leaf marked [AcBinarySerializable(false)] (opt-in). // All sub-references are _All_False-typed via the generic closing. // `sealed` to enable AcBinary's non-polymorphic fast-path. // ============================================================================ [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class SharedTag_All_False : SharedTagBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class SharedCategory_All_False : SharedCategoryBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class SharedUser_All_False : SharedUserBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class UserPreferences_All_False : UserPreferencesBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class MetadataInfo_All_False : MetadataInfoBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class TestOrder_All_False : TestOrderBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class TestOrderItem_All_False : TestOrderItemBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class TestPallet_All_False : TestPalletBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class TestMeasurement_All_False : TestMeasurementBase { } [MemoryPackable] [AcBinarySerializable(false)] [MessagePackObject] public sealed partial class TestMeasurementPoint_All_False : TestMeasurementPointBase { } // ============================================================================ // MIXED family — drift reproduction (SGen-emit asymmetry check). // Mirrors the FruitBank ProductDto / OrderDto / GenericAttributeDto attribute: // [AcBinarySerializable(false, true, false, true, false, false)] // meta=false, IdTracking=true, RefHandling=FALSE, Intern=true, Filter=false, Poly=false // // Parent: EnableRefHandlingFeature=FALSE ◀ the asymmetry trigger // Child: EnableRefHandlingFeature=true (IId, all features ON) // // Hypothesis (confirmed): the SGen reader-emit guard for collection-element / Complex / // dictionary-value dispatch (EmitReadCollectionElement / EmitReadComplex / EmitReadDictionary) // used to check the PARENT-level enableRefHandling flag. The writer-emit only depends on // CHILD-level flags (ElementNeedsRefScan / DictValueNeedsRefScan / runtime // UseTypeReferenceHandling). With runtime ReferenceHandling=All + duplicate child instances, // the writer runtime emits ObjectRefFirst / ObjectRef, but the reader's zero-branch path // couldn't decode them → DECIMAL_DRIFT on MarkerDecimal after the Children list or // ChildrenMap dictionary. // // Fix: parent-flag removed from reader guards; routing through RefAwareEmitPredicate // (single source of truth shared with writer-side EmitDirectCollectionWrite). // // The existing _All_True family tests don't exercise this path because // EnableRefHandlingFeature=true on the parent → reader emitted the full // ref-aware switch → never hit the zero-branch bug. // ============================================================================ [MemoryPackable] [AcBinarySerializable(false, true, false, true, false, false)] [MessagePackObject] public sealed partial class TestRefAsymParent : AyCode.Core.Interfaces.IId { [Key(0)] public int Id { get; set; } [Key(1)] public System.Collections.Generic.List? Children { get; set; } [Key(2)] public decimal MarkerDecimal { get; set; } [Key(3)] public System.Collections.Generic.Dictionary? ChildrenMap { get; set; } [Key(4)] public decimal MarkerDecimal2 { get; set; } } [MemoryPackable] [AcBinarySerializable(true)] [MessagePackObject] public sealed partial class TestRefAsymChild : AyCode.Core.Interfaces.IId { [Key(0)] public int Id { get; set; } [Key(1)] public string Name { get; set; } = ""; }