From f98073d5081d2ec0fbe6dc480b1b3ed89329a51c Mon Sep 17 00:00:00 2001 From: devhl-labs Date: Wed, 6 Nov 2024 03:29:17 -0500 Subject: [PATCH] Refactor copy lambda (#19983) * comment out broken tests * refactored copy lambda * added tests --- .../languages/AbstractCSharpCodegen.java | 13 ++-- .../templating/mustache/CopyLambda.java | 50 +++++++++++-- .../templating/mustache/PasteLambda.java | 33 +++------ .../generichost/JsonConverter.mustache | 52 +++++++------- .../generichost/RateLimitProvider`1.mustache | 8 ++- .../generichost/ValidateRegex.mustache | 2 +- .../generichost/WritePropertyHelper.mustache | 5 +- .../generichost/modelGeneric.mustache | 8 ++- .../mustache/CopyPasteLambdaTest.java | 71 +++++++++++++++++++ 9 files changed, 176 insertions(+), 66 deletions(-) create mode 100644 modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CopyPasteLambdaTest.java diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java index 5c022bc82e6..c09ea9b0a9a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java @@ -33,6 +33,8 @@ import org.openapitools.codegen.model.ModelsMap; import org.openapitools.codegen.model.OperationMap; import org.openapitools.codegen.model.OperationsMap; import org.openapitools.codegen.templating.mustache.*; +import org.openapitools.codegen.templating.mustache.CopyLambda.CopyContent; +import org.openapitools.codegen.templating.mustache.CopyLambda.WhiteSpaceStrategy; import org.openapitools.codegen.utils.ModelUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -427,7 +429,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen { @Override protected ImmutableMap.Builder addMustacheLambdas() { - CopyLambda copyLambda = new CopyLambda(); + final CopyContent copyContent = new CopyContent(); return super.addMustacheLambdas() .put("camelcase_sanitize_param", new CamelCaseAndSanitizeLambda().generator(this).escapeAsParamName(true)) @@ -443,12 +445,13 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen { .put("first", new FirstLambda(" ")) .put("firstDot", new FirstLambda("\\.")) .put("indent1", new IndentedLambda(4, " ", false, true)) + .put("indentAll1", new IndentedLambda(4, " ", true, true)) .put("indent3", new IndentedLambda(12, " ", false, true)) .put("indent4", new IndentedLambda(16, " ", false, true)) - .put("copy", copyLambda) - .put("paste", new PasteLambda(copyLambda, true, true, true, false)) - .put("pasteOnce", new PasteLambda(copyLambda, true, true, true, true)) - .put("pasteLine", new PasteLambda(copyLambda, true, true, false, false)) + .put("copy", new CopyLambda(copyContent, WhiteSpaceStrategy.None, WhiteSpaceStrategy.None)) + .put("copyText", new CopyLambda(copyContent, WhiteSpaceStrategy.Strip, WhiteSpaceStrategy.StripLineBreakIfPresent)) + .put("paste", new PasteLambda(copyContent, false)) + .put("pasteOnce", new PasteLambda(copyContent, true)) .put("uniqueLines", new UniqueLambda("\n", false)) .put("unique", new UniqueLambda("\n", true)) .put("camel_case", new CamelCaseLambda()) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/CopyLambda.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/CopyLambda.java index f1e4868c59b..8da2eda0faa 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/CopyLambda.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/CopyLambda.java @@ -27,7 +27,7 @@ import com.samskivert.mustache.Template.Fragment; * * Register: *
- * additionalProperties.put("copy", new CopyLambda());
+ * additionalProperties.put("copy", new CopyLambda(new CopyContent()));
  * 
* * Use: @@ -36,13 +36,55 @@ import com.samskivert.mustache.Template.Fragment; * */ public class CopyLambda implements Mustache.Lambda { - public String savedContent; + public static class CopyContent { + public String content; + } - public CopyLambda() { + public CopyContent copyContent; + private final WhiteSpaceStrategy leadingWhiteSpaceStrategy; + private final WhiteSpaceStrategy trailingWhiteSpaceStrategy; + + public enum WhiteSpaceStrategy { + None, + AppendLineBreakIfMissing, + Strip, + StripLineBreakIfPresent + } + + public CopyLambda(CopyContent content, WhiteSpaceStrategy leadingWhiteSpaceStrategy, WhiteSpaceStrategy trailingWhiteSpaceStrategy) { + this.copyContent = content; + this.leadingWhiteSpaceStrategy = leadingWhiteSpaceStrategy; + this.trailingWhiteSpaceStrategy = trailingWhiteSpaceStrategy; } @Override public void execute(Fragment fragment, Writer writer) throws IOException { - savedContent = fragment.execute().stripTrailing(); + String content = fragment.execute(); + + if (this.leadingWhiteSpaceStrategy == WhiteSpaceStrategy.AppendLineBreakIfMissing && !content.startsWith("\n")){ + content = "\n" + content; + } + + if (this.leadingWhiteSpaceStrategy == WhiteSpaceStrategy.Strip) { + content = content.stripLeading(); + } + + if (this.leadingWhiteSpaceStrategy == WhiteSpaceStrategy.StripLineBreakIfPresent && content.startsWith("\n")) { + content = content.substring(1); + } + + if (this.trailingWhiteSpaceStrategy == WhiteSpaceStrategy.AppendLineBreakIfMissing && !content.endsWith("\n")){ + content = content + "\n"; + } + + if (this.trailingWhiteSpaceStrategy == WhiteSpaceStrategy.Strip){ + content = content.stripTrailing(); + } + + if (this.trailingWhiteSpaceStrategy == WhiteSpaceStrategy.StripLineBreakIfPresent && content.endsWith("\n")) { + content = content.substring(0, content.length() - 1); + } + + this.copyContent.content = content; } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/PasteLambda.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/PasteLambda.java index ea798d9dc3c..de7f128d5c2 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/PasteLambda.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/PasteLambda.java @@ -19,6 +19,8 @@ package org.openapitools.codegen.templating.mustache; import java.io.IOException; import java.io.Writer; +import org.openapitools.codegen.templating.mustache.CopyLambda.CopyContent; + import com.samskivert.mustache.Mustache; import com.samskivert.mustache.Template.Fragment; @@ -27,7 +29,7 @@ import com.samskivert.mustache.Template.Fragment; * * Register: *
- * additionalProperties.put("paste", new PasteLambda(copyLambda, true, true, true, false));
+ * additionalProperties.put("paste", new PasteLambda(copyContent, false));
  * 
* * Use: @@ -36,41 +38,26 @@ import com.samskivert.mustache.Template.Fragment; * */ public class PasteLambda implements Mustache.Lambda { - private final CopyLambda copyLambda; - private final Boolean stripLeading; - private final Boolean stripTrailing; - private final Boolean endWithLineBreak; + private final CopyContent copyContent; private final Boolean clear; - public PasteLambda(CopyLambda copyLambda, Boolean stripLeading, Boolean stripTrailing, Boolean endWithLineBreak, boolean clear) { - this.copyLambda = copyLambda; - this.stripLeading = stripLeading; - this.stripTrailing = stripTrailing; - this.endWithLineBreak = endWithLineBreak; + public PasteLambda(CopyContent copyContent, boolean clear) { + this.copyContent = copyContent; this.clear = clear; } @Override public void execute(Fragment fragment, Writer writer) throws IOException { - String content = this.copyLambda.savedContent; + String content = this.copyContent.content; if (content == null) { return; } - if (this.stripTrailing){ - content = content.stripTrailing(); - } - if (this.stripLeading) { - content = content.stripLeading(); - } - if (this.endWithLineBreak && !content.endsWith("\n")){ - content = content + "\n"; - } - writer.write(content); - if (this.clear) { - this.copyLambda.savedContent = null; + this.copyContent.content = null; } + + writer.write(content); } } diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache index 189acfd7421..b5d2e170157 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache @@ -342,12 +342,12 @@ public override void Write(Utf8JsonWriter writer, {{classname}} {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}, JsonSerializerOptions jsonSerializerOptions) { {{#lambda.trimLineBreaks}} - {{#lambda.copy}} + {{#lambda.copyText}} {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}} - {{/lambda.copy}} + {{/lambda.copyText}} {{#discriminator}} {{#children}} - if ({{#lambda.pasteLine}}{{/lambda.pasteLine}} is {{classname}} {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}){ + if ({{#lambda.paste}}{{/lambda.paste}} is {{classname}} {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}){ JsonSerializer.Serialize<{{{name}}}>(writer, {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}, jsonSerializerOptions); return; } @@ -449,9 +449,9 @@ {{^isMap}} {{^isEnum}} {{^isUuid}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteString("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} @@ -460,44 +460,44 @@ {{/isMap}} {{/isString}} {{#isBoolean}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteBoolean("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}{{nrt!}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}{{#required}}{{#isNullable}}.Value{{/isNullable}}{{/required}}); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} {{/isBoolean}} {{^isEnum}} {{#isNumeric}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteNumber("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}{{nrt!}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}{{#required}}{{#isNullable}}.Value{{/isNullable}}{{/required}}); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} {{/isNumeric}} {{/isEnum}} {{#isDate}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteString("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}{{nrt!}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}{{#required}}{{#isNullable}}.Value{{/isNullable}}{{/required}}.ToString({{name}}Format)); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} {{/isDate}} {{#isDateTime}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteString("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}{{nrt!}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}{{#required}}{{#isNullable}}.Value{{/isNullable}}{{/required}}.ToString({{name}}Format)); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} {{/isDateTime}} {{#isEnum}} {{#isNumeric}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteNumber("{{baseName}}", {{#isInnerEnum}}{{classname}}.{{/isInnerEnum}}{{{datatypeWithEnum}}}ToJsonValue({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}{{nrt!}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}{{#required}}{{#isNullable}}.Value{{/isNullable}}{{/required}})); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} @@ -519,9 +519,9 @@ {{/isNullable}} {{/isInnerEnum}} {{^isInnerEnum}} - {{#lambda.copy}} + {{#lambda.copyText}} {{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}} - {{/lambda.copy}} + {{/lambda.copyText}} {{#required}} {{#isNullable}} if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}} == null) @@ -533,7 +533,7 @@ {{#enumVars}} {{#-first}} {{#isString}} - if ({{#lambda.pasteLine}}{{/lambda.pasteLine}}RawValue != null){{! we cant use name here because enumVar also has a name property, so use the paste lambda instead }} + if ({{#lambda.paste}}{{/lambda.paste}}RawValue != null){{! we cant use name here because enumVar also has a name property, so use the paste lambda instead }} writer.WriteString("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{nameInPascalCase}}{{/lambda.camelcase_sanitize_param}}RawValue); else writer.WriteNull("{{baseName}}"); @@ -552,10 +552,10 @@ {{#enumVars}} {{#-first}} {{^isNumeric}} - writer.WriteString("{{baseName}}", {{#lambda.pasteLine}}{{/lambda.pasteLine}}RawValue); + writer.WriteString("{{baseName}}", {{#lambda.paste}}{{/lambda.paste}}RawValue); {{/isNumeric}} {{#isNumeric}} - writer.WriteNumber("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{#lambda.pasteLine}}{{/lambda.pasteLine}}{{/lambda.camelcase_sanitize_param}}RawValue); + writer.WriteNumber("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{#lambda.paste}}{{/lambda.paste}}{{/lambda.camelcase_sanitize_param}}RawValue); {{/isNumeric}} {{/-first}} {{/enumVars}} @@ -568,16 +568,16 @@ {{#isNullable}} if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}Option{{nrt!}}.Value != null) { - var {{#lambda.pasteLine}}{{/lambda.pasteLine}}RawValue = {{{datatypeWithEnum}}}ValueConverter.ToJsonValue({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}Option.Value{{nrt!}}.Value); - writer.{{#lambda.first}}{{#allowableValues}}{{#enumVars}}{{^isNumeric}}WriteString {{/isNumeric}}{{#isNumeric}}WriteNumber {{/isNumeric}}{{/enumVars}}{{/allowableValues}}{{/lambda.first}}("{{baseName}}", {{#lambda.pasteLine}}{{/lambda.pasteLine}}RawValue); + var {{#lambda.paste}}{{/lambda.paste}}RawValue = {{{datatypeWithEnum}}}ValueConverter.ToJsonValue({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}Option.Value{{nrt!}}.Value); + writer.{{#lambda.first}}{{#allowableValues}}{{#enumVars}}{{^isNumeric}}WriteString {{/isNumeric}}{{#isNumeric}}WriteNumber {{/isNumeric}}{{/enumVars}}{{/allowableValues}}{{/lambda.first}}("{{baseName}}", {{#lambda.paste}}{{/lambda.paste}}RawValue); } else writer.WriteNull("{{baseName}}"); {{/isNullable}} {{^isNullable}} { - var {{#lambda.pasteLine}}{{/lambda.pasteLine}}RawValue = {{{datatypeWithEnum}}}ValueConverter.ToJsonValue({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{nrt!}}.Value); - writer.{{#lambda.first}}{{#allowableValues}}{{#enumVars}}{{^isNumeric}}WriteString {{/isNumeric}}{{#isNumeric}}WriteNumber {{/isNumeric}}{{/enumVars}}{{/allowableValues}}{{/lambda.first}}("{{baseName}}", {{#lambda.pasteLine}}{{/lambda.pasteLine}}RawValue); + var {{#lambda.paste}}{{/lambda.paste}}RawValue = {{{datatypeWithEnum}}}ValueConverter.ToJsonValue({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{nrt!}}.Value); + writer.{{#lambda.first}}{{#allowableValues}}{{#enumVars}}{{^isNumeric}}WriteString {{/isNumeric}}{{#isNumeric}}WriteNumber {{/isNumeric}}{{/enumVars}}{{/allowableValues}}{{/lambda.first}}("{{baseName}}", {{#lambda.paste}}{{/lambda.paste}}RawValue); } {{/isNullable}} {{/required}} @@ -586,9 +586,9 @@ {{/isMap}} {{/isEnum}} {{#isUuid}} - {{#lambda.copy}} + {{#lambda.copyText}} writer.WriteString("{{baseName}}", {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}{{nrt!}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}{{#required}}{{#isNullable}}.Value{{/isNullable}}{{/required}}); - {{/lambda.copy}} + {{/lambda.copyText}} {{#lambda.indent3}} {{>WriteProperty}} {{/lambda.indent3}} diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/RateLimitProvider`1.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/RateLimitProvider`1.mustache index 857a505ab70..14b0a1c574e 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/RateLimitProvider`1.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/RateLimitProvider`1.mustache @@ -53,11 +53,15 @@ namespace {{packageName}}.{{clientPackage}} } else { - {{#lambda.indent1}}{{#lambda.pasteLine}}{{/lambda.pasteLine}}{{/lambda.indent1}} + {{#lambda.indentAll1}} + {{#lambda.paste}} + {{/lambda.paste}} + {{/lambda.indentAll1}} } {{/hasApiKeyMethods}} {{^hasApiKeyMethods}} - {{#lambda.pasteLine}}{{/lambda.pasteLine}} + {{#lambda.paste}} + {{/lambda.paste}} {{/hasApiKeyMethods}} foreach(Channel tokens in AvailableTokens.Values) diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/ValidateRegex.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/ValidateRegex.mustache index 78aba8fb345..8918b8cf40e 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/ValidateRegex.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/ValidateRegex.mustache @@ -1,7 +1,7 @@ // {{{name}}} ({{{dataType}}}) pattern Regex regex{{{name}}} = new Regex(@"{{{vendorExtensions.x-regex}}}"{{#vendorExtensions.x-modifiers}}{{#-first}}, {{/-first}}RegexOptions.{{{.}}}{{^-last}} | {{/-last}}{{/vendorExtensions.x-modifiers}}); {{#lambda.copy}}this.{{{name}}}{{#useGenericHost}}{{^required}}Option.Value{{/required}}{{/useGenericHost}} != null && {{/lambda.copy}} -if ({{#lambda.first}}{{^required}}{{#lambda.pasteLine}}{{/lambda.pasteLine}} {{/required}}{{#isNullable}}{{#lambda.pasteLine}}{{/lambda.pasteLine}}{{/isNullable}}{{/lambda.first}}!regex{{{name}}}.Match(this.{{{name}}}{{#useGenericHost}}{{^required}}Option.Value{{/required}}{{/useGenericHost}}{{#isUuid}}.ToString(){{#lambda.first}}{{^required}}{{nrt!}} {{/required}}{{#isNullable}}! {{/isNullable}}{{/lambda.first}}{{/isUuid}}).Success) +if ({{#lambda.first}}{{^required}}{{#lambda.paste}}{{/lambda.paste}} {{/required}}{{#isNullable}}{{#lambda.paste}}{{/lambda.paste}}{{/isNullable}}{{/lambda.first}}!regex{{{name}}}.Match(this.{{{name}}}{{#useGenericHost}}{{^required}}Option.Value{{/required}}{{/useGenericHost}}{{#isUuid}}.ToString(){{#lambda.first}}{{^required}}{{nrt!}} {{/required}}{{#isNullable}}! {{/isNullable}}{{/lambda.first}}{{/isUuid}}).Success) { yield return new System.ComponentModel.DataAnnotations.ValidationResult("Invalid value for {{{name}}}, must match a pattern of " + regex{{{name}}}, new [] { "{{{name}}}" }); } \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/WritePropertyHelper.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/WritePropertyHelper.mustache index 183946cf79b..616993bcea7 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/WritePropertyHelper.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/WritePropertyHelper.mustache @@ -1,9 +1,10 @@ {{#isNullable}} if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{/required}} != null) - {{#lambda.pasteLine}}{{/lambda.pasteLine}} + {{#lambda.paste}}{{/lambda.paste}} else writer.WriteNull("{{baseName}}"); {{/isNullable}} {{^isNullable}} -{{#lambda.pasteLine}}{{/lambda.pasteLine}} +{{#lambda.paste}} +{{/lambda.paste}} {{/isNullable}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/modelGeneric.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/modelGeneric.mustache index 0f338dd25b5..fe8e1e24d95 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/modelGeneric.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/modelGeneric.mustache @@ -345,15 +345,17 @@ {{/readOnlyVars}} {{#readOnlyVars}} {{#lambda.copy}} - if ({{name}} != null) hashCode = (hashCode * 59) + {{name}}.GetHashCode(); + {{/lambda.copy}} {{#isNullable}} - {{#lambda.pasteOnce}}{{/lambda.pasteOnce}} + {{#lambda.pasteOnce}} + {{/lambda.pasteOnce}} {{/isNullable}} {{^required}} - {{#lambda.pasteOnce}}{{/lambda.pasteOnce}} + {{#lambda.pasteOnce}} + {{/lambda.pasteOnce}} {{/required}} {{/readOnlyVars}} {{#isAdditionalPropertiesTrue}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CopyPasteLambdaTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CopyPasteLambdaTest.java new file mode 100644 index 00000000000..1facb85eaf8 --- /dev/null +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/templating/mustache/CopyPasteLambdaTest.java @@ -0,0 +1,71 @@ +package org.openapitools.codegen.templating.mustache; + +import static org.mockito.AdditionalAnswers.returnsFirstArg; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Map; + +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openapitools.codegen.CodegenConfig; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.openapitools.codegen.templating.mustache.CopyLambda.CopyContent; +import org.openapitools.codegen.templating.mustache.CopyLambda.WhiteSpaceStrategy; + +public class CopyPasteLambdaTest extends LambdaTest { + + @Mock + CodegenConfig generator; + + @BeforeMethod + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void camelCaseTest() { + final CopyContent copyContent = new CopyContent(); + Map ctx = context("copy", new CopyLambda(copyContent, WhiteSpaceStrategy.None, WhiteSpaceStrategy.None)); + ctx.put("paste", new PasteLambda(copyContent, false)); + test("foo", "{{#copy}}foo{{/copy}}{{#paste}}{{/paste}}", ctx); + + // the first line break does not count + // it results in the tag being the only element on the line, so the line does not get printed + test("\nfoo\n", "{{#copy}}\n\nfoo\n{{/copy}}{{#paste}}{{/paste}}", ctx); + } + + @Test + public void camelCaseTestAppend() { + final CopyContent copyContent = new CopyContent(); + Map ctx = context("copy", new CopyLambda(copyContent, WhiteSpaceStrategy.AppendLineBreakIfMissing, WhiteSpaceStrategy.AppendLineBreakIfMissing)); + ctx.put("paste", new PasteLambda(copyContent, false)); + test("\nfoo\n", "{{#copy}}foo{{/copy}}{{#paste}}{{/paste}}", ctx); + test("\nfoo\n", "{{#copy}}\n\nfoo\n{{/copy}}{{#paste}}{{/paste}}", ctx); + } + + @Test + public void camelCaseTestStripLineBreakIfPresent() { + final CopyContent copyContent = new CopyContent(); + Map ctx = context("copy", new CopyLambda(copyContent, WhiteSpaceStrategy.StripLineBreakIfPresent, WhiteSpaceStrategy.StripLineBreakIfPresent)); + ctx.put("paste", new PasteLambda(copyContent, false)); + test("foo", "{{#copy}}foo{{/copy}}{{#paste}}{{/paste}}", ctx); + test("foo", "{{#copy}}\nfoo\n{{/copy}}{{#paste}}{{/paste}}", ctx); + test(" \nfoo\n ", "{{#copy}}\n\n \nfoo\n {{/copy}}{{#paste}}{{/paste}}", ctx); + test(" foo ", "{{#copy}}\n\n foo \n{{/copy}}{{#paste}}{{/paste}}", ctx); + } + + @Test + public void camelCaseTestStrip() { + final CopyContent copyContent = new CopyContent(); + Map ctx = context("copy", new CopyLambda(copyContent, WhiteSpaceStrategy.Strip, WhiteSpaceStrategy.Strip)); + ctx.put("paste", new PasteLambda(copyContent, false)); + test("foo", "{{#copy}}foo{{/copy}}{{#paste}}{{/paste}}", ctx); + test("foo", "{{#copy}}\n\nfoo\n{{/copy}}{{#paste}}{{/paste}}", ctx); + test("foo", "{{#copy}} \nfoo\n {{/copy}}{{#paste}}{{/paste}}", ctx); + test("foo", "{{#copy}}\n\n foo \n{{/copy}}{{#paste}}{{/paste}}", ctx); + } +}