@eclipse-glsp/server 2.8.0-next.5 → 2.8.0-next.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/lib/common/features/directediting/context-edit-validator.js +3 -3
  2. package/lib/common/features/directediting/context-edit-validator.js.map +1 -1
  3. package/package.json +8 -8
  4. package/src/common/features/directediting/context-edit-validator.ts +2 -2
  5. package/src/browser/di/browser-action-dispatch-scope.spec.ts +0 -75
  6. package/src/common/actions/action-handler-registry.spec.ts +0 -52
  7. package/src/common/actions/global-action-provider.spec.ts +0 -68
  8. package/src/common/command/command-stack.spec.ts +0 -239
  9. package/src/common/command/command.spec.ts +0 -92
  10. package/src/common/command/recording-command.spec.ts +0 -86
  11. package/src/common/di/binding-target.spec.ts +0 -147
  12. package/src/common/di/multi-bindings.spec.ts +0 -133
  13. package/src/common/features/contextactions/context-actions-provider-registry.spec.ts +0 -69
  14. package/src/common/features/contextactions/request-context-actions-handler.spec.ts +0 -75
  15. package/src/common/features/contextactions/tool-palette-item-provider.spec.ts +0 -46
  16. package/src/common/features/directediting/context-edit-validator-registry.spec.ts +0 -54
  17. package/src/common/features/directediting/request-edit-validation-handler.spec.ts +0 -131
  18. package/src/common/features/model/gmodel-serializer.spec.ts +0 -141
  19. package/src/common/features/type-hints/request-type-hints-action-handler.spec.ts +0 -59
  20. package/src/common/operations/operation-handler-registry.spec.ts +0 -50
  21. package/src/common/protocol/glsp-server.spec.ts +0 -154
  22. package/src/common/session/client-session-factory.spec.ts +0 -60
  23. package/src/common/session/client-session-manager.spec.ts +0 -83
  24. package/src/common/test/mock-util.ts +0 -281
  25. package/src/common/utils/action-queue.spec.ts +0 -133
  26. package/src/common/utils/promise-queue.spec.ts +0 -142
  27. package/src/common/utils/registry.spec.ts +0 -225
  28. package/src/node/actions/action-dispatcher.spec.ts +0 -678
  29. package/src/node/launch/cli-parser.spec.ts +0 -61
  30. package/src/node/launch/socket-cli-parser.spec.ts +0 -73
  31. package/src/node/launch/socket-server-launcher.spec.ts +0 -74
@@ -1,83 +0,0 @@
1
- /********************************************************************************
2
- * Copyright (c) 2022-2023 STMicroelectronics and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
- import { expect } from 'chai';
17
- import { Container, ContainerModule } from 'inversify';
18
- import * as sinon from 'sinon';
19
- import * as mock from '../test/mock-util';
20
- import { Logger } from '../utils/logger';
21
- import { ClientSessionFactory } from './client-session-factory';
22
- import { DefaultClientSessionManager } from './client-session-manager';
23
-
24
- describe('test DefaultClientSessionManager', () => {
25
- const testSession = mock.createClientSession('myId', 'myDiagram');
26
- const testSessionListener = new mock.StubClientSessionListener();
27
-
28
- const sessionFactory = new mock.StubClientSessionFactory();
29
- sinon.stub(sessionFactory, 'create').returns(testSession);
30
-
31
- const container = new Container();
32
- container.load(
33
- new ContainerModule(bind => {
34
- bind(Logger).toConstantValue(new mock.StubLogger());
35
- bind(ClientSessionFactory).toConstantValue(sessionFactory);
36
- })
37
- );
38
- const sessionManager = container.resolve(DefaultClientSessionManager);
39
-
40
- it('add listener', () => {
41
- expect(sessionManager.addListener(testSessionListener, testSession.id)).true;
42
- });
43
-
44
- it('add create client session', () => {
45
- // Mock setup
46
- const listener_create = sinon.spy(testSessionListener, 'sessionCreated');
47
- // Test execution
48
- const createdSession = sessionManager.getOrCreateClientSession({
49
- clientSessionId: testSession.id,
50
- diagramType: testSession.diagramType,
51
- clientActionKinds: []
52
- });
53
- expect(createdSession).to.not.be.undefined;
54
- expect(createdSession.id).to.be.equal(testSession.id);
55
- expect(createdSession.diagramType).to.be.equal(testSession.diagramType);
56
-
57
- const retrievedSession = sessionManager.getSession(testSession.id);
58
- expect(retrievedSession).to.not.be.undefined;
59
- expect(retrievedSession).to.be.equal(createdSession);
60
- expect(listener_create.calledWith(testSession));
61
- });
62
-
63
- it('get sessions by type', () => {
64
- const clientSessions = sessionManager.getSessionsByType(testSession.diagramType);
65
- expect(clientSessions.length).to.be.equal(1);
66
- expect(clientSessions[0]).to.be.equal(testSession);
67
- });
68
-
69
- it('get sessions by type that does no exist', async () => {
70
- const clientSessions = sessionManager.getSessionsByType('wrongType');
71
- expect(clientSessions.length).to.be.equal(0);
72
- });
73
-
74
- it('dispose client session', () => {
75
- // Mock setup
76
- const listener_dispose = sinon.spy(testSessionListener, 'sessionDisposed');
77
- // Test execution
78
- expect(sessionManager.disposeClientSession(testSession.id)).to.be.equal(true);
79
- const session = sessionManager.getSession(testSession.id);
80
- expect(session).to.be.undefined;
81
- expect(listener_dispose.calledWith(testSession));
82
- });
83
- });
@@ -1,281 +0,0 @@
1
- /********************************************************************************
2
- * Copyright (c) 2022-2026 STMicroelectronics and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
-
17
- // Stub-implementation classes used for unit testing
18
-
19
- import { GEdge, GModelElement, GModelElementConstructor, GNode } from '@eclipse-glsp/graph';
20
- import {
21
- Action,
22
- ActionMessage,
23
- Args,
24
- CreateNodeOperation,
25
- EdgeTypeHint,
26
- GLSPClientProxy,
27
- GLSPServer,
28
- GLSPServerListener,
29
- InitializeClientSessionParameters,
30
- MaybeArray,
31
- MaybePromise,
32
- Point,
33
- RequestAction,
34
- RequestEditValidationAction,
35
- ResponseAction,
36
- ShapeTypeHint,
37
- ValidationStatus
38
- } from '@eclipse-glsp/protocol';
39
- import { expect } from 'chai';
40
- import { Container } from 'inversify';
41
- import { MessageConnection } from 'vscode-jsonrpc';
42
- import { ActionDispatcher } from '../actions/action-dispatcher';
43
- import { ActionHandler, ActionHandlerFactory } from '../actions/action-handler';
44
- import { Command } from '../command/command';
45
- import { DiagramConfiguration, ServerLayoutKind } from '../diagram/diagram-configuration';
46
- import { ContextEditValidator } from '../features/directediting/context-edit-validator';
47
- import { LabelEditValidator } from '../features/directediting/label-edit-validator';
48
- import { GModelCreateEdgeOperationHandler } from '../gmodel/gmodel-create-edge-operation-handler';
49
- import { GModelCreateNodeOperationHandler } from '../gmodel/gmodel-create-node-operation-handler';
50
- import { ClientSession } from '../session/client-session';
51
- import { ClientSessionFactory } from '../session/client-session-factory';
52
- import { ClientSessionInitializer } from '../session/client-session-initializer';
53
- import { ClientSessionListener } from '../session/client-session-listener';
54
- import { ClientSessionManager } from '../session/client-session-manager';
55
- import { LogLevel, Logger } from '../utils/logger';
56
-
57
- export async function delay(ms: number): Promise<void> {
58
- return new Promise(resolve => setTimeout(resolve, ms));
59
- }
60
-
61
- /**
62
- * Consumes a maybe async function and checks for error
63
- * @param method - The function to check
64
- * @param message - Optional message to match with error message
65
- */
66
- export async function expectToThrowAsync(toEvaluate: () => MaybePromise<void>, message?: string): Promise<void> {
67
- let err: Error | undefined = undefined;
68
- try {
69
- await toEvaluate();
70
- } catch (error: any) {
71
- err = error;
72
- }
73
- if (message) {
74
- expect(err?.message).to.be.equal(message);
75
- } else {
76
- expect(err).to.be.an('Error');
77
- }
78
- }
79
-
80
- export function createClientSession(
81
- id: string,
82
- diagramType: string,
83
- container = new Container(),
84
- actionDispatcher = new StubActionDispatcher()
85
- ): ClientSession {
86
- return {
87
- id,
88
- diagramType,
89
- container,
90
- actionDispatcher,
91
- dispose: () => {
92
- //
93
- }
94
- };
95
- }
96
-
97
- export class StubActionHandler implements ActionHandler {
98
- constructor(public actionKinds: string[]) {}
99
-
100
- execute(action: Action): MaybePromise<Action[]> {
101
- return [];
102
- }
103
- }
104
-
105
- export class StubCreateNodeOperationHandler extends GModelCreateNodeOperationHandler {
106
- elementTypeIds: string[];
107
-
108
- constructor(readonly label: string) {
109
- super();
110
- this.elementTypeIds = [label];
111
- }
112
-
113
- createNode(operation: CreateNodeOperation, relativeLocation?: Point): GNode | undefined {
114
- return new GNode();
115
- }
116
- }
117
-
118
- export class StubCreateEdgeOperationHandler extends GModelCreateEdgeOperationHandler {
119
- elementTypeIds: string[];
120
-
121
- constructor(readonly label: string) {
122
- super();
123
- this.elementTypeIds = [label];
124
- }
125
-
126
- createEdge(source: GModelElement, target: GModelElement): GEdge | undefined {
127
- return undefined;
128
- }
129
- }
130
-
131
- export class StubActionDispatcher implements ActionDispatcher {
132
- dispatchAfterNextUpdate(...actions: MaybeArray<Action[]>): void {}
133
-
134
- dispatch(action: Action): Promise<void> {
135
- return Promise.resolve();
136
- }
137
-
138
- dispatchAll(...actions: MaybeArray<Action>[]): Promise<void> {
139
- return Promise.resolve();
140
- }
141
-
142
- request<Res extends ResponseAction>(action: RequestAction<Res>): Promise<Res> {
143
- return Promise.reject(new Error('Not implemented in stub'));
144
- }
145
-
146
- requestUntil<Res extends ResponseAction>(
147
- action: RequestAction<Res>,
148
- timeoutMs?: number,
149
- rejectOnTimeout?: boolean
150
- ): Promise<Res | undefined> {
151
- return Promise.reject(new Error('Not implemented in stub'));
152
- }
153
- }
154
-
155
- export class StubClientSessionFactory implements ClientSessionFactory {
156
- create(params: InitializeClientSessionParameters): ClientSession {
157
- const { clientSessionId, diagramType } = params;
158
- return createClientSession(clientSessionId, diagramType);
159
- }
160
- }
161
-
162
- export class StubClientSessionManager implements ClientSessionManager {
163
- getOrCreateClientSession(params: InitializeClientSessionParameters): ClientSession {
164
- const { clientSessionId, diagramType } = params;
165
- return createClientSession(clientSessionId, diagramType);
166
- }
167
-
168
- getSession(clientSessionId: string): ClientSession | undefined {
169
- return undefined;
170
- }
171
-
172
- getSessions(): ClientSession[] {
173
- return [];
174
- }
175
-
176
- getSessionsByType(diagramType: string): ClientSession[] {
177
- return [];
178
- }
179
-
180
- disposeClientSession(clientSessionId: string): boolean {
181
- return true;
182
- }
183
-
184
- addListener(listener: ClientSessionListener, ...clientSessionIds: string[]): boolean {
185
- return true;
186
- }
187
-
188
- removeListener(listener: ClientSessionListener): boolean {
189
- return true;
190
- }
191
-
192
- removeListeners(...clientSessionIds: string[]): void {
193
- return undefined;
194
- }
195
- }
196
-
197
- export class StubLogger extends Logger {
198
- logLevel = LogLevel.none;
199
- caller = undefined;
200
-
201
- info(message: string, ...params: any[]): void {}
202
-
203
- warn(message: string, ...params: any[]): void {}
204
-
205
- error(message: string, ...params: any[]): void {}
206
-
207
- debug(message: string, ...params: any[]): void {}
208
- }
209
-
210
- export class StubClientSessionListener implements ClientSessionListener {
211
- sessionCreated(clientSession: ClientSession): void {}
212
-
213
- sessionDisposed(clientSession: ClientSession): void {}
214
- }
215
-
216
- export class StubGLSPClientProxy implements GLSPClientProxy {
217
- connect(connection: MessageConnection): void {}
218
-
219
- process(message: ActionMessage<Action>): void {}
220
- }
221
-
222
- export class StubGLSPServerListener implements GLSPServerListener {
223
- serverInitialized(server: GLSPServer): void {}
224
-
225
- serverShutDown(server: GLSPServer): void {}
226
- }
227
-
228
- export class StubDiagramConfiguration implements DiagramConfiguration {
229
- typeMapping = new Map<string, GModelElementConstructor>();
230
-
231
- shapeTypeHints: ShapeTypeHint[] = [];
232
-
233
- edgeTypeHints: EdgeTypeHint[] = [];
234
-
235
- layoutKind = ServerLayoutKind.NONE;
236
-
237
- needsClientLayout = true;
238
-
239
- animatedUpdate = true;
240
- }
241
-
242
- export class TestLabelEditValidator extends LabelEditValidator {
243
- validate(label: string, element: GModelElement): ValidationStatus {
244
- if (label === 'error') {
245
- return { severity: ValidationStatus.Severity.ERROR, message: 'error' };
246
- }
247
- if (label === 'warning') {
248
- return { severity: ValidationStatus.Severity.WARNING, message: 'warning' };
249
- }
250
- return { severity: ValidationStatus.Severity.OK, message: 'ok' };
251
- }
252
- }
253
-
254
- export class TestContextEditValidator implements ContextEditValidator {
255
- get contextId(): string {
256
- return 'test';
257
- }
258
-
259
- validate(action: RequestEditValidationAction): ValidationStatus {
260
- if (action.text === 'error') {
261
- return { severity: ValidationStatus.Severity.ERROR, message: 'error' };
262
- }
263
- if (action.text === 'warning') {
264
- return { severity: ValidationStatus.Severity.WARNING, message: 'warning' };
265
- }
266
- return { severity: ValidationStatus.Severity.OK, message: 'ok' };
267
- }
268
- }
269
-
270
- export const stubActionHandlerFactory: ActionHandlerFactory = constructor => new constructor();
271
-
272
- export class StubClientSessionInitializer implements ClientSessionInitializer {
273
- initialize(args?: Args): void {}
274
- }
275
-
276
- export class StubCommand implements Command {
277
- execute(): void {}
278
- undo(): void {}
279
- redo(): void {}
280
- canUndo?(): boolean;
281
- }
@@ -1,133 +0,0 @@
1
- /********************************************************************************
2
- * Copyright (c) 2026 EclipseSource and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
- import { expect } from 'chai';
17
- import { expectToThrowAsync } from '../test/mock-util';
18
- import { ActionQueue } from './action-queue';
19
-
20
- describe('ActionQueue', () => {
21
- it('yields pushed items in FIFO order', async () => {
22
- const channel = new ActionQueue<number>();
23
- const consumed: number[] = [];
24
-
25
- const consumer = (async (): Promise<void> => {
26
- for await (const entry of channel.consume()) {
27
- consumed.push(entry.item);
28
- entry.resolve();
29
- }
30
- })();
31
-
32
- await Promise.all([channel.push(1), channel.push(2), channel.push(3)]);
33
- channel.stop();
34
- await consumer;
35
-
36
- expect(consumed).to.deep.equal([1, 2, 3]);
37
- });
38
-
39
- it('resolves the push promise once the consumer resolves the entry', async () => {
40
- const channel = new ActionQueue<string>();
41
- let entryResolver: (() => void) | undefined;
42
-
43
- const consumer = (async (): Promise<void> => {
44
- for await (const entry of channel.consume()) {
45
- entryResolver = entry.resolve;
46
- return;
47
- }
48
- })();
49
-
50
- const pushed = channel.push('a');
51
- // Give the consumer a turn to pick up the entry.
52
- await Promise.resolve();
53
- await consumer;
54
- expect(entryResolver).to.exist;
55
- entryResolver!();
56
- await pushed;
57
- });
58
-
59
- it('propagates reject() from the consumer back to the pushing caller', async () => {
60
- const channel = new ActionQueue<number>();
61
-
62
- const consumer = (async (): Promise<void> => {
63
- for await (const entry of channel.consume()) {
64
- entry.reject(new Error('boom'));
65
- return;
66
- }
67
- })();
68
-
69
- const pushed = channel.push(1);
70
- await consumer;
71
- await expectToThrowAsync(() => pushed, 'boom');
72
- });
73
-
74
- it('rejects push() after stop()', async () => {
75
- const channel = new ActionQueue<number>();
76
- channel.stop();
77
- await expectToThrowAsync(() => channel.push(1), 'ActionQueue is stopped');
78
- });
79
-
80
- it('consumer exits after stop() and drain', async () => {
81
- const channel = new ActionQueue<number>();
82
- const consumed: number[] = [];
83
-
84
- const consumer = (async (): Promise<void> => {
85
- for await (const entry of channel.consume()) {
86
- consumed.push(entry.item);
87
- entry.resolve();
88
- }
89
- })();
90
-
91
- await channel.push(1);
92
- await channel.push(2);
93
- channel.stop();
94
- await consumer;
95
-
96
- expect(consumed).to.deep.equal([1, 2]);
97
- expect(channel.isStopped).to.be.true;
98
- });
99
-
100
- it('rejectPending() rejects all queued push() promises without stopping', async () => {
101
- const channel = new ActionQueue<number>();
102
- const pushes = [channel.push(1), channel.push(2)];
103
- expect(channel.size).to.equal(2);
104
-
105
- channel.rejectPending(new Error('cleared'));
106
-
107
- await expectToThrowAsync(() => pushes[0], 'cleared');
108
- await expectToThrowAsync(() => pushes[1], 'cleared');
109
- expect(channel.size).to.equal(0);
110
- expect(channel.isStopped).to.be.false;
111
- });
112
-
113
- it('size reflects the number of unconsumed entries', async () => {
114
- const channel = new ActionQueue<number>();
115
- channel.push(1);
116
- channel.push(2);
117
- channel.push(3);
118
- expect(channel.size).to.equal(3);
119
- });
120
-
121
- it('throws when a second consumer is started', async () => {
122
- const channel = new ActionQueue<number>();
123
- const first = channel.consume();
124
- // Kick off the first consumer so it registers as the active consumer.
125
- const firstStep = first.next();
126
-
127
- const second = channel.consume();
128
- await expectToThrowAsync(() => second.next().then(() => undefined), 'ActionQueue supports only a single consumer');
129
-
130
- channel.stop();
131
- await firstStep;
132
- });
133
- });
@@ -1,142 +0,0 @@
1
- /********************************************************************************
2
- * Copyright (c) 2022-2026 STMicroelectronics and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
- import { delay } from '../test/mock-util';
17
-
18
- import { expect } from 'chai';
19
- // eslint-disable-next-line import-x/no-deprecated
20
- import { PromiseQueue } from './promise-queue';
21
-
22
- // Helper types and functions that are needed for test setup
23
-
24
- /**
25
- * Helper class to inspect the state of promise during its resolve() execution.
26
- */
27
- class PromiseState {
28
- private _started = false;
29
- private _stopped = false;
30
- onStartRunnable?: () => void;
31
- onStopRunnable?: () => void;
32
-
33
- start(): void {
34
- this._started = true;
35
- if (this.onStartRunnable) {
36
- this.onStartRunnable();
37
- }
38
- }
39
-
40
- stop(): void {
41
- this._stopped = true;
42
- if (this.onStopRunnable) {
43
- this.onStopRunnable();
44
- }
45
- }
46
-
47
- onStart(runnable: () => void): void {
48
- this.onStartRunnable = runnable;
49
- }
50
-
51
- onStop(runnable: () => void): void {
52
- this.onStopRunnable = runnable;
53
- }
54
-
55
- get started(): boolean {
56
- return this._started;
57
- }
58
-
59
- get stopped(): boolean {
60
- return this._stopped;
61
- }
62
- }
63
-
64
- interface TestPromise {
65
- state: PromiseState;
66
- promise: () => Promise<void>;
67
- }
68
-
69
- function newTestPromise(resolveTime: number): TestPromise {
70
- const state = new PromiseState();
71
- const promise = async (): Promise<void> => {
72
- state.start();
73
- await delay(resolveTime);
74
- state.stop();
75
- };
76
- return { state, promise };
77
- }
78
-
79
- // eslint-disable-next-line @typescript-eslint/no-deprecated, import-x/no-deprecated
80
- let queue = new PromiseQueue();
81
-
82
- // Test execution
83
- describe('test PromiseQueue', () => {
84
- beforeEach(() => {
85
- // eslint-disable-next-line import-x/no-deprecated, @typescript-eslint/no-deprecated
86
- queue = new PromiseQueue();
87
- });
88
- it('enqueue - one element', async () => {
89
- const { state, promise } = newTestPromise(100);
90
- state.onStart(() => {
91
- expect(queue.isBusy).true;
92
- });
93
- const queEnd = queue.enqueue(promise);
94
- expect(queue.isEmpty).true;
95
- await queEnd;
96
- });
97
-
98
- it('enqueue - two elements', async () => {
99
- const p1 = newTestPromise(100);
100
- p1.state.onStop(() => expect(p2.state.started).false);
101
-
102
- const p2 = newTestPromise(100);
103
-
104
- p2.state.onStart(() => {
105
- expect(queue.isEmpty).true;
106
- expect(p1.state.stopped).true;
107
- });
108
-
109
- queue.enqueue(p1.promise);
110
- const queEnd = queue.enqueue(p2.promise);
111
- expect(queue.size).to.be.equal(1);
112
- await queEnd;
113
- });
114
-
115
- it('enqueue - three elements (first promise in queue has longest resolve time)', async () => {
116
- const p1 = newTestPromise(300);
117
- p1.state.onStop(() => {
118
- expect(p2.state.started).false;
119
- expect(p3.state.started).false;
120
- });
121
-
122
- const p2 = newTestPromise(200);
123
- p2.state.onStart(() => {
124
- expect(queue.size).to.be.equal(1);
125
- expect(p1.state.stopped).true;
126
- expect(p3.state.started).false;
127
- });
128
-
129
- const p3 = newTestPromise(100);
130
- p3.state.onStart(() => {
131
- expect(queue.isEmpty).true;
132
- expect(p2.state.stopped).true;
133
- });
134
-
135
- queue.enqueue(p1.promise);
136
- queue.enqueue(p2.promise);
137
- expect(queue.size).to.be.equal(1);
138
- const queueEnd = queue.enqueue(p3.promise);
139
- expect(queue.size).to.be.equal(2);
140
- await queueEnd;
141
- });
142
- });