From e5cc6f570c639b7cd0a9cc8b43f4136f29d081bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cezary=20Pi=C4=85tek?= Date: Thu, 25 May 2023 20:59:13 +0200 Subject: [PATCH] Code generator improvements (#940) * Fix quotation marks escaping in multiline string * Add support for JsonPartialMatcher and JsonPartialWildcardMatcher in mapping code generator --- .../Serialization/MappingConverter.cs | 21 +++++++++++++++++-- src/WireMock.Net/Util/CSharpFormatter.cs | 18 ++++++++++++---- ...eMockAdminApi_GetMappingsCode.verified.txt | 18 ++++++++++++++++ .../WireMockAdminApiTests.cs | 18 +++++++++++++++- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/WireMock.Net/Serialization/MappingConverter.cs b/src/WireMock.Net/Serialization/MappingConverter.cs index aa45caf5b..ff40cbd28 100644 --- a/src/WireMock.Net/Serialization/MappingConverter.cs +++ b/src/WireMock.Net/Serialization/MappingConverter.cs @@ -107,11 +107,28 @@ public string ToCSharpCode(IMapping mapping, MappingConverterSettings? settings if (bodyMatcher is { Matchers: { } }) { - var wildcardMatcher = bodyMatcher.Matchers.OfType().FirstOrDefault(); - if (wildcardMatcher is { } && wildcardMatcher.GetPatterns().Any()) + if (bodyMatcher.Matchers.OfType().FirstOrDefault() is { } wildcardMatcher && wildcardMatcher.GetPatterns().Any()) { sb.AppendLine($" .WithBody({GetString(wildcardMatcher)})"); } + else if (bodyMatcher.Matchers.OfType().FirstOrDefault() is { Value: { } } jsonPartialMatcher) + { + sb.AppendLine(@$" .WithBody(new JsonPartialMatcher( + value: {ToCSharpStringLiteral(jsonPartialMatcher.Value.ToString())}, + ignoreCase: {ToCSharpBooleanLiteral(jsonPartialMatcher.IgnoreCase)}, + throwException: {ToCSharpBooleanLiteral(jsonPartialMatcher.ThrowException)}, + regex: {ToCSharpBooleanLiteral(jsonPartialMatcher.Regex)} + ))"); + } + else if (bodyMatcher.Matchers.OfType().FirstOrDefault() is { Value: { } } jsonPartialWildcardMatcher) + { + sb.AppendLine(@$" .WithBody(new JsonPartialWildcardMatcher( + value: {ToCSharpStringLiteral(jsonPartialWildcardMatcher.Value.ToString())}, + ignoreCase: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.IgnoreCase)}, + throwException: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.ThrowException)}, + regex: {ToCSharpBooleanLiteral(jsonPartialWildcardMatcher.Regex)} + ))"); + } } sb.AppendLine(@" )"); diff --git a/src/WireMock.Net/Util/CSharpFormatter.cs b/src/WireMock.Net/Util/CSharpFormatter.cs index f8fd80654..8a79ddc43 100644 --- a/src/WireMock.Net/Util/CSharpFormatter.cs +++ b/src/WireMock.Net/Util/CSharpFormatter.cs @@ -129,15 +129,25 @@ public static string ConvertJsonToAnonymousObjectDefinition(JToken token, int in }; } + public static string ToCSharpBooleanLiteral(bool value) => value ? "true" : "false"; + public static string ToCSharpStringLiteral(string? value) { - var escapedValue = value?.Replace("\"", "\\\"") ?? string.Empty; - if (escapedValue.Contains("\n")) + if (string.IsNullOrEmpty(value)) { - return $"@\"{escapedValue}\""; + return "\"\""; } - return $"\"{escapedValue}\""; + if (value.Contains("\n")) + { + var escapedValue = value?.Replace("\"", "\"\"") ?? string.Empty; + return $"@\"{escapedValue}\""; + } + else + { + var escapedValue = value?.Replace("\"", "\\\"") ?? string.Empty; + return $"\"{escapedValue}\""; + } } public static string FormatPropertyName(string propertyName) diff --git a/test/WireMock.Net.Tests/WireMockAdminApiTests.IWireMockAdminApi_GetMappingsCode.verified.txt b/test/WireMock.Net.Tests/WireMockAdminApiTests.IWireMockAdminApi_GetMappingsCode.verified.txt index 777f41cd3..4ba964e08 100644 --- a/test/WireMock.Net.Tests/WireMockAdminApiTests.IWireMockAdminApi_GetMappingsCode.verified.txt +++ b/test/WireMock.Net.Tests/WireMockAdminApiTests.IWireMockAdminApi_GetMappingsCode.verified.txt @@ -70,3 +70,21 @@ text }) ); +server + .Given(Request.Create() + .UsingMethod("POST") + .WithPath("/foo3") + .WithBody(new JsonPartialMatcher( + value: "{ a = 1, b = 2 }", + ignoreCase: false, + throwException: false, + regex: false + )) + ) + .WithGuid("4126dec8-470b-4eff-93bb-c24f83b8b1fd") + .RespondWith(Response.Create() + .WithStatusCode(200) + .WithBody(@"Line1 +Some ""value"" in Line2") + ); + diff --git a/test/WireMock.Net.Tests/WireMockAdminApiTests.cs b/test/WireMock.Net.Tests/WireMockAdminApiTests.cs index 8aeeb7cc0..e566b7bda 100644 --- a/test/WireMock.Net.Tests/WireMockAdminApiTests.cs +++ b/test/WireMock.Net.Tests/WireMockAdminApiTests.cs @@ -18,6 +18,7 @@ using WireMock.Client; using WireMock.Handlers; using WireMock.Logging; +using WireMock.Matchers; using WireMock.Models; using WireMock.Net.Tests.VerifyExtensions; using WireMock.RequestBuilders; @@ -719,6 +720,7 @@ public async Task IWireMockAdminApi_GetMappingsCode() var guid1 = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05"); var guid2 = Guid.Parse("1b731398-4a5b-457f-a6e3-d65e541c428f"); var guid3 = Guid.Parse("f74fd144-df53-404f-8e35-da22a640bd5f"); + var guid4 = Guid.Parse("4126DEC8-470B-4EFF-93BB-C24F83B8B1FD"); var server = WireMockServer.StartWithAdminInterface(); server @@ -769,11 +771,25 @@ public async Task IWireMockAdminApi_GetMappingsCode() " }) ); + server + .Given( + Request.Create() + .WithPath("/foo3") + .WithBody(new JsonPartialMatcher(new { a=1, b=2})) + .UsingPost() + ) + .WithGuid(guid4) + .RespondWith( + Response.Create() + .WithStatusCode(200) + .WithBody("Line1\r\nSome \"value\" in Line2") + ); + // Act var api = RestClient.For(server.Url); var mappings = await api.GetMappingsAsync().ConfigureAwait(false); - mappings.Should().HaveCount(3); + mappings.Should().HaveCount(4); var code = await api.GetMappingsCodeAsync().ConfigureAwait(false);