[csharp] Treat enum models consistently (#6851)

* [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<EnumType> regardless of whether
it is defined as an inline enum or a referenced enum model.

* Categorizing C# integration test for enums as general

* [csharp] Remove enum-ref integration test

* [csharp] Clean up general enum support integration test, validate different enum usage cases.
This commit is contained in:
Jim Schubert 2017-11-09 04:14:47 -05:00 committed by wing328
parent 8b251555ac
commit 92ac1edd78
17 changed files with 1148 additions and 33 deletions

View File

@ -4,6 +4,14 @@ package io.swagger.codegen;
* A class for storing constants that are used throughout the project. * A class for storing constants that are used throughout the project.
*/ */
public class CodegenConstants { 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 = "apiPackage";
public static final String API_PACKAGE_DESC = "package for generated api classes"; public static final String API_PACKAGE_DESC = "package for generated api classes";

View File

@ -33,9 +33,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
private Boolean generateApiDocumentation = null; private Boolean generateApiDocumentation = null;
private Boolean generateModelTests = null; private Boolean generateModelTests = null;
private Boolean generateModelDocumentation = null; private Boolean generateModelDocumentation = null;
private Boolean generateSwaggerMetadata = true;
private String basePath; private String basePath;
private String basePathWithoutHost; private String basePathWithoutHost;
private String contextPath; private String contextPath;
private Map<String, String> generatorPropertyDefaults = new HashMap<>();
@Override @Override
public Generator opts(ClientOptInput opts) { public Generator opts(ClientOptInput opts) {
@ -61,6 +63,38 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
return this; 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;
}
/**
* 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
*/
@SuppressWarnings("WeakerAccess")
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() { private String getScheme() {
String scheme; String scheme;
if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) { if (swagger.getSchemes() != null && swagger.getSchemes().size() > 0) {
@ -88,11 +122,11 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
} }
private void configureGeneratorProperties() { private void configureGeneratorProperties() {
// allows generating only models by specifying a CSV of models to generate, or empty for all // allows generating only models by specifying a CSV of models to generate, or empty for all
generateApis = System.getProperty("apis") != null ? true : null; // NOTE: Boolean.TRUE is required below rather than `true` because of JVM boxing constraints and type inference.
generateModels = System.getProperty("models") != null ? true : null; generateApis = System.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
generateSupportingFiles = System.getProperty("supportingFiles") != null ? true : 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) { if (generateApis == null && generateModels == null && generateSupportingFiles == null) {
// no specifics are set, generate everything // no specifics are set, generate everything
@ -110,10 +144,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. // 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 // 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; generateModelTests = System.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
generateModelDocumentation = System.getProperty("modelDocs") != null ? Boolean.valueOf(System.getProperty("modelDocs")) : true; generateModelDocumentation = System.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
generateApiTests = System.getProperty("apiTests") != null ? Boolean.valueOf(System.getProperty("apiTests")) : true; generateApiTests = System.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
generateApiDocumentation = System.getProperty("apiDocs") != null ? Boolean.valueOf(System.getProperty("apiDocs")) : 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 // Additional properties added for tests to exclude references in project related files
@ -595,7 +629,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
final String swaggerCodegenIgnore = ".swagger-codegen-ignore"; final String swaggerCodegenIgnore = ".swagger-codegen-ignore";
String ignoreFileNameTarget = config.outputFolder() + File.separator + swaggerCodegenIgnore; String ignoreFileNameTarget = config.outputFolder() + File.separator + swaggerCodegenIgnore;
File ignoreFile = new File(ignoreFileNameTarget); File ignoreFile = new File(ignoreFileNameTarget);
if (!ignoreFile.exists()) { if (generateSwaggerMetadata && !ignoreFile.exists()) {
String ignoreFileNameSource = File.separator + config.getCommonTemplateDir() + File.separator + swaggerCodegenIgnore; String ignoreFileNameSource = File.separator + config.getCommonTemplateDir() + File.separator + swaggerCodegenIgnore;
String ignoreFileContents = readResourceContents(ignoreFileNameSource); String ignoreFileContents = readResourceContents(ignoreFileNameSource);
try { try {
@ -606,13 +640,15 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
files.add(ignoreFile); files.add(ignoreFile);
} }
final String swaggerVersionMetadata = config.outputFolder() + File.separator + ".swagger-codegen" + File.separator + "VERSION"; if(generateSwaggerMetadata) {
File swaggerVersionMetadataFile = new File(swaggerVersionMetadata); final String swaggerVersionMetadata = config.outputFolder() + File.separator + ".swagger-codegen" + File.separator + "VERSION";
try { File swaggerVersionMetadataFile = new File(swaggerVersionMetadata);
writeToFile(swaggerVersionMetadata, ImplementationVersion.read()); try {
files.add(swaggerVersionMetadataFile); writeToFile(swaggerVersionMetadata, ImplementationVersion.read());
} catch (IOException e) { files.add(swaggerVersionMetadataFile);
throw new RuntimeException("Could not generate supporting file '" + swaggerVersionMetadata + "'", e); } catch (IOException e) {
throw new RuntimeException("Could not generate supporting file '" + swaggerVersionMetadata + "'", e);
}
} }
/* /*

View File

@ -1,6 +1,7 @@
package io.swagger.codegen.languages; package io.swagger.codegen.languages;
import io.swagger.codegen.*; import io.swagger.codegen.*;
import io.swagger.codegen.utils.ModelUtils;
import io.swagger.models.properties.*; import io.swagger.models.properties.*;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -296,6 +297,11 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
additionalProperties.put(CodegenConstants.INTERFACE_PREFIX, interfacePrefix); additionalProperties.put(CodegenConstants.INTERFACE_PREFIX, interfacePrefix);
} }
@Override
public void postProcessModelProperty(CodegenModel model, CodegenProperty property) {
super.postProcessModelProperty(model, property);
}
@Override @Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) { public Map<String, Object> postProcessModels(Map<String, Object> objs) {
List<Object> models = (List<Object>) objs.get("models"); List<Object> models = (List<Object>) objs.get("models");
@ -315,6 +321,61 @@ public abstract class AbstractCSharpCodegen extends DefaultCodegen implements Co
return postProcessModelsEnum(objs); 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<String, Object> postProcessAllModels(Map<String, Object> objs) {
final Map<String, Object> 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<String, Object> models) {
Map<String, CodegenModel> enumRefs = new HashMap<String, CodegenModel>();
for (Map.Entry<String, Object> entry : models.entrySet()) {
CodegenModel model = ModelUtils.getModelByName(entry.getKey(), models);
if (model.isEnum) {
enumRefs.put(entry.getKey(), model);
}
}
for (Map.Entry<String, Object> 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 @Override
public Map<String, Object> postProcessOperations(Map<String, Object> objs) { public Map<String, Object> postProcessOperations(Map<String, Object> objs) {
super.postProcessOperations(objs); super.postProcessOperations(objs);

View File

@ -513,11 +513,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
this.packageGuid = packageGuid; this.packageGuid = packageGuid;
} }
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objMap) {
return super.postProcessModels(objMap);
}
@Override @Override
public void postProcessParameter(CodegenParameter parameter) { public void postProcessParameter(CodegenParameter parameter) {
postProcessPattern(parameter.pattern, parameter.vendorExtensions); postProcessPattern(parameter.pattern, parameter.vendorExtensions);
@ -530,7 +525,6 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen {
super.postProcessModelProperty(model, property); super.postProcessModelProperty(model, property);
} }
/* /*
* The swagger pattern spec follows the Perl convention and style of modifiers. .NET * 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 * does not support this syntax directly so we need to convert the pattern to a .NET compatible

View File

@ -12,16 +12,18 @@
{{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>{{^netStandard}}{{#validatable}}, IValidatableObject{{/validatable}}{{/netStandard}} {{>visibility}} partial class {{classname}} : {{#parent}}{{{parent}}}, {{/parent}} IEquatable<{{classname}}>{{^netStandard}}{{#validatable}}, IValidatableObject{{/validatable}}{{/netStandard}}
{ {
{{#vars}} {{#vars}}
{{#isEnum}}
{{>modelInnerEnum}}
{{/isEnum}}
{{#items.isEnum}} {{#items.isEnum}}
{{#items}} {{#items}}
{{^complexType}}
{{>modelInnerEnum}} {{>modelInnerEnum}}
{{/complexType}}
{{/items}} {{/items}}
{{/items.isEnum}} {{/items.isEnum}}
{{/vars}} {{#isEnum}}
{{#vars}} {{^complexType}}
{{>modelInnerEnum}}
{{/complexType}}
{{/isEnum}}
{{#isEnum}} {{#isEnum}}
/// <summary> /// <summary>
/// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}} /// {{^description}}Gets or Sets {{{name}}}{{/description}}{{#description}}{{description}}{{/description}}
@ -30,7 +32,7 @@
/// <value>{{description}}</value> /// <value>{{description}}</value>
{{/description}} {{/description}}
[DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})]
public {{{datatypeWithEnum}}}{{#isEnum}}{{^isContainer}}?{{/isContainer}}{{/isEnum}} {{name}} { get; set; } public {{#complexType}}{{{complexType}}}{{/complexType}}{{^complexType}}{{{datatypeWithEnum}}}{{/complexType}}{{^isContainer}}{{^required}}?{{/required}}{{/isContainer}} {{name}} { get; set; }
{{/isEnum}} {{/isEnum}}
{{/vars}} {{/vars}}
{{#hasRequired}} {{#hasRequired}}
@ -53,7 +55,7 @@
{{#hasOnlyReadOnly}} {{#hasOnlyReadOnly}}
[JsonConstructorAttribute] [JsonConstructorAttribute]
{{/hasOnlyReadOnly}} {{/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}} {{#vars}}
{{^isInherited}} {{^isInherited}}

View File

@ -3,6 +3,7 @@ package io.swagger.codegen;
import static io.swagger.codegen.testutils.AssertFile.assertPathEqualsRecursively; import static io.swagger.codegen.testutils.AssertFile.assertPathEqualsRecursively;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -20,10 +21,19 @@ public abstract class AbstractIntegrationTest {
protected abstract Map<String, String> configProperties(); protected abstract Map<String, String> configProperties();
protected Boolean generateSwaggerMetadata = true;
protected Map<String, String> systemPropertyOverrides = new HashMap<>();
// @wing328: ignore for the time being until we fix the error with the integration test // @wing328: ignore for the time being until we fix the error with the integration test
@Test(enabled = false) @Test(enabled = false)
public void generatesCorrectDirectoryStructure() throws IOException { public void generatesCorrectDirectoryStructure() throws IOException {
DefaultGenerator codeGen = new DefaultGenerator(); DefaultGenerator codeGen = new DefaultGenerator();
codeGen.setGenerateSwaggerMetadata(generateSwaggerMetadata);
for (Map.Entry<String, String> propertyOverride : systemPropertyOverrides.entrySet()) {
codeGen.setGeneratorPropertyDefault(propertyOverride.getKey(), propertyOverride.getValue());
}
IntegrationTestPathsConfig integrationTestPathsConfig = getIntegrationTestPathsConfig(); IntegrationTestPathsConfig integrationTestPathsConfig = getIntegrationTestPathsConfig();
String specContent = Files.readFile(integrationTestPathsConfig.getSpecPath().toFile()); String specContent = Files.readFile(integrationTestPathsConfig.getSpecPath().toFile());
@ -31,7 +41,7 @@ public abstract class AbstractIntegrationTest {
CodegenConfig codegenConfig = getCodegenConfig(); CodegenConfig codegenConfig = getCodegenConfig();
codegenConfig.setOutputDir(integrationTestPathsConfig.getOutputPath().toString()); codegenConfig.setOutputDir(integrationTestPathsConfig.getOutputPath().toString());
codegenConfig.setIgnoreFilePathOverride(integrationTestPathsConfig.getIgnoreFilePath().toFile().toString());
ClientOpts clientOpts = new ClientOpts(); ClientOpts clientOpts = new ClientOpts();
clientOpts.setProperties(configProperties()); clientOpts.setProperties(configProperties());
ClientOptInput opts = new ClientOptInput() ClientOptInput opts = new ClientOptInput()

View File

@ -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 CsharpClientGeneralEnumSupportIntegrationTest extends AbstractIntegrationTest {
public CsharpClientGeneralEnumSupportIntegrationTest() {
generateSwaggerMetadata = false;
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<String, String>();
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-support");
}
@Override
protected CodegenConfig getCodegenConfig() {
return new CSharpClientCodegen();
}
@Override
protected Map<String, String> configProperties() {
Map<String, String> 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 enum support, generalized across supported C# versions.")
public void test() throws IOException {
this.generatesCorrectDirectoryStructure();
}
}

View File

@ -10,6 +10,7 @@ import io.swagger.models.Model;
import io.swagger.models.ModelImpl; import io.swagger.models.ModelImpl;
import io.swagger.models.RefModel; import io.swagger.models.RefModel;
import io.swagger.models.properties.Property; import io.swagger.models.properties.Property;
import io.swagger.models.properties.RefProperty;
import io.swagger.models.properties.StringProperty; import io.swagger.models.properties.StringProperty;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Test; import org.testng.annotations.Test;

View File

@ -8,15 +8,17 @@ public class IntegrationTestPathsConfig {
private final Path outputPath; private final Path outputPath;
private final Path specPath; private final Path specPath;
private final Path expectedPath; private final Path expectedPath;
private final Path ignoreFilePath;
public IntegrationTestPathsConfig(String location) { 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); outputPath = INTEGRATION_TEST_PATH.resolve(outputLocation);
expectedPath = INTEGRATION_TEST_PATH.resolve(expectedLocation); expectedPath = INTEGRATION_TEST_PATH.resolve(expectedLocation);
specPath = INTEGRATION_TEST_PATH.resolve(specLocation); specPath = INTEGRATION_TEST_PATH.resolve(specLocation);
ignoreFilePath = INTEGRATION_TEST_PATH.resolve(ignoreFileLocation);
} }
public Path getOutputPath() { public Path getOutputPath() {
@ -30,4 +32,6 @@ public class IntegrationTestPathsConfig {
public Path getExpectedPath() { public Path getExpectedPath() {
return expectedPath; return expectedPath;
} }
public Path getIgnoreFilePath() { return ignoreFilePath; }
} }

View File

@ -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
{
/// <summary>
/// Invalid use of required on $ref enum, per Swagger 2.0 spec: Any members other than &#39;$ref&#39; in a JSON Reference object SHALL be ignored. See My_Class_With_Required_Inline_Enum for appropriate usage.
/// </summary>
[DataContract]
public partial class MyClassWithInvalidRequiredEnumUsageOnRef : IEquatable<MyClassWithInvalidRequiredEnumUsageOnRef>, IValidatableObject
{
/// <summary>
/// Gets or Sets Days
/// </summary>
[DataMember(Name="days", EmitDefaultValue=false)]
public WeekDays? Days { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MyClassWithInvalidRequiredEnumUsageOnRef" /> class.
/// </summary>
/// <param name="First">First.</param>
/// <param name="Days">Days.</param>
public MyClassWithInvalidRequiredEnumUsageOnRef(bool? First = default(bool?), WeekDays? Days = default(WeekDays?))
{
this.First = First;
this.Days = Days;
}
/// <summary>
/// Gets or Sets First
/// </summary>
[DataMember(Name="first", EmitDefaultValue=false)]
public bool? First { get; set; }
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
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();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="input">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object input)
{
return this.Equals(input as MyClassWithInvalidRequiredEnumUsageOnRef);
}
/// <summary>
/// Returns true if MyClassWithInvalidRequiredEnumUsageOnRef instances are equal
/// </summary>
/// <param name="input">Instance of MyClassWithInvalidRequiredEnumUsageOnRef to be compared</param>
/// <returns>Boolean</returns>
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))
);
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
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;
}
}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
yield break;
}
}
}

View File

@ -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
{
/// <summary>
/// MyClassWithOptionalEnum
/// </summary>
[DataContract]
public partial class MyClassWithOptionalEnum : IEquatable<MyClassWithOptionalEnum>, IValidatableObject
{
/// <summary>
/// Gets or Sets Days
/// </summary>
[DataMember(Name="days", EmitDefaultValue=false)]
public WeekDays? Days { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MyClassWithOptionalEnum" /> class.
/// </summary>
/// <param name="Quarantine">Quarantine.</param>
/// <param name="Grayware">Grayware.</param>
/// <param name="Days">Days.</param>
public MyClassWithOptionalEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), WeekDays? Days = default(WeekDays?))
{
this.Quarantine = Quarantine;
this.Grayware = Grayware;
this.Days = Days;
}
/// <summary>
/// Gets or Sets Quarantine
/// </summary>
[DataMember(Name="quarantine", EmitDefaultValue=false)]
public bool? Quarantine { get; set; }
/// <summary>
/// Gets or Sets Grayware
/// </summary>
[DataMember(Name="grayware", EmitDefaultValue=false)]
public bool? Grayware { get; set; }
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
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();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="input">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object input)
{
return this.Equals(input as MyClassWithOptionalEnum);
}
/// <summary>
/// Returns true if MyClassWithOptionalEnum instances are equal
/// </summary>
/// <param name="input">Instance of MyClassWithOptionalEnum to be compared</param>
/// <returns>Boolean</returns>
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))
);
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
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;
}
}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
yield break;
}
}
}

View File

@ -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
{
/// <summary>
/// MyClassWithOptionalInlineEnum
/// </summary>
[DataContract]
public partial class MyClassWithOptionalInlineEnum : IEquatable<MyClassWithOptionalInlineEnum>, IValidatableObject
{
/// <summary>
/// Gets or Sets Days
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DaysEnum
{
/// <summary>
/// Enum Sun for "sun"
/// </summary>
[EnumMember(Value = "sun")]
Sun,
/// <summary>
/// Enum Mon for "mon"
/// </summary>
[EnumMember(Value = "mon")]
Mon,
/// <summary>
/// Enum Tue for "tue"
/// </summary>
[EnumMember(Value = "tue")]
Tue,
/// <summary>
/// Enum Wed for "wed"
/// </summary>
[EnumMember(Value = "wed")]
Wed,
/// <summary>
/// Enum Thu for "thu"
/// </summary>
[EnumMember(Value = "thu")]
Thu,
/// <summary>
/// Enum Fri for "fri"
/// </summary>
[EnumMember(Value = "fri")]
Fri,
/// <summary>
/// Enum Sat for "sat"
/// </summary>
[EnumMember(Value = "sat")]
Sat
}
/// <summary>
/// Gets or Sets Days
/// </summary>
[DataMember(Name="days", EmitDefaultValue=false)]
public DaysEnum? Days { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MyClassWithOptionalInlineEnum" /> class.
/// </summary>
/// <param name="Quarantine">Quarantine.</param>
/// <param name="Grayware">Grayware.</param>
/// <param name="Days">Days.</param>
public MyClassWithOptionalInlineEnum(bool? Quarantine = default(bool?), bool? Grayware = default(bool?), DaysEnum? Days = default(DaysEnum?))
{
this.Quarantine = Quarantine;
this.Grayware = Grayware;
this.Days = Days;
}
/// <summary>
/// Gets or Sets Quarantine
/// </summary>
[DataMember(Name="quarantine", EmitDefaultValue=false)]
public bool? Quarantine { get; set; }
/// <summary>
/// Gets or Sets Grayware
/// </summary>
[DataMember(Name="grayware", EmitDefaultValue=false)]
public bool? Grayware { get; set; }
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
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();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="input">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object input)
{
return this.Equals(input as MyClassWithOptionalInlineEnum);
}
/// <summary>
/// Returns true if MyClassWithOptionalInlineEnum instances are equal
/// </summary>
/// <param name="input">Instance of MyClassWithOptionalInlineEnum to be compared</param>
/// <returns>Boolean</returns>
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))
);
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
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;
}
}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
yield break;
}
}
}

View File

@ -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
{
/// <summary>
/// MyClassWithRequiredInlineEnum
/// </summary>
[DataContract]
public partial class MyClassWithRequiredInlineEnum : IEquatable<MyClassWithRequiredInlineEnum>, IValidatableObject
{
/// <summary>
/// Gets or Sets Days
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum DaysEnum
{
/// <summary>
/// Enum Sun for "sun"
/// </summary>
[EnumMember(Value = "sun")]
Sun,
/// <summary>
/// Enum Mon for "mon"
/// </summary>
[EnumMember(Value = "mon")]
Mon,
/// <summary>
/// Enum Tue for "tue"
/// </summary>
[EnumMember(Value = "tue")]
Tue,
/// <summary>
/// Enum Wed for "wed"
/// </summary>
[EnumMember(Value = "wed")]
Wed,
/// <summary>
/// Enum Thu for "thu"
/// </summary>
[EnumMember(Value = "thu")]
Thu,
/// <summary>
/// Enum Fri for "fri"
/// </summary>
[EnumMember(Value = "fri")]
Fri,
/// <summary>
/// Enum Sat for "sat"
/// </summary>
[EnumMember(Value = "sat")]
Sat
}
/// <summary>
/// Gets or Sets Days
/// </summary>
[DataMember(Name="days", EmitDefaultValue=false)]
public DaysEnum Days { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MyClassWithRequiredInlineEnum" /> class.
/// </summary>
[JsonConstructorAttribute]
protected MyClassWithRequiredInlineEnum() { }
/// <summary>
/// Initializes a new instance of the <see cref="MyClassWithRequiredInlineEnum" /> class.
/// </summary>
/// <param name="Quarantine">Quarantine.</param>
/// <param name="Grayware">Grayware.</param>
/// <param name="Days">Days (required).</param>
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;
}
/// <summary>
/// Gets or Sets Quarantine
/// </summary>
[DataMember(Name="quarantine", EmitDefaultValue=false)]
public bool? Quarantine { get; set; }
/// <summary>
/// Gets or Sets Grayware
/// </summary>
[DataMember(Name="grayware", EmitDefaultValue=false)]
public bool? Grayware { get; set; }
/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
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();
}
/// <summary>
/// Returns the JSON string presentation of the object
/// </summary>
/// <returns>JSON string presentation of the object</returns>
public string ToJson()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
/// <summary>
/// Returns true if objects are equal
/// </summary>
/// <param name="input">Object to be compared</param>
/// <returns>Boolean</returns>
public override bool Equals(object input)
{
return this.Equals(input as MyClassWithRequiredInlineEnum);
}
/// <summary>
/// Returns true if MyClassWithRequiredInlineEnum instances are equal
/// </summary>
/// <param name="input">Instance of MyClassWithRequiredInlineEnum to be compared</param>
/// <returns>Boolean</returns>
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))
);
}
/// <summary>
/// Gets the hash code
/// </summary>
/// <returns>Hash code</returns>
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;
}
}
/// <summary>
/// To validate all properties of the instance
/// </summary>
/// <param name="validationContext">Validation context</param>
/// <returns>Validation Result</returns>
IEnumerable<System.ComponentModel.DataAnnotations.ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
yield break;
}
}
}

View File

@ -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
{
/// <summary>
/// Defines WeekDays
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public enum WeekDays
{
/// <summary>
/// Enum Sun for "sun"
/// </summary>
[EnumMember(Value = "sun")]
Sun,
/// <summary>
/// Enum Mon for "mon"
/// </summary>
[EnumMember(Value = "mon")]
Mon,
/// <summary>
/// Enum Tue for "tue"
/// </summary>
[EnumMember(Value = "tue")]
Tue,
/// <summary>
/// Enum Wed for "wed"
/// </summary>
[EnumMember(Value = "wed")]
Wed,
/// <summary>
/// Enum Thu for "thu"
/// </summary>
[EnumMember(Value = "thu")]
Thu,
/// <summary>
/// Enum Fri for "fri"
/// </summary>
[EnumMember(Value = "fri")]
Fri,
/// <summary>
/// Enum Sat for "sat"
/// </summary>
[EnumMember(Value = "sat")]
Sat
}
}

View File

@ -0,0 +1,125 @@
{
"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"
}
}
},
"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": {
"type": "boolean"
},
"grayware": {
"type": "boolean"
},
"days": {
"type": "string",
"enum": [
"sun",
"mon",
"tue",
"wed",
"thu",
"fri",
"sat"
]
}
}
},
"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"
]
}
}
}
}
}

View File

@ -0,0 +1,9 @@
!**/IO.Swagger/Model/*.cs
**/Api/
**/Client/
**/Properties
**/IO.Swagger.Test/
**/*
*/*
.swagger-codegen/
*/.*

View File

@ -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;