From 595e1b8ca8612d01d6bb004f125dc00eb420dca4 Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Thu, 13 Feb 2020 16:29:12 -0800 Subject: [PATCH 1/4] Add a test that was failing --- sdk/core/core-http/test/utilsTests.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 sdk/core/core-http/test/utilsTests.ts diff --git a/sdk/core/core-http/test/utilsTests.ts b/sdk/core/core-http/test/utilsTests.ts new file mode 100644 index 000000000000..b2e7b4afa4e1 --- /dev/null +++ b/sdk/core/core-http/test/utilsTests.ts @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import { isValidUuid } from "../lib/util/utils"; + +describe("utils", function() { + describe("isValidUuid()", function() { + it("should return true on a valid Uuid in multiple calls", function() { + + const uuidString = "ae9b0564-7aa1-47d1-8061-0ffd8f12f723"; + + isValidUuid(uuidString).should.be.true; + + isValidUuid(uuidString).should.be.true; + }) + }); +}) \ No newline at end of file From abfe38a7e222dcb9ca420aa4ecaa1feea776b8dc Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Thu, 13 Feb 2020 17:04:34 -0800 Subject: [PATCH 2/4] Fix isValidUuid() issue due to using test() with global flag set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It caused the next isValidUuid() call to return false. According to MDN: > When a regex has the global flag set, test() will advance the lastIndex of the regex. (RegExp.prototype.exec() also advances the lastIndex property.) Further calls to test(str) will resume searching str starting from lastIndex. The lastIndex property will continue to increase each time test() returns true. Note: As long as test() returns true, lastIndex will not reset—even when testing a different string! When test() returns false, the calling regex's lastIndex property will reset to 0. --- sdk/core/core-http/lib/util/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/core/core-http/lib/util/utils.ts b/sdk/core/core-http/lib/util/utils.ts index 2f076be25a7a..635761573113 100644 --- a/sdk/core/core-http/lib/util/utils.ts +++ b/sdk/core/core-http/lib/util/utils.ts @@ -7,7 +7,7 @@ import { RestError } from "../restError"; import { WebResource } from "../webResource"; import { Constants } from "./constants"; -const validUuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/gi; +const validUuidRegex = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/i; /** * A constant that indicates whether the environment is node.js or browser based. From 0457f6db708171a8faec94cad1a9a6fccd01f5db Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Thu, 13 Feb 2020 17:12:44 -0800 Subject: [PATCH 3/4] use expect from chai so we have message when test fails --- sdk/core/core-http/rollup.base.config.js | 2 +- sdk/core/core-http/test/utilsTests.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sdk/core/core-http/rollup.base.config.js b/sdk/core/core-http/rollup.base.config.js index 93fac1a677b5..065b85c980ad 100644 --- a/sdk/core/core-http/rollup.base.config.js +++ b/sdk/core/core-http/rollup.base.config.js @@ -85,7 +85,7 @@ export function browserConfig(test = false, production = false) { }), cjs({ namedExports: { - chai: ["assert", "AssertionError", "should"], + chai: ["assert", "AssertionError", "should", "expect"], events: ["EventEmitter"], "@opentelemetry/types": ["CanonicalCode", "SpanKind", "TraceFlags"] } diff --git a/sdk/core/core-http/test/utilsTests.ts b/sdk/core/core-http/test/utilsTests.ts index b2e7b4afa4e1..d573fa50a4c2 100644 --- a/sdk/core/core-http/test/utilsTests.ts +++ b/sdk/core/core-http/test/utilsTests.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +import { expect } from "chai"; import { isValidUuid } from "../lib/util/utils"; describe("utils", function() { @@ -9,9 +10,8 @@ describe("utils", function() { const uuidString = "ae9b0564-7aa1-47d1-8061-0ffd8f12f723"; - isValidUuid(uuidString).should.be.true; - - isValidUuid(uuidString).should.be.true; + expect(isValidUuid(uuidString), "First call failed").to.be.true; + expect(isValidUuid(uuidString), "Second call failed").to.be.true; }) }); }) \ No newline at end of file From 064a2ed0c735728488cb4ffef6ce8588e783e1ff Mon Sep 17 00:00:00 2001 From: Jeremy Meng Date: Thu, 13 Feb 2020 17:16:52 -0800 Subject: [PATCH 4/4] Remove all global flags from single line match tests --- sdk/core/core-http/lib/serializer.ts | 60 ++++++++++++++-------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/sdk/core/core-http/lib/serializer.ts b/sdk/core/core-http/lib/serializer.ts index b0d1813c6994..0f8d9f94f8a2 100644 --- a/sdk/core/core-http/lib/serializer.ts +++ b/sdk/core/core-http/lib/serializer.ts @@ -89,7 +89,7 @@ export class Serializer { if (!objectName) { objectName = mapper.serializedName!; } - if (mapperType.match(/^Sequence$/gi) !== null) { + if (mapperType.match(/^Sequence$/i) !== null) { payload = []; } @@ -124,26 +124,26 @@ export class Serializer { } else { // Validate Constraints if any this.validateConstraints(mapper, object, objectName); - if (mapperType.match(/^any$/gi) !== null) { + if (mapperType.match(/^any$/i) !== null) { payload = object; - } else if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/gi) !== null) { + } else if (mapperType.match(/^(Number|String|Boolean|Object|Stream|Uuid)$/i) !== null) { payload = serializeBasicTypes(mapperType, objectName, object); - } else if (mapperType.match(/^Enum$/gi) !== null) { + } else if (mapperType.match(/^Enum$/i) !== null) { const enumMapper: EnumMapper = mapper as EnumMapper; payload = serializeEnumType(objectName, enumMapper.type.allowedValues, object); } else if ( - mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/gi) !== null + mapperType.match(/^(Date|DateTime|TimeSpan|DateTimeRfc1123|UnixTime)$/i) !== null ) { payload = serializeDateTypes(mapperType, object, objectName); - } else if (mapperType.match(/^ByteArray$/gi) !== null) { + } else if (mapperType.match(/^ByteArray$/i) !== null) { payload = serializeByteArrayType(objectName, object); - } else if (mapperType.match(/^Base64Url$/gi) !== null) { + } else if (mapperType.match(/^Base64Url$/i) !== null) { payload = serializeBase64UrlType(objectName, object); - } else if (mapperType.match(/^Sequence$/gi) !== null) { + } else if (mapperType.match(/^Sequence$/i) !== null) { payload = serializeSequenceType(this, mapper as SequenceMapper, object, objectName); - } else if (mapperType.match(/^Dictionary$/gi) !== null) { + } else if (mapperType.match(/^Dictionary$/i) !== null) { payload = serializeDictionaryType(this, mapper as DictionaryMapper, object, objectName); - } else if (mapperType.match(/^Composite$/gi) !== null) { + } else if (mapperType.match(/^Composite$/i) !== null) { payload = serializeCompositeType(this, mapper as CompositeMapper, object, objectName); } } @@ -182,7 +182,7 @@ export class Serializer { objectName = mapper.serializedName!; } - if (mapperType.match(/^Composite$/gi) !== null) { + if (mapperType.match(/^Composite$/i) !== null) { payload = deserializeCompositeType(this, mapper as CompositeMapper, responseBody, objectName); } else { if (this.isXML) { @@ -196,12 +196,12 @@ export class Serializer { } } - if (mapperType.match(/^Number$/gi) !== null) { + if (mapperType.match(/^Number$/i) !== null) { payload = parseFloat(responseBody); if (isNaN(payload)) { payload = responseBody; } - } else if (mapperType.match(/^Boolean$/gi) !== null) { + } else if (mapperType.match(/^Boolean$/i) !== null) { if (responseBody === "true") { payload = true; } else if (responseBody === "false") { @@ -209,19 +209,19 @@ export class Serializer { } else { payload = responseBody; } - } else if (mapperType.match(/^(String|Enum|Object|Stream|Uuid|TimeSpan|any)$/gi) !== null) { + } else if (mapperType.match(/^(String|Enum|Object|Stream|Uuid|TimeSpan|any)$/i) !== null) { payload = responseBody; - } else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/gi) !== null) { + } else if (mapperType.match(/^(Date|DateTime|DateTimeRfc1123)$/i) !== null) { payload = new Date(responseBody); - } else if (mapperType.match(/^UnixTime$/gi) !== null) { + } else if (mapperType.match(/^UnixTime$/i) !== null) { payload = unixTimeToDate(responseBody); - } else if (mapperType.match(/^ByteArray$/gi) !== null) { + } else if (mapperType.match(/^ByteArray$/i) !== null) { payload = base64.decodeString(responseBody); - } else if (mapperType.match(/^Base64Url$/gi) !== null) { + } else if (mapperType.match(/^Base64Url$/i) !== null) { payload = base64UrlToByteArray(responseBody); - } else if (mapperType.match(/^Sequence$/gi) !== null) { + } else if (mapperType.match(/^Sequence$/i) !== null) { payload = deserializeSequenceType(this, mapper as SequenceMapper, responseBody, objectName); - } else if (mapperType.match(/^Dictionary$/gi) !== null) { + } else if (mapperType.match(/^Dictionary$/i) !== null) { payload = deserializeDictionaryType( this, mapper as DictionaryMapper, @@ -315,25 +315,25 @@ function unixTimeToDate(n: number): Date | undefined { function serializeBasicTypes(typeName: string, objectName: string, value: any): any { if (value !== null && value !== undefined) { - if (typeName.match(/^Number$/gi) !== null) { + if (typeName.match(/^Number$/i) !== null) { if (typeof value !== "number") { throw new Error(`${objectName} with value ${value} must be of type number.`); } - } else if (typeName.match(/^String$/gi) !== null) { + } else if (typeName.match(/^String$/i) !== null) { if (typeof value.valueOf() !== "string") { throw new Error(`${objectName} with value "${value}" must be of type string.`); } - } else if (typeName.match(/^Uuid$/gi) !== null) { + } else if (typeName.match(/^Uuid$/i) !== null) { if (!(typeof value.valueOf() === "string" && utils.isValidUuid(value))) { throw new Error( `${objectName} with value "${value}" must be of type string and a valid uuid.` ); } - } else if (typeName.match(/^Boolean$/gi) !== null) { + } else if (typeName.match(/^Boolean$/i) !== null) { if (typeof value !== "boolean") { throw new Error(`${objectName} with value ${value} must be of type boolean.`); } - } else if (typeName.match(/^Stream$/gi) !== null) { + } else if (typeName.match(/^Stream$/i) !== null) { const objectType = typeof value; if ( objectType !== "string" && @@ -395,7 +395,7 @@ function serializeBase64UrlType(objectName: string, value: any): any { function serializeDateTypes(typeName: string, value: any, objectName: string) { if (value != undefined) { - if (typeName.match(/^Date$/gi) !== null) { + if (typeName.match(/^Date$/i) !== null) { if ( !( value instanceof Date || @@ -408,7 +408,7 @@ function serializeDateTypes(typeName: string, value: any, objectName: string) { value instanceof Date ? value.toISOString().substring(0, 10) : new Date(value).toISOString().substring(0, 10); - } else if (typeName.match(/^DateTime$/gi) !== null) { + } else if (typeName.match(/^DateTime$/i) !== null) { if ( !( value instanceof Date || @@ -418,7 +418,7 @@ function serializeDateTypes(typeName: string, value: any, objectName: string) { throw new Error(`${objectName} must be an instanceof Date or a string in ISO8601 format.`); } value = value instanceof Date ? value.toISOString() : new Date(value).toISOString(); - } else if (typeName.match(/^DateTimeRfc1123$/gi) !== null) { + } else if (typeName.match(/^DateTimeRfc1123$/i) !== null) { if ( !( value instanceof Date || @@ -428,7 +428,7 @@ function serializeDateTypes(typeName: string, value: any, objectName: string) { throw new Error(`${objectName} must be an instanceof Date or a string in RFC-1123 format.`); } value = value instanceof Date ? value.toUTCString() : new Date(value).toUTCString(); - } else if (typeName.match(/^UnixTime$/gi) !== null) { + } else if (typeName.match(/^UnixTime$/i) !== null) { if ( !( value instanceof Date || @@ -441,7 +441,7 @@ function serializeDateTypes(typeName: string, value: any, objectName: string) { ); } value = dateToUnixTime(value); - } else if (typeName.match(/^TimeSpan$/gi) !== null) { + } else if (typeName.match(/^TimeSpan$/i) !== null) { if (!utils.isDuration(value)) { throw new Error( `${objectName} must be a string in ISO 8601 format. Instead was "${value}".`