pulumi/sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts

254 lines
11 KiB
TypeScript
Raw Normal View History

Reorganize closure tests to prepare for multiple typescript versions (#15753) # Description In preparation of https://github.com/pulumi/pulumi/issues/15735 we make the closure tests proper integration tests so that we can run them with different typescript versions. Move each test to its own folder instead of one large file. This PR only changes tests, and does not touch any of the function serialisation code. Some snapshots had to be updated for indentation changes. Hidden after all the test cases is the test script [sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts](https://github.com/pulumi/pulumi/blob/dfcc953c08051555ba1fa363b0694d195cfcc27a/sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts) Verified that tests run in CI https://github.com/pulumi/pulumi/actions/runs/8389170587/job/22975068167?pr=15753 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-25 13:19:17 +00:00
// 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 * as assert from "assert";
Make function serialization work on typescript 4 and 5 (#15761) # Description Builds on top of https://github.com/pulumi/pulumi/pull/15753 Fixes https://github.com/pulumi/pulumi/issues/15735 There are a couple breaking changes in the typescript API that we use in `sdk/nodejs/runtime/closure/rewriteSuper.ts`. This PR adds a shim that is used to bridge the differences and versions the snapshots where needed. This does not make typescript a peer dependency yet. Instead the tests force a specific version to be used via [yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/). ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-27 10:03:57 +00:00
import execa from "execa";
Reorganize closure tests to prepare for multiple typescript versions (#15753) # Description In preparation of https://github.com/pulumi/pulumi/issues/15735 we make the closure tests proper integration tests so that we can run them with different typescript versions. Move each test to its own folder instead of one large file. This PR only changes tests, and does not touch any of the function serialisation code. Some snapshots had to be updated for indentation changes. Hidden after all the test cases is the test script [sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts](https://github.com/pulumi/pulumi/blob/dfcc953c08051555ba1fa363b0694d195cfcc27a/sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts) Verified that tests run in CI https://github.com/pulumi/pulumi/actions/runs/8389170587/job/22975068167?pr=15753 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-25 13:19:17 +00:00
import * as fs from "fs/promises";
import { readdirSync } from "fs";
import * as path from "path";
import * as semver from "semver";
import * as typescript from "typescript";
// @ts-ignore: The test installs @pulumi/pulumi
import { runtime } from "@pulumi/pulumi";
// @ts-ignore: The test installs @pulumi/pulumi
import * as pkg from "@pulumi/pulumi/runtime/closure/package";
Reorganize closure tests to prepare for multiple typescript versions (#15753) # Description In preparation of https://github.com/pulumi/pulumi/issues/15735 we make the closure tests proper integration tests so that we can run them with different typescript versions. Move each test to its own folder instead of one large file. This PR only changes tests, and does not touch any of the function serialisation code. Some snapshots had to be updated for indentation changes. Hidden after all the test cases is the test script [sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts](https://github.com/pulumi/pulumi/blob/dfcc953c08051555ba1fa363b0694d195cfcc27a/sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts) Verified that tests run in CI https://github.com/pulumi/pulumi/actions/runs/8389170587/job/22975068167?pr=15753 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-25 13:19:17 +00:00
const platformIndependentEOL = /\r\n|\r|\n/g;
// Load the snapshot with a version range that satisfies the typescript version.
async function getSnapshot(testCase: string, typescriptVersion: string): Promise<string> {
const files = await fs.readdir(`./cases/${testCase}`);
for (const file of files) {
if (file.startsWith("snapshot.") && file.endsWith(".txt")) {
const range = file.slice("snapshot.".length, -".txt".length);
if (range) {
if (semver.satisfies(typescriptVersion, range)) {
return fs.readFile(path.join("cases", testCase, `snapshot.${range}.txt`), "utf-8");
}
}
}
}
return fs.readFile(path.join("cases", testCase, "snapshot.txt"), "utf-8");
}
Make function serialization work on typescript 4 and 5 (#15761) # Description Builds on top of https://github.com/pulumi/pulumi/pull/15753 Fixes https://github.com/pulumi/pulumi/issues/15735 There are a couple breaking changes in the typescript API that we use in `sdk/nodejs/runtime/closure/rewriteSuper.ts`. This PR adds a shim that is used to bridge the differences and versions the snapshots where needed. This does not make typescript a peer dependency yet. Instead the tests force a specific version to be used via [yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/). ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-27 10:03:57 +00:00
// This test validates that the typescript version used by the closure tests
// is the same as the one used by the pulumi package and that we are testing
// what we think we are testing ...
it(`resolve to the correct typescript version within the pulumi package`,
async function () {
const { stdout } = await execa("npm", ["ls", "typescript", "--json"], { cwd: __dirname, reject: false });
const deps = JSON.parse(stdout);
const version = deps.dependencies["@pulumi/pulumi"].dependencies.typescript.version;
assert.strictEqual(version, typescript.version);
});
Reorganize closure tests to prepare for multiple typescript versions (#15753) # Description In preparation of https://github.com/pulumi/pulumi/issues/15735 we make the closure tests proper integration tests so that we can run them with different typescript versions. Move each test to its own folder instead of one large file. This PR only changes tests, and does not touch any of the function serialisation code. Some snapshots had to be updated for indentation changes. Hidden after all the test cases is the test script [sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts](https://github.com/pulumi/pulumi/blob/dfcc953c08051555ba1fa363b0694d195cfcc27a/sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts) Verified that tests run in CI https://github.com/pulumi/pulumi/actions/runs/8389170587/job/22975068167?pr=15753 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-25 13:19:17 +00:00
describe(`closure tests (TypeScript ${typescript.version})`, function () {
const cases = readdirSync("cases"); // describe does not support async functions
for (const testCase of cases) {
const { func, isFactoryFunction, error: expectedError, description, allowSecrets, after } = require(`./cases/${testCase}`);
const nodeMajor = parseInt(process.version.split(".")[0].slice(1));
if (description === "Use webcrypto via global.crypto" && nodeMajor < 19) {
// This test uses global.crypto, which is only available in Node 19 and later.
continue;
}
it(`${description} (TypeScript ${typescript.version})`, async () => {
if (expectedError) {
await assert.rejects(async () => {
await runtime.serializeFunction(func, {
allowSecrets: allowSecrets ?? false,
isFactoryFunction: isFactoryFunction ?? false,
});
}, err => {
Make function serialization work on typescript 4 and 5 (#15761) # Description Builds on top of https://github.com/pulumi/pulumi/pull/15753 Fixes https://github.com/pulumi/pulumi/issues/15735 There are a couple breaking changes in the typescript API that we use in `sdk/nodejs/runtime/closure/rewriteSuper.ts`. This PR adds a shim that is used to bridge the differences and versions the snapshots where needed. This does not make typescript a peer dependency yet. Instead the tests force a specific version to be used via [yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/). ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-27 10:03:57 +00:00
const actual = anonymizeFunctionNames((<Error>err).message);
assert.strictEqual(actual, expectedError);
Reorganize closure tests to prepare for multiple typescript versions (#15753) # Description In preparation of https://github.com/pulumi/pulumi/issues/15735 we make the closure tests proper integration tests so that we can run them with different typescript versions. Move each test to its own folder instead of one large file. This PR only changes tests, and does not touch any of the function serialisation code. Some snapshots had to be updated for indentation changes. Hidden after all the test cases is the test script [sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts](https://github.com/pulumi/pulumi/blob/dfcc953c08051555ba1fa363b0694d195cfcc27a/sdk/nodejs/tests/runtime/testdata/closure-tests/test.ts) Verified that tests run in CI https://github.com/pulumi/pulumi/actions/runs/8389170587/job/22975068167?pr=15753 ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-25 13:19:17 +00:00
return true;
});
} else {
const sf = await runtime.serializeFunction(func, {
allowSecrets: allowSecrets ?? false,
isFactoryFunction: isFactoryFunction ?? false,
});
if (after) {
after();
}
let snapshot = await getSnapshot(testCase, typescript.version);
// Replace all new lines with \n to make the comparison platform independent.
snapshot = snapshot.replace(platformIndependentEOL, "\n")
const actual = sf.text.replace(platformIndependentEOL, "\n")
assert.strictEqual(actual, snapshot);
}
});
}
});
Make function serialization work on typescript 4 and 5 (#15761) # Description Builds on top of https://github.com/pulumi/pulumi/pull/15753 Fixes https://github.com/pulumi/pulumi/issues/15735 There are a couple breaking changes in the typescript API that we use in `sdk/nodejs/runtime/closure/rewriteSuper.ts`. This PR adds a shim that is used to bridge the differences and versions the snapshots where needed. This does not make typescript a peer dependency yet. Instead the tests force a specific version to be used via [yarn resolutions](https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/). ## Checklist - [x] I have run `make tidy` to update any new dependencies - [x] I have run `make lint` to verify my code passes the lint check - [x] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [x] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-03-27 10:03:57 +00:00
function anonymizeFunctionNames(text: string): string {
return text.replace(/function '.+'/g, "function '<anonymous>'");
}
describe("mock package", () => {
describe("module", () => {
it("remaps exports correctly for mockpackage", () => {
assert.strictEqual(pkg.getModuleFromPath("mockpackage/lib/index.js"), "mockpackage");
});
it("should return undefined on unexported members", () => {
assert.throws(() => pkg.getModuleFromPath("mockpackage/lib/external.js"));
});
});
describe("disregard null targets", () => {
// ./node_modules/es-module-package/package.json
const packagedef = {
name: "es-module-package",
exports: {
"./features/private-internal-b/*": null,
"./features/*": "./src/features/*.js",
"./features/private-internal/*": null,
},
};
it(`handles wildcard paths`, () => {
assert.strictEqual(
pkg.getModuleFromPath("es-module-package/src/features/private-inter.js", packagedef),
"es-module-package/features/private-inter",
);
assert.strictEqual(
pkg.getModuleFromPath("es-module-package/src/features/x.js", packagedef),
"es-module-package/features/x",
);
assert.strictEqual(
pkg.getModuleFromPath("es-module-package/src/features/y/z/foo/bar/baz.js", packagedef),
"es-module-package/features/y/z/foo/bar/baz",
);
});
it(`handles whitelisting blacklisted directories`, () => {
assert.strictEqual(
pkg.getModuleFromPath("es-module-package/features/internal/public/index.js", {
name: "es-module-package",
exports: {
"./features/internal/*": null,
".": "./features/internal/public/index.js",
},
}),
"es-module-package",
);
});
});
describe("basic package exports", () => {
// https://nodejs.org/api/packages.html#package-entry-points
const packagedef = {
name: "my-mod",
exports: {
".": "./lib/index.js",
"./lib": "./lib/index.js",
"./lib/index": "./lib/index.js",
"./lib/index.js": "./lib/index.js",
"./feature": "./feature/index.js",
"./feature/index.js": "./feature/index.js",
"./package.json": "./package.json",
},
};
it("handles multiple aliases 1", () => {
assert.strictEqual(pkg.getModuleFromPath("my-mod/lib/index.js", packagedef), "my-mod/lib/index.js");
});
it("handles multiple aliases 2", () => {
assert.strictEqual(pkg.getModuleFromPath("my-mod/feature/index.js", packagedef), "my-mod/feature/index.js");
});
it("returns with no modification", () => {
assert.strictEqual(pkg.getModuleFromPath("my-mod/package.json", packagedef), "my-mod/package.json");
});
});
describe("wildcard package exports", () => {
const packagedef = {
name: "my-mod",
exports: {
".": "./lib/index.js",
"./lib": "./lib/index.js",
"./lib/*": "./lib/*.js",
"./feature": "./feature/index.js",
"./feature/*": "./feature/*.js",
"./package.json": "./package.json",
},
};
it("wildcard module", () => {
assert.strictEqual(pkg.getModuleFromPath("my-mod/lib/foobar.js", packagedef), "my-mod/lib/foobar");
assert.strictEqual(pkg.getModuleFromPath("my-mod/lib/foo.js.js", packagedef), "my-mod/lib/foo.js"); // check
assert.strictEqual(pkg.getModuleFromPath("my-mod/feature/foobar.js", packagedef), "my-mod/feature/foobar");
});
it("manual regression tests", () => {
assert.strictEqual(
pkg.getModuleFromPath("my-mod/internal/public/index.js.js", {
name: "my-mod",
exports: {
".": "./internal/public/index.js",
"./public/*": "./internal/public/*.js",
},
}),
"my-mod/public/index.js",
);
assert.strictEqual(
pkg.getModuleFromPath("my-mod/internal/public/index.js", {
name: "my-mod",
exports: {
".": "./internal/public/index.js",
"./public/*": "./internal/public/*",
},
}),
"my-mod",
);
});
});
describe("conditional import/require package exports", () => {
const packagedef = {
// package.json
name: "that-mod",
exports: {
".": "./main.js",
"./feature": {
node: "./feature-node.js",
default: "./feature.js",
},
},
type: "module",
};
it("remaps conditional node/default nested packages", () => {
assert.strictEqual(pkg.getModuleFromPath("that-mod/main.js", packagedef), "that-mod");
assert.strictEqual(pkg.getModuleFromPath("that-mod/feature-node.js", packagedef), "that-mod/feature");
assert.strictEqual(pkg.getModuleFromPath("that-mod/feature.js", packagedef), "that-mod/feature");
});
});
describe("conditional import/require package exports", () => {
const packagedef = {
// package.json
name: "this-mod",
main: "./main-require.cjs",
exports: {
import: "./main-module.js",
require: "./main-require.cjs",
},
type: "module",
};
it("remaps to main pkg", () => {
assert.throws(() => pkg.getModuleFromPath("this-mod/main-module.js", packagedef));
assert.strictEqual(pkg.getModuleFromPath("this-mod/main-require.cjs", packagedef), "this-mod");
});
});
describe("error cases", () => {
it("returns the original module if package.json not found", () => {
assert.strictEqual(pkg.getModuleFromPath("this-mod/main-require.cjs"), "this-mod/main-require.cjs");
});
});
Serialize function values obtained from Function.bind (#15887) <!--- Thanks so much for your contribution! If this is your first time contributing, please ensure that you have read the [CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md) documentation. --> # Description When encountering a function obtained via `Function.bind` we previously failed to serialise the function because we could not get the function text. This PR uses the v8 debugger API to grab the internal `[[TargetFunction]]` property to obtain the original function and re-bind it. This does currently not handle successive binds like ```(function f() { ... }).bind("a").bind("b")``` Ref https://github.com/pulumi/pulumi/issues/5294 ## Checklist - [ ] I have run `make tidy` to update any new dependencies - [ ] I have run `make lint` to verify my code passes the lint check - [ ] I have formatted my code using `gofumpt` <!--- Please provide details if the checkbox below is to be left unchecked. --> - [ ] I have added tests that prove my fix is effective or that my feature works <!--- User-facing changes require a CHANGELOG entry. --> - [x] I have run `make changelog` and committed the `changelog/pending/<file>` documenting my change <!-- If the change(s) in this PR is a modification of an existing call to the Pulumi Cloud, then the service should honor older versions of the CLI where this change would not exist. You must then bump the API version in /pkg/backend/httpstate/client/api.go, as well as add it to the service. --> - [ ] Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version <!-- @Pulumi employees: If yes, you must submit corresponding changes in the service repo. -->
2024-04-10 11:17:53 +00:00
});