4050e3128b5103fbf3135850cfc147e573f46742
[idea/community.git] / java / java-tests / testSrc / com / intellij / openapi / roots / impl / DirectoryIndexTest.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.openapi.roots.impl;
17
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.command.WriteCommandAction;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.fileTypes.FileTypeManager;
22 import com.intellij.openapi.fileTypes.ex.FileTypeManagerEx;
23 import com.intellij.openapi.module.ModifiableModuleModel;
24 import com.intellij.openapi.module.Module;
25 import com.intellij.openapi.module.ModuleManager;
26 import com.intellij.openapi.module.StdModuleTypes;
27 import com.intellij.openapi.roots.*;
28 import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
29 import com.intellij.openapi.util.EmptyRunnable;
30 import com.intellij.openapi.util.io.FileUtil;
31 import com.intellij.openapi.vfs.*;
32 import com.intellij.testFramework.IdeaTestCase;
33 import com.intellij.testFramework.PlatformTestCase;
34 import com.intellij.testFramework.PsiTestUtil;
35 import gnu.trove.THashSet;
36 import org.jetbrains.annotations.NotNull;
37 import org.jetbrains.annotations.Nullable;
38 import org.jetbrains.jps.model.java.JavaResourceRootType;
39 import org.jetbrains.jps.model.java.JavaSourceRootType;
40 import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
41
42 import java.io.File;
43 import java.io.IOException;
44 import java.util.*;
45
46 import static java.util.Collections.singletonList;
47
48 @PlatformTestCase.WrapInCommand
49 public class DirectoryIndexTest extends IdeaTestCase {
50   private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.impl.DirectoryIndexTest");
51
52   private DirectoryIndexImpl myIndex;
53
54   private Module myModule2, myModule3;
55   private VirtualFile myRootVFile;
56   private VirtualFile myModule1Dir, myModule2Dir, myModule3Dir;
57   private VirtualFile mySrcDir1, mySrcDir2;
58   private VirtualFile myTestSrc1;
59   private VirtualFile myPack1Dir, myPack2Dir;
60   private VirtualFile myFileLibDir, myFileLibSrc, myFileLibCls;
61   private VirtualFile myLibDir, myLibSrcDir, myLibClsDir;
62   private VirtualFile myCvsDir;
63   private VirtualFile myExcludeDir;
64   private VirtualFile myOutputDir;
65   private VirtualFile myModule1OutputDir;
66   private VirtualFile myResDir, myTestResDir;
67   private VirtualFile myExcludedLibSrcDir, myExcludedLibClsDir;
68   private ProjectFileIndex myFileIndex;
69
70   @Override
71   protected void setUp() throws Exception {
72     super.setUp();
73
74     final File root = createTempDirectory();
75
76     ApplicationManager.getApplication().runWriteAction(new Runnable() {
77       @Override
78       public void run() {
79         try {
80           /*
81             root
82                 lib
83                     file.src
84                     file.cls
85                 module1
86                     src1
87                         pack1
88                         testSrc
89                             pack2
90                     res
91                     testRes
92                     lib
93                         src
94                           exc
95                         cls
96                           exc
97                     module2
98                         src2
99                             CVS
100                             excluded
101                 module3
102                 out
103                     module1
104           */
105           myRootVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(root);
106           assertNotNull(myRootVFile);
107
108           myFileLibDir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "lib");
109           myFileLibSrc = myFileLibDir.createChildData(DirectoryIndexTest.this, "file.src");
110           myFileLibCls = myFileLibDir.createChildData(DirectoryIndexTest.this, "file.cls");
111           myModule1Dir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "module1");
112           mySrcDir1 = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "src1");
113           myPack1Dir = mySrcDir1.createChildDirectory(DirectoryIndexTest.this, "pack1");
114           myTestSrc1 = mySrcDir1.createChildDirectory(DirectoryIndexTest.this, "testSrc");
115           myPack2Dir = myTestSrc1.createChildDirectory(DirectoryIndexTest.this, "pack2");
116           myResDir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "res");
117           myTestResDir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "testRes");
118
119           myLibDir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "lib");
120           myLibSrcDir = myLibDir.createChildDirectory(DirectoryIndexTest.this, "src");
121           myExcludedLibSrcDir = myLibSrcDir.createChildDirectory(DirectoryIndexTest.this, "exc");
122           myLibClsDir = myLibDir.createChildDirectory(DirectoryIndexTest.this, "cls");
123           myExcludedLibClsDir = myLibClsDir.createChildDirectory(DirectoryIndexTest.this, "exc");
124           myModule2Dir = myModule1Dir.createChildDirectory(DirectoryIndexTest.this, "module2");
125           mySrcDir2 = myModule2Dir.createChildDirectory(DirectoryIndexTest.this, "src2");
126           myCvsDir = mySrcDir2.createChildDirectory(DirectoryIndexTest.this, "CVS");
127           myExcludeDir = mySrcDir2.createChildDirectory(DirectoryIndexTest.this, "excluded");
128
129           myModule3Dir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "module3");
130
131           myOutputDir = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "out");
132           myModule1OutputDir = myOutputDir.createChildDirectory(DirectoryIndexTest.this, "module1");
133
134           getCompilerProjectExtension().setCompilerOutputUrl(myOutputDir.getUrl());
135           ModuleManager moduleManager = ModuleManager.getInstance(myProject);
136
137           // fill roots of module1
138           {
139             ModuleRootModificationUtil.setModuleSdk(myModule, null);
140             PsiTestUtil.addContentRoot(myModule, myModule1Dir);
141             PsiTestUtil.addSourceRoot(myModule, mySrcDir1);
142             PsiTestUtil.addSourceRoot(myModule, myTestSrc1, true);
143             PsiTestUtil.addSourceRoot(myModule, myResDir, JavaResourceRootType.RESOURCE);
144             PsiTestUtil.addSourceRoot(myModule, myTestResDir, JavaResourceRootType.TEST_RESOURCE);
145
146             ModuleRootModificationUtil.addModuleLibrary(myModule, "lib.js",
147                                                         singletonList(myFileLibCls.getUrl()), singletonList(myFileLibSrc.getUrl()));
148             PsiTestUtil.addExcludedRoot(myModule, myExcludedLibClsDir);
149             PsiTestUtil.addExcludedRoot(myModule, myExcludedLibSrcDir);
150           }
151
152           // fill roots of module2
153           {
154             VirtualFile moduleFile = myModule2Dir.createChildData(DirectoryIndexTest.this, "module2.iml");
155             myModule2 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId());
156
157             PsiTestUtil.addContentRoot(myModule2, myModule2Dir);
158             PsiTestUtil.addSourceRoot(myModule2, mySrcDir2);
159             PsiTestUtil.addExcludedRoot(myModule2, myExcludeDir);
160             ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib",
161                                                         singletonList(myLibClsDir.getUrl()), singletonList(myLibSrcDir.getUrl()),
162                                                         Arrays.asList(myExcludedLibClsDir.getUrl(), myExcludedLibSrcDir.getUrl()), DependencyScope.COMPILE, true);
163           }
164
165           // fill roots of module3
166           {
167             VirtualFile moduleFile = myModule3Dir.createChildData(DirectoryIndexTest.this, "module3.iml");
168             myModule3 = moduleManager.newModule(moduleFile.getPath(), StdModuleTypes.JAVA.getId());
169
170             PsiTestUtil.addContentRoot(myModule3, myModule3Dir);
171             ModuleRootModificationUtil.addDependency(myModule3, myModule2);
172           }
173         }
174         catch (IOException e) {
175           LOG.error(e);
176         }
177       }
178     });
179
180     myIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject);
181     myFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
182     // to not interfere with previous test firing vfs events
183     VirtualFileManager.getInstance().syncRefresh();
184   }
185
186   private CompilerProjectExtension getCompilerProjectExtension() {
187     final CompilerProjectExtension instance = CompilerProjectExtension.getInstance(myProject);
188     assertNotNull(instance);
189     return instance;
190   }
191
192   public void testDirInfos() throws IOException {
193     assertNotInProject(myRootVFile);
194
195     // beware: files in directory index
196     checkInfo(myFileLibSrc, null, false, true, "", null, myModule);
197     checkInfo(myFileLibCls, null, true, false, "", null, myModule);
198
199     checkInfo(myModule1Dir, myModule, false, false, null, null);
200     checkInfo(mySrcDir1, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
201     checkInfo(myPack1Dir, myModule, false, false, "pack1", JavaSourceRootType.SOURCE, myModule);
202     checkInfo(myTestSrc1, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
203     checkInfo(myPack2Dir, myModule, false, false, "pack2", JavaSourceRootType.TEST_SOURCE, myModule);
204     checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
205     checkInfo(myTestResDir, myModule, false, false, "", JavaResourceRootType.TEST_RESOURCE, myModule);
206
207     checkInfo(myLibDir, myModule, false, false, null, null);
208     checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
209     checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
210     
211     assertEquals(myLibSrcDir, assertInProject(myLibSrcDir).getSourceRoot());
212
213     checkInfo(myModule2Dir, myModule2, false, false, null, null);
214     checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
215     assertNotInProject(myCvsDir);
216     assertExcluded(myExcludeDir, myModule2);
217     assertExcluded(myExcludedLibClsDir, myModule);
218     assertExcluded(myExcludedLibSrcDir, myModule);
219
220     assertEquals(myModule1Dir, assertInProject(myLibClsDir).getContentRoot());
221
222     checkInfo(myModule3Dir, myModule3, false, false, null, null);
223
224     VirtualFile cvs = myPack1Dir.createChildDirectory(this, "CVS");
225     assertNotInProject(cvs);
226     assertNull(myFileIndex.getPackageNameByDirectory(cvs));
227   }
228
229   public void testDirsByPackageName() throws IOException {
230     checkPackage("", true, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibSrcDir, myLibClsDir);
231     checkPackage("", false, mySrcDir1, myTestSrc1, myResDir, myTestResDir, mySrcDir2, myLibClsDir);
232     
233     checkPackage("pack1", true, myPack1Dir);
234     checkPackage("pack1", false, myPack1Dir);
235     
236     checkPackage("pack2", true, myPack2Dir);
237     checkPackage("pack2", false, myPack2Dir);
238     
239     checkPackage(".pack2", false);
240     checkPackage(".pack2", true);
241
242     VirtualFile libClsPack = myLibClsDir.createChildDirectory(this, "pack1");
243     VirtualFile libSrcPack = myLibSrcDir.createChildDirectory(this, "pack1");
244     fireRootsChanged();
245     checkPackage("pack1", true, myPack1Dir, libSrcPack, libClsPack);
246     checkPackage("pack1", false, myPack1Dir, libClsPack);
247   }
248
249   public void testDirectoriesWithPackagePrefix() {
250     PsiTestUtil.addSourceRoot(myModule3, myModule3Dir);
251     WriteCommandAction.runWriteCommandAction(myProject, new Runnable() {
252       @Override
253       public void run() {
254         final ModifiableRootModel model = ModuleRootManager.getInstance(myModule3).getModifiableModel();
255         model.getContentEntries()[0].getSourceFolders()[0].setPackagePrefix("pack1");
256         model.commit();
257       }
258     });
259     checkPackage("pack1", true, myPack1Dir, myModule3Dir);
260   }
261
262   public void testPackageDirectoriesWithDots() throws IOException {
263     VirtualFile fooBar = mySrcDir1.createChildDirectory(this, "foo.bar");
264     VirtualFile goo1 = fooBar.createChildDirectory(this, "goo");
265     VirtualFile foo = mySrcDir2.createChildDirectory(this, "foo");
266     VirtualFile bar = foo.createChildDirectory(this, "bar");
267     VirtualFile goo2 = bar.createChildDirectory(this, "goo");
268
269     checkPackage("foo", false, foo);
270     checkPackage("foo.bar", false, bar, fooBar);
271     checkPackage("foo.bar.goo", false, goo2, goo1);
272   }
273
274   public void testCreateDir() throws Exception {
275     String path = mySrcDir1.getPath().replace('/', File.separatorChar);
276     assertTrue(new File(path + File.separatorChar + "dir1" + File.separatorChar + "dir2").mkdirs());
277     assertTrue(new File(path + File.separatorChar + "CVS").mkdirs());
278     VirtualFileManager.getInstance().syncRefresh();
279
280     myIndex.checkConsistency();
281   }
282
283   public void testDeleteDir() throws Exception {
284     VirtualFile subdir1 = mySrcDir1.createChildDirectory(this, "subdir1");
285     VirtualFile subdir2 = subdir1.createChildDirectory(this, "subdir2");
286     subdir2.createChildDirectory(this, "subdir3");
287
288     myIndex.checkConsistency();
289
290     subdir1.delete(this);
291
292     myIndex.checkConsistency();
293   }
294
295   public void testMoveDir() throws Exception {
296     VirtualFile subdir = mySrcDir2.createChildDirectory(this, "subdir1");
297     subdir.createChildDirectory(this, "subdir2");
298
299     myIndex.checkConsistency();
300
301     subdir.move(this, mySrcDir1);
302
303     myIndex.checkConsistency();
304   }
305
306   public void testRenameDir() throws Exception {
307     VirtualFile subdir = mySrcDir2.createChildDirectory(this, "subdir1");
308     subdir.createChildDirectory(this, "subdir2");
309
310     myIndex.checkConsistency();
311
312     subdir.rename(this, "abc.d");
313
314     myIndex.checkConsistency();
315   }
316
317   public void testRenameRoot() throws Exception {
318     myModule1Dir.rename(this, "newName");
319
320     myIndex.checkConsistency();
321   }
322
323   public void testMoveRoot() throws Exception {
324     myModule1Dir.move(this, myModule3Dir);
325
326     myIndex.checkConsistency();
327   }
328
329   public void testAddProjectDir() throws Exception {
330     new WriteCommandAction.Simple(getProject()) {
331       @Override
332       protected void run() throws Throwable {
333         VirtualFile newDir = myModule1Dir.getParent().createChildDirectory(DirectoryIndexTest.this, "newDir");
334         newDir.createChildDirectory(DirectoryIndexTest.this, "subdir");
335
336         myIndex.checkConsistency();
337         PsiTestUtil.addContentRoot(myModule, newDir);
338       }
339     }.execute().throwException();
340
341
342     myIndex.checkConsistency();
343   }
344
345   public void testChangeIgnoreList() throws Exception {
346     VirtualFile newDir = myModule1Dir.createChildDirectory(this, "newDir");
347     
348     myIndex.checkConsistency();
349     assertInProject(newDir);
350
351     final FileTypeManagerEx fileTypeManager = (FileTypeManagerEx)FileTypeManager.getInstance();
352     final String list = fileTypeManager.getIgnoredFilesList();
353     final String list1 = list + ";" + "newDir";
354     try {
355       ApplicationManager.getApplication().runWriteAction(new Runnable() {
356         @Override
357         public void run() {
358           fileTypeManager.setIgnoredFilesList(list1);
359         }
360       });
361       myIndex.checkConsistency();
362       assertNotInProject(newDir);
363     }
364     finally {
365       ApplicationManager.getApplication().runWriteAction(new Runnable() {
366         @Override
367         public void run() {
368           fileTypeManager.setIgnoredFilesList(list);
369         }
370       });
371       assertInProject(newDir);
372     }
373   }
374
375   public void testIgnoredFile() throws IOException {
376     VirtualFile ignoredFile = myModule1Dir.createChildData(this, "CVS");
377     DirectoryInfo info = myIndex.getInfoForFile(ignoredFile);
378     assertTrue(info.isIgnored());
379     assertTrue(myFileIndex.isExcluded(ignoredFile));
380     assertTrue(myFileIndex.isUnderIgnored(ignoredFile));
381   }
382
383   public void testAddModule() throws Exception {
384     myIndex.checkConsistency();
385
386     new WriteCommandAction.Simple(getProject()) {
387       @Override
388       protected void run() throws Throwable {
389         VirtualFile newModuleContent = myRootVFile.createChildDirectory(DirectoryIndexTest.this, "newModule");
390         newModuleContent.createChildDirectory(DirectoryIndexTest.this, "subDir");
391         ModuleManager moduleManager = ModuleManager.getInstance(myProject);
392         Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
393         PsiTestUtil.addContentRoot(module, newModuleContent);
394       }
395     }.execute().throwException();
396
397
398     myIndex.checkConsistency();
399   }
400
401   public void testModuleUnderIgnoredDir() throws IOException {
402     final VirtualFile ignored = myRootVFile.createChildDirectory(this, "RCS");
403     assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
404     assertTrue(myFileIndex.isExcluded(ignored));
405     assertTrue(myFileIndex.isUnderIgnored(ignored));
406     final VirtualFile module4 = ignored.createChildDirectory(this, "module4");
407     assertFalse(FileTypeManager.getInstance().isFileIgnored(module4));
408     assertTrue(myFileIndex.isExcluded(module4));
409     assertTrue(myFileIndex.isUnderIgnored(module4));
410
411     new WriteCommandAction.Simple(getProject()) {
412       @Override
413       protected void run() throws Throwable {
414         ModuleManager moduleManager = ModuleManager.getInstance(myProject);
415         Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
416         PsiTestUtil.addContentRoot(module, module4);
417         assertNotInProject(ignored);
418         checkInfo(module4, module, false, false, null, null);
419       }
420     }.execute().throwException();
421
422   }
423
424   public void testModuleInIgnoredDir() throws IOException {
425     final VirtualFile ignored = myRootVFile.createChildDirectory(this, "RCS");
426     assertTrue(FileTypeManager.getInstance().isFileIgnored(ignored));
427     
428     new WriteCommandAction.Simple(getProject()) {
429       @Override
430       protected void run() throws Throwable {
431         ModuleManager moduleManager = ModuleManager.getInstance(myProject);
432         ModifiableModuleModel model = moduleManager.getModifiableModel();
433         model.disposeModule(myModule);
434         model.disposeModule(myModule2);
435         model.disposeModule(myModule3);
436         model.commit();
437         Module module = moduleManager.newModule(myRootVFile.getPath() + "/newModule.iml", StdModuleTypes.JAVA.getId());
438         PsiTestUtil.addContentRoot(module, ignored);
439         checkInfo(ignored, module, false, false, null, null);
440       }
441     }.execute().throwException();
442   }
443
444   public void testExcludedDirsInLibraries() {
445     assertFalse(myFileIndex.isInLibraryClasses(myExcludedLibClsDir));
446     assertTrue(myFileIndex.isExcluded(myExcludedLibClsDir));
447     assertFalse(myFileIndex.isUnderIgnored(myExcludedLibClsDir));
448     assertFalse(myFileIndex.isInLibrarySource(myExcludedLibSrcDir));
449     assertTrue(myFileIndex.isExcluded(myExcludedLibSrcDir));
450     assertFalse(myFileIndex.isUnderIgnored(myExcludedLibSrcDir));
451   }
452
453   public void testExplicitExcludeOfInner() throws Exception {
454     PsiTestUtil.addExcludedRoot(myModule, myModule2Dir);
455
456     myIndex.checkConsistency();
457
458     checkInfo(myModule2Dir, myModule2, false, false, null, null);
459     checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
460   }
461
462   public void testResettingProjectOutputPath() throws Exception {
463     VirtualFile output1 = myModule1Dir.createChildDirectory(this, "output1");
464     VirtualFile output2 = myModule1Dir.createChildDirectory(this, "output2");
465
466     assertInProject(output1);
467     assertInProject(output2);
468
469     getCompilerProjectExtension().setCompilerOutputUrl(output1.getUrl());
470     fireRootsChanged();
471
472     assertExcluded(output1, myModule);
473     assertInProject(output2);
474
475     getCompilerProjectExtension().setCompilerOutputUrl(output2.getUrl());
476     fireRootsChanged();
477
478     assertInProject(output1);
479     assertExcluded(output2, myModule);
480   }
481
482   private void fireRootsChanged() {
483     ProjectRootManagerEx.getInstanceEx(getProject()).makeRootsChange(EmptyRunnable.getInstance(), false, true);
484   }
485
486   public void testModuleSourceAsLibrarySource() throws Exception {
487     ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Collections.<String>emptyList(), Arrays.asList(mySrcDir1.getUrl()));
488     
489     checkInfo(mySrcDir1, myModule, false, true, "", JavaSourceRootType.SOURCE, myModule, myModule);
490     OrderEntry[] entries = myIndex.getOrderEntries(myIndex.getInfoForFile(mySrcDir1));
491     assertInstanceOf(entries[0], LibraryOrderEntry.class);
492     assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
493
494     checkInfo(myTestSrc1, myModule, false, true, "testSrc", JavaSourceRootType.TEST_SOURCE, myModule, myModule);
495     entries = myIndex.getOrderEntries(myIndex.getInfoForFile(myTestSrc1));
496     assertInstanceOf(entries[0], LibraryOrderEntry.class);
497     assertInstanceOf(entries[1], ModuleSourceOrderEntry.class);
498   }
499
500   public void testModuleSourceAsLibraryClasses() throws Exception {
501     ModuleRootModificationUtil.addModuleLibrary(myModule, "someLib", Arrays.asList(mySrcDir1.getUrl()), Collections.<String>emptyList());
502     checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
503     assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(mySrcDir1))), ModuleSourceOrderEntry.class);
504   }
505
506   public void testModulesWithSameSourceContentRoot() {
507     // now our API allows this (ReformatCodeActionTest), although UI doesn't. Maybe API shouldn't allow it as well?
508     PsiTestUtil.addContentRoot(myModule2, myModule1Dir);
509     PsiTestUtil.addSourceRoot(myModule2, mySrcDir1);
510
511     checkInfo(myModule1Dir, myModule, false, false, null, null);
512     checkInfo(mySrcDir1, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule3, myModule);
513     checkInfo(myTestSrc1, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule3, myModule);
514     checkInfo(myResDir, myModule, false, false, "", JavaResourceRootType.RESOURCE, myModule);
515
516     checkInfo(mySrcDir2, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
517     assertEquals(myModule2Dir, myIndex.getInfoForFile(mySrcDir2).getContentRoot());
518   }
519
520   public void testModuleWithSameSourceRoot() {
521     PsiTestUtil.addSourceRoot(myModule2, mySrcDir1);
522     checkInfo(mySrcDir1, myModule2, false, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
523     checkInfo(myTestSrc1, myModule2, false, false, "testSrc", JavaSourceRootType.SOURCE, myModule2, myModule3);
524   }
525
526   public void testModuleContentUnderSourceRoot() {
527     PsiTestUtil.addContentRoot(myModule2, myPack1Dir);
528     checkInfo(myPack1Dir, myModule2, false, false, null, null);
529   }
530
531   public void testSameSourceAndOutput() {
532     PsiTestUtil.setCompilerOutputPath(myModule, mySrcDir1.getUrl(), false);
533     assertExcluded(mySrcDir1, myModule);
534   }
535
536   public void testExcludedDirShouldBeExcludedRightAfterItsCreation() throws Exception {
537     VirtualFile excluded = myModule1Dir.createChildDirectory(this, "excluded");
538     VirtualFile projectOutput = myModule1Dir.createChildDirectory(this, "projectOutput");
539     VirtualFile module2Output = myModule1Dir.createChildDirectory(this, "module2Output");
540     VirtualFile module2TestOutput = myModule2Dir.createChildDirectory(this, "module2TestOutput");
541
542     assertInProject(excluded);
543     assertInProject(projectOutput);
544     assertInProject(module2Output);
545     assertInProject(module2TestOutput);
546
547     getCompilerProjectExtension().setCompilerOutputUrl(projectOutput.getUrl());
548
549     PsiTestUtil.addExcludedRoot(myModule, excluded);
550     PsiTestUtil.setCompilerOutputPath(myModule2, module2Output.getUrl(), false);
551     PsiTestUtil.setCompilerOutputPath(myModule2, module2TestOutput.getUrl(), true);
552     PsiTestUtil.setExcludeCompileOutput(myModule2, true);
553
554     assertExcluded(excluded, myModule);
555     assertExcluded(projectOutput, myModule);
556     assertExcluded(module2Output, myModule);
557     assertExcluded(module2TestOutput, myModule2);
558
559     excluded.delete(this);
560     projectOutput.delete(this);
561     module2Output.delete(this);
562     module2TestOutput.delete(this);
563
564     final List<VirtualFile> created = new ArrayList<VirtualFile>();
565     VirtualFileListener l = new VirtualFileAdapter() {
566       @Override
567       public void fileCreated(@NotNull VirtualFileEvent e) {
568         VirtualFile file = e.getFile();
569         String fileName = e.getFileName();
570         assertExcluded(file, fileName.contains("module2TestOutput") ? myModule2 : myModule);
571         created.add(file);
572       }
573     };
574     VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
575     
576     excluded = myModule1Dir.createChildDirectory(this, excluded.getName());
577     assertExcluded(excluded, myModule);
578
579     projectOutput = myModule1Dir.createChildDirectory(this, projectOutput.getName());
580     assertExcluded(projectOutput, myModule);
581
582     module2Output = myModule1Dir.createChildDirectory(this, module2Output.getName());
583     assertExcluded(module2Output, myModule);
584
585     module2TestOutput = myModule2Dir.createChildDirectory(this, module2TestOutput.getName());
586     assertExcluded(module2TestOutput, myModule2);
587
588     assertEquals(created.toString(), 4, created.size());
589   }
590
591   public void testExcludesShouldBeRecognizedRightOnRefresh() throws Exception {
592     final VirtualFile dir = myModule1Dir.createChildDirectory(this, "dir");
593     final VirtualFile excluded = dir.createChildDirectory(this, "excluded");
594     PsiTestUtil.addExcludedRoot(myModule, excluded);
595     new WriteCommandAction.Simple(getProject()) {
596       @Override
597       protected void run() throws Throwable {
598         dir.delete(DirectoryIndexTest.this);
599       }
600     }.execute().throwException();
601
602
603     boolean created = new File(myModule1Dir.getPath(), "dir/excluded/foo").mkdirs();
604     assertTrue(created);
605
606     VirtualFileListener l = new VirtualFileAdapter() {
607       @Override
608       public void fileCreated(@NotNull VirtualFileEvent e) {
609         assertEquals("dir", e.getFileName());
610
611         VirtualFile file = e.getFile();
612         assertInProject(file);
613         assertExcluded(file.findFileByRelativePath("excluded"), myModule);
614         assertExcluded(file.findFileByRelativePath("excluded/foo"), myModule);
615       }
616     };
617
618     VirtualFileManager.getInstance().addVirtualFileListener(l, getTestRootDisposable());
619     VirtualFileManager.getInstance().syncRefresh();
620   }
621
622   public void testProcessingNestedContentRootsOfExcludedDirsOnCreation() {
623     String rootPath = myModule1Dir.getPath();
624     final File f = new File(rootPath, "excludedDir/dir/anotherContentRoot");
625     ApplicationManager.getApplication().runWriteAction(new Runnable() {
626       @Override
627       public void run() {
628         ModifiableRootModel rootModel = ModuleRootManager.getInstance(myModule).getModifiableModel();
629         rootModel.getContentEntries()[0]
630           .addExcludeFolder(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(f.getParentFile().getParent())));
631         rootModel.commit();
632
633         rootModel = ModuleRootManager.getInstance(myModule2).getModifiableModel();
634         rootModel.addContentEntry(VfsUtilCore.pathToUrl(FileUtil.toSystemIndependentName(f.getPath())));
635         rootModel.commit();
636
637         assertTrue(f.getPath(), f.exists() || f.mkdirs());
638         LocalFileSystem.getInstance().refresh(false);
639       }
640     });
641
642
643     assertExcluded(LocalFileSystem.getInstance().findFileByIoFile(f.getParentFile().getParentFile()), myModule);
644     assertInProject(LocalFileSystem.getInstance().findFileByIoFile(f));
645   }
646
647   public void testLibraryDirInContent() throws Exception {
648     ModuleRootModificationUtil.addModuleLibrary(myModule, myModule1Dir.getUrl());
649
650     myIndex.checkConsistency();
651
652     checkInfo(myModule1Dir, myModule, true, false, "", null, myModule);
653     checkInfo(mySrcDir1, myModule, true, false, "", JavaSourceRootType.SOURCE, myModule);
654
655     checkInfo(myModule2Dir, myModule2, true, false, "module2", null, myModule);
656     checkInfo(mySrcDir2, myModule2, true, false, "", JavaSourceRootType.SOURCE, myModule2, myModule3);
657     checkInfo(myExcludeDir, null, true, false, "module2.src2.excluded", null, myModule3);
658
659     checkInfo(myLibDir, myModule, true, false, "lib", null, myModule);
660     checkInfo(myLibClsDir, myModule, true, false, "", null, myModule2, myModule3);
661
662     //myModule is included into order entries instead of myModule2 because classes root for libraries dominates on source roots
663     checkInfo(myLibSrcDir, myModule, true, true, "", null, myModule, myModule3);
664     
665     checkInfo(myResDir, myModule, true, false, "", JavaResourceRootType.RESOURCE, myModule);
666     assertInstanceOf(assertOneElement(myIndex.getOrderEntries(assertInProject(myResDir))), ModuleSourceOrderEntry.class);
667
668     checkInfo(myExcludedLibSrcDir, null, true, false, "lib.src.exc", null, myModule3, myModule);
669     checkInfo(myExcludedLibClsDir, null, true, false, "lib.cls.exc", null, myModule3);
670
671     checkPackage("lib.src.exc", true, myExcludedLibSrcDir);
672     checkPackage("lib.cls.exc", true, myExcludedLibClsDir);
673     
674     checkPackage("lib.src", true);
675     checkPackage("lib.cls", true);
676     
677     checkPackage("exc", false);
678     checkPackage("exc", true);
679   }
680
681   public void testExcludeCompilerOutputOutsideOfContentRoot() throws Exception {
682     assertTrue(myFileIndex.isExcluded(myOutputDir));
683     assertFalse(myFileIndex.isUnderIgnored(myOutputDir));
684     assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
685     assertFalse(myFileIndex.isExcluded(myOutputDir.getParent()));
686     assertExcludedFromProject(myOutputDir);
687     assertExcludedFromProject(myModule1OutputDir);
688     String moduleOutputUrl = myModule1OutputDir.getUrl();
689
690     myOutputDir.delete(this);
691
692     PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, false);
693     myOutputDir = myRootVFile.createChildDirectory(this, "out");
694     myModule1OutputDir = myOutputDir.createChildDirectory(this, "module1");
695
696     assertExcludedFromProject(myOutputDir);
697     assertExcludedFromProject(myModule1OutputDir);
698     assertTrue(myFileIndex.isExcluded(myModule1OutputDir));
699
700     PsiTestUtil.setCompilerOutputPath(myModule, moduleOutputUrl, true);
701     PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, false);
702     PsiTestUtil.setCompilerOutputPath(myModule2, moduleOutputUrl, true);
703     PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, false);
704     PsiTestUtil.setCompilerOutputPath(myModule3, moduleOutputUrl, true);
705     
706     // now no module inherits project output dir, but it still should be project-excluded
707     assertExcludedFromProject(myOutputDir);
708
709     // project output inside module content shouldn't be projectExcludeRoot
710     VirtualFile projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
711     getCompilerProjectExtension().setCompilerOutputUrl(projectOutputUnderContent.getUrl());
712     fireRootsChanged();
713
714     assertNotExcluded(myOutputDir);
715     assertExcluded(projectOutputUnderContent, myModule);
716
717     projectOutputUnderContent.delete(this);
718     projectOutputUnderContent = myModule1Dir.createChildDirectory(this, "projectOutputUnderContent");
719     assertNotExcluded(myOutputDir);
720     assertExcluded(projectOutputUnderContent, myModule);
721   }
722
723   public void testFileContentAndSourceRoots() throws IOException {
724     VirtualFile fileRoot = myRootVFile.createChildData(this, "fileRoot.txt");
725     VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
726     VirtualFile fileTestSourceRoot = myRootVFile.createChildData(this, "fileTestSourceRoot.txt");
727
728     assertNotInProject(fileRoot);
729     assertFalse(myFileIndex.isInContent(fileRoot));
730     assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot));
731
732     ContentEntry contentEntry = PsiTestUtil.addContentRoot(myModule, fileRoot);
733     assertEquals(fileRoot, contentEntry.getFile());
734     checkInfo(fileRoot, myModule, false, false, "", null);
735     assertTrue(myFileIndex.isInContent(fileRoot));
736     assertFalse(myFileIndex.isInSource(fileRoot));
737  
738     PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
739     PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
740     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
741     assertTrue(myFileIndex.isInContent(fileSourceRoot));
742     assertTrue(myFileIndex.isInSource(fileSourceRoot));
743  
744     PsiTestUtil.addContentRoot(myModule, fileTestSourceRoot);
745     PsiTestUtil.addSourceRoot(myModule, fileTestSourceRoot, true);
746     checkInfo(fileTestSourceRoot, myModule, false, false, "", JavaSourceRootType.TEST_SOURCE, myModule);
747     assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
748     assertTrue(myFileIndex.isInSource(fileTestSourceRoot));
749
750     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
751
752     // removing file source root
753     PsiTestUtil.removeSourceRoot(myModule, fileTestSourceRoot);
754     checkInfo(fileTestSourceRoot, myModule, false, false, "", null);
755     assertTrue(myFileIndex.isInContent(fileTestSourceRoot));
756     assertFalse(myFileIndex.isInSource(fileTestSourceRoot));
757     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot, fileSourceRoot, fileTestSourceRoot), null);
758  
759     // removing file content root
760     PsiTestUtil.removeContentEntry(myModule, contentEntry.getFile());
761     assertNotInProject(fileRoot);
762     assertFalse(myFileIndex.isInContent(fileRoot));
763     assertFalse(myFileIndex.isInSource(fileRoot));
764     assertIteratedContent(myFileIndex, Arrays.asList(fileSourceRoot, fileTestSourceRoot), Arrays.asList(fileRoot));
765   }
766
767   private void assertIteratedContent(ProjectFileIndex fileIndex,
768                                      @Nullable List<VirtualFile> contains,
769                                      @Nullable List<VirtualFile> doesntContain) {
770     final Set<VirtualFile> collected = new THashSet<VirtualFile>();
771     fileIndex.iterateContent(new ContentIterator() {
772       @Override
773       public boolean processFile(VirtualFile fileOrDir) {
774         collected.add(fileOrDir);
775         return true;
776       }
777     });
778     if (contains != null) assertContainsElements(collected, contains);
779     if (doesntContain != null) assertDoesntContain(collected, doesntContain);
780   }
781
782   public void testFileSourceRootsUnderDirContentRoot() throws IOException {
783     VirtualFile fileSourceRoot = myModule1Dir.createChildData(this, "fileSourceRoot.txt");
784     assertTrue(myFileIndex.isInContent(fileSourceRoot));
785     assertFalse(myFileIndex.isInSource(fileSourceRoot));
786
787     PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
788     assertTrue(myFileIndex.isInContent(fileSourceRoot));
789     assertTrue(myFileIndex.isInSource(fileSourceRoot));
790     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
791
792     // removing file source root
793     PsiTestUtil.removeSourceRoot(myModule, fileSourceRoot);
794     assertTrue(myFileIndex.isInContent(fileSourceRoot));
795     assertFalse(myFileIndex.isInSource(fileSourceRoot));
796   }
797
798   public void testFileModuleExcludeRootUnderDirectoryRoot() throws IOException {
799     VirtualFile fileExcludeRoot = mySrcDir1.createChildData(this, "fileExcludeRoot.txt");
800     assertTrue(myFileIndex.isInContent(fileExcludeRoot));
801     assertTrue(myFileIndex.isInSource(fileExcludeRoot));
802     assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
803
804     PsiTestUtil.addExcludedRoot(myModule, fileExcludeRoot);
805     assertFalse(myFileIndex.isInContent(fileExcludeRoot));
806     assertFalse(myFileIndex.isInSource(fileExcludeRoot));
807     assertExcluded(fileExcludeRoot, myModule);
808     assertIteratedContent(myFileIndex, null, Arrays.asList(fileExcludeRoot));
809
810     // removing file exclude root
811     PsiTestUtil.removeExcludedRoot(myModule, fileExcludeRoot);
812     assertTrue(myFileIndex.isInContent(fileExcludeRoot));
813     assertTrue(myFileIndex.isInSource(fileExcludeRoot));
814     assertIteratedContent(myFileIndex, Arrays.asList(fileExcludeRoot), null);
815   }
816
817   public void testFileModuleExcludeRootUnderFileRoot() throws IOException {
818     VirtualFile fileRoot = myRootVFile.createChildData(this, "fileRoot.txt");
819     PsiTestUtil.addContentRoot(myModule, fileRoot);
820     checkInfo(fileRoot, myModule, false, false, "", null);
821     assertTrue(myFileIndex.isInContent(fileRoot));
822     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
823     
824     PsiTestUtil.addExcludedRoot(myModule, fileRoot);
825     assertFalse(myFileIndex.isInContent(fileRoot));
826     assertExcluded(fileRoot, myModule);
827     assertIteratedContent(myFileIndex, null, Arrays.asList(fileRoot));
828  
829     // removing file exclude root
830     PsiTestUtil.removeExcludedRoot(myModule, fileRoot);
831     checkInfo(fileRoot, myModule, false, false, "", null);
832     assertTrue(myFileIndex.isInContent(fileRoot));
833     assertIteratedContent(myFileIndex, Arrays.asList(fileRoot), null);
834   }
835
836   public void testFileLibraryInsideFolderLibrary() throws IOException {
837     VirtualFile file = myLibSrcDir.createChildData(this, "empty.txt");
838     ModuleRootModificationUtil.addModuleLibrary(myModule2, "lib2",
839                                                 Collections.<String>emptyList(), singletonList(file.getUrl()),
840                                                 Collections.<String>emptyList(), DependencyScope.COMPILE, true);
841
842     // same for the dir and for the file
843     checkInfo(file, myModule, false, true, "", null, myModule2, myModule3);
844     checkInfo(myLibSrcDir, myModule, false, true, "", null, myModule2, myModule3);
845   }
846
847   public void testFileContentRootsModifications() throws IOException {
848     VirtualFile temp = myRootVFile.createChildDirectory(this, "temp");
849
850     VirtualFile fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
851     assertNotInProject(fileSourceRoot);
852
853     PsiTestUtil.addContentRoot(myModule, fileSourceRoot);
854     PsiTestUtil.addSourceRoot(myModule, fileSourceRoot);
855     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
856     assertTrue(myFileIndex.isInContent(fileSourceRoot));
857     assertTrue(myFileIndex.isInSource(fileSourceRoot));
858
859     // delete and recreate
860     fileSourceRoot.delete(this);
861     assertNotInProject(fileSourceRoot);
862     assertFalse(myFileIndex.isInContent(fileSourceRoot));
863     assertFalse(myFileIndex.isInSource(fileSourceRoot));
864     fileSourceRoot = myRootVFile.createChildData(this, "fileSourceRoot.txt");
865     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
866     assertTrue(myFileIndex.isInContent(fileSourceRoot));
867     assertTrue(myFileIndex.isInSource(fileSourceRoot));
868
869     // delete and move from another dir 
870     fileSourceRoot.delete(this);
871     assertNotInProject(fileSourceRoot);
872     assertFalse(myFileIndex.isInContent(fileSourceRoot));
873     assertFalse(myFileIndex.isInSource(fileSourceRoot));
874     fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
875     assertNotInProject(fileSourceRoot);
876     fileSourceRoot.move(this, myRootVFile);
877     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
878     assertTrue(myFileIndex.isInContent(fileSourceRoot));
879     assertTrue(myFileIndex.isInSource(fileSourceRoot));
880
881     // delete and copy from another dir 
882     fileSourceRoot.delete(this);
883     assertNotInProject(fileSourceRoot);
884     assertFalse(myFileIndex.isInContent(fileSourceRoot));
885     assertFalse(myFileIndex.isInSource(fileSourceRoot));
886     fileSourceRoot = temp.createChildData(this, "fileSourceRoot.txt");
887     assertNotInProject(fileSourceRoot);
888     fileSourceRoot = fileSourceRoot.copy(this, myRootVFile, "fileSourceRoot.txt");
889     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
890     assertTrue(myFileIndex.isInContent(fileSourceRoot));
891     assertTrue(myFileIndex.isInSource(fileSourceRoot));
892     
893     // delete and rename from another file
894     fileSourceRoot.delete(this);
895     assertNotInProject(fileSourceRoot);
896     assertFalse(myFileIndex.isInContent(fileSourceRoot));
897     assertFalse(myFileIndex.isInSource(fileSourceRoot));
898     fileSourceRoot = myRootVFile.createChildData(this, "temp_file.txt");
899     assertNotInProject(fileSourceRoot);
900     fileSourceRoot.rename(this, "fileSourceRoot.txt");
901     checkInfo(fileSourceRoot, myModule, false, false, "", JavaSourceRootType.SOURCE, myModule);
902     assertTrue(myFileIndex.isInContent(fileSourceRoot));
903     assertTrue(myFileIndex.isInSource(fileSourceRoot));
904   }
905
906   private void checkInfo(VirtualFile file,
907                          @Nullable Module module,
908                          boolean isInLibrary,
909                          boolean isInLibrarySource,
910                          @Nullable String packageName, 
911                          @Nullable final JpsModuleSourceRootType<?> moduleSourceRootType,
912                          Module... modulesOfOrderEntries) {
913     DirectoryInfo info = assertInProject(file);
914     assertEquals(module, info.getModule());
915     if (moduleSourceRootType != null) {
916       assertTrue("isInModuleSource", info.isInModuleSource());
917       assertEquals(moduleSourceRootType, myIndex.getSourceRootType(info));
918     }
919     else {
920       assertFalse("isInModuleSource", info.isInModuleSource());
921     }
922     assertEquals(isInLibrary, info.hasLibraryClassRoot());
923     assertEquals(isInLibrarySource, info.isInLibrarySource());
924
925     if (file.isDirectory()) {
926       assertEquals(packageName, myFileIndex.getPackageNameByDirectory(file));
927     }
928
929     assertEquals(Arrays.toString(myIndex.getOrderEntries(info)), modulesOfOrderEntries.length, myIndex.getOrderEntries(info).length);
930     for (Module aModule : modulesOfOrderEntries) {
931       OrderEntry found = ModuleFileIndexImpl.findOrderEntryWithOwnerModule(aModule, myIndex.getOrderEntries(info));
932       assertNotNull("not found: " + aModule + " in " + Arrays.toString(myIndex.getOrderEntries(info)), found);
933     }
934   }
935
936   private void assertNotInProject(VirtualFile file) {
937     DirectoryInfo info = myIndex.getInfoForFile(file);
938     assertFalse(info.toString(), info.isInProject());
939     assertFalse(info.toString(), info.isExcluded());
940   }
941
942   private void assertExcluded(VirtualFile file, Module module) {
943     DirectoryInfo info = myIndex.getInfoForFile(file);
944     assertTrue(info.toString(), info.isExcluded());
945     assertEquals(module, info.getModule());
946   }
947
948   private DirectoryInfo assertInProject(VirtualFile file) {
949     DirectoryInfo info = myIndex.getInfoForFile(file);
950     assertTrue(file.toString(), info.isInProject());
951     myIndex.assertConsistency(info);
952     return info;
953   }
954
955   private void assertNotExcluded(VirtualFile file) {
956     assertFalse(myIndex.getInfoForFile(file).isExcluded());
957   }
958
959   private void assertExcludedFromProject(VirtualFile file) {
960     assertExcluded(file, null);
961   }
962
963   private void checkPackage(String packageName, boolean includeLibrarySources, VirtualFile... expectedDirs) {
964     VirtualFile[] actualDirs = myIndex.getDirectoriesByPackageName(packageName, includeLibrarySources).toArray(VirtualFile.EMPTY_ARRAY);
965     assertNotNull(actualDirs);
966     assertOrderedEquals(actualDirs, expectedDirs);
967
968     for (VirtualFile dir : expectedDirs) {
969       String actualName = myIndex.getPackageName(dir);
970       assertEquals("Invalid package name for dir " + dir + ": " + packageName, packageName, actualName);
971     }
972   }
973
974 }