define(["require", "exports", "bluejax", "chai"], function (require, exports, bluejax_1, chai_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    function delay(timeout) {
        return new Promise((resolve) => setTimeout(resolve, timeout));
    }
    exports.delay = delay;
    function waitFor(fn, pollDelay = 100, timeout) {
        const start = Date.now();
        function check() {
            const ret = fn();
            if (ret) {
                return ret;
            }
            if ((timeout !== undefined) && (Date.now() - start > timeout)) {
                return false;
            }
            return delay(pollDelay).then(check);
        }
        // TypeScript does not like Promise.resolve(check).
        return Promise.resolve().then(check);
    }
    exports.waitFor = waitFor;
    function waitForSuccess(fn, pollDelay, timeout) {
        return waitFor(() => {
            try {
                fn();
                return true;
            }
            catch (e) {
                if (e instanceof chai_1.AssertionError) {
                    return false;
                }
                throw e;
            }
        }, pollDelay, timeout).then(() => undefined);
    }
    exports.waitForSuccess = waitForSuccess;
    // tslint:disable-next-line:completed-docs
    class DataProvider {
        constructor(base) {
            this.base = base;
            this.cache = Object.create(null);
            this.parser = new DOMParser();
            this.registered = Object.create(null);
        }
        register(name, path) {
            this.registered[name] = path;
        }
        getNamed(name) {
            const path = this.registered[name];
            return this.getText(path);
        }
        getNamedDoc(name) {
            const path = this.registered[name];
            return this.getDoc(path);
        }
        getText(path) {
            return this._getText(this.base + path);
        }
        _getText(path) {
            return Promise.resolve().then(() => {
                const cached = this.cache[path];
                if (cached !== undefined) {
                    return cached;
                }
                return bluejax_1.ajax({ url: path, dataType: "text" })
                    .then((data) => {
                    this.cache[path] = data;
                    return data;
                });
            });
        }
        getDoc(path) {
            return this._getText(this.base + path).then((data) => {
                return this.parser.parseFromString(data, "text/xml");
            });
        }
    }
    exports.DataProvider = DataProvider;
    function expectError(fn, errorLike, pattern) {
        return fn().then(() => {
            throw new Error("should have thrown an error");
        }, 
        // tslint:disable-next-line:no-any
        (ex) => {
            if (!(errorLike instanceof RegExp || typeof errorLike === "string")) {
                chai_1.expect(ex).to.be.instanceof(errorLike);
            }
            else {
                pattern = errorLike;
            }
            if (pattern instanceof RegExp) {
                chai_1.expect(ex).to.have.property("message").match(pattern);
            }
            else {
                chai_1.expect(ex).to.have.property("message").equal(pattern);
            }
        });
    }
    exports.expectError = expectError;
    // tslint:disable-next-line:no-any
    function makeFakePasteEvent(clipboardData) {
        const event = new $.Event("paste");
        event.originalEvent = {
            clipboardData,
            // tslint:disable-next-line:no-empty
            stopImmediatePropagation: () => { },
            // tslint:disable-next-line:no-empty
            preventDefault: () => { },
            // tslint:disable-next-line:no-empty
            stopPropagation: () => { },
        };
        return event;
    }
    exports.makeFakePasteEvent = makeFakePasteEvent;
});
//# sourceMappingURL=util.js.map