// Copyright 2024-2024, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. import { randomInt } from "crypto"; import execa from "execa"; import * as fs from "fs/promises"; import * as path from "path"; import * as process from "process"; import * as tmp from "tmp"; import { pack } from "./pack"; // Write a package.json that installs the local pulumi package and ensures we // have the right typescript version. async function writePackageJSON( dir: string, pulumiPackagePath: string, typescriptVersion: string, nodeTypesVersion: string, ) { const packageJSON = { name: "closure-tests", version: "1.0.0", license: "Apache-2.0", dependencies: { "@pulumi/pulumi": pulumiPackagePath, "@types/mocha": "^9.0.0", "@types/node": nodeTypesVersion, "@types/semver": "^7.5.6", mocha: "^9.0.0", "mocha-suppress-logs": "^0.5.1", mockpackage: "file:mockpackage-src", semver: "^7.5.4", "ts-node": "^7.0.1", typescript: typescriptVersion, }, resolutions: { typescript: typescriptVersion, }, }; await fs.writeFile(path.join(dir, "package.json"), JSON.stringify(packageJSON, undefined, 4)); } async function copyDir(src: string, dest: string) { const entries: any[] = await fs.readdir( src, { recursive: true, withFileTypes: true } as any /* recursive option is new in node 18 */, ); for (const entry of entries) { const srcPath = path.join(entry.path, entry.name); const destPath = srcPath.replace(src, dest); const destDir = path.dirname(destPath); if (entry.isFile()) { await fs.mkdir(destDir, { recursive: true }); await fs.copyFile(srcPath, destPath); } } } async function run(typescriptVersion: string, nodeTypesVersion: string) { const tmpDir = tmp.dirSync({ prefix: "closure-test-", unsafeCleanup: true }); const sdkRoot = path.join(__dirname, "..", "..", ".."); const sdkRootBin = path.join(sdkRoot, "bin"); // Add a random suffix to the package name to avoid any issues with yarn caching the tgz. const packageName = `pulumi-${randomInt(10000, 99999)}.tgz`; const pulumiPackagePath = path.join(tmpDir.name, packageName); await pack(sdkRootBin, pulumiPackagePath); await writePackageJSON(tmpDir.name, pulumiPackagePath, typescriptVersion, nodeTypesVersion); await copyDir(path.join(sdkRoot, "tests", "runtime", "testdata", "closure-tests"), tmpDir.name); await execa("yarn", ["install"], { cwd: tmpDir.name }); await execa("yarn", ["tsc"], { cwd: tmpDir.name }); await execa("yarn", ["mocha", "--timeout", "30000", "test.js"], { cwd: tmpDir.name, stdio: "inherit", }); tmpDir.removeCallback(); } async function main() { for (const [ts, typesNode] of [ ["~3.8.3", "^17"], // Latest 3.8.x, this is the default version. ["<4.8.0", "^20"], // Before 4.8.0, the typescript API we use has some breaking changes in 4.8.0. ["^4.9.5", "^20"], // Latest 4.x.x ["<5.2.0", "^20"], // Awaiter changed slightly in 5.2.0 https://github.com/microsoft/TypeScript/pull/56296 ["^5.2.0", "^20"], // Latest 5.x.x ]) { await run(ts, typesNode); } } main().catch((error) => { console.error(error); process.exit(1); });