Skip to content
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
9 changes: 9 additions & 0 deletions src/core/AutoRest.Core/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/core/AutoRest.Core/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -323,4 +323,7 @@
<data name="InvalidMutabilityValueForReadOnly" xml:space="preserve">
<value>When property is modeled as "readOnly": true then x-ms-mutability extension can only have "read" value. When property is modeled as "readOnly": false then applying x-ms-mutability extension with only "read" value is not allowed. Extension contains invalid values: '{0}'.</value>
</data>
<data name="BooleanPropertyNotRecommended" xml:space="preserve">
<value>Booleans are not descriptive and make them hard to use. Instead use string enums with allowed set of values defined: '{0}'.</value>
</data>
</root>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"swagger": "2.0",
"info": {
"title": "Boolean properties not recommended in models",
"description": "Some documentation.",
"version": "2017-02-08"
},
"host": "management.azure.com",
"schemes": [
"https"
],
"basePath": "/",
"produces": [
"application/json"
],
"consumes": [
"application/json"
],
"paths": {
"/foo": {
"post": {
"operationId": "PostFoo",
"summary": "Foo path",
"description": "Foo operation",
"responses": {
"default": {
"description": "Unexpected error"
}
}
}
}
},
"definitions": {
"Test1": {
"description": "Property for foo path 1",
"properties": {
"nameAvailable": {
"readOnly": true,
"type": "boolean",
"description": "Gets a boolean value that indicates whether the name is available for you to use. If true, the name is available. If false, the name has already been taken or invalid and cannot be used."
}
}
},
"parameters": {
"SubscriptionIdParameter": {
"name": "subscriptionId",
"in": "path",
"required": true,
"type": "string",
"description": "test subscription id"
},
"ApiVersion": {
"name": "api-version",
"in": "path",
"required": true,
"type": "string",
"description": "test api version"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ public void AvoidMsdnReferencesValidation()
messages.AssertOnlyValidationMessage(typeof(AvoidMsdnReferences), 4);
}

[Fact]
public void BooleanPropertiesValidation()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per @amarzavery we should be adding "positive" tests too

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure which positive test to add in this case, since many of the other tests already don't have boolean properties included. For example, "clean-complex-spec.json" does not have boolean properties and therefore doesn't return this warning. If you think that's not enough, just let me know and I can add something else.

{
var messages = ValidateSwagger(Path.Combine("Swagger", "Validation", "boolean-properties.json"));

messages.AssertOnlyValidationMessage(typeof(BooleanPropertyNotRecommended));
}

[Fact]
public void DefaultValueInEnumValidation()
{
Expand Down
2 changes: 1 addition & 1 deletion src/modeler/AutoRest.Swagger/Model/ServiceDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public ServiceDefinition()

/// <summary>
/// Key is the object serviceTypeName and the value is swagger definition.
/// </summary>
[Rule(typeof(BooleanPropertyNotRecommended))]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: deleted line

[Rule(typeof(ResourceModelValidation))]
[Rule(typeof(TrackedResourceValidation))]
[Rule(typeof(ResourceIsMsResourceValidation))]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using AutoRest.Core.Logging;
using AutoRest.Core.Properties;
using AutoRest.Core.Validation;
using System.Collections.Generic;
using AutoRest.Swagger.Model;

namespace AutoRest.Swagger.Validation
{
/// <summary>
/// Flags properties of boolean type as they are not recommended, unless it's the only option.
/// </summary>
public class BooleanPropertyNotRecommended : TypedRule<Dictionary<string, Schema>>
{
/// <summary>
/// The template message for this Rule.
/// </summary>
/// <remarks>
/// This may contain placeholders '{0}' for parameterized messages.
/// </remarks>
public override string MessageTemplate => Resources.BooleanPropertyNotRecommended;

/// <summary>
/// The severity of this message (ie, debug/info/warning/error/fatal, etc)
/// </summary>
public override Category Severity => Category.Warning;

/// <summary>
/// Validates whether properties of type boolean exist.
/// </summary>
/// <param name="definitions">Operation Definition to validate</param>
/// <returns>true if there are propeties of type boolean, false otherwise.</returns>
public override bool IsValid(Dictionary<string, Schema> definitions, RuleContext context, out object[] formatParameters)
{
formatParameters = null;
List<string> booleanProperties = new List<string>();
foreach (string key in definitions.Keys)
{
Schema definitionSchema = definitions.GetValueOrNull(key);
if (definitionSchema.Properties != null)
{
foreach (var property in definitionSchema.Properties)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can probably be simplified using Linq's .Select() construct, will leave it to your discretion

{
if (property.Value.Type.ToString().ToLower().Equals("boolean"))
{
booleanProperties.Add(key + "/" + property.Key);

}
}
}
}
formatParameters = new[] { string.Join(", ", booleanProperties.ToArray()) };
return (booleanProperties.Count == 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly you are returning a true (or valid) if there are no boolean properties, I believe the comments don't reflect it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, thanks! I'll make another PR for the fix as this one got merged.

}
}
}