undoablevector.spec.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // Copyright (c) Jupyter Development Team.
  2. // Distributed under the terms of the Modified BSD License.
  3. import expect = require('expect.js');
  4. import {
  5. JSONObject
  6. } from '@phosphor/coreutils';
  7. import {
  8. ObservableUndoableVector, ISerializer
  9. } from '@jupyterlab/coreutils';
  10. class Test {
  11. constructor(value: JSONObject) {
  12. this._value = value;
  13. }
  14. get value(): JSONObject {
  15. return this._value;
  16. }
  17. private _value: JSONObject;
  18. }
  19. let count = 0;
  20. class Serializer implements ISerializer<Test> {
  21. fromJSON(value: JSONObject): Test {
  22. value['count'] = count++;
  23. return new Test(value);
  24. }
  25. toJSON(value: Test): JSONObject {
  26. return value.value;
  27. }
  28. }
  29. const serializer = new Serializer();
  30. const value: JSONObject = { name: 'foo' };
  31. describe('notebook/common/undo', () => {
  32. describe('ObservableUndoableVector', () => {
  33. describe('#constructor', () => {
  34. it('should create a new ObservableUndoableVector', () => {
  35. let vector = new ObservableUndoableVector(serializer);
  36. expect(vector).to.be.an(ObservableUndoableVector);
  37. });
  38. });
  39. describe('#canRedo', () => {
  40. it('should return false if there is no history', () => {
  41. let vector = new ObservableUndoableVector(serializer);
  42. expect(vector.canRedo).to.be(false);
  43. });
  44. it('should return true if there is an undo that can be redone', () => {
  45. let vector = new ObservableUndoableVector(serializer);
  46. vector.pushBack(new Test(value));
  47. vector.undo();
  48. expect(vector.canRedo).to.be(true);
  49. });
  50. });
  51. describe('#canUndo', () => {
  52. it('should return false if there is no history', () => {
  53. let vector = new ObservableUndoableVector(serializer);
  54. expect(vector.canUndo).to.be(false);
  55. });
  56. it('should return true if there is a change that can be undone', () => {
  57. let vector = new ObservableUndoableVector(serializer);
  58. vector.pushBack(serializer.fromJSON(value));
  59. expect(vector.canUndo).to.be(true);
  60. });
  61. });
  62. describe('#dispose()', () => {
  63. it('should dispose of the resources used by the vector', () => {
  64. let vector = new ObservableUndoableVector(serializer);
  65. vector.dispose();
  66. expect(vector.isDisposed).to.be(true);
  67. vector.dispose();
  68. expect(vector.isDisposed).to.be(true);
  69. });
  70. });
  71. describe('#beginCompoundOperation()', () => {
  72. it('should begin a compound operation', () => {
  73. let vector = new ObservableUndoableVector(serializer);
  74. vector.beginCompoundOperation();
  75. vector.pushBack(serializer.fromJSON(value));
  76. vector.pushBack(serializer.fromJSON(value));
  77. vector.endCompoundOperation();
  78. expect(vector.canUndo).to.be(true);
  79. vector.undo();
  80. expect(vector.canUndo).to.be(false);
  81. });
  82. it('should not be undoable if isUndoAble is set to false', () => {
  83. let vector = new ObservableUndoableVector(serializer);
  84. vector.beginCompoundOperation(false);
  85. vector.pushBack(serializer.fromJSON(value));
  86. vector.pushBack(serializer.fromJSON(value));
  87. vector.endCompoundOperation();
  88. expect(vector.canUndo).to.be(false);
  89. });
  90. });
  91. describe('#endCompoundOperation()', () => {
  92. it('should end a compound operation', () => {
  93. let vector = new ObservableUndoableVector(serializer);
  94. vector.beginCompoundOperation();
  95. vector.pushBack(serializer.fromJSON(value));
  96. vector.pushBack(serializer.fromJSON(value));
  97. vector.endCompoundOperation();
  98. expect(vector.canUndo).to.be(true);
  99. vector.undo();
  100. expect(vector.canUndo).to.be(false);
  101. });
  102. });
  103. describe('#undo()', () => {
  104. it('should undo a pushBack', () => {
  105. let vector = new ObservableUndoableVector(serializer);
  106. vector.pushBack(serializer.fromJSON(value));
  107. vector.undo();
  108. expect(vector.length).to.be(0);
  109. });
  110. it('should undo a pushAll', () => {
  111. let vector = new ObservableUndoableVector(serializer);
  112. vector.pushAll([serializer.fromJSON(value),
  113. serializer.fromJSON(value)]);
  114. vector.undo();
  115. expect(vector.length).to.be(0);
  116. });
  117. it('should undo a remove', () => {
  118. let vector = new ObservableUndoableVector(serializer);
  119. vector.pushAll([serializer.fromJSON(value),
  120. serializer.fromJSON(value)]);
  121. vector.removeAt(0);
  122. vector.undo();
  123. expect(vector.length).to.be(2);
  124. });
  125. it('should undo a removeRange', () => {
  126. let vector = new ObservableUndoableVector(serializer);
  127. vector.pushAll([serializer.fromJSON(value),
  128. serializer.fromJSON(value),
  129. serializer.fromJSON(value),
  130. serializer.fromJSON(value),
  131. serializer.fromJSON(value),
  132. serializer.fromJSON(value)]);
  133. vector.removeRange(1, 3);
  134. vector.undo();
  135. expect(vector.length).to.be(6);
  136. });
  137. it('should undo a move', () => {
  138. let items = [serializer.fromJSON(value),
  139. serializer.fromJSON(value),
  140. serializer.fromJSON(value)];
  141. let vector = new ObservableUndoableVector(serializer);
  142. vector.pushAll(items);
  143. vector.move(1, 2);
  144. vector.undo();
  145. expect((vector.at(1) as any)['count']).to.be((items[1] as any)['count']);
  146. });
  147. });
  148. describe('#redo()', () => {
  149. it('should redo a pushBack', () => {
  150. let vector = new ObservableUndoableVector(serializer);
  151. vector.pushBack(serializer.fromJSON(value));
  152. vector.undo();
  153. vector.redo();
  154. expect(vector.length).to.be(1);
  155. });
  156. it('should redo a pushAll', () => {
  157. let vector = new ObservableUndoableVector(serializer);
  158. vector.pushAll([serializer.fromJSON(value),
  159. serializer.fromJSON(value)]);
  160. vector.undo();
  161. vector.redo();
  162. expect(vector.length).to.be(2);
  163. });
  164. it('should redo a remove', () => {
  165. let vector = new ObservableUndoableVector(serializer);
  166. vector.pushAll([serializer.fromJSON(value),
  167. serializer.fromJSON(value)]);
  168. vector.removeAt(0);
  169. vector.undo();
  170. vector.redo();
  171. expect(vector.length).to.be(1);
  172. });
  173. it('should redo a removeRange', () => {
  174. let vector = new ObservableUndoableVector(serializer);
  175. vector.pushAll([serializer.fromJSON(value),
  176. serializer.fromJSON(value),
  177. serializer.fromJSON(value),
  178. serializer.fromJSON(value),
  179. serializer.fromJSON(value),
  180. serializer.fromJSON(value)]);
  181. vector.removeRange(1, 3);
  182. vector.undo();
  183. vector.redo();
  184. expect(vector.length).to.be(4);
  185. });
  186. it('should undo a move', () => {
  187. let items = [serializer.fromJSON(value),
  188. serializer.fromJSON(value),
  189. serializer.fromJSON(value)];
  190. let vector = new ObservableUndoableVector(serializer);
  191. vector.pushAll(items);
  192. vector.move(1, 2);
  193. vector.undo();
  194. vector.redo();
  195. expect((vector.at(2) as any)['count']).to.be((items[1] as any)['count']);
  196. });
  197. });
  198. describe('#clearUndo()', () => {
  199. it('should clear the undo stack', () => {
  200. let vector = new ObservableUndoableVector(serializer);
  201. vector.pushBack(serializer.fromJSON(value));
  202. vector.clearUndo();
  203. expect(vector.canUndo).to.be(false);
  204. });
  205. });
  206. });
  207. });