* fix url encoding issue

* new URL add base host

* fix URL based

* fix unittest

* rename function

* renmae

* update changelog

* update test and remove unused readme

* fix data-plane regex

* update liveValidator
This commit is contained in:
Ruoxuan Wang 2021-11-23 11:13:34 +08:00 коммит произвёл GitHub
Родитель 73dfa760e1
Коммит d1e42e9767
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
20 изменённых файлов: 2503 добавлений и 17 удалений

Просмотреть файл

@ -7,6 +7,7 @@
- LiveValidator - ignore LRO header check if using 201/200+ provisioningState
- SemanticValidator - Fix false alarm for MISSING_PATH_PARAMETER_DEFINITION
- ModelValidator/SemanticValidator - support suppression on error code
- Use `new URL` instead of `url.parse`. Since url.parse will encode url and will be deprecated.
- SemanticValidator - Add new rules of 'INVALID_XMS_DISCRIMINATOR_VALUE' and 'DISCRIMINATOR_PROPERTY_NOT_FOUND'
## 11/04/2021 2.10.2

Просмотреть файл

@ -6,8 +6,8 @@ import * as os from "os";
import * as path from "path";
import { resolve as pathResolve } from "path";
import { ParsedUrlQuery } from "querystring";
import * as url from "url";
import * as util from "util";
import { URL } from "url";
import * as _ from "lodash";
import * as models from "../models";
import { requestResponseDefinition } from "../models/requestResponse";
@ -24,6 +24,7 @@ import { RuntimeException } from "../util/validationError";
import { inversifyGetContainer, inversifyGetInstance, TYPES } from "../inversifyUtils";
import { setDefaultOpts } from "../swagger/loader";
import { apiValidationErrors, ApiValidationErrorCode } from "../util/errorDefinitions";
import { kvPairsToObject } from "../util/utils";
import { LiveValidatorLoader, LiveValidatorLoaderOption } from "./liveValidatorLoader";
import { getProviderFromPathTemplate, OperationSearcher } from "./operationSearcher";
import {
@ -382,7 +383,9 @@ export class LiveValidator {
};
}
if (!liveRequest.query) {
liveRequest.query = url.parse(liveRequest.url, true).query;
liveRequest.query = kvPairsToObject(
new URL(liveRequest.url, "https://management.azure.com").searchParams
);
}
let errors: LiveValidationIssue[] = [];
let runtimeException;
@ -715,6 +718,7 @@ export class LiveValidator {
const startTimeAddSpecToCache = Date.now();
this.operationSearcher.addSpecToCache(spec);
// TODO: add data-plane RP to cache.
this.logging(
`Add spec to cache ${swaggerPath}`,
LiveValidatorLoggingLevels.info,
@ -834,15 +838,15 @@ export const parseValidationRequest = (
let resourceType = "";
let providerNamespace = "";
const parsedUrl = url.parse(requestUrl, true);
const parsedUrl = new URL(requestUrl, "https://management.azure.com");
const pathStr = parsedUrl.pathname || "";
if (pathStr !== "") {
// Lower all the keys and values of query parameters before searching for `api-version`
const queryObject = _.transform(
parsedUrl.query,
(obj: ParsedUrlQuery, value, key) =>
(obj[key.toLowerCase()] = _.isString(value) ? value.toLowerCase() : value)
);
const queryObject: ParsedUrlQuery = {};
parsedUrl.searchParams.forEach((value, key) => {
queryObject[key.toLowerCase()] = value.toLowerCase();
});
apiVersion = (queryObject["api-version"] || C.unknownApiVersion) as string;
providerNamespace = getProviderFromPathTemplate(pathStr) || C.unknownResourceProvider;
resourceType = utils.getResourceType(pathStr, providerNamespace);

Просмотреть файл

@ -343,11 +343,22 @@ export function getProviderFromPathTemplate(pathStr?: string | null): string | u
}
const providerRegEx = new RegExp("/providers/(:?[^{/]+)", "gi");
export function getProviderFromSpecPath(specPath: string): string | undefined {
const match = providerInSpecPathRegEx.exec(specPath);
return match === null ? undefined : match[1];
export interface PathProvider {
provider: string;
type: "resource-manager" | "data-plane";
}
const providerInSpecPathRegEx = new RegExp("/resource-manager/(:?[^{/]+)", "gi");
export function getProviderFromSpecPath(specPath: string): PathProvider | undefined {
const manageManagementMatch = managementPlaneProviderInSpecPathRegEx.exec(specPath);
const dataPlaneMatch = dataPlaneProviderInSpecPathRegEx.exec(specPath);
return manageManagementMatch === null
? dataPlaneMatch === null
? undefined
: { provider: dataPlaneMatch[1], type: "data-plane" }
: { provider: manageManagementMatch[1], type: "resource-manager" };
}
const managementPlaneProviderInSpecPathRegEx = new RegExp("/(resource-manager)/(:?[^{/]+)", "gi");
const dataPlaneProviderInSpecPathRegEx = new RegExp("/(data-plane)/(:?[^{/]+)", "gi");
/**
* Gets list of matched operations objects for given url.

Просмотреть файл

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as url from "url";
import { URL } from "url";
import { mapEntries, MutableStringMap } from "@azure-tools/openapi-tools-common";
import * as msRest from "ms-rest";
@ -30,7 +30,9 @@ export class HttpTemplate {
protected getHost(): string | undefined {
const requestUrl = this.request.url;
return requestUrl ? url.parse(requestUrl).host : "management.azure.com";
return requestUrl
? new URL(requestUrl, "https://management.azure.com").host
: "management.azure.com";
}
protected getCurlRequestHeaders(padding?: string): string {

Просмотреть файл

@ -489,6 +489,15 @@ export function isUrlEncoded(str: string): boolean {
}
}
export function kvPairsToObject(entries: any) {
const result: any = {};
for (const [key, value] of entries) {
// each 'entry' is a [key, value] tupple
result[key] = value;
}
return result;
}
/**
* Determines whether the given model is a pure (free-form) object candidate (i.e. equivalent of the
* C# Object type).

Просмотреть файл

@ -3,7 +3,7 @@
import * as fs from "fs";
import * as pathlib from "path";
import * as url from "url";
import { URL } from "url";
import {
MutableStringMap,
StringMap,
@ -14,6 +14,7 @@ import {
} from "@azure-tools/openapi-tools-common";
import swaggerParser from "swagger-parser";
import { log } from "./util/logging";
import { kvPairsToObject } from "./util/utils";
interface Options {
output?: string;
@ -142,9 +143,10 @@ export class XMsExampleExtractor {
let queryParams: any = {};
for (const recordingEntry of values(recordingEntries)) {
entryIndex++;
const parsedUrl = url.parse(recordingEntry.RequestUri, true);
const parsedUrl = new URL(recordingEntry.RequestUri, "https://management.azure.com");
let recordingPath = parsedUrl.href || "";
queryParams = parsedUrl.query || {};
queryParams = kvPairsToObject(parsedUrl.searchParams) || {};
const hostUrl = parsedUrl ? parsedUrl.protocol! + "//" + parsedUrl.hostname! : undefined;
const headerParams = recordingEntry.RequestHeaders;

Просмотреть файл

@ -0,0 +1,35 @@
{
"liveRequest": {
"url": "https://fakeendpoint.table.core.windows.net/Tables('uttableb8e52e37')?api-version=2019-02-02",
"headers": {
"Accept": "application/json",
"Accept-Encoding": "gzip, deflate",
"Authorization": "Sanitized",
"Content-Length": "0",
"Date": "Mon, 18 Oct 2021 21:58:36 GMT",
"User-Agent": "azsdk-python-data-tables/12.1.1 Python/3.9.2 (Windows-10-10.0.19041-SP0)",
"x-ms-client-request-id": "8b35094a-305e-11ec-9e2a-5cf37093a909",
"x-ms-date": "Mon, 18 Oct 2021 21:58:36 GMT",
"x-ms-version": "2019-02-02"
},
"body": null,
"method": "DELETE"
},
"liveResponse": {
"body": null,
"statusCode": "204",
"headers": {
"Cache-Control": "no-cache",
"Content-Length": "0",
"Date": "Mon, 18 Oct 2021 21:58:29 GMT",
"Server": [
"Windows-Azure-Table/1.0",
"Microsoft-HTTPAPI/2.0"
],
"X-Content-Type-Options": "nosniff",
"x-ms-client-request-id": "8b35094a-305e-11ec-9e2a-5cf37093a909",
"x-ms-request-id": "57627185-2002-0015-6a6b-c4666e000000",
"x-ms-version": "2019-02-02"
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"url": "myaccount.table.core.windows.net",
"tableProperties": {
"TableName": "mytable"
}
},
"responses": {
"201": {
"body": {
"odata.metadata": "https://myaccount.table.core.windows.net/$metadata#Tables/@Element",
"odata.type": " myaccount.Tables",
"odata.id": "https://myaccount.table.core.windows.net/Tables('mytable')",
"odata.editLink": "Tables('mytable')",
"TableName": "mytable"
}
},
"204": {}
}
}

Просмотреть файл

@ -0,0 +1,10 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"url": "myaccount.table.core.windows.net",
"table": "mytable"
},
"responses": {
"204": {}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"If-Match": "*",
"url": "myaccount.table.core.windows.net",
"table": "Customers",
"partitionKey": "mypartitionkey",
"rowKey": "myrowkey"
},
"responses": {
"204": {}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"$top": 1,
"url": "myaccount.table.core.windows.net"
},
"responses": {
"200": {
"body": {
"odata.metadata": "https://myaccount.table.core.windows.net/$metadata#Tables",
"value": [
{
"odata.type": "myaccount.Tables",
"odata.id": "https://myaccount.table.core.windows.net/Tables('mytable')",
"odata.editLink": "Tables('mytable')",
"TableName": "mytable"
}
]
}
}
}
}

Просмотреть файл

@ -0,0 +1,48 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"table": "Customer",
"url": "myaccount.table.core.windows.net",
"tableEntityProperties": {
"Address": "Mountain View",
"Age": 23,
"AmountDue": 200.23,
"CustomerCode@odata.type": "Edm.Guid",
"CustomerCode": "c9da6455-213d-42c9-9a79-3e9149a57833",
"CustomerSince@odata.type": "Edm.DateTime",
"CustomerSince": "2008-07-10T00:00:00",
"IsActive": true,
"NumberOfOrders@odata.type": "Edm.Int64",
"NumberOfOrders": "255",
"PartitionKey": "mypartitionkey",
"RowKey": "myrowkey"
}
},
"responses": {
"201": {
"body": {
"odata.metadata": "https://myaccount.table.core.windows.net/Customer/$metadata#Customers/@Element",
"odata.type": "myaccount.Customers",
"odata.id": " https://myaccount.table.core.windows.net/Customers(PartitionKey='mypartitionkey',RowKey='myrowkey')",
"odata.etag": "W/\"0x5B168C7B6E589D2\"",
"odata.editLink": "Customers(PartitionKey='mypartitionkey',RowKey='myrowkey')",
"PartitionKey": "mypartitionkey",
"RowKey": "myrowkey",
"Timestamp@odata.type": "Edm.DateTime",
"Timestamp": "2013-08-22T01:12:06.2608595Z",
"Address": "Mountain View",
"Age": 23,
"AmountDue": 200.23,
"CustomerCode@odata.type": "Edm.Guid",
"CustomerCode": "c9da6455-213d-42c9-9a79-3e9149a57833",
"CustomerSince@odata.type": "Edm.DateTime",
"CustomerSince": "2008-07-10T00:00:00",
"IsActive": true,
"NumberOfOrders@odata.type": "Edm.Int64",
"NumberOfOrders": "255"
}
},
"204": {}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"url": "myaccount.table.core.windows.net",
"table": "Customers",
"partitionKey": "mypartitionkey",
"rowKey": "myrowkey",
"tableEntityProperties": {
"Address": "Santa Clara",
"Age": 23,
"AmountDue": 200.23,
"CustomerCode@odata.type": "Edm.Guid",
"CustomerCode": "c9da6455-213d-42c9-9a79-3e9149a57833",
"CustomerSince@odata.type": "Edm.DateTime",
"CustomerSince": "2008-07-10T00:00:00",
"IsActive": false,
"NumberOfOrders@odata.type": "Edm.Int64",
"NumberOfOrders": "255",
"PartitionKey": "mypartitionkey",
"RowKey": "myrowkey"
}
},
"responses": {
"204": {}
}
}

Просмотреть файл

@ -0,0 +1,30 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"url": "myaccount.table.core.windows.net",
"$top": 1,
"table": "Customer"
},
"responses": {
"200": {
"body": {
"odata.metadata": " https://myaccount.table.core.windows.net/metadata#Customers",
"value": [
{
"PartitionKey": "Customer",
"RowKey": "Name",
"odata.type": "myaccount.Customers",
"odata.id": "https://myaccount.table.core.windows.net/Customers(PartitionKey=Customer',RowKey='Name')",
"odata.etag": "W/\"0x5B168C7B6E589D2\"",
"odata.editLink": "Customers(PartitionKey=Customer',RowKey='Name')",
"Timestamp@odata.type": "Edm.DateTime",
"Timestamp": "2013-08-22T00:20:16.3134645Z",
"CustomerSince@odata.type": "Edm.DateTime",
"CustomerSince": "2008-10-01T15:25:05.2852025Z"
}
]
}
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"url": "myaccount.table.core.windows.net",
"table": "Customers",
"partitionKey": "Customer",
"rowKey": "Name"
},
"responses": {
"200": {
"body": {
"odata.metadata": " https://myaccount.table.core.windows.net/metadata#Customers",
"odata.type": "myaccount.Customers",
"odata.id": "https://myaccount.table.core.windows.net/Customers(PartitionKey=Customer',RowKey='Name')",
"odata.etag": "W/\"0x5B168C7B6E589D2\"",
"odata.editLink": "Customers(PartitionKey=Customer',RowKey='Name')",
"PartitionKey": "Customer",
"RowKey": "Name",
"Timestamp@odata.type": "Edm.DateTime",
"Timestamp": "2013-08-22T00:20:16.3134645Z",
"CustomerSince@odata.type": "Edm.DateTime",
"CustomerSince": "2008-10-01T15:25:05.2852025Z"
}
}
}
}

Просмотреть файл

@ -0,0 +1,27 @@
{
"parameters": {
"x-ms-version": "2019-02-02",
"DataServiceVersion": "3.0",
"url": "myaccount.table.core.windows.net",
"table": "Customers",
"partitionKey": "mypartitionkey",
"rowKey": "myrowkey",
"tableEntityProperties": {
"Address": "Santa Clara",
"Age": 23,
"AmountDue": 200.23,
"CustomerCode@odata.type": "Edm.Guid",
"CustomerCode": "c9da6455-213d-42c9-9a79-3e9149a57833",
"CustomerSince@odata.type": "Edm.DateTime",
"CustomerSince": "2008-07-10T00:00:00",
"IsActive": false,
"NumberOfOrders@odata.type": "Edm.Int64",
"NumberOfOrders": "255",
"PartitionKey": "mypartitionkey",
"RowKey": "myrowkey"
}
},
"responses": {
"204": {}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,248 @@
# Table Dataplane
> see https://aka.ms/autorest
This is the AutoRest configuration file for Tables.
---
## Getting Started
To build the SDK for Tables, simply [Install AutoRest](https://aka.ms/autorest/install) and in this folder, run:
> `autorest`
To see additional help and options, run:
> `autorest --help`
---
## Configuration
### Basic Information
These are the global settings for the Tables API.
``` yaml
azure-validator: true
openapi-type: data-plane
tag: package-2019-02
```
### Tag: package-2019-02
These settings apply only when `--tag=package-2019-02` is specified on the command line.
``` yaml $(tag) == 'package-2019-02'
input-file:
- Microsoft.Tables/preview/2019-02-02/table.json
```
---
# Suppressions
``` yaml
directive:
- suppress: D5001
where: $["x-ms-paths"]["/?ServiceProperties"].put
reason: The path only supports XML input/outputm which is not supported
- suppress: D5001
where: $["x-ms-paths"]["/?ServiceProperties"].get
reason: The path only supports XML input/outputm which is not supported
- suppress: D5001
where: $["x-ms-paths"]["/?ServiceStats"].get
reason: The path only supports XML input/outputm which is not supported
- suppress: D5001
where: $.paths["/{table}"].get
reason: The path only supports XML input/outputm which is not supported
- suppress: D5001
where: $.paths["/{table}"].put
reason: The path only supports XML input/outputm which is not supported
- suppress: R3016
where: $.definitions.TableServiceError.properties.Message
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableServiceProperties.properties.Logging
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableServiceProperties.properties.HourMetrics
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableServiceProperties.properties.MinuteMetrics
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableServiceProperties.properties.Cors
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Logging.properties.Version
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Logging.properties.Delete
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Logging.properties.Read
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Logging.properties.Write
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Logging.properties.RetentionPolicy
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Metrics.properties.Version
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Metrics.properties.Enabled
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Metrics.properties.IncludeAPIs
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.Metrics.properties.RetentionPolicy
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.CorsRule.properties.AllowedOrigins
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.CorsRule.properties.AllowedMethods
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.CorsRule.properties.AllowedHeaders
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.CorsRule.properties.ExposedHeaders
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.CorsRule.properties.MaxAgeInSeconds
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.RetentionPolicy.properties.Enabled
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.RetentionPolicy.properties.Days
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableServiceStats.properties.GeoReplication
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.GeoReplication.properties.Status
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.GeoReplication.properties.LastSyncTime
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableProperties.properties.TableName
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableResponse.properties["odata.metadata"]
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableQueryResponse.properties["odata.metadata"]
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableResponseProperties.properties.TableName
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableResponseProperties.properties["odata.type"]
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableResponseProperties.properties["odata.id"]
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableResponseProperties.properties["odata.editLink"]
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.SignedIdentifier.properties.Id
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.SignedIdentifier.properties.AccessPolicy
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.AccessPolicy.properties.Start
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.AccessPolicy.properties.Expiry
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.AccessPolicy.properties.Permission
reason: Response from service is not camel case
- suppress: R3016
where: $.definitions.TableEntityQueryResponse.properties["odata.metadata"]
reason: Response from service is not camel case
- suppress: R2058
where: $["x-ms-paths"]["/?ServiceStats"]
reason: Cannot provide operation in "paths"
- suppress: R2058
where: $["x-ms-paths"]["/?ServiceProperties"]
reason: Cannot provide operation in "paths"
```
---
# Code Generation
## Swagger to SDK
Swagger to SDK has been intentionally disabled for this spec.
## C#
These settings apply only when `--csharp` is specified on the command line.
Please also specify `--csharp-sdks-folder=<path to "SDKs" directory of your azure-sdk-for-net clone>`.
``` yaml $(csharp)
csharp:
azure-arm: true
license-header: MICROSOFT_MIT_NO_VERSION
namespace: Microsoft.Azure.Storage.Tables
output-folder: $(csharp-sdks-folder)/Storage/Tables/Generated
clear-output-folder: true
```
## Python
See configuration in [readme.python.md](./readme.python.md)
## Go
See configuration in [readme.go.md](./readme.go.md)
## Java
These settings apply only when `--java` is specified on the command line.
Please also specify `--azure-libraries-for-java-folder=<path to the root directory of your azure-libraries-for-java clone>`.
``` yaml $(java)
java:
azure-arm: true
namespace: com.microsoft.azure.storage.tables
license-header: MICROSOFT_MIT_NO_CODEGEN
output-folder: $(azure-libraries-for-java-folder)/azure-storage-tables
```
## Multi-API/Profile support for AutoRest v3 generators
AutoRest V3 generators require the use of `--tag=all-api-versions` to select api files.
This block is updated by an automatic script. Edits may be lost!
``` yaml $(tag) == 'all-api-versions' /* autogenerated */
# include the azure profile definitions from the standard location
require: $(this-folder)/../../../profiles/readme.md
# all the input files across all versions
input-file:
- $(this-folder)/Microsoft.Tables/preview/2019-02-02/table.json
```
If there are files that should not be in the `all-api-versions` set,
uncomment the `exclude-file` section below and add the file paths.
``` yaml $(tag) == 'all-api-versions'
#exclude-file:
# - $(this-folder)/Microsoft.Example/stable/2010-01-01/somefile.json
```

Просмотреть файл

@ -0,0 +1,26 @@
// Copyright (c) 2021 Microsoft Corporation
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
import { LiveValidator } from "../lib/liveValidation/liveValidator";
describe("LiveValidator for data-plane", () => {
describe("Initialization", () => {
it("should initialize data-plane swagger without errors", async () => {
const tableSwaggerFilePath =
"cosmos-db/data-plane/Microsoft.Tables/preview/2019-02-02/table.json";
const options = {
swaggerPathsPattern: [tableSwaggerFilePath],
directory: "./test/liveValidation/swaggers/specification",
};
const liveValidator = new LiveValidator(options);
await liveValidator.initialize();
expect(liveValidator.operationSearcher.cache.size).toEqual(1);
expect(Array.from(liveValidator.operationSearcher.cache.keys())).toEqual([
"microsoft.unknown",
]);
});
});
});

Просмотреть файл

@ -249,6 +249,13 @@ describe("Live Validator", () => {
"get": 2,
"put": 1,
},
"2019-02-02": Object {
"delete": 2,
"get": 6,
"patch": 1,
"post": 2,
"put": 3,
},
}
`);
assert.strictEqual(numberOfSpecs, cache.size);