Merge remote-tracking branch 'origin/master'
[idea/community.git] / platform / vcs-impl / testSrc / com / intellij / openapi / vcs / LocalChangesUnderRootsTest.java
1 package com.intellij.openapi.vcs;
2
3 import com.intellij.openapi.util.Pair;
4 import com.intellij.openapi.vcs.changes.Change;
5 import com.intellij.openapi.vcs.changes.ChangeListManager;
6 import com.intellij.openapi.vcs.changes.ContentRevision;
7 import com.intellij.openapi.vcs.changes.committed.MockAbstractVcs;
8 import com.intellij.testFramework.vcs.MockContentRevision;
9 import com.intellij.openapi.vcs.changes.ui.ChangesComparator;
10 import com.intellij.openapi.vcs.history.VcsRevisionNumber;
11 import com.intellij.openapi.vcs.impl.LocalChangesUnderRoots;
12 import com.intellij.openapi.vcs.impl.projectlevelman.AllVcses;
13 import com.intellij.openapi.vcs.impl.projectlevelman.AllVcsesI;
14 import com.intellij.openapi.vfs.VirtualFile;
15 import com.intellij.testFramework.PlatformTestCase;
16 import com.intellij.testFramework.VfsTestUtil;
17 import com.intellij.testFramework.vcs.MockChangeListManager;
18 import org.junit.Before;
19 import org.junit.Test;
20
21 import java.lang.reflect.Field;
22 import java.util.*;
23
24 /**
25  * @author Kirill Likhodedov
26  */
27 public class LocalChangesUnderRootsTest extends PlatformTestCase {
28
29   private LocalChangesUnderRoots myLocalChangesUnderRoots;
30   private MockChangeListManager myChangeListManager;
31   private VirtualFile myBaseDir;
32
33   @Before
34   protected void setUp() throws Exception {
35     super.setUp();
36
37     myChangeListManager = new MockChangeListManager();
38     myBaseDir = myProject.getBaseDir();
39     myLocalChangesUnderRoots = new LocalChangesUnderRoots(ChangeListManager.getInstance(myProject),
40                                                           ProjectLevelVcsManager.getInstance(myProject));
41
42     substituteChangeListManager();
43   }
44
45   // This is not good, but declaring MockChangeListManager might break other tests
46   private void substituteChangeListManager() throws NoSuchFieldException, IllegalAccessException {
47     Field myChangeManager = LocalChangesUnderRoots.class.getDeclaredField("myChangeManager");
48     myChangeManager.setAccessible(true);
49     myChangeManager.set(myLocalChangesUnderRoots, myChangeListManager);
50   }
51
52   @Test
53   public void testChangesInTwoGitRoots() {
54     AllVcsesI myVcses = AllVcses.getInstance(myProject);
55     myVcses.registerManually(new MockAbstractVcs(myProject, "Mock"));
56
57     List<VirtualFile> roots = createRootStructure(
58       Pair.create(myBaseDir.getPath(), "Mock"),
59       Pair.create("community", "Mock")
60     );
61
62     Change changeBeforeCommunity = createChangeForPath("a.txt");
63     Change changeAfterCommunity = createChangeForPath("readme.txt");
64     Change changeInCommunity = createChangeForPath("community/com.txt");
65     myChangeListManager.addChanges(changeBeforeCommunity, changeAfterCommunity, changeInCommunity);
66     
67     Map<VirtualFile, Collection<Change>> expected = new HashMap<VirtualFile, Collection<Change>>();
68     expected.put(roots.get(0), Arrays.asList(changeBeforeCommunity, changeAfterCommunity));
69     expected.put(roots.get(1), Arrays.asList(changeInCommunity));
70
71     Map<VirtualFile, Collection<Change>> changesUnderRoots = myLocalChangesUnderRoots.getChangesUnderRoots(roots);
72     assertEqualMaps(expected, changesUnderRoots);
73   }
74
75   private static void assertEqualMaps(Map<VirtualFile, Collection<Change>> expected, Map<VirtualFile, Collection<Change>> actual) {
76     assertEquals("Maps size is different. " + expectedActualMessage(expected, actual), expected.size(), actual.size());
77     for (Map.Entry<VirtualFile, Collection<Change>> expectedEntry : expected.entrySet()) {
78       VirtualFile root = expectedEntry.getKey();
79       if (!actual.containsKey(root)) {
80         fail("Didn't find root [" + root + "]. " + expectedActualMessage(expected, actual));
81       }
82       List<Change> expectedChanges = new ArrayList<Change>(expectedEntry.getValue());
83       List<Change> actualChanges = new ArrayList<Change>(actual.get(root));
84       Collections.sort(expectedChanges, ChangesComparator.getInstance(false));
85       Collections.sort(actualChanges, ChangesComparator.getInstance(false));
86       assertEquals("Changes not equal for root [" + root + "]. " + expectedActualMessage(expected, actual), expectedChanges, actualChanges);
87     }
88   }
89
90   private static String expectedActualMessage(Object expected, Object actual) {
91     return "\nExpected:\n " + expected + "\nActual:\n" + actual;
92   }
93
94   private List<VirtualFile> createRootStructure(Pair<String, String>... pathAndVcs) {
95     List<VirtualFile> roots = new ArrayList<VirtualFile>();
96     List<VcsDirectoryMapping> mappings = new ArrayList<VcsDirectoryMapping>();
97     for (Pair<String, String> pathAndVc : pathAndVcs) {
98       String path = pathAndVc.first;
99       String vcs = pathAndVc.second;
100       
101       VirtualFile vf;
102       if (path.equals(myBaseDir.getPath())) {
103         vf = myBaseDir;
104       } else {
105         vf = VfsTestUtil.createDir(myBaseDir, path);
106       }
107
108       mappings.add(new VcsDirectoryMapping(vf.getPath(), vcs));
109       roots.add(vf);
110     }
111     ProjectLevelVcsManager.getInstance(myProject).setDirectoryMappings(mappings);
112     return roots;
113   }
114
115   private Change createChangeForPath(String path) {
116     VirtualFile file = VfsTestUtil.createFile(myBaseDir, path);
117     FilePath filePath = new FilePathImpl(file);
118     ContentRevision beforeRevision = new MockContentRevision(filePath, new VcsRevisionNumber.Int(1));
119     ContentRevision afterRevision = new MockContentRevision(filePath, new VcsRevisionNumber.Int(2));
120     return new Change(beforeRevision, afterRevision);
121   }
122   
123 }