Add backlog of tests and create new @autorest/testing common test package (#3838)

This commit is contained in:
Timothee Guerin 2021-02-03 14:34:15 -08:00 коммит произвёл GitHub
Родитель 0e48c57326
Коммит 5b4ec5131a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
44 изменённых файлов: 734 добавлений и 125 удалений

20
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,20 @@
# top-most EditorConfig file
root = true
[*]
# (Please don't specify an indent_size here; that has too many unintended consequences.)
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
# JS/TS files
[*.{js,jsx,ts,tsx}]
indent_size = 2
# Json files
[*.{json}]
indent_size = 2
# Yaml files
[*.{yaml}]
indent_size = 2

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/codemodel",
"comment": "",
"type": "none"
}
],
"packageName": "@autorest/codemodel",
"email": "tiguerin@microsoft.com"
}

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/core",
"comment": "Internal: Add some tests to the tree shaker",
"type": "patch"
}
],
"packageName": "@autorest/core",
"email": "tiguerin@microsoft.com"
}

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/modelerfour",
"comment": "Internal: Move out test custom matchers to seperate package",
"type": "patch"
}
],
"packageName": "@autorest/modelerfour",
"email": "tiguerin@microsoft.com"
}

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/test-utils",
"comment": "Initial content, include file snapshot matching",
"type": "minor"
}
],
"packageName": "@autorest/test-utils",
"email": "tiguerin@microsoft.com"
}

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

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@azure-tools/oai2-to-oai3",
"comment": "Internal: Add scenario tests",
"type": "patch"
}
],
"packageName": "@azure-tools/oai2-to-oai3",
"email": "tiguerin@microsoft.com"
}

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

@ -18,6 +18,7 @@ dependencies:
'@rush-temp/modelerfour': 'file:projects/modelerfour.tgz' '@rush-temp/modelerfour': 'file:projects/modelerfour.tgz'
'@rush-temp/oai2-to-oai3': 'file:projects/oai2-to-oai3.tgz_prettier@2.2.1' '@rush-temp/oai2-to-oai3': 'file:projects/oai2-to-oai3.tgz_prettier@2.2.1'
'@rush-temp/schemas': 'file:projects/schemas.tgz' '@rush-temp/schemas': 'file:projects/schemas.tgz'
'@rush-temp/test-utils': 'file:projects/test-utils.tgz_prettier@2.2.1'
'@types/body-parser': 1.19.0 '@types/body-parser': 1.19.0
'@types/commonmark': 0.27.4 '@types/commonmark': 0.27.4
'@types/deep-equal': 1.0.1 '@types/deep-equal': 1.0.1
@ -506,7 +507,7 @@ packages:
globals: 12.4.0 globals: 12.4.0
ignore: 4.0.6 ignore: 4.0.6
import-fresh: 3.3.0 import-fresh: 3.3.0
js-yaml: 3.14.1 js-yaml: 3.13.1
lodash: 4.17.20 lodash: 4.17.20
minimatch: 3.0.4 minimatch: 3.0.4
strip-json-comments: 3.1.1 strip-json-comments: 3.1.1
@ -520,7 +521,7 @@ packages:
camelcase: 5.3.1 camelcase: 5.3.1
find-up: 4.1.0 find-up: 4.1.0
get-package-type: 0.1.0 get-package-type: 0.1.0
js-yaml: 3.14.1 js-yaml: 3.13.1
resolve-from: 5.0.0 resolve-from: 5.0.0
dev: false dev: false
engines: engines:
@ -1938,7 +1939,7 @@ packages:
dependencies: dependencies:
caniuse-lite: 1.0.30001183 caniuse-lite: 1.0.30001183
colorette: 1.2.1 colorette: 1.2.1
electron-to-chromium: 1.3.652 electron-to-chromium: 1.3.653
escalade: 3.1.1 escalade: 3.1.1
node-releases: 1.1.70 node-releases: 1.1.70
dev: false dev: false
@ -2817,10 +2818,10 @@ packages:
dev: false dev: false
resolution: resolution:
integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
/electron-to-chromium/1.3.652: /electron-to-chromium/1.3.653:
dev: false dev: false
resolution: resolution:
integrity: sha512-85J5D0Ksxjq2MIHfgwOURRej72UMlexbaa7t+oKTJan3Pa/RBE8vJ4/JzwaQjLCElPvd0XeLWi7+xYTVrq96aA== integrity: sha512-LehOhcl74u9fkV9Un6WahJ+Xh+0FZLCCDnKYis1Olx1DX2ugRww5PJicE65OG8yznMj8EOQZRcz6FSV1xKxqsA==
/emittery/0.7.2: /emittery/0.7.2:
dev: false dev: false
engines: engines:
@ -3202,7 +3203,7 @@ packages:
import-fresh: 3.3.0 import-fresh: 3.3.0
imurmurhash: 0.1.4 imurmurhash: 0.1.4
is-glob: 4.0.1 is-glob: 4.0.1
js-yaml: 3.14.1 js-yaml: 3.13.1
json-stable-stringify-without-jsonify: 1.0.1 json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1 levn: 0.4.1
lodash: 4.17.20 lodash: 4.17.20
@ -5133,14 +5134,6 @@ packages:
hasBin: true hasBin: true
resolution: resolution:
integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== integrity: sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
/js-yaml/3.14.1:
dependencies:
argparse: 1.0.10
esprima: 4.0.1
dev: false
hasBin: true
resolution:
integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
/js-yaml/4.0.0: /js-yaml/4.0.0:
dependencies: dependencies:
argparse: 2.0.1 argparse: 2.0.1
@ -9143,9 +9136,7 @@ packages:
eslint: 7.19.0 eslint: 7.19.0
eslint-plugin-prettier: 3.2.0_eslint@7.19.0+prettier@2.2.1 eslint-plugin-prettier: 3.2.0_eslint@7.19.0+prettier@2.2.1
eslint-plugin-unicorn: 27.0.0_eslint@7.19.0 eslint-plugin-unicorn: 27.0.0_eslint@7.19.0
expect: 26.6.2
jest: 26.6.3 jest: 26.6.3
jest-snapshot: 26.6.2
prettier: 2.2.1 prettier: 2.2.1
recursive-diff: 1.0.8 recursive-diff: 1.0.8
rimraf: 3.0.2 rimraf: 3.0.2
@ -9158,7 +9149,7 @@ packages:
dev: false dev: false
name: '@rush-temp/modelerfour' name: '@rush-temp/modelerfour'
resolution: resolution:
integrity: sha512-FoIOdQ7TjmcaXomZinNzvF1jw1epQvnyoPAreXotN1qShiqgfQcs49N+7bBoe122fQf8cacWSqapHNhER4K1wg== integrity: sha512-dDoKlI+WbFmKIg98l3+7kzsLZtSr/ufVsEnu0ow0+0S/AbUpT4NKpXI2KgAKW4TznZOl6ZJezJAKs0IxcYgVOQ==
tarball: 'file:projects/modelerfour.tgz' tarball: 'file:projects/modelerfour.tgz'
version: 0.0.0 version: 0.0.0
'file:projects/oai2-to-oai3.tgz_prettier@2.2.1': 'file:projects/oai2-to-oai3.tgz_prettier@2.2.1':
@ -9186,7 +9177,7 @@ packages:
peerDependencies: peerDependencies:
prettier: '*' prettier: '*'
resolution: resolution:
integrity: sha512-c3miz7la4bG0FxuVgMmZNrNdoyFkH218u1UyDt2xBrDpp/jbtm8y0YL/IMvGrFso1Yf2z7JGUhTjev4XSFo8Yg== integrity: sha512-y3ZMMf925okHkt10QtBjIQFNUz+G+UkihzURLLBdRrCehA/yKReMmpM5TKNPnrcg1rGFn2y/a/kAWmUZOQVTZw==
tarball: 'file:projects/oai2-to-oai3.tgz' tarball: 'file:projects/oai2-to-oai3.tgz'
version: 0.0.0 version: 0.0.0
'file:projects/schemas.tgz': 'file:projects/schemas.tgz':
@ -9196,6 +9187,25 @@ packages:
integrity: sha512-R4SNYE56Q0TOMYcT8gSTZIInxE9vVJH1k54SR8Ksvg8HNkzG+Pko1NIxb8zpWFB74VEmx3TDaruHnodgJjUrvQ== integrity: sha512-R4SNYE56Q0TOMYcT8gSTZIInxE9vVJH1k54SR8Ksvg8HNkzG+Pko1NIxb8zpWFB74VEmx3TDaruHnodgJjUrvQ==
tarball: 'file:projects/schemas.tgz' tarball: 'file:projects/schemas.tgz'
version: 0.0.0 version: 0.0.0
'file:projects/test-utils.tgz_prettier@2.2.1':
dependencies:
'@types/jest': 26.0.20
eslint: 7.19.0
eslint-plugin-prettier: 3.2.0_eslint@7.19.0+prettier@2.2.1
eslint-plugin-unicorn: 27.0.0_eslint@7.19.0
expect: 26.6.2
jest: 26.6.3
jest-snapshot: 26.6.2
rimraf: 3.0.2
dev: false
id: 'file:projects/test-utils.tgz'
name: '@rush-temp/test-utils'
peerDependencies:
prettier: '*'
resolution:
integrity: sha512-8nMXR/fQrY7cWzKlnWAWLNAPsCqTy218Yq76aUySEg/K65B+nGDBNIZewWlUh3Dy4q/xEwC+EN8tG9/SSwQ9EA==
tarball: 'file:projects/test-utils.tgz'
version: 0.0.0
specifiers: specifiers:
'@azure-tools/async-io': ~3.0.0 '@azure-tools/async-io': ~3.0.0
'@azure-tools/datastore': ~4.1.0 '@azure-tools/datastore': ~4.1.0
@ -9216,6 +9226,7 @@ specifiers:
'@rush-temp/modelerfour': 'file:./projects/modelerfour.tgz' '@rush-temp/modelerfour': 'file:./projects/modelerfour.tgz'
'@rush-temp/oai2-to-oai3': 'file:./projects/oai2-to-oai3.tgz' '@rush-temp/oai2-to-oai3': 'file:./projects/oai2-to-oai3.tgz'
'@rush-temp/schemas': 'file:./projects/schemas.tgz' '@rush-temp/schemas': 'file:./projects/schemas.tgz'
'@rush-temp/test-utils': 'file:./projects/test-utils.tgz'
'@types/body-parser': ^1.19.0 '@types/body-parser': ^1.19.0
'@types/commonmark': ^0.27.0 '@types/commonmark': ^0.27.0
'@types/deep-equal': ^1.0.1 '@types/deep-equal': ^1.0.1

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

@ -5,7 +5,7 @@ const defaultConfig = require("../../../jest.default.config");
const config = { const config = {
...defaultConfig, ...defaultConfig,
setupFilesAfterEnv: ["<rootDir>/test/setupJest.ts"], setupFilesAfterEnv: ["<rootDir>/test/setupJest.ts"],
testMatch: ["<rootDir>/test/**/*.test.ts"], testMatch: ["<rootDir>/test/**/*.test.ts", "<rootDir>/src/**/*.test.ts"],
globals: { globals: {
"ts-jest": { "ts-jest": {
tsconfig: "tsconfig.json", tsconfig: "tsconfig.json",

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

@ -48,7 +48,7 @@ import {
createTransformerPlugin, createTransformerPlugin,
createGraphTransformerPlugin, createGraphTransformerPlugin,
} from "./plugins/transformer"; } from "./plugins/transformer";
import { createTreeShakerPlugin } from "./plugins/tree-shaker"; import { createTreeShakerPlugin } from "./plugins/tree-shaker/tree-shaker";
import { createApiVersionParameterHandlerPlugin } from "./plugins/version-param-handler"; import { createApiVersionParameterHandlerPlugin } from "./plugins/version-param-handler";
import { createJsonToYamlPlugin, createYamlToJsonPlugin } from "./plugins/yaml-and-json"; import { createJsonToYamlPlugin, createYamlToJsonPlugin } from "./plugins/yaml-and-json";
import { createOpenApiSchemaValidatorPlugin, createSwaggerSchemaValidatorPlugin } from "./schema-validation"; import { createOpenApiSchemaValidatorPlugin, createSwaggerSchemaValidatorPlugin } from "./schema-validation";

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

@ -0,0 +1,87 @@
import { Source } from "@azure-tools/datastore";
import { JsonType, Model } from "@azure-tools/openapi";
import { create } from "domain";
import { OAI3Shaker } from "./tree-shaker";
const createTestModel = (model: any): Model => {
return {
openApi: "3.0.0",
paths: {},
info: {
title: "Test spec",
version: "1.0.0",
},
servers: {},
security: {},
components: {},
tags: {},
...model,
};
};
const shake = async (model: any) => {
const source: Source = {
ReadObject: () => Promise.resolve<any>(createTestModel(model)),
key: "test",
};
const shaker = new OAI3Shaker(source, false);
return shaker.getOutput();
};
describe("Tree shaker", () => {
describe("when using x-ms-client-name", () => {
it("keeps x-ms-client-name when used on a schema", async () => {
const result = await shake({
components: {
schemas: {
Foo: {
"type": JsonType.Object,
"x-ms-client-name": "FooClient",
},
},
},
});
expect(result.components.schemas.Foo["x-ms-client-name"]).toEqual("FooClient");
});
it("keeps x-ms-client-name when used on a parameter", async () => {
const result = await shake({
paths: {
"/mypath": {
get: {
parameters: [{ "in": "query", "name": "some-param", "x-ms-client-name": "SomeParamClient" }],
},
},
},
});
const param = Object.values<any>(result.components.parameters)[0];
expect(param["x-ms-client-name"]).toEqual("SomeParamClient");
});
it("it removes x-ms-client-name on shaked model when used on property with inline model definition", async () => {
const result = await shake({
components: {
schemas: {
Foo: {
type: JsonType.Object,
properties: {
bar: {
"x-ms-client-name": "barClient",
"type": JsonType.Object,
"properties": {
name: { type: JsonType.String },
},
},
},
},
},
},
});
expect(result.components.schemas.Foo.properties.bar["x-ms-client-name"]).toEqual("barClient");
expect(result.components.schemas["Foo-bar"]["x-ms-client-name"]).toBeUndefined();
});
});
});

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

@ -11,8 +11,8 @@ import {
JsonPath, JsonPath,
Source, Source,
} from "@azure-tools/datastore"; } from "@azure-tools/datastore";
import { ConfigurationView } from "../../configuration"; import { ConfigurationView } from "../../../configuration";
import { PipelinePlugin } from "../common"; import { PipelinePlugin } from "../../common";
import { values, length } from "@azure-tools/linq"; import { values, length } from "@azure-tools/linq";
import { createHash } from "crypto"; import { createHash } from "crypto";

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

@ -1,62 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as aio from "@azure-tools/async-io";
import * as datastore from "@azure-tools/datastore";
import assert from "assert";
import { OAI3Shaker } from "../src/lib/pipeline/plugins/tree-shaker";
try {
require("source-map-support").install();
} catch {
/* unused */
}
const resources = `${__dirname}../../../test/resources/shaker`;
describe("TestShaker", () => {
// todo: fix test
xit("Test Shaker", async () => {
const inputUri = "mem://input.yaml";
const outputUri = "mem://output.yaml";
const input = await aio.readFile(`${resources}/input.yaml`);
const output = await aio.readFile(`${resources}/output.yaml`);
const map = new Map<string, string>([
[inputUri, input],
[outputUri, output],
]);
const mfs = new datastore.MemoryFileSystem(map);
const cts: datastore.CancellationTokenSource = {
cancel() {
/* unused */
},
dispose() {
/* unused */
},
token: { isCancellationRequested: false, onCancellationRequested: <any>null },
};
const ds = new datastore.DataStore(cts.token);
const scope = ds.GetReadThroughScope(mfs);
const inputDataHandle = await scope.Read(inputUri);
const outputDataHandle = await scope.Read(outputUri);
assert(inputDataHandle != null);
assert(outputDataHandle != null);
if (inputDataHandle && outputDataHandle) {
// if (inputDataHandle) {
const outputObject = await outputDataHandle.ReadObject();
const shaker = new OAI3Shaker(inputDataHandle, false);
// testing: dump out the converted file
// console.log(FastStringify(shaken));
assert.deepEqual(await shaker.getOutput(), outputObject, "Should be the same");
}
});
});

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

@ -41,6 +41,7 @@
"devDependencies": { "devDependencies": {
"@autorest/codemodel": "~4.14.3", "@autorest/codemodel": "~4.14.3",
"@autorest/extension-base": "~3.1.0", "@autorest/extension-base": "~3.1.0",
"@autorest/test-utils": "~0.0.1",
"@azure-tools/async-io": "~3.0.0", "@azure-tools/async-io": "~3.0.0",
"@azure-tools/codegen": "~2.5.0", "@azure-tools/codegen": "~2.5.0",
"@azure-tools/datastore": "~4.1.0", "@azure-tools/datastore": "~4.1.0",
@ -58,8 +59,6 @@
"eslint-plugin-prettier": "~3.2.0", "eslint-plugin-prettier": "~3.2.0",
"eslint-plugin-unicorn": "~27.0.0", "eslint-plugin-unicorn": "~27.0.0",
"eslint": "^7.17.0", "eslint": "^7.17.0",
"expect": "~26.6.2",
"jest-snapshot": "~26.6.2",
"jest": "^26.6.3", "jest": "^26.6.3",
"prettier": "~2.2.1", "prettier": "~2.2.1",
"recursive-diff": "~1.0.6", "recursive-diff": "~1.0.6",

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

@ -1 +1,2 @@
import "./custom-matchers"; // eslint-disable-next-line unicorn/filename-case
import "@autorest/test-utils/dist/matchers";

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

@ -11,7 +11,7 @@
"build": "tsc -p .", "build": "tsc -p .",
"watch": "tsc -p . --watch", "watch": "tsc -p . --watch",
"lint:fix": "eslint ./src --fix --ext .ts", "lint:fix": "eslint ./src --fix --ext .ts",
"lint": "eslint ./src --ext .ts", "lint": "eslint ./src --ext .ts --max-warnings=0",
"prepare": "npm run build", "prepare": "npm run build",
"test": "echo codemodel: No Tests.", "test": "echo codemodel: No Tests.",
"test:ci": "echo codemodel: No Tests.", "test:ci": "echo codemodel: No Tests.",

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

@ -5,6 +5,7 @@ const defaultConfig = require("../../../jest.default.config");
const config = { const config = {
...defaultConfig, ...defaultConfig,
testMatch: ["<rootDir>/test/**/*.test.ts"], testMatch: ["<rootDir>/test/**/*.test.ts"],
setupFilesAfterEnv: ["<rootDir>/test/setup-jest.ts"],
}; };
module.exports = config; module.exports = config;

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

@ -36,6 +36,7 @@
"homepage": "https://github.com/Azure/perks/tree/master/oai2-to-oai3#readme", "homepage": "https://github.com/Azure/perks/tree/master/oai2-to-oai3#readme",
"readme": "https://github.com/Azure/perks/tree/master/oai2-to-oai3/readme.md", "readme": "https://github.com/Azure/perks/tree/master/oai2-to-oai3/readme.md",
"devDependencies": { "devDependencies": {
"@autorest/test-utils": "~0.0.1",
"@types/jest": "^26.0.20", "@types/jest": "^26.0.20",
"@types/js-yaml": "~4.0.0", "@types/js-yaml": "~4.0.0",
"@types/node": "~14.14.20", "@types/node": "~14.14.20",

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

@ -678,12 +678,6 @@ export class Oai2ToOai3 {
return { value: createGraphProxy(this.originalFilename, pointer, this.mappings), pointer }; return { value: createGraphProxy(this.originalFilename, pointer, this.mappings), pointer };
} }
visitUnspecified(nodes: Iterable<Node>) {
for (const { value, pointer } of nodes) {
console.error(`?? Unknown item: ${pointer} : ${value}`);
}
}
async visitPaths(target: any, paths: Iterable<Node>, globalConsumes: Array<string>, globalProduces: Array<string>) { async visitPaths(target: any, paths: Iterable<Node>, globalConsumes: Array<string>, globalProduces: Array<string>) {
for (const { key: uri, pointer, children: pathItemMembers } of paths) { for (const { key: uri, pointer, children: pathItemMembers } of paths) {
await this.visitPath(target, uri, pointer, pathItemMembers, globalConsumes, globalProduces); await this.visitPath(target, uri, pointer, pathItemMembers, globalConsumes, globalProduces);
@ -817,38 +811,22 @@ export class Oai2ToOai3 {
} }
const parameterName = parsedRef.componentName; const parameterName = parsedRef.componentName;
if (parsedRef.basePath === "/parameters/") { if (parsedRef.basePath === "/parameters/") {
// TODO: I think we don't need this at all and can just call the else. TO check when adding the unit tests. const dereferencedParameter = await this.resolveReference(parsedRef.file, parsedRef.path);
if (parsedRef.file == "" || parsedRef.file === this.originalFilename) { if (!dereferencedParameter) {
const dereferencedParameter = get(this.original, parsedRef.path); throw new Error(`Cannot find reference ${value.$ref}`);
}
if ( if (
dereferencedParameter.in === "body" || dereferencedParameter.in === "body" ||
dereferencedParameter.type === "file" || dereferencedParameter.type === "file" ||
dereferencedParameter.in === "formData" dereferencedParameter.in === "formData"
) { ) {
childIterator = () => visit(dereferencedParameter, [parameterName]); childIterator = () => visit(dereferencedParameter, [parameterName]);
value = dereferencedParameter; value = dereferencedParameter;
pointer = parsedRef.path; pointer = parsedRef.path;
}
} else {
const dereferencedParameter = await this.resolveReference(parsedRef.file, parsedRef.path);
if (!dereferencedParameter) {
throw new Error(`Cannot find reference ${value.$ref}`);
}
if (
dereferencedParameter.in === "body" ||
dereferencedParameter.type === "file" ||
dereferencedParameter.in === "formData"
) {
childIterator = () => visit(dereferencedParameter, [parameterName]);
value = dereferencedParameter;
pointer = parsedRef.path;
}
} }
} else { } else {
// TODO: Throw exception throw new Error(`Reference ${value.$ref} is invalid. It should be referencing a parameter(#/parameters/xzy)`);
console.error("### CAN'T RESOLVE $ref", value.$ref);
} }
} }

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

@ -0,0 +1,15 @@
{
"servers": [],
"components": {
"schemas": {
"MyBodySchema": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
}
}
}
}
}

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

@ -0,0 +1,39 @@
{
"servers": [],
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"openapi": "3.0.0",
"info": {
"x-ms-metadata": {
"apiVersions": [
"test-0.1"
]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {
"/test": {
"get": {
"operationId": "test",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/MyBodySchema"
}
}
},
"required": true,
"x-ms-requestBody-name": "MyBodyParam"
},
"x-ms-requestBody-index": 0,
"responses": {
"200": {
"description": "OK."
}
}
}
}
}
}

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

@ -0,0 +1,19 @@
{
"servers": [],
"components": {
"parameters": {
"GlobalEndpoint": {
"name": "Endpoint",
"in": "path",
"description": "Shared endpoint param.",
"required": true,
"x-ms-parameter-location": "client",
"x-ms-skip-url-encoding": true,
"schema": {
"default": "https://api.cognitive.microsoft.com",
"type": "string"
}
}
}
}
}

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

@ -0,0 +1,35 @@
{
"servers": [
{
"url": "{Endpoint}",
"variables": {
"Endpoint": {
"x-name": "Endpoint",
"description": "Shared endpoint param.",
"x-ms-parameter-location": "client",
"x-required": true,
"x-type": "string",
"x-in": "path",
"x-ms-skip-url-encoding": true,
"default": "https://api.cognitive.microsoft.com",
"x-ms-original": {
"$ref": "other.json#/components/parameters/GlobalEndpoint"
}
}
}
}
],
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"openapi": "3.0.0",
"info": {
"x-ms-metadata": {
"apiVersions": [
"test-0.1"
]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {}
}

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

@ -0,0 +1,35 @@
{
"servers": [],
"components": {
"parameters": {
"QueryParm": {
"name": "MyQueryParam",
"in": "query",
"required": true,
"schema": {
"items": {
"$ref": "#/components/schemas/MyQuerySchema"
}
}
},
"HeaderParam": {
"name": "MyHeaderParam",
"in": "query",
"required": true,
"schema": {
"items": {
"$ref": "#/components/schemas/MyHeaderSchema"
}
}
}
},
"schemas": {
"MyQuerySchema": {
"type": "string"
},
"MyHeaderSchema": {
"type": "string"
}
}
}
}

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

@ -0,0 +1,35 @@
{
"servers": [],
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"openapi": "3.0.0",
"info": {
"x-ms-metadata": {
"apiVersions": [
"test-0.1"
]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {
"/test": {
"get": {
"operationId": "test",
"parameters": [
{
"$ref": "other.json#/components/parameters/QueryParm"
},
{
"$ref": "other.json#/components/parameters/HeaderParam"
}
],
"responses": {
"200": {
"description": "OK."
}
}
}
}
}
}

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

@ -0,0 +1,15 @@
{
"servers": [],
"components": {
"schemas": {
"MySharedSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}
}

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

@ -0,0 +1,28 @@
{
"servers": [],
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"openapi": "3.0.0",
"info": {
"x-ms-metadata": {
"apiVersions": [
"test-0.1"
]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {},
"components": {
"schemas": {
"MySchema": {
"type": "object",
"properties": {
"myProp": {
"$ref": "other.json#/components/schemas/MySharedSchema"
}
}
}
}
}
}

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

@ -0,0 +1,22 @@
{
"parameters": {
"BodyParam": {
"in": "body",
"name": "MyBodyParam",
"required": true,
"schema": {
"$ref": "#/definitions/MyBodySchema"
}
}
},
"definitions": {
"MyBodySchema": {
"type": "object",
"properties": {
"url": {
"type": "string"
}
}
}
}
}

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

@ -0,0 +1,26 @@
{
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"swagger": "2.0",
"info": {
"x-ms-metadata": {
"apiVersions": ["test-0.1"]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {
"/test": {
"get": {
"operationId": "test",
"parameters": [{ "$ref": "other.json#/parameters/BodyParam" }],
"responses": {
"200": {
"description": "OK."
}
}
}
}
},
"definitions": {}
}

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

@ -0,0 +1,14 @@
{
"parameters": {
"GlobalEndpoint": {
"name": "Endpoint",
"description": "Shared endpoint param.",
"x-ms-parameter-location": "client",
"required": true,
"type": "string",
"in": "path",
"x-ms-skip-url-encoding": true,
"default": "https://api.cognitive.microsoft.com"
}
}
}

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

@ -0,0 +1,23 @@
{
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"swagger": "2.0",
"info": {
"x-ms-metadata": {
"apiVersions": ["test-0.1"]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"x-ms-parameterized-host": {
"hostTemplate": "{Endpoint}",
"useSchemePrefix": false,
"parameters": [
{
"$ref": "other.json#/parameters/GlobalEndpoint"
}
]
},
"paths": {},
"definitions": {}
}

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

@ -0,0 +1,28 @@
{
"parameters": {
"QueryParm": {
"in": "query",
"name": "MyQueryParam",
"required": true,
"schema": {
"$ref": "#/definitions/MyQuerySchema"
}
},
"HeaderParam": {
"in": "query",
"name": "MyHeaderParam",
"required": true,
"schema": {
"$ref": "#/definitions/MyHeaderSchema"
}
}
},
"definitions": {
"MyQuerySchema": {
"type": "string"
},
"MyHeaderSchema": {
"type": "string"
}
}
}

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

@ -0,0 +1,29 @@
{
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"swagger": "2.0",
"info": {
"x-ms-metadata": {
"apiVersions": ["test-0.1"]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {
"/test": {
"get": {
"operationId": "test",
"parameters": [
{ "$ref": "other.json#/parameters/QueryParm" },
{ "$ref": "other.json#/parameters/HeaderParam" }
],
"responses": {
"200": {
"description": "OK."
}
}
}
}
},
"definitions": {}
}

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

@ -0,0 +1,12 @@
{
"definitions": {
"MySharedSchema": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
}
}
}
}

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

@ -0,0 +1,21 @@
{
"$schema": "https://github.com/OAI/OpenAPI-Specification/blob/master/schemas/v2.0/schema.json",
"swagger": "2.0",
"info": {
"x-ms-metadata": {
"apiVersions": ["test-0.1"]
},
"title": "Test",
"description": "test",
"version": "test-0.1"
},
"paths": {},
"definitions": {
"MySchema": {
"type": "object",
"properties": {
"myProp": { "$ref": "other.json#/definitions/MySharedSchema" }
}
}
}
}

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

@ -0,0 +1,52 @@
import fs from "fs";
import { basename, join } from "path";
import { convertOai2ToOai3, OaiToOai3FileInput } from "../../src";
const inputsFolder = `${__dirname}/inputs/`;
const expectedFolder = `${__dirname}/expected/`;
const getOAI3InputsFromTestFiles = async (
testName: string,
filenames: string[],
): Promise<Map<string, OaiToOai3FileInput>> => {
const map = new Map<string, OaiToOai3FileInput>();
for (const filename of filenames) {
const buffer = await fs.promises.readFile(join(inputsFolder, testName, filename));
const name = basename(filename);
map.set(name, { name, schema: JSON.parse(buffer.toString()) });
}
return map;
};
const expectInputsMatchSnapshots = async (testName: string, filenames: string[]) => {
const map = await getOAI3InputsFromTestFiles(testName, filenames);
const results = await convertOai2ToOai3(map);
for (const result of results) {
const jsonResult = JSON.stringify(result.result, null, 2);
expect(jsonResult).toMatchRawFileSnapshot(join(expectedFolder, testName, result.name));
}
};
describe("Scenario testings", () => {
it("Convert cross file schema references", async () => {
// The expected result is for the body parameter to be copied over but not the schema.
await expectInputsMatchSnapshots("cross-file-schema-refs", ["swagger.json", "other.json"]);
});
it("Convert cross file regular parameters", async () => {
// The expected result is the ref just change from /parameters -> /components/parameters.
await expectInputsMatchSnapshots("cross-file-parameters-refs", ["swagger.json", "other.json"]);
});
it("Convert cross file body parameter", async () => {
// The expected result is the ref just change from /defnitions -> /components/schemas.
await expectInputsMatchSnapshots("cross-file-body-refs", ["swagger.json", "other.json"]);
});
it("Convert cross file parameterized host", async () => {
// The expected result is the parmaeter to be included/expanded in the OpenAPI3 server property.
await expectInputsMatchSnapshots("cross-file-parameterized-host-refs", ["swagger.json", "other.json"]);
});
});

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

@ -0,0 +1 @@
import "@autorest/test-utils/dist/matchers";

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

@ -0,0 +1,3 @@
parser: "@typescript-eslint/parser"
extends:
- "../../../.default-eslintrc.yaml"

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

@ -0,0 +1,44 @@
{
"name": "@autorest/test-utils",
"version": "0.0.1",
"description": "Set of testing utils that are used across packages",
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"scripts": {
"build": "tsc -p .",
"watch": "tsc -p . --watch",
"clean": "rimraf ./dist",
"lint:fix": "eslint ./src --fix --ext .ts",
"lint": "eslint ./src --ext .ts --max-warnings=0",
"test:ci": "echo 'No tests'",
"test": "echo 'No tests'"
},
"engines": {
"node": ">=10.13.0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Azure/autorest.git"
},
"keywords": [
"autorest"
],
"author": "Microsoft Corporation",
"license": "MIT",
"bugs": {
"url": "https://github.com/Azure/autorest/issues"
},
"homepage": "https://github.com/Azure/autorest#readme",
"dependencies": {
"expect": "~26.6.2",
"jest-snapshot": "~26.6.2",
"jest": "^26.6.3"
},
"devDependencies": {
"@types/jest": "^26.0.20",
"eslint-plugin-prettier": "~3.2.0",
"eslint-plugin-unicorn": "~27.0.0",
"eslint": "^7.17.0",
"rimraf": "^3.0.2"
}
}

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

@ -0,0 +1,3 @@
# Autorest Testing
This package contains a set of utilities used for testing such as custom matchers.

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

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

@ -6,7 +6,7 @@ import * as path from "path";
declare global { declare global {
namespace jest { namespace jest {
interface Matchers<R> { interface Matchers<R> {
toMatchRawFileSnapshot(snapshotFile: string): CustomMatcherResult; toMatchRawFileSnapshot(snapshotFile: string): jest.CustomMatcherResult;
} }
} }
} }
@ -39,7 +39,10 @@ function toMatchRawFileSnapshot(
}; };
} }
const filepath = getAbsolutePathToSnapshot(this.testPath!, filename); if (!this.testPath) {
throw new Error("Unexpected matcher state, testPath is undefined");
}
const filepath = getAbsolutePathToSnapshot(this.testPath, filename);
const content: string = received; const content: string = received;
const updateSnapshot: "none" | "all" | "new" = (this.snapshotState as any)._updateSnapshot; const updateSnapshot: "none" | "all" | "new" = (this.snapshotState as any)._updateSnapshot;

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

@ -0,0 +1,3 @@
// Import the all custom matchers
// This is to be used inside a jest setup step.
import "./file-snapshot";

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

@ -0,0 +1,7 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "dist"
},
"include": ["src/**/*.ts", "test/**/*.ts"]
}

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

@ -60,6 +60,12 @@
"reviewCategory": "production", "reviewCategory": "production",
"shouldPublish": true "shouldPublish": true
}, },
{
"packageName": "@autorest/test-utils",
"projectFolder": "packages/testing/test-utils",
"reviewCategory": "production",
"shouldPublish": true
},
{ {
"packageName": "@autorest/extension-base", "packageName": "@autorest/extension-base",
"projectFolder": "packages/libs/extension-base", "projectFolder": "packages/libs/extension-base",