Browse Source

add more control to indexState() return-value

The indexState() method was enhanced to be more configurable. A bitmask
controls which of the optional parts are reported. All data about
the worktree is not reported anymore by this method which makes the
interface more cleaner for users wanting to test only the state of the
index.
This was done because the previous version reported always so much
additional data that it was hard to write good assertions against it.

Change-Id: I9b481e97f8fcf3fcdbb785b801dc07bfa85dcc33
Signed-off-by: Christian Halstrick <christian.halstrick@sap.com>
Signed-off-by: Stefan Lay <stefan.lay@sap.com>
stable-0.9
Christian Halstrick 15 years ago committed by Stefan Lay
parent
commit
9a008d68b5
  1. 22
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java
  2. 114
      org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryTestCase.java

22
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RacyGitTests.java

@ -48,7 +48,6 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.TreeSet; import java.util.TreeSet;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.FileTreeIterator;
@ -118,7 +117,6 @@ public class RacyGitTests extends RepositoryTestCase {
public void testRacyGitDetection() throws IOException, public void testRacyGitDetection() throws IOException,
IllegalStateException, InterruptedException { IllegalStateException, InterruptedException {
DirCache dc;
TreeSet<Long> modTimes = new TreeSet<Long>(); TreeSet<Long> modTimes = new TreeSet<Long>();
File lastFile; File lastFile;
@ -137,7 +135,10 @@ public class RacyGitTests extends RepositoryTestCase {
// now add both files to the index. No racy git expected // now add both files to the index. No racy git expected
addToIndex(modTimes); addToIndex(modTimes);
assertEquals("[[a, modTime(index/file): t0/t0], [b, modTime(index/file): t0/t0]]", indexState(modTimes)); assertEquals(
"[a, mode:100644, time:t0, length:1, sha1:2e65efe2a145dda7ee51d1741299f848e5bf752e]" +
"[b, mode:100644, time:t0, length:1, sha1:63d8dbd40c23542e740659a7168a0ce3138ea748]",
indexState(SMUDGE | MOD_TIME | LENGTH | CONTENT_ID));
// Remember the last modTime of index file. All modifications times of // Remember the last modTime of index file. All modifications times of
// further modification are translated to this value so it looks that // further modification are translated to this value so it looks that
@ -151,15 +152,12 @@ public class RacyGitTests extends RepositoryTestCase {
// mod time. // mod time.
addToIndex(modTimes); addToIndex(modTimes);
dc = db.readDirCache(); db.readDirCache();
assertTrue(dc.getEntryCount() == 2); // although racily clean a should not be reported as being dirty
assertTrue(dc.getEntry("a").isSmudged()); assertEquals(
assertFalse(dc.getEntry("b").isSmudged()); "[a, mode:100644, time:t1, smudged, length:0]" +
"[b, mode:100644, time:t0, length:1]",
// although racily clean a should not be reported as beeing dirty indexState(SMUDGE|MOD_TIME|LENGTH));
assertEquals("[[a, modTime(index/file): t0/t0, unsmudged], [b, modTime(index/file): t1/t1]]", indexState(modTimes));
assertEquals("[[a, modTime(index/file): t0/t0, unsmudged], [b, modTime(index/file): t1/t1]]", indexState(modTimes));
} }
/** /**

114
org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/RepositoryTestCase.java

@ -52,19 +52,13 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TreeSet; import java.util.TreeSet;
import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheIterator; import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase; import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.storage.file.FileRepository; import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.treewalk.FileTreeIteratorWithTimeControl;
import org.eclipse.jgit.treewalk.NameConflictTreeWalk; import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
/** /**
@ -126,45 +120,85 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
trash = db.getWorkTree(); trash = db.getWorkTree();
} }
public String indexState(TreeSet<Long> modTimes) public static final int MOD_TIME = 1;
throws IllegalStateException, MissingObjectException,
IncorrectObjectTypeException, IOException { public static final int SMUDGE = 2;
public static final int LENGTH = 4;
public static final int CONTENT_ID = 8;
/**
* Represent the state of the index in one String. This representation is
* useful when writing tests which do assertions on the state of the index.
* By default information about path, mode, stage (if different from 0) is
* included. A bitmask controls which additional info about
* modificationTimes, smudge state and length is included.
* <p>
* The format of the returned string is described with this BNF:
*
* <pre>
* result = ( "[" path mode stage? time? smudge? length? sha1? "]" )* .
* mode = ", mode:" number .
* stage = ", stage:" number .
* time = ", time:t" timestamp-index .
* smudge = "" | ", smudged" .
* length = ", length:" number .
* sha1 = ", sha1:" hex-sha1 .
*
* 'stage' is only presented when the stage is different from 0. All
* reported time stamps are mapped to strings like "t0", "t1", ... "tn". The
* smallest reported time-stamp will be called "t0". This allows to write
* assertions against the string although the concrete value of the
* time stamps is unknown.
*
* @param includedOptions
* a bitmask constructed out of the constants {@link #MOD_TIME},
* {@link #SMUDGE}, {@link #LENGTH} and {@link #CONTENT_ID}
* controlling which info is present in the resulting string.
* @return a string encoding the index state
* @throws IllegalStateException
* @throws IOException
*/
public String indexState(int includedOptions)
throws IllegalStateException, IOException {
DirCache dc = db.readDirCache(); DirCache dc = db.readDirCache();
Map lookup = new HashMap(); StringBuilder sb = new StringBuilder();
List ret = new ArrayList(dc.getEntryCount()); TreeSet<Long> timeStamps = null;
// iterate once over the dircache just to collect all time stamps
if (0 != (includedOptions & MOD_TIME)) {
timeStamps = new TreeSet<Long>();
for (int i=0; i<dc.getEntryCount(); ++i)
timeStamps.add(Long.valueOf(dc.getEntry(i).getLastModified()));
}
// iterate again, now produce the result string
NameConflictTreeWalk tw = new NameConflictTreeWalk(db); NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
tw.reset(); tw.reset();
tw.addTree(new FileTreeIteratorWithTimeControl(db, modTimes));
tw.addTree(new DirCacheIterator(dc)); tw.addTree(new DirCacheIterator(dc));
boolean smudgedBefore;
while (tw.next()) { while (tw.next()) {
List entry = new ArrayList(4); DirCacheIterator dcIt = tw.getTree(0, DirCacheIterator.class);
FileTreeIteratorWithTimeControl fIt = tw.getTree(0, sb.append("["+tw.getPathString()+", mode:" + dcIt.getEntryFileMode());
FileTreeIteratorWithTimeControl.class); int stage = dcIt.getDirCacheEntry().getStage();
DirCacheIterator dcIt = tw.getTree(1, DirCacheIterator.class); if (stage != 0)
entry.add(tw.getPathString()); sb.append(", stage:" + stage);
entry.add("modTime(index/file): " if (0 != (includedOptions & MOD_TIME)) {
+ ((dcIt == null) ? "null" : lookup(Long.valueOf(dcIt sb.append(", time:t"+
.getDirCacheEntry().getLastModified()), "t%n", timeStamps.headSet(Long.valueOf(dcIt.getDirCacheEntry().getLastModified())).size());
lookup)) }
+ "/" if (0 != (includedOptions & SMUDGE))
+ ((fIt == null) ? "null" : lookup( if (dcIt.getDirCacheEntry().isSmudged())
Long.valueOf(fIt.getEntryLastModified()), "t%n", sb.append(", smudged");
lookup))); if (0 != (includedOptions & LENGTH))
smudgedBefore = (dcIt == null) ? false : dcIt.getDirCacheEntry() sb.append(", length:"
.isSmudged(); + Integer.toString(dcIt.getDirCacheEntry().getLength()));
if (fIt != null if (0 != (includedOptions & CONTENT_ID))
&& dcIt != null sb.append(", sha1:" + ObjectId.toString(dcIt
&& fIt.isModified(dcIt.getDirCacheEntry(), true, true, .getEntryObjectId()));
db.getFS())) sb.append("]");
entry.add("dirty");
if (dcIt != null && dcIt.getDirCacheEntry().isSmudged())
entry.add("smudged");
else if (smudgedBefore)
entry.add("unsmudged");
ret.add(entry);
} }
return ret.toString(); return sb.toString();
} }
/** /**
@ -186,7 +220,7 @@ public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
* @param lookupTable * @param lookupTable
* a table storing object-name mappings. * a table storing object-name mappings.
* @return a name of that object. Is not guaranteed to be unique. Use * @return a name of that object. Is not guaranteed to be unique. Use
* nameTemplates containing "%n" to always have uniqe names * nameTemplates containing "%n" to always have unique names
*/ */
public static String lookup(Object l, String nameTemplate, public static String lookup(Object l, String nameTemplate,
Map<Object, String> lookupTable) { Map<Object, String> lookupTable) {

Loading…
Cancel
Save