import { createDeferredPromise, } from "alcalzone-shared/deferred-promise";
import { setTimer } from "./Timers.js";
/** Allows waiting for something for a given amount of time, after which the expectation will automatically be rejected. */
export class TimedExpectation {
    constructor(timeoutMs, predicate, timeoutErrorMessage = "Expectation was not fulfilled within the timeout", preventDefault = false) {
        this.promise = createDeferredPromise();
        this.timeout = setTimer(() => this.reject(), timeoutMs);
        this.timeoutErrorMessage = timeoutErrorMessage;
        this.predicate = predicate;
        this.preventDefault = preventDefault;
        // We need create the stack on a temporary object or the Error
        // class will try to print the message
        const tmp = { message: "" };
        Error.captureStackTrace(tmp, TimedExpectation);
        this.stack = tmp.stack.replace(/^Error:?\s*\n/, "");
    }
    promise;
    timeout;
    _done = false;
    timeoutErrorMessage;
    predicate;
    preventDefault;
    /** The stack trace where the timed expectation was created */
    stack;
    resolve(result) {
        if (this._done)
            return;
        this.timeout?.clear();
        this.promise.resolve(result);
    }
    reject() {
        if (this._done)
            return;
        this.timeout?.clear();
        const err = new Error(this.timeoutErrorMessage);
        err.stack = this.stack;
        this.promise.reject(err);
    }
    // Make this await-able
    // oxlint-disable-next-line no-thenable
    then(onfulfilled, onrejected) {
        return this.promise.then(onfulfilled, onrejected);
    }
}
//# sourceMappingURL=TimedExpectation.js.map