undo-redo-service.test.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { describe, it, expect, beforeEach, vi } from 'vitest';
  6. import {
  7. OperationService,
  8. StackOperation,
  9. UndoRedoChangeEvent,
  10. UndoRedoChangeType,
  11. UndoRedoService,
  12. } from '../src';
  13. import { createHistoryContainer } from '../__mocks__/history-container.mock';
  14. describe('operation-registry', () => {
  15. let undoRedoService: UndoRedoService;
  16. let container;
  17. let createStackOperation = (operations = []) =>
  18. new StackOperation(container.get(OperationService), operations);
  19. beforeEach(() => {
  20. container = createHistoryContainer();
  21. undoRedoService = container.get(UndoRedoService);
  22. });
  23. it('pushElement', () => {
  24. const element = createStackOperation();
  25. undoRedoService.pushElement(element);
  26. expect(undoRedoService.getUndoStack()).toEqual([element]);
  27. });
  28. it('getUndoStack', () => {
  29. const element = createStackOperation();
  30. undoRedoService.pushElement(element);
  31. expect(undoRedoService.getUndoStack()).toEqual([element]);
  32. });
  33. it('getRedoStack', () => {
  34. const element = createStackOperation();
  35. undoRedoService.pushElement(element);
  36. expect(undoRedoService.getRedoStack()).toEqual([]);
  37. });
  38. it('clearRedoStack', () => {
  39. const element = createStackOperation();
  40. undoRedoService.pushElement(element);
  41. undoRedoService.clearRedoStack();
  42. expect(undoRedoService.getRedoStack()).toEqual([]);
  43. });
  44. it('undo', async () => {
  45. const element = createStackOperation();
  46. await undoRedoService.undo();
  47. undoRedoService.pushElement(element);
  48. await undoRedoService.undo();
  49. expect(undoRedoService.getUndoStack()).toEqual([]);
  50. });
  51. it('undo twice will only revert once', async () => {
  52. const element = createStackOperation();
  53. undoRedoService.pushElement(element);
  54. undoRedoService.pushElement(element);
  55. undoRedoService.undo();
  56. undoRedoService.undo();
  57. expect(undoRedoService.getUndoStack()).toEqual([element]);
  58. });
  59. it('redo', async () => {
  60. const element = createStackOperation();
  61. undoRedoService.pushElement(element);
  62. await undoRedoService.undo();
  63. await undoRedoService.redo();
  64. expect(undoRedoService.getUndoStack()).toEqual([element]);
  65. });
  66. it('canUndo', () => {
  67. const element = createStackOperation();
  68. expect(undoRedoService.canUndo()).toEqual(false);
  69. undoRedoService.pushElement(element);
  70. expect(undoRedoService.canUndo()).toEqual(true);
  71. });
  72. it('canRedo', async () => {
  73. const element = createStackOperation();
  74. expect(undoRedoService.canRedo()).toEqual(false);
  75. undoRedoService.pushElement(element);
  76. expect(undoRedoService.canRedo()).toEqual(false);
  77. await undoRedoService.undo();
  78. expect(undoRedoService.canRedo()).toEqual(true);
  79. });
  80. it('change event', async () => {
  81. const element = createStackOperation();
  82. const events: UndoRedoChangeEvent[] = [];
  83. undoRedoService.onChange(e => events.push(e));
  84. undoRedoService.pushElement(element);
  85. await undoRedoService.undo();
  86. await undoRedoService.redo();
  87. expect(events.map(e => e.type)).toMatchSnapshot();
  88. });
  89. it('clear', () => {
  90. const fn = vi.fn();
  91. const element = createStackOperation();
  92. undoRedoService.pushElement(element);
  93. undoRedoService.pushElement(element);
  94. undoRedoService.onChange(event => {
  95. if (event.type === UndoRedoChangeType.CLEAR) {
  96. fn();
  97. }
  98. });
  99. undoRedoService.undo();
  100. undoRedoService.clear();
  101. expect(undoRedoService.getUndoStack()).toEqual([]);
  102. expect(undoRedoService.getRedoStack()).toEqual([]);
  103. expect(fn).toBeCalledTimes(1);
  104. });
  105. });