This change adopts the code review suggestion to use a bag of options for config constraints rather than having overloaded function names. This is a much cleaner approach, lets us use more descriptive names, and is far more future proof in case we decide to add more capabilities.
5255 lines
122 KiB
TypeScript
5255 lines
122 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\\": [] }", ["pkg:color"]: "orange", ["pkg:strlen"]: "abcdefgh", ["pkg:pattern"]: "aBcDeFgH", ["pkg:quantity"]: "8"};
|
|
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, "fullKey", { configurable: true, writable: true, value: __f17 });
|
|
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 __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\\": [] }", ["pkg:color"]: "orange", ["pkg:strlen"]: "abcdefgh", ["pkg:pattern"]: "aBcDeFgH", ["pkg:quantity"]: "8"};
|
|
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, "fullKey", { configurable: true, writable: true, value: __f17 });
|
|
__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 __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();`,
|
|
});
|
|
}
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
}
|