diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml index 4af666bc..a98ebedf 100644 --- a/.azure-pipelines/ci.yml +++ b/.azure-pipelines/ci.yml @@ -33,7 +33,5 @@ jobs: - script: npm run check-format displayName: Check formatting - - script: | - npm link - autorest-testserver validate-spec-coverage --maxErrorCount=596 + - script: npm run validate-spec-coverage displayName: Validate OpenAPI specs mock API coverage diff --git a/package.json b/package.json index acc5a2b9..76c9217e 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ "prepack": "npm run build", "format": "npm run -s prettier -- --write", "check-format": "npm run -s prettier -- --check", - "prettier": "prettier --config ./.prettierrc.yml **/*.{ts,js,cjs,mjs,json,yml,yaml,md}" + "prettier": "prettier --config ./.prettierrc.yml **/*.{ts,js,cjs,mjs,json,yml,yaml,md}", + "validate-spec-coverage": "node ./dist/cli/cli.js validate-spec-coverage --maxErrorCount=164" }, "engines": { "node": ">=10" diff --git a/src/cli/commands/validate-spec-coverage-command.ts b/src/cli/commands/validate-spec-coverage-command.ts index fb7db898..a1d9307b 100644 --- a/src/cli/commands/validate-spec-coverage-command.ts +++ b/src/cli/commands/validate-spec-coverage-command.ts @@ -7,7 +7,6 @@ import { registerLegacyRoutes } from "../../legacy"; import { logger } from "../../logger"; import { getPathsFromSpecs, SpecPath } from "../../services"; import { findFilesFromPattern } from "../../utils"; -import { CliConfig } from "../cli-config"; interface Layer { route: { path: string; methods: Record }; @@ -73,7 +72,6 @@ const findSpecCoverageErrors = (paths: SpecPath[], registeredPaths: Layer[]): Sp */ const validateRouteDefined = (path: SpecPath, registeredPaths: Layer[]): HttpMethod[] => { const methodFound: Partial> = {}; - for (const registeredPath of registeredPaths) { if (registeredPath.regexp.test(path.path)) { for (const [method, defined] of Object.entries(registeredPath.route.methods)) { @@ -84,7 +82,7 @@ const validateRouteDefined = (path: SpecPath, registeredPaths: Layer[]): HttpMet } } - return path.methods.filter((x) => !methodFound[x]); + return path.methods.filter((x) => !methodFound[x]).filter((x) => !x.startsWith("x-")); }; const loadRegisteredRoutes = async (): Promise => { @@ -99,14 +97,24 @@ const loadRegisteredRoutes = async (): Promise => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const findRoutesFromMiddleware = (middleware: any): Layer[] => { - let routes: Layer[] = []; + const routes: Layer[] = []; if (middleware.route) { - routes.push(middleware); + routes.push({ route: middleware.route, regexp: middleware.regexp }); } else if (middleware.name === "router") { for (const nested of middleware.handle.stack) { - routes = routes.concat(findRoutesFromMiddleware(nested)); + if (nested.route) { + routes.push({ route: nested.route, regexp: concatRegexp(middleware.regexp, nested.regexp) }); + } } } return routes; }; + +/** + * Combine the router regex with the child regex. + */ +function concatRegexp(router: RegExp, child: RegExp) { + const reg = router.source.replace("\\/?(?=\\/|$)", child.source.slice(1)); + return new RegExp(reg, child.flags); +} diff --git a/swagger/azure-report.json b/swagger/azure-report.json deleted file mode 100644 index e15ab98e..00000000 --- a/swagger/azure-report.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "AutoRest Report Service For Azure", - "description": "Test Infrastructure for AutoRest", - "version": "1.0.0" - }, - "host": "localhost:3000", - "schemes": ["http"], - "produces": ["application/json"], - "consumes": ["application/json"], - "paths": { - "/report/azure": { - "get": { - "operationId": "getReport", - "description": "Get test coverage report", - "parameters": [ - { - "name": "qualifier", - "in": "query", - "required": false, - "type": "string", - "description": "If specified, qualifies the generated report further (e.g. '2.7' vs '3.5' in for Python). The only effect is, that generators that run all tests several times, can distinguish the generated reports." - } - ], - "responses": { - "200": { - "description": "The test coverage mapping", - "schema": { - "type": "object", - "additionalProperties": { - "type": "integer" - } - } - }, - "default": { - "description": "Unexpected error", - "schema": { - "$ref": "#/definitions/Error" - } - } - } - } - } - }, - "definitions": { - "Error": { - "type": "object", - "properties": { - "status": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - } - } - } - } -}