var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    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) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    const isNode = typeof window !== "undefined" ? false : true;
    function runTestPromise(args) {
        return __awaiter(this, void 0, void 0, function* () {
            const { testClass, name } = args;
            let t = null;
            try {
                t = new (testClass)();
                yield t.init();
                const r = t[name]();
                if (r) {
                    yield r;
                }
            }
            catch (e) {
                args.error = e.stack ? `${e.message}\r\n${e.stack}` : e.toString();
            }
            finally {
                if (t && t.logText) {
                    args.logText = (args.logText || "") + t.logText;
                }
                try {
                    yield t.dispose();
                }
                catch (ex) {
                    args.error =
                        (args.error || "")
                            + (ex.stack ? (`${ex.message}\r\n${ex.stack}`) : ex.toString());
                }
            }
        });
    }
    function sandbox(args) {
        return __awaiter(this, void 0, void 0, function* () {
            if (isNode) {
                const vm = require("vm");
                const g = {
                    document: null,
                    bridge: {},
                    window: {
                        DI: null,
                        UMD: null,
                        bridge: null
                    },
                    UMD: {
                        resolvePath(v) {
                            return v;
                        }
                    },
                    DI: null,
                    testCase: Object.assign(Object.assign({}, args), { runTestPromise }),
                    CustomEvent: null,
                };
                yield new Promise((resolve, reject) => {
                    g.testCase.resolve = resolve;
                    g.testCase.reject = reject;
                    g.DI = g.UMD;
                    const { JSDOM } = require("jsdom");
                    const dom = new JSDOM(`<!DOCTYPE html><body><p>Hello world</p></body></html>`);
                    g.window = dom.window;
                    g.document = dom.window.document;
                    g.CustomEvent = function CustomEvent(type, p) {
                        const e = document.createEvent("CustomEvent");
                        const pe = p ? Object.assign({}, p) : {};
                        e.initCustomEvent(type, pe.bubble, pe.cancelable, pe.detail);
                        return e;
                    };
                    g.window.DI = g.UMD;
                    g.window.UMD = g.UMD;
                    g.window.bridge = g.bridge;
                    vm.createContext(g);
                    const script = new vm.Script(`
            const t = testCase;
            t.runTestPromise(t).then(t.resolve).catch(t.reject);`);
                    script.runInContext(g);
                });
                args.error = g.testCase.error;
                args.logText = g.testCase.logText;
            }
            else {
                yield runTestPromise(args);
            }
        });
    }
    exports.default = sandbox;
});
//# sourceMappingURL=sandbox.js.map