b833b9759b30b42bd0e290a30e5e571bac83475f
[idea/community.git] / platform / platform-tests / testSrc / com / intellij / openapi / fileEditor / impl / IdeDocumentHistoryTest.java
1 // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.openapi.fileEditor.impl;
3
4 import com.intellij.mock.Mock;
5 import com.intellij.openapi.fileEditor.FileEditor;
6 import com.intellij.openapi.fileEditor.FileEditorProvider;
7 import com.intellij.openapi.fileEditor.FileEditorState;
8 import com.intellij.openapi.fileEditor.FileEditorStateLevel;
9 import com.intellij.openapi.fileEditor.ex.FileEditorWithProvider;
10 import com.intellij.openapi.util.Disposer;
11 import com.intellij.openapi.util.Pair;
12 import com.intellij.openapi.vfs.VirtualFile;
13 import com.intellij.testFramework.HeavyPlatformTestCase;
14 import org.jetbrains.annotations.NotNull;
15
16 public class IdeDocumentHistoryTest extends HeavyPlatformTestCase {
17   private IdeDocumentHistoryImpl myHistory;
18
19   private Mock.MyFileEditor  mySelectedEditor;
20   private Mock.MyVirtualFile mySelectedFile;
21   private FileEditorState myEditorState;
22   private FileEditorProvider myProvider;
23
24   private MyState myState1;
25   private MyState myState2;
26   private MyState myState3;
27
28   @Override
29   protected void setUp() throws Exception {
30     super.setUp();
31
32     mySelectedEditor = new Mock.MyFileEditor() {
33       @Override
34       @NotNull
35       public FileEditorState getState(@NotNull FileEditorStateLevel level) {
36         return myEditorState;
37       }
38
39       @Override
40       public void setState(@NotNull FileEditorState state) {
41         myEditorState = state;
42       }
43     };
44
45     myHistory = new IdeDocumentHistoryImpl(getProject(), new EditorManager()) {
46       @Override
47       protected FileEditorWithProvider getSelectedEditor() {
48         return mySelectedEditor == null ? null : new FileEditorWithProvider(mySelectedEditor, myProvider);
49       }
50
51       @Override
52       protected void executeCommand(Runnable runnable, String name, Object groupId) {
53         myHistory.onCommandStarted();
54         runnable.run();
55         myHistory.onSelectionChanged();
56         myHistory.onCommandFinished(getProject(), groupId);
57       }
58     };
59
60     mySelectedFile = new Mock.MyVirtualFile();
61     myEditorState = new MyState(false, "start");
62     myProvider = new Mock.MyFileEditorProvider() {
63       @Override
64       @NotNull
65       public String getEditorTypeId() {
66         return "EditorType";
67       }
68     };
69   }
70
71   @Override
72   protected void tearDown() throws Exception {
73     try {
74       Disposer.dispose(myHistory);
75       myHistory = null;
76       mySelectedEditor = null;
77       myEditorState = null;
78       myProvider = null;
79       mySelectedFile = null;
80       myState1 = null;
81       myState2 = null;
82       myState3 = null;
83     }
84     catch (Throwable e) {
85       addSuppressedException(e);
86     }
87     finally {
88       super.tearDown();
89     }
90   }
91
92   public void testNoHistoryRecording() {
93     myHistory.onCommandStarted();
94     myHistory.onCommandFinished(getProject(), null);
95
96     assertFalse(myHistory.isBackAvailable());
97     assertFalse(myHistory.isForwardAvailable());
98   }
99
100   public void testNavigationRecording() {
101     makeNavigationChange(myState2);
102
103     assertTrue(myHistory.isBackAvailable());
104     assertFalse(myHistory.isForwardAvailable());
105
106     assertEquals(1, myHistory.getBackPlaces().size());
107   }
108
109   public void testMergingForwardPlaces() {
110     myEditorState = new MyState(true, "state1");
111     makeNavigationChange(new MyState(true, "state2"));
112
113     assertTrue(myHistory.isBackAvailable());
114     assertFalse(myHistory.isForwardAvailable());
115
116     assertEquals(1, myHistory.getBackPlaces().size());
117   }
118
119   public void testSimpleNavigation() {
120     pushTwoStates();
121
122     assertFalse(myHistory.isForwardAvailable());
123     assertTrue(myHistory.isBackAvailable());
124
125     myHistory.back();
126     assertTrue(myHistory.isBackAvailable());
127     assertTrue(myHistory.isForwardAvailable());
128     assertSame(myState2, myEditorState);
129
130     myHistory.back();
131     assertFalse(myHistory.isBackAvailable());
132     assertTrue(myHistory.isForwardAvailable());
133     assertSame(myState1, myEditorState);
134
135     myHistory.forward();
136     assertTrue(myHistory.isBackAvailable());
137     assertTrue(myHistory.isForwardAvailable());
138     assertSame(myState2, myEditorState);
139
140     myHistory.forward();
141     assertTrue(myHistory.isBackAvailable());
142     assertFalse(myHistory.isForwardAvailable());
143     assertSame(myState3, myEditorState);
144   }
145
146   public void testQueueCutOff() {
147     pushTwoStates();
148     myHistory.back();
149
150     assertTrue(myHistory.isBackAvailable());
151     assertTrue(myHistory.isForwardAvailable());
152
153     MyState newState = new MyState(false, "newState");
154     makeNavigationChange(newState);
155
156     assertTrue(myHistory.isBackAvailable());
157     assertFalse(myHistory.isForwardAvailable());
158
159     myHistory.back();
160     assertSame(myState2, myEditorState);
161     myHistory.back();
162     assertSame(myState1, myEditorState);
163     assertFalse(myHistory.isBackAvailable());
164   }
165
166   public void testRemoveInvalid() {
167     pushTwoStates();
168     assertTrue(myHistory.isBackAvailable());
169
170     mySelectedFile.myValid = false;
171     myHistory.removeInvalidFilesFromStacks();
172
173     assertFalse(myHistory.isBackAvailable());
174     assertFalse(myHistory.isForwardAvailable());
175   }
176
177
178   private void pushTwoStates() {
179     myState1 = new MyState(false, "state1");
180     myState2 = new MyState(false, "state2");
181     myState3 = new MyState(false, "state3");
182
183     myEditorState = myState1;
184     makeNavigationChange(myState2);
185     makeNavigationChange(myState3);
186   }
187
188   private void makeNavigationChange(MyState newState) {
189     myHistory.onCommandStarted();
190     myHistory.onSelectionChanged();
191     myHistory.onCommandFinished(getProject(), null);
192     myEditorState = newState;
193   }
194
195   private class EditorManager extends Mock.MyFileEditorManager {
196     @Override
197     public VirtualFile getFile(@NotNull FileEditor editor) {
198       return mySelectedFile;
199     }
200
201     @Override
202     @NotNull
203     public Pair<FileEditor[], FileEditorProvider[]> openFileWithProviders(@NotNull VirtualFile file, boolean focusEditor, boolean searchForSplitter) {
204       return Pair.create(new FileEditor[]{mySelectedEditor}, new FileEditorProvider[]{myProvider});
205     }
206
207     @Override
208     public FileEditorProvider getProvider(FileEditor editor) {
209       return myProvider;
210     }
211   }
212
213   private static class MyState implements FileEditorState {
214
215     private final boolean myCanBeMerged;
216     private final String myName;
217
218     MyState(boolean canBeMerged, String name) {
219       myCanBeMerged = canBeMerged;
220       myName = name;
221     }
222
223     @Override
224     public boolean canBeMergedWith(FileEditorState otherState, FileEditorStateLevel level) {
225       return myCanBeMerged;
226     }
227
228     public String toString() {
229       return myName;
230     }
231   }
232 }