1+ using System . Reflection ;
2+ using System . Text . Json ;
3+ using Microsoft . CodeAnalysis ;
4+ using Microsoft . CodeAnalysis . CSharp ;
15using MetaObjects . Codegen ;
26using MetaObjects . Codegen . Generators ;
37using MetaObjects . Loader ;
@@ -36,7 +40,7 @@ public class ValueObjectWireIgnoreTests
3640 """ ;
3741
3842 [ Fact ]
39- public void A_non_nullable_value_type_member_carries_no_ignore_condition ( )
43+ public void A_value_object_with_required_value_type_members_round_trips_and_omits_a_null_optional_member ( )
4044 {
4145 var r = new MetaDataLoader ( ) . Load ( [ new InMemoryStringSource ( Model , id : "model.json" ) ] ) ;
4246 Assert . Empty ( r . Errors ) ;
@@ -46,18 +50,27 @@ public void A_non_nullable_value_type_member_carries_no_ignore_condition()
4650 Root = r . Root ,
4751 Config = new GenConfig { OutDir = "/tmp" , Namespace = "Acme.Generated" } ,
4852 } ) ;
49- var src = Assert . Single ( files , f => f . Path == "Telemetry.g.cs" ) . Content ;
53+ var trees = files . Select ( f => CSharpSyntaxTree . ParseText ( f . Content , new CSharpParseOptions ( LanguageVersion . CSharp12 ) , path : f . Path ) ) ;
54+ var comp = CSharpCompilation . Create ( "vo_wire_ignore_" + Guid . NewGuid ( ) . ToString ( "N" ) , trees ,
55+ DbContextCompileTests . BuildReferences ( ) , new CSharpCompilationOptions ( OutputKind . DynamicallyLinkedLibrary ) ) ;
56+ using var ms = new MemoryStream ( ) ;
57+ var emit = comp . Emit ( ms ) ;
58+ Assert . True ( emit . Success , string . Join ( "\n " , emit . Diagnostics . Where ( d => d . Severity == DiagnosticSeverity . Error ) ) ) ;
59+ var telemetry = Assembly . Load ( ms . ToArray ( ) ) . GetTypes ( ) . Single ( t => t . Name == "Telemetry" ) ;
5060
51- var lines = src . Split ( '\n ' ) . Select ( l => l . TrimEnd ( ) ) . ToList ( ) ;
52- string [ ] Attrs ( string decl ) =>
53- lines . TakeWhile ( l => ! l . Contains ( decl ) ) . Reverse ( ) . TakeWhile ( l => l . TrimStart ( ) . StartsWith ( "[" ) ) . ToArray ( ) ;
61+ const string body = """
62+ {"capturedAt":"2026-03-04T05:06:07Z","latitude":51.5,"live":true,"fee":"12.50","token":"3f2504e0-4f89-11d3-9a0c-0305e82c3301"}
63+ """ ;
64+ var value = JsonSerializer . Deserialize ( body , telemetry ) ! ;
65+ Assert . Equal ( 51.5 , telemetry . GetProperty ( "Latitude" ) ! . GetValue ( value ) ) ;
66+ Assert . Equal ( DateTimeOffset . Parse ( "2026-03-04T05:06:07Z" ) , telemetry . GetProperty ( "CapturedAt" ) ! . GetValue ( value ) ) ;
67+ Assert . Null ( telemetry . GetProperty ( "TempC" ) ! . GetValue ( value ) ) ;
5468
55- Assert . DoesNotContain ( Attrs ( "public double Latitude" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
56- Assert . DoesNotContain ( Attrs ( "public DateTimeOffset CapturedAt" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
57- Assert . DoesNotContain ( Attrs ( "public bool Live" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
58- Assert . DoesNotContain ( Attrs ( "public decimal Fee" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
59- Assert . DoesNotContain ( Attrs ( "public Guid Token" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
60- Assert . Contains ( Attrs ( "public int? TempC" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
61- Assert . Contains ( Attrs ( "public string? Note" ) , l => l . Contains ( "WhenWritingNull" ) ) ;
69+ var wire = JsonDocument . Parse ( JsonSerializer . Serialize ( value , telemetry ) ) . RootElement ;
70+ Assert . Equal ( 51.5 , wire . GetProperty ( "latitude" ) . GetDouble ( ) ) ;
71+ Assert . Equal ( DateTimeOffset . Parse ( "2026-03-04T05:06:07Z" ) , wire . GetProperty ( "capturedAt" ) . GetDateTimeOffset ( ) ) ;
72+ Assert . True ( wire . GetProperty ( "live" ) . GetBoolean ( ) ) ;
73+ Assert . False ( wire . TryGetProperty ( "tempC" , out _ ) ) ;
74+ Assert . False ( wire . TryGetProperty ( "note" , out _ ) ) ;
6275 }
6376}
0 commit comments