From 14a2cdf50281abce4714351cf42493ad0f626ed2 Mon Sep 17 00:00:00 2001 From: annatisch Date: Thu, 2 Jun 2016 11:38:27 -0700 Subject: [PATCH] [Python] Fixed bug in enum namespace docs (#1074) * Fixed bug in enum namespace docs * Fixed parameter order * Fixed decimal serialization * Added decimal tests * formatting cleanups --- .../AcceptanceTests/number_tests.py | 12 ++++ .../models/basic.py | 2 +- .../operations/number.py | 18 +++--- .../operations/enum.py | 5 +- .../operations/header.py | 2 +- .../operations/paths.py | 4 +- .../operations/queries.py | 4 +- .../autorestvalidationtest/models/product.py | 2 +- .../Python/Python/ClientModelExtensions.cs | 8 ++- .../TemplateModels/MethodTemplateModel.cs | 5 +- .../TemplateModels/ModelTemplateModel.cs | 5 +- .../ServiceClientTemplateModel.cs | 15 +++-- AutoRest/TestServer/server/app.js | 12 +++- AutoRest/TestServer/server/routes/number.js | 57 ++++++++++++++++--- 14 files changed, 114 insertions(+), 37 deletions(-) diff --git a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/number_tests.py b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/number_tests.py index c3cc2bdea971b..3f3816ee3defe 100644 --- a/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/number_tests.py +++ b/AutoRest/Generators/Python/Python.Tests/AcceptanceTests/number_tests.py @@ -30,6 +30,7 @@ import isodate import tempfile import json +from decimal import Decimal from datetime import date, datetime, timedelta import os from os.path import dirname, pardir, join, realpath, sep, pardir @@ -59,6 +60,10 @@ def test_numbers(self): client.number.put_small_double(2.5976931e-101) client.number.put_big_double_negative_decimal(-99999999.99) client.number.put_big_double_positive_decimal(99999999.99) + client.number.put_big_decimal(Decimal(2.5976931e+101)) + client.number.put_small_decimal(Decimal(2.5976931e-101)) + client.number.put_big_decimal_positive_decimal(Decimal(99999999.99)) + client.number.put_big_decimal_negative_decimal(Decimal(-99999999.99)) client.number.get_null() self.assertEqual(client.number.get_big_float(), 3.402823e+20) self.assertEqual(client.number.get_small_float(), 3.402823e-20) @@ -66,6 +71,13 @@ def test_numbers(self): self.assertEqual(client.number.get_small_double(), 2.5976931e-101) self.assertEqual(client.number.get_big_double_negative_decimal(), -99999999.99) self.assertEqual(client.number.get_big_double_positive_decimal(), 99999999.99) + self.assertEqual(client.number.get_big_decimal(), 2.5976931e+101) + self.assertEqual(client.number.get_small_decimal(), 2.5976931e-101) + self.assertEqual(client.number.get_big_decimal_negative_decimal(), -99999999.99) + self.assertEqual(client.number.get_big_decimal_positive_decimal(), 99999999.99) + + with self.assertRaises(DeserializationError): + client.number.get_invalid_decimal() with self.assertRaises(DeserializationError): client.number.get_invalid_double() diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/models/basic.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/models/basic.py index 69a638c4f89c8..e42e7e46cc7cc 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/models/basic.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyComplex/autorestcomplextestservice/models/basic.py @@ -22,7 +22,7 @@ class Basic(Model): :param color: Possible values include: 'cyan', 'Magenta', 'YELLOW', 'blacK' :type color: str or :class:`CMYKColors - ` + ` """ _attribute_map = { diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyNumber/autorestnumbertestservice/operations/number.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyNumber/autorestnumbertestservice/operations/number.py index 407caf3075958..9afbf132ed0b2 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyNumber/autorestnumbertestservice/operations/number.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyNumber/autorestnumbertestservice/operations/number.py @@ -199,7 +199,7 @@ def get_invalid_decimal( deserialized = None if response.status_code == 200: - deserialized = self._deserialize('Decimal', response) + deserialized = self._deserialize('decimal', response) if raw: client_raw_response = ClientRawResponse(deserialized, response) @@ -584,7 +584,7 @@ def put_big_decimal( header_parameters.update(custom_headers) # Construct body - body_content = self._serialize.body(number_body, 'Decimal') + body_content = self._serialize.body(number_body, 'decimal') # Construct and send request request = self._client.put(url, query_parameters) @@ -634,7 +634,7 @@ def get_big_decimal( deserialized = None if response.status_code == 200: - deserialized = self._deserialize('Decimal', response) + deserialized = self._deserialize('decimal', response) if raw: client_raw_response = ClientRawResponse(deserialized, response) @@ -671,7 +671,7 @@ def put_big_decimal_positive_decimal( header_parameters.update(custom_headers) # Construct body - body_content = self._serialize.body(number_body, 'Decimal') + body_content = self._serialize.body(number_body, 'decimal') # Construct and send request request = self._client.put(url, query_parameters) @@ -721,7 +721,7 @@ def get_big_decimal_positive_decimal( deserialized = None if response.status_code == 200: - deserialized = self._deserialize('Decimal', response) + deserialized = self._deserialize('decimal', response) if raw: client_raw_response = ClientRawResponse(deserialized, response) @@ -758,7 +758,7 @@ def put_big_decimal_negative_decimal( header_parameters.update(custom_headers) # Construct body - body_content = self._serialize.body(number_body, 'Decimal') + body_content = self._serialize.body(number_body, 'decimal') # Construct and send request request = self._client.put(url, query_parameters) @@ -808,7 +808,7 @@ def get_big_decimal_negative_decimal( deserialized = None if response.status_code == 200: - deserialized = self._deserialize('Decimal', response) + deserialized = self._deserialize('decimal', response) if raw: client_raw_response = ClientRawResponse(deserialized, response) @@ -1019,7 +1019,7 @@ def put_small_decimal( header_parameters.update(custom_headers) # Construct body - body_content = self._serialize.body(number_body, 'Decimal') + body_content = self._serialize.body(number_body, 'decimal') # Construct and send request request = self._client.put(url, query_parameters) @@ -1069,7 +1069,7 @@ def get_small_decimal( deserialized = None if response.status_code == 200: - deserialized = self._deserialize('Decimal', response) + deserialized = self._deserialize('decimal', response) if raw: client_raw_response = ClientRawResponse(deserialized, response) diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyString/autorestswaggerbatservice/operations/enum.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyString/autorestswaggerbatservice/operations/enum.py index 9880ab28e0910..926e8b418f580 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyString/autorestswaggerbatservice/operations/enum.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/BodyString/autorestswaggerbatservice/operations/enum.py @@ -42,7 +42,8 @@ def get_not_expandable( deserialized response :param operation_config: :ref:`Operation configuration overrides`. - :rtype: :class:`Colors ` + :rtype: :class:`Colors + ` :rtype: :class:`ClientRawResponse` if raw=true """ @@ -85,7 +86,7 @@ def put_not_expandable( :param string_body: Possible values include: 'red color', 'green-color', 'blue_color' :type string_body: str or :class:`Colors - ` + ` :param dict custom_headers: headers that will be added to the request :param bool raw: returns the direct response alongside the deserialized response diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Header/autorestswaggerbatheaderservice/operations/header.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Header/autorestswaggerbatheaderservice/operations/header.py index 22fc077e71f66..a44d8569917d6 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Header/autorestswaggerbatheaderservice/operations/header.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Header/autorestswaggerbatheaderservice/operations/header.py @@ -1197,7 +1197,7 @@ def param_enum( :param value: Send a post request with header values 'GREY' . Possible values include: 'White', 'black', 'GREY' :type value: str or :class:`GreyscaleColors - ` + ` :param dict custom_headers: headers that will be added to the request :param bool raw: returns the direct response alongside the deserialized response diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py index c5e497e11e4f7..fa471ef4aade5 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/paths.py @@ -642,7 +642,7 @@ def enum_valid( :param enum_path: send the value green. Possible values include: 'red color', 'green color', 'blue color' :type enum_path: str or :class:`UriColor - ` + ` :param dict custom_headers: headers that will be added to the request :param bool raw: returns the direct response alongside the deserialized response @@ -688,7 +688,7 @@ def enum_null( :param enum_path: send null should throw. Possible values include: 'red color', 'green color', 'blue color' :type enum_path: str or :class:`UriColor - ` + ` :param dict custom_headers: headers that will be added to the request :param bool raw: returns the direct response alongside the deserialized response diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/queries.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/queries.py index 309ef289b50d2..bc643c4fb7e12 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/queries.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Url/autoresturltestservice/operations/queries.py @@ -806,7 +806,7 @@ def enum_valid( :param enum_query: 'green color' enum value. Possible values include: 'red color', 'green color', 'blue color' :type enum_query: str or :class:`UriColor - ` + ` :param dict custom_headers: headers that will be added to the request :param bool raw: returns the direct response alongside the deserialized response @@ -849,7 +849,7 @@ def enum_null( :param enum_query: null string value. Possible values include: 'red color', 'green color', 'blue color' :type enum_query: str or :class:`UriColor - ` + ` :param dict custom_headers: headers that will be added to the request :param bool raw: returns the direct response alongside the deserialized response diff --git a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/models/product.py b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/models/product.py index a8e00da0b0808..241f57547bba1 100644 --- a/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/models/product.py +++ b/AutoRest/Generators/Python/Python.Tests/Expected/AcceptanceTests/Validation/autorestvalidationtest/models/product.py @@ -40,7 +40,7 @@ class Product(Model): :param const_string_as_enum: Constant string as Enum. Possible values include: 'constant_string_as_enum' :type const_string_as_enum: str or :class:`EnumConst - ` + ` """ _validation = { diff --git a/AutoRest/Generators/Python/Python/ClientModelExtensions.cs b/AutoRest/Generators/Python/Python/ClientModelExtensions.cs index 131b0ef8a7941..9735853848e2f 100644 --- a/AutoRest/Generators/Python/Python/ClientModelExtensions.cs +++ b/AutoRest/Generators/Python/Python/ClientModelExtensions.cs @@ -157,6 +157,11 @@ public static string ToPythonRuntimeTypeString(this IType type) { return "base64"; } + + if (known.Type == KnownPrimaryType.Decimal) + { + return "decimal"; + } } var enumType = type as EnumType; @@ -264,7 +269,8 @@ public static string GetPythonSerializationType(IType type) { KnownPrimaryType.DateTimeRfc1123, "rfc-1123" }, { KnownPrimaryType.TimeSpan, "duration" }, { KnownPrimaryType.UnixTime, "unix-time" }, - { KnownPrimaryType.Base64Url, "base64" } + { KnownPrimaryType.Base64Url, "base64" }, + { KnownPrimaryType.Decimal, "decimal" } }; PrimaryType primaryType = type as PrimaryType; if (primaryType != null) diff --git a/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs b/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs index 2c3a051d9c93d..04de13af7ed53 100644 --- a/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs +++ b/AutoRest/Generators/Python/Python/TemplateModels/MethodTemplateModel.cs @@ -557,6 +557,9 @@ public string GetDocumentationType(IType type) string result = "object"; var modelNamespace = ServiceClient.Name.ToPythonCase().Replace("_", ""); + if (!ServiceClient.Namespace.IsNullOrEmpty()) + modelNamespace = ServiceClient.Namespace.ToPythonCase().Replace("_", ""); + var primaryType = type as PrimaryType; var listType = type as SequenceType; var enumType = type as EnumType; @@ -593,8 +596,6 @@ public string GetDocumentationType(IType type) } else if (type is CompositeType) { - if (!ServiceClient.Namespace.IsNullOrEmpty()) - modelNamespace = ServiceClient.Namespace.ToPythonCase().Replace("_", ""); result = string.Format(CultureInfo.InvariantCulture, ":class:`{0} <{1}.models.{0}>`", type.Name, modelNamespace); } diff --git a/AutoRest/Generators/Python/Python/TemplateModels/ModelTemplateModel.cs b/AutoRest/Generators/Python/Python/TemplateModels/ModelTemplateModel.cs index 8ae4061b940b5..b3a08a8f26cb1 100644 --- a/AutoRest/Generators/Python/Python/TemplateModels/ModelTemplateModel.cs +++ b/AutoRest/Generators/Python/Python/TemplateModels/ModelTemplateModel.cs @@ -466,6 +466,9 @@ public string GetPropertyDocumentationType(IType type) string result = "object"; var modelNamespace = ServiceClient.Name.ToPythonCase().Replace("_", ""); + if (!ServiceClient.Namespace.IsNullOrEmpty()) + modelNamespace = ServiceClient.Namespace.ToPythonCase().Replace("_", ""); + var listType = type as SequenceType; if (type is PrimaryType) { @@ -485,8 +488,6 @@ public string GetPropertyDocumentationType(IType type) } else if (type is CompositeType) { - if (!ServiceClient.Namespace.IsNullOrEmpty()) - modelNamespace = ServiceClient.Namespace.ToPythonCase().Replace("_", ""); result = string.Format(CultureInfo.InvariantCulture, ":class:`{0} <{1}.models.{0}>`", type.Name, modelNamespace); } diff --git a/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs b/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs index 24317c08c1faa..e853814a5ac93 100644 --- a/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs +++ b/AutoRest/Generators/Python/Python/TemplateModels/ServiceClientTemplateModel.cs @@ -83,8 +83,9 @@ public virtual string RequiredConstructorParameters { get { + var parameters = this.Properties.OrderBy(item => !item.IsRequired); var requireParams = new List(); - foreach (var property in this.Properties) + foreach (var property in parameters) { if (property.IsRequired) { @@ -109,8 +110,9 @@ public virtual string ConfigConstructorParameters { get { + var parameters = this.Properties.OrderBy(item => !item.IsRequired); var configParams = new List(); - foreach (var property in this.Properties) + foreach (var property in parameters) { configParams.Add(property.Name.ToPythonCase()); } @@ -257,6 +259,10 @@ public string GetPropertyDocumentationType(IType type) throw new ArgumentNullException("type"); } + var modelNamespace = ServiceClient.Name.ToPythonCase().Replace("_", ""); + if (!ServiceClient.Namespace.IsNullOrEmpty()) + modelNamespace = ServiceClient.Namespace.ToPythonCase().Replace("_", ""); + string result = "object"; var primaryType = type as PrimaryType; var listType = type as SequenceType; @@ -277,7 +283,7 @@ public string GetPropertyDocumentationType(IType type) } else if (type is EnumType) { - result = "str"; + result = string.Format(CultureInfo.InvariantCulture, "str or :class:`{0} <{1}.models.{0}>`", type.Name, modelNamespace); } else if (type is DictionaryType) { @@ -285,9 +291,6 @@ public string GetPropertyDocumentationType(IType type) } else if (type is CompositeType) { - var modelNamespace = ServiceClient.Name.ToPythonCase().Replace("_", ""); - if (!ServiceClient.Namespace.IsNullOrEmpty()) - modelNamespace = ServiceClient.Namespace.ToPythonCase().Replace("_", ""); result = string.Format(CultureInfo.InvariantCulture, ":class:`{0} <{1}.models.{0}>`", type.Name, modelNamespace); } diff --git a/AutoRest/TestServer/server/app.js b/AutoRest/TestServer/server/app.js index a462baa91787d..c5cac25c02b9a 100644 --- a/AutoRest/TestServer/server/app.js +++ b/AutoRest/TestServer/server/app.js @@ -444,7 +444,17 @@ var coverage = { "getInvalidUnixTime": 1, "getNullUnixTime": 1, "putUnixTime": 1, - "UrlPathsIntUnixTime": 1 + "UrlPathsIntUnixTime": 1, + /* TODO: Once all the languages implement these tests, the scenario counters should be reset to zero. It is currently implemented in Python */ + "getDecimalInvalid": 1, + "getDecimalBig": 1, + "getDecimalSmall": 1, + "getDecimalBigPositiveDecimal" : 1, + "getDecimalBigNegativeDecimal" : 1, + "putDecimalBig": 1, + "putDecimalSmall": 1, + "putDecimalBigPositiveDecimal" : 1, + "putDecimalBigNegativeDecimal" : 1, }; // view engine setup diff --git a/AutoRest/TestServer/server/routes/number.js b/AutoRest/TestServer/server/routes/number.js index a312d2917fc88..bbe1a873b3564 100644 --- a/AutoRest/TestServer/server/routes/number.js +++ b/AutoRest/TestServer/server/routes/number.js @@ -25,8 +25,21 @@ var number = function(coverage) { } else { utils.send400(res, next, "Did not like the value provided for big double in the req " + util.inspect(req.body)); } + } else if (req.params.format === 'decimal') { + if (req.params.value === '2.5976931e+101' && req.body === 2.5976931e+101) { + coverage['putDecimalBig']++; + res.status(200).end(); + } else if (req.params.value === '99999999.99' && req.body === 99999999.99) { + coverage['putDecimalBigPositiveDecimal']++; + res.status(200).end(); + } else if (req.params.value === '-99999999.99' && req.body === -99999999.99) { + coverage['putDecimalBigNegativeDecimal']++; + res.status(200).end(); + } else { + utils.send400(res, next, "Did not like the value provided for big decimal in the req " + util.inspect(req.body)); + } } else { - utils.send400(res, next, "Please use either float or double in the req " + util.inspect(req.params.format)); + utils.send400(res, next, "Please use either float, double or decimal in the req " + util.inspect(req.params.format)); } }); @@ -51,8 +64,21 @@ var number = function(coverage) { } else { utils.send400(res, next, "Did not understand the value provided for big double in the req " + util.inspect(req.params.value)); } + } else if (req.params.format === 'decimal') { + if (req.params.value === '2.5976931e+101') { + coverage['getDecimalBig']++; + res.status(200).end('2.5976931e+101'); + } else if (req.params.value === '99999999.99') { + coverage['getDecimalBigPositiveDecimal']++; + res.status(200).end('99999999.99'); + } else if (req.params.value === '-99999999.99') { + coverage['getDecimalBigNegativeDecimal']++; + res.status(200).end('-99999999.99'); + } else { + utils.send400(res, next, "Did not understand the value provided for big decimal in the req " + util.inspect(req.params.value)); + } } else { - utils.send400(res, next, "Please use either float or double in the req " + util.inspect(req.params.format)); + utils.send400(res, next, "Please use either float, double or decimal in the req " + util.inspect(req.params.format)); } }); @@ -66,13 +92,20 @@ var number = function(coverage) { } } else if (req.params.format === 'double') { if (req.params.value === '2.5976931e-101' && req.body === 2.5976931e-101) { - coverage['putDoubleSmallScientificNotation']++ + coverage['putDoubleSmallScientificNotation']++; res.status(200).end(); } else { utils.send400(res, next, "Did not like the value provided for small double in the req " + util.inspect(req.body)); } + } else if (req.params.format === 'decimal') { + if (req.params.value === '2.5976931e-101' && req.body === 2.5976931e-101) { + coverage['putDecimalSmall']++; + res.status(200).end(); + } else { + utils.send400(res, next, "Did not like the value provided for small decimal in the req " + util.inspect(req.body)); + } } else { - utils.send400(res, next, "Please use either float or double in the req " + util.inspect(req.params.format)); + utils.send400(res, next, "Please use either float, double or decimal in the req " + util.inspect(req.params.format)); } }); @@ -86,13 +119,20 @@ var number = function(coverage) { } } else if (req.params.format === 'double') { if (req.params.value === '2.5976931e-101') { - coverage['getDoubleSmallScientificNotation']++ - res.status(200).end('2.5976931e-101'); + coverage['getDoubleSmallScientificNotation']++; + res.status(200).end('2.5976931e-101'); } else { utils.send400(res, next, "Did not like the value provided for small double in the req " + util.inspect(req.params.value)); } + } else if (req.params.format === 'decimal') { + if (req.params.value === '2.5976931e-101') { + coverage['getDecimalSmall']++; + res.status(200).end('2.5976931e-101'); + } else { + utils.send400(res, next, "Did not like the value provided for small decimal in the req " + util.inspect(req.params.value)); + } } else { - utils.send400(res, next, "Please use either float or double in the req " + util.inspect(req.params.format)); + utils.send400(res, next, "Please use either float, double or decimal in the req " + util.inspect(req.params.format)); } }); @@ -106,6 +146,9 @@ var number = function(coverage) { } else if (req.params.scenario === 'invaliddouble') { coverage['getDoubleInvalid']++; res.status(200).end('9223372036854775910.980089k'); + } else if (req.params.scenario === 'invaliddecimal') { + coverage['getDecimalInvalid']++; + res.status(200).end('9223372036854775910.980089k'); } else { res.status(400).send('Request path must contain true or false'); }