@eclipse-glsp/server 2.8.0-next.0 → 2.8.0-next.10

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 (132) hide show
  1. package/lib/browser/launch/worker-server-launcher.js +3 -5
  2. package/lib/browser/launch/worker-server-launcher.js.map +1 -1
  3. package/lib/common/actions/action-dispatcher.js +5 -8
  4. package/lib/common/actions/action-dispatcher.js.map +1 -1
  5. package/lib/common/actions/action-handler-registry.js +1 -1
  6. package/lib/common/actions/action-handler-registry.js.map +1 -1
  7. package/lib/common/actions/global-action-provider.js +1 -2
  8. package/lib/common/actions/global-action-provider.js.map +1 -1
  9. package/lib/common/command/command.js +1 -2
  10. package/lib/common/command/command.js.map +1 -1
  11. package/lib/common/command/recording-command.js +3 -6
  12. package/lib/common/command/recording-command.js.map +1 -1
  13. package/lib/common/di/diagram-module.js +5 -6
  14. package/lib/common/di/diagram-module.js.map +1 -1
  15. package/lib/common/di/glsp-module.js +1 -1
  16. package/lib/common/di/glsp-module.js.map +1 -1
  17. package/lib/common/di/server-module.js +1 -1
  18. package/lib/common/di/server-module.js.map +1 -1
  19. package/lib/common/features/directediting/context-edit-validator.js +3 -3
  20. package/lib/common/features/directediting/context-edit-validator.js.map +1 -1
  21. package/lib/common/features/directediting/label-edit-validator.js +1 -1
  22. package/lib/common/features/directediting/label-edit-validator.js.map +1 -1
  23. package/lib/common/features/layout/computed-bounds-action-handler.d.ts +16 -1
  24. package/lib/common/features/layout/computed-bounds-action-handler.d.ts.map +1 -1
  25. package/lib/common/features/layout/computed-bounds-action-handler.js +41 -4
  26. package/lib/common/features/layout/computed-bounds-action-handler.js.map +1 -1
  27. package/lib/common/features/layout/layout-operation-handler.js +1 -2
  28. package/lib/common/features/layout/layout-operation-handler.js.map +1 -1
  29. package/lib/common/features/model/gmodel-index.js +3 -5
  30. package/lib/common/features/model/gmodel-index.js.map +1 -1
  31. package/lib/common/features/model/gmodel-serializer.js +1 -2
  32. package/lib/common/features/model/gmodel-serializer.js.map +1 -1
  33. package/lib/common/features/model/model-submission-handler.d.ts +1 -2
  34. package/lib/common/features/model/model-submission-handler.d.ts.map +1 -1
  35. package/lib/common/features/model/model-submission-handler.js +3 -6
  36. package/lib/common/features/model/model-submission-handler.js.map +1 -1
  37. package/lib/common/features/model/request-model-action-handler.js +4 -6
  38. package/lib/common/features/model/request-model-action-handler.js.map +1 -1
  39. package/lib/common/features/navigation/navigation-target-resolution.js +1 -1
  40. package/lib/common/features/navigation/navigation-target-resolution.js.map +1 -1
  41. package/lib/common/features/progress/progress-service.d.ts.map +1 -1
  42. package/lib/common/features/progress/progress-service.js +1 -2
  43. package/lib/common/features/progress/progress-service.js.map +1 -1
  44. package/lib/common/features/validation/request-markers-handler.js +1 -2
  45. package/lib/common/features/validation/request-markers-handler.js.map +1 -1
  46. package/lib/common/gmodel/change-routing-points-operation-handler.js +1 -2
  47. package/lib/common/gmodel/change-routing-points-operation-handler.js.map +1 -1
  48. package/lib/common/gmodel/gmodel-create-node-operation-handler.js +3 -5
  49. package/lib/common/gmodel/gmodel-create-node-operation-handler.js.map +1 -1
  50. package/lib/common/gmodel/paste-operation-handler.d.ts +1 -1
  51. package/lib/common/gmodel/paste-operation-handler.d.ts.map +1 -1
  52. package/lib/common/gmodel/paste-operation-handler.js +8 -11
  53. package/lib/common/gmodel/paste-operation-handler.js.map +1 -1
  54. package/lib/common/launch/glsp-server-launcher.d.ts +8 -1
  55. package/lib/common/launch/glsp-server-launcher.d.ts.map +1 -1
  56. package/lib/common/launch/glsp-server-launcher.js +11 -1
  57. package/lib/common/launch/glsp-server-launcher.js.map +1 -1
  58. package/lib/common/launch/jsonrpc-server-launcher.d.ts +51 -2
  59. package/lib/common/launch/jsonrpc-server-launcher.d.ts.map +1 -1
  60. package/lib/common/launch/jsonrpc-server-launcher.js +82 -3
  61. package/lib/common/launch/jsonrpc-server-launcher.js.map +1 -1
  62. package/lib/common/operations/compound-operation-handler.js +1 -1
  63. package/lib/common/operations/compound-operation-handler.js.map +1 -1
  64. package/lib/common/operations/json-operation-handler.js +2 -3
  65. package/lib/common/operations/json-operation-handler.js.map +1 -1
  66. package/lib/common/protocol/glsp-server.js +6 -7
  67. package/lib/common/protocol/glsp-server.js.map +1 -1
  68. package/lib/common/session/client-session-manager.js +3 -5
  69. package/lib/common/session/client-session-manager.js.map +1 -1
  70. package/lib/common/utils/action-queue.js +2 -4
  71. package/lib/common/utils/action-queue.js.map +1 -1
  72. package/lib/common/utils/client-options-util.js +2 -2
  73. package/lib/common/utils/client-options-util.js.map +1 -1
  74. package/lib/common/utils/glsp-server-error.d.ts +2 -3
  75. package/lib/common/utils/glsp-server-error.d.ts.map +1 -1
  76. package/lib/common/utils/glsp-server-error.js +1 -1
  77. package/lib/common/utils/glsp-server-error.js.map +1 -1
  78. package/lib/common/utils/layout-util.d.ts +5 -5
  79. package/lib/common/utils/layout-util.d.ts.map +1 -1
  80. package/lib/common/utils/layout-util.js +17 -19
  81. package/lib/common/utils/layout-util.js.map +1 -1
  82. package/lib/common/utils/logger.js +1 -2
  83. package/lib/common/utils/logger.js.map +1 -1
  84. package/lib/node/abstract-json-model-storage.js +2 -4
  85. package/lib/node/abstract-json-model-storage.js.map +1 -1
  86. package/lib/node/launch/socket-server-launcher.d.ts +39 -2
  87. package/lib/node/launch/socket-server-launcher.d.ts.map +1 -1
  88. package/lib/node/launch/socket-server-launcher.js +50 -31
  89. package/lib/node/launch/socket-server-launcher.js.map +1 -1
  90. package/lib/node/launch/websocket-server-launcher.d.ts +36 -5
  91. package/lib/node/launch/websocket-server-launcher.d.ts.map +1 -1
  92. package/lib/node/launch/websocket-server-launcher.js +54 -13
  93. package/lib/node/launch/websocket-server-launcher.js.map +1 -1
  94. package/package.json +17 -21
  95. package/src/common/features/directediting/context-edit-validator.ts +2 -2
  96. package/src/common/features/layout/computed-bounds-action-handler.ts +52 -4
  97. package/src/common/features/model/model-submission-handler.ts +3 -2
  98. package/src/common/features/progress/progress-service.ts +2 -3
  99. package/src/common/gmodel/paste-operation-handler.ts +6 -6
  100. package/src/common/launch/glsp-server-launcher.ts +12 -1
  101. package/src/common/launch/jsonrpc-server-launcher.ts +89 -2
  102. package/src/common/utils/glsp-server-error.ts +3 -5
  103. package/src/common/utils/layout-util.ts +13 -12
  104. package/src/node/launch/socket-server-launcher.ts +54 -31
  105. package/src/node/launch/websocket-server-launcher.ts +72 -14
  106. package/src/browser/di/browser-action-dispatch-scope.spec.ts +0 -75
  107. package/src/common/actions/action-handler-registry.spec.ts +0 -52
  108. package/src/common/actions/global-action-provider.spec.ts +0 -68
  109. package/src/common/command/command-stack.spec.ts +0 -239
  110. package/src/common/command/command.spec.ts +0 -92
  111. package/src/common/command/recording-command.spec.ts +0 -86
  112. package/src/common/di/binding-target.spec.ts +0 -147
  113. package/src/common/di/multi-bindings.spec.ts +0 -133
  114. package/src/common/features/contextactions/context-actions-provider-registry.spec.ts +0 -69
  115. package/src/common/features/contextactions/request-context-actions-handler.spec.ts +0 -75
  116. package/src/common/features/contextactions/tool-palette-item-provider.spec.ts +0 -46
  117. package/src/common/features/directediting/context-edit-validator-registry.spec.ts +0 -54
  118. package/src/common/features/directediting/request-edit-validation-handler.spec.ts +0 -131
  119. package/src/common/features/model/gmodel-serializer.spec.ts +0 -141
  120. package/src/common/features/type-hints/request-type-hints-action-handler.spec.ts +0 -59
  121. package/src/common/operations/operation-handler-registry.spec.ts +0 -50
  122. package/src/common/protocol/glsp-server.spec.ts +0 -154
  123. package/src/common/session/client-session-factory.spec.ts +0 -60
  124. package/src/common/session/client-session-manager.spec.ts +0 -83
  125. package/src/common/test/mock-util.ts +0 -281
  126. package/src/common/utils/action-queue.spec.ts +0 -133
  127. package/src/common/utils/promise-queue.spec.ts +0 -142
  128. package/src/common/utils/registry.spec.ts +0 -225
  129. package/src/node/actions/action-dispatcher.spec.ts +0 -678
  130. package/src/node/launch/cli-parser.spec.ts +0 -61
  131. package/src/node/launch/socket-cli-parser.spec.ts +0 -73
  132. package/src/node/launch/socket-server-launcher.spec.ts +0 -74
@@ -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
- });