Skip to content

Commit 52ec9a4

Browse files
committed
no-mistakes(review): Test C# value-object JSON behavior via Roslyn compile
1 parent cdf9396 commit 52ec9a4

1 file changed

Lines changed: 25 additions & 12 deletions

File tree

‎server/csharp/MetaObjects.Codegen.Tests/ValueObjectWireIgnoreTests.cs‎

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
using System.Reflection;
2+
using System.Text.Json;
3+
using Microsoft.CodeAnalysis;
4+
using Microsoft.CodeAnalysis.CSharp;
15
using MetaObjects.Codegen;
26
using MetaObjects.Codegen.Generators;
37
using 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

Comments
 (0)