pulumi/sdk/nodejs/tests/runtime/closure.spec.ts
2018-08-27 14:25:37 -07:00

5319 lines
124 KiB
TypeScript

// Copyright 2016-2018, 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.
// tslint:disable
import * as assert from "assert";
import { EOL } from "os";
import { runtime } from "../../index";
import * as pulumi from "../../index";
import { output } from "../../resource";
import { assertAsyncThrows, asyncTest } from "../util";
import * as typescript from "typescript";
interface ClosureCase {
pre?: () => void; // an optional function to run before this case.
title: string; // a title banner for the test case.
func?: Function; // the function whose body and closure to serialize.
factoryFunc?: Function; // the function whose body and closure to serialize (as a factory).
expectText?: string; // optionally also validate the serialization to JavaScript text.
expectPackages?: Set<string>; // optionally also validate the packages required by the JavaScript text.
error?: string; // error message we expect to be thrown if we are unable to serialize closure.
afters?: ClosureCase[]; // an optional list of test cases to run afterwards.
}
export const exportedValue = 42;
// This group of tests ensure that we serialize closures properly.
describe("closure", () => {
const cases: ClosureCase[] = [];
cases.push({
title: "Empty function closure",
func: function () { },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Empty named function",
func: function f() { },
expectText: `exports.handler = __f;
function __f() {
return (function() {
with({ f: __f }) {
return function /*f*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Named function with self-reference",
func: function f() { f(); },
expectText: `exports.handler = __f;
function __f() {
return (function() {
with({ f: __f }) {
return function /*f*/() { f(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Function closure with this capture",
func: function () { console.log(this); },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { console.log(this); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Function closure with this and arguments capture",
func: function () { console.log(this + arguments); },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { console.log(this + arguments); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Empty arrow closure",
func: () => { },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return () => { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Arrow closure with this capture",
func: () => { console.log(this); },
expectText: undefined,
error:
`Error serializing function 'func': closure.spec.js(0,0)
function 'func': closure.spec.js(0,0): which could not be serialized because
arrow function captured 'this'. Assign 'this' to another name outside function and capture that.
Function code:
() => { console.log(this); }
`,
});
const awaiterCode =
`
function __f1() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`;
cases.push({
title: "Async lambda that does not capture this",
func: async () => { },
expectText: `exports.handler = __f0;
${awaiterCode}
function __f0() {
return (function() {
with({ __awaiter: __f1 }) {
return () => __awaiter(this, void 0, void 0, function* () { });
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Async lambda that does capture this",
func: async () => { console.log(this); },
expectText: undefined,
error: `Error serializing function 'func': closure.spec.js(0,0)
function 'func': closure.spec.js(0,0): which could not be serialized because
arrow function captured 'this'. Assign 'this' to another name outside function and capture that.
Function code:
() => __awaiter(this, void 0, void 0, function* () { console.log(this); })
`,
});
cases.push({
title: "Async function that does not capture this",
func: async function() { },
expectText: `exports.handler = __f0;
${awaiterCode}
function __f0() {
return (function() {
with({ __awaiter: __f1 }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Async function that does capture this",
func: async function () { console.log(this); },
expectText: `exports.handler = __f0;
${awaiterCode}
function __f0() {
return (function() {
with({ __awaiter: __f1 }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { console.log(this); });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Arrow closure with this and arguments capture",
func: (function() { return () => { console.log(this + arguments); } }).apply(this, [0, 1]),
expectText: undefined,
error: `Error serializing function '<anonymous>': closure.spec.js(0,0)
function '<anonymous>': closure.spec.js(0,0): which could not be serialized because
arrow function captured 'this'. Assign 'this' to another name outside function and capture that.
Function code:
() => { console.log(this + arguments); }
`,
});
cases.push({
title: "Arrow closure with this capture inside function closure",
func: function () { () => { console.log(this); } },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { () => { console.log(this); }; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Arrow closure with this and arguments capture inside function closure",
func: function () { () => { console.log(this + arguments); } },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { () => { console.log(this + arguments); }; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
{
class Task {
run: any;
constructor() {
this.run = async function() { };
}
}
const task = new Task();
cases.push({
title: "Invocation of async function that does not capture this #1",
func: async function() { await task.run(); },
expectText: `exports.handler = __f0;
var __task = {run: __f2};
function __f1() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ __awaiter: __f1 }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ __awaiter: __f1, task: __task }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { yield task.run(); });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class Task {
run: any;
constructor() {
this.run = async function() { console.log(this); };
}
}
const task = new Task();
cases.push({
title: "Invocation of async function that does capture this #1",
func: async function() { await task.run(); },
expectText: `exports.handler = __f0;
var __task_proto = {};
Object.defineProperty(__task_proto, "constructor", { configurable: true, writable: true, value: __f2 });
var __task = Object.create(__task_proto);
__task.run = __f3;
function __f1() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ __awaiter: __f1 }) {
return function /*constructor*/() {
this.run = function () {
return __awaiter(this, void 0, void 0, function* () { console.log(this); });
};
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ __awaiter: __f1 }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { console.log(this); });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ __awaiter: __f1, task: __task }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { yield task.run(); });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class Task {
run: any;
constructor() {
this.run = async () => { };
}
}
const task = new Task();
cases.push({
title: "Invocation of async lambda that does not capture this #1",
func: async function() { await task.run(); },
expectText: `exports.handler = __f0;
var __task = {run: __f2};
function __f1() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ __awaiter: __f1 }) {
return () => __awaiter(this, void 0, void 0, function* () { });
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ __awaiter: __f1, task: __task }) {
return function () {
return __awaiter(this, void 0, void 0, function* () { yield task.run(); });
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class Task {
run: any;
constructor() {
this.run = async () => { console.log(this); };
}
}
const task = new Task();
cases.push({
title: "Invocation of async lambda that capture this #1",
func: async function() { await task.run(); },
expectText: undefined,
error: `Error serializing function 'func': closure.spec.js(0,0)
function 'func': closure.spec.js(0,0): captured
variable 'task' which indirectly referenced
function '<anonymous>': closure.spec.js(0,0): which could not be serialized because
arrow function captured 'this'. Assign 'this' to another name outside function and capture that.
Function code:
() => __awaiter(this, void 0, void 0, function* () { console.log(this); })
`,
});
}
cases.push({
title: "Empty function closure w/ args",
func: function (x: any, y: any, z: any) { },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function (x, y, z) { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
cases.push({
title: "Empty arrow closure w/ args",
func: (x: any, y: any, z: any) => { },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return (x, y, z) => { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
// Serialize captures.
cases.push({
title: "Doesn't serialize global captures",
func: () => { console.log("Just a global object reference"); },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return () => { console.log("Just a global object reference"); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
{
const wcap = "foo";
const xcap = 97;
const ycap = [ true, -1, "yup" ];
const zcap = {
a: "a",
b: false,
c: [ 0 ],
};
cases.push({
title: "Serializes basic captures",
func: () => { console.log(wcap + `${xcap}` + ycap.length + eval(zcap.a + zcap.b + zcap.c)); },
expectText: `exports.handler = __f0;
var __ycap = [true, -1, "yup"];
var __zcap = {};
__zcap.a = "a";
__zcap.b = false;
var __zcap_c = [0];
__zcap.c = __zcap_c;
function __f0() {
return (function() {
with({ wcap: "foo", xcap: 97, ycap: __ycap, zcap: __zcap }) {
return () => { console.log(wcap + \`\${xcap}\` + ycap.length + eval(zcap.a + zcap.b + zcap.c)); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
let nocap1 = 1, nocap2 = 2, nocap3 = 3, nocap4 = 4, nocap5 = 5, nocap6 = 6, nocap7 = 7;
let nocap8 = 8, nocap9 = 9, nocap10 = 10;
let cap1 = 100, cap2 = 200, cap3 = 300, cap4 = 400, cap5 = 500, cap6 = 600, cap7 = 700;
let cap8 = 800;
const functext = `(nocap1, nocap2) => {
let zz = nocap1 + nocap2; // not a capture: args
let yy = nocap3; // not a capture: var later on
if (zz) {
zz += cap1; // true capture
let cap1 = 9; // because let is properly scoped
zz += nocap4; // not a capture
var nocap4 = 7; // because var is function scoped
zz += cap2; // true capture
const cap2 = 33;
var nocap3 = 8; // block the above capture
}
let f1 = (nocap5) => {
yy += nocap5; // not a capture: args
cap3++; // capture
};
let f2 = (function (nocap6) {
zz += nocap6; // not a capture: args
if (cap4) { // capture
yy = 0;
}
});
let www = nocap7(); // not a capture; it is defined below
if (true) {
function nocap7() {
}
}
let [{t: [nocap8]},,nocap9 = "hello",...nocap10] = [{t: [true]},null,undefined,1,2];
let vvv = [nocap8, nocap9, nocap10]; // not a capture; declarations from destructuring
let aaa = { // captures in property and method declarations
[cap5]: cap6,
[cap7]() {
cap8
}
}
}`;
cases.push({
title: "Doesn't serialize non-free variables (but retains frees)",
func: eval(functext),
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ cap1: 100, cap2: 200, cap3: 300, cap4: 400, cap5: 500, cap6: 600, cap7: 700, cap8: 800 }) {
return (nocap1, nocap2) => {
let zz = nocap1 + nocap2; // not a capture: args
let yy = nocap3; // not a capture: var later on
if (zz) {
zz += cap1; // true capture
let cap1 = 9; // because let is properly scoped
zz += nocap4; // not a capture
var nocap4 = 7; // because var is function scoped
zz += cap2; // true capture
const cap2 = 33;
var nocap3 = 8; // block the above capture
}
let f1 = (nocap5) => {
yy += nocap5; // not a capture: args
cap3++; // capture
};
let f2 = (function (nocap6) {
zz += nocap6; // not a capture: args
if (cap4) { // capture
yy = 0;
}
});
let www = nocap7(); // not a capture; it is defined below
if (true) {
function nocap7() {
}
}
let [{t: [nocap8]},,nocap9 = "hello",...nocap10] = [{t: [true]},null,undefined,1,2];
let vvv = [nocap8, nocap9, nocap10]; // not a capture; declarations from destructuring
let aaa = { // captures in property and method declarations
[cap5]: cap6,
[cap7]() {
cap8
}
}
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
let nocap1 = 1;
let cap1 = 100;
cases.push({
title: "Complex capturing cases #1",
func: () => {
// cap1 is captured here.
// nocap1 introduces a new variable that shadows the outer one.
let [nocap1 = cap1] = [];
console.log(nocap1);
},
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ cap1: 100 }) {
return () => {
// cap1 is captured here.
// nocap1 introduces a new variable that shadows the outer one.
let [nocap1 = cap1] = [];
console.log(nocap1);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
let nocap1 = 1;
let cap1 = 100;
cases.push({
title: "Complex capturing cases #2",
func: () => {
// cap1 is captured here.
// nocap1 introduces a new variable that shadows the outer one.
let {nocap1 = cap1} = {};
console.log(nocap1);
},
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ cap1: 100 }) {
return () => {
// cap1 is captured here.
// nocap1 introduces a new variable that shadows the outer one.
let { nocap1 = cap1 } = {};
console.log(nocap1);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
let nocap1 = 1;
let cap1 = 100;
cases.push({
title: "Complex capturing cases #3",
func: () => {
// cap1 is captured here.
// nocap1 introduces a new variable that shadows the outer one.
let {x: nocap1 = cap1} = {};
console.log(nocap1);
},
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ cap1: 100 }) {
return () => {
// cap1 is captured here.
// nocap1 introduces a new variable that shadows the outer one.
let { x: nocap1 = cap1 } = {};
console.log(nocap1);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
cases.push({
title: "Don't capture built-ins",
func: () => { let x: any = eval("undefined + null + NaN + Infinity + __filename"); require("os"); },
expectPackages: new Set(["os"]),
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return () => { let x = eval("undefined + null + NaN + Infinity + __filename"); require("os"); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
{
const os = require("os");
cases.push({
title: "Capture built in module by ref",
func: () => os,
expectPackages: new Set([]),
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ os: require("os") }) {
return () => os;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const os = require("os");
cases.push({
title: "Wrapped lambda function",
func: (a: any,
b: any,
c: any) => {
const v =
os;
return { v };
},
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ os: require("os") }) {
return (a, b, c) => {
const v = os;
return { v };
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const os = require("os");
function wrap(handler: Function) {
return () => handler;
}
const func = wrap(() => os);
cases.push({
title: "Capture module through indirect function references",
func: func,
expectText: `exports.handler = __f0;
function __f1() {
return (function() {
with({ os: require("os") }) {
return () => os;
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ handler: __f1 }) {
return () => handler;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const util = require("../util");
cases.push({
title: "Capture user-defined module by value",
func: () => util,
expectText: `exports.handler = __f0;
var __util = {};
Object.defineProperty(__util, "__esModule", { value: true });
__util.asyncTest = __asyncTest;
__util.assertAsyncThrows = __assertAsyncThrows;
function __f1() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __asyncTest() {
return (function() {
with({ __awaiter: __f1, asyncTest: __asyncTest }) {
return function /*asyncTest*/(test) {
return (done) => {
const go = () => __awaiter(this, void 0, void 0, function* () {
let caught;
try {
yield test();
}
catch (err) {
caught = err;
}
finally {
done(caught);
}
});
go();
};
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __assertAsyncThrows() {
return (function() {
with({ __awaiter: __f1, assert: require("assert"), assertAsyncThrows: __assertAsyncThrows }) {
return function /*assertAsyncThrows*/(test) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield test();
}
catch (err) {
return err.message;
}
assert(false, "Function was expected to throw, but didn't");
return "";
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ util: __util }) {
return () => util;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
cases.push({
title: "Don't capture catch variables",
func: () => { try { } catch (err) { console.log(err); } },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return () => { try { }
catch (err) {
console.log(err);
} };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
// Recursive function serialization.
{
const fff = "fff!";
const ggg = "ggg!";
const xcap = {
fff: function () { console.log(fff); },
ggg: () => { console.log(ggg); },
zzz: {
a: [ (a1: any, a2: any) => { console.log(a1 + a2); } ],
},
};
const func = () => {
xcap.fff();
xcap.ggg();
xcap.zzz.a[0]("x", "y");
};
cases.push({
title: "Serializes recursive function captures",
func: func,
expectText: `exports.handler = __f0;
var __xcap = {};
__xcap.fff = __f1;
__xcap.ggg = __f2;
var __xcap_zzz = {};
var __xcap_zzz_a = [__f3];
__xcap_zzz.a = __xcap_zzz_a;
__xcap.zzz = __xcap_zzz;
function __f1() {
return (function() {
with({ fff: "fff!" }) {
return function () { console.log(fff); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ ggg: "ggg!" }) {
return () => { console.log(ggg); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return (a1, a2) => { console.log(a1 + a2); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ xcap: __xcap }) {
return () => {
xcap.fff();
xcap.ggg();
xcap.zzz.a[0]("x", "y");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class CapCap {
constructor() {
(<any>this).x = 42;
(<any>this).f = () => { console.log((<any>this).x); };
}
}
const cap: any = new CapCap();
cases.push({
title: "Serializes `this` capturing arrow functions",
func: cap.f,
expectText: undefined,
error: `Error serializing function '<anonymous>': closure.spec.js(0,0)
function '<anonymous>': closure.spec.js(0,0): which could not be serialized because
arrow function captured 'this'. Assign 'this' to another name outside function and capture that.
Function code:
() => { console.log(this.x); }
`,
});
}
cases.push({
title: "Don't serialize `this` in function expressions",
func: function() { return this; },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
{
const mutable: any = {};
cases.push({
title: "Serialize mutable objects by value at the time of capture (pre-mutation)",
func: function() { return mutable; },
expectText: `exports.handler = __f0;
var __mutable = {};
function __f0() {
return (function() {
with({ mutable: __mutable }) {
return function () { return mutable; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
afters: [{
pre: () => { mutable.timesTheyAreAChangin = true; },
title: "Serialize mutable objects by value at the time of capture (post-mutation)",
func: function() { return mutable; },
expectText: `exports.handler = __f0;
var __mutable = {timesTheyAreAChangin: true};
function __f0() {
return (function() {
with({ mutable: __mutable }) {
return function () { return mutable; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
}],
});
}
{
const v = { d: output(4) };
cases.push({
title: "Output capture",
func: function () { console.log(v); },
expectText: `exports.handler = __f0;
var __v = {};
var __v_d_proto = {};
__f1.prototype = __v_d_proto;
Object.defineProperty(__v_d_proto, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__v_d_proto, "apply", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__v_d_proto, "get", { configurable: true, writable: true, value: __f3 });
var __v_d = Object.create(__v_d_proto);
__v_d.value = 4;
__v.d = __v_d;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/(value) {
this.value = value;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*apply*/(func) {
throw new Error("'apply' is not allowed from inside a cloud-callback. Use 'get' to retrieve the value of this Output directly.");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*get*/() {
return this.value;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ v: __v }) {
return function () { console.log(v); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = {
d1: output(4),
d2: output("str"),
d3: output(undefined),
d4: output({ a: 1, b: true }),
};
cases.push({
title: "Multiple output capture",
func: function () { console.log(v); },
expectText: `exports.handler = __f0;
var __v = {};
var __v_d1_proto = {};
__f1.prototype = __v_d1_proto;
Object.defineProperty(__v_d1_proto, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__v_d1_proto, "apply", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__v_d1_proto, "get", { configurable: true, writable: true, value: __f3 });
var __v_d1 = Object.create(__v_d1_proto);
__v_d1.value = 4;
__v.d1 = __v_d1;
var __v_d2 = Object.create(__v_d1_proto);
__v_d2.value = "str";
__v.d2 = __v_d2;
var __v_d3 = Object.create(__v_d1_proto);
__v_d3.value = undefined;
__v.d3 = __v_d3;
var __v_d4 = Object.create(__v_d1_proto);
var __v_d4_value = {a: 1, b: true};
__v_d4.value = __v_d4_value;
__v.d4 = __v_d4;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/(value) {
this.value = value;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*apply*/(func) {
throw new Error("'apply' is not allowed from inside a cloud-callback. Use 'get' to retrieve the value of this Output directly.");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*get*/() {
return this.value;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ v: __v }) {
return function () { console.log(v); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = {
d1: output(4),
d2: <any>undefined,
};
v.d2 = output({ a: 1, b: v });
cases.push({
title: "Recursive output capture",
func: function () { console.log(v); },
expectText: `exports.handler = __f0;
var __v = {};
var __v_d1_proto = {};
__f1.prototype = __v_d1_proto;
Object.defineProperty(__v_d1_proto, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__v_d1_proto, "apply", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__v_d1_proto, "get", { configurable: true, writable: true, value: __f3 });
var __v_d1 = Object.create(__v_d1_proto);
__v_d1.value = 4;
__v.d1 = __v_d1;
var __v_d2 = Object.create(__v_d1_proto);
var __v_d2_value = {};
__v_d2_value.a = 1;
__v_d2_value.b = __v;
__v_d2.value = __v_d2_value;
__v.d2 = __v_d2;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/(value) {
this.value = value;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*apply*/(func) {
throw new Error("'apply' is not allowed from inside a cloud-callback. Use 'get' to retrieve the value of this Output directly.");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*get*/() {
return this.value;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ v: __v }) {
return function () { console.log(v); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const obj = { method1() { return this.method2(); }, method2: () => { return; } };
cases.push({
title: "Capture object with methods",
func: function () { console.log(obj); },
expectText: `exports.handler = __f0;
var __obj = {method1: __f1, method2: __f2};
function __f1() {
return (function() {
with({ }) {
return function /*method1*/() { return this.method2(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return () => { return; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ obj: __obj }) {
return function () { console.log(obj); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Undeclared variable in typeof",
// @ts-ignore
func: function () { const x = typeof a; },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ a: undefined }) {
return function () { const x = typeof a; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const a = 0;
cases.push({
title: "Declared variable in typeof",
// @ts-ignore
func: function () { const x = typeof a; },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ a: 0 }) {
return function () { const x = typeof a; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const array: any[] = [];
const obj = { 80: "foo", arr: array };
array.push(obj);
cases.push({
title: "Capture numeric property",
func: function () { return array; },
expectText: `exports.handler = __f0;
var __array = [];
var __array_0 = {};
__array_0["80"] = "foo";
__array_0.arr = __array;
__array[0] = __array_0;
function __f0() {
return (function() {
with({ array: __array }) {
return function () { return array; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const outer: any = { o: 1 };
const array = [outer];
outer.b = array;
const C = (function () {
function C() {}
C.prototype.m = function () { return this.n() + outer; };
C.prototype.n = function () { return array; };
(<any>C).m = function () { return this.n(); };
return C;
}());
cases.push({
title: "Serialize es5-style class",
func: () => C,
expectText: `exports.handler = __f0;
var __C_prototype = {};
Object.defineProperty(__C_prototype, "constructor", { configurable: true, writable: true, value: __C });
var __outer = {};
__outer.o = 1;
var __outer_b = [];
__outer_b[0] = __outer;
__outer.b = __outer_b;
__C_prototype.m = __f1;
__C_prototype.n = __f2;
__C.prototype = __C_prototype;
__C.m = __f3;
function __C() {
return (function() {
with({ C: __C }) {
return function /*C*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ outer: __outer }) {
return function () { return this.n() + outer; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ array: __outer_b }) {
return function () { return array; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function () { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __C }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const outer: any = { o: 1 };
const array = [outer];
outer.b = array;
class C {
public static s() { return array; }
public m() { return this.n(); }
public n() { return outer; }
}
cases.push({
title: "Serialize class",
func: () => C,
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "m", { configurable: true, writable: true, value: __f2 });
var __outer = {};
__outer.o = 1;
var __outer_b = [];
__outer_b[0] = __outer;
__outer.b = __outer_b;
Object.defineProperty(__f1_prototype, "n", { configurable: true, writable: true, value: __f3 });
__f1.prototype = __f1_prototype;
__f1.s = __f4;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*m*/() { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ outer: __outer }) {
return function /*n*/() { return outer; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ array: __outer_b }) {
return function /*s*/() { return array; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
private x: number;
public static s() { return 0; }
constructor() {
this.x = 1;
}
public m() { return this.n(); }
public n() { return 1; }
}
cases.push({
title: "Serialize class with constructor and field",
func: () => C,
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "m", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__f1_prototype, "n", { configurable: true, writable: true, value: __f3 });
__f1.prototype = __f1_prototype;
__f1.s = __f4;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() {
this.x = 1;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*m*/() { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*n*/() { return 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ }) {
return function /*s*/() { return 0; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
private x: number;
public static s() { return 0; }
constructor() {
this.x = 1;
}
public m() { return this.n(); }
public n() { return 1; }
}
cases.push({
title: "Serialize constructed class",
func: () => new C(),
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "m", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__f1_prototype, "n", { configurable: true, writable: true, value: __f3 });
__f1.prototype = __f1_prototype;
__f1.s = __f4;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() {
this.x = 1;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*m*/() { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*n*/() { return 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ }) {
return function /*s*/() { return 0; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => new C();
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
public m() { return this.n(); }
public n() { return 0; }
}
cases.push({
title: "Serialize instance class methods",
func: new C().m,
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function /*m*/() { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
public delete() { return 0; }
}
cases.push({
title: "Serialize method with reserved name",
func: new C().delete,
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function /*delete*/() { return 0; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
public static m() { return this.n(); }
public static n() { return 0; }
}
cases.push({
title: "Serialize static class methods",
func: C.m,
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function /*m*/() { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const D = (function () {
function D() {
;
}
(<any>D).m = function () { return this.n(); };
(<any>D).n = function () { return 0; };
return D;
}());
cases.push({
title: "Serialize static class methods (es5 class style)",
func: (<any>D).m,
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ }) {
return function () { return this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const array: any[] = [1];
array.push(array);
cases.push({
title: "Cyclic object #1",
func: () => array,
expectText: `exports.handler = __f0;
var __array = [];
__array[0] = 1;
__array[1] = __array;
function __f0() {
return (function() {
with({ array: __array }) {
return () => array;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const obj: any = {a: 1};
obj.b = obj;
cases.push({
title: "Cyclic object #2",
func: () => obj,
expectText: `exports.handler = __f0;
var __obj = {};
__obj.a = 1;
__obj.b = __obj;
function __f0() {
return (function() {
with({ obj: __obj }) {
return () => obj;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const obj: any = {a: []};
obj.a.push(obj);
obj.b = obj.a;
cases.push({
title: "Cyclic object #3",
func: () => obj,
expectText: `exports.handler = __f0;
var __obj = {};
var __obj_a = [];
__obj_a[0] = __obj;
__obj.a = __obj_a;
__obj.b = __obj_a;
function __f0() {
return (function() {
with({ obj: __obj }) {
return () => obj;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const obj: any = {a: []};
obj.a.push(obj);
obj.b = obj.a;
const obj2 = [obj, obj];
cases.push({
title: "Cyclic object #4",
func: () => obj2,
expectText: `exports.handler = __f0;
var __obj2 = [];
var __obj2_0 = {};
var __obj2_0_a = [];
__obj2_0_a[0] = __obj2_0;
__obj2_0.a = __obj2_0_a;
__obj2_0.b = __obj2_0_a;
__obj2[0] = __obj2_0;
__obj2[1] = __obj2_0;
function __f0() {
return (function() {
with({ obj2: __obj2 }) {
return () => obj2;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const obj: any = {a: 1};
function f1() { return obj; }
function f2() { console.log(obj); }
cases.push({
title: "Object captured across multiple functions",
func: () => { f1(); obj.a = 2; f2(); },
expectText: `exports.handler = __f0;
var __obj = {a: 1};
function __f1() {
return (function() {
with({ obj: __obj, f1: __f1 }) {
return function /*f1*/() { return obj; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ obj: __obj, f2: __f2 }) {
return function /*f2*/() { console.log(obj); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ f1: __f1, obj: __obj, f2: __f2 }) {
return () => { f1(); obj.a = 2; f2(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = {};
Object.defineProperty(v, "key", {
configurable: true,
value: 1,
});
cases.push({
title: "Complex property descriptor #1",
func: () => v,
expectText: `exports.handler = __f0;
var __v = {};
Object.defineProperty(__v, "key", { configurable: true, value: 1 });
function __f0() {
return (function() {
with({ v: __v }) {
return () => v;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = {};
Object.defineProperty(v, "key", {
writable: true,
enumerable: true,
value: 1,
});
cases.push({
title: "Complex property descriptor #2",
func: () => v,
expectText: `exports.handler = __f0;
var __v = {};
Object.defineProperty(__v, "key", { enumerable: true, writable: true, value: 1 });
function __f0() {
return (function() {
with({ v: __v }) {
return () => v;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = [1, 2, 3];
delete v[1];
cases.push({
title: "Test array #1",
func: () => v,
expectText: `exports.handler = __f0;
var __v = [];
__v[0] = 1;
__v[2] = 3;
function __f0() {
return (function() {
with({ v: __v }) {
return () => v;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = [1, 2, 3];
delete v[1];
(<any>v).foo = "";
cases.push({
title: "Test array #2",
func: () => v,
expectText: `exports.handler = __f0;
var __v = [];
__v[0] = 1;
__v[2] = 3;
__v.foo = "";
function __f0() {
return (function() {
with({ v: __v }) {
return () => v;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = () => { return 1; };
(<any>v).foo = "bar";
cases.push({
title: "Test function with property",
func: v,
expectText: `exports.handler = __f0;
__f0.foo = "bar";
function __f0() {
return (function() {
with({ }) {
return () => { return 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const x = Object.create(null);
const v = () => { return x; };
cases.push({
title: "Test null prototype",
func: v,
expectText: `exports.handler = __f0;
var __x = Object.create(null);
function __f0() {
return (function() {
with({ x: __x }) {
return () => { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const x = Object.create(Number.prototype);
const v = () => { return x; };
cases.push({
title: "Test non-default object prototype",
func: v,
expectText: `exports.handler = __f0;
var __x = Object.create(global.Number.prototype);
function __f0() {
return (function() {
with({ x: __x }) {
return () => { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const x = Object.create({ x() { return v; } });
const v = () => { return x; };
cases.push({
title: "Test recursive prototype object prototype",
func: v,
expectText: `exports.handler = __f0;
var __x_proto = {x: __f1};
var __x = Object.create(__x_proto);
function __f1() {
return (function() {
with({ v: __f0 }) {
return function /*x*/() { return v; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ x: __x }) {
return () => { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const v = () => { return 0; };
Object.setPrototypeOf(v, () => { return 1; });
cases.push({
title: "Test non-default function prototype",
func: v,
expectText: `exports.handler = __f0;
Object.setPrototypeOf(__f0, __f1);
function __f0() {
return (function() {
with({ }) {
return () => { return 0; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ }) {
return () => { return 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
function *f() { yield 1; }
cases.push({
title: "Test generator func",
func: f,
expectText: `exports.handler = __f;
var __f_prototype = Object.create(Object.getPrototypeOf((function*(){}).prototype));
__f.prototype = __f_prototype;
Object.setPrototypeOf(__f, Object.getPrototypeOf(function*(){}));
function __f() {
return (function() {
with({ f: __f }) {
return function* /*f*/() { yield 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const gf = (function *() { yield 1; });
cases.push({
title: "Test anonymous generator func",
func: gf,
expectText: `exports.handler = __f0;
var __f0_prototype = Object.create(Object.getPrototypeOf((function*(){}).prototype));
__f0.prototype = __f0_prototype;
Object.setPrototypeOf(__f0, Object.getPrototypeOf(function*(){}));
function __f0() {
return (function() {
with({ }) {
return function* () { yield 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
private _x: number;
constructor() {
this._x = 0;
}
get foo() {
return this._x;
}
set foo(v: number) {
this._x = v;
}
}
cases.push({
title: "Test getter/setter #1",
func: () => C,
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "foo", { configurable: true, get: __f2, set: __f3 });
__f1.prototype = __f1_prototype;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() {
this._x = 0;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*foo*/() {
return this._x;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*foo*/(v) {
this._x = v;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const methodName = "method name";
class C {
[methodName](a: number) {
return a;
}
}
cases.push({
title: "Test computed method name.",
func: () => C,
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "method name", { configurable: true, writable: true, value: __f2 });
__f1.prototype = __f1_prototype;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function (a) {
return a;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const sym = Symbol("test_symbol");
class C {
[sym](a: number) {
return a;
}
getSym() { return sym; }
}
cases.push({
title: "Test symbols #1",
func: () => C,
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
var __sym = Object.create(global.Symbol.prototype);
Object.defineProperty(__f1_prototype, "getSym", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__f1_prototype, __sym, { configurable: true, writable: true, value: __f3 });
__f1.prototype = __f1_prototype;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ sym: __sym }) {
return function /*getSym*/() { return sym; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function (a) {
return a;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
[Symbol.iterator](a: number) {
return a;
}
}
cases.push({
title: "Test Symbol.iterator",
func: () => C,
expectText: `exports.handler = __f0;
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, Symbol.iterator, { configurable: true, writable: true, value: __f2 });
__f1.prototype = __f1_prototype;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function (a) {
return a;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class D {
public n: number;
constructor(n: number) {
this.n = n;
console.log("DConstructor");
}
dMethod(x: number) { return x; }
dVirtual() { return 1; }
}
class C extends D {
constructor(n: number) {
super(n + 1);
console.log("CConstructor");
}
cMethod() {
return "" +
super.dMethod + super["dMethod"] +
super.dMethod(1) + super["dMethod"](2) +
super.dMethod(super.dMethod(3));
}
dVirtual() { return 3; }
}
cases.push({
title: "Test class extension",
func: () => C,
expectText: `exports.handler = __f0;
var __f2_prototype = {};
Object.defineProperty(__f2_prototype, "constructor", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__f2_prototype, "dMethod", { configurable: true, writable: true, value: __f3 });
Object.defineProperty(__f2_prototype, "dVirtual", { configurable: true, writable: true, value: __f4 });
__f2.prototype = __f2_prototype;
var __f1_prototype = Object.create(__f2_prototype);
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "cMethod", { configurable: true, writable: true, value: __f5 });
Object.defineProperty(__f1_prototype, "dVirtual", { configurable: true, writable: true, value: __f6 });
__f1.prototype = __f1_prototype;
Object.setPrototypeOf(__f1, __f2);
function __f2() {
return (function() {
with({ }) {
return function /*constructor*/(n) {
this.n = n;
console.log("DConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*dMethod*/(x) { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ }) {
return function /*dVirtual*/() { return 1; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ __super: __f2 }) {
return function /*constructor*/(n) {
__super.call(this, n + 1);
console.log("CConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f5() {
return (function() {
with({ __super: __f2 }) {
return function /*cMethod*/() {
return "" +
__super.prototype.dMethod + __super.prototype["dMethod"] +
__super.prototype.dMethod.call(this, 1) + __super.prototype["dMethod"].call(this, 2) +
__super.prototype.dMethod.call(this, __super.prototype.dMethod.call(this, 3));
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f6() {
return (function() {
with({ __super: __f2 }) {
return function /*dVirtual*/() { return 3; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class A {
public n: number;
constructor(n: number) {
this.n = n;
console.log("AConstruction");
}
method(x: number) { return x; }
}
class B extends A {
constructor(n: number) {
super(n + 1);
console.log("BConstructor");
}
method(n: number) { return 1 + super.method(n + 1); }
}
class C extends B {
constructor(n: number) {
super(n * 2);
console.log("CConstructor");
}
method(n: number) { return 2 * super.method(n * 2); }
}
cases.push({
title: "Three level inheritance",
func: () => C,
expectText: `exports.handler = __f0;
var __f3_prototype = {};
Object.defineProperty(__f3_prototype, "constructor", { configurable: true, writable: true, value: __f3 });
Object.defineProperty(__f3_prototype, "method", { configurable: true, writable: true, value: __f4 });
__f3.prototype = __f3_prototype;
var __f2_prototype = Object.create(__f3_prototype);
Object.defineProperty(__f2_prototype, "constructor", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__f2_prototype, "method", { configurable: true, writable: true, value: __f5 });
__f2.prototype = __f2_prototype;
Object.setPrototypeOf(__f2, __f3);
var __f1_prototype = Object.create(__f2_prototype);
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "method", { configurable: true, writable: true, value: __f6 });
__f1.prototype = __f1_prototype;
Object.setPrototypeOf(__f1, __f2);
function __f3() {
return (function() {
with({ }) {
return function /*constructor*/(n) {
this.n = n;
console.log("AConstruction");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ }) {
return function /*method*/(x) { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ __super: __f3 }) {
return function /*constructor*/(n) {
__super.call(this, n + 1);
console.log("BConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f5() {
return (function() {
with({ __super: __f3 }) {
return function /*method*/(n) { return 1 + __super.prototype.method.call(this, n + 1); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ __super: __f2 }) {
return function /*constructor*/(n) {
__super.call(this, n * 2);
console.log("CConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f6() {
return (function() {
with({ __super: __f2 }) {
return function /*method*/(n) { return 2 * __super.prototype.method.call(this, n * 2); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`});
}
{
const sym = Symbol();
class A {
public n: number;
constructor(n: number) {
this.n = n;
console.log("AConstruction");
}
public [sym](x: number) { return x; }
}
class B extends A {
constructor(n: number) {
super(n + 1);
console.log("BConstructor");
}
// @ts-ignore
public [sym](n: number) { return 1 + super[sym](n + 1); }
}
class C extends B {
constructor(n: number) {
super(n * 2);
console.log("CConstructor");
}
// @ts-ignore
public [sym](n: number) { return 2 * super[sym](n * 2); }
}
cases.push({
title: "Three level inheritance with symbols",
func: () => C,
expectText: `exports.handler = __f0;
var __f3_prototype = {};
Object.defineProperty(__f3_prototype, "constructor", { configurable: true, writable: true, value: __f3 });
var __f3_prototype_sym = Object.create(global.Symbol.prototype);
Object.defineProperty(__f3_prototype, __f3_prototype_sym, { configurable: true, writable: true, value: __f4 });
__f3.prototype = __f3_prototype;
var __f2_prototype = Object.create(__f3_prototype);
Object.defineProperty(__f2_prototype, "constructor", { configurable: true, writable: true, value: __f2 });
Object.defineProperty(__f2_prototype, __f3_prototype_sym, { configurable: true, writable: true, value: __f5 });
__f2.prototype = __f2_prototype;
Object.setPrototypeOf(__f2, __f3);
var __f1_prototype = Object.create(__f2_prototype);
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, __f3_prototype_sym, { configurable: true, writable: true, value: __f6 });
__f1.prototype = __f1_prototype;
Object.setPrototypeOf(__f1, __f2);
function __f3() {
return (function() {
with({ }) {
return function /*constructor*/(n) {
this.n = n;
console.log("AConstruction");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ }) {
return function (x) { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ __super: __f3 }) {
return function /*constructor*/(n) {
__super.call(this, n + 1);
console.log("BConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f5() {
return (function() {
with({ sym: __f3_prototype_sym, __super: __f3 }) {
return function /*__computed*/(n) { return 1 + __super.prototype[sym].call(this, n + 1); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ __super: __f2 }) {
return function /*constructor*/(n) {
__super.call(this, n * 2);
console.log("CConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f6() {
return (function() {
with({ sym: __f3_prototype_sym, __super: __f2 }) {
return function /*__computed*/(n) { return 2 * __super.prototype[sym].call(this, n * 2); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ C: __f1 }) {
return () => C;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`});
}
{
const sym = Symbol();
class A {
public n: number;
static method(x: number) { return x; }
static [sym](x: number) { return x * x; }
constructor(n: number) {
this.n = n;
console.log("AConstruction");
}
}
class B extends A {
static method(n: number) { return 1 + super.method(n + 1); }
// @ts-ignore
static [sym](x: number) { return x * super[sym](x + 1); }
constructor(n: number) {
super(n + 1);
console.log("BConstructor");
}
}
cases.push({
title: "Two level static inheritance",
func: () => B,
expectText: `exports.handler = __f0;
__f2.method = __f3;
var __f2_sym = Object.create(global.Symbol.prototype);
__f2[__f2_sym] = __f4;
__f1.method = __f5;
__f1[__f2_sym] = __f6;
Object.setPrototypeOf(__f1, __f2);
function __f2() {
return (function() {
with({ }) {
return function /*constructor*/(n) {
this.n = n;
console.log("AConstruction");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ }) {
return function /*method*/(x) { return x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ }) {
return function (x) { return x * x; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ __super: __f2 }) {
return function /*constructor*/(n) {
__super.call(this, n + 1);
console.log("BConstructor");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f5() {
return (function() {
with({ __super: __f2 }) {
return function /*method*/(n) { return 1 + __super.method.call(this, n + 1); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f6() {
return (function() {
with({ sym: __f2_sym, __super: __f2 }) {
return function /*__computed*/(x) { return x * __super[sym].call(this, x + 1); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ B: __f1 }) {
return () => B;
}
}).apply(undefined, undefined).apply(this, arguments);
}
`});
}
{
const o = { a: 1, b: 2 };
cases.push({
title: "Capture subset of properties #1",
func: function () { console.log(o.a); },
expectText: `exports.handler = __f0;
var __o = {a: 1};
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.a); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c: 3 };
cases.push({
title: "Capture subset of properties #2",
func: function () { console.log(o.b + o.c); },
expectText: `exports.handler = __f0;
var __o = {b: 2, c: 3};
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b + o.c); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c: 3 };
cases.push({
title: "Capture all if object is used as is.",
func: function () { console.log(o); },
expectText: `exports.handler = __f0;
var __o = {a: 1, b: 2, c: 3};
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c() { return this; } };
cases.push({
title: "Capture all if object property is invoked, and it uses this.",
func: function () { console.log(o.c()); },
expectText: `exports.handler = __f0;
var __o = {a: 1, b: 2, c: __f1};
function __f1() {
return (function() {
with({ }) {
return function /*c*/() { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.c()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c() { const v = () => this; } };
cases.push({
title: "Capture all if object property is invoked, and it uses this in nested arrow function.",
func: function () { console.log(o.c()); },
expectText: `exports.handler = __f0;
var __o = {a: 1, b: 2, c: __f1};
function __f1() {
return (function() {
with({ }) {
return function /*c*/() { const v = () => this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.c()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c() { const v = function () { return this; }; } };
cases.push({
title: "Capture one if object property is invoked, but it uses this in nested function.",
func: function () { console.log(o.c()); },
expectText: `exports.handler = __f0;
var __o = {c: __f1};
function __f1() {
return (function() {
with({ }) {
return function /*c*/() { const v = function () { return this; }; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.c()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c() { return this; } };
cases.push({
title: "Capture one if object property is captured, uses this, but is not invoked",
func: function () { console.log(o.c); },
expectText: `exports.handler = __f0;
var __o = {c: __f1};
function __f1() {
return (function() {
with({ }) {
return function /*c*/() { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.c); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 2, c() { return 0; } };
cases.push({
title: "Capture one if object property is invoked, and it does not use this.",
func: function () { console.log(o.c()); },
expectText: `exports.handler = __f0;
var __o = {c: __f1};
function __f1() {
return (function() {
with({ }) {
return function /*c*/() { return 0; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.c()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c() { return this; } } };
cases.push({
title: "Capture subset if sub object property is invoked.",
func: function () { console.log(o.b.c()); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {c: __f1};
__o.b = __o_b;
function __f1() {
return (function() {
with({ }) {
return function /*c*/() { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.c()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, get b() { return this; } };
cases.push({
title: "Capture all if getter and getter uses this.",
func: function () { console.log(o.b); },
expectText: `exports.handler = __f0;
var __o = {};
__o.a = 1;
Object.defineProperty(__o, "b", { configurable: true, enumerable: true, get: __f1 });
function __f1() {
return (function() {
with({ }) {
return function /*b*/() { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, get b() { return 0; } };
cases.push({
title: "Capture one if getter and getter does not use this.",
func: function () { console.log(o.b); },
expectText: `exports.handler = __f0;
var __o = {};
Object.defineProperty(__o, "b", { configurable: true, enumerable: true, get: __f1 });
function __f1() {
return (function() {
with({ }) {
return function /*b*/() { return 0; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 1, c: 2 };
function f1() {
console.log(o.a);
f2();
}
function f2() {
console.log(o.c);
}
cases.push({
title: "Capture multi props from different contexts #1",
func: f1,
expectText: `exports.handler = __f1;
var __o = {a: 1, c: 2};
function __f2() {
return (function() {
with({ o: __o, f2: __f2 }) {
return function /*f2*/() {
console.log(o.c);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ o: __o, f2: __f2, f1: __f1 }) {
return function /*f1*/() {
console.log(o.a);
f2();
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1 };
function f1() {
// @ts-ignore
console.log(o.c);
}
cases.push({
title: "Do not capture non-existent prop",
func: f1,
expectText: `exports.handler = __f1;
var __o = {};
function __f1() {
return (function() {
with({ o: __o, f1: __f1 }) {
return function /*f1*/() {
// @ts-ignore
console.log(o.c);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 1, c: 2 };
function f1() {
console.log(o.a);
f2();
}
function f2() {
console.log(o);
}
cases.push({
title: "Capture all props from different contexts #1",
func: f1,
expectText: `exports.handler = __f1;
var __o = {a: 1, b: 1, c: 2};
function __f2() {
return (function() {
with({ o: __o, f2: __f2 }) {
return function /*f2*/() {
console.log(o);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ o: __o, f2: __f2, f1: __f1 }) {
return function /*f1*/() {
console.log(o.a);
f2();
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: 1, c: 2 };
function f1() {
console.log(o);
f2();
}
function f2() {
console.log(o.a);
}
cases.push({
title: "Capture all props from different contexts #2",
func: f1,
expectText: `exports.handler = __f1;
var __o = {a: 1, b: 1, c: 2};
function __f2() {
return (function() {
with({ o: __o, f2: __f2 }) {
return function /*f2*/() {
console.log(o.a);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ o: __o, f2: __f2, f1: __f1 }) {
return function /*f1*/() {
console.log(o);
f2();
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
a: number;
b: number;
constructor() {
this.a = 1;
this.b = 2;
}
m() { console.log(this); }
}
const o = new C();
cases.push({
title: "Capture all props if prototype is and uses this #1",
func: function () { o.m(); },
expectText: `exports.handler = __f0;
var __o_proto = {};
__f1.prototype = __o_proto;
Object.defineProperty(__o_proto, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__o_proto, "m", { configurable: true, writable: true, value: __f2 });
var __o = Object.create(__o_proto);
__o.a = 1;
__o.b = 2;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() {
this.a = 1;
this.b = 2;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*m*/() { console.log(this); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { o.m(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
a: number;
b: number;
constructor() {
this.a = 1;
this.b = 2;
}
m() { }
}
const o = new C();
cases.push({
title: "Capture no props if prototype is used but does not use this #1",
func: function () { o.m(); },
expectText: `exports.handler = __f0;
var __o = {};
Object.defineProperty(__o, "m", { configurable: true, writable: true, value: __f1 });
function __f1() {
return (function() {
with({ }) {
return function /*m*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { o.m(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
class C {
a: number;
constructor() {
this.a = 1;
}
m() { (<any>this).n(); }
}
class D extends C {
b: number;
constructor() {
super();
this.b = 2;
}
n() {}
}
const o = new D();
cases.push({
title: "Capture all props if prototype is accessed #2",
func: function () { o.m(); },
expectText: `exports.handler = __f0;
var __o_proto_proto = {};
__f1.prototype = __o_proto_proto;
Object.defineProperty(__o_proto_proto, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__o_proto_proto, "m", { configurable: true, writable: true, value: __f2 });
var __o_proto = Object.create(__o_proto_proto);
__f3.prototype = __o_proto;
Object.setPrototypeOf(__f3, __f1);
Object.defineProperty(__o_proto, "constructor", { configurable: true, writable: true, value: __f3 });
Object.defineProperty(__o_proto, "n", { configurable: true, writable: true, value: __f4 });
var __o = Object.create(__o_proto);
__o.a = 1;
__o.b = 2;
function __f1() {
return (function() {
with({ }) {
return function /*constructor*/() {
this.a = 1;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ }) {
return function /*m*/() { this.n(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ __super: __f1 }) {
return function /*constructor*/() {
__super.call(this);
this.b = 2;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f4() {
return (function() {
with({ __super: __f1 }) {
return function /*n*/() { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { o.m(); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const table1: any = { primaryKey: 1, insert: () => { }, scan: () => { } };
async function testScanReturnsAllValues() {
await table1.insert({[table1.primaryKey.get()]: "val1", value1: 1, value2: "1"});
await table1.insert({[table1.primaryKey.get()]: "val2", value1: 2, value2: "2"});
const values = null;
// @ts-ignore
const value1 = values.find(v => v[table1.primaryKey.get()] === "val1");
// @ts-ignore
const value2 = values.find(v => v[table1.primaryKey.get()] === "val2");
}
cases.push({
title: "Cloud table function",
func: testScanReturnsAllValues,
expectText: `exports.handler = __testScanReturnsAllValues;
var __table1 = {insert: __f1, primaryKey: 1};
function __f0() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ }) {
return () => { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __testScanReturnsAllValues() {
return (function() {
with({ __awaiter: __f0, table1: __table1, testScanReturnsAllValues: __testScanReturnsAllValues }) {
return function /*testScanReturnsAllValues*/() {
return __awaiter(this, void 0, void 0, function* () {
yield table1.insert({ [table1.primaryKey.get()]: "val1", value1: 1, value2: "1" });
yield table1.insert({ [table1.primaryKey.get()]: "val2", value1: 2, value2: "2" });
const values = null;
// @ts-ignore
const value1 = values.find(v => v[table1.primaryKey.get()] === "val1");
// @ts-ignore
const value2 = values.find(v => v[table1.primaryKey.get()] === "val2");
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { x: 1, doNotCapture: true }, c: 2 };
function f1() {
console.log(o);
}
cases.push({
title: "Do not capture #1",
func: f1,
expectText: `exports.handler = __f1;
var __o = {a: 1, b: undefined, c: 2};
function __f1() {
return (function() {
with({ o: __o, f1: __f1 }) {
return function /*f1*/() {
console.log(o);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: () => console.log("the actual function") };
(<any>o.b).doNotCapture = true;
function f1() {
console.log(o);
}
cases.push({
title: "Do not capture #2",
func: f1,
expectText: `exports.handler = __f1;
var __o = {a: 1, b: __f0};
function __f0() {
return (function() {
with({ message: "Function 'b' cannot be called at runtime. It can only be used at deployment time.\\n\\nFunction code:\\n () => console.log(\\"the actual function\\")\\n" }) {
return () => { throw new Error(message); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ o: __o, f1: __f1 }) {
return function /*f1*/() {
console.log(o);
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const lambda1 = () => console.log(1);
const lambda2 = () => console.log(1);
function f3() {
return (lambda1(), lambda2());
}
cases.push({
title: "Merge simple functions",
func: f3,
expectText: `exports.handler = __f3;
function __f0() {
return (function() {
with({ }) {
return () => console.log(1);
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ lambda1: __f0, lambda2: __f0, f3: __f3 }) {
return function /*f3*/() {
return (lambda1(), lambda2());
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const awaiter1 = function (thisArg: any, _arguments: any, P: any, generator: any) {
return new (P || (P = Promise))(function (resolve: any, reject: any) {
function fulfilled(value: any) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value: any) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result: any) { result.done ? resolve(result.value) : new P(function (resolve1: any) { resolve1(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
const awaiter2 = function (thisArg: any, _arguments: any, P: any, generator: any) {
return new (P || (P = Promise))(function (resolve: any, reject: any) {
function fulfilled(value: any) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value: any) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result: any) { result.done ? resolve(result.value) : new P(function (resolve1: any) { resolve1(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
function f3() {
const v1 = awaiter1, v2 = awaiter2;
}
cases.push({
title: "Share __awaiter functions",
func: f3,
expectText: `exports.handler = __f3;
function __f0() {
return (function() {
with({ }) {
return function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try {
step(generator.next(value));
}
catch (e) {
reject(e);
} }
function rejected(value) { try {
step(generator["throw"](value));
}
catch (e) {
reject(e);
} }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve1) { resolve1(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f3() {
return (function() {
with({ awaiter1: __f0, awaiter2: __f0, f3: __f3 }) {
return function /*f3*/() {
const v1 = awaiter1, v2 = awaiter2;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Capture of exported variable #1",
func: function () { console.log(exportedValue); },
expectText: `exports.handler = __f0;
var __exports = {exportedValue: 42};
function __f0() {
return (function() {
with({ exports: __exports }) {
return function () { console.log(exports.exportedValue); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Capture of exported variable #2",
func: function () { console.log(exports.exportedValue); },
expectText: `exports.handler = __f0;
var __exports = {exportedValue: 42};
function __f0() {
return (function() {
with({ exports: __exports }) {
return function () { console.log(exports.exportedValue); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Capture of exported variable #3",
func: function () { console.log(module.exports.exportedValue); },
expectText: `exports.handler = __f0;
var __module = {};
var __module_exports = {exportedValue: 42};
__module.exports = __module_exports;
function __f0() {
return (function() {
with({ module: __module }) {
return function () { console.log(module.exports.exportedValue); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
function foo() {
require("./util");
}
cases.push({
title: "Required packages #1",
func: function () { require("typescript"); foo(); if (true) { require("os") } },
expectPackages: new Set(["os", "typescript", "./util"]),
expectText: `exports.handler = __f0;
function __foo() {
return (function() {
with({ foo: __foo }) {
return function /*foo*/() {
require("./util");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ foo: __foo }) {
return function () { require("typescript"); foo(); if (true) {
require("os");
} };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: 2, d: 3 } };
cases.push({
title: "Analyze property chain #1",
func: function () { console.log(o.b.c); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {c: 2};
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.c); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: 2, d: 3 } };
cases.push({
title: "Analyze property chain #2",
func: function () { console.log(o.b); console.log(o.b.c); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {c: 2, d: 3};
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b); console.log(o.b.c); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: 2, d: 3 } };
cases.push({
title: "Analyze property chain #3",
func: function () { console.log(o.b); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {c: 2, d: 3};
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: 2, d: 3 } };
cases.push({
title: "Analyze property chain #4",
func: function () { console.log(o.a); },
expectText: `exports.handler = __f0;
var __o = {a: 1};
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.a); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: { d: 1, e: 3 } } };
cases.push({
title: "Analyze property chain #5",
func: function () { console.log(o.b.c.d); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {};
var __o_b_c = {d: 1};
__o_b.c = __o_b_c;
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.c.d); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: { d: 1, e: 3 } } };
cases.push({
title: "Analyze property chain #6",
func: function () { console.log(o.b.c.d); console.log(o.b); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {};
var __o_b_c = {d: 1, e: 3};
__o_b.c = __o_b_c;
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.c.d); console.log(o.b); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: { d: 1, e: 3 } } };
cases.push({
title: "Analyze property chain #7",
func: function () { console.log(o.b.c.d); console.log(o.b.c); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {};
var __o_b_c = {d: 1, e: 3};
__o_b.c = __o_b_c;
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.c.d); console.log(o.b.c); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: { c: { d: 1, e: 3 } } };
cases.push({
title: "Analyze property chain #8",
func: function () { console.log(o.b.c.d); console.log(o.b.c); console.log(o.b); },
expectText: `exports.handler = __f0;
var __o = {};
var __o_b = {};
var __o_b_c = {d: 1, e: 3};
__o_b.c = __o_b_c;
__o.b = __o_b;
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.c.d); console.log(o.b.c); console.log(o.b); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: function () { } };
cases.push({
title: "Analyze property chain #9",
func: function () { console.log(o.b.name); },
expectText: `exports.handler = __f0;
var __o = {b: __f1};
function __f1() {
return (function() {
with({ }) {
return function () { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.name); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: function () { } };
cases.push({
title: "Analyze property chain #10",
func: function () { console.log(o.b.name); console.log(o.b()); },
expectText: `exports.handler = __f0;
var __o = {b: __f1};
function __f1() {
return (function() {
with({ }) {
return function () { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.name); console.log(o.b()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: function () { } };
cases.push({
title: "Analyze property chain #11",
func: function () { console.log(o.b()); console.log(o.b.name); },
expectText: `exports.handler = __f0;
var __o = {b: __f1};
function __f1() {
return (function() {
with({ }) {
return function () { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b()); console.log(o.b.name); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: function () { return this; } };
cases.push({
title: "Analyze property chain #12",
func: function () { console.log(o.b.name); console.log(o.b()); },
expectText: `exports.handler = __f0;
var __o = {a: 1, b: __f1};
function __f1() {
return (function() {
with({ }) {
return function () { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b.name); console.log(o.b()); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o = { a: 1, b: function () { return this; } };
cases.push({
title: "Analyze property chain #13",
func: function () { console.log(o.b()); console.log(o.b.name); },
expectText: `exports.handler = __f0;
var __o = {a: 1, b: __f1};
function __f1() {
return (function() {
with({ }) {
return function () { return this; };
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ o: __o }) {
return function () { console.log(o.b()); console.log(o.b.name); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #14",
func: function () { console.log(o2.b.d); console.log(o1); },
expectText: `exports.handler = __f0;
var __o2 = {};
var __o2_b = {d: 3, c: 2};
__o2.b = __o2_b;
function __f0() {
return (function() {
with({ o2: __o2, o1: __o2_b }) {
return function () { console.log(o2.b.d); console.log(o1); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #15",
func: function () { console.log(o1); console.log(o2.b.d); },
expectText: `exports.handler = __f0;
var __o1 = {c: 2, d: 3};
var __o2 = {};
__o2.b = __o1;
function __f0() {
return (function() {
with({ o1: __o1, o2: __o2 }) {
return function () { console.log(o1); console.log(o2.b.d); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
const o3 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #16",
func: function () { console.log(o2.b.c); console.log(o3.b.d); },
expectText: `exports.handler = __f0;
var __o2 = {};
var __o2_b = {c: 2, d: 3};
__o2.b = __o2_b;
var __o3 = {};
__o3.b = __o2_b;
function __f0() {
return (function() {
with({ o2: __o2, o3: __o3 }) {
return function () { console.log(o2.b.c); console.log(o3.b.d); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
const o3 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #17",
func: function () { console.log(o2.b.d); console.log(o3.b.d); },
expectText: `exports.handler = __f0;
var __o2 = {};
var __o2_b = {d: 3};
__o2.b = __o2_b;
var __o3 = {};
__o3.b = __o2_b;
function __f0() {
return (function() {
with({ o2: __o2, o3: __o3 }) {
return function () { console.log(o2.b.d); console.log(o3.b.d); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
const o3 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #18",
func: function () { console.log(o2.b); console.log(o2.b.d); console.log(o3.b.d); },
expectText: `exports.handler = __f0;
var __o2 = {};
var __o2_b = {c: 2, d: 3};
__o2.b = __o2_b;
var __o3 = {};
__o3.b = __o2_b;
function __f0() {
return (function() {
with({ o2: __o2, o3: __o3 }) {
return function () { console.log(o2.b); console.log(o2.b.d); console.log(o3.b.d); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
const o3 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #19",
func: function () { console.log(o2.b.d); console.log(o3.b.d); console.log(o2.b); },
expectText: `exports.handler = __f0;
var __o2 = {};
var __o2_b = {c: 2, d: 3};
__o2.b = __o2_b;
var __o3 = {};
__o3.b = __o2_b;
function __f0() {
return (function() {
with({ o2: __o2, o3: __o3 }) {
return function () { console.log(o2.b.d); console.log(o3.b.d); console.log(o2.b); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
const o3 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #20",
func: function () { console.log(o2.b.d); console.log(o3.b.d); console.log(o1); },
expectText: `exports.handler = __f0;
var __o2 = {};
var __o2_b = {d: 3, c: 2};
__o2.b = __o2_b;
var __o3 = {};
__o3.b = __o2_b;
function __f0() {
return (function() {
with({ o2: __o2, o3: __o3, o1: __o2_b }) {
return function () { console.log(o2.b.d); console.log(o3.b.d); console.log(o1); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
const o1 = { c: 2, d: 3 };
const o2 = { a: 1, b: o1 };
const o3 = { a: 1, b: o1 };
cases.push({
title: "Analyze property chain #21",
func: function () { console.log(o1); console.log(o2.b.d); console.log(o3.b.d); },
expectText: `exports.handler = __f0;
var __o1 = {c: 2, d: 3};
var __o2 = {};
__o2.b = __o1;
var __o3 = {};
__o3.b = __o1;
function __f0() {
return (function() {
with({ o1: __o1, o2: __o2, o3: __o3 }) {
return function () { console.log(o1); console.log(o2.b.d); console.log(o3.b.d); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Capture non-built-in module",
func: function () { typescript.parseCommandLine([""]); },
expectText: `exports.handler = __f0;
function __f0() {
return (function() {
with({ typescript: require("typescript/lib/typescript.js") }) {
return function () { typescript.parseCommandLine([""]); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Fail to capture non-deployment module due to native code",
func: function () { console.log(pulumi); },
error: `Error serializing function 'func': closure.spec.js(0,0)
function 'func': closure.spec.js(0,0): captured
module './bin/index.js' which indirectly referenced
function 'debug': index.js(0,0): which captured
module './bin/runtime/settings.js' which indirectly referenced
function 'getEngine': settings.js(0,0): which captured
module './bin/proto/engine_grpc_pb.js' which indirectly referenced
(...)
Function code:
(...)
Module './bin/index.js' is a 'deployment only' module. In general these cannot be captured inside a 'run time' function.`
});
}
{
// Used just to validate that if we capture a Config object we see these values serialized over.
// Specifically, the module that Config uses needs to be captured by value and not be
// 'require-reference'.
runtime.setConfig("test:TestingKey1", "TestingValue1");
const testConfig = new pulumi.Config("test");
cases.push({
title: "Capture config created on the outside",
func: function () { const v = testConfig.get("TestingKey1"); console.log(v); },
expectText: `exports.handler = __f0;
var __testConfig_proto = {};
var __config = {["test:TestingKey1"]: "TestingValue1", ["test:TestingKey2"]: "TestingValue2", ["pkg:a"]: "foo", ["pkg:bar"]: "b", ["pkg:baz"]: "baz", ["otherpkg:a"]: "babble", ["otherpkg:nothere"]: "bazzle", ["pkg:boolf"]: "false", ["pkg:boolt"]: "true", ["pkg:num"]: "42.333", ["pkg:array"]: "[ 0, false, 2, \\"foo\\" ]", ["pkg:struct"]: "{ \\"foo\\": \\"bar\\", \\"mim\\": [] }"};
var __options = {project: undefined};
var __runtime = {getConfig: __getConfig, getProject: __0_getProject};
var __metadata_1 = {getProject: __getProject};
__f1.prototype = __testConfig_proto;
Object.defineProperty(__testConfig_proto, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__testConfig_proto, "get", { configurable: true, writable: true, value: __f2 });
__f5.isInstance = __f6;
(...)
Object.setPrototypeOf(__f4, __f5);
Object.defineProperty(__testConfig_proto, "getBoolean", { configurable: true, writable: true, value: __f3 });
Object.defineProperty(__testConfig_proto, "getNumber", { configurable: true, writable: true, value: __f7 });
Object.defineProperty(__testConfig_proto, "getObject", { configurable: true, writable: true, value: __f8 });
Object.setPrototypeOf(__f10, __f5);
Object.defineProperty(__testConfig_proto, "require", { configurable: true, writable: true, value: __f9 });
Object.defineProperty(__testConfig_proto, "requireBoolean", { configurable: true, writable: true, value: __f11 });
Object.defineProperty(__testConfig_proto, "requireNumber", { configurable: true, writable: true, value: __f12 });
Object.defineProperty(__testConfig_proto, "requireObject", { configurable: true, writable: true, value: __f13 });
Object.defineProperty(__testConfig_proto, "fullKey", { configurable: true, writable: true, value: __f14 });
var __testConfig = Object.create(__testConfig_proto);
__testConfig.name = "test";
function __getConfig() {
return (function() {
with({ config: __config, getConfig: __getConfig }) {
return function /*getConfig*/(k) {
return config[k];
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __0_getProject() {
return (function() {
with({ options: __options, getProject: __0_getProject }) {
return function /*getProject*/() {
return options.project;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __getProject() {
return (function() {
with({ runtime: __runtime, getProject: __getProject }) {
return function /*getProject*/() {
const project = runtime.getProject();
if (project) {
return project;
}
throw new Error("Project unknown; are you using the Pulumi CLI?");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ metadata_1: __metadata_1 }) {
return function /*constructor*/(name) {
if (name === undefined) {
name = metadata_1.getProject();
}
if (name.endsWith(":config")) {
name = name.replace(/:config$/, "");
}
this.name = name;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ runtime_1: __runtime }) {
return function /*get*/(key) {
return runtime_1.getConfig(this.fullKey(key));
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
(...)
function __f0() {
return (function() {
with({ testConfig: __testConfig }) {
return function () { const v = testConfig.get("TestingKey1"); console.log(v); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
runtime.setConfig("test:TestingKey2", "TestingValue2");
cases.push({
title: "Capture config created on the inside",
func: function () { const v = new pulumi.Config("test").get("TestingKey2"); console.log(v); },
expectText: `exports.handler = __f0;
var __options = {project: undefined};
var __config = {["test:TestingKey1"]: "TestingValue1", ["test:TestingKey2"]: "TestingValue2", ["pkg:a"]: "foo", ["pkg:bar"]: "b", ["pkg:baz"]: "baz", ["otherpkg:a"]: "babble", ["otherpkg:nothere"]: "bazzle", ["pkg:boolf"]: "false", ["pkg:boolt"]: "true", ["pkg:num"]: "42.333", ["pkg:array"]: "[ 0, false, 2, \\"foo\\" ]", ["pkg:struct"]: "{ \\"foo\\": \\"bar\\", \\"mim\\": [] }"};
var __runtime = {getProject: __0_getProject, getConfig: __getConfig};
var __metadata_1 = {getProject: __getProject};
var __f1_prototype = {};
Object.defineProperty(__f1_prototype, "constructor", { configurable: true, writable: true, value: __f1 });
Object.defineProperty(__f1_prototype, "get", { configurable: true, writable: true, value: __f2 });
__f5.isInstance = __f6;
(...)
Object.setPrototypeOf(__f4, __f5);
Object.defineProperty(__f1_prototype, "getBoolean", { configurable: true, writable: true, value: __f3 });
Object.defineProperty(__f1_prototype, "getNumber", { configurable: true, writable: true, value: __f7 });
Object.defineProperty(__f1_prototype, "getObject", { configurable: true, writable: true, value: __f8 });
Object.setPrototypeOf(__f10, __f5);
Object.defineProperty(__f1_prototype, "require", { configurable: true, writable: true, value: __f9 });
Object.defineProperty(__f1_prototype, "requireBoolean", { configurable: true, writable: true, value: __f11 });
Object.defineProperty(__f1_prototype, "requireNumber", { configurable: true, writable: true, value: __f12 });
Object.defineProperty(__f1_prototype, "requireObject", { configurable: true, writable: true, value: __f13 });
Object.defineProperty(__f1_prototype, "fullKey", { configurable: true, writable: true, value: __f14 });
__f1.prototype = __f1_prototype;
var __pulumi = {Config: __f1};
function __0_getProject() {
return (function() {
with({ options: __options, getProject: __0_getProject }) {
return function /*getProject*/() {
return options.project;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __getConfig() {
return (function() {
with({ config: __config, getConfig: __getConfig }) {
return function /*getConfig*/(k) {
return config[k];
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __getProject() {
return (function() {
with({ runtime: __runtime, getProject: __getProject }) {
return function /*getProject*/() {
const project = runtime.getProject();
if (project) {
return project;
}
throw new Error("Project unknown; are you using the Pulumi CLI?");
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f1() {
return (function() {
with({ metadata_1: __metadata_1 }) {
return function /*constructor*/(name) {
if (name === undefined) {
name = metadata_1.getProject();
}
if (name.endsWith(":config")) {
name = name.replace(/:config$/, "");
}
this.name = name;
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f2() {
return (function() {
with({ runtime_1: __runtime }) {
return function /*get*/(key) {
return runtime_1.getConfig(this.fullKey(key));
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
(...)
function __f0() {
return (function() {
with({ pulumi: __pulumi }) {
return function () { const v = new pulumi.Config("test").get("TestingKey2"); console.log(v); };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
}
{
cases.push({
title: "Capture factory func #1",
factoryFunc: () => {
const serverlessExpress = require("aws-serverless-express");
const express = require("express");
const app = express();
app.get("/", (req: any, res: any) => {
res.json({ succeeded: true });
});
const server = serverlessExpress.createServer(app);
return (event: any, context: any) => {
serverlessExpress.proxy(server, event, context);
};
},
expectText: `
function __f0() {
return (function() {
with({ }) {
return () => {
const serverlessExpress = require("aws-serverless-express");
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.json({ succeeded: true });
});
const server = serverlessExpress.createServer(app);
return (event, context) => {
serverlessExpress.proxy(server, event, context);
};
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
exports.handler = __f0();`,
});
}
{
const outerVal = [{}];
(<any>outerVal[0]).inner = outerVal;
function foo() {
outerVal.pop();
}
function bar() {
outerVal.join();
}
cases.push({
title: "Capture factory func #2",
factoryFunc: () => {
outerVal.push({});
foo();
return (event: any, context: any) => {
bar();
};
},
expectText: `
var __outerVal = [];
var __outerVal_0 = {};
__outerVal_0.inner = __outerVal;
__outerVal[0] = __outerVal_0;
function __foo() {
return (function() {
with({ outerVal: __outerVal, foo: __foo }) {
return function /*foo*/() {
outerVal.pop();
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __bar() {
return (function() {
with({ outerVal: __outerVal, bar: __bar }) {
return function /*bar*/() {
outerVal.join();
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
function __f0() {
return (function() {
with({ outerVal: __outerVal, foo: __foo, bar: __bar }) {
return () => {
outerVal.push({});
foo();
return (event, context) => {
bar();
};
};
}
}).apply(undefined, undefined).apply(this, arguments);
}
exports.handler = __f0();`,
});
}
cases.push({
title: "Deconstructing function",
// @ts-ignore
func: function f({ whatever }) { },
expectText: `exports.handler = __f;
function __f() {
return (function() {
with({ f: __f }) {
return function /*f*/({ whatever }) { };
}
}).apply(undefined, undefined).apply(this, arguments);
}
`,
});
// Run a bunch of direct checks on async js functions if we're in node 8 or above.
// We can't do this inline as node6 doesn't understand 'async functions'. And we
// can't do this in TS as TS will convert the async-function to be a normal non-async
// function.
const version = Number(process.version.match(/^v(\d+)\.\d+/)![1]);
if (version >= 8) {
const jsCases = require("./jsClosureCases");
cases.push(...jsCases.cases);
}
// Make a callback to keep running tests.
let remaining = cases;
while (true) {
const test = remaining.shift();
if (!test) {
return;
}
// if (test.title !== "Two level static inheritance") {
// continue;
// }
it(test.title, asyncTest(async () => {
// Run pre-actions.
if (test.pre) {
test.pre();
}
// Invoke the test case.
if (test.expectText) {
const sf = await serializeFunction(test);
compareTextWithWildcards(test.expectText, sf.text);
if (test.expectPackages) {
assert.equal(sf.requiredPackages.size, test.expectPackages.size)
for (const p of sf.requiredPackages) {
assert.equal(test.expectPackages.has(p), true);
}
}
}
else {
const message = await assertAsyncThrows(async () => {
await serializeFunction(test);
});
// replace real locations with (0,0) so that our test baselines do not need to
// updated any time this file changes.
const regex = /\([0-9]+,[0-9]+\)/g;
const withoutLocations = message.replace(regex, "(0,0)");
if (test.error) {
compareTextWithWildcards(test.error, withoutLocations);
}
}
}));
// Schedule any additional tests.
if (test.afters) {
remaining = test.afters.concat(remaining);
}
}
async function serializeFunction(test: ClosureCase) {
if (test.func) {
return await runtime.serializeFunction(test.func);
}
else if (test.factoryFunc) {
return await runtime.serializeFunction(test.factoryFunc!, { isFactoryFunction: true });
}
else {
throw new Error("Have to supply [func] or [factoryFunc]!");
}
}
});
/**
* compareErrorText compares an "expected" error string and an "actual" error string
* and issues an error if they do not match.
*
* This function accepts two repetition operators to make writing tests easier against
* error messages that are dependent on the environment:
*
* * (...) alone on a single line causes the matcher to accept zero or more lines
* between the repetition and the next line.
* * (...) within in the context of a line causes the matcher to accept zero or more characters
* between the repetition and the next character.
*
* This is useful when testing error messages that you get when capturing bulit-in modules,
* because the specific error message differs between Node versions.
* @param expected The expected error message string, potentially containing repetitions
* @param actual The actual error message string
*/
function compareTextWithWildcards(expected: string, actual: string) {
const wildcard = "(...)";
if (!expected.includes(wildcard)) {
// We get a nice diff view if we diff the entire string, so do that
// if we didn't get a wildcard.
assert.equal(actual, expected);
return;
}
const expectedLines = expected.split(EOL);
const actualLines = actual.split(EOL);
let actualIndex = 0;
for (let expectedIndex = 0; expectedIndex < expectedLines.length; expectedIndex++) {
const expectedLine = expectedLines[expectedIndex].trim();
if (expectedLine === wildcard) {
if (expectedIndex + 1 === expectedLines.length) {
return;
}
const nextLine = expectedLines[++expectedIndex].trim();
while (true) {
const actualLine = actualLines[actualIndex++].trim();
if (actualLine === nextLine) {
break;
}
if (actualIndex === actualLines.length) {
assert.fail(`repetition failed to find match: expected terminator ${nextLine}, received ${actual}`);
}
}
} else if (expectedLine.includes(wildcard)) {
const line = actualLines[actualIndex++].trim();
const index = expectedLine.indexOf(wildcard);
const indexAfter = index + wildcard.length;
assert.equal(line.substring(0, index), expectedLine.substring(0, index));
if (indexAfter === expectedLine.length) {
continue;
}
let repetitionIndex = index;
for (; repetitionIndex < line.length; repetitionIndex++) {
if (line[repetitionIndex] === expectedLine[indexAfter]) {
break;
}
}
assert.equal(line.substring(repetitionIndex), expectedLine.substring(indexAfter));
} else {
assert.equal(actualLines[actualIndex++].trim(), expectedLine);
}
}
}