move some tests to the platform
[idea/community.git] / java / java-tests / testSrc / com / intellij / psi / PsiDocumentManagerImplTest.java
1 package com.intellij.psi;
2
3 import com.intellij.ide.impl.ProjectUtil;
4 import com.intellij.mock.MockDocument;
5 import com.intellij.mock.MockPsiFile;
6 import com.intellij.openapi.application.ApplicationManager;
7 import com.intellij.openapi.editor.Document;
8 import com.intellij.openapi.editor.impl.DocumentImpl;
9 import com.intellij.openapi.editor.impl.event.DocumentEventImpl;
10 import com.intellij.openapi.fileEditor.FileDocumentManager;
11 import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
12 import com.intellij.openapi.project.Project;
13 import com.intellij.openapi.project.ex.ProjectManagerEx;
14 import com.intellij.openapi.vfs.LocalFileSystem;
15 import com.intellij.openapi.vfs.VirtualFile;
16 import com.intellij.psi.impl.DebugUtil;
17 import com.intellij.psi.impl.PsiDocumentManagerImpl;
18 import com.intellij.psi.impl.TextBlock;
19 import com.intellij.psi.impl.source.PsiFileImpl;
20 import com.intellij.testFramework.LeakHunter;
21 import com.intellij.testFramework.LightVirtualFile;
22 import com.intellij.testFramework.PlatformTestCase;
23 import com.intellij.util.Processor;
24 import com.intellij.util.concurrency.Semaphore;
25 import com.intellij.util.ui.UIUtil;
26
27 import java.io.File;
28 import java.lang.ref.Reference;
29 import java.util.concurrent.atomic.AtomicInteger;
30
31 public class PsiDocumentManagerImplTest extends PlatformTestCase {
32   private PsiDocumentManagerImpl getPsiDocumentManager() {
33     return (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(getProject());
34   }
35
36   public void testGetCachedPsiFile_NoFile() throws Exception {
37     final PsiFile file = getPsiDocumentManager().getCachedPsiFile(new MockDocument());
38     assertNull(file);
39   }
40
41   public void testGetPsiFile_NotRegisteredDocument() throws Exception {
42     final PsiFile file = getPsiDocumentManager().getPsiFile(new MockDocument());
43     assertNull(file);
44   }
45
46   public void testGetDocument_FirstGet() throws Exception {
47     VirtualFile vFile = createFile();
48     final PsiFile file = new MockPsiFile(vFile, getPsiManager());
49
50     final Document document = getPsiDocumentManager().getDocument(file);
51     assertNotNull(document);
52     assertSame(document, FileDocumentManager.getInstance().getDocument(vFile));
53   }
54
55   private static LightVirtualFile createFile() {
56     return new LightVirtualFile("foo.java");
57   }
58
59   public void testDocumentGced() throws Exception {
60     VirtualFile vFile = createFile();
61     PsiDocumentManagerImpl documentManager = getPsiDocumentManager();
62     long id = System.identityHashCode(documentManager.getDocument(getPsiManager().findFile(vFile)));
63
64     documentManager.commitAllDocuments();
65     UIUtil.dispatchAllInvocationEvents();
66     UIUtil.dispatchAllInvocationEvents();
67     assertEmpty(documentManager.getUncommittedDocuments());
68
69     LeakHunter.checkLeak(documentManager, DocumentImpl.class);
70     LeakHunter.checkLeak(documentManager, PsiFileImpl.class, new Processor<PsiFileImpl>() {
71       @Override
72       public boolean process(PsiFileImpl psiFile) {
73         return psiFile.getViewProvider().getVirtualFile().getFileSystem() instanceof LocalFileSystem;
74       }
75     });
76     //Class.forName("com.intellij.util.ProfilingUtil").getDeclaredMethod("forceCaptureMemorySnapshot").invoke(null);
77
78     Reference<Document> reference = vFile.getUserData(FileDocumentManagerImpl.DOCUMENT_KEY);
79     assertNotNull(reference);
80     for (int i=0;i<1000;i++) {
81       UIUtil.dispatchAllInvocationEvents();
82       if (reference.get() == null) break;
83       System.gc();
84     }
85     assertNull(documentManager.getCachedDocument(getPsiManager().findFile(vFile)));
86
87     Document newDoc = documentManager.getDocument(getPsiManager().findFile(vFile));
88     assertTrue(id != System.identityHashCode(newDoc));
89   }
90
91   public void testGetUncommittedDocuments_noDocuments() throws Exception {
92     assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
93   }
94
95   public void testGetUncommittedDocuments_documentChanged_DontProcessEvents() throws Exception {
96     PsiFile file = getPsiManager().findFile(createFile());
97
98     final Document document = getPsiDocumentManager().getDocument(file);
99
100     final TextBlock block = TextBlock.get(file);
101     ApplicationManager.getApplication().runWriteAction(new Runnable() {
102       public void run() {
103         block.performAtomically(new Runnable() {
104           @Override
105           public void run() {
106             getPsiDocumentManager().documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
107           }
108         });
109       }
110     });
111
112
113     assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
114   }
115
116   public void testGetUncommittedDocuments_documentNotRegistered() throws Exception {
117     final Document document = new MockDocument();
118
119     ApplicationManager.getApplication().runWriteAction(new Runnable() {
120       public void run() {
121         getPsiDocumentManager().documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
122       }
123     });
124
125
126     assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
127   }
128
129   public void testCommitDocument_RemovesFromUncommittedList() throws Exception {
130     PsiFile file = getPsiManager().findFile(createFile());
131
132     final Document document = getPsiDocumentManager().getDocument(file);
133
134     ApplicationManager.getApplication().runWriteAction(new Runnable() {
135       public void run() {
136         getPsiDocumentManager().documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
137       }
138     });
139
140
141     getPsiDocumentManager().commitDocument(document);
142     assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
143   }
144
145   public void testCommitAllDocument_RemovesFromUncommittedList() throws Exception {
146     PsiFile file = getPsiManager().findFile(createFile());
147
148     final Document document = getPsiDocumentManager().getDocument(file);
149
150     ApplicationManager.getApplication().runWriteAction(new Runnable() {
151       public void run() {
152         getPsiDocumentManager().documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
153       }
154     });
155
156
157     getPsiDocumentManager().commitAllDocuments();
158     assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
159   }
160
161   public void testDocumentFromAlienProjectDoesNotEndsUpInMyUncommittedList() throws Exception {
162     PsiFile file = getPsiManager().findFile(createFile());
163
164     final Document document = getPsiDocumentManager().getDocument(file);
165
166     File temp = createTempDirectory();
167     final Project alienProject = createProject(new File(temp, "alien.ipr"), DebugUtil.currentStackTrace());
168     boolean succ2 = ProjectManagerEx.getInstanceEx().openProject(alienProject);
169     assertTrue(succ2);
170
171
172     try {
173       PsiManager alienManager = PsiManager.getInstance(alienProject);
174       final String alienText = "alien";
175
176       LightVirtualFile alienVirt = new LightVirtualFile("foo.java", alienText);
177       final PsiFile alienFile = alienManager.findFile(alienVirt);
178       final PsiDocumentManagerImpl alienDocManager = (PsiDocumentManagerImpl)PsiDocumentManager.getInstance(alienProject);
179       final Document alienDocument = alienDocManager.getDocument(alienFile);
180       //alienDocument.putUserData(CACHED_VIEW_PROVIDER, new MockFileViewProvider(alienFile));
181       assertEquals(0, alienDocManager.getUncommittedDocuments().length);
182       assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
183
184       ApplicationManager.getApplication().runWriteAction(new Runnable() {
185         public void run() {
186           getPsiDocumentManager()
187             .documentChanged(new DocumentEventImpl(alienDocument, 0, "", "", alienDocument.getModificationStamp(), false));
188           assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
189           assertEquals(0, alienDocManager.getUncommittedDocuments().length);
190
191           alienDocManager.documentChanged(new DocumentEventImpl(alienDocument, 0, "", "", alienDocument.getModificationStamp(), false));
192           assertEquals(0, getPsiDocumentManager().getUncommittedDocuments().length);
193           assertEquals(1, alienDocManager.getUncommittedDocuments().length);
194
195           getPsiDocumentManager().documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
196           assertEquals(1, getPsiDocumentManager().getUncommittedDocuments().length);
197           assertEquals(1, alienDocManager.getUncommittedDocuments().length);
198
199           alienDocManager.documentChanged(new DocumentEventImpl(document, 0, "", "", document.getModificationStamp(), false));
200           assertEquals(1, getPsiDocumentManager().getUncommittedDocuments().length);
201           assertEquals(1, alienDocManager.getUncommittedDocuments().length);
202         }
203       });
204     }
205     finally {
206       ProjectUtil.closeAndDispose(alienProject);
207     }
208   }
209
210   public void testCommitInBackground() {
211     PsiFile file = getPsiManager().findFile(createFile());
212     assertTrue(file.isPhysical());
213     final Document document = getPsiDocumentManager().getDocument(file);
214
215     final Semaphore semaphore = new Semaphore();
216     semaphore.down();
217     getPsiDocumentManager().performWhenAllCommitted(new Runnable() {
218       @Override
219       public void run() {
220         assertTrue(getPsiDocumentManager().isCommitted(document));
221         semaphore.up();
222       }
223     });
224     waitAndPump(semaphore);
225     assertTrue(getPsiDocumentManager().isCommitted(document));
226
227     ApplicationManager.getApplication().runWriteAction(new Runnable() {
228       public void run() {
229         document.insertString(0, "class X {}");
230       }
231     });
232
233     semaphore.down();
234     getPsiDocumentManager().performWhenAllCommitted(new Runnable() {
235       @Override
236       public void run() {
237         assertTrue(getPsiDocumentManager().isCommitted(document));
238         semaphore.up();
239       }
240     });
241     waitAndPump(semaphore);
242     assertTrue(getPsiDocumentManager().isCommitted(document));
243
244     final AtomicInteger count = new AtomicInteger();
245     final Runnable action = new Runnable() {
246       @Override
247       public void run() {
248         count.incrementAndGet();
249       }
250     };
251
252     ApplicationManager.getApplication().runWriteAction(new Runnable() {
253       public void run() {
254         document.insertString(0, "/**/");
255         boolean executed = getPsiDocumentManager().cancelAndRunWhenAllCommitted("xxx", action);
256         assertFalse(executed);
257         executed = getPsiDocumentManager().cancelAndRunWhenAllCommitted("xxx", action);
258         assertFalse(executed);
259         assertEquals(0, count.get());
260       }
261     });
262
263     while (!getPsiDocumentManager().isCommitted(document)) {
264       UIUtil.dispatchAllInvocationEvents();
265     }
266     assertTrue(getPsiDocumentManager().isCommitted(document));
267     assertEquals(1, count.get());
268
269     count.set(0);
270     ApplicationManager.getApplication().runWriteAction(new Runnable() {
271       public void run() {
272         document.insertString(0, "/**/");
273         boolean executed = getPsiDocumentManager().performWhenAllCommitted(action);
274         assertFalse(executed);
275         executed = getPsiDocumentManager().performWhenAllCommitted(action);
276         assertFalse(executed);
277         assertEquals(0, count.get());
278       }
279     });
280
281     while (!getPsiDocumentManager().isCommitted(document)) {
282       UIUtil.dispatchAllInvocationEvents();
283     }
284     assertTrue(getPsiDocumentManager().isCommitted(document));
285     assertEquals(2, count.get());
286   }
287
288   private static void waitAndPump(Semaphore semaphore) {
289     while (!semaphore.waitFor(10)) {
290       UIUtil.dispatchAllInvocationEvents();
291     }
292   }
293
294   @Override
295   protected boolean isRunInWriteAction() {
296     return false;
297   }
298 }