Skip to main content
summaryrefslogtreecommitdiffstats
blob: c4a4dc56cc9ae45ec91ed427f901432bf604e0be (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
package org.eclipse.team.tests.ccvs.core.provider;
/*
 * (c) Copyright IBM Corp. 2000, 2002.
 * All Rights Reserved.
 */
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.team.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.ccvs.core.CVSTag;
import org.eclipse.team.ccvs.core.CVSTeamProvider;
import org.eclipse.team.ccvs.core.ICVSFile;
import org.eclipse.team.core.IFileTypeRegistry;
import org.eclipse.team.core.TeamException;
import org.eclipse.team.core.TeamPlugin;
import org.eclipse.team.internal.ccvs.core.client.Command;
import org.eclipse.team.internal.ccvs.core.client.Command.KSubstOption;
import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot;
import org.eclipse.team.internal.ccvs.core.syncinfo.ResourceSyncInfo;
import org.eclipse.team.tests.ccvs.core.CVSTestSetup;
import org.eclipse.team.tests.ccvs.core.EclipseTest;
import org.eclipse.team.tests.ccvs.core.JUnitTestCase;

/*
 * This class tests both the CVSProvider and the CVSTeamProvider
 */
public class CVSProviderTest extends EclipseTest {

	/**
	 * Constructor for CVSProviderTest
	 */
	public CVSProviderTest() {
		super();
	}

	/**
	 * Constructor for CVSProviderTest
	 */
	public CVSProviderTest(String name) {
		super(name);
	}

	public static Test suite() {
		TestSuite suite = new TestSuite(CVSProviderTest.class);
		return new CVSTestSetup(suite);
		//return new CVSTestSetup(new CVSProviderTest("testVersionTag"));
	}
	
	public void testAdd() throws TeamException, CoreException {
		
		// Test add with cvsignores
		/*
		IProject project = createProject("testAdd", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt" });
		IFile file = project.getFile(".cvsignore");
		file.create(new ByteArrayInputStream("ignored.txt".getBytes()), false, null);
		file = project.getFile("ignored.txt");
		file.create(new ByteArrayInputStream("some text".getBytes()), false, null);
		file = project.getFile("notignored.txt");
		file.create(new ByteArrayInputStream("some more text".getBytes()), false, null);
		file = project.getFile("folder1/.cvsignore");
		file.create(new ByteArrayInputStream("ignored.txt".getBytes()), false, null);
		file = project.getFile("folder1/ignored.txt");
		file.create(new ByteArrayInputStream("some text".getBytes()), false, null);
		file = project.getFile("folder1/notignored.txt");
		file.create(new ByteArrayInputStream("some more text".getBytes()), false, null);
		
		getProvider(project).add(new IResource[] {project}, IResource.DEPTH_INFINITE, DEFAULT_MONITOR);
		
		assertTrue( ! CVSWorkspaceRoot.getCVSResourceFor(project.getFile("ignored.txt")).isManaged());
		assertTrue( ! CVSWorkspaceRoot.getCVSResourceFor(project.getFile("folder1/ignored.txt")).isManaged());
		
		assertTrue(CVSWorkspaceRoot.getCVSResourceFor(project.getFile("notignored.txt")).isManaged());
		assertTrue(CVSWorkspaceRoot.getCVSResourceFor(project.getFile("folder1/notignored.txt")).isManaged());
		assertTrue(CVSWorkspaceRoot.getCVSResourceFor(project.getFile(".cvsignore")).isManaged());
		assertTrue(CVSWorkspaceRoot.getCVSResourceFor(project.getFile("folder1/.cvsignore")).isManaged());
		*/
	}
	
	public void testDelete() throws TeamException, CoreException {
		// Not supported yet
	}
	
	public void testCheckin() throws TeamException, CoreException, IOException {
		IProject project = createProject("testCheckin", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt" });
		
		// Perform some operations on the project
		IResource[] newResources = buildResources(project, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
		IFile file = project.getFile("changed.txt");
		JUnitTestCase.waitMsec(1500);
		file.setContents(getRandomContents(), false, false, null);
		getProvider(project).add(newResources, IResource.DEPTH_ZERO, DEFAULT_MONITOR);
		getProvider(project).delete(new IResource[] {project.getFile("deleted.txt")}, DEFAULT_MONITOR);
		assertIsModified("testDeepCheckin: ", newResources);
		assertIsModified("testDeepCheckin: ", new IResource[] {project.getFile("deleted.txt"), project.getFile("changed.txt")});
		getProvider(project).checkin(new IResource[] {project}, IResource.DEPTH_INFINITE, DEFAULT_MONITOR);
		assertLocalStateEqualsRemote(project);
	}
	
	public void testMoved() throws TeamException, CoreException {
		// Not supported yet
	}
	
	public void testUpdate() throws TeamException, CoreException, IOException {
		// Create a test project, import it into cvs and check it out
		IProject project = createProject("testUpdate", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt" });

		// Check the project out under a different name
		IProject copy = checkoutCopy(project, "-copy");
		
		// Perform some operations on the copy
		addResources(copy, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
		IFile file = copy.getFile("changed.txt");
		JUnitTestCase.waitMsec(1500);
		file.setContents(getRandomContents(), false, false, null);
		getProvider(copy).delete(new IResource[] {copy.getFile("deleted.txt")}, DEFAULT_MONITOR);
		
		// Commit the copy and update the project
		getProvider(copy).checkin(new IResource[] {copy}, IResource.DEPTH_INFINITE, DEFAULT_MONITOR);
		getProvider(project).update(new IResource[] {project}, Command.NO_LOCAL_OPTIONS, null, null, DEFAULT_MONITOR);
		assertEquals(project, copy);
	}
	
	public void testVersionTag() throws TeamException, CoreException, IOException {
		
		// Create a test project, import it into cvs and check it out
		IProject project = createProject("testTag", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt" });
		
		// Perform some operations on the copy and commit
		IProject copy = checkoutCopy(project, "-copy");
		addResources(copy, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
		changeResources(copy, new String[] {"changed.txt"}, false);
		deleteResources(copy, new String[] {"deleted.txt"}, false);
		checkinResources(copy, true);
		
		// Tag the original, checkout the tag and compare with original
		CVSTag v1Tag = new CVSTag("v1", CVSTag.VERSION);
		tagProject(project, v1Tag);
		IProject v1 = checkoutCopy(project, v1Tag);
		assertEquals(project, v1);
		
		// Update original to HEAD and compare with copy including tags
		updateProject(project, null, false);
		assertEquals(project, copy, false, true);
		
		// Update copy to v1 and compare with the copy (including tag)
		updateProject(copy, v1Tag, false);
		assertEquals(copy, v1, false, true);
		
		// Update copy back to HEAD and compare with project (including tag)
		updateProject(copy, CVSTag.DEFAULT, false);
		assertEquals(project, copy, false, true);
	}
	
	public void testMakeBranch() throws TeamException, CoreException, IOException {
		// Create a test project
		IProject project = createProject("testSyncOnBranch", new String[] { "file1.txt", "file2.txt", "file3.txt", "folder1/", "folder1/a.txt", "folder1/b.txt"});

		// Make some local modifications including "cvs adds" and "cvs removes"
		addResources(project, new String[] {"folder1/c.txt"}, false);
		deleteResources(project, new String[] {"folder1/b.txt"}, false);
		changeResources(project, new String[] {"file2.txt"}, false);
		
		// Make the branch including a pre-version
		CVSTag version = new CVSTag("v1", CVSTag.BRANCH);
		CVSTag branch = new CVSTag("branch1", CVSTag.BRANCH);
		getProvider(project).makeBranch(new IResource[] {project}, version, branch, true, true, DEFAULT_MONITOR);

		// Checkout a copy from the branch and version and compare
		IProject branchCopy = checkoutCopy(project, branch);
		IProject versionCopy = checkoutCopy(project, branch);
		assertEquals(branchCopy, versionCopy, true, false);
		
		// Commit the project, update the branch and compare
		commitProject(project);
		updateProject(branchCopy, null, false);
		assertEquals(branchCopy, project, false, true);
	}
	 
	public void testPruning() throws TeamException, CoreException, IOException {
		// Create a project with empty folders
		CVSProviderPlugin.getPlugin().setPruneEmptyDirectories(false);
		IProject project = createProject("testPruning", new String[] { "file.txt", "folder1/", "folder2/folder3/" });

		// Disable pruning, checkout a copy and ensure original and copy are the same
		IProject copy = checkoutCopy(project, "-copy");
		assertEquals(project, copy); 

		// Enable pruning, update copy and ensure emtpy folders are gone
		CVSProviderPlugin.getPlugin().setPruneEmptyDirectories(true);
		updateProject(copy, null, false);
		assertDoesNotExistInFileSystem(new IResource[] {copy.getFolder("folder1"), copy.getFolder("folder2"), copy.getFolder("folder2/folder3")});
		
		// Checkout another copy and ensure that the two copies are the same (with pruning enabled)
		IProject copy2 = checkoutCopy(project, "-copy2");
		assertEquals(copy, copy2); 
		
		// Disable pruning, update copy and ensure directories come back
		CVSProviderPlugin.getPlugin().setPruneEmptyDirectories(false);
		updateProject(copy, null, false);
		assertEquals(project, copy);
		
		// Enable pruning again since it's the default
		CVSProviderPlugin.getPlugin().setPruneEmptyDirectories(true);
	}

	public void testGet() throws TeamException, CoreException, IOException {
		
		// Create a project
		IProject project = createProject("testGet", new String[] { "changed.txt", "deleted.txt", "folder1/", "folder1/a.txt" });
		
		// Checkout a copy and modify locally
		IProject copy = checkoutCopy(project, "-copy");
		addResources(copy, new String[] { "added.txt", "folder2/", "folder2/added.txt" }, false);
		deleteResources(copy, new String[] {"deleted.txt"}, false);
		IFile file = copy.getFile("changed.txt");
		JUnitTestCase.waitMsec(1500);
		file.setContents(getRandomContents(), false, false, null);

		// get the remote conetns
		getProvider(copy).get(new IResource[] {copy}, IResource.DEPTH_INFINITE, DEFAULT_MONITOR);
		assertEquals(project, copy);
	}
	
	public void testCleanLineDelimiters() throws TeamException, CoreException, IOException {
		// Create a project
		IProject project = getUniqueTestProject("testCleanLineDelimiters");
		IFile file = project.getFile("testfile");
		IProgressMonitor monitor = new NullProgressMonitor();

		// empty file
		setFileContents(file, "");
		CVSTeamProvider.cleanLineDelimiters(file, false, monitor);
		assertEqualsFileContents(file, "");
		CVSTeamProvider.cleanLineDelimiters(file, true, monitor);
		assertEqualsFileContents(file, "");
		
		// one byte
		setFileContents(file, "a");
		CVSTeamProvider.cleanLineDelimiters(file, false, monitor);
		assertEqualsFileContents(file, "a");
		CVSTeamProvider.cleanLineDelimiters(file, true, monitor);
		assertEqualsFileContents(file, "a");
		
		// single orphan carriage return (should be preserved)
		setFileContents(file, "\r");
		CVSTeamProvider.cleanLineDelimiters(file, false, monitor);
		assertEqualsFileContents(file, "\r");
		CVSTeamProvider.cleanLineDelimiters(file, true, monitor);
		assertEqualsFileContents(file, "\r");

		// single line feed
		setFileContents(file, "\n");
		CVSTeamProvider.cleanLineDelimiters(file, false, monitor);
		assertEqualsFileContents(file, "\n");
		CVSTeamProvider.cleanLineDelimiters(file, true, monitor);
		assertEqualsFileContents(file, "\r\n");
		
		// single carriage return line feed
		setFileContents(file, "\r\n");
		CVSTeamProvider.cleanLineDelimiters(file, true, monitor);
		assertEqualsFileContents(file, "\r\n");
		CVSTeamProvider.cleanLineDelimiters(file, false, monitor);
		assertEqualsFileContents(file, "\n");
		
		// mixed text with orphaned CR's
		setFileContents(file, "The \r\n quick brown \n fox \r\r\r\n jumped \n\n over \r\n the \n lazy dog.\r\n");
		CVSTeamProvider.cleanLineDelimiters(file, false, monitor);
		assertEqualsFileContents(file, "The \n quick brown \n fox \r\r\n jumped \n\n over \n the \n lazy dog.\n");
		setFileContents(file, "The \r\n quick brown \n fox \r\r\r\n jumped \n\n over \r\n the \n lazy dog.\r\n");
		CVSTeamProvider.cleanLineDelimiters(file, true, monitor);
		assertEqualsFileContents(file, "The \r\n quick brown \r\n fox \r\r\r\n jumped \r\n\r\n over \r\n the \r\n lazy dog.\r\n");
	}
	
	public void testKeywordSubstitution() throws TeamException, CoreException, IOException {
		testKeywordSubstitution(Command.KSUBST_BINARY); // -kb
		testKeywordSubstitution(Command.KSUBST_TEXT); // -ko
		testKeywordSubstitution(Command.KSUBST_TEXT_EXPAND); // -kkv
	}

	private void testKeywordSubstitution(KSubstOption ksubst) throws TeamException, CoreException, IOException {
		// setup some known file types
		TeamPlugin.getFileTypeRegistry().setValue("xbin", IFileTypeRegistry.BINARY);
		TeamPlugin.getFileTypeRegistry().setValue("xtxt", IFileTypeRegistry.TEXT);
		
		// create a test project
		IProject project = createProject("testKeywordSubstitution", new String[] { "dummy" });
		addResources(project, new String[] { "binary.xbin", "text.xtxt", "folder1/", "folder1/a.xtxt" }, true);
		addResources(project, new String[] { "added.xbin", "added.xtxt" }, false);
		assertHasKSubstOption(project, "binary.xbin", Command.KSUBST_BINARY);
		assertHasKSubstOption(project, "added.xbin", Command.KSUBST_BINARY);
		// XXX should these be KSUBST_TEXT instead?
		assertHasKSubstOption(project, "text.xtxt", Command.KSUBST_TEXT_EXPAND);
		assertHasKSubstOption(project, "folder1/a.xtxt", Command.KSUBST_TEXT_EXPAND);
		assertHasKSubstOption(project, "added.xtxt", Command.KSUBST_TEXT_EXPAND);
		
		// change keyword substitution
		IStatus status = getProvider(project).setKeywordSubstitution(new IResource[] { project },
			IResource.DEPTH_INFINITE, ksubst, null);
		assertTrue("Status should be ok, was: " + status.toString(), status.isOK());
		assertHasKSubstOption(project, "binary.xbin", ksubst);
		assertHasKSubstOption(project, "text.xtxt", ksubst);
		assertHasKSubstOption(project, "folder1/a.xtxt", ksubst);
		assertHasKSubstOption(project, "added.xtxt", ksubst);
		assertHasKSubstOption(project, "added.xbin", ksubst);

		// verify that substitution mode changed remotely and "added.xtxt", "added.xbin" don't exist
		IProject copy = checkoutCopy(project, "-copy");
		assertHasKSubstOption(copy, "binary.xbin", ksubst);
		assertHasKSubstOption(copy, "text.xtxt", ksubst);
		assertHasKSubstOption(copy, "folder1/a.xtxt", ksubst);
		assertDoesNotExistInWorkspace(copy.getFile("added.xtxt"));
		assertDoesNotExistInWorkspace(copy.getFile("added.xbin"));
		
		// commit added files then checkout the copy again
		commitResources(project, new String[] { "added.xbin", "added.xtxt" });
		IProject copy2 = checkoutCopy(project, "-copy2");
		assertHasKSubstOption(copy2, "added.xtxt", ksubst);
		assertHasKSubstOption(copy2, "added.xbin", ksubst);
		
		// verify that local contents are up to date
		assertEquals(project, copy2);
	}
	
	public static void setFileContents(IFile file, String string) throws CoreException {
		InputStream is = new ByteArrayInputStream(string.getBytes());
		if (file.exists()) {
			file.setContents(is, false /*force*/, true /*keepHistory*/, null);
		} else {
			file.create(is, false /*force*/, null);
		}
	}
	public static String getFileContents(IFile file) throws CoreException, IOException {
		StringBuffer buf = new StringBuffer();
		InputStream is = new BufferedInputStream(file.getContents());
		try {
			int c;
			while ((c = is.read()) != -1) buf.append((char)c);
		} finally {
			is.close();
		}
		return buf.toString();
	}
	
	public static void assertEqualsFileContents(IFile file, String string) throws CoreException, IOException {
		String other = getFileContents(file);
		assertEquals(string, other);
	}
	
	public static void assertHasKSubstOption(IContainer container, String filename, KSubstOption ksubst)
		throws TeamException {
		IFile file = container.getFile(new Path(filename));
		ICVSFile cvsFile = CVSWorkspaceRoot.getCVSFileFor(file);
		ResourceSyncInfo info = cvsFile.getSyncInfo();
		KSubstOption other = KSubstOption.fromMode(info.getKeywordMode());
		assertEquals(ksubst, other);
	}
}

Back to the top