Skip to content

Commit 173adba

Browse files
CopiloteNeRGy164
andcommitted
Add JsonConstructor to InvocationDescription for Arguments deserialization
Co-authored-by: eNeRGy164 <10671831+eNeRGy164@users.noreply.github.com>
1 parent 9c40ea0 commit 173adba

File tree

3 files changed

+210
-0
lines changed

3 files changed

+210
-0
lines changed

src/DendroDocs.Shared/Descriptions/InvocationDescription.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using DendroDocs.Json;
2+
13
namespace DendroDocs;
24

35
/// <summary>
@@ -6,6 +8,20 @@ namespace DendroDocs;
68
[DebuggerDisplay("Invocation \"{ContainingType,nq}.{Name,nq}\"")]
79
public class InvocationDescription(string containingType, string name) : Statement
810
{
11+
/// <summary>
12+
/// Initializes a new instance of the <see cref="InvocationDescription"/> class with arguments.
13+
/// </summary>
14+
/// <param name="containingType">The type that contains the invoked method or constructor.</param>
15+
/// <param name="name">The name of the invoked method or constructor.</param>
16+
/// <param name="arguments">The collection of arguments passed to the invocation.</param>
17+
[Newtonsoft.Json.JsonConstructor]
18+
[JsonConstructor]
19+
public InvocationDescription(string containingType, string name, List<ArgumentDescription>? arguments)
20+
: this(containingType, name)
21+
{
22+
if (arguments is not null) this.Arguments.AddRange(arguments);
23+
}
24+
925
/// <summary>
1026
/// Gets the type that contains the invoked method or constructor.
1127
/// </summary>
@@ -19,5 +35,7 @@ public class InvocationDescription(string containingType, string name) : Stateme
1935
/// <summary>
2036
/// Gets the collection of arguments passed to the invocation.
2137
/// </summary>
38+
[Newtonsoft.Json.JsonProperty(ItemTypeNameHandling = Newtonsoft.Json.TypeNameHandling.None)]
39+
[Newtonsoft.Json.JsonConverter(typeof(ConcreteTypeConverter<List<ArgumentDescription>>))]
2240
public List<ArgumentDescription> Arguments { get; } = [];
2341
}

tests/DendroDocs.Shared.Tests/Serialization/NewtonsoftDeserializationTests.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,4 +485,100 @@ public void ConstructorParameters_Should_BeDeserializedCorrectly()
485485
secondParameter.Name.ShouldBe("value");
486486
secondParameter.Attributes.Count.ShouldBe(0);
487487
}
488+
489+
[TestMethod]
490+
public void InvocationArguments_Should_BeDeserializedCorrectly_Newtonsoft()
491+
{
492+
// Assign
493+
var json = """
494+
[{
495+
"FullName": "Test.Controller",
496+
"Methods": [{
497+
"Name": "TestMethod",
498+
"Statements": [{
499+
"$type": "DendroDocs.InvocationDescription, DendroDocs.Shared",
500+
"ContainingType": "Test.Service",
501+
"Name": "PublishMessageAsync",
502+
"Arguments": [{
503+
"Type": "string",
504+
"Text": "e.MessageType"
505+
}, {
506+
"Type": "Test.Event",
507+
"Text": "e"
508+
}]
509+
}]
510+
}]
511+
}]
512+
""";
513+
514+
// Act
515+
var types = JsonConvert.DeserializeObject<List<TypeDescription>>(json, JsonDefaults.DeserializerSettings())!;
516+
517+
// Assert
518+
types.Count.ShouldBe(1);
519+
types[0].Methods.Count.ShouldBe(1);
520+
types[0].Methods[0].Statements.Count.ShouldBe(1);
521+
522+
var invocation = types[0].Methods[0].Statements[0].ShouldBeOfType<InvocationDescription>();
523+
invocation.ContainingType.ShouldBe("Test.Service");
524+
invocation.Name.ShouldBe("PublishMessageAsync");
525+
invocation.Arguments.Count.ShouldBe(2);
526+
527+
invocation.Arguments[0].Type.ShouldBe("string");
528+
invocation.Arguments[0].Text.ShouldBe("e.MessageType");
529+
530+
invocation.Arguments[1].Type.ShouldBe("Test.Event");
531+
invocation.Arguments[1].Text.ShouldBe("e");
532+
}
533+
534+
[TestMethod]
535+
public void InvocationArguments_Should_BeDeserializedCorrectly_ComplexExample_Newtonsoft()
536+
{
537+
// Test case based on the original issue's JSON
538+
var json = """
539+
[{
540+
"FullName": "Pitstop.Application.CustomerManagementAPI.Controllers.CustomersController",
541+
"Methods": [{
542+
"Name": "RegisterAsync",
543+
"Statements": [{
544+
"$type": "DendroDocs.InvocationDescription, DendroDocs.Shared",
545+
"ContainingType": "Pitstop.Infrastructure.Messaging.IMessagePublisher",
546+
"Name": "PublishMessageAsync",
547+
"Arguments": [{
548+
"Type": "string",
549+
"Text": "e.MessageType"
550+
}, {
551+
"Type": "Pitstop.CustomerManagementAPI.Events.CustomerRegistered",
552+
"Text": "e"
553+
}, {
554+
"Type": "string",
555+
"Text": ""
556+
}]
557+
}]
558+
}]
559+
}]
560+
""";
561+
562+
// Act
563+
var types = JsonConvert.DeserializeObject<List<TypeDescription>>(json, JsonDefaults.DeserializerSettings())!;
564+
565+
// Assert
566+
types.Count.ShouldBe(1);
567+
types[0].Methods.Count.ShouldBe(1);
568+
types[0].Methods[0].Statements.Count.ShouldBe(1);
569+
570+
var invocation = types[0].Methods[0].Statements[0].ShouldBeOfType<InvocationDescription>();
571+
invocation.ContainingType.ShouldBe("Pitstop.Infrastructure.Messaging.IMessagePublisher");
572+
invocation.Name.ShouldBe("PublishMessageAsync");
573+
invocation.Arguments.Count.ShouldBe(3);
574+
575+
invocation.Arguments[0].Type.ShouldBe("string");
576+
invocation.Arguments[0].Text.ShouldBe("e.MessageType");
577+
578+
invocation.Arguments[1].Type.ShouldBe("Pitstop.CustomerManagementAPI.Events.CustomerRegistered");
579+
invocation.Arguments[1].Text.ShouldBe("e");
580+
581+
invocation.Arguments[2].Type.ShouldBe("string");
582+
invocation.Arguments[2].Text.ShouldBe("");
583+
}
488584
}

tests/DendroDocs.Shared.Tests/Serialization/TextJsonDeserializationTests.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,4 +580,100 @@ public void ConstructorParameters_Should_BeDeserializedCorrectly()
580580
secondParameter.Name.ShouldBe("value");
581581
secondParameter.Attributes.Count.ShouldBe(0);
582582
}
583+
584+
[TestMethod]
585+
public void InvocationArguments_Should_BeDeserializedCorrectly_TextJson()
586+
{
587+
// Assign
588+
var json = """
589+
[{
590+
"FullName": "Test.Controller",
591+
"Methods": [{
592+
"Name": "TestMethod",
593+
"Statements": [{
594+
"$type": "DendroDocs.InvocationDescription, DendroDocs.Shared",
595+
"ContainingType": "Test.Service",
596+
"Name": "PublishMessageAsync",
597+
"Arguments": [{
598+
"Type": "string",
599+
"Text": "e.MessageType"
600+
}, {
601+
"Type": "Test.Event",
602+
"Text": "e"
603+
}]
604+
}]
605+
}]
606+
}]
607+
""";
608+
609+
// Act
610+
var types = JsonSerializer.Deserialize<List<TypeDescription>>(json, JsonDefaults.DeserializerOptions())!;
611+
612+
// Assert
613+
types.Count.ShouldBe(1);
614+
types[0].Methods.Count.ShouldBe(1);
615+
types[0].Methods[0].Statements.Count.ShouldBe(1);
616+
617+
var invocation = types[0].Methods[0].Statements[0].ShouldBeOfType<InvocationDescription>();
618+
invocation.ContainingType.ShouldBe("Test.Service");
619+
invocation.Name.ShouldBe("PublishMessageAsync");
620+
invocation.Arguments.Count.ShouldBe(2);
621+
622+
invocation.Arguments[0].Type.ShouldBe("string");
623+
invocation.Arguments[0].Text.ShouldBe("e.MessageType");
624+
625+
invocation.Arguments[1].Type.ShouldBe("Test.Event");
626+
invocation.Arguments[1].Text.ShouldBe("e");
627+
}
628+
629+
[TestMethod]
630+
public void InvocationArguments_Should_BeDeserializedCorrectly_ComplexExample_TextJson()
631+
{
632+
// Test case based on the original issue's JSON
633+
var json = """
634+
[{
635+
"FullName": "Pitstop.Application.CustomerManagementAPI.Controllers.CustomersController",
636+
"Methods": [{
637+
"Name": "RegisterAsync",
638+
"Statements": [{
639+
"$type": "DendroDocs.InvocationDescription, DendroDocs.Shared",
640+
"ContainingType": "Pitstop.Infrastructure.Messaging.IMessagePublisher",
641+
"Name": "PublishMessageAsync",
642+
"Arguments": [{
643+
"Type": "string",
644+
"Text": "e.MessageType"
645+
}, {
646+
"Type": "Pitstop.CustomerManagementAPI.Events.CustomerRegistered",
647+
"Text": "e"
648+
}, {
649+
"Type": "string",
650+
"Text": ""
651+
}]
652+
}]
653+
}]
654+
}]
655+
""";
656+
657+
// Act
658+
var types = JsonSerializer.Deserialize<List<TypeDescription>>(json, JsonDefaults.DeserializerOptions())!;
659+
660+
// Assert
661+
types.Count.ShouldBe(1);
662+
types[0].Methods.Count.ShouldBe(1);
663+
types[0].Methods[0].Statements.Count.ShouldBe(1);
664+
665+
var invocation = types[0].Methods[0].Statements[0].ShouldBeOfType<InvocationDescription>();
666+
invocation.ContainingType.ShouldBe("Pitstop.Infrastructure.Messaging.IMessagePublisher");
667+
invocation.Name.ShouldBe("PublishMessageAsync");
668+
invocation.Arguments.Count.ShouldBe(3);
669+
670+
invocation.Arguments[0].Type.ShouldBe("string");
671+
invocation.Arguments[0].Text.ShouldBe("e.MessageType");
672+
673+
invocation.Arguments[1].Type.ShouldBe("Pitstop.CustomerManagementAPI.Events.CustomerRegistered");
674+
invocation.Arguments[1].Text.ShouldBe("e");
675+
676+
invocation.Arguments[2].Type.ShouldBe("string");
677+
invocation.Arguments[2].Text.ShouldBe("");
678+
}
583679
}

0 commit comments

Comments
 (0)