Bug fix: `scenarios is undefined` when running AutoRest plugin (#276)

* reproduce "scenarios is undefined" error

* Bug fix: `scenarios is undefined` when running AutoRest plugin
This commit is contained in:
Sergey Shandar 2018-07-18 13:47:23 -07:00 коммит произвёл GitHub
Родитель d47ad01113
Коммит 8e3eac69f5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 321 добавлений и 290 удалений

2
.vscode/launch.json поставляемый
Просмотреть файл

@ -84,7 +84,7 @@
"stopOnEntry": false,
"args": [
"--no-timeouts",
"test/modelValidatorTests.ts",
"test/autorestPluginTests.ts",
"-r",
"ts-node/register",
"--no-timeouts"

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

@ -1,3 +1,6 @@
### 07/18/2018 0.4.59
- Bug fix: `scenarios is undefined` when running AutoRest plugin.
### 07/17/2018 0.4.58
- export additional types.

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

@ -0,0 +1,253 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as linq from "linq"
import * as jsonPath from "jsonpath"
import * as yaml from "js-yaml"
import * as utils from "../util/utils"
import { log } from "../util/logging"
import * as specValidator from "../validators/specValidator"
import { IAutoRestPluginInitiator } from
"@microsoft.azure/autorest-extension-base/dist/lib/extension-base"
import * as extensionBase from "@microsoft.azure/autorest-extension-base"
import { SourceLocation } from
"@microsoft.azure/autorest-extension-base/dist/lib/types"
import { Unknown } from "../util/unknown"
import { CommonError } from "../util/commonError"
import { SwaggerObject } from "yasway"
import { ModelValidator } from "../validators/modelValidator"
export const extension = new extensionBase.AutoRestExtension()
const openAPIDocUrl = "https://github.com/Azure/oav"
const modelValidatorPluginName = "model-validator"
const modelValidationCategory = "ExampleModelViolation"
class FormattedOutput {
constructor(
public readonly channel: Channel,
public readonly details: {},
public readonly code: string[],
public readonly text: string,
public readonly source: SourceLocation[]) {
}
}
export type Channel = "information" | "warning" | "error" | "debug" | "verbose"
export interface Message {
readonly channel: Channel
readonly text: string
readonly details: Unknown
readonly code: string[]
readonly source: SourceLocation[]
}
/**
* Returns a promise with the examples validation of the swagger.
*/
async function analyzeSwagger(
swaggerFileName: string, autoRestApi: extensionBase.Host
): Promise<void> {
const swaggerFile = await autoRestApi.ReadFile(swaggerFileName)
const swagger = yaml.safeLoad(swaggerFile)
const exampleValidationResults = await openApiValidationExample(swagger, swaggerFileName)
for (const result of exampleValidationResults) {
autoRestApi.Message({
Channel: result.channel,
Text: result.text,
Details: result.details,
Key: result.code,
Source: result.source,
})
}
// console.error(JSON.stringify(exampleValidationResults, null, 2))
}
extension.Add(
modelValidatorPluginName,
async (autoRestApi: IAutoRestPluginInitiator): Promise<void> => {
const swaggerFileNames = await autoRestApi.ListInputs()
const promises = swaggerFileNames.map(
async (swaggerFileName) => await analyzeSwagger(swaggerFileName, autoRestApi))
await Promise.all(promises)
})
export interface Options extends specValidator.Options {
consoleLogLevel?: Unknown
}
export async function openApiValidationExample(
swagger: yaml.DocumentLoadResult, swaggerFileName: string, options?: Options
): Promise<Message[]> {
const formattedResult: FormattedOutput[] = []
if (!options) { options = {} }
options.consoleLogLevel = "off"
log.consoleLogLevel = options.consoleLogLevel
const specVal = new ModelValidator(
swaggerFileName, swagger as SwaggerObject, options)
// console.error(JSON.stringify(swagger, null, 2))
await specVal.initialize()
try {
specVal.validateOperations()
const specValidationResult = specVal.specValidationResult
for (const op of utils.getKeys(specValidationResult.operations)) {
const operation = specValidationResult.operations[op]
if (operation === undefined) {
throw new Error("operation is undefined")
}
const xmsExamplesNode = operation["x-ms-examples"];
if (xmsExamplesNode === undefined) {
throw new Error("xmsExamplesNode is undefined")
}
const scenarios = xmsExamplesNode.scenarios
for (const scenario of utils.getKeys(scenarios)) {
if (scenarios === undefined) {
throw new Error("scenarios is undefined")
}
// invalid? meaning that there's an issue found in the validation
const scenarioItem = scenarios[scenario]
if (scenarioItem === undefined) {
throw new Error("scenarioItem is undefined")
}
if (scenarioItem.isValid === false) {
// get path to x-ms-examples in swagger
const xmsexPath = linq
.from(jsonPath.nodes(
swagger, `$.paths[*][?(@.operationId==='${op}')]["x-ms-examples"]`))
.select(x => x.path)
.firstOrDefault();
if (!xmsexPath) {
throw new Error("Model Validator: Path to x-ms-examples not found.")
}
// console.error(JSON.stringify(scenarioItem, null, 2));
let result = new FormattedOutput(
"verbose",
{ scenarioItem, scenario },
[modelValidationCategory],
"Model validator found issue (see details).",
[{ document: swaggerFileName, Position: { path: xmsexPath } }])
formattedResult.push(result)
// request
const request = scenarioItem.request
if (request !== undefined && request.isValid === false) {
const error = request.error as CommonError
const innerErrors = error.innerErrors
if (!innerErrors || !innerErrors.length) {
throw new Error("Model Validator: Unexpected format.")
}
for (const innerError of innerErrors) {
const innerErrorPath = innerError.path as string[]
const path = convertIndicesFromStringToNumbers(innerErrorPath)
// console.error(JSON.stringify(error, null, 2))
const resultDetails = {
type: "Error",
code: error.code,
message: error.message,
id: error.id,
validationCategory: modelValidationCategory,
innerErrors: innerError,
}
if (error.code === undefined || error.id === undefined) {
throw new Error("Invalid error.")
}
result = new FormattedOutput(
"error",
resultDetails,
[error.code, error.id, modelValidationCategory],
innerError.message
+ ". \nScenario: "
+ scenario
+ ". \nDetails: "
+ JSON.stringify(innerError.errors, null, 2)
+ "\nMore info: "
+ openAPIDocUrl
+ "#"
+ error.id.toLowerCase()
+ "-"
+ error.code.toLowerCase()
+ "\n",
[{ document: swaggerFileName, Position: { path } }])
formattedResult.push(result)
}
}
// responses
if (scenarioItem.responses !== undefined) {
for (const responseCode of utils.getKeys(scenarioItem.responses)) {
const response = scenarioItem.responses[responseCode]
if (response.isValid === false) {
const error = response.error as CommonError
const innerErrors = error.innerErrors
if (!innerErrors || !innerErrors.length) {
throw new Error("Model Validator: Unexpected format.")
}
for (const innerError of innerErrors) {
// console.error(JSON.stringify(error, null, 2));
const resultDetails = {
type: "Error",
code: error.code,
message: error.message,
id: error.id,
validationCategory: modelValidationCategory,
innerErrors: innerError,
}
if (error.code === undefined || error.id === undefined) {
throw new Error("Invalid error.")
}
result = new FormattedOutput(
"error",
resultDetails,
[error.code, error.id, modelValidationCategory],
innerError.message
+ ". \nScenario: "
+ scenario
+ ". \nDetails: "
+ JSON.stringify(innerError.errors, null, 2)
+ "\nMore info: "
+ openAPIDocUrl
+ "#"
+ error.id.toLowerCase()
+ "-"
+ error.code.toLowerCase() + "\n",
[{
document: swaggerFileName,
Position: {
path: xmsexPath
.slice(0, xmsexPath.length - 1)
.concat(["responses", responseCode]),
},
}])
formattedResult.push(result)
}
}
}
}
}
}
}
return formattedResult
} catch (err) {
/* tslint:disable-next-line:no-console */
console.error(err)
throw err
}
}
/**
* Path comes with indices as strings in "inner errors", so converting those to actual numbers for
* path to work.
*/
function convertIndicesFromStringToNumbers(path: string[]): Array<string|number> {
const result: Array<string|number> = path.slice()
for (let i = 1; i < result.length; ++i) {
const num = parseInt(result[i] as string)
if (!isNaN(num) && result[i - 1] === "parameters") {
result[i] = num
}
}
return result
}

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

@ -3,252 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as linq from "linq"
import * as jsonPath from "jsonpath"
import * as yaml from "js-yaml"
import * as utils from "../util/utils"
import { log } from "../util/logging"
import * as specValidator from "../validators/specValidator"
import * as extensionBase from "@microsoft.azure/autorest-extension-base"
import { IAutoRestPluginInitiator } from
"@microsoft.azure/autorest-extension-base/dist/lib/extension-base"
import { SourceLocation } from
"@microsoft.azure/autorest-extension-base/dist/lib/types"
import { Unknown } from "../util/unknown"
import { CommonError } from "../util/commonError"
import { SwaggerObject } from "yasway"
import { ModelValidator } from "../validators/modelValidator"
const openAPIDocUrl = "https://github.com/Azure/oav"
const extension = new extensionBase.AutoRestExtension()
const modelValidatorPluginName = "model-validator"
const modelValidationCategory = "ExampleModelViolation"
class FormattedOutput {
constructor(
public readonly channel: Channel,
public readonly details: {},
public readonly code: string[],
public readonly text: string,
public readonly source: SourceLocation[]) {
}
}
export type Channel = "information" | "warning" | "error" | "debug" | "verbose"
export interface Message {
readonly channel: Channel
readonly text: string
readonly details: Unknown
readonly code: string[]
readonly source: SourceLocation[]
}
/**
* Returns a promise with the examples validation of the swagger.
*/
async function analyzeSwagger(
swaggerFileName: string, autoRestApi: extensionBase.Host
): Promise<void> {
const swaggerFile = await autoRestApi.ReadFile(swaggerFileName)
const swagger = yaml.safeLoad(swaggerFile)
const exampleValidationResults = await openApiValidationExample(swagger, swaggerFileName)
for (const result of exampleValidationResults) {
autoRestApi.Message({
Channel: result.channel,
Text: result.text,
Details: result.details,
Key: result.code,
Source: result.source,
})
}
// console.error(JSON.stringify(exampleValidationResults, null, 2))
}
extension.Add(
modelValidatorPluginName,
async (autoRestApi: IAutoRestPluginInitiator): Promise<void> => {
const swaggerFileNames = await autoRestApi.ListInputs()
const promises = swaggerFileNames.map(
swaggerFileName => analyzeSwagger(swaggerFileName, autoRestApi))
await Promise.all(promises)
})
export interface Options extends specValidator.Options {
consoleLogLevel?: Unknown
}
export async function openApiValidationExample(
swagger: yaml.DocumentLoadResult, swaggerFileName: string, options?: Options
): Promise<Message[]> {
const formattedResult: FormattedOutput[] = []
if (!options) { options = {} }
options.consoleLogLevel = "off"
log.consoleLogLevel = options.consoleLogLevel
const specVal = new ModelValidator(
swaggerFileName, swagger as SwaggerObject, options)
// console.error(JSON.stringify(swagger, null, 2))
await specVal.initialize()
try {
specVal.validateOperations()
const specValidationResult = specVal.specValidationResult
for (const op of utils.getKeys(specValidationResult.operations)) {
const operation = specValidationResult.operations[op]
if (operation === undefined) {
throw new Error("operation is undefined")
}
const xmsExamplesNode = operation["x-ms-examples"];
if (xmsExamplesNode === undefined) {
throw new Error("xmsExamplesNode is undefined")
}
const scenarios = xmsExamplesNode.scenarios
if (scenarios === undefined) {
throw new Error("scenarios is undefined")
}
for (const scenario of utils.getKeys(scenarios)) {
// invalid? meaning that there's an issue found in the validation
const scenarioItem = scenarios[scenario]
if (scenarioItem === undefined) {
throw new Error("scenarios is undefined")
}
if (scenarioItem.isValid === false) {
// get path to x-ms-examples in swagger
const xmsexPath = linq
.from(jsonPath.nodes(
swagger, `$.paths[*][?(@.operationId==='${op}')]["x-ms-examples"]`))
.select(x => x.path)
.firstOrDefault();
if (!xmsexPath) {
throw new Error("Model Validator: Path to x-ms-examples not found.")
}
// console.error(JSON.stringify(scenarioItem, null, 2));
let result = new FormattedOutput(
"verbose",
{ scenarioItem, scenario },
[modelValidationCategory],
"Model validator found issue (see details).",
[{ document: swaggerFileName, Position: { path: xmsexPath } }])
formattedResult.push(result)
// request
const request = scenarioItem.request
if (request !== undefined && request.isValid === false) {
const error = request.error as CommonError
const innerErrors = error.innerErrors
if (!innerErrors || !innerErrors.length) {
throw new Error("Model Validator: Unexpected format.")
}
for (const innerError of innerErrors) {
const innerErrorPath = innerError.path as string[]
const path = convertIndicesFromStringToNumbers(innerErrorPath)
// console.error(JSON.stringify(error, null, 2))
const resultDetails = {
type: "Error",
code: error.code,
message: error.message,
id: error.id,
validationCategory: modelValidationCategory,
innerErrors: innerError,
}
if (error.code === undefined || error.id === undefined) {
throw new Error("Invalid error.")
}
result = new FormattedOutput(
"error",
resultDetails,
[error.code, error.id, modelValidationCategory],
innerError.message
+ ". \nScenario: "
+ scenario
+ ". \nDetails: "
+ JSON.stringify(innerError.errors, null, 2)
+ "\nMore info: "
+ openAPIDocUrl
+ "#"
+ error.id.toLowerCase()
+ "-"
+ error.code.toLowerCase()
+ "\n",
[{ document: swaggerFileName, Position: { path } }])
formattedResult.push(result)
}
}
// responses
if (scenarioItem.responses !== undefined) {
for (const responseCode of utils.getKeys(scenarioItem.responses)) {
const response = scenarioItem.responses[responseCode]
if (response.isValid === false) {
const error = response.error as CommonError
const innerErrors = error.innerErrors
if (!innerErrors || !innerErrors.length) {
throw new Error("Model Validator: Unexpected format.")
}
for (const innerError of innerErrors) {
// console.error(JSON.stringify(error, null, 2));
const resultDetails = {
type: "Error",
code: error.code,
message: error.message,
id: error.id,
validationCategory: modelValidationCategory,
innerErrors: innerError,
}
if (error.code === undefined || error.id === undefined) {
throw new Error("Invalid error.")
}
result = new FormattedOutput(
"error",
resultDetails,
[error.code, error.id, modelValidationCategory],
innerError.message
+ ". \nScenario: "
+ scenario
+ ". \nDetails: "
+ JSON.stringify(innerError.errors, null, 2)
+ "\nMore info: "
+ openAPIDocUrl
+ "#"
+ error.id.toLowerCase()
+ "-"
+ error.code.toLowerCase() + "\n",
[{
document: swaggerFileName,
Position: {
path: xmsexPath
.slice(0, xmsexPath.length - 1)
.concat(["responses", responseCode]),
},
}])
formattedResult.push(result)
}
}
}
}
}
}
}
return formattedResult
} catch (err) {
/* tslint:disable-next-line:no-console */
console.error(err)
throw err
}
}
/**
* Path comes with indices as strings in "inner errors", so converting those to actual numbers for
* path to work.
*/
function convertIndicesFromStringToNumbers(path: string[]): Array<string|number> {
const result: Array<string|number> = path.slice()
for (let i = 1; i < result.length; ++i) {
const num = parseInt(result[i] as string)
if (!isNaN(num) && result[i - 1] === "parameters") {
result[i] = num
}
}
return result
}
import { extension } from "./extension"
// tslint:disable-next-line:no-floating-promises
extension.Run()

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

@ -27,7 +27,7 @@ export const builder: yargs.CommandBuilder = {
},
}
export function handler(argv: yargs.Arguments): Promise<void> {
export async function handler(argv: yargs.Arguments): Promise<void> {
log.debug(argv.toString())
const specPath = argv.specPath
const recordings = argv.recordings
@ -37,5 +37,5 @@ export function handler(argv: yargs.Arguments): Promise<void> {
output: argv.outDir,
matchApiVersion: argv.matchApiVersion,
}
return validate.extractXMsExamples(specPath, recordings, vOptions)
return await validate.extractXMsExamples(specPath, recordings, vOptions)
}

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

@ -134,7 +134,7 @@ export type Options = request.CoreOptions & request.UrlOptions & {
*
* @return {Promise} promise - A promise that resolves to the responseBody or rejects to an error.
*/
export function makeRequest(options: Options): Promise<SwaggerObject> {
export async function makeRequest(options: Options): Promise<SwaggerObject> {
const promise = new Promise<SwaggerObject>((resolve, reject) => {
request(options, (err, response, responseBody) => {
if (err) {
@ -160,7 +160,7 @@ export function makeRequest(options: Options): Promise<SwaggerObject> {
resolve(res)
})
})
return promise
return await promise
}
/*
@ -299,9 +299,9 @@ export function joinPath(...args: string[]): string {
*
* @returns {object} jsonDoc - Parsed document in JSON format.
*/
export function parseJsonWithPathFragments(...args: string[]): Promise<SwaggerObject> {
export async function parseJsonWithPathFragments(...args: string[]): Promise<SwaggerObject> {
const specPath = joinPath(...args)
return parseJson(specPath)
return await parseJson(specPath)
}
/*
@ -799,7 +799,7 @@ export function getValues<T>(obj: StringMap<T>|null): Array<NonUndefined<T>> {
.* The check is necessary because Object.keys does not coerce parameters to object type.
* @param {*} obj
*/
export function getKeys(obj: StringMap<any>): string[] {
export function getKeys(obj: StringMap<any>|undefined): string[] {
if (obj === undefined || obj === null) {
return []
}

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

@ -84,10 +84,10 @@ async function validate<T>(
}
}
export function validateSpec(
export async function validateSpec(
specPath: string, options: Options|undefined
): Promise<SpecValidationResult> {
return validate(options, async o => {
return await validate(options, async o => {
// As a part of resolving discriminators we replace all the parent references
// with a oneOf array containing references to the parent and its children.
// This breaks the swagger specification 2.0 schema since oneOf is not supported.
@ -126,10 +126,10 @@ export async function validateCompositeSpec(
})
}
export function validateExamples(
export async function validateExamples(
specPath: string, operationIds: string|undefined, options?: Options
): Promise<SpecValidationResult> {
return validate(options, async o => {
return await validate(options, async o => {
const validator = new ModelValidator(specPath, null, o)
finalValidationResult[specPath] = validator.specValidationResult
await validator.initialize()
@ -155,10 +155,10 @@ export function validateExamples(
})
}
export function validateExamplesInCompositeSpec(
export async function validateExamplesInCompositeSpec(
compositeSpecPath: string, options: Options
): Promise<ReadonlyArray<SpecValidationResult>> {
return validate(options, async o => {
return await validate(options, async o => {
o.consoleLogLevel = log.consoleLogLevel
o.logFilepath = log.filepath
const docs = await getDocumentsFromCompositeSwagger(compositeSpecPath)
@ -204,7 +204,7 @@ export async function resolveCompositeSpec(
const docs = await getDocumentsFromCompositeSwagger(specPath)
options.consoleLogLevel = log.consoleLogLevel
options.logFilepath = log.filepath
const promiseFactories = docs.map(doc => () => resolveSpec(doc, outputDir, options))
const promiseFactories = docs.map(doc => async () => await resolveSpec(doc, outputDir, options))
await utils.executePromisesSequentially(promiseFactories)
} catch (err) {
log.error(err)
@ -246,7 +246,7 @@ export async function generateWireFormatInCompositeSpec(
options.consoleLogLevel = log.consoleLogLevel
options.logFilepath = log.filepath
const promiseFactories = docs.map(doc =>
() => generateWireFormat(doc, outDir, emitYaml, null, options))
async () => await generateWireFormat(doc, outDir, emitYaml, null, options))
await utils.executePromisesSequentially(promiseFactories)
} catch (err) {
log.error(err)
@ -317,7 +317,7 @@ export function logDetailedInfo<T extends CommonValidationResult>(
log.silly("----------------------------")
}
export function extractXMsExamples(
export async function extractXMsExamples(
specPath: string, recordings: Unknown, options: Options
): Promise<void> {
@ -325,5 +325,5 @@ export function extractXMsExamples(
log.consoleLogLevel = options.consoleLogLevel || log.consoleLogLevel
log.filepath = options.logFilepath || log.filepath
const xMsExampleExtractor = new XMsExampleExtractor(specPath, recordings, options)
return xMsExampleExtractor.extract()
return await xMsExampleExtractor.extract()
}

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

@ -195,7 +195,7 @@ export class LiveValidator {
// ...
// }
const promiseFactories = swaggerPaths.map(
swaggerPath => () => this.getSwaggerInitializer(swaggerPath))
swaggerPath => async () => await this.getSwaggerInitializer(swaggerPath))
await utils.executePromisesSequentially(promiseFactories)
log.info("Cache initialization complete.")

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

@ -258,7 +258,7 @@ export class SpecResolver {
const allRefsRemoteRelative = JsonRefs.findRefs(doc, options)
const promiseFactories = utils.getKeys(allRefsRemoteRelative).map(refName => {
const refDetails = allRefsRemoteRelative[refName]
return () => this.resolveRelativeReference(refName, refDetails, doc, docPath)
return async () => await this.resolveRelativeReference(refName, refDetails, doc, docPath)
});
if (promiseFactories.length) {
await utils.executePromisesSequentially(promiseFactories)

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

@ -176,7 +176,7 @@ export class WireFormatGenerator {
return err
}
private resolveExamples(): Promise<any> {
private async resolveExamples(): Promise<any> {
const self = this
const options = {
relativeBase: self.specDir,
@ -186,17 +186,17 @@ export class WireFormatGenerator {
const allRefsRemoteRelative = JsonRefs.findRefs(self.specInJson, options)
const promiseFactories = utils.getKeys(allRefsRemoteRelative).map(refName => {
const refDetails = allRefsRemoteRelative[refName]
return () => self.resolveRelativeReference(
return async () => await self.resolveRelativeReference(
refName, refDetails, self.specInJson, self.specPath)
})
if (promiseFactories.length) {
return utils.executePromisesSequentially(promiseFactories)
return await utils.executePromisesSequentially(promiseFactories)
} else {
return Promise.resolve(self.specInJson)
return self.specInJson
}
}
private resolveRelativeReference(
private async resolveRelativeReference(
refName: any, refDetails: any, doc: any, docPath: any
): Promise<any> {
@ -216,7 +216,6 @@ export class WireFormatGenerator {
throw new Error('docPath cannot be null or undefined and must be of type "string".')
}
const self = this
const node = refDetails.def
const slicedRefName = refName.slice(1)
const reference = node.$ref
@ -229,21 +228,20 @@ export class WireFormatGenerator {
docPath = utils.joinPath(docDir, parsedReference.filePath)
}
return utils.parseJson(docPath).then((result: any) => {
if (!parsedReference.localReference) {
// Since there is no local reference we will replace the key in the object with the parsed
// json (relative) file it is refering to.
const regex = /.*x-ms-examples.*/ig
if (slicedRefName.match(regex) !== null) {
const exampleObj = {
filePath: docPath,
value: result
}
utils.setObject(doc, slicedRefName, exampleObj)
const result = await utils.parseJson(docPath)
if (!parsedReference.localReference) {
// Since there is no local reference we will replace the key in the object with the parsed
// json (relative) file it is referring to.
const regex = /.*x-ms-examples.*/ig
if (slicedRefName.match(regex) !== null) {
const exampleObj = {
filePath: docPath,
value: result
}
utils.setObject(doc, slicedRefName, exampleObj)
}
return Promise.resolve(doc)
})
}
return doc
}
/*

2
package-lock.json сгенерированный
Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "oav",
"version": "0.4.58",
"version": "0.4.59",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

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

@ -1,6 +1,6 @@
{
"name": "oav",
"version": "0.4.58",
"version": "0.4.59",
"author": {
"name": "Microsoft Corporation",
"email": "azsdkteam@microsoft.com",
@ -95,7 +95,7 @@
},
"scripts": {
"tsc": "tsc",
"tslint": "tslint ./*.ts ./lib/**/*.ts ./test/**/*.ts ./types/**/*.ts",
"tslint": "tslint --project tsconfig.json ./*.ts ./lib/**/*.ts ./test/**/*.ts ./types/**/*.ts",
"test": "npm run tsc && npm run tslint && nyc mocha ./test/**/*.ts -r ts-node/register -t 10000",
"start": "node ./dist/lib/autorestPlugin/pluginHost.js",
"prepack": "npm install && tsc && npm run tslint",

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

@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
import * as ap from "../lib/autorestPlugin/extension"
import { SwaggerObject } from "yasway"
describe("autorestPlugin/pluginHost", () => {
it("shouldn't fail if no scenarios", async () => {
const swagger: SwaggerObject = {
paths: {
"/somepath/": {
get: {}
}
}
}
await ap.openApiValidationExample(swagger, "path")
})
})

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

@ -9,6 +9,7 @@ const options = {
}
const validator = new LiveValidator(options)
// tslint:disable-next-line:no-floating-promises
validator.initialize().then(() => {
const reqRes = require(
__dirname +

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

@ -16,7 +16,10 @@
"interface-name": false,
"jsdoc-format": false,
"object-literal-shorthand": false,
"forin": false
"forin": false,
"no-floating-promises": true,
"await-promise": true,
"promise-function-async": true
},
"rulesDirectory": []
}