@eclipse-glsp/server 1.1.0-next.3d7585d.42 → 1.1.0-next.44bd1e0.43

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 (175) hide show
  1. package/lib/common/command/command-stack.d.ts +38 -8
  2. package/lib/common/command/command-stack.d.ts.map +1 -1
  3. package/lib/common/command/command-stack.js +75 -6
  4. package/lib/common/command/command-stack.js.map +1 -1
  5. package/lib/common/command/command-stack.spec.d.ts +2 -0
  6. package/lib/common/command/command-stack.spec.d.ts.map +1 -0
  7. package/lib/common/command/command-stack.spec.js +207 -0
  8. package/lib/common/command/command-stack.spec.js.map +1 -0
  9. package/lib/common/command/command.d.ts +30 -4
  10. package/lib/common/command/command.d.ts.map +1 -1
  11. package/lib/common/command/command.js +69 -0
  12. package/lib/common/command/command.js.map +1 -1
  13. package/lib/common/command/command.spec.d.ts +2 -0
  14. package/lib/common/command/command.spec.d.ts.map +1 -0
  15. package/lib/common/command/command.spec.js +86 -0
  16. package/lib/common/command/command.spec.js.map +1 -0
  17. package/lib/common/command/recording-command.d.ts +75 -0
  18. package/lib/common/command/recording-command.d.ts.map +1 -0
  19. package/lib/common/command/recording-command.js +99 -0
  20. package/lib/common/command/recording-command.js.map +1 -0
  21. package/lib/common/command/recording-command.spec.d.ts +17 -0
  22. package/lib/common/command/recording-command.spec.d.ts.map +1 -0
  23. package/lib/common/command/recording-command.spec.js +62 -0
  24. package/lib/common/command/recording-command.spec.js.map +1 -0
  25. package/lib/common/command/undo-redo-action-handler.d.ts +28 -0
  26. package/lib/common/command/undo-redo-action-handler.d.ts.map +1 -0
  27. package/lib/common/command/undo-redo-action-handler.js +72 -0
  28. package/lib/common/command/undo-redo-action-handler.js.map +1 -0
  29. package/lib/common/di/diagram-module.d.ts +3 -0
  30. package/lib/common/di/diagram-module.d.ts.map +1 -1
  31. package/lib/common/di/diagram-module.js +12 -0
  32. package/lib/common/di/diagram-module.js.map +1 -1
  33. package/lib/common/features/contextactions/tool-palette-item-provider.d.ts +1 -1
  34. package/lib/common/features/contextactions/tool-palette-item-provider.d.ts.map +1 -1
  35. package/lib/common/features/contextactions/tool-palette-item-provider.js +2 -4
  36. package/lib/common/features/contextactions/tool-palette-item-provider.js.map +1 -1
  37. package/lib/common/{gmodel → features/layout}/computed-bounds-action-handler.d.ts +8 -3
  38. package/lib/common/features/layout/computed-bounds-action-handler.d.ts.map +1 -0
  39. package/lib/common/{gmodel → features/layout}/computed-bounds-action-handler.js +8 -3
  40. package/lib/common/features/layout/computed-bounds-action-handler.js.map +1 -0
  41. package/lib/common/features/layout/layout-operation-handler.d.ts +12 -3
  42. package/lib/common/features/layout/layout-operation-handler.d.ts.map +1 -1
  43. package/lib/common/features/layout/layout-operation-handler.js +26 -10
  44. package/lib/common/features/layout/layout-operation-handler.js.map +1 -1
  45. package/lib/common/features/model/model-state.d.ts +0 -2
  46. package/lib/common/features/model/model-state.d.ts.map +1 -1
  47. package/lib/common/features/model/model-state.js +0 -1
  48. package/lib/common/features/model/model-state.js.map +1 -1
  49. package/lib/common/features/model/model-submission-handler.d.ts +2 -0
  50. package/lib/common/features/model/model-submission-handler.d.ts.map +1 -1
  51. package/lib/common/features/model/model-submission-handler.js +7 -2
  52. package/lib/common/features/model/model-submission-handler.js.map +1 -1
  53. package/lib/common/features/model/save-model-action-handler.d.ts +2 -2
  54. package/lib/common/features/model/save-model-action-handler.d.ts.map +1 -1
  55. package/lib/common/features/model/save-model-action-handler.js +5 -5
  56. package/lib/common/features/model/save-model-action-handler.js.map +1 -1
  57. package/lib/common/gmodel/apply-label-edit-operation-handler.d.ts +4 -5
  58. package/lib/common/gmodel/apply-label-edit-operation-handler.d.ts.map +1 -1
  59. package/lib/common/gmodel/apply-label-edit-operation-handler.js +12 -21
  60. package/lib/common/gmodel/apply-label-edit-operation-handler.js.map +1 -1
  61. package/lib/common/gmodel/change-bounds-operation-handler.d.ts +9 -6
  62. package/lib/common/gmodel/change-bounds-operation-handler.d.ts.map +1 -1
  63. package/lib/common/gmodel/change-bounds-operation-handler.js +14 -14
  64. package/lib/common/gmodel/change-bounds-operation-handler.js.map +1 -1
  65. package/lib/common/gmodel/change-routing-points-operation-handler.d.ts +5 -5
  66. package/lib/common/gmodel/change-routing-points-operation-handler.d.ts.map +1 -1
  67. package/lib/common/gmodel/change-routing-points-operation-handler.js +11 -14
  68. package/lib/common/gmodel/change-routing-points-operation-handler.js.map +1 -1
  69. package/lib/common/{operations → gmodel}/cut-operation-handler.d.ts +5 -4
  70. package/lib/common/gmodel/cut-operation-handler.d.ts.map +1 -0
  71. package/lib/common/{operations → gmodel}/cut-operation-handler.js +13 -11
  72. package/lib/common/gmodel/cut-operation-handler.js.map +1 -0
  73. package/lib/common/gmodel/delete-operation-handler.d.ts +6 -6
  74. package/lib/common/gmodel/delete-operation-handler.d.ts.map +1 -1
  75. package/lib/common/gmodel/delete-operation-handler.js +13 -10
  76. package/lib/common/gmodel/delete-operation-handler.js.map +1 -1
  77. package/lib/common/gmodel/gmodel-create-edge-operation-handler.d.ts +11 -7
  78. package/lib/common/gmodel/gmodel-create-edge-operation-handler.d.ts.map +1 -1
  79. package/lib/common/gmodel/gmodel-create-edge-operation-handler.js +12 -13
  80. package/lib/common/gmodel/gmodel-create-edge-operation-handler.js.map +1 -1
  81. package/lib/common/gmodel/gmodel-create-node-operation-handler.d.ts +32 -5
  82. package/lib/common/gmodel/gmodel-create-node-operation-handler.d.ts.map +1 -1
  83. package/lib/common/gmodel/gmodel-create-node-operation-handler.js +45 -3
  84. package/lib/common/gmodel/gmodel-create-node-operation-handler.js.map +1 -1
  85. package/lib/common/gmodel/gmodel-diagram-module.d.ts +8 -8
  86. package/lib/common/gmodel/gmodel-diagram-module.d.ts.map +1 -1
  87. package/lib/common/gmodel/gmodel-diagram-module.js +15 -21
  88. package/lib/common/gmodel/gmodel-diagram-module.js.map +1 -1
  89. package/lib/common/gmodel/gmodel-operation-handler.d.ts +23 -0
  90. package/lib/common/gmodel/gmodel-operation-handler.d.ts.map +1 -0
  91. package/lib/common/gmodel/gmodel-operation-handler.js +43 -0
  92. package/lib/common/gmodel/gmodel-operation-handler.js.map +1 -0
  93. package/lib/common/gmodel/index.d.ts +2 -1
  94. package/lib/common/gmodel/index.d.ts.map +1 -1
  95. package/lib/common/gmodel/index.js +2 -1
  96. package/lib/common/gmodel/index.js.map +1 -1
  97. package/lib/common/gmodel/paste-operation-handler.d.ts +7 -6
  98. package/lib/common/gmodel/paste-operation-handler.d.ts.map +1 -1
  99. package/lib/common/gmodel/paste-operation-handler.js +20 -15
  100. package/lib/common/gmodel/paste-operation-handler.js.map +1 -1
  101. package/lib/common/gmodel/reconnect-edge-operation-handler.d.ts +5 -5
  102. package/lib/common/gmodel/reconnect-edge-operation-handler.d.ts.map +1 -1
  103. package/lib/common/gmodel/reconnect-edge-operation-handler.js +11 -14
  104. package/lib/common/gmodel/reconnect-edge-operation-handler.js.map +1 -1
  105. package/lib/common/index.d.ts +2 -1
  106. package/lib/common/index.d.ts.map +1 -1
  107. package/lib/common/index.js +2 -1
  108. package/lib/common/index.js.map +1 -1
  109. package/lib/common/operations/compound-operation-handler.d.ts +5 -5
  110. package/lib/common/operations/compound-operation-handler.d.ts.map +1 -1
  111. package/lib/common/operations/compound-operation-handler.js +37 -9
  112. package/lib/common/operations/compound-operation-handler.js.map +1 -1
  113. package/lib/common/operations/create-operation-handler.d.ts +8 -40
  114. package/lib/common/operations/create-operation-handler.d.ts.map +1 -1
  115. package/lib/common/operations/create-operation-handler.js +26 -85
  116. package/lib/common/operations/create-operation-handler.js.map +1 -1
  117. package/lib/common/operations/operation-action-handler.d.ts +10 -1
  118. package/lib/common/operations/operation-action-handler.d.ts.map +1 -1
  119. package/lib/common/operations/operation-action-handler.js +37 -22
  120. package/lib/common/operations/operation-action-handler.js.map +1 -1
  121. package/lib/common/operations/operation-handler-registry.d.ts +11 -2
  122. package/lib/common/operations/operation-handler-registry.d.ts.map +1 -1
  123. package/lib/common/operations/operation-handler-registry.js +31 -2
  124. package/lib/common/operations/operation-handler-registry.js.map +1 -1
  125. package/lib/common/operations/operation-handler.d.ts +28 -11
  126. package/lib/common/operations/operation-handler.d.ts.map +1 -1
  127. package/lib/common/operations/operation-handler.js +50 -1
  128. package/lib/common/operations/operation-handler.js.map +1 -1
  129. package/lib/common/test/mock-util.d.ts +7 -0
  130. package/lib/common/test/mock-util.d.ts.map +1 -1
  131. package/lib/common/test/mock-util.js +20 -37
  132. package/lib/common/test/mock-util.js.map +1 -1
  133. package/package.json +4 -3
  134. package/src/common/command/command-stack.spec.ts +239 -0
  135. package/src/common/command/command-stack.ts +99 -14
  136. package/src/common/command/command.spec.ts +93 -0
  137. package/src/common/command/command.ts +89 -4
  138. package/src/common/command/recording-command.spec.ts +74 -0
  139. package/src/common/command/recording-command.ts +119 -0
  140. package/src/common/command/undo-redo-action-handler.ts +57 -0
  141. package/src/common/di/diagram-module.ts +13 -0
  142. package/src/common/features/contextactions/tool-palette-item-provider.ts +2 -4
  143. package/src/common/{gmodel → features/layout}/computed-bounds-action-handler.ts +9 -4
  144. package/src/common/features/layout/layout-operation-handler.ts +26 -11
  145. package/src/common/features/model/model-state.ts +0 -3
  146. package/src/common/features/model/model-submission-handler.ts +6 -2
  147. package/src/common/features/model/save-model-action-handler.ts +5 -6
  148. package/src/common/gmodel/apply-label-edit-operation-handler.ts +13 -15
  149. package/src/common/gmodel/change-bounds-operation-handler.ts +12 -8
  150. package/src/common/gmodel/change-routing-points-operation-handler.ts +8 -7
  151. package/src/common/{operations → gmodel}/cut-operation-handler.ts +9 -8
  152. package/src/common/gmodel/delete-operation-handler.ts +16 -10
  153. package/src/common/gmodel/gmodel-create-edge-operation-handler.ts +16 -10
  154. package/src/common/gmodel/gmodel-create-node-operation-handler.ts +54 -6
  155. package/src/common/gmodel/gmodel-diagram-module.ts +22 -27
  156. package/src/common/gmodel/gmodel-operation-handler.ts +31 -0
  157. package/src/common/gmodel/index.ts +2 -1
  158. package/src/common/gmodel/paste-operation-handler.ts +19 -11
  159. package/src/common/gmodel/reconnect-edge-operation-handler.ts +8 -7
  160. package/src/common/index.ts +2 -1
  161. package/src/common/operations/compound-operation-handler.ts +14 -12
  162. package/src/common/operations/create-operation-handler.ts +17 -74
  163. package/src/common/operations/operation-action-handler.ts +51 -27
  164. package/src/common/operations/operation-handler-registry.ts +18 -3
  165. package/src/common/operations/operation-handler.ts +38 -13
  166. package/src/common/test/mock-util.ts +21 -36
  167. package/lib/common/gmodel/apply-label-edit-operation-handler.spec.d.ts +0 -2
  168. package/lib/common/gmodel/apply-label-edit-operation-handler.spec.d.ts.map +0 -1
  169. package/lib/common/gmodel/apply-label-edit-operation-handler.spec.js +0 -38
  170. package/lib/common/gmodel/apply-label-edit-operation-handler.spec.js.map +0 -1
  171. package/lib/common/gmodel/computed-bounds-action-handler.d.ts.map +0 -1
  172. package/lib/common/gmodel/computed-bounds-action-handler.js.map +0 -1
  173. package/lib/common/operations/cut-operation-handler.d.ts.map +0 -1
  174. package/lib/common/operations/cut-operation-handler.js.map +0 -1
  175. package/src/common/gmodel/apply-label-edit-operation-handler.spec.ts +0 -40
@@ -14,9 +14,10 @@
14
14
  *
15
15
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
16
16
  ********************************************************************************/
17
+ /* eslint-disable @typescript-eslint/no-empty-function */
17
18
  // Stub-implementation classes used for unit testing
18
19
  Object.defineProperty(exports, "__esModule", { value: true });
19
- exports.StubClientSessionInitializer = exports.stubActionHandlerFactory = exports.TestContextEditValidator = exports.TestLabelEditValidator = exports.StubDiagramConfiguration = exports.StubGLSPServerListener = exports.StubGLSPClientProxy = exports.StubClientSessionListener = exports.StubLogger = exports.StubClientSessionManager = exports.StubClientSessionFactory = exports.StubActionDispatcher = exports.StubCreateEdgeOperationHandler = exports.StubCreateNodeOperationHandler = exports.StubActionHandler = exports.createClientSession = exports.delay = void 0;
20
+ exports.StubCommand = exports.StubClientSessionInitializer = exports.stubActionHandlerFactory = exports.TestContextEditValidator = exports.TestLabelEditValidator = exports.StubDiagramConfiguration = exports.StubGLSPServerListener = exports.StubGLSPClientProxy = exports.StubClientSessionListener = exports.StubLogger = exports.StubClientSessionManager = exports.StubClientSessionFactory = exports.StubActionDispatcher = exports.StubCreateEdgeOperationHandler = exports.StubCreateNodeOperationHandler = exports.StubActionHandler = exports.createClientSession = exports.delay = void 0;
20
21
  const graph_1 = require("@eclipse-glsp/graph");
21
22
  const protocol_1 = require("@eclipse-glsp/protocol");
22
23
  const inversify_1 = require("inversify");
@@ -72,9 +73,7 @@ class StubCreateEdgeOperationHandler extends index_1.GModelCreateEdgeOperationHa
72
73
  }
73
74
  exports.StubCreateEdgeOperationHandler = StubCreateEdgeOperationHandler;
74
75
  class StubActionDispatcher {
75
- dispatchAfterNextUpdate(...actions) {
76
- // NO-OP
77
- }
76
+ dispatchAfterNextUpdate(...actions) { }
78
77
  dispatch(action) {
79
78
  return Promise.resolve();
80
79
  }
@@ -121,45 +120,25 @@ class StubLogger extends logger_1.Logger {
121
120
  this.logLevel = logger_1.LogLevel.none;
122
121
  this.caller = undefined;
123
122
  }
124
- info(message, ...params) {
125
- // no-op
126
- }
127
- warn(message, ...params) {
128
- // no-op
129
- }
130
- error(message, ...params) {
131
- // no-op
132
- }
133
- debug(message, ...params) {
134
- // no-op
135
- }
123
+ info(message, ...params) { }
124
+ warn(message, ...params) { }
125
+ error(message, ...params) { }
126
+ debug(message, ...params) { }
136
127
  }
137
128
  exports.StubLogger = StubLogger;
138
129
  class StubClientSessionListener {
139
- sessionCreated(clientSession) {
140
- // no-op
141
- }
142
- sessionDisposed(clientSession) {
143
- // no-op
144
- }
130
+ sessionCreated(clientSession) { }
131
+ sessionDisposed(clientSession) { }
145
132
  }
146
133
  exports.StubClientSessionListener = StubClientSessionListener;
147
134
  class StubGLSPClientProxy {
148
- connect(connection) {
149
- // no-op
150
- }
151
- process(message) {
152
- // no-op
153
- }
135
+ connect(connection) { }
136
+ process(message) { }
154
137
  }
155
138
  exports.StubGLSPClientProxy = StubGLSPClientProxy;
156
139
  class StubGLSPServerListener {
157
- serverInitialized(server) {
158
- // no-op
159
- }
160
- serverShutDown(server) {
161
- // no-op
162
- }
140
+ serverInitialized(server) { }
141
+ serverShutDown(server) { }
163
142
  }
164
143
  exports.StubGLSPServerListener = StubGLSPServerListener;
165
144
  class StubDiagramConfiguration {
@@ -203,9 +182,13 @@ exports.TestContextEditValidator = TestContextEditValidator;
203
182
  const stubActionHandlerFactory = constructor => new constructor();
204
183
  exports.stubActionHandlerFactory = stubActionHandlerFactory;
205
184
  class StubClientSessionInitializer {
206
- initialize(args) {
207
- // no-op
208
- }
185
+ initialize(args) { }
209
186
  }
210
187
  exports.StubClientSessionInitializer = StubClientSessionInitializer;
188
+ class StubCommand {
189
+ execute() { }
190
+ undo() { }
191
+ redo() { }
192
+ }
193
+ exports.StubCommand = StubCommand;
211
194
  //# sourceMappingURL=mock-util.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock-util.js","sourceRoot":"","sources":["../../../src/common/test/mock-util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mock-util.js","sourceRoot":"","sources":["../../../src/common/test/mock-util.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclipse-glsp/server",
3
- "version": "1.1.0-next.3d7585d.42+3d7585d",
3
+ "version": "1.1.0-next.44bd1e0.43+44bd1e0",
4
4
  "description": "A js server framework for Eclipse GLSP",
5
5
  "keywords": [
6
6
  "eclipse",
@@ -59,10 +59,11 @@
59
59
  "watch": "tsc -w"
60
60
  },
61
61
  "dependencies": {
62
- "@eclipse-glsp/graph": "1.1.0-next.3d7585d.42+3d7585d",
62
+ "@eclipse-glsp/graph": "1.1.0-next.44bd1e0.43+44bd1e0",
63
63
  "@eclipse-glsp/protocol": "next",
64
64
  "@types/uuid": "8.3.1",
65
65
  "commander": "^8.3.0",
66
+ "fast-json-patch": "^3.1.0",
66
67
  "inversify": "^5.1.1",
67
68
  "winston": "^3.3.3"
68
69
  },
@@ -72,5 +73,5 @@
72
73
  "publishConfig": {
73
74
  "access": "public"
74
75
  },
75
- "gitHead": "3d7585df49f6df95ea707e55cfc8e435b578cea3"
76
+ "gitHead": "44bd1e05dcc86ad71386a5286eed7e3300afb51a"
76
77
  }
@@ -0,0 +1,239 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023 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 { Container, ContainerModule } from 'inversify';
18
+ import * as sinon from 'sinon';
19
+ import { StubCommand, StubLogger } from '../test/mock-util';
20
+ import { Logger } from '../utils/logger';
21
+ import { DefaultCommandStack } from './command-stack';
22
+
23
+ describe('test DefaultCommandStack', () => {
24
+ const sandbox = sinon.createSandbox();
25
+ const container = new Container();
26
+
27
+ const command1 = sandbox.stub(new StubCommand());
28
+ const command2 = sandbox.stub(new StubCommand());
29
+ let commandStack: DefaultCommandStack;
30
+
31
+ container.load(
32
+ new ContainerModule(bind => {
33
+ bind(Logger).toConstantValue(new StubLogger());
34
+ })
35
+ );
36
+ commandStack = container.resolve(DefaultCommandStack);
37
+
38
+ afterEach(() => {
39
+ sandbox.reset();
40
+ commandStack = container.resolve(DefaultCommandStack);
41
+ });
42
+
43
+ describe('execute', () => {
44
+ it('should execute the given command and become dirty', () => {
45
+ expect(commandStack.isDirty).to.be.false;
46
+ commandStack.execute(command1);
47
+ expect(command1.execute.calledOnce).to.be.true;
48
+ expect(commandStack.isDirty).to.be.true;
49
+ });
50
+
51
+ it('should execute the given commands in order and become dirty', () => {
52
+ expect(commandStack.isDirty).to.be.false;
53
+ commandStack.execute(command1);
54
+ commandStack.execute(command2);
55
+
56
+ expect(command1.execute.calledOnce).to.be.true;
57
+ expect(command2.execute.calledOnce).to.be.true;
58
+ expect(command2.execute.calledAfter(command1.execute)).to.be.true;
59
+ expect(commandStack.isDirty).to.be.true;
60
+ });
61
+
62
+ it('should be able to undo after execute', () => {
63
+ expect(commandStack.canUndo()).to.be.false;
64
+ commandStack.execute(command1);
65
+ expect(commandStack.canUndo()).to.be.true;
66
+ });
67
+
68
+ it('should clear the redo stack after execution', () => {
69
+ commandStack['commands'].push(command2);
70
+ commandStack['top'] = -1;
71
+ expect(commandStack.canRedo()).to.be.true;
72
+
73
+ commandStack.execute(command1);
74
+ expect(commandStack.canRedo()).to.be.false;
75
+ });
76
+
77
+ it('should flush the stack in case of an execution error', () => {
78
+ command2.execute.throwsException();
79
+ const flushSpy = sandbox.spy(commandStack, 'flush');
80
+
81
+ expect(() => commandStack.execute(command2)).to.throw();
82
+ expect(command2.execute.calledOnce).to.be.true;
83
+ expect(flushSpy.calledOnce).to.be.true;
84
+ });
85
+ });
86
+
87
+ describe('undo', () => {
88
+ it('should do nothing if the command stack is empty', () => {
89
+ expect(commandStack.isDirty).to.be.false;
90
+
91
+ commandStack.undo();
92
+ expect(commandStack.canUndo()).to.be.false;
93
+ expect(commandStack.canRedo()).to.be.false;
94
+ expect(commandStack.isDirty).to.be.false;
95
+ });
96
+
97
+ it('should undo the command and become non-dirty again', () => {
98
+ commandStack['commands'].push(command1);
99
+ commandStack['top'] = 0;
100
+ expect(commandStack.isDirty).to.be.true;
101
+ expect(commandStack.canUndo()).to.be.true;
102
+ expect(commandStack.canRedo()).to.be.false;
103
+
104
+ commandStack.undo();
105
+ expect(command1.undo.calledOnce).to.be.true;
106
+ expect(commandStack.isDirty).to.be.false;
107
+ expect(commandStack.canRedo()).to.be.true;
108
+ expect(commandStack.canUndo()).to.be.false;
109
+ });
110
+
111
+ it('should undo multiple command and become non-dirty again', () => {
112
+ commandStack['commands'].push(command1, command2);
113
+ commandStack['top'] = 1;
114
+ expect(commandStack.isDirty).to.be.true;
115
+ expect(commandStack.canUndo()).to.be.true;
116
+ expect(commandStack.canRedo()).to.be.false;
117
+
118
+ commandStack.undo();
119
+ expect(command2.undo.calledOnce).to.be.true;
120
+ expect(commandStack.canRedo()).to.be.true;
121
+ expect(commandStack.canUndo()).to.be.true;
122
+ expect(commandStack.isDirty).to.be.true;
123
+
124
+ commandStack.undo();
125
+ expect(command1.undo.calledOnce).to.be.true;
126
+ expect(command1.undo.calledAfter(command2.undo)).to.be.true;
127
+ expect(commandStack.isDirty).to.be.false;
128
+ expect(commandStack.canRedo()).to.be.true;
129
+ expect(commandStack.canUndo()).to.be.false;
130
+ });
131
+ it('should flush the stack in case of an execution error', () => {
132
+ command2.undo.throwsException();
133
+ const flushSpy = sandbox.spy(commandStack, 'flush');
134
+ commandStack['commands'].push(command2);
135
+ commandStack['top'] = 0;
136
+
137
+ expect(() => commandStack.undo()).to.throw();
138
+ expect(command2.undo.calledOnce).to.be.true;
139
+ expect(flushSpy.calledOnce).to.be.true;
140
+ });
141
+ });
142
+
143
+ describe('redo', () => {
144
+ it('should do nothing if the command stack is empty', () => {
145
+ expect(commandStack.isDirty).to.be.false;
146
+
147
+ commandStack.redo();
148
+ expect(commandStack.canUndo()).to.be.false;
149
+ expect(commandStack.canRedo()).to.be.false;
150
+ expect(commandStack.isDirty).to.be.false;
151
+ });
152
+
153
+ it('should redo the command and become dirty again', () => {
154
+ commandStack['commands'].push(command1);
155
+ commandStack['top'] = -1;
156
+ expect(commandStack.isDirty).to.be.false;
157
+ expect(commandStack.canUndo()).to.be.false;
158
+ expect(commandStack.canRedo()).to.be.true;
159
+
160
+ commandStack.redo();
161
+ expect(command1.redo.calledOnce).to.be.true;
162
+ expect(commandStack.isDirty).to.be.true;
163
+ expect(commandStack.canRedo()).to.be.false;
164
+ expect(commandStack.canUndo()).to.be.true;
165
+ });
166
+
167
+ it('should undo multiple command and become non-dirty again', () => {
168
+ commandStack['commands'].push(command2, command1);
169
+ commandStack['top'] = -1;
170
+ commandStack['saveIndex'] = -1;
171
+ expect(commandStack.isDirty).to.be.false;
172
+ expect(commandStack.canUndo()).to.be.false;
173
+ expect(commandStack.canRedo()).to.be.true;
174
+
175
+ commandStack.redo();
176
+ expect(command2.redo.calledOnce).to.be.true;
177
+ expect(commandStack.canRedo()).to.be.true;
178
+ expect(commandStack.canUndo()).to.be.true;
179
+ expect(commandStack.isDirty).to.be.true;
180
+
181
+ commandStack.redo();
182
+ expect(command1.redo.calledOnce).to.be.true;
183
+ expect(command1.redo.calledAfter(command2.redo)).to.be.true;
184
+ expect(commandStack.isDirty).to.be.true;
185
+ expect(commandStack.canRedo()).to.be.false;
186
+ expect(commandStack.canUndo()).to.be.true;
187
+ });
188
+ it('should flush the stack in case of an execution error', () => {
189
+ command2.redo.throwsException();
190
+ const flushSpy = sandbox.spy(commandStack, 'flush');
191
+ commandStack['commands'].push(command2);
192
+ commandStack['top'] = -1;
193
+
194
+ expect(() => commandStack.redo()).to.throw();
195
+ expect(command2.redo.calledOnce).to.be.true;
196
+ expect(flushSpy.calledOnce).to.be.true;
197
+ });
198
+ it('should be able to undo after redo', () => {
199
+ commandStack['commands'].push(command1);
200
+ commandStack['top'] = -1;
201
+ expect(commandStack.canUndo()).to.be.false;
202
+ commandStack.redo();
203
+ expect(commandStack.canUndo()).to.be.true;
204
+ });
205
+ });
206
+
207
+ describe('flush', () => {
208
+ it('should reset the internal state of the command stack', () => {
209
+ commandStack['commands'].push(command1, command1);
210
+ commandStack['top'] = 0;
211
+
212
+ commandStack.flush();
213
+ expect(commandStack.isDirty).to.be.false;
214
+ expect(commandStack.canUndo()).to.be.false;
215
+ expect(commandStack.canRedo()).to.be.false;
216
+ });
217
+ });
218
+
219
+ describe('isSaveDone', () => {
220
+ it('should become non-dirty after execution', () => {
221
+ commandStack['commands'].push(command1);
222
+ commandStack['top'] = 0;
223
+ expect(commandStack.isDirty).to.be.true;
224
+
225
+ commandStack.saveIsDone();
226
+ expect(commandStack.isDirty).to.be.false;
227
+ });
228
+ it('should maintain undo/redo history after execution', () => {
229
+ commandStack['commands'].push(command1, command2);
230
+ commandStack['top'] = 0;
231
+ expect(commandStack.canUndo()).to.be.true;
232
+ expect(commandStack.canRedo()).to.be.true;
233
+
234
+ commandStack.saveIsDone();
235
+ expect(commandStack.canUndo()).to.be.true;
236
+ expect(commandStack.canRedo()).to.be.true;
237
+ });
238
+ });
239
+ });
@@ -13,62 +13,147 @@
13
13
  *
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
- import { injectable } from 'inversify';
16
+ import { inject, injectable } from 'inversify';
17
+ import { Logger } from '../utils/logger';
17
18
  import { Command } from './command';
18
19
 
19
20
  export const CommandStack = Symbol('CommandStack');
20
21
 
21
22
  /**
22
- * A basic implementation of an undoable stack of commands.
23
- * See {@link Command} for more details about the command methods that this implementation uses.
23
+ * A command stack keeps track of {@link Command commands} that have been executed.
24
+ * Executed commands can be undone in the reverse order of their original execution.
25
+ * Unless a new command has been executed after an undo operation, commands can be
26
+ * redone in the original order of their execution.
27
+ *
24
28
  */
25
29
  export interface CommandStack {
26
30
  /**
27
- * Clears any redoable commands not yet redone, adds the command, and then executes the command.
31
+ * Clears any redoable commands not yet redone, adds the command to the stack and then invokes {@link Command.execute}.
28
32
  * @param command the command to execute.
29
33
  */
30
34
  execute(command: Command): void;
31
35
 
32
36
  /**
33
- * Moves the top of the stack down, undoing what was formerly the top command.
37
+ * Removes the topmost (i.e. last executed) command from the stack and invokes {@link Command.undo}.
34
38
  */
35
39
  undo(): void;
36
40
 
37
41
  /**
38
- * Moves the top of the stack up, redoing the new top command.
42
+ * Returns `true` if the top command on the stack can be undone.
43
+ */
44
+ canUndo(): boolean;
45
+
46
+ /**
47
+ * Re-adds the last undo command on top of the stack and invokes {@link Command.redo}
39
48
  */
40
49
  redo(): void;
41
50
 
42
51
  /**
43
- * The command stack has currently unsaved changes.
52
+ * Returns `true` if there are redoable commands in the stack.
44
53
  */
45
- isDirty(): boolean;
54
+ canRedo(): boolean;
46
55
 
47
56
  /**
48
57
  * Called after a save has been successfully performed.
49
58
  */
50
59
  saveIsDone(): void;
60
+
61
+ /**
62
+ * Indicates wether the command stack has unsaved changes.
63
+ */
64
+ readonly isDirty: boolean;
65
+
66
+ /**
67
+ * Disposes all the commands in the stack.
68
+ */
69
+ flush(): void;
51
70
  }
52
71
 
53
72
  @injectable()
54
73
  export class DefaultCommandStack implements CommandStack {
74
+ @inject(Logger)
75
+ protected logger: Logger;
76
+
77
+ protected commands: Command[] = [];
78
+
79
+ /**
80
+ * The current position within the command list from which the next execute, undo, or redo, will be performed.
81
+ */
82
+ protected top = -1;
83
+
84
+ /**
85
+ * The current position within the command list when {@link DefaultCommandStack.saveIsDone} is called.
86
+ */
87
+ protected saveIndex = -1;
88
+
55
89
  execute(command: Command): void {
56
- // no-op
90
+ try {
91
+ command.execute();
92
+ } catch (error) {
93
+ this.handleError(error);
94
+ }
95
+ // Clear the command list past the top (i.e. the old redo list)
96
+ this.commands = this.commands.slice(0, this.top + 1);
97
+ this.commands.push(command);
98
+ ++this.top;
99
+
100
+ // if the saveIndex points to the old redo list we can never reach a state again
101
+ // where save is not necessary. => ensure that `isDirty` always returns true
102
+ if (this.saveIndex >= this.top) {
103
+ this.saveIndex = -2;
104
+ }
57
105
  }
58
106
 
59
107
  undo(): void {
60
- // no-op
108
+ if (this.canUndo()) {
109
+ const command = this.commands[this.top--];
110
+ try {
111
+ command.undo();
112
+ } catch (error) {
113
+ this.handleError(error);
114
+ }
115
+ }
116
+ }
117
+
118
+ canUndo(): boolean {
119
+ return this.top !== -1 //
120
+ ? Command.canUndo(this.commands[this.top])
121
+ : false;
61
122
  }
62
123
 
63
124
  redo(): void {
64
- // no-op
125
+ if (this.canRedo()) {
126
+ const command = this.commands[++this.top];
127
+ try {
128
+ command.redo();
129
+ } catch (error) {
130
+ this.handleError(error);
131
+ }
132
+ }
65
133
  }
66
134
 
67
- isDirty(): boolean {
68
- return false;
135
+ canRedo(): boolean {
136
+ return this.top < this.commands.length - 1;
137
+ }
138
+
139
+ get isDirty(): boolean {
140
+ return this.saveIndex !== this.top;
69
141
  }
70
142
 
71
143
  saveIsDone(): void {
72
- // no-op
144
+ this.saveIndex = this.top;
145
+ }
146
+
147
+ flush(): void {
148
+ this.commands = [];
149
+ this.top = -1;
150
+ this.saveIndex = -1;
151
+ }
152
+
153
+ protected handleError(error: any): never {
154
+ // if an error occurred during the command execution the stack might be in an erroneous state => we have to flush the command stack
155
+ this.flush();
156
+ this.logger.error('An error occurred during command execution. CommandStack will be flushed!', error);
157
+ throw error;
73
158
  }
74
159
  }
@@ -0,0 +1,93 @@
1
+ /********************************************************************************
2
+ * Copyright (c) 2023 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 * as sinon from 'sinon';
18
+ import { StubCommand } from '../test/mock-util';
19
+ import { CompoundCommand } from './command';
20
+
21
+ describe('CompoundCommand', () => {
22
+ const sandbox = sinon.createSandbox();
23
+
24
+ const command1 = sandbox.stub(new StubCommand());
25
+ const command2 = sandbox.stub(new StubCommand());
26
+ const command3 = sandbox.stub(new StubCommand());
27
+
28
+ const compoundCommand = new CompoundCommand(command1, command2, command3);
29
+
30
+ afterEach(() => {
31
+ sandbox.reset();
32
+ });
33
+
34
+ describe('execute', () => {
35
+ it('Should execute the subcommands in order', () => {
36
+ compoundCommand.execute();
37
+ expect(command1.execute.calledOnce).to.be.true;
38
+ expect(command2.execute.calledOnce).to.be.true;
39
+ expect(command3.execute.calledOnce).to.be.true;
40
+ expect(command1.execute.calledBefore(command2.execute)).to.be.true;
41
+ expect(command2.execute.calledBefore(command3.execute)).to.be.true;
42
+ });
43
+ it('Should undo partially executed subcommands in case of an error', () => {
44
+ command3.execute.throwsException();
45
+
46
+ expect(() => compoundCommand.execute()).to.throw();
47
+
48
+ expect(command1.execute.calledOnce).to.be.true;
49
+ expect(command2.execute.calledOnce).to.be.true;
50
+ expect(command3.execute.calledOnce).to.be.true;
51
+ expect(command1.undo.calledOnce).to.be.true;
52
+ expect(command2.undo.calledOnce).to.be.true;
53
+ });
54
+ });
55
+
56
+ describe('undo', () => {
57
+ it('Should undo the subcommands in reverse order', () => {
58
+ compoundCommand.undo();
59
+ expect(command1.undo.calledOnce).to.be.true;
60
+ expect(command2.undo.calledOnce).to.be.true;
61
+ expect(command3.undo.calledOnce).to.be.true;
62
+ expect(command1.undo.calledAfter(command2.undo)).to.be.true;
63
+ expect(command2.undo.calledAfter(command3.undo)).to.be.true;
64
+ });
65
+
66
+ it('Should redo partially undone subcommands in case of an error', () => {
67
+ command1.undo.throwsException();
68
+
69
+ expect(() => compoundCommand.undo()).to.throw();
70
+
71
+ expect(command1.undo.calledOnce).to.be.true;
72
+ expect(command2.undo.calledOnce).to.be.true;
73
+ expect(command3.undo.calledOnce).to.be.true;
74
+ expect(command3.redo.calledOnce).to.be.true;
75
+ expect(command2.redo.calledOnce).to.be.true;
76
+ });
77
+ });
78
+
79
+ describe('canUndo', () => {
80
+ it('should return true if all subcommands can be undone', () => {
81
+ command1.canUndo?.returns(true);
82
+ command2.canUndo?.returns(true);
83
+ command3.canUndo?.returns(true);
84
+ expect(compoundCommand.canUndo()).to.be.true;
85
+ });
86
+ it('should return true if anyof the subcommands cannot be undone', () => {
87
+ command1.canUndo?.returns(true);
88
+ command2.canUndo?.returns(false);
89
+ command3.canUndo?.returns(true);
90
+ expect(compoundCommand.canUndo()).to.be.true;
91
+ });
92
+ });
93
+ });