Skip to content

Merge dev into master #206

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 22 commits into from
Jun 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3fe412e
Merge pull request #181 from microsoftgraph/master
MIchaelMainer Feb 12, 2019
0dffe50
Add NamespacePrefix that's used as the class name prefix for generati…
MIchaelMainer Feb 15, 2019
1467af8
Merge pull request #182 from microsoftgraph/addObjCSetting
MIchaelMainer Feb 15, 2019
dc42529
Update README.md
MIchaelMainer Feb 26, 2019
96ef07d
Added preprocessors for nav properties
MIchaelMainer Feb 27, 2019
19d8d41
Ad additional preprocessing.
MIchaelMainer Feb 27, 2019
80a607c
Support updating the default base Graph URL via the endpointVersion a…
MIchaelMainer Mar 4, 2019
3d497a8
Merge pull request #184 from microsoftgraph/supportBetaDefaultEndpoint
MIchaelMainer Mar 5, 2019
c6a41c8
Merge pull request #183 from microsoftgraph/addedIntunePreprocessing
MIchaelMainer Mar 5, 2019
2b3921d
add rule to add containsTarget=true to labelPolicy navigation
MIchaelMainer Mar 6, 2019
16eb717
Merge pull request #185 from microsoftgraph/addPreProLabelPolicy
MIchaelMainer Mar 6, 2019
be7f1c1
Convert edm.Decimal to number
MIchaelMainer Mar 7, 2019
f958816
Merge pull request #186 from microsoftgraph/typescriptDecimal
MIchaelMainer Mar 8, 2019
092ef1f
Handle CRLF in doc annotations as code comments.
MIchaelMainer Mar 21, 2019
d1fd61e
Merge pull request #190 from microsoftgraph/fixCRLFdoc
MIchaelMainer Apr 3, 2019
545439f
Updated request builder interfaces to inherit from common interface
MIchaelMainer Apr 3, 2019
4ca1e5b
Fix for enum naming for camelcased+underscore scenario (#194)
MIchaelMainer Apr 30, 2019
3eb5335
Added preprocess rule for new intune navigation (#195)
MIchaelMainer May 1, 2019
ed77c7d
Updating EntityRequest.Base.template with code fix for response heade…
irvinesunday May 29, 2019
b6093d9
Fixed spacing indentation (#204)
irvinesunday May 30, 2019
9d03622
Fixed bugs for publishing in definitely typed repo (#203)
muthurathinam May 30, 2019
0edb485
Add contains target for new entities. (#205)
MIchaelMainer Jun 4, 2019
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
95 changes: 95 additions & 0 deletions GraphODataTemplateWriter.Test/TypeHelperTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using Microsoft.Graph.ODataTemplateWriter.CodeHelpers.CSharp;
using Microsoft.Graph.ODataTemplateWriter.CodeHelpers.TypeScript;
using Microsoft.Graph.ODataTemplateWriter.CodeHelpers.PHP;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Vipr.Core.CodeModel;


namespace GraphODataTemplateWriter.Test
{
[TestClass]
public class TypeHelperTests
{
OdcmProperty testProperty;
string actualInputString = "\r\n Test string";
string expectedOutputString = "\r\n/// Test string";

[TestInitialize]
public void Initialize()
{
testProperty = new OdcmProperty("testPropertyName");
}

/// <summary>
/// Test that GetSanitizedLongDescription provides long descriptions without uncommented lines of text.
/// </summary>
[TestMethod]
public void Long_Description_Doesnt_Contain_Uncommented_NewLine_For_CSharp()
{
testProperty.LongDescription = actualInputString;
string sanitizedString = TypeHelperCSharp.GetSanitizedLongDescription(testProperty); // Explicitly bind to extension method.

Assert.AreEqual(expectedOutputString, sanitizedString, "GetSanitizedLongDescription is not handling escaped CRLF.");
}

/// <summary>
/// Test that GetSanitizedLongDescription provides descriptions without uncommented lines of text.
/// </summary>
[TestMethod]
public void Description_Doesnt_Contain_Uncommented_NewLine_For_CSharp()
{
testProperty.Description = actualInputString;
string sanitizedString = TypeHelperCSharp.GetSanitizedLongDescription(testProperty);

Assert.AreEqual(expectedOutputString, sanitizedString, "GetSanitizedLongDescription is not handling escaped CRLF.");
}

/// <summary>
/// Test that GetSanitizedLongDescription provides long descriptions without uncommented lines of text for Typescript.
/// </summary>
[TestMethod]
public void Long_Description_Doesnt_Contain_Uncommented_NewLine_For_Typescript()
{
testProperty.LongDescription = actualInputString;
string sanitizedString = TypeHelperTypeScript.GetSanitizedLongDescription(testProperty); // Explicitly bind to extension method.

Assert.AreEqual(expectedOutputString, sanitizedString, "GetSanitizedLongDescription is not handling escaped CRLF.");
}

/// <summary>
/// Test that GetSanitizedLongDescription provides descriptions without uncommented lines of text for Typescript.
/// </summary>
[TestMethod]
public void Description_Doesnt_Contain_Uncommented_NewLine_For_Typescript()
{
testProperty.Description = actualInputString;
string sanitizedString = TypeHelperTypeScript.GetSanitizedLongDescription(testProperty);

Assert.AreEqual(expectedOutputString, sanitizedString, "GetSanitizedLongDescription is not handling escaped CRLF.");
}

/// <summary>
/// Test that GetSanitizedLongDescription provides long descriptions without uncommented lines of text for PHP.
/// </summary>
[TestMethod]
public void Long_Description_Doesnt_Contain_Uncommented_NewLine_For_PHP()
{
testProperty.LongDescription = actualInputString;
string sanitizedString = TypeHelperPHP.GetSanitizedLongDescription(testProperty); // Explicitly bind to extension method.

Assert.AreEqual(expectedOutputString, sanitizedString, "GetSanitizedLongDescription is not handling escaped CRLF.");
}

/// <summary>
/// Test that GetSanitizedLongDescription provides descriptions without uncommented lines of text for PHP.
/// </summary>
[TestMethod]
public void Description_Doesnt_Contain_Uncommented_NewLine_For_PHP()
{
testProperty.Description = actualInputString;
string sanitizedString = TypeHelperPHP.GetSanitizedLongDescription(testProperty);

Assert.AreEqual(expectedOutputString, sanitizedString, "GetSanitizedLongDescription is not handling escaped CRLF.");
}
}
}
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ and optionally :

Example :

` { "Template": "EntityType", "SubProcessor": "EntityType", "Type": "Model", "Name": "<Class>", "Matches" : "includeThisType", "Exclude" : "ExcludedTypeName;OtherExcludedTypeName" }`
` { "Template": "EntityCollectionPage", "SubProcessor": "NavigationCollectionProperty", "Type": "Request", "Name": "<Class><Property>CollectionPage", "Matches" : "includeThisType", "Exclude" : "ExcludedTypeName;OtherExcludedTypeName" }`

It is important to understand that subprocessors are mapped to methods that query the **OdcmModel** and return a set of OData objects. This mapping is maintained in [TemplateProcess.InitializeSubprocessor()](https://github.com/microsoftgraph/MSGraph-SDK-Code-Generator/blob/dev/src/GraphODataTemplateWriter/TemplateProcessor/TemplateProcessor.cs#L54). The language specific mappings exist in the [config directory](https://github.com/microsoftgraph/MSGraph-SDK-Code-Generator/tree/dev/src/GraphODataTemplateWriter/.config). Each OData object returned by the subprocessor is applied to the mapped template which results in a code file output per each OData object.

In the above example, the objects in result set of the NavigationCollectionProperty subprocessor will each be applied to the EntityCollectionPage template. Each result will be a code file for each object returned by the NavigationCollectionProperty subprocessor.

#### SubProcessors

Expand Down
56 changes: 55 additions & 1 deletion Templates/CSharp/Base/EntityRequest.Base.template.tt
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,9 @@ public void AppendUpdateAsyncHeader(string entityName, string lowerCaseEntityNam
{
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" /// <param name=\"cancellationToken\">The <see cref=\"CancellationToken\"/> for the request.</param>");
}
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" /// <exception cref=\"ClientException\">Thrown when an object returned in a response is used for updating an object in Microsoft Graph.</exception>");
}

stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" /// <returns>The updated {0}.</returns>", entityName);
Expand Down Expand Up @@ -390,6 +392,58 @@ public string GetEntityUpdateAsyncMethod(OdcmClass odcmClass, bool initializeCol
stringBuilder.AppendFormat(" public async System.Threading.Tasks.Task<{0}> UpdateAsync({0} {1}ToUpdate, CancellationToken cancellationToken)", entityName, lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" if ({0}ToUpdate.AdditionalData != null)", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" if ({0}ToUpdate.AdditionalData.ContainsKey(Constants.HttpPropertyNames.ResponseHeaders) ||", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" {0}ToUpdate.AdditionalData.ContainsKey(Constants.HttpPropertyNames.StatusCode))", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" throw new ClientException(");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" new Error");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" Code = GeneratedErrorConstants.Codes.NotAllowed,");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" Message = String.Format(GeneratedErrorConstants.Messages.ResponseObjectUsedForUpdate, {0}ToUpdate.GetType().Name)", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" });");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" }");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" }");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" if ({0}ToUpdate.AdditionalData != null)", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" if ({0}ToUpdate.AdditionalData.ContainsKey(Constants.HttpPropertyNames.ResponseHeaders) ||", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" {0}ToUpdate.AdditionalData.ContainsKey(Constants.HttpPropertyNames.StatusCode))", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" throw new ClientException(");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" new Error");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" {");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" Code = GeneratedErrorConstants.Codes.NotAllowed,");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" Message = String.Format(GeneratedErrorConstants.Messages.ResponseObjectUsedForUpdate, {0}ToUpdate.GetType().Name)", lowerCaseEntityName);
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" });");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" }");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" }");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" this.ContentType = \"{0}\";", templateWriter.jsonContentType);
stringBuilder.Append(Environment.NewLine);
Expand Down
2 changes: 2 additions & 0 deletions Templates/CSharp/Base/IEntityRequest.Base.template.tt
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ public void AppendUpdateAsyncMethodHeader(string entityName, string lowerCaseEnt
{
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" /// <param name=\"cancellationToken\">The <see cref=\"CancellationToken\"/> for the request.</param>");
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" /// <exception cref=\"ClientException\">Thrown when an object returned in a response is used for updating an object in Microsoft Graph.</exception>");
}

stringBuilder.Append(Environment.NewLine);
Expand Down
2 changes: 1 addition & 1 deletion Templates/CSharp/Base/IRequestBuilder.Base.template.tt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public string GetInterfaceDefinition(string interfaceName)
stringBuilder.Append(Environment.NewLine);
stringBuilder.Append(" /// </summary>");
stringBuilder.Append(Environment.NewLine);
stringBuilder.AppendFormat(" public partial interface I{0}", interfaceName);
stringBuilder.AppendFormat(" public partial interface I{0} : IBaseRequestBuilder", interfaceName);

return stringBuilder.ToString();
}
Expand Down
1 change: 1 addition & 0 deletions Templates/CSharp/Base/SharedCSharp.template.tt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ bool logTemplateSrc = true;
<#=writer.WriteHeader()#>

// **NOTE** This file was generated by a tool and any changes will be overwritten.
// <auto-generated/>

<# if (logTemplateSrc) { #>
// Template Source: <#= TemplateName(host.TemplateFile) #>
Expand Down
8 changes: 6 additions & 2 deletions Templates/CSharp/Model/ComplexType.cs.tt
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,14 @@ namespace <#=complex.Namespace.GetNamespaceName()#>
// to disambiguate the type of the descendant class being sent.
if (complex.IsBaseAbstractAndReferencedAsPropertyType() && !complex.IsAbstract)
{
#> public <#=complexTypeName#>()
#> /// <summary>
/// Initializes a new instance of the <see cref="<#=complexTypeName#>"/> class.
/// </summary>
public <#=complexTypeName#>()
{
this.ODataType = "<#=complex.FullName#>";
}<#
}
<#
}
foreach(var property in complex.Properties)
{
Expand Down
2 changes: 1 addition & 1 deletion Templates/CSharp/Model/EnumType.cs.tt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace <#=enumT.Namespace.GetNamespaceName()#>
#>

/// <summary>
/// <#=emumMember.Name.SplitCamelCase()#>
/// <#=emumMember.Name.ToUpperFirstChar().SplitCamelCase()#>
/// </summary>
<#=emumMember.Name.ToCheckedCase().GetSanitizedPropertyName()#> = <#=emumMember.Value#>,
<#
Expand Down
2 changes: 1 addition & 1 deletion Templates/PHP/Model/EnumType.php.tt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class <#=enumT.Name.ToUpperFirstChar()#> extends Enum
<#
} else {
#>
const <#= value.Name.ToUnderscore().ToUpper()#> = "<#= value.Name.ToCamelize()#>";
const <#= value.Name.ToUnderscorePHPEnum().ToUpper()#> = "<#= value.Name.ToCamelize()#>";
<# }
count++;
}
Expand Down
16 changes: 6 additions & 10 deletions Templates/TypeScript/src/entity_types.ts.tt
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@
var enumTypes = model.GetEnumTypes();
var complexTypes = model.GetComplexTypes();
#>
// Type definitions for the Microsoft Graph API
// Type definitions for the Microsoft Graph <VERSION_STRING>
// Project: https://github.com/microsoftgraph/msgraph-typescript-typings
// Definitions by: Microsoft Graph Team <https://github.com/microsoftgraph>

<#= writer.WriteHeader() #>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.1

export as namespace microsoftgraph;

<# foreach(var enumType in enumTypes) { #>
export type <#= enumType.Name.UpperCaseFirstChar() #> = <#= enumType.GetEnumValues() #>
export type <#= enumType.Name.UpperCaseFirstChar() #> = <#= enumType.GetEnumValues() #>;
<# } #>
<#
foreach(var entityType in entityTypes)
Expand All @@ -28,13 +28,11 @@ export type <#= enumType.Name.UpperCaseFirstChar() #> = <#= enumType.GetEnumValu
#>

export interface <#= entityType.Name.UpperCaseFirstChar() #><# if (entityType.Base != null) { #> extends <#= entityType.Base.Name.UpperCaseFirstChar() #><# }#> {

<# foreach(var prop in entityType.Properties.ToList()) { #>
<# if (prop.LongDescription != null || prop.Description != null) { #>
/** <#=prop.GetSanitizedLongDescription()#> */
<# } #>
<#= prop.Name #>?: <#= prop.GetTypeString() #>

<#= prop.Name #>?: <#= prop.GetTypeString() #>;
<# } #>
}
<#
Expand All @@ -45,13 +43,11 @@ export interface <#= entityType.Name.UpperCaseFirstChar() #><# if (entityType.Ba
{
#>
export interface <#= complexType.Name.UpperCaseFirstChar()#><# if (complexType.Base != null) { #> extends <#= complexType.Base.Name.UpperCaseFirstChar() #><# }#> {

<# foreach(var prop in complexType.Properties) { #>
<# if (prop.LongDescription != null || prop.Description != null) { #>
/** <#=prop.GetSanitizedLongDescription()#> */
<# } #>
<#= prop.Name #>?: <#= prop.GetTypeString() #>

<#= prop.Name #>?: <#= prop.GetTypeString() #>;
<# } #>
}
<# } #>
64 changes: 47 additions & 17 deletions src/GraphODataTemplateWriter/.config/ObjCSettings.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,51 @@
{
"StaticCodePrefix": "MS",
"TemplateMapping": {
"Shared": [
{
"_Comment" : "HACK: It seems the entire 'Shared' section is copy pasted from TemplateWriterSettings.json",
"_Comment2" : "with the sole purpose of preventing the Client from being named 'MSGraphGraphServiceClient'.",
"Template": "EntityClient", "SubProcessor": "EntityContainer", "Type": "Client", "Name": "Client"
},
"StaticCodePrefix": "MS",
"NamespacePrefix": "MSGraph",
"TemplateMapping": {
"Shared": [
{
"_Comment": "HACK: It seems the entire 'Shared' section is copy pasted from TemplateWriterSettings.json",
"_Comment2": "with the sole purpose of preventing the Client from being named 'MSGraphGraphServiceClient'.",
"Template": "EntityClient",
"SubProcessor": "EntityContainer",
"Type": "Client",
"Name": "Client"
},

{ "Template": "EntityType", "SubProcessor": "EntityType", "Type": "Model", "Name": "<Class>" },
{ "Template": "ComplexType", "SubProcessor": "ComplexType", "Type": "Model", "Name": "<Class>", "Ignore": "methodResponse" },
{ "Template": "EnumType", "SubProcessor": "EnumType", "Type": "Model", "Name": "<Class>" }
],
{
"Template": "EntityType",
"SubProcessor": "EntityType",
"Type": "Model",
"Name": "<Class>"
},
{
"Template": "ComplexType",
"SubProcessor": "ComplexType",
"Type": "Model",
"Name": "<Class>",
"Ignore": "methodResponse"
},
{
"Template": "EnumType",
"SubProcessor": "EnumType",
"Type": "Model",
"Name": "<Class>"
}
],

"ObjC": [
{ "Template": "ClientModels", "SubProcessor": "Other", "Type": "Model", "Name": "ClientModels" },
{ "Template": "ODataEntities", "SubProcessor": "Other", "Type": "Model", "Name": "ODataEntities" }
]
}
"ObjC": [
{
"Template": "ClientModels",
"SubProcessor": "Other",
"Type": "Model",
"Name": "ClientModels"
},
{
"Template": "ODataEntities",
"SubProcessor": "Other",
"Type": "Model",
"Name": "ODataEntities"
}
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,10 @@ public static string GetSanitizedLongDescription(this OdcmProperty property)

if (description != null)
{
return description.Replace("<", "&lt;").Replace(">", "&gt;").Replace("&", "&amp;");
return description.Replace("<", "&lt;")
.Replace(">", "&gt;")
.Replace("&", "&amp;")
.Replace("\r\n", "\r\n///"); // &#xD;&#xA; The HTML encoded has already been converted to escaped chars.
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ public static string GetSanitizedLongDescription(this OdcmProperty property)

if (description != null)
{
return description.Replace("<", "&lt;").Replace(">", "&gt;").Replace("&", "&amp;");
return description.Replace("<", "&lt;")
.Replace(">", "&gt;")
.Replace("&", "&amp;")
.Replace("\r\n", "\r\n///"); // &#xD;&#xA; The HTML encoded has already been converted to escaped chars.
}
return null;
}
Expand Down
Loading