Skip to content

updates from dev #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions Templates/CSharp/Base/SharedCSharp.template.tt
Original file line number Diff line number Diff line change
Expand Up @@ -314,4 +314,34 @@ public string GetRequestMethodWithOptionsHeader()
/// <returns>The built request.</returns>";
}

// -------------------------------------------------------------
// Methods used in MethodRequest.cs.tt and IMethodRequest.cs.tt for OData actions and functions.
// -------------------------------------------------------------

/// <summary>
/// Used in MethodRequest.cs.tt and IMethodRequest.cs.tt to get the ODataMethod*Response type
/// defined in Microsoft.Graph.Core. Updates to supported OData primitives for OData methods
/// needs to occur in MethodRequest.cs.tt, IMethodRequest.cs.tt, Microsoft.Graph.Core, and here.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public string GetMethodRequestPrimitiveReturnTypeString(string type)
{
switch (type.ToLowerInvariant())
{
case "string":
return "ODataMethodStringResponse";
case "int32":
return "ODataMethodIntResponse";
case "boolean":
case "bool":
return "ODataMethodBooleanResponse";
case "int64":
return "ODataMethodLongResponse";
default:
return type;
}
}


#>
25 changes: 24 additions & 1 deletion Templates/CSharp/Requests/IMethodRequest.cs.tt
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,42 @@ var requestType = entityName + methodName + "Request";

var returnEntityType = method.ReturnType == null ? null : method.ReturnType.GetTypeString(@namespace);
var returnEntityParameter = string.Empty;
if (returnEntityType != null) {returnEntityParameter = returnEntityType.ToLower();}
if (returnEntityType != null)
{
returnEntityParameter = returnEntityType.ToLower();

// Updates to supported OData primitives need to occur here,
// IMethodRequest.cs.tt, Microsoft.Graph.Core, and in
// GetMethodRequestPrimitiveReturnTypeString() in SharedCSharp.
var tempReturnType = GetMethodRequestPrimitiveReturnTypeString(returnEntityType);

// These magic strings represent types in Microsoft.Graph.Core.
// If the return type is a primitive, then make it nullable.
if (tempReturnType == "ODataMethodIntResponse" ||
tempReturnType == "ODataMethodBooleanResponse" ||
tempReturnType == "ODataMethodLongResponse")
{
returnEntityType = returnEntityType + "?";
}
}
var returnTypeObject = method.ReturnType == null ? null : method.ReturnType.AsOdcmClass();



var isCollection = method.IsCollection;

var sendAsyncReturnType = isCollection
? "I" + entityName + methodName + "CollectionPage"
: returnEntityType;



var methodReturnType = sendAsyncReturnType == null
? "System.Threading.Tasks.Task"
: "System.Threading.Tasks.Task<" + sendAsyncReturnType + ">";



bool hasParameters = method.Parameters != null && method.Parameters.Any();
bool includeRequestBody = hasParameters && isAction;
bool returnsStream = string.Equals(sendAsyncReturnType, "Stream");
Expand Down
93 changes: 82 additions & 11 deletions Templates/CSharp/Requests/MethodRequest.cs.tt
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,79 @@ var entityName = method.Class.Name.ToCheckedCase();
var isFunction = method.IsFunction;
var isAction = !isFunction;
var isComposable = method.IsComposable;
var isCollection = method.IsCollection;

var methodName = method.Name.Substring(method.Name.IndexOf('.') + 1).ToCheckedCase();
var requestType = entityName + methodName + "Request";

var returnEntityType = method.ReturnType == null ? null : method.ReturnType.GetTypeString(@namespace);

var returnEntityParameter = string.Empty;
if (returnEntityType != null) {returnEntityParameter = returnEntityType.ToLower();}

var isCollection = method.IsCollection;
// Represents the return of the SendAsync call within a public GetSync() or PostAsync() call.
var sendAsyncReturnType = string.Empty;

var sendAsyncReturnType = isCollection
? "I" + entityName + methodName + "CollectionPage"
: returnEntityType;
// Indicates whether the OData method returns an OData primitive (non-collection).
// Collections of OData primitives is already supported.
var isPrimitiveReturnType = false;

var methodReturnType = sendAsyncReturnType == null
? "System.Threading.Tasks.Task"
: "System.Threading.Tasks.Task<" + sendAsyncReturnType + ">";
// Represents the return type of a GetAsync() or PostAsync() call.
var returnEntityType = method.ReturnType == null ? null : method.ReturnType.GetTypeString(@namespace);

// Set the SendAsync return type and determine whether we are working with an OData primitive.
if (returnEntityType != null)
{
returnEntityParameter = returnEntityType.ToLower();
if (isCollection)
{
sendAsyncReturnType = "I" + entityName + methodName + "CollectionPage";
}
else
{
// Updates to supported OData primitives need to occur here,
// IMethodRequest.cs.tt, Microsoft.Graph.Core, and in
// GetMethodRequestPrimitiveReturnTypeString() in SharedCSharp.
sendAsyncReturnType = GetMethodRequestPrimitiveReturnTypeString(returnEntityType);

// These magic strings represent types in M.G.C.
if (sendAsyncReturnType == "ODataMethodStringResponse" ||
sendAsyncReturnType == "ODataMethodIntResponse" ||
sendAsyncReturnType == "ODataMethodBooleanResponse" ||
sendAsyncReturnType == "ODataMethodLongResponse")
{
isPrimitiveReturnType = true;
}
}
}
else
{
sendAsyncReturnType = returnEntityType;
}

// Set the return type of the public GetSync() or PostAsync() call.
var methodReturnType = string.Empty;
if (sendAsyncReturnType == null)
{
methodReturnType = "System.Threading.Tasks.Task";
}
else
{
if (isCollection)
{
var collectionPage = "I" + entityName + methodName + "CollectionPage";
methodReturnType = "System.Threading.Tasks.Task<" + collectionPage + ">";
}
else
{
var returnParameter = sendAsyncReturnType == "ODataMethodIntResponse" ||
sendAsyncReturnType == "ODataMethodBooleanResponse" ||
sendAsyncReturnType == "ODataMethodLongResponse" ? returnEntityType + "?"
: returnEntityType;
methodReturnType = "System.Threading.Tasks.Task<" + returnParameter + ">";
}
}

string methodOverloadReturnType = methodReturnType;

if (isCollection)
if (isCollection || isPrimitiveReturnType)
{
methodReturnType = string.Concat("async ", methodReturnType);
}
Expand Down Expand Up @@ -178,9 +229,19 @@ namespace <#=@namespace#>
}
else if (!string.IsNullOrEmpty(sendAsyncReturnType))
{
if (isPrimitiveReturnType)
{
#>
var response = await this.SendAsync<<#=sendAsyncReturnType#>>(<#=methodParameter#>, cancellationToken);
return response.Value;
<#
}
else
{
#>
return this.SendAsync<<#=sendAsyncReturnType#>>(<#=methodParameter#>, cancellationToken);
<#
}
}
else
{
Expand Down Expand Up @@ -278,9 +339,19 @@ namespace <#=@namespace#>
}
else if (!string.IsNullOrEmpty(sendAsyncReturnType))
{
if (isPrimitiveReturnType)
{
#>
var response = await this.SendAsync<<#=sendAsyncReturnType#>>(null, cancellationToken);
return response.Value;
<#
}
else
{
#>
return this.SendAsync<<#=sendAsyncReturnType#>>(null, cancellationToken);
<#
}
}
else
{
Expand Down
20 changes: 11 additions & 9 deletions src/GraphODataTemplateWriter/CodeHelpers/Java/TypeHelperJava.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,9 +1269,9 @@ public static string CreateParameterDef(IEnumerable<OdcmParameter> parameters)
* The {0}.
* {1}
*/
@SerializedName(""{2}"")
@SerializedName(value = ""{2}"", alternate = {{""{3}""}})
@Expose
public {3} {4};
public {4} {5};

";
foreach (var p in parameters)
Expand All @@ -1281,6 +1281,7 @@ public static string CreateParameterDef(IEnumerable<OdcmParameter> parameters)
p.ParamName().SplitCamelCase(),
ReplaceInvalidCharacters(p.LongDescription),
p.ParamName(),
p.ParamName().ToUpperFirstChar(),
p.ParamType(),
p.ParamName().SanitizePropertyName(p).ToLowerFirstChar()
);
Expand Down Expand Up @@ -1413,19 +1414,19 @@ public static string CreatePropertyDef(IEnumerable<OdcmProperty> properties, boo
var format =
@" /**
* The {0}.
* {4}
* {1}
*/
@SerializedName(""{1}"")
@SerializedName(value = ""{2}"", alternate = {{""{3}""}})
@Expose
public {2} {3};
public {4} {5};

";
var collectionFormat =
@" /**
* The {0}.
* {4}
* {1}
*/
public {2} {3};
public {4} {5};

";

Expand Down Expand Up @@ -1454,10 +1455,11 @@ public static string CreatePropertyDef(IEnumerable<OdcmProperty> properties, boo

sb.AppendFormat(propertyFormat,
propertyName.SplitCamelCase(),
GetSanitizedDescription(property),
property.Name,
propertyName,
propertyType,
property.Name.ToLowerFirstChar().SanitizePropertyName(property),
GetSanitizedDescription(property));
property.Name.ToLowerFirstChar().SanitizePropertyName(property));
}
return sb.ToString();
}
Expand Down
37 changes: 37 additions & 0 deletions test/Typewriter.Test/Given_a_valid_metadata_file_to_Typewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -555,5 +555,42 @@ public void It_transforms_metadata()
Assert.IsTrue(hasContainsTargetBeenSet, $"The expected ContainsTarget attribute wasn't set in the transformed cleaned metadata.");
Assert.IsFalse(hasCapabilityAnnotations, $"The expected capability annotations weren't removed in the transformed cleaned metadata.");
}

[Test, RunInApplicationDomain]
[TestCase("TestType2FunctionMethodWithStringRequest.cs", "var response = await this.SendAsync<ODataMethodStringResponse>(null, cancellationToken);")]
[TestCase("TestType2FunctionMethodWithBooleanRequest.cs", "var response = await this.SendAsync<ODataMethodBooleanResponse>(null, cancellationToken);")]
[TestCase("TestType2FunctionMethodWithInt32Request.cs", "var response = await this.SendAsync<ODataMethodIntResponse>(null, cancellationToken);")]
[TestCase("TestType3ActionMethodWithInt64Request.cs", "var response = await this.SendAsync<ODataMethodLongResponse>(null, cancellationToken);")]
public void It_creates_method_request_with_OData_return_type(string outputFileName, string testParameter)
{
const string outputDirectory = "output";

Options optionsCSharp = new Options()
{
Output = outputDirectory,
Language = "CSharp",
GenerationMode = GenerationMode.Files
};

Generator.GenerateFiles(testMetadata, optionsCSharp);

FileInfo fileInfo = new FileInfo(outputDirectory + generatedOutputUrl + @"\Requests\" + outputFileName);
Assert.IsTrue(fileInfo.Exists, $"Expected: {fileInfo.FullName}. File was not found.");

IEnumerable<string> lines = File.ReadLines(fileInfo.FullName);
bool hasTestParameter = false;

foreach (var line in lines)
{
// We only need to check once.
if (line.Contains(testParameter))
{
hasTestParameter = true;
break;
}
}

Assert.IsTrue(hasTestParameter, $"The expected test token string, '{testParameter}', was not set in the generated test file. We didn't properly generate the SendAsync method.");
}
}
}
17 changes: 17 additions & 0 deletions test/Typewriter.Test/Resources/dirtyMetadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,23 @@
<Parameter Name="Comment" Type="Edm.String" Unicode="false" />
<Parameter Name="TestProperty" Type="Edm.String" Nullable="true"/>
</Action>

<Function Name="FunctionMethodWithString" IsBound="true">
<Parameter Name="bindparameter" Type="microsoft.graph.testType2" />
<ReturnType Type="Edm.String" Unicode="false" />
</Function>
<Function Name="FunctionMethodWithBoolean" IsBound="true">
<Parameter Name="bindparameter" Type="microsoft.graph.testType2" />
<ReturnType Type="Edm.Boolean" Nullable="false" />
</Function>
<Function Name="FunctionMethodWithInt32" IsBound="true">
<Parameter Name="bindparameter" Type="microsoft.graph.testType2" />
<ReturnType Type="Edm.Int32" Nullable="false" />
</Function>
<Action Name="ActionMethodWithInt64" IsBound="true">
<Parameter Name="bindingParameter" Type="microsoft.graph.testType3" />
<ReturnType Type="Edm.Int64" Nullable="false" />
</Action>

<EntityContainer Name="GraphService">
<Singleton Name="testSingleton" Type="microsoft.graph.testSingleton"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class Call extends Entity implements IJsonBackedObject {
* The Subject.
*
*/
@SerializedName("subject")
@SerializedName(value = "subject", alternate = {"Subject"})
@Expose
public String subject;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ public class CloudCommunications extends Entity implements IJsonBackedObject {
* The Calls.
*
*/
@SerializedName("calls")
@SerializedName(value = "calls", alternate = {"Calls"})
@Expose
public CallCollectionPage calls;

/**
* The Call Records.
*
*/
@SerializedName("callRecords")
@SerializedName(value = "callRecords", alternate = {"CallRecords"})
@Expose
public CallRecordCollectionPage callRecords;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,23 @@ public class DerivedComplexTypeRequest extends EmptyBaseComplexTypeRequest imple
* The Property1.
*
*/
@SerializedName("property1")
@SerializedName(value = "property1", alternate = {"Property1"})
@Expose
public String property1;

/**
* The Property2.
*
*/
@SerializedName("property2")
@SerializedName(value = "property2", alternate = {"Property2"})
@Expose
public String property2;

/**
* The Enum Property.
*
*/
@SerializedName("enumProperty")
@SerializedName(value = "enumProperty", alternate = {"EnumProperty"})
@Expose
public Enum1 enumProperty;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class DirectoryObject extends Entity implements IJsonBackedObject {
* The Deleted Date Time.
*
*/
@SerializedName("deletedDateTime")
@SerializedName(value = "deletedDateTime", alternate = {"DeletedDateTime"})
@Expose
public java.util.Calendar deletedDateTime;

Expand Down
Loading