@eclipse-emfcloud/model-service-theia
Version:
Model service Theia
202 lines • 10.8 kB
JavaScript
;
// *****************************************************************************
// Copyright (C) 2024 STMicroelectronics.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: MIT License which is
// available at https://opensource.org/licenses/MIT.
//
// SPDX-License-Identifier: EPL-2.0 OR MIT
// *****************************************************************************
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = __importStar(require("chai"));
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
const sinon_1 = __importDefault(require("sinon"));
const sinon_chai_1 = __importDefault(require("sinon-chai"));
const promise_util_1 = require("@theia/core/lib/common/promise-util");
const promise_util_2 = require("../promise-util");
chai_1.default.use(sinon_chai_1.default);
chai_1.default.use(chai_as_promised_1.default);
describe('timeout', async () => {
it('completes in time', async () => {
const wrapped = (0, promise_util_1.delay)(1)(42);
const promise = (0, promise_util_2.timeout)(wrapped);
await (0, chai_1.expect)(promise).eventually.to.equal(42);
});
it('times out', async () => {
const wrapped = (0, promise_util_1.delay)(5000)(42);
const promise = (0, promise_util_2.timeout)(wrapped, 25);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('Promise timed out.');
});
it('propagates failure', async () => {
const wrapped = Promise.reject(new Error('as intended'));
const promise = (0, promise_util_2.timeout)(wrapped);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('as intended');
});
it('short-cuts immediate timeouts', async () => {
const promise = (0, promise_util_2.timeout)((0, promise_util_1.delay)(1)(42), 0);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('Promise timed out.');
});
describe('call-backs', () => {
it('completes in time', async () => {
const cb = sinon_1.default.stub();
const wrapped = (0, promise_util_1.delay)(1)(42);
const promise = (0, promise_util_2.timeout)(wrapped, 1000, cb);
await (0, chai_1.expect)(promise).eventually.to.be.fulfilled;
(0, chai_1.expect)(cb).to.have.been.calledWith(42);
});
it('times out', async () => {
const cb = sinon_1.default.stub();
const wrapped = (0, promise_util_1.delay)(5000)(42);
const promise = (0, promise_util_2.timeout)(wrapped, 25, cb);
await (0, chai_1.expect)(promise).eventually.to.be.rejected;
(0, chai_1.expect)(cb).to.have.been.calledWith('timeout');
});
it('propagates failure', async () => {
const cb = sinon_1.default.stub();
const wrapped = Promise.reject(new Error('as intended'));
const promise = (0, promise_util_2.timeout)(wrapped, 1000, cb);
await (0, chai_1.expect)(promise).eventually.to.be.rejected;
(0, chai_1.expect)(cb).to.have.been.calledWithMatch({ message: 'as intended' });
});
it('timeout message', async () => {
const cb = sinon_1.default.stub().returns('custom message');
const wrapped = (0, promise_util_1.delay)(5000)(42);
const promise = (0, promise_util_2.timeout)(wrapped, 25, cb);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('custom message');
});
it('short-cuts immediate timeouts', async () => {
const cb = sinon_1.default.stub().returns('custom message');
const promise = (0, promise_util_2.timeout)((0, promise_util_1.delay)(1)(42), -100, cb);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('custom message');
(0, chai_1.expect)(cb).to.have.been.calledWith('timeout');
});
});
});
describe('retryUntilFulfilled', async () => {
it('succeeds on first try', async () => {
const wrapped = (0, promise_util_1.delay)(1)(42);
const promise = (0, promise_util_2.retryUntilFulfilled)(() => wrapped);
await (0, chai_1.expect)(promise).eventually.to.equal(42);
});
it('succeeds on second first try', async () => {
const stub = sinon_1.default
.stub()
.onFirstCall()
.callsFake(() => Promise.reject(new Error('Boom!')))
.callsFake(() => (0, promise_util_1.delay)(1)(42));
const promise = (0, promise_util_2.retryUntilFulfilled)(stub);
await (0, chai_1.expect)(promise).eventually.to.equal(42);
});
describe('with explicit timeout', () => {
it('succeeds on first try', async () => {
const wrapped = (0, promise_util_1.delay)(1)(42);
const promise = (0, promise_util_2.retryUntilFulfilled)(() => (0, promise_util_2.timeout)(wrapped, 100));
await (0, chai_1.expect)(promise).eventually.to.equal(42);
});
it('succeeds on second first try', async () => {
const stub = sinon_1.default
.stub()
.onFirstCall()
.callsFake(() => Promise.reject(new Error('Boom!')))
.callsFake(() => (0, promise_util_1.delay)(1)(42));
const promise = (0, promise_util_2.retryUntilFulfilled)(() => (0, promise_util_2.timeout)(stub(), 100));
await (0, chai_1.expect)(promise).eventually.to.equal(42);
});
it('times out', async () => {
const wrapped = (0, promise_util_1.delay)(5000)(42);
const promise = (0, promise_util_2.retryUntilFulfilled)(() => (0, promise_util_2.timeout)(wrapped, 75));
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('Promise timed out.');
});
it('times out with call-back', async () => {
const cb = sinon_1.default.stub().returns('custom message');
const wrapped = (0, promise_util_1.delay)(5000)(42);
const promise = (0, promise_util_2.retryUntilFulfilled)(() => (0, promise_util_2.timeout)(wrapped, 75, cb));
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('custom message');
(0, chai_1.expect)(cb).to.have.been.calledWith('timeout');
});
it('propagates failure', async () => {
const wrapped = Promise.reject(new Error('as intended'));
const promise = (0, promise_util_2.retryUntilFulfilled)(() => (0, promise_util_2.timeout)(wrapped, 75));
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('as intended');
});
it('short-cuts settled promises', async () => {
const wrapped = (0, promise_util_2.timeout)((0, promise_util_1.delay)(1)(42), 100);
await wrapped;
const promise = (0, promise_util_2.retryUntilFulfilled)(() => wrapped);
await (0, chai_1.expect)(promise).eventually.to.equal(42);
});
it('short-cuts settled promises with call-back', async () => {
const cb = sinon_1.default.stub();
const wrapped = (0, promise_util_2.timeout)((0, promise_util_1.delay)(1)(42), 100, cb);
await wrapped;
const promise = (0, promise_util_2.retryUntilFulfilled)(() => wrapped);
await (0, chai_1.expect)(promise).eventually.to.equal(42);
(0, chai_1.expect)(cb).to.have.been.calledWith(42);
});
it('unwraps a failed retry', async () => {
const failed = (0, promise_util_2.timeout)(''.length === 0
? Promise.reject(new Error('Boom!'))
: Promise.resolve(), 15);
const stub = sinon_1.default
.stub()
.onFirstCall()
.callsFake(() => (0, promise_util_2.timeout)(Promise.reject(new Error('Boom!')), 75))
.callsFake(() => failed);
const promise = (0, promise_util_2.retryUntilFulfilled)(stub);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('Boom!');
});
it('unwraps a timed-out retry', async () => {
const timedOut = (0, promise_util_2.timeout)((0, promise_util_1.delay)(75)(42), 15);
const stub = sinon_1.default
.stub()
.onFirstCall()
.callsFake(() => (0, promise_util_2.timeout)(Promise.reject(new Error('Boom!')), 75))
.callsFake(() => timedOut);
const promise = (0, promise_util_2.retryUntilFulfilled)(stub);
await (0, chai_1.expect)(promise).eventually.to.be.rejectedWith('Boom!');
});
it('unwraps a completed retry', async () => {
const completed = (0, promise_util_2.timeout)((0, promise_util_1.delay)(15)(42), 15);
const stub = sinon_1.default
.stub()
.onFirstCall()
.callsFake(() => (0, promise_util_2.timeout)(Promise.reject(new Error('Boom!')), 75))
.callsFake(() => completed);
const promise = (0, promise_util_2.retryUntilFulfilled)(stub);
await (0, chai_1.expect)(promise).eventually.to.be.equal(42);
});
});
});
//# sourceMappingURL=promise-util.spec.js.map