From 7b5e5c8289895fdb300decf88693d6dca3280627 Mon Sep 17 00:00:00 2001 From: James Schubert Date: Mon, 30 Oct 2017 15:23:50 -0400 Subject: [PATCH 1/7] [csharp] Treat enum models consistently C# works differently from most languages in that enums are not considered objects. This means default(EnumType) will choose a default of the first enum option. This isn't desirable because it breaks the required = false functionality of swagger specs, which defines a property which isn't required to exist in the message body. Rather than force consumers to use enum values such as UNSPECIFIED, UNKNOWN, NOT_SET, etc... we can treat enums as primitives. This means any non-required enum will become Nullable regardless of whether it is defined as an inline enum or a referenced enum model. --- .../io/swagger/codegen/CodegenConstants.java | 8 + .../io/swagger/codegen/DefaultGenerator.java | 60 +++-- .../languages/AbstractCSharpCodegen.java | 63 ++++++ .../languages/CSharpClientCodegen.java | 6 - .../resources/csharp/modelGeneric.mustache | 14 +- .../codegen/AbstractIntegrationTest.java | 12 +- .../CsharpClientEnumRefIntegrationTest.java | 53 +++++ ...CsharpClientInlineEnumIntegrationTest.java | 53 +++++ .../codegen/csharp/CsharpModelEnumTest.java | 1 + .../testutils/IntegrationTestPathsConfig.java | 10 +- .../Model/MyClassWithOptionalEnum.cs | 206 ++++++++++++++++++ .../csharp/enum-inline-spec.json | 59 +++++ .../csharp/enum-inline.ignore | 9 + .../Model/MyClassWithOptionalEnum.cs | 156 +++++++++++++ .../src/IO.Swagger/Model/WeekDays.cs | 77 +++++++ .../csharp/enum-ref-spec.json | 62 ++++++ .../integrationtests/csharp/enum-ref.ignore | 9 + 17 files changed, 826 insertions(+), 32 deletions(-) create mode 100644 modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java create mode 100644 modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline.ignore create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-spec.json create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref.ignore diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java index 4dea75e8208..a650422f224 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java @@ -4,6 +4,14 @@ package io.swagger.codegen; * A class for storing constants that are used throughout the project. */ public class CodegenConstants { + public static final String APIS = "apis"; + public static final String MODELS = "models"; + public static final String SUPPORTING_FILES = "supportingFiles"; + public static final String MODEL_TESTS = "modelTests"; + public static final String MODEL_DOCS = "modelDocs"; + public static final String API_TESTS = "apiTests"; + public static final String API_DOCS = "apiDocs"; + public static final String API_PACKAGE = "apiPackage"; public static final String API_PACKAGE_DESC = "package for generated api classes"; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index 80033e12699..ccfdda11082 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -33,9 +33,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { private Boolean generateApiDocumentation = null; private Boolean generateModelTests = null; private Boolean generateModelDocumentation = null; + private Boolean generateSwaggerMetadata = true; private String basePath; private String basePathWithoutHost; private String contextPath; + private Map generatorPropertyDefaults = new HashMap<>(); @Override public Generator opts(ClientOptInput opts) { @@ -61,6 +63,31 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { return this; } + public void setGenerateSwaggerMetadata(Boolean generateSwaggerMetadata) { + this.generateSwaggerMetadata = generateSwaggerMetadata; + } + + /** + * Set generator properties otherwise pulled from system properties. + * Useful for running tests in parallel without relying on System.properties. + * @param key The system property key + * @param value The system property value + */ + public void setGeneratorPropertyDefault(final String key, final String value) { + this.generatorPropertyDefaults.put(key, value); + } + + private Boolean getGeneratorPropertyDefaultSwitch(final String key, final Boolean defaultValue) { + String result = null; + if (this.generatorPropertyDefaults.containsKey(key)) { + result = this.generatorPropertyDefaults.get(key); + } + if (result != null) { + return Boolean.valueOf(result); + } + return defaultValue; + } + private String getScheme() { String scheme; if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) { @@ -88,11 +115,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { } private void configureGeneratorProperties() { - // allows generating only models by specifying a CSV of models to generate, or empty for all - generateApis = System.getProperty("apis") != null ? true : null; - generateModels = System.getProperty("models") != null ? true : null; - generateSupportingFiles = System.getProperty("supportingFiles") != null ? true : null; + generateApis = System.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null); + generateModels = System.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null); + generateSupportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null); if (generateApis == null && generateModels == null && generateSupportingFiles == null) { // no specifics are set, generate everything @@ -110,10 +136,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { } // model/api tests and documentation options rely on parent generate options (api or model) and no other options. // They default to true in all scenarios and can only be marked false explicitly - generateModelTests = System.getProperty("modelTests") != null ? Boolean.valueOf(System.getProperty("modelTests")) : true; - generateModelDocumentation = System.getProperty("modelDocs") != null ? Boolean.valueOf(System.getProperty("modelDocs")) : true; - generateApiTests = System.getProperty("apiTests") != null ? Boolean.valueOf(System.getProperty("apiTests")) : true; - generateApiDocumentation = System.getProperty("apiDocs") != null ? Boolean.valueOf(System.getProperty("apiDocs")) : true; + generateModelTests = System.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true); + generateModelDocumentation = System.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true); + generateApiTests = System.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true); + generateApiDocumentation = System.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true); // Additional properties added for tests to exclude references in project related files @@ -595,7 +621,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { final String swaggerCodegenIgnore = ".swagger-codegen-ignore"; String ignoreFileNameTarget = config.outputFolder() + File.separator + swaggerCodegenIgnore; File ignoreFile = new File(ignoreFileNameTarget); - if (!ignoreFile.exists()) { + if (generateSwaggerMetadata && !ignoreFile.exists()) { String ignoreFileNameSource = File.separator + config.getCommonTemplateDir() + File.separator + swaggerCodegenIgnore; String ignoreFileContents = readResourceContents(ignoreFileNameSource); try { @@ -606,13 +632,15 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { files.add(ignoreFile); } - final String swaggerVersionMetadata = config.outputFolder() + File.separator + ".swagger-codegen" + File.separator + "VERSION"; - File swaggerVersionMetadataFile = new File(swaggerVersionMetadata); - try { - writeToFile(swaggerVersionMetadata, ImplementationVersion.read()); - files.add(swaggerVersionMetadataFile); - } catch (IOException e) { - throw new RuntimeException("Could not generate supporting file '" + swaggerVersionMetadata + "'", e); + if(generateSwaggerMetadata) { + final String swaggerVersionMetadata = config.outputFolder() + File.separator + ".swagger-codegen" + File.separator + "VERSION"; + File swaggerVersionMetadataFile = new File(swaggerVersionMetadata); + try { + writeToFile(swaggerVersionMetadata, ImplementationVersion.read()); + files.add(swaggerVersionMetadataFile); + } catch (IOException e) { + throw new RuntimeException("Could not generate supporting file '" + swaggerVersionMetadata + "'", e); + } } /* diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java index bbd06e02421..c2dc53c205c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java @@ -1,6 +1,7 @@ package io.swagger.codegen.languages; import io.swagger.codegen.*; +import io.swagger.codegen.utils.ModelUtils; import io.swagger.models.properties.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -296,6 +297,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co additionalProperties.put(CodegenConstants.INTERFACE_PREFIX, interfacePrefix); } + @Override + public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { + super.postProcessModelProperty(model, property); + } + @Override public Map postProcessModels(Map objs) { List models = (List) objs.get("models"); @@ -309,12 +315,69 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co if (var.name.equalsIgnoreCase(cm.name)) { var.name = "_" + var.name; } + + if(var.isEnum) { + // In C#, Enums are considered primitives because they're compiled to numerical types (int by default) + var.isPrimitiveType = true; + + // HACK: Consider Nullable as a container so we can properly handle unsupplied enum values as null. + var.isContainer = var.required; + } } } // process enum in models return postProcessModelsEnum(objs); } + @Override + public Map postProcessAllModels(Map objs) { + final Map processed = super.postProcessAllModels(objs); + postProcessEnumRefs(processed); + return processed; + } + + /** + * C# differs from other languages in that Enums are not _true_ objects; enums are compiled to integral types. + * So, in C#, an enum is considers more like a user-defined primitive. + * + * When working with enums, we can't always assume a RefModel is a nullable type (where default(YourType) == null), + * so this post processing runs through all models to find RefModel'd enums. Then, it runs through all vars and modifies + * those vars referencing RefModel'd enums to work the same as inlined enums rather than as objects. + * @param models + */ + private void postProcessEnumRefs(final Map models) { + Map enumRefs = new HashMap(); + for (Map.Entry entry : models.entrySet()) { + CodegenModel model = ModelUtils.getModelByName(entry.getKey(), models); + if (model.isEnum) { + enumRefs.put(entry.getKey(), model); + } + } + + for (Map.Entry entry : models.entrySet()) { + String swaggerName = entry.getKey(); + CodegenModel model = ModelUtils.getModelByName(swaggerName, models); + if (model != null) { + for (CodegenProperty var : model.allVars) { + if (enumRefs.containsKey(var.datatype)) { + // Handle any enum properties referred to by $ref. + // This is different in C# than most other generators, because enums in C# are compiled to integral types, + // while enums in many other languages are true objects. + CodegenModel refModel = enumRefs.get(var.datatype); + var.allowableValues = refModel.allowableValues; + updateCodegenPropertyEnum(var); + + // We do these after updateCodegenPropertyEnum to avoid generalities that don't mesh with C#. + var.isPrimitiveType = true; + var.isEnum = true; + } + } + } else { + LOGGER.warn("Expected to retrieve model %s by name, but no model was found. Check your -Dmodels inclusions.", swaggerName); + } + } + } + @Override public Map postProcessOperations(Map objs) { super.postProcessOperations(objs); diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index 69bee7bd9c9..5816ccd3ea6 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -505,11 +505,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { this.packageGuid = packageGuid; } - @Override - public Map postProcessModels(Map objMap) { - return super.postProcessModels(objMap); - } - @Override public void postProcessParameter(CodegenParameter parameter) { postProcessPattern(parameter.pattern, parameter.vendorExtensions); @@ -522,7 +517,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { super.postProcessModelProperty(model, property); } - /* * The swagger pattern spec follows the Perl convention and style of modifiers. .NET * does not support this syntax directly so we need to convert the pattern to a .NET compatible diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache index 990818fd328..ef9d93b8e3b 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache @@ -12,16 +12,18 @@ {{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>{{^netStandard}}{{#validatable}}, IValidatableObject{{/validatable}}{{/netStandard}} { {{#vars}} - {{#isEnum}} -{{>modelInnerEnum}} - {{/isEnum}} {{#items.isEnum}} {{#items}} + {{^complexType}} {{>modelInnerEnum}} + {{/complexType}} {{/items}} {{/items.isEnum}} - {{/vars}} - {{#vars}} + {{#isEnum}} + {{^complexType}} +{{>modelInnerEnum}} + {{/complexType}} + {{/isEnum}} {{#isEnum}} /// /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} @@ -30,7 +32,7 @@ /// {{description}} {{/description}} [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] - public {{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}?{{/isContainer}}{{/isEnum}} {{name}} { get; set; } + public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}?{{/isContainer}} {{name}} { get; set; } {{/isEnum}} {{/vars}} {{#hasRequired}} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/AbstractIntegrationTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/AbstractIntegrationTest.java index e65340b55bf..846ef4446bd 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/AbstractIntegrationTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/AbstractIntegrationTest.java @@ -3,6 +3,7 @@ package io.swagger.codegen; import static io.swagger.codegen.testutils.AssertFile.assertPathEqualsRecursively; import java.io.IOException; +import java.util.HashMap; import java.util.Map; import org.testng.annotations.Test; @@ -20,10 +21,19 @@ public abstract class AbstractIntegrationTest { protected abstract Map configProperties(); + protected Boolean generateSwaggerMetadata = true; + + protected Map systemPropertyOverrides = new HashMap<>(); + // @wing328: ignore for the time being until we fix the error with the integration test @Test(enabled = false) public void generatesCorrectDirectoryStructure() throws IOException { DefaultGenerator codeGen = new DefaultGenerator(); + codeGen.setGenerateSwaggerMetadata(generateSwaggerMetadata); + for (Map.Entry propertyOverride : systemPropertyOverrides.entrySet()) { + codeGen.setGeneratorPropertyDefault(propertyOverride.getKey(), propertyOverride.getValue()); + } + IntegrationTestPathsConfig integrationTestPathsConfig = getIntegrationTestPathsConfig(); String specContent = Files.readFile(integrationTestPathsConfig.getSpecPath().toFile()); @@ -31,7 +41,7 @@ public abstract class AbstractIntegrationTest { CodegenConfig codegenConfig = getCodegenConfig(); codegenConfig.setOutputDir(integrationTestPathsConfig.getOutputPath().toString()); - + codegenConfig.setIgnoreFilePathOverride(integrationTestPathsConfig.getIgnoreFilePath().toFile().toString()); ClientOpts clientOpts = new ClientOpts(); clientOpts.setProperties(configProperties()); ClientOptInput opts = new ClientOptInput() diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java new file mode 100644 index 00000000000..59df570bb19 --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java @@ -0,0 +1,53 @@ +package io.swagger.codegen.csharp; + +import com.google.common.collect.ImmutableMap; +import io.swagger.codegen.AbstractIntegrationTest; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.languages.CSharpClientCodegen; +import io.swagger.codegen.testutils.IntegrationTestPathsConfig; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class CsharpClientEnumRefIntegrationTest extends AbstractIntegrationTest { + public CsharpClientEnumRefIntegrationTest() { + generateSwaggerMetadata = false; + + ImmutableMap.Builder builder = new ImmutableMap.Builder(); + systemPropertyOverrides = builder + .put(CodegenConstants.APIS, Boolean.FALSE.toString()) + .put(CodegenConstants.MODELS, Boolean.TRUE.toString()) + .put(CodegenConstants.API_DOCS, Boolean.FALSE.toString()) + .put(CodegenConstants.MODEL_DOCS, Boolean.FALSE.toString()) + .put(CodegenConstants.API_TESTS, Boolean.FALSE.toString()) + .put(CodegenConstants.MODEL_TESTS, Boolean.FALSE.toString()) + .put(CodegenConstants.SUPPORTING_FILES, Boolean.FALSE.toString()) + .build(); + } + + @Override + protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { + return new IntegrationTestPathsConfig("csharp/enum-ref"); + } + + @Override + protected CodegenConfig getCodegenConfig() { + return new CSharpClientCodegen(); + } + + @Override + protected Map configProperties() { + Map properties = new HashMap<>(); + properties.put(CodegenConstants.EXCLUDE_TESTS, Boolean.TRUE.toString()); + return properties; + } + + // TODO: Remove this when super.generatesCorrectDirectoryStructure() is re-enabled. + @Test(description = "Verify csharp enums as ref properties") + public void test() throws IOException { + this.generatesCorrectDirectoryStructure(); + } +} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java new file mode 100644 index 00000000000..d5825c0621a --- /dev/null +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java @@ -0,0 +1,53 @@ +package io.swagger.codegen.csharp; + +import com.google.common.collect.ImmutableMap; +import io.swagger.codegen.AbstractIntegrationTest; +import io.swagger.codegen.CodegenConfig; +import io.swagger.codegen.CodegenConstants; +import io.swagger.codegen.languages.CSharpClientCodegen; +import io.swagger.codegen.testutils.IntegrationTestPathsConfig; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +public class CsharpClientInlineEnumIntegrationTest extends AbstractIntegrationTest { + public CsharpClientInlineEnumIntegrationTest() { + generateSwaggerMetadata = false; + + ImmutableMap.Builder builder = new ImmutableMap.Builder(); + systemPropertyOverrides = builder + .put(CodegenConstants.APIS, Boolean.FALSE.toString()) + .put(CodegenConstants.MODELS, Boolean.TRUE.toString()) + .put(CodegenConstants.API_DOCS, Boolean.FALSE.toString()) + .put(CodegenConstants.MODEL_DOCS, Boolean.FALSE.toString()) + .put(CodegenConstants.API_TESTS, Boolean.FALSE.toString()) + .put(CodegenConstants.MODEL_TESTS, Boolean.FALSE.toString()) + .put(CodegenConstants.SUPPORTING_FILES, Boolean.FALSE.toString()) + .build(); + } + + @Override + protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { + return new IntegrationTestPathsConfig("csharp/enum-inline"); + } + + @Override + protected CodegenConfig getCodegenConfig() { + return new CSharpClientCodegen(); + } + + @Override + protected Map configProperties() { + Map properties = new HashMap<>(); + properties.put(CodegenConstants.EXCLUDE_TESTS, Boolean.TRUE.toString()); + return properties; + } + + // TODO: Remove this when super.generatesCorrectDirectoryStructure() is re-enabled. + @Test(description = "Verify csharp enums as ref properties") + public void test() throws IOException { + this.generatesCorrectDirectoryStructure(); + } +} diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpModelEnumTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpModelEnumTest.java index 8a8b0a726b1..ae13bad0b36 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpModelEnumTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpModelEnumTest.java @@ -10,6 +10,7 @@ import io.swagger.models.Model; import io.swagger.models.ModelImpl; import io.swagger.models.RefModel; import io.swagger.models.properties.Property; +import io.swagger.models.properties.RefProperty; import io.swagger.models.properties.StringProperty; import org.testng.Assert; import org.testng.annotations.Test; diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/testutils/IntegrationTestPathsConfig.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/testutils/IntegrationTestPathsConfig.java index 4335c69dd2d..bb08d0bce27 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/testutils/IntegrationTestPathsConfig.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/testutils/IntegrationTestPathsConfig.java @@ -8,15 +8,17 @@ public class IntegrationTestPathsConfig { private final Path outputPath; private final Path specPath; private final Path expectedPath; + private final Path ignoreFilePath; public IntegrationTestPathsConfig(String location) { - this(location + "-spec.json", location + "-result", location + "-expected"); + this(location + "-spec.json", location + "-result", location + "-expected", location + ".ignore"); } - public IntegrationTestPathsConfig(String specLocation, String outputLocation, String expectedLocation) { + public IntegrationTestPathsConfig(String specLocation, String outputLocation, String expectedLocation, String ignoreFileLocation) { outputPath = INTEGRATION_TEST_PATH.resolve(outputLocation); expectedPath = INTEGRATION_TEST_PATH.resolve(expectedLocation); specPath = INTEGRATION_TEST_PATH.resolve(specLocation); + ignoreFilePath = INTEGRATION_TEST_PATH.resolve(ignoreFileLocation); } public Path getOutputPath() { @@ -30,4 +32,6 @@ public class IntegrationTestPathsConfig { public Path getExpectedPath() { return expectedPath; } -} \ No newline at end of file + + public Path getIgnoreFilePath() { return ignoreFilePath; } +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs new file mode 100644 index 00000000000..a15588f0d2d --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs @@ -0,0 +1,206 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// MyClassWithOptionalEnum + /// + [DataContract] + public partial class MyClassWithOptionalEnum : IEquatable, IValidatableObject + { + /// + /// Gets or Sets Days + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum DaysEnum + { + + /// + /// Enum Sun for "sun" + /// + [EnumMember(Value = "sun")] + Sun, + + /// + /// Enum Mon for "mon" + /// + [EnumMember(Value = "mon")] + Mon, + + /// + /// Enum Tue for "tue" + /// + [EnumMember(Value = "tue")] + Tue, + + /// + /// Enum Wed for "wed" + /// + [EnumMember(Value = "wed")] + Wed, + + /// + /// Enum Thu for "thu" + /// + [EnumMember(Value = "thu")] + Thu, + + /// + /// Enum Fri for "fri" + /// + [EnumMember(Value = "fri")] + Fri, + + /// + /// Enum Sat for "sat" + /// + [EnumMember(Value = "sat")] + Sat + } + + /// + /// Gets or Sets Days + /// + [DataMember(Name="days", EmitDefaultValue=false)] + public DaysEnum? Days { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// Quarantine. + /// Grayware. + /// Days. + public MyClassWithOptionalEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), DaysEnum? Days = default(DaysEnum?)) + { + this.Quarantine = Quarantine; + this.Grayware = Grayware; + this.Days = Days; + } + + /// + /// Gets or Sets Quarantine + /// + [DataMember(Name="quarantine", EmitDefaultValue=false)] + public bool? Quarantine { get; set; } + + /// + /// Gets or Sets Grayware + /// + [DataMember(Name="grayware", EmitDefaultValue=false)] + public bool? Grayware { get; set; } + + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class MyClassWithOptionalEnum {\n"); + sb.Append(" Quarantine: ").Append(Quarantine).Append("\n"); + sb.Append(" Grayware: ").Append(Grayware).Append("\n"); + sb.Append(" Days: ").Append(Days).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as MyClassWithOptionalEnum); + } + + /// + /// Returns true if MyClassWithOptionalEnum instances are equal + /// + /// Instance of MyClassWithOptionalEnum to be compared + /// Boolean + public bool Equals(MyClassWithOptionalEnum input) + { + if (input == null) + return false; + + return + ( + this.Quarantine == input.Quarantine || + (this.Quarantine != null && + this.Quarantine.Equals(input.Quarantine)) + ) && + ( + this.Grayware == input.Grayware || + (this.Grayware != null && + this.Grayware.Equals(input.Grayware)) + ) && + ( + this.Days == input.Days || + (this.Days != null && + this.Days.Equals(input.Days)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Quarantine != null) + hashCode = hashCode * 59 + this.Quarantine.GetHashCode(); + if (this.Grayware != null) + hashCode = hashCode * 59 + this.Grayware.GetHashCode(); + if (this.Days != null) + hashCode = hashCode * 59 + this.Days.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json new file mode 100644 index 00000000000..d3860aa3449 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json @@ -0,0 +1,59 @@ +{ + "swagger": "2.0", + "info": { + "version": "1", + "title": "My title" + }, + "host": "localhost:10010", + "basePath": "/", + "schemes": [ + "http", + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/": { + "get": { + "operationId": "getRoot", + "summary": "Root operation", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "200 OK Response" + } + } + } + } + }, + "definitions": { + "My_Class_With_Optional_Enum": { + "properties": { + "quarantine": { + "type": "boolean" + }, + "grayware": { + "type": "boolean" + }, + "days": { + "type": "string", + "enum": [ + "sun", + "mon", + "tue", + "wed", + "thu", + "fri", + "sat" + ] + } + } + } + } +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline.ignore b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline.ignore new file mode 100644 index 00000000000..48a88a03835 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline.ignore @@ -0,0 +1,9 @@ +!**/IO.Swagger/Model/*.cs +**/Api/ +**/Client/ +**/Properties +**/IO.Swagger.Test/ +**/* +*/* +.swagger-codegen/ +*/.* diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs new file mode 100644 index 00000000000..870174af6ec --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs @@ -0,0 +1,156 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// MyClassWithOptionalEnum + /// + [DataContract] + public partial class MyClassWithOptionalEnum : IEquatable, IValidatableObject + { + /// + /// Gets or Sets Days + /// + [DataMember(Name="days", EmitDefaultValue=false)] + public WeekDays? Days { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// Quarantine. + /// Grayware. + /// Days. + public MyClassWithOptionalEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), WeekDays? Days = default(WeekDays?)) + { + this.Quarantine = Quarantine; + this.Grayware = Grayware; + this.Days = Days; + } + + /// + /// Gets or Sets Quarantine + /// + [DataMember(Name="quarantine", EmitDefaultValue=false)] + public bool? Quarantine { get; set; } + + /// + /// Gets or Sets Grayware + /// + [DataMember(Name="grayware", EmitDefaultValue=false)] + public bool? Grayware { get; set; } + + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class MyClassWithOptionalEnum {\n"); + sb.Append(" Quarantine: ").Append(Quarantine).Append("\n"); + sb.Append(" Grayware: ").Append(Grayware).Append("\n"); + sb.Append(" Days: ").Append(Days).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as MyClassWithOptionalEnum); + } + + /// + /// Returns true if MyClassWithOptionalEnum instances are equal + /// + /// Instance of MyClassWithOptionalEnum to be compared + /// Boolean + public bool Equals(MyClassWithOptionalEnum input) + { + if (input == null) + return false; + + return + ( + this.Quarantine == input.Quarantine || + (this.Quarantine != null && + this.Quarantine.Equals(input.Quarantine)) + ) && + ( + this.Grayware == input.Grayware || + (this.Grayware != null && + this.Grayware.Equals(input.Grayware)) + ) && + ( + this.Days == input.Days || + (this.Days != null && + this.Days.Equals(input.Days)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Quarantine != null) + hashCode = hashCode * 59 + this.Quarantine.GetHashCode(); + if (this.Grayware != null) + hashCode = hashCode * 59 + this.Grayware.GetHashCode(); + if (this.Days != null) + hashCode = hashCode * 59 + this.Days.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs new file mode 100644 index 00000000000..ae81432d79b --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs @@ -0,0 +1,77 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// Defines WeekDays + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum WeekDays + { + + /// + /// Enum Sun for "sun" + /// + [EnumMember(Value = "sun")] + Sun, + + /// + /// Enum Mon for "mon" + /// + [EnumMember(Value = "mon")] + Mon, + + /// + /// Enum Tue for "tue" + /// + [EnumMember(Value = "tue")] + Tue, + + /// + /// Enum Wed for "wed" + /// + [EnumMember(Value = "wed")] + Wed, + + /// + /// Enum Thu for "thu" + /// + [EnumMember(Value = "thu")] + Thu, + + /// + /// Enum Fri for "fri" + /// + [EnumMember(Value = "fri")] + Fri, + + /// + /// Enum Sat for "sat" + /// + [EnumMember(Value = "sat")] + Sat + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-spec.json b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-spec.json new file mode 100644 index 00000000000..2330bc718a3 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-spec.json @@ -0,0 +1,62 @@ +{ + "swagger": "2.0", + "info": { + "version": "1", + "title": "My title" + }, + "host": "localhost:10010", + "basePath": "/", + "schemes": [ + "http", + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/": { + "get": { + "operationId": "getRoot", + "summary": "Root operation", + "produces": [ + "application/json" + ], + "responses": { + "200": { + "description": "200 OK Response" + } + } + } + } + }, + "definitions": { + "WeekDays": { + "type": "string", + "enum": [ + "sun", + "mon", + "tue", + "wed", + "thu", + "fri", + "sat" + ] + }, + "My_Class_With_Optional_Enum": { + "properties": { + "quarantine": { + "type": "boolean" + }, + "grayware": { + "type": "boolean" + }, + "days": { + "$ref": "#/definitions/WeekDays" + } + } + } + } +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref.ignore b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref.ignore new file mode 100644 index 00000000000..48a88a03835 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref.ignore @@ -0,0 +1,9 @@ +!**/IO.Swagger/Model/*.cs +**/Api/ +**/Client/ +**/Properties +**/IO.Swagger.Test/ +**/* +*/* +.swagger-codegen/ +*/.* From 08c8773b500e64805034e2f990b1fe18d187b575 Mon Sep 17 00:00:00 2001 From: James Schubert Date: Tue, 31 Oct 2017 12:48:29 -0400 Subject: [PATCH 2/7] Categorizing C# integration test for enums as general --- .../CsharpClientEnumRefIntegrationTest.java | 2 +- ...entGeneralEnumSupportIntegrationTest.java} | 8 +- .../Model/MyClassWithOptionalEnum.cs | 0 .../src/IO.Swagger/Model/WeekDays.cs | 0 .../csharp/{ => general}/enum-ref-spec.json | 0 .../csharp/{ => general}/enum-ref.ignore | 0 .../Model/MyClassWithOptionalEnum.cs | 54 +---- .../Model/MyClassWithOptionalInlineEnum.cs | 206 ++++++++++++++++++ .../src/IO.Swagger/Model/WeekDays.cs | 77 +++++++ .../enum-support-spec.json} | 25 +++ .../enum-support.ignore} | 0 11 files changed, 315 insertions(+), 57 deletions(-) rename modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/{CsharpClientInlineEnumIntegrationTest.java => CsharpClientGeneralEnumSupportIntegrationTest.java} (84%) rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{ => general}/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs (100%) rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{ => general}/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs (100%) rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{ => general}/enum-ref-spec.json (100%) rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{ => general}/enum-ref.ignore (100%) rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{enum-inline-expected => general/enum-support-expected}/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs (78%) create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{enum-inline-spec.json => general/enum-support-spec.json} (68%) rename modules/swagger-codegen/src/test/resources/integrationtests/csharp/{enum-inline.ignore => general/enum-support.ignore} (100%) diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java index 59df570bb19..34cbc0da9c6 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java @@ -30,7 +30,7 @@ public class CsharpClientEnumRefIntegrationTest extends AbstractIntegrationTest @Override protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { - return new IntegrationTestPathsConfig("csharp/enum-ref"); + return new IntegrationTestPathsConfig("csharp/general/enum-ref"); } @Override diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientGeneralEnumSupportIntegrationTest.java similarity index 84% rename from modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java rename to modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientGeneralEnumSupportIntegrationTest.java index d5825c0621a..3dc36696119 100644 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientInlineEnumIntegrationTest.java +++ b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientGeneralEnumSupportIntegrationTest.java @@ -12,8 +12,8 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -public class CsharpClientInlineEnumIntegrationTest extends AbstractIntegrationTest { - public CsharpClientInlineEnumIntegrationTest() { +public class CsharpClientGeneralEnumSupportIntegrationTest extends AbstractIntegrationTest { + public CsharpClientGeneralEnumSupportIntegrationTest() { generateSwaggerMetadata = false; ImmutableMap.Builder builder = new ImmutableMap.Builder(); @@ -30,7 +30,7 @@ public class CsharpClientInlineEnumIntegrationTest extends AbstractIntegrationTe @Override protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { - return new IntegrationTestPathsConfig("csharp/enum-inline"); + return new IntegrationTestPathsConfig("csharp/general/enum-support"); } @Override @@ -46,7 +46,7 @@ public class CsharpClientInlineEnumIntegrationTest extends AbstractIntegrationTe } // TODO: Remove this when super.generatesCorrectDirectoryStructure() is re-enabled. - @Test(description = "Verify csharp enums as ref properties") + @Test(description = "Verify csharp enum support, generalized across supported C# versions.") public void test() throws IOException { this.generatesCorrectDirectoryStructure(); } diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs similarity index 100% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs similarity index 100% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-spec.json b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-spec.json similarity index 100% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref-spec.json rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-spec.json diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref.ignore b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref.ignore similarity index 100% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-ref.ignore rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref.ignore diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs similarity index 78% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs index a15588f0d2d..870174af6ec 100644 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs @@ -30,68 +30,18 @@ namespace IO.Swagger.Model [DataContract] public partial class MyClassWithOptionalEnum : IEquatable, IValidatableObject { - /// - /// Gets or Sets Days - /// - [JsonConverter(typeof(StringEnumConverter))] - public enum DaysEnum - { - - /// - /// Enum Sun for "sun" - /// - [EnumMember(Value = "sun")] - Sun, - - /// - /// Enum Mon for "mon" - /// - [EnumMember(Value = "mon")] - Mon, - - /// - /// Enum Tue for "tue" - /// - [EnumMember(Value = "tue")] - Tue, - - /// - /// Enum Wed for "wed" - /// - [EnumMember(Value = "wed")] - Wed, - - /// - /// Enum Thu for "thu" - /// - [EnumMember(Value = "thu")] - Thu, - - /// - /// Enum Fri for "fri" - /// - [EnumMember(Value = "fri")] - Fri, - - /// - /// Enum Sat for "sat" - /// - [EnumMember(Value = "sat")] - Sat - } - /// /// Gets or Sets Days /// [DataMember(Name="days", EmitDefaultValue=false)] - public DaysEnum? Days { get; set; } + public WeekDays? Days { get; set; } /// /// Initializes a new instance of the class. /// /// Quarantine. /// Grayware. /// Days. - public MyClassWithOptionalEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), DaysEnum? Days = default(DaysEnum?)) + public MyClassWithOptionalEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), WeekDays? Days = default(WeekDays?)) { this.Quarantine = Quarantine; this.Grayware = Grayware; diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs new file mode 100644 index 00000000000..2146daae4de --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs @@ -0,0 +1,206 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// MyClassWithOptionalInlineEnum + /// + [DataContract] + public partial class MyClassWithOptionalInlineEnum : IEquatable, IValidatableObject + { + /// + /// Gets or Sets Days + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum DaysEnum + { + + /// + /// Enum Sun for "sun" + /// + [EnumMember(Value = "sun")] + Sun, + + /// + /// Enum Mon for "mon" + /// + [EnumMember(Value = "mon")] + Mon, + + /// + /// Enum Tue for "tue" + /// + [EnumMember(Value = "tue")] + Tue, + + /// + /// Enum Wed for "wed" + /// + [EnumMember(Value = "wed")] + Wed, + + /// + /// Enum Thu for "thu" + /// + [EnumMember(Value = "thu")] + Thu, + + /// + /// Enum Fri for "fri" + /// + [EnumMember(Value = "fri")] + Fri, + + /// + /// Enum Sat for "sat" + /// + [EnumMember(Value = "sat")] + Sat + } + + /// + /// Gets or Sets Days + /// + [DataMember(Name="days", EmitDefaultValue=false)] + public DaysEnum? Days { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// Quarantine. + /// Grayware. + /// Days. + public MyClassWithOptionalInlineEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), DaysEnum? Days = default(DaysEnum?)) + { + this.Quarantine = Quarantine; + this.Grayware = Grayware; + this.Days = Days; + } + + /// + /// Gets or Sets Quarantine + /// + [DataMember(Name="quarantine", EmitDefaultValue=false)] + public bool? Quarantine { get; set; } + + /// + /// Gets or Sets Grayware + /// + [DataMember(Name="grayware", EmitDefaultValue=false)] + public bool? Grayware { get; set; } + + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class MyClassWithOptionalInlineEnum {\n"); + sb.Append(" Quarantine: ").Append(Quarantine).Append("\n"); + sb.Append(" Grayware: ").Append(Grayware).Append("\n"); + sb.Append(" Days: ").Append(Days).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as MyClassWithOptionalInlineEnum); + } + + /// + /// Returns true if MyClassWithOptionalInlineEnum instances are equal + /// + /// Instance of MyClassWithOptionalInlineEnum to be compared + /// Boolean + public bool Equals(MyClassWithOptionalInlineEnum input) + { + if (input == null) + return false; + + return + ( + this.Quarantine == input.Quarantine || + (this.Quarantine != null && + this.Quarantine.Equals(input.Quarantine)) + ) && + ( + this.Grayware == input.Grayware || + (this.Grayware != null && + this.Grayware.Equals(input.Grayware)) + ) && + ( + this.Days == input.Days || + (this.Days != null && + this.Days.Equals(input.Days)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Quarantine != null) + hashCode = hashCode * 59 + this.Quarantine.GetHashCode(); + if (this.Grayware != null) + hashCode = hashCode * 59 + this.Grayware.GetHashCode(); + if (this.Days != null) + hashCode = hashCode * 59 + this.Days.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs new file mode 100644 index 00000000000..ae81432d79b --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs @@ -0,0 +1,77 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// Defines WeekDays + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum WeekDays + { + + /// + /// Enum Sun for "sun" + /// + [EnumMember(Value = "sun")] + Sun, + + /// + /// Enum Mon for "mon" + /// + [EnumMember(Value = "mon")] + Mon, + + /// + /// Enum Tue for "tue" + /// + [EnumMember(Value = "tue")] + Tue, + + /// + /// Enum Wed for "wed" + /// + [EnumMember(Value = "wed")] + Wed, + + /// + /// Enum Thu for "thu" + /// + [EnumMember(Value = "thu")] + Thu, + + /// + /// Enum Fri for "fri" + /// + [EnumMember(Value = "fri")] + Fri, + + /// + /// Enum Sat for "sat" + /// + [EnumMember(Value = "sat")] + Sat + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json similarity index 68% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json index d3860aa3449..ac230b1c5b8 100644 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline-spec.json +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json @@ -33,7 +33,32 @@ } }, "definitions": { + "WeekDays": { + "type": "string", + "enum": [ + "sun", + "mon", + "tue", + "wed", + "thu", + "fri", + "sat" + ] + }, "My_Class_With_Optional_Enum": { + "properties": { + "quarantine": { + "type": "boolean" + }, + "grayware": { + "type": "boolean" + }, + "days": { + "$ref": "#/definitions/WeekDays" + } + } + }, + "My_Class_With_Optional_Inline_Enum": { "properties": { "quarantine": { "type": "boolean" diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline.ignore b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support.ignore similarity index 100% rename from modules/swagger-codegen/src/test/resources/integrationtests/csharp/enum-inline.ignore rename to modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support.ignore From 8be610b9a44a5acd1c28daaff61328044cdd7992 Mon Sep 17 00:00:00 2001 From: James Schubert Date: Tue, 31 Oct 2017 12:49:50 -0400 Subject: [PATCH 3/7] [csharp] Remove enum-ref integration test --- .../CsharpClientEnumRefIntegrationTest.java | 53 ------ .../Model/MyClassWithOptionalEnum.cs | 156 ------------------ .../src/IO.Swagger/Model/WeekDays.cs | 77 --------- .../csharp/general/enum-ref-spec.json | 62 ------- .../csharp/general/enum-ref.ignore | 9 - 5 files changed, 357 deletions(-) delete mode 100644 modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java delete mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs delete mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs delete mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-spec.json delete mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref.ignore diff --git a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java b/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java deleted file mode 100644 index 34cbc0da9c6..00000000000 --- a/modules/swagger-codegen/src/test/java/io/swagger/codegen/csharp/CsharpClientEnumRefIntegrationTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.swagger.codegen.csharp; - -import com.google.common.collect.ImmutableMap; -import io.swagger.codegen.AbstractIntegrationTest; -import io.swagger.codegen.CodegenConfig; -import io.swagger.codegen.CodegenConstants; -import io.swagger.codegen.languages.CSharpClientCodegen; -import io.swagger.codegen.testutils.IntegrationTestPathsConfig; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -public class CsharpClientEnumRefIntegrationTest extends AbstractIntegrationTest { - public CsharpClientEnumRefIntegrationTest() { - generateSwaggerMetadata = false; - - ImmutableMap.Builder builder = new ImmutableMap.Builder(); - systemPropertyOverrides = builder - .put(CodegenConstants.APIS, Boolean.FALSE.toString()) - .put(CodegenConstants.MODELS, Boolean.TRUE.toString()) - .put(CodegenConstants.API_DOCS, Boolean.FALSE.toString()) - .put(CodegenConstants.MODEL_DOCS, Boolean.FALSE.toString()) - .put(CodegenConstants.API_TESTS, Boolean.FALSE.toString()) - .put(CodegenConstants.MODEL_TESTS, Boolean.FALSE.toString()) - .put(CodegenConstants.SUPPORTING_FILES, Boolean.FALSE.toString()) - .build(); - } - - @Override - protected IntegrationTestPathsConfig getIntegrationTestPathsConfig() { - return new IntegrationTestPathsConfig("csharp/general/enum-ref"); - } - - @Override - protected CodegenConfig getCodegenConfig() { - return new CSharpClientCodegen(); - } - - @Override - protected Map configProperties() { - Map properties = new HashMap<>(); - properties.put(CodegenConstants.EXCLUDE_TESTS, Boolean.TRUE.toString()); - return properties; - } - - // TODO: Remove this when super.generatesCorrectDirectoryStructure() is re-enabled. - @Test(description = "Verify csharp enums as ref properties") - public void test() throws IOException { - this.generatesCorrectDirectoryStructure(); - } -} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs deleted file mode 100644 index 870174af6ec..00000000000 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/MyClassWithOptionalEnum.cs +++ /dev/null @@ -1,156 +0,0 @@ -/* - * My title - * - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) - * - * OpenAPI spec version: 1 - * - * Generated by: https://github.com/swagger-api/swagger-codegen.git - */ - -using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Runtime.Serialization; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using System.ComponentModel.DataAnnotations; -using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; - -namespace IO.Swagger.Model -{ - /// - /// MyClassWithOptionalEnum - /// - [DataContract] - public partial class MyClassWithOptionalEnum : IEquatable, IValidatableObject - { - /// - /// Gets or Sets Days - /// - [DataMember(Name="days", EmitDefaultValue=false)] - public WeekDays? Days { get; set; } - /// - /// Initializes a new instance of the class. - /// - /// Quarantine. - /// Grayware. - /// Days. - public MyClassWithOptionalEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), WeekDays? Days = default(WeekDays?)) - { - this.Quarantine = Quarantine; - this.Grayware = Grayware; - this.Days = Days; - } - - /// - /// Gets or Sets Quarantine - /// - [DataMember(Name="quarantine", EmitDefaultValue=false)] - public bool? Quarantine { get; set; } - - /// - /// Gets or Sets Grayware - /// - [DataMember(Name="grayware", EmitDefaultValue=false)] - public bool? Grayware { get; set; } - - - /// - /// Returns the string presentation of the object - /// - /// String presentation of the object - public override string ToString() - { - var sb = new StringBuilder(); - sb.Append("class MyClassWithOptionalEnum {\n"); - sb.Append(" Quarantine: ").Append(Quarantine).Append("\n"); - sb.Append(" Grayware: ").Append(Grayware).Append("\n"); - sb.Append(" Days: ").Append(Days).Append("\n"); - sb.Append("}\n"); - return sb.ToString(); - } - - /// - /// Returns the JSON string presentation of the object - /// - /// JSON string presentation of the object - public string ToJson() - { - return JsonConvert.SerializeObject(this, Formatting.Indented); - } - - /// - /// Returns true if objects are equal - /// - /// Object to be compared - /// Boolean - public override bool Equals(object input) - { - return this.Equals(input as MyClassWithOptionalEnum); - } - - /// - /// Returns true if MyClassWithOptionalEnum instances are equal - /// - /// Instance of MyClassWithOptionalEnum to be compared - /// Boolean - public bool Equals(MyClassWithOptionalEnum input) - { - if (input == null) - return false; - - return - ( - this.Quarantine == input.Quarantine || - (this.Quarantine != null && - this.Quarantine.Equals(input.Quarantine)) - ) && - ( - this.Grayware == input.Grayware || - (this.Grayware != null && - this.Grayware.Equals(input.Grayware)) - ) && - ( - this.Days == input.Days || - (this.Days != null && - this.Days.Equals(input.Days)) - ); - } - - /// - /// Gets the hash code - /// - /// Hash code - public override int GetHashCode() - { - unchecked // Overflow is fine, just wrap - { - int hashCode = 41; - if (this.Quarantine != null) - hashCode = hashCode * 59 + this.Quarantine.GetHashCode(); - if (this.Grayware != null) - hashCode = hashCode * 59 + this.Grayware.GetHashCode(); - if (this.Days != null) - hashCode = hashCode * 59 + this.Days.GetHashCode(); - return hashCode; - } - } - - /// - /// To validate all properties of the instance - /// - /// Validation context - /// Validation Result - IEnumerable IValidatableObject.Validate(ValidationContext validationContext) - { - yield break; - } - } - -} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs deleted file mode 100644 index ae81432d79b..00000000000 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-expected/src/IO.Swagger/Model/WeekDays.cs +++ /dev/null @@ -1,77 +0,0 @@ -/* - * My title - * - * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) - * - * OpenAPI spec version: 1 - * - * Generated by: https://github.com/swagger-api/swagger-codegen.git - */ - -using System; -using System.Linq; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Runtime.Serialization; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using System.ComponentModel.DataAnnotations; -using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; - -namespace IO.Swagger.Model -{ - /// - /// Defines WeekDays - /// - [JsonConverter(typeof(StringEnumConverter))] - public enum WeekDays - { - - /// - /// Enum Sun for "sun" - /// - [EnumMember(Value = "sun")] - Sun, - - /// - /// Enum Mon for "mon" - /// - [EnumMember(Value = "mon")] - Mon, - - /// - /// Enum Tue for "tue" - /// - [EnumMember(Value = "tue")] - Tue, - - /// - /// Enum Wed for "wed" - /// - [EnumMember(Value = "wed")] - Wed, - - /// - /// Enum Thu for "thu" - /// - [EnumMember(Value = "thu")] - Thu, - - /// - /// Enum Fri for "fri" - /// - [EnumMember(Value = "fri")] - Fri, - - /// - /// Enum Sat for "sat" - /// - [EnumMember(Value = "sat")] - Sat - } - -} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-spec.json b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-spec.json deleted file mode 100644 index 2330bc718a3..00000000000 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref-spec.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "version": "1", - "title": "My title" - }, - "host": "localhost:10010", - "basePath": "/", - "schemes": [ - "http", - "https" - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/": { - "get": { - "operationId": "getRoot", - "summary": "Root operation", - "produces": [ - "application/json" - ], - "responses": { - "200": { - "description": "200 OK Response" - } - } - } - } - }, - "definitions": { - "WeekDays": { - "type": "string", - "enum": [ - "sun", - "mon", - "tue", - "wed", - "thu", - "fri", - "sat" - ] - }, - "My_Class_With_Optional_Enum": { - "properties": { - "quarantine": { - "type": "boolean" - }, - "grayware": { - "type": "boolean" - }, - "days": { - "$ref": "#/definitions/WeekDays" - } - } - } - } -} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref.ignore b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref.ignore deleted file mode 100644 index 48a88a03835..00000000000 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-ref.ignore +++ /dev/null @@ -1,9 +0,0 @@ -!**/IO.Swagger/Model/*.cs -**/Api/ -**/Client/ -**/Properties -**/IO.Swagger.Test/ -**/* -*/* -.swagger-codegen/ -*/.* From 72b9ab6cab137a578ebefebd6796eb939ec10081 Mon Sep 17 00:00:00 2001 From: James Schubert Date: Tue, 31 Oct 2017 14:17:13 -0400 Subject: [PATCH 4/7] [csharp] Clean up general enum support integration test, validate different enum usage cases. --- .../io/swagger/codegen/DefaultGenerator.java | 8 + .../languages/AbstractCSharpCodegen.java | 14 +- .../resources/csharp/modelGeneric.mustache | 4 +- ...yClassWithInvalidRequiredEnumUsageOnRef.cs | 140 +++++++++++ .../Model/MyClassWithRequiredInlineEnum.cs | 219 ++++++++++++++++++ .../csharp/general/enum-support-spec.json | 41 ++++ .../csharp/general/enum-support.sh | 14 ++ 7 files changed, 430 insertions(+), 10 deletions(-) create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithInvalidRequiredEnumUsageOnRef.cs create mode 100644 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs create mode 100755 modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support.sh diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index ccfdda11082..2c166e69577 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -63,6 +63,12 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { return this; } + /** + * Programmatically disable the output of .swagger-codegen/VERSION, .swagger-codegen-ignore, + * or other metadata files used by Swagger Codegen. + * @param generateSwaggerMetadata true: enable outputs, false: disable outputs + */ + @SuppressWarnings("WeakerAccess") public void setGenerateSwaggerMetadata(Boolean generateSwaggerMetadata) { this.generateSwaggerMetadata = generateSwaggerMetadata; } @@ -73,6 +79,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { * @param key The system property key * @param value The system property value */ + @SuppressWarnings("WeakerAccess") public void setGeneratorPropertyDefault(final String key, final String value) { this.generatorPropertyDefaults.put(key, value); } @@ -116,6 +123,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { private void configureGeneratorProperties() { // allows generating only models by specifying a CSV of models to generate, or empty for all + // NOTE: Boolean.TRUE is required below rather than `true` because of JVM boxing constraints and type inference. generateApis = System.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null); generateModels = System.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null); generateSupportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null); diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java index c2dc53c205c..243c75d8bd1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java @@ -315,20 +315,18 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co if (var.name.equalsIgnoreCase(cm.name)) { var.name = "_" + var.name; } - - if(var.isEnum) { - // In C#, Enums are considered primitives because they're compiled to numerical types (int by default) - var.isPrimitiveType = true; - - // HACK: Consider Nullable as a container so we can properly handle unsupplied enum values as null. - var.isContainer = var.required; - } } } // process enum in models return postProcessModelsEnum(objs); } + /** + * Invoked by {@link DefaultGenerator} after all models have been post-processed, allowing for a last pass of codegen-specific model cleanup. + * + * @param objs Current state of codegen object model. + * @return An in-place modified state of the codegen object model. + */ @Override public Map postProcessAllModels(Map objs) { final Map processed = super.postProcessAllModels(objs); diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache index ef9d93b8e3b..74d2bddc1e8 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelGeneric.mustache @@ -32,7 +32,7 @@ /// {{description}} {{/description}} [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] - public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}?{{/isContainer}} {{name}} { get; set; } + public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; } {{/isEnum}} {{/vars}} {{#hasRequired}} @@ -55,7 +55,7 @@ {{#hasOnlyReadOnly}} [JsonConstructorAttribute] {{/hasOnlyReadOnly}} - public {{classname}}({{#readWriteVars}}{{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}?{{/isContainer}}{{/isEnum}} {{name}} = {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}default({{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}?{{/isContainer}}{{/isEnum}}){{/defaultValue}}{{^-last}}, {{/-last}}{{/readWriteVars}}){{#parent}} : base({{#parentVars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}} + public {{classname}}({{#readWriteVars}}{{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}}{{/isEnum}} {{name}} = {{#defaultValue}}{{{defaultValue}}}{{/defaultValue}}{{^defaultValue}}default({{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}}{{/isEnum}}){{/defaultValue}}{{^-last}}, {{/-last}}{{/readWriteVars}}){{#parent}} : base({{#parentVars}}{{name}}{{#hasMore}}, {{/hasMore}}{{/parentVars}}){{/parent}} { {{#vars}} {{^isInherited}} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithInvalidRequiredEnumUsageOnRef.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithInvalidRequiredEnumUsageOnRef.cs new file mode 100644 index 00000000000..2a9a895ecb2 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithInvalidRequiredEnumUsageOnRef.cs @@ -0,0 +1,140 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// Invalid use of required on $ref enum, per Swagger 2.0 spec: Any members other than '$ref' in a JSON Reference object SHALL be ignored. See My_Class_With_Required_Inline_Enum for appropriate usage. + /// + [DataContract] + public partial class MyClassWithInvalidRequiredEnumUsageOnRef : IEquatable, IValidatableObject + { + /// + /// Gets or Sets Days + /// + [DataMember(Name="days", EmitDefaultValue=false)] + public WeekDays? Days { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// First. + /// Days. + public MyClassWithInvalidRequiredEnumUsageOnRef(bool? First = default(bool?), WeekDays? Days = default(WeekDays?)) + { + this.First = First; + this.Days = Days; + } + + /// + /// Gets or Sets First + /// + [DataMember(Name="first", EmitDefaultValue=false)] + public bool? First { get; set; } + + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class MyClassWithInvalidRequiredEnumUsageOnRef {\n"); + sb.Append(" First: ").Append(First).Append("\n"); + sb.Append(" Days: ").Append(Days).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as MyClassWithInvalidRequiredEnumUsageOnRef); + } + + /// + /// Returns true if MyClassWithInvalidRequiredEnumUsageOnRef instances are equal + /// + /// Instance of MyClassWithInvalidRequiredEnumUsageOnRef to be compared + /// Boolean + public bool Equals(MyClassWithInvalidRequiredEnumUsageOnRef input) + { + if (input == null) + return false; + + return + ( + this.First == input.First || + (this.First != null && + this.First.Equals(input.First)) + ) && + ( + this.Days == input.Days || + (this.Days != null && + this.Days.Equals(input.Days)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.First != null) + hashCode = hashCode * 59 + this.First.GetHashCode(); + if (this.Days != null) + hashCode = hashCode * 59 + this.Days.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs new file mode 100644 index 00000000000..fb43dccce3f --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs @@ -0,0 +1,219 @@ +/* + * My title + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * OpenAPI spec version: 1 + * + * Generated by: https://github.com/swagger-api/swagger-codegen.git + */ + +using System; +using System.Linq; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.ComponentModel.DataAnnotations; +using SwaggerDateConverter = IO.Swagger.Client.SwaggerDateConverter; + +namespace IO.Swagger.Model +{ + /// + /// MyClassWithRequiredInlineEnum + /// + [DataContract] + public partial class MyClassWithRequiredInlineEnum : IEquatable, IValidatableObject + { + /// + /// Gets or Sets Days + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum DaysEnum + { + + /// + /// Enum Sun for "sun" + /// + [EnumMember(Value = "sun")] + Sun, + + /// + /// Enum Mon for "mon" + /// + [EnumMember(Value = "mon")] + Mon, + + /// + /// Enum Tue for "tue" + /// + [EnumMember(Value = "tue")] + Tue, + + /// + /// Enum Wed for "wed" + /// + [EnumMember(Value = "wed")] + Wed, + + /// + /// Enum Thu for "thu" + /// + [EnumMember(Value = "thu")] + Thu, + + /// + /// Enum Fri for "fri" + /// + [EnumMember(Value = "fri")] + Fri, + + /// + /// Enum Sat for "sat" + /// + [EnumMember(Value = "sat")] + Sat + } + + /// + /// Gets or Sets Days + /// + [DataMember(Name="days", EmitDefaultValue=false)] + public DaysEnum Days { get; set; } + /// + /// Initializes a new instance of the class. + /// + [JsonConstructorAttribute] + protected MyClassWithRequiredInlineEnum() { } + /// + /// Initializes a new instance of the class. + /// + /// Quarantine. + /// Grayware. + /// Days (required). + public MyClassWithRequiredInlineEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), DaysEnum Days = default(DaysEnum)) + { + // to ensure "Days" is required (not null) + if (Days == null) + { + throw new InvalidDataException("Days is a required property for MyClassWithRequiredInlineEnum and cannot be null"); + } + else + { + this.Days = Days; + } + this.Quarantine = Quarantine; + this.Grayware = Grayware; + } + + /// + /// Gets or Sets Quarantine + /// + [DataMember(Name="quarantine", EmitDefaultValue=false)] + public bool? Quarantine { get; set; } + + /// + /// Gets or Sets Grayware + /// + [DataMember(Name="grayware", EmitDefaultValue=false)] + public bool? Grayware { get; set; } + + + /// + /// Returns the string presentation of the object + /// + /// String presentation of the object + public override string ToString() + { + var sb = new StringBuilder(); + sb.Append("class MyClassWithRequiredInlineEnum {\n"); + sb.Append(" Quarantine: ").Append(Quarantine).Append("\n"); + sb.Append(" Grayware: ").Append(Grayware).Append("\n"); + sb.Append(" Days: ").Append(Days).Append("\n"); + sb.Append("}\n"); + return sb.ToString(); + } + + /// + /// Returns the JSON string presentation of the object + /// + /// JSON string presentation of the object + public string ToJson() + { + return JsonConvert.SerializeObject(this, Formatting.Indented); + } + + /// + /// Returns true if objects are equal + /// + /// Object to be compared + /// Boolean + public override bool Equals(object input) + { + return this.Equals(input as MyClassWithRequiredInlineEnum); + } + + /// + /// Returns true if MyClassWithRequiredInlineEnum instances are equal + /// + /// Instance of MyClassWithRequiredInlineEnum to be compared + /// Boolean + public bool Equals(MyClassWithRequiredInlineEnum input) + { + if (input == null) + return false; + + return + ( + this.Quarantine == input.Quarantine || + (this.Quarantine != null && + this.Quarantine.Equals(input.Quarantine)) + ) && + ( + this.Grayware == input.Grayware || + (this.Grayware != null && + this.Grayware.Equals(input.Grayware)) + ) && + ( + this.Days == input.Days || + (this.Days != null && + this.Days.Equals(input.Days)) + ); + } + + /// + /// Gets the hash code + /// + /// Hash code + public override int GetHashCode() + { + unchecked // Overflow is fine, just wrap + { + int hashCode = 41; + if (this.Quarantine != null) + hashCode = hashCode * 59 + this.Quarantine.GetHashCode(); + if (this.Grayware != null) + hashCode = hashCode * 59 + this.Grayware.GetHashCode(); + if (this.Days != null) + hashCode = hashCode * 59 + this.Days.GetHashCode(); + return hashCode; + } + } + + /// + /// To validate all properties of the instance + /// + /// Validation context + /// Validation Result + IEnumerable IValidatableObject.Validate(ValidationContext validationContext) + { + yield break; + } + } + +} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json index ac230b1c5b8..99f0dba3974 100644 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-spec.json @@ -58,6 +58,23 @@ } } }, + + "My_Class_With_Invalid_Required_Enum_Usage_On_Ref": { + "description": "Invalid use of required on $ref enum, per Swagger 2.0 spec: Any members other than '$ref' in a JSON Reference object SHALL be ignored. See My_Class_With_Required_Inline_Enum for appropriate usage.", + "properties": { + "first": { + "type": "boolean" + }, + "days": { + "$ref": "#/definitions/WeekDays", + "required": true + }, + "second": { + "type": "int" + } + } + }, + "My_Class_With_Optional_Inline_Enum": { "properties": { "quarantine": { @@ -79,6 +96,30 @@ ] } } + }, + + "My_Class_With_Required_Inline_Enum": { + "required": [ "days" ], + "properties": { + "quarantine": { + "type": "boolean" + }, + "grayware": { + "type": "boolean" + }, + "days": { + "type": "string", + "enum": [ + "sun", + "mon", + "tue", + "wed", + "thu", + "fri", + "sat" + ] + } + } } } } diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support.sh b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support.sh new file mode 100755 index 00000000000..896022ab737 --- /dev/null +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +set -euo pipefail + +declare opts="-DdebugModels -Dproject -Dmodels -DmodelTests=false -DmodelDocs=false $JAVA_OPTS" +declare curdir=$(cd $(dirname "${BASH_SOURCE}") && pwd) + +# NOTE: This is sensitive to the location of this script. +declare clijar=${SWAGGER_CODEGEN_CLI_JAR:-$(cd $curdir && cd ../../../../../../../swagger-codegen-cli/target/ && echo $PWD)/swagger-codegen-cli.jar} + +exec \java ${opts} -jar ${clijar} generate \ + -i enum-support-spec.json -l csharp \ + --additional-properties targetFramework=v4.5 \ + -o enum-support-expected; From 1058728777b64acc11dc2e109758e2c3a2bf0592 Mon Sep 17 00:00:00 2001 From: James Schubert Date: Sat, 4 Nov 2017 17:22:23 -0400 Subject: [PATCH 5/7] [csharp] Clean up ref/inner enum struture Enums defines as ref models have a different object structure (CodegenModel) than those defined as inner enums (CodegenProperty). To make these look as similar as possible, we walk all ref model enums and reassign enumVars with the same properties inherited from the top level CodegenProperty so CodegenModel enums can use the same templates as inner enums. --- .../io/swagger/codegen/DefaultCodegen.java | 2 + .../languages/AbstractCSharpCodegen.java | 132 ++++++++++++++---- .../languages/CSharpClientCodegen.java | 17 +-- .../main/resources/csharp/enumClass.mustache | 17 --- .../main/resources/csharp/modelEnum.mustache | 12 +- .../resources/csharp/modelInnerEnum.mustache | 12 +- .../Model/MyClassWithOptionalInlineEnum.cs | 16 +-- .../Model/MyClassWithRequiredInlineEnum.cs | 16 +-- .../src/IO.Swagger/Model/WeekDays.cs | 16 ++- 9 files changed, 146 insertions(+), 94 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java index 2e8b0ebab5b..c80f2373bff 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultCodegen.java @@ -1955,6 +1955,8 @@ public class DefaultCodegen { if (property.defaultValue != null) { property.defaultValue = property.defaultValue.replace(baseItem.baseType, toEnumName(baseItem)); } + + updateCodegenPropertyEnum(property); } } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java index 243c75d8bd1..a97545615e3 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java @@ -1,5 +1,7 @@ package io.swagger.codegen.languages; +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; import io.swagger.codegen.*; import io.swagger.codegen.utils.ModelUtils; import io.swagger.models.properties.*; @@ -8,6 +10,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; +import java.io.IOException; +import java.io.Writer; import java.util.*; public abstract class AbstractCSharpCodegen extends DefaultCodegen implements CodegenConfig { @@ -343,6 +347,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co * those vars referencing RefModel'd enums to work the same as inlined enums rather than as objects. * @param models */ + @SuppressWarnings({ "unchecked" }) private void postProcessEnumRefs(final Map models) { Map enumRefs = new HashMap(); for (Map.Entry entry : models.entrySet()) { @@ -354,6 +359,7 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co for (Map.Entry entry : models.entrySet()) { String swaggerName = entry.getKey(); + CodegenModel model = ModelUtils.getModelByName(swaggerName, models); if (model != null) { for (CodegenProperty var : model.allVars) { @@ -363,11 +369,57 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co // while enums in many other languages are true objects. CodegenModel refModel = enumRefs.get(var.datatype); var.allowableValues = refModel.allowableValues; + var.isEnum = true; + updateCodegenPropertyEnum(var); - // We do these after updateCodegenPropertyEnum to avoid generalities that don't mesh with C#. + // We do this after updateCodegenPropertyEnum to avoid generalities that don't mesh with C#. var.isPrimitiveType = true; - var.isEnum = true; + } + } + + // We're looping all models here. + if (model.isEnum) { + // We now need to make allowableValues.enumVars look like the context of CodegenProperty + Boolean isString = false; + Boolean isInteger = false; + Boolean isLong = false; + Boolean isByte = false; + + if (model.dataType.startsWith("byte")) { + // C# Actually supports byte and short enums, swagger spec only supports byte. + isByte = true; + model.vendorExtensions.put("x-enum-byte", true); + } else if (model.dataType.startsWith("int32")) { + isInteger = true; + model.vendorExtensions.put("x-enum-integer", true); + } else if (model.dataType.startsWith("int64")) { + isLong = true; + model.vendorExtensions.put("x-enum-long", true); + } else { + // C# doesn't support non-integral enums, so we need to treat everything else as strings (e.g. to not lose precision or data integrity) + isString = true; + model.vendorExtensions.put("x-enum-string", true); + } + + // Since we iterate enumVars for modelnnerEnum and enumClass templates, and CodegenModel is missing some of CodegenProperty's properties, + // we can take advantage of Mustache's contextual lookup to add the same "properties" to the model's enumVars scope rather than CodegenProperty's scope. + List> enumVars = (ArrayList>)model.allowableValues.get("enumVars"); + List> newEnumVars = new ArrayList>(); + for (Map enumVar : enumVars) { + Map mixedVars = new HashMap(); + mixedVars.putAll(enumVar); + + mixedVars.put("isString", isString); + mixedVars.put("isLong", isLong); + mixedVars.put("isInteger", isInteger); + mixedVars.put("isByte", isByte); + + newEnumVars.add(mixedVars); + } + + if (!newEnumVars.isEmpty()) { + model.allowableValues.put("enumVars", newEnumVars); } } } else { @@ -376,6 +428,42 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co } } + /** + * Update codegen property's enum by adding "enumVars" (with name and value) + * + * @param var list of CodegenProperty + */ + @Override + public void updateCodegenPropertyEnum(CodegenProperty var) { + if (var.vendorExtensions == null) { + var.vendorExtensions = new HashMap<>(); + } + + super.updateCodegenPropertyEnum(var); + + // Because C# uses nullable primitives for datatype, and datatype is used in DefaultCodegen for determining enum-ness, guard against weirdness here. + if (var.isEnum) { + if ("byte".equals(var.dataFormat)) {// C# Actually supports byte and short enums. + var.vendorExtensions.put("x-enum-byte", true); + var.isString = false; + var.isLong = false; + var.isInteger = false; + } else if ("int32".equals(var.dataFormat)) { + var.isInteger = true; + var.isString = false; + var.isLong = false; + } else if ("int64".equals(var.dataFormat)) { + var.isLong = true; + var.isString = false; + var.isInteger = false; + } else {// C# doesn't support non-integral enums, so we need to treat everything else as strings (e.g. to not lose precision or data integrity) + var.isString = true; + var.isInteger = false; + var.isLong = false; + } + } + } + @Override public Map postProcessOperations(Map objs) { super.postProcessOperations(objs); @@ -746,6 +834,19 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co this.interfacePrefix = interfacePrefix; } + @Override + public String toEnumValue(String value, String datatype) { + // C# only supports enums as literals for int, int?, long, long?, byte, and byte?. All else must be treated as strings. + // Per: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/enum + // The approved types for an enum are byte, sbyte, short, ushort, int, uint, long, or ulong. + // but we're not supporting unsigned integral types or shorts. + if(datatype.startsWith("int") || datatype.startsWith("long") || datatype.startsWith("byte")) { + return value; + } + + return escapeText(value); + } + @Override public String toEnumVarName(String name, String datatype) { if (name.length() == 0) { @@ -776,32 +877,6 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co return sanitizeName(camelize(property.name)) + "Enum"; } - /* - @Override - public String toEnumName(CodegenProperty property) { - String enumName = sanitizeName(property.name); - if (!StringUtils.isEmpty(modelNamePrefix)) { - enumName = modelNamePrefix + "_" + enumName; - } - - if (!StringUtils.isEmpty(modelNameSuffix)) { - enumName = enumName + "_" + modelNameSuffix; - } - - // model name cannot use reserved keyword, e.g. return - if (isReservedWord(enumName)) { - LOGGER.warn(enumName + " (reserved word) cannot be used as model name. Renamed to " + camelize("model_" + enumName)); - enumName = "model_" + enumName; // e.g. return => ModelReturn (after camelize) - } - - if (enumName.matches("\\d.*")) { // starts with number - return "_" + enumName; - } else { - return enumName; - } - } - */ - public String testPackageName() { return this.packageName + ".Test"; } @@ -816,5 +891,4 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co public String escapeUnsafeCharacters(String input) { return input.replace("*/", "*_/").replace("/*", "/_*").replace("--", "- -"); } - } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java index 5816ccd3ea6..b40bdff2a9c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/CSharpClientCodegen.java @@ -611,19 +611,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { return codegenModel; } - @Override - public String toEnumValue(String value, String datatype) { - if ("int?".equalsIgnoreCase(datatype) || "long?".equalsIgnoreCase(datatype) || - "double?".equalsIgnoreCase(datatype) || "float?".equalsIgnoreCase(datatype)) { - return value; - } else if ("float?".equalsIgnoreCase(datatype)) { - // for float in C#, append "f". e.g. 3.14 => 3.14f - return value + "f"; - } else { - return "\"" + escapeText(value) + "\""; - } - } - @Override public String toEnumVarName(String value, String datatype) { if (value.length() == 0) { @@ -636,8 +623,8 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { } // number - if ("int?".equals(datatype) || "long?".equals(datatype) || - "double?".equals(datatype) || "float?".equals(datatype)) { + if(datatype.startsWith("int") || datatype.startsWith("long") || + datatype.startsWith("double") || datatype.startsWith("float")) { String varName = "NUMBER_" + value; varName = varName.replaceAll("-", "MINUS_"); varName = varName.replaceAll("\\+", "PLUS_"); diff --git a/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache b/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache deleted file mode 100644 index d8d5d4185dd..00000000000 --- a/modules/swagger-codegen/src/main/resources/csharp/enumClass.mustache +++ /dev/null @@ -1,17 +0,0 @@ - /// - /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} - /// - {{#description}} - /// {{description}} - {{/description}} - [JsonConverter(typeof(StringEnumConverter))] - {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} - { - {{#allowableValues}}{{#enumVars}} - /// - /// Enum {{name}} for {{{value}}} - /// - [EnumMember(Value = {{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isFloat}}"{{/isFloat}}{{#isDouble}}"{{/isDouble}}{{{value}}}{{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isFloat}}"{{/isFloat}})] - {{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^-last}}, - {{/-last}}{{/enumVars}}{{/allowableValues}} - } diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache index 64e50883f8d..9d91ab60e0e 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelEnum.mustache @@ -4,14 +4,16 @@ {{#description}} /// {{description}} {{/description}} + {{#allowableValues}}{{#enumVars}}{{#-first}}{{#isString}} [JsonConverter(typeof(StringEnumConverter))] - {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{/isString}}{{/-first}}{{/enumVars}}{{/allowableValues}} + {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}} { {{#allowableValues}}{{#enumVars}} /// - /// Enum {{name}} for {{{value}}} + /// Enum {{name}} for value: {{{value}}} /// - [EnumMember(Value = {{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{{value}}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}})] - {{name}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^-last}}, + {{#isString}}[EnumMember(Value = "{{{value}}}")]{{/isString}} + {{name}}{{^isString}} = {{{value}}}{{/isString}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} - } + }{{! NOTE: This model's enumVars is modified to look like CodegenProperty}} diff --git a/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache b/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache index 7af083a925f..12ba61de347 100644 --- a/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache +++ b/modules/swagger-codegen/src/main/resources/csharp/modelInnerEnum.mustache @@ -1,19 +1,21 @@ {{^isContainer}} /// - /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} + /// {{^description}}Defines {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} /// {{#description}} /// {{description}} {{/description}} + {{#isString}} [JsonConverter(typeof(StringEnumConverter))] - {{>visibility}} enum {{#datatypeWithEnum}}{{&.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}} + {{/isString}} + {{>visibility}} enum {{#datatypeWithEnum}}{{.}}{{/datatypeWithEnum}}{{^datatypeWithEnum}}{{classname}}{{/datatypeWithEnum}}{{#vendorExtensions.x-enum-byte}}: byte{{/vendorExtensions.x-enum-byte}} { {{#allowableValues}}{{#enumVars}} /// - /// Enum {{name}} for {{{value}}} + /// Enum {{name}} for value: {{{value}}} /// - [EnumMember(Value = {{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isFloat}}"{{/isFloat}}{{#isDouble}}"{{/isDouble}}{{{value}}}{{#isLong}}"{{/isLong}}{{#isInteger}}"{{/isInteger}}{{#isDouble}}"{{/isDouble}}{{#isFloat}}"{{/isFloat}})] - {{name}}{{#isLong}} = {{{value}}}{{/isLong}}{{#isInteger}} = {{{value}}}{{/isInteger}}{{^-last}}, + {{#isString}}[EnumMember(Value = "{{{value}}}")]{{/isString}} + {{name}}{{^isString}} = {{{value}}}{{/isString}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}} } {{/isContainer}} diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs index 2146daae4de..6ab512ac960 100644 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithOptionalInlineEnum.cs @@ -31,50 +31,50 @@ namespace IO.Swagger.Model public partial class MyClassWithOptionalInlineEnum : IEquatable, IValidatableObject { /// - /// Gets or Sets Days + /// Defines Days /// [JsonConverter(typeof(StringEnumConverter))] public enum DaysEnum { /// - /// Enum Sun for "sun" + /// Enum Sun for value: sun /// [EnumMember(Value = "sun")] Sun, /// - /// Enum Mon for "mon" + /// Enum Mon for value: mon /// [EnumMember(Value = "mon")] Mon, /// - /// Enum Tue for "tue" + /// Enum Tue for value: tue /// [EnumMember(Value = "tue")] Tue, /// - /// Enum Wed for "wed" + /// Enum Wed for value: wed /// [EnumMember(Value = "wed")] Wed, /// - /// Enum Thu for "thu" + /// Enum Thu for value: thu /// [EnumMember(Value = "thu")] Thu, /// - /// Enum Fri for "fri" + /// Enum Fri for value: fri /// [EnumMember(Value = "fri")] Fri, /// - /// Enum Sat for "sat" + /// Enum Sat for value: sat /// [EnumMember(Value = "sat")] Sat diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs index fb43dccce3f..a131c7e774a 100644 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/MyClassWithRequiredInlineEnum.cs @@ -31,50 +31,50 @@ namespace IO.Swagger.Model public partial class MyClassWithRequiredInlineEnum : IEquatable, IValidatableObject { /// - /// Gets or Sets Days + /// Defines Days /// [JsonConverter(typeof(StringEnumConverter))] public enum DaysEnum { /// - /// Enum Sun for "sun" + /// Enum Sun for value: sun /// [EnumMember(Value = "sun")] Sun, /// - /// Enum Mon for "mon" + /// Enum Mon for value: mon /// [EnumMember(Value = "mon")] Mon, /// - /// Enum Tue for "tue" + /// Enum Tue for value: tue /// [EnumMember(Value = "tue")] Tue, /// - /// Enum Wed for "wed" + /// Enum Wed for value: wed /// [EnumMember(Value = "wed")] Wed, /// - /// Enum Thu for "thu" + /// Enum Thu for value: thu /// [EnumMember(Value = "thu")] Thu, /// - /// Enum Fri for "fri" + /// Enum Fri for value: fri /// [EnumMember(Value = "fri")] Fri, /// - /// Enum Sat for "sat" + /// Enum Sat for value: sat /// [EnumMember(Value = "sat")] Sat diff --git a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs index ae81432d79b..92d45a5c028 100644 --- a/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs +++ b/modules/swagger-codegen/src/test/resources/integrationtests/csharp/general/enum-support-expected/src/IO.Swagger/Model/WeekDays.cs @@ -27,48 +27,50 @@ namespace IO.Swagger.Model /// /// Defines WeekDays /// + [JsonConverter(typeof(StringEnumConverter))] + public enum WeekDays { /// - /// Enum Sun for "sun" + /// Enum Sun for value: sun /// [EnumMember(Value = "sun")] Sun, /// - /// Enum Mon for "mon" + /// Enum Mon for value: mon /// [EnumMember(Value = "mon")] Mon, /// - /// Enum Tue for "tue" + /// Enum Tue for value: tue /// [EnumMember(Value = "tue")] Tue, /// - /// Enum Wed for "wed" + /// Enum Wed for value: wed /// [EnumMember(Value = "wed")] Wed, /// - /// Enum Thu for "thu" + /// Enum Thu for value: thu /// [EnumMember(Value = "thu")] Thu, /// - /// Enum Fri for "fri" + /// Enum Fri for value: fri /// [EnumMember(Value = "fri")] Fri, /// - /// Enum Sat for "sat" + /// Enum Sat for value: sat /// [EnumMember(Value = "sat")] Sat From 018c8d3ece713f62612be389a8ce610d28419ee4 Mon Sep 17 00:00:00 2001 From: James Schubert Date: Mon, 6 Nov 2017 21:12:56 -0500 Subject: [PATCH 6/7] Remove unused imports --- .../io/swagger/codegen/languages/AbstractCSharpCodegen.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java index a97545615e3..dfe4e8ff099 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractCSharpCodegen.java @@ -1,7 +1,5 @@ package io.swagger.codegen.languages; -import com.samskivert.mustache.Mustache; -import com.samskivert.mustache.Template; import io.swagger.codegen.*; import io.swagger.codegen.utils.ModelUtils; import io.swagger.models.properties.*; @@ -10,8 +8,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; -import java.io.IOException; -import java.io.Writer; import java.util.*; public abstract class AbstractCSharpCodegen extends DefaultCodegen implements CodegenConfig { From 64fafb5db33267ce094378b7f6b787234764072b Mon Sep 17 00:00:00 2001 From: James Schubert Date: Mon, 13 Nov 2017 21:56:42 -0500 Subject: [PATCH 7/7] [all] sys props in CodegenConstants --- .../swagger/codegen/plugin/CodeGenMojo.java | 22 +++++++++---------- .../io/swagger/codegen/CodegenConstants.java | 4 ++++ .../io/swagger/codegen/DefaultGenerator.java | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java index a73ed6aa0c0..58fbeda5943 100644 --- a/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java +++ b/modules/swagger-codegen-maven-plugin/src/main/java/io/swagger/codegen/plugin/CodeGenMojo.java @@ -405,28 +405,28 @@ public class CodeGenMojo extends AbstractMojo { // Set generation options if (null != generateApis && generateApis) { - System.setProperty("apis", ""); + System.setProperty(CodegenConstants.APIS, ""); } else { - System.clearProperty("apis"); + System.clearProperty(CodegenConstants.APIS); } if (null != generateModels && generateModels) { - System.setProperty("models", modelsToGenerate); + System.setProperty(CodegenConstants.MODELS, modelsToGenerate); } else { - System.clearProperty("models"); + System.clearProperty(CodegenConstants.MODELS); } if (null != generateSupportingFiles && generateSupportingFiles) { - System.setProperty("supportingFiles", supportingFilesToGenerate); + System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate); } else { - System.clearProperty("supportingFiles"); + System.clearProperty(CodegenConstants.SUPPORTING_FILES); } - System.setProperty("modelTests", generateModelTests.toString()); - System.setProperty("modelDocs", generateModelDocumentation.toString()); - System.setProperty("apiTests", generateApiTests.toString()); - System.setProperty("apiDocs", generateApiDocumentation.toString()); - System.setProperty("withXml", withXml.toString()); + System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString()); + System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString()); + System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString()); + System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString()); + System.setProperty(CodegenConstants.WITH_XML, withXml.toString()); if (configOptions != null) { // Retained for backwards-compataibility with configOptions -> instantiation-types diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java index b0b08dfe523..5b307344ccf 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/CodegenConstants.java @@ -4,6 +4,8 @@ package io.swagger.codegen; * A class for storing constants that are used throughout the project. */ public class CodegenConstants { + /* System Properties */ + // NOTE: We may want to move these to a separate class to avoid confusion or modification. public static final String APIS = "apis"; public static final String MODELS = "models"; public static final String SUPPORTING_FILES = "supportingFiles"; @@ -11,6 +13,8 @@ public class CodegenConstants { public static final String MODEL_DOCS = "modelDocs"; public static final String API_TESTS = "apiTests"; public static final String API_DOCS = "apiDocs"; + public static final String WITH_XML = "withXml"; + /* /end System Properties */ public static final String API_PACKAGE = "apiPackage"; public static final String API_PACKAGE_DESC = "package for generated api classes"; diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java index 2c166e69577..e10350207a9 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/DefaultGenerator.java @@ -543,7 +543,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator { return; } Set supportingFilesToGenerate = null; - String supportingFiles = System.getProperty("supportingFiles"); + String supportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES); if (supportingFiles != null && !supportingFiles.isEmpty()) { supportingFilesToGenerate = new HashSet(Arrays.asList(supportingFiles.split(","))); }