Skip to content

Commit

Permalink
Merge pull request #9 from amarzavery/fixenum
Browse files Browse the repository at this point in the history
Add support for Enums
  • Loading branch information
amarzavery committed Oct 20, 2017
2 parents 0e3b809 + b330a86 commit 5f949f3
Show file tree
Hide file tree
Showing 69 changed files with 1,407 additions and 258 deletions.
13 changes: 12 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,15 @@ src/obj/
yarn.lock

*.log
*.csproj
*.csproj

.travis.yml
.git*
.git
.vs/
node_modules/
.ntvs_analysis.*
.nuget/
packages/
packages.config
gulpfile.js
7 changes: 7 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
language: node_js
sudo: false
node_js:
- "8"

script:
- npm -s run-script testci
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contact [[email protected]](mailto:[email protected]) with any additio

``` yaml
use-extension:
"@microsoft.azure/autorest.modeler": "2.1.22"
"@microsoft.azure/autorest.modeler": "2.1.23"

pipeline:
typescript/modeler:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"shx": "^0.2.2",
"through2-parallel": "^0.1.3",
"yargs": "^8.0.2",
"@microsoft.azure/autorest.testserver": "^2.1.0",
"@microsoft.azure/autorest.testserver": "^2.2.0",
"yarn": "^1.0.2"
},
"dependencies": {
Expand Down
2 changes: 1 addition & 1 deletion src/azure/Templates/AzureMethodGroupTemplate.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
@EmptyLine
import * as msRest from "ms-rest-js";
@if (Model.ContainsCompositeTypeInParametersOrReturnType())
@if (Model.ContainsCompositeOrEnumTypeInParametersOrReturnType())
{
@:import * as Models from "../models";
}
Expand Down
5 changes: 5 additions & 0 deletions src/azure/Templates/AzureModelIndexTemplate.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ export { BaseResource, CloudError };
@EmptyLine
@:@(Include(new PageModelTemplate(), model))
}
@foreach (var model in Model.EnumTypes)
{
@EmptyLine
@:@(Include(new EnumTemplate(), model))
}
27 changes: 26 additions & 1 deletion src/vanilla/ClientModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,12 @@ public static string TSType(this IModelType type, bool inModelsModule) {
}
else if (enumType != null)
{
tsType = "string";
var enumName = enumType.Name;
tsType = "Models." + enumName;
if (inModelsModule || enumName.Contains('.'))
{
tsType = enumName;
}
}
else if (composite != null)
{
Expand Down Expand Up @@ -934,5 +939,25 @@ public static bool SkipUrlEncoding(this Parameter parameter)
return parameter.Extensions.ContainsKey(SwaggerExtensions.SkipUrlEncodingExtension) &&
(bool)parameter.Extensions[SwaggerExtensions.SkipUrlEncodingExtension];
}

public static bool IsCompositeOrEnumType(this IModelType type)
{
if (type is CompositeType || type is EnumType)
{
return true;
}
else if (type is SequenceType)
{
return (type as SequenceType).ElementType.IsCompositeOrEnumType();
}
else if (type is DictionaryType)
{
return (type as DictionaryType).ValueType.IsCompositeOrEnumType();
}
else
{
return false;
}
}
}
}
46 changes: 42 additions & 4 deletions src/vanilla/CodeNamerTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,45 @@ public CodeNamerTS()

public override string GetMethodName(string name) => CamelCase(GetEscapedReservedName(name, "Method"));

public override string GetEnumMemberName(string name) => CamelCase(name);
public override string GetEnumMemberName(string name)
{
if (name == null)
{
return "null";
}
else if (string.IsNullOrEmpty(name))
{
return "EMPTY_STRING";
}
string result = RemoveInvalidCharacters(new System.Text.RegularExpressions.Regex("[\\ -]+").Replace(name, "_"));
Func<char, bool> isUpper = new Func<char, bool>(c => c >= 'A' && c <= 'Z');
Func<char, bool> isLower = new Func<char, bool>(c => c >= 'a' && c <= 'z');
for (int i = 1; i < result.Length - 1; i++)
{
if (isUpper(result[i]))
{
if (result[i - 1] != '_' && isLower(result[i - 1]))
{
result = result.Insert(i, "_");
}
}
}
return result.ToUpperInvariant();
}

public static string GetEnumValueName(string valueName, PrimaryType valueType)
{
if (valueName == null)
{
return "null as any";
}
if (valueType == null)
{
// Since valueType is null we will default the EnumValue to be a string. Hence sending a quoted string back.
return Instance.QuoteValue(valueName, "'");
}
return Instance.EscapeDefaultValue(valueName, valueType);
}

public override string IsNameLegal(string desiredName, IIdentifier whoIsAsking)
{
Expand Down Expand Up @@ -122,11 +160,11 @@ public override string EscapeDefaultValue(string defaultValue, IModelType type)
case KnownPrimaryType.Date:
case KnownPrimaryType.DateTime:
case KnownPrimaryType.DateTimeRfc1123:
return "new Date('" + defaultValue + "')";
return $"new Date('{defaultValue}')";
case KnownPrimaryType.TimeSpan:
return "moment.duration('" + defaultValue + "')";
return $"moment.duration('{defaultValue}')";
case KnownPrimaryType.ByteArray:
return "new Buffer('" + defaultValue + "')";
return $"new Buffer('{defaultValue}')";
}
}
return defaultValue;
Expand Down
10 changes: 3 additions & 7 deletions src/vanilla/Model/MethodGroupTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public bool ContainsTimeSpan
}
}

public bool ContainsCompositeTypeInParametersOrReturnType()
public bool ContainsCompositeOrEnumTypeInParametersOrReturnType()
{
bool result = false;
foreach(var method in MethodTemplateModels)
Expand All @@ -47,17 +47,13 @@ public bool ContainsCompositeTypeInParametersOrReturnType()
result = true;
break;
}
result = parametersToBeScanned.Any(p => p.ModelType is CompositeType ||
(p.ModelType is SequenceType && (p.ModelType as SequenceType).ElementType is CompositeType) ||
(p.ModelType is DictionaryType && (p.ModelType as DictionaryType).ValueType is CompositeType));
result = parametersToBeScanned.Any(p => p.ModelType.IsCompositeOrEnumType());

if (result)
break;
}
if (!result)
result = MethodTemplateModels.Any(m => m.ReturnType.Body is CompositeType ||
(m.ReturnType.Body is SequenceType && (m.ReturnType.Body as SequenceType).ElementType is CompositeType) ||
(m.ReturnType.Body is DictionaryType && (m.ReturnType.Body as DictionaryType).ValueType is CompositeType));
result = MethodTemplateModels.Any(m => m.ReturnType.Body.IsCompositeOrEnumType());
return result;
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/vanilla/Templates/EnumTemplate.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@using AutoRest.Core
@using AutoRest.Core.Model
@using AutoRest.TypeScript
@inherits AutoRest.Core.Template<EnumType>

/**
* Defines values for @(Model.Name).
@if (Model.ExtendedDocumentation != null)
{
@:@(WrapComment(" * ", Model.ExtendedDocumentation))
}
* @@readonly
* @@enum {@CodeNamer.Instance.CamelCase(Model.UnderlyingType.Name)}
*/
export enum @(Model.Name) {
@for (int i = 0; i < Model.Values.Count; i++)
{
if (Model.Values[i].Description != null)
{
@:/**
@:@(WrapComment(" * ", Model.Values[i].Description))
@: */
}
@:@(CodeNamer.Instance.GetEnumMemberName(Model.Values[i].MemberName)) = @(CodeNamerTS.GetEnumValueName(Model.Values[i].SerializedName, Model.UnderlyingType)),
}
}
2 changes: 1 addition & 1 deletion src/vanilla/Templates/MethodGroupTemplate.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
@EmptyLine
import * as msRest from "ms-rest-js";
@if (Model.ContainsCompositeTypeInParametersOrReturnType())
@if (Model.ContainsCompositeOrEnumTypeInParametersOrReturnType())
{
@:import * as Models from "../models";
}
Expand Down
7 changes: 7 additions & 0 deletions src/vanilla/Templates/ModelIndexTemplate.cshtml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@using System.Linq
@using AutoRest.TypeScript.vanilla.Templates
@using AutoRest.TypeScript.Model
@inherits AutoRest.Core.Template<AutoRest.TypeScript.Model.CodeModelTS>
/*
@Header(" * ")
Expand All @@ -19,3 +20,9 @@
@EmptyLine
@:@(Include(new ModelTemplate(), model))
}
@foreach (var model in Model.EnumTypes)
{
@EmptyLine
@:@(Include(new EnumTemplate(), model))
}

61 changes: 60 additions & 1 deletion src/vanilla/TransformerTS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,68 @@ public override CodeModelTS TransformCodeModel(CodeModel cm)
PerformParameterMapping(codeModel);
CreateModelTypeForOptionalClientProperties(codeModel);
CreateModelTypesForOptionalMethodParameters(codeModel);
AddEnumTypesToCodeModel(codeModel);
return codeModel;
}

public void AddEnumTypesToCodeModel(CodeModelTS cm)
{
// If there is an model property that is an EnumType and has not been added to the EnumTypes then add it.
foreach (var modelType in cm.AllModelTypes)
{
foreach(var property in modelType.Properties)
{
if (property.ModelType is EnumType propertyAsEnum && !cm.EnumTypes.Contains(propertyAsEnum))
{
if(string.IsNullOrEmpty(propertyAsEnum.Name.RawValue))
{
propertyAsEnum.SetName(property.Name);
}
cm.Add(propertyAsEnum);
}
}
}
// If there is a method parameter that is an EnumType and has not been added to the EnumTypes then add it.
foreach (var method in cm.Methods)
{
foreach(var parameter in method.Parameters)
{
if (parameter.ModelType is EnumType parameterAsEnum && !cm.EnumTypes.Contains(parameterAsEnum))
{
if (string.IsNullOrEmpty(parameterAsEnum.Name.RawValue))
{
parameterAsEnum.SetName(parameter.Name);
}
cm.Add(parameterAsEnum);
}
}
// If there is a response body or header in the response pair that is an EnumType and has not been
// added to the EnumTypes then add it.
foreach (var responsePair in method.Responses)
{
var response = responsePair.Value;
var modelTypes = new List<IModelType>
{
response.Body,
response.Headers
};
foreach (var modelType in modelTypes)
{
if (modelType is EnumType modelTypeAsEnum && !cm.EnumTypes.Contains(modelTypeAsEnum))
{
if (string.IsNullOrEmpty(modelTypeAsEnum.Name.RawValue))
{
var enumName = $"{method.Name.ToPascalCase()}{responsePair.Key}";
if (modelType.Equals(response.Body)) enumName += "Response";
modelTypeAsEnum.SetName(enumName);
}
cm.Add(modelTypeAsEnum);
}
}
}
}
}

public void PerformParameterMapping(CodeModelTS cm)
{
foreach (var method in cm.Methods)
Expand Down Expand Up @@ -120,7 +179,7 @@ public virtual void CreateModelTypesForOptionalMethodParameters(CodeModelTS cm)
optionsParameterModelType.BaseModelType = New<CompositeType>(new { Name = "RequestOptionsBase", SerializedName = "RequestOptionsBase" });
foreach(var optionalParameter in optionalParameters)
{
optionsParameterModelType.Add(New<Core.Model.Property>(new
optionsParameterModelType.Add(New<Property>(new
{
IsReadOnly = false,
Name = optionalParameter.Name,
Expand Down
4 changes: 2 additions & 2 deletions test/azure/AcceptanceTests/azureCompositeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as assert from 'assert';
import * as msRest from 'ms-rest-js';
import * as msRestAzure from 'ms-rest-azure-js';

import { AzureCompositeModel } from '../Expected/AcceptanceTests/AzureCompositeModelClient/azureCompositeModel';
import { AzureCompositeModel, AzureCompositeModelModels } from '../Expected/AcceptanceTests/AzureCompositeModelClient/azureCompositeModel';
var dummyToken = 'dummy12321343423';
var credentials = new msRest.TokenCredentials(dummyToken);

Expand All @@ -25,7 +25,7 @@ describe('typescript', function () {
result.id.should.equal(2);
result.name.should.equal('abc');
result.color.should.equal('YELLOW');
testClient.basic.putValid({ 'id': 2, 'name': 'abc', color: 'Magenta' }, function (error, result) {
testClient.basic.putValid({ 'id': 2, 'name': 'abc', color: AzureCompositeModelModels.CMYKColors.MAGENTA }, function (error, result) {
should.not.exist(error);
done();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ export interface Basic {
*/
name?: string;
/**
* @member {string} [color] Possible values include: 'cyan', 'Magenta',
* @member {CMYKColors} [color] Possible values include: 'cyan', 'Magenta',
* 'YELLOW', 'blacK'
*/
color?: string;
color?: CMYKColors;
}

/**
Expand Down Expand Up @@ -616,3 +616,16 @@ export interface ReadonlypropertyPutValidOptionalParams extends RequestOptionsBa
size?: number;
}


/**
* Defines values for CMYKColors.
* Possible values include: 'cyan', 'Magenta', 'YELLOW', 'blacK'
* @readonly
* @enum {string}
*/
export enum CMYKColors {
CYAN = 'cyan',
MAGENTA = 'Magenta',
YELLOW = 'YELLOW',
BLACK = 'blacK',
}
Loading

0 comments on commit 5f949f3

Please sign in to comment.