From 2e56fde0bc8d4709af4610a96d075a3e25b937bd Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 12:42:13 -0400 Subject: [PATCH 01/12] add e2e tests --- .../basic-latest/main.tsp | 5 ++ .../basic-latest/package.json | 15 ++++ .../e2e-tests.js | 88 +++++++++++++++++++ .../package.json | 1 + 4 files changed, 109 insertions(+) create mode 100644 packages/typespec-client-generator-core/basic-latest/main.tsp create mode 100644 packages/typespec-client-generator-core/basic-latest/package.json create mode 100644 packages/typespec-client-generator-core/e2e-tests.js diff --git a/packages/typespec-client-generator-core/basic-latest/main.tsp b/packages/typespec-client-generator-core/basic-latest/main.tsp new file mode 100644 index 0000000000..a7488426c2 --- /dev/null +++ b/packages/typespec-client-generator-core/basic-latest/main.tsp @@ -0,0 +1,5 @@ +import "@typespec/rest"; +import "@typespec/openapi3"; +import "@azure-tools/typespec-client-generator-core"; + +op ping(): void; diff --git a/packages/typespec-client-generator-core/basic-latest/package.json b/packages/typespec-client-generator-core/basic-latest/package.json new file mode 100644 index 0000000000..33e90c1a8a --- /dev/null +++ b/packages/typespec-client-generator-core/basic-latest/package.json @@ -0,0 +1,15 @@ +{ + "name": "@azure-tools/tcgc-test-basic-latest", + "dependencies": { + "@typespec/compiler": "latest", + "@typespec/rest": "latest", + "@typespec/http": "latest", + "@typespec/versioning": "latest", + "@typespec/openapi": "latest", + "@typespec/openapi3": "latest", + "@azure-tools/typespec-azure-core": "latest", + "@azure-tools/typespec-autorest": "latest", + "@azure-tools/typespec-azure-resource-manager": "latest" + }, + "private": true +} diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js new file mode 100644 index 0000000000..f552a0c562 --- /dev/null +++ b/packages/typespec-client-generator-core/e2e-tests.js @@ -0,0 +1,88 @@ +import { join } from "path"; +import { readdirSync } from "fs"; +import { repoRoot, run } from "../../eng/scripts/helpers.js"; + +const tcgcTestDir = join(repoRoot, "packages", "typespec-client-generator-core"); + +function main() { + printInfo(); + // await cleanTcgcDirectory(); + const packages = packPackages(); + testBasicLatest(packages); +} +main(); + +function printInfo() { + console.log("-".repeat(100)); + console.log("Npm Version: "); + run("npm", ["-v"]); + console.log("-".repeat(100)); +} + +function cleanTcgcDirectory() { + run("git", ["clean", "-xfd"], { cwd: tcgcTestDir }); +} + +function packPackages() { + run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }); + const outputFolder = join(repoRoot, "/temp/artifacts"); + const files = readdirSync(outputFolder); + console.log("Built packages:", files); + + function resolvePackage(start) { + const pkgName = files.find((x) => x.startsWith(start)); + if (pkgName === undefined) { + throw new Error(`Cannot resolve package starting with "${start}"`); + } + return join(outputFolder, pkgName); + } + + return { + "@typespec/compiler": resolvePackage("typespec-compiler-"), + "@typespec/openapi": resolvePackage("typespec-openapi-"), + "@typespec/openapi3": resolvePackage("typespec-openapi3-"), + "@typespec/http": resolvePackage("typespec-http-"), + "@typespec/rest": resolvePackage("typespec-rest-"), + "@typespec/versioning": resolvePackage("typespec-versioning-"), + "@azure-tools/typespec-azure-core": resolvePackage("typespec-azure-core-"), + "@azure-tools/typespec-autorest": resolvePackage("typespec-autorest-"), + "@azure-tools/typespec-azure-resource-manager": resolvePackage("typespec-azure-resource-manager-"), + }; +} + +function runTypeSpec(compilerTgz, args, options) { + run(npxCmd, ["-y", "-p", compilerTgz, "tsp", ...args], { ...options }); +} + +function testBasicLatest(packages) { + const basicLatestDir = join(tcgcTestDir, "basic-latest"); + const outputDir = join(basicLatestDir, "tsp-output"); + console.log("Clearing basic-latest output"); + rmSync(outputDir, { recursive: true, force: true }); + console.log("Cleared basic-latest output"); + + console.log("Installing basic-latest dependencies"); + runTypeSpec(packages["@typespec/compiler"], ["install"], { cwd: basicLatestDir }); + console.log("Installed basic-latest dependencies"); + + console.log("Running tsp compile ."); + runTypeSpec( + packages["@typespec/compiler"], + ["compile", ".", "--emit", "@typespec/openapi3"], + { + cwd: basicLatestDir, + } + ); + console.log("Completed tsp compile ."); + + expectOpenApiOutput(outputDir); +} + +function expectOpenApiOutput(outputDir) { + const expectedOutputFile = join(outputDir, "@typespec/openapi3/openapi.yaml"); + if (existsSync(expectedOutputFile)) { + console.log("Output created successfully."); + } else { + throw new Error(`Test failed to produce openapi output at "${expectedOutputFile}"`); + } +} diff --git a/packages/typespec-client-generator-core/package.json b/packages/typespec-client-generator-core/package.json index 1de18a823d..0eb04fb541 100644 --- a/packages/typespec-client-generator-core/package.json +++ b/packages/typespec-client-generator-core/package.json @@ -43,6 +43,7 @@ "test:watch": "vitest -w", "test:ui": "vitest --ui", "test:ci": "vitest run --coverage --reporter=junit --reporter=default", + "test:e2e": "node ./e2e-tests.js", "lint": "eslint . --max-warnings=0", "lint:fix": "eslint . --fix ", "regen-docs": "tspd doc . --enable-experimental --output-dir ../../docs/libraries/typespec-client-generator-core/reference" From 976b5b3176ac12ccacce849647e2a8e2445cb86f Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 13:17:11 -0400 Subject: [PATCH 02/12] add e2e test --- .../e2e-tests.js | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js index f552a0c562..483ac0a0cd 100644 --- a/packages/typespec-client-generator-core/e2e-tests.js +++ b/packages/typespec-client-generator-core/e2e-tests.js @@ -1,12 +1,14 @@ import { join } from "path"; -import { readdirSync } from "fs"; +import { readdirSync, rmSync } from "fs"; import { repoRoot, run } from "../../eng/scripts/helpers.js"; const tcgcTestDir = join(repoRoot, "packages", "typespec-client-generator-core"); +const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx"; + function main() { printInfo(); - // await cleanTcgcDirectory(); + cleanTcgcDirectory(); const packages = packPackages(); testBasicLatest(packages); } @@ -25,8 +27,11 @@ function cleanTcgcDirectory() { function packPackages() { run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }); - const outputFolder = join(repoRoot, "/temp/artifacts"); - const files = readdirSync(outputFolder); + run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }) + const azureOutputFolder = join(repoRoot, "/temp/artifacts"); + const coreOutputFolder = join(repoRoot, "/core/temp/artifacts"); + const files = readdirSync(azureOutputFolder).concat(readdirSync(coreOutputFolder)); + console.log("Built packages:", files); function resolvePackage(start) { @@ -34,6 +39,7 @@ function packPackages() { if (pkgName === undefined) { throw new Error(`Cannot resolve package starting with "${start}"`); } + const outputFolder = start.startsWith("azure-tools") ? azureOutputFolder : coreOutputFolder; return join(outputFolder, pkgName); } @@ -44,9 +50,9 @@ function packPackages() { "@typespec/http": resolvePackage("typespec-http-"), "@typespec/rest": resolvePackage("typespec-rest-"), "@typespec/versioning": resolvePackage("typespec-versioning-"), - "@azure-tools/typespec-azure-core": resolvePackage("typespec-azure-core-"), - "@azure-tools/typespec-autorest": resolvePackage("typespec-autorest-"), - "@azure-tools/typespec-azure-resource-manager": resolvePackage("typespec-azure-resource-manager-"), + "@azure-tools/typespec-azure-core": resolvePackage("azure-tools-typespec-azure-core-"), + "@azure-tools/typespec-autorest": resolvePackage("azure-tools-typespec-autorest-"), + "@azure-tools/typespec-azure-resource-manager": resolvePackage("azure-tools-typespec-azure-resource-manager-"), }; } From 3f5dd5021331a27c9501b2205a29975f840040e8 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 13:19:10 -0400 Subject: [PATCH 03/12] add changeset --- .chronus/changes/add_e2e_test-2024-4-10-13-19-5.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .chronus/changes/add_e2e_test-2024-4-10-13-19-5.md diff --git a/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md b/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md new file mode 100644 index 0000000000..559ca5413e --- /dev/null +++ b/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md @@ -0,0 +1,7 @@ +--- +changeKind: internal +packages: + - "@azure-tools/typespec-client-generator-core" +--- + +add ci step to check against latest released typespec compiler \ No newline at end of file From 127202a63cd1b3d182b474810872c2639ad7a209 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 13:23:04 -0400 Subject: [PATCH 04/12] format and correct repo spec --- .../e2e-tests.js | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js index 483ac0a0cd..2675f7dd32 100644 --- a/packages/typespec-client-generator-core/e2e-tests.js +++ b/packages/typespec-client-generator-core/e2e-tests.js @@ -1,11 +1,10 @@ -import { join } from "path"; import { readdirSync, rmSync } from "fs"; -import { repoRoot, run } from "../../eng/scripts/helpers.js"; +import { join } from "path"; +import { repoRoot, coreRepoRoot, run } from "../../eng/scripts/helpers.js"; const tcgcTestDir = join(repoRoot, "packages", "typespec-client-generator-core"); const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx"; - function main() { printInfo(); cleanTcgcDirectory(); @@ -27,7 +26,7 @@ function cleanTcgcDirectory() { function packPackages() { run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }); - run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }) + run("pnpm", ["-w", "pack:all"], { cwd: coreRepoRoot }); const azureOutputFolder = join(repoRoot, "/temp/artifacts"); const coreOutputFolder = join(repoRoot, "/core/temp/artifacts"); const files = readdirSync(azureOutputFolder).concat(readdirSync(coreOutputFolder)); @@ -52,7 +51,9 @@ function packPackages() { "@typespec/versioning": resolvePackage("typespec-versioning-"), "@azure-tools/typespec-azure-core": resolvePackage("azure-tools-typespec-azure-core-"), "@azure-tools/typespec-autorest": resolvePackage("azure-tools-typespec-autorest-"), - "@azure-tools/typespec-azure-resource-manager": resolvePackage("azure-tools-typespec-azure-resource-manager-"), + "@azure-tools/typespec-azure-resource-manager": resolvePackage( + "azure-tools-typespec-azure-resource-manager-" + ), }; } @@ -72,13 +73,9 @@ function testBasicLatest(packages) { console.log("Installed basic-latest dependencies"); console.log("Running tsp compile ."); - runTypeSpec( - packages["@typespec/compiler"], - ["compile", ".", "--emit", "@typespec/openapi3"], - { - cwd: basicLatestDir, - } - ); + runTypeSpec(packages["@typespec/compiler"], ["compile", ".", "--emit", "@typespec/openapi3"], { + cwd: basicLatestDir, + }); console.log("Completed tsp compile ."); expectOpenApiOutput(outputDir); From feca240e80cfd4bdec3c11cf26e143aafd57a955 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 13:25:51 -0400 Subject: [PATCH 05/12] format --- packages/typespec-client-generator-core/e2e-tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js index 2675f7dd32..2ac7555546 100644 --- a/packages/typespec-client-generator-core/e2e-tests.js +++ b/packages/typespec-client-generator-core/e2e-tests.js @@ -1,6 +1,6 @@ import { readdirSync, rmSync } from "fs"; import { join } from "path"; -import { repoRoot, coreRepoRoot, run } from "../../eng/scripts/helpers.js"; +import { coreRepoRoot, repoRoot, run } from "../../eng/scripts/helpers.js"; const tcgcTestDir = join(repoRoot, "packages", "typespec-client-generator-core"); const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx"; From 82c506dc8eaaf75c7ed29c3485d884b7707fcc45 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 13:27:43 -0400 Subject: [PATCH 06/12] add lint --- packages/typespec-client-generator-core/e2e-tests.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js index 2ac7555546..d47b976f62 100644 --- a/packages/typespec-client-generator-core/e2e-tests.js +++ b/packages/typespec-client-generator-core/e2e-tests.js @@ -1,3 +1,5 @@ +/* eslint-disable no-console */ + import { readdirSync, rmSync } from "fs"; import { join } from "path"; import { coreRepoRoot, repoRoot, run } from "../../eng/scripts/helpers.js"; @@ -14,7 +16,7 @@ function main() { main(); function printInfo() { - console.log("-".repeat(100)); + console.log("-".repeat(100)); // console.log("Npm Version: "); run("npm", ["-v"]); console.log("-".repeat(100)); From c74689f26eaf3eff695854e4ad1964946a907d13 Mon Sep 17 00:00:00 2001 From: iscai-msft Date: Fri, 10 May 2024 13:48:00 -0400 Subject: [PATCH 07/12] add install of tcgc in packPackages --- packages/typespec-client-generator-core/e2e-tests.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js index d47b976f62..4ad31cc001 100644 --- a/packages/typespec-client-generator-core/e2e-tests.js +++ b/packages/typespec-client-generator-core/e2e-tests.js @@ -27,6 +27,7 @@ function cleanTcgcDirectory() { } function packPackages() { + run("pnpm", ["install"], { cwd: tcgcTestDir }); run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }); run("pnpm", ["-w", "pack:all"], { cwd: coreRepoRoot }); const azureOutputFolder = join(repoRoot, "/temp/artifacts"); From f94d26f837b52bafe1e22d5b6d53321a6639ebb6 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 10 May 2024 11:44:32 -0700 Subject: [PATCH 08/12] fix --- packages/typespec-client-generator-core/src/public-utils.ts | 3 +-- packages/typespec-client-generator-core/src/types.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/typespec-client-generator-core/src/public-utils.ts b/packages/typespec-client-generator-core/src/public-utils.ts index dc31fa009d..31b22e5cbd 100644 --- a/packages/typespec-client-generator-core/src/public-utils.ts +++ b/packages/typespec-client-generator-core/src/public-utils.ts @@ -15,7 +15,6 @@ import { getProjectedName, ignoreDiagnostics, isErrorModel, - isType, listServices, resolveEncodedName, } from "@typespec/compiler"; @@ -196,7 +195,7 @@ export function getLibraryName( type.templateMapper.args .filter( (arg): arg is Model | Enum => - isType(arg) && (arg.kind === "Model" || arg.kind === "Enum") && arg.name.length > 0 + "kind" in arg && (arg.kind === "Model" || arg.kind === "Enum") && arg.name.length > 0 ) .map((arg) => pascalCase(arg.name)) .join("") diff --git a/packages/typespec-client-generator-core/src/types.ts b/packages/typespec-client-generator-core/src/types.ts index 09cabdc7b5..3de24fdc41 100644 --- a/packages/typespec-client-generator-core/src/types.ts +++ b/packages/typespec-client-generator-core/src/types.ts @@ -28,7 +28,6 @@ import { ignoreDiagnostics, isErrorModel, isNeverType, - isType, } from "@typespec/compiler"; import { Authentication, @@ -1147,7 +1146,7 @@ function checkAndGetClientType( if (context.filterOutCoreModels && isAzureCoreModel(effectivePayloadType)) { if (effectivePayloadType.templateMapper && effectivePayloadType.name) { effectivePayloadType.templateMapper.args - .filter(isType) + .filter((arg): arg is Type => "kind" in arg) .filter((arg) => arg.kind === "Model" && arg.name) .forEach((arg) => { retval.push(...diagnostics.pipe(checkAndGetClientType(context, arg, operation))); From b77d0cdc7338b62717881338415cebf444cd5dde Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 10 May 2024 11:46:10 -0700 Subject: [PATCH 09/12] update this --- eng/pipelines/jobs/e2e-job.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/jobs/e2e-job.yml b/eng/pipelines/jobs/e2e-job.yml index 86a2592323..cafeb94bf8 100644 --- a/eng/pipelines/jobs/e2e-job.yml +++ b/eng/pipelines/jobs/e2e-job.yml @@ -24,4 +24,4 @@ jobs: displayName: Cadl Ranch e2e tests - script: pnpm test:e2e - displayName: UI Tests + displayName: E2E Tests From 174f556bbf5c4438dc037a805c666dcff45e3863 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 10 May 2024 11:58:04 -0700 Subject: [PATCH 10/12] Update add_e2e_test-2024-4-10-13-19-5.md --- .chronus/changes/add_e2e_test-2024-4-10-13-19-5.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md b/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md index 559ca5413e..f545abb605 100644 --- a/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md +++ b/.chronus/changes/add_e2e_test-2024-4-10-13-19-5.md @@ -1,7 +1,7 @@ --- -changeKind: internal +changeKind: fix packages: - "@azure-tools/typespec-client-generator-core" --- -add ci step to check against latest released typespec compiler \ No newline at end of file +Fix: Crash due to using api from next version of the compiler From 95835a64ab9660bd88ff10b3d0418905c168be98 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 10 May 2024 13:07:26 -0700 Subject: [PATCH 11/12] Better e2e tests --- .../e2e-tests.js | 94 ------------------- .../{ => e2e}/basic-latest/main.tsp | 1 - .../{ => e2e}/basic-latest/package.json | 0 .../e2e/check-latest.e2e.ts | 76 +++++++++++++++ .../package.json | 2 +- .../tsconfig.json | 2 +- .../vitest.config.e2e.ts | 17 ++++ 7 files changed, 95 insertions(+), 97 deletions(-) delete mode 100644 packages/typespec-client-generator-core/e2e-tests.js rename packages/typespec-client-generator-core/{ => e2e}/basic-latest/main.tsp (76%) rename packages/typespec-client-generator-core/{ => e2e}/basic-latest/package.json (100%) create mode 100644 packages/typespec-client-generator-core/e2e/check-latest.e2e.ts create mode 100644 packages/typespec-client-generator-core/vitest.config.e2e.ts diff --git a/packages/typespec-client-generator-core/e2e-tests.js b/packages/typespec-client-generator-core/e2e-tests.js deleted file mode 100644 index 4ad31cc001..0000000000 --- a/packages/typespec-client-generator-core/e2e-tests.js +++ /dev/null @@ -1,94 +0,0 @@ -/* eslint-disable no-console */ - -import { readdirSync, rmSync } from "fs"; -import { join } from "path"; -import { coreRepoRoot, repoRoot, run } from "../../eng/scripts/helpers.js"; - -const tcgcTestDir = join(repoRoot, "packages", "typespec-client-generator-core"); -const npxCmd = process.platform === "win32" ? "npx.cmd" : "npx"; - -function main() { - printInfo(); - cleanTcgcDirectory(); - const packages = packPackages(); - testBasicLatest(packages); -} -main(); - -function printInfo() { - console.log("-".repeat(100)); // - console.log("Npm Version: "); - run("npm", ["-v"]); - console.log("-".repeat(100)); -} - -function cleanTcgcDirectory() { - run("git", ["clean", "-xfd"], { cwd: tcgcTestDir }); -} - -function packPackages() { - run("pnpm", ["install"], { cwd: tcgcTestDir }); - run("pnpm", ["-w", "pack:all"], { cwd: repoRoot }); - run("pnpm", ["-w", "pack:all"], { cwd: coreRepoRoot }); - const azureOutputFolder = join(repoRoot, "/temp/artifacts"); - const coreOutputFolder = join(repoRoot, "/core/temp/artifacts"); - const files = readdirSync(azureOutputFolder).concat(readdirSync(coreOutputFolder)); - - console.log("Built packages:", files); - - function resolvePackage(start) { - const pkgName = files.find((x) => x.startsWith(start)); - if (pkgName === undefined) { - throw new Error(`Cannot resolve package starting with "${start}"`); - } - const outputFolder = start.startsWith("azure-tools") ? azureOutputFolder : coreOutputFolder; - return join(outputFolder, pkgName); - } - - return { - "@typespec/compiler": resolvePackage("typespec-compiler-"), - "@typespec/openapi": resolvePackage("typespec-openapi-"), - "@typespec/openapi3": resolvePackage("typespec-openapi3-"), - "@typespec/http": resolvePackage("typespec-http-"), - "@typespec/rest": resolvePackage("typespec-rest-"), - "@typespec/versioning": resolvePackage("typespec-versioning-"), - "@azure-tools/typespec-azure-core": resolvePackage("azure-tools-typespec-azure-core-"), - "@azure-tools/typespec-autorest": resolvePackage("azure-tools-typespec-autorest-"), - "@azure-tools/typespec-azure-resource-manager": resolvePackage( - "azure-tools-typespec-azure-resource-manager-" - ), - }; -} - -function runTypeSpec(compilerTgz, args, options) { - run(npxCmd, ["-y", "-p", compilerTgz, "tsp", ...args], { ...options }); -} - -function testBasicLatest(packages) { - const basicLatestDir = join(tcgcTestDir, "basic-latest"); - const outputDir = join(basicLatestDir, "tsp-output"); - console.log("Clearing basic-latest output"); - rmSync(outputDir, { recursive: true, force: true }); - console.log("Cleared basic-latest output"); - - console.log("Installing basic-latest dependencies"); - runTypeSpec(packages["@typespec/compiler"], ["install"], { cwd: basicLatestDir }); - console.log("Installed basic-latest dependencies"); - - console.log("Running tsp compile ."); - runTypeSpec(packages["@typespec/compiler"], ["compile", ".", "--emit", "@typespec/openapi3"], { - cwd: basicLatestDir, - }); - console.log("Completed tsp compile ."); - - expectOpenApiOutput(outputDir); -} - -function expectOpenApiOutput(outputDir) { - const expectedOutputFile = join(outputDir, "@typespec/openapi3/openapi.yaml"); - if (existsSync(expectedOutputFile)) { - console.log("Output created successfully."); - } else { - throw new Error(`Test failed to produce openapi output at "${expectedOutputFile}"`); - } -} diff --git a/packages/typespec-client-generator-core/basic-latest/main.tsp b/packages/typespec-client-generator-core/e2e/basic-latest/main.tsp similarity index 76% rename from packages/typespec-client-generator-core/basic-latest/main.tsp rename to packages/typespec-client-generator-core/e2e/basic-latest/main.tsp index a7488426c2..5a7a1c3e52 100644 --- a/packages/typespec-client-generator-core/basic-latest/main.tsp +++ b/packages/typespec-client-generator-core/e2e/basic-latest/main.tsp @@ -1,5 +1,4 @@ import "@typespec/rest"; -import "@typespec/openapi3"; import "@azure-tools/typespec-client-generator-core"; op ping(): void; diff --git a/packages/typespec-client-generator-core/basic-latest/package.json b/packages/typespec-client-generator-core/e2e/basic-latest/package.json similarity index 100% rename from packages/typespec-client-generator-core/basic-latest/package.json rename to packages/typespec-client-generator-core/e2e/basic-latest/package.json diff --git a/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts b/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts new file mode 100644 index 0000000000..8ab956ef40 --- /dev/null +++ b/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts @@ -0,0 +1,76 @@ +/* eslint-disable no-console */ + +import { findTestPackageRoot } from "@typespec/compiler/testing"; +import { SpawnOptions, spawn } from "child_process"; +import { cp, readdir, rm } from "fs/promises"; +import { join, resolve } from "path"; +import { beforeAll, it } from "vitest"; + +const packageRoot = await findTestPackageRoot(import.meta.url); +const tempDir = join(packageRoot, "temp/e2e"); + +let tgzFile: string; +beforeAll(async () => { + await rm(tempDir, { recursive: true, force: true }); + + await execAsync("pnpm", ["pack", "--pack-destination", tempDir]); + const files = await readdir(tempDir); + + const filename = files.find((x) => x.startsWith("azure-tools-typespec-client-generator-core-")); + if (filename === undefined) { + throw new Error( + `Cannot resolve package starting with "azure-tools-typespec-client-generator-core-"` + ); + } + tgzFile = join(tempDir, filename); +}); + +// Make sure it works with the latest version of dependencies and not just the local build. +it("works with latest version of packages", async () => { + const dir = await setupScenario("basic-latest"); + await execAsync("npm", ["install", tgzFile], { cwd: dir }); + await execAsync("npx", ["tsp", "compile", ".", tgzFile], { cwd: dir }); +}); + +async function setupScenario(name: string): Promise { + const target = resolve(tempDir, name); + await cp(resolve(packageRoot, "e2e", name), target, { + recursive: true, + }); + return target; +} + +async function execAsync( + command: string, + args: string[] = [], + options: SpawnOptions = {} +): Promise<{ exitCode: number; stdio: string; stdout: string; stderr: string; proc: any }> { + const child = spawn(command, args, options); + + return new Promise((resolve, reject) => { + child.on("error", (error) => { + reject(error); + }); + const stdio: Buffer[] = []; + const stdout: Buffer[] = []; + const stderr: Buffer[] = []; + child.stdout?.on("data", (data) => { + stdout.push(data); + stdio.push(data); + }); + child.stderr?.on("data", (data) => { + stderr.push(data); + stdio.push(data); + }); + + child.on("exit", (exitCode) => { + resolve({ + exitCode: exitCode ?? -1, + stdio: Buffer.concat(stdio).toString(), + stdout: Buffer.concat(stdout).toString(), + stderr: Buffer.concat(stderr).toString(), + proc: child, + }); + }); + }); +} diff --git a/packages/typespec-client-generator-core/package.json b/packages/typespec-client-generator-core/package.json index 0eb04fb541..aeb2aacb86 100644 --- a/packages/typespec-client-generator-core/package.json +++ b/packages/typespec-client-generator-core/package.json @@ -43,7 +43,7 @@ "test:watch": "vitest -w", "test:ui": "vitest --ui", "test:ci": "vitest run --coverage --reporter=junit --reporter=default", - "test:e2e": "node ./e2e-tests.js", + "test:e2e": "vitest run --config ./vitest.config.e2e.ts", "lint": "eslint . --max-warnings=0", "lint:fix": "eslint . --fix ", "regen-docs": "tspd doc . --enable-experimental --output-dir ../../docs/libraries/typespec-client-generator-core/reference" diff --git a/packages/typespec-client-generator-core/tsconfig.json b/packages/typespec-client-generator-core/tsconfig.json index 691e8fb04d..1aef16e920 100644 --- a/packages/typespec-client-generator-core/tsconfig.json +++ b/packages/typespec-client-generator-core/tsconfig.json @@ -10,5 +10,5 @@ "rootDir": ".", "tsBuildInfoFile": "temp/tsconfig.tsbuildinfo" }, - "include": ["src/**/*.ts", "test/**/*.ts"] + "include": ["src/**/*.ts", "test/**/*.ts", "e2e/**/*.ts"] } diff --git a/packages/typespec-client-generator-core/vitest.config.e2e.ts b/packages/typespec-client-generator-core/vitest.config.e2e.ts new file mode 100644 index 0000000000..1fa434e6aa --- /dev/null +++ b/packages/typespec-client-generator-core/vitest.config.e2e.ts @@ -0,0 +1,17 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "node", + testTimeout: 60_000, + isolate: false, + coverage: { + reporter: ["cobertura", "json", "text"], + }, + outputFile: { + junit: "./test-results.xml", + }, + + include: ["e2e/**/*.e2e.ts"], + }, +}); From d17367aaa47ab84204f4e7152df0a5bd1f6dec5d Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Fri, 10 May 2024 13:16:37 -0700 Subject: [PATCH 12/12] Fix --- .../e2e/check-latest.e2e.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts b/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts index 8ab956ef40..ed4baee80f 100644 --- a/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts +++ b/packages/typespec-client-generator-core/e2e/check-latest.e2e.ts @@ -1,5 +1,3 @@ -/* eslint-disable no-console */ - import { findTestPackageRoot } from "@typespec/compiler/testing"; import { SpawnOptions, spawn } from "child_process"; import { cp, readdir, rm } from "fs/promises"; @@ -13,7 +11,7 @@ let tgzFile: string; beforeAll(async () => { await rm(tempDir, { recursive: true, force: true }); - await execAsync("pnpm", ["pack", "--pack-destination", tempDir]); + await execSuccessAsync("pnpm", ["pack", "--pack-destination", tempDir]); const files = await readdir(tempDir); const filename = files.find((x) => x.startsWith("azure-tools-typespec-client-generator-core-")); @@ -28,8 +26,8 @@ beforeAll(async () => { // Make sure it works with the latest version of dependencies and not just the local build. it("works with latest version of packages", async () => { const dir = await setupScenario("basic-latest"); - await execAsync("npm", ["install", tgzFile], { cwd: dir }); - await execAsync("npx", ["tsp", "compile", ".", tgzFile], { cwd: dir }); + await execSuccessAsync("npm", ["install", tgzFile], { cwd: dir }); + await execSuccessAsync("npx", ["tsp", "compile", "."], { cwd: dir }); }); async function setupScenario(name: string): Promise { @@ -40,6 +38,16 @@ async function setupScenario(name: string): Promise { return target; } +async function execSuccessAsync(command: string, args: string[] = [], options: SpawnOptions = {}) { + const result = await execAsync(command, args, options); + if (result.exitCode !== 0) { + throw new Error( + `Command '${command} ${args.join(" ")}' failed with exit code ${result.exitCode}\n` + + result.stdio + ); + } + return result; +} async function execAsync( command: string, args: string[] = [],