comparison test/org/tmatesoft/hg/test/TestHistory.java @ 520:1ee452f31187

Experimental support for inverse direction history walking. Refactored/streamlined cancellation in HgLogCommand and down the stack
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 21 Dec 2012 21:20:26 +0100
parents 0d5e1ea7955e
children 59e555c85da0
comparison
equal deleted inserted replaced
519:934037edbea0 520:1ee452f31187
40 import org.tmatesoft.hg.core.HgFileRenameHandlerMixin; 40 import org.tmatesoft.hg.core.HgFileRenameHandlerMixin;
41 import org.tmatesoft.hg.core.HgFileRevision; 41 import org.tmatesoft.hg.core.HgFileRevision;
42 import org.tmatesoft.hg.core.HgLogCommand; 42 import org.tmatesoft.hg.core.HgLogCommand;
43 import org.tmatesoft.hg.core.HgLogCommand.CollectHandler; 43 import org.tmatesoft.hg.core.HgLogCommand.CollectHandler;
44 import org.tmatesoft.hg.core.Nodeid; 44 import org.tmatesoft.hg.core.Nodeid;
45 import org.tmatesoft.hg.internal.AdapterPlug;
45 import org.tmatesoft.hg.repo.HgLookup; 46 import org.tmatesoft.hg.repo.HgLookup;
46 import org.tmatesoft.hg.repo.HgRepository; 47 import org.tmatesoft.hg.repo.HgRepository;
47 import org.tmatesoft.hg.test.LogOutputParser.Record; 48 import org.tmatesoft.hg.test.LogOutputParser.Record;
48 import org.tmatesoft.hg.util.Adaptable; 49 import org.tmatesoft.hg.util.Adaptable;
50 import org.tmatesoft.hg.util.CancelSupport;
51 import org.tmatesoft.hg.util.CancelledException;
49 import org.tmatesoft.hg.util.Pair; 52 import org.tmatesoft.hg.util.Pair;
50 import org.tmatesoft.hg.util.Path; 53 import org.tmatesoft.hg.util.Path;
51 54
52 55
53 /** 56 /**
91 @Test 94 @Test
92 public void testCompleteLog() throws Exception { 95 public void testCompleteLog() throws Exception {
93 changelogParser.reset(); 96 changelogParser.reset();
94 eh.run("hg", "log", "--debug"); 97 eh.run("hg", "log", "--debug");
95 List<HgChangeset> r = new HgLogCommand(repo).execute(); 98 List<HgChangeset> r = new HgLogCommand(repo).execute();
96 report("hg log - COMPLETE REPO HISTORY", r, true); 99 report("hg log - COMPLETE REPO HISTORY", r, true);
100
101 r = new HgLogCommand(repo).debugSwitch1().execute();
102 report("hg log - COMPLETE REPO HISTORY, FROM NEW TO OLD", r, false);
97 } 103 }
98 104
99 @Test 105 @Test
100 public void testFollowHistory() throws Exception { 106 public void testFollowHistory() throws Exception {
101 final Path f = Path.create("cmdline/org/tmatesoft/hg/console/Remote.java"); 107 final Path f = Path.create("cmdline/org/tmatesoft/hg/console/Remote.java");
191 // Command iterates old to new, rename comes after last fname1 revision. Since we don't follow 197 // Command iterates old to new, rename comes after last fname1 revision. Since we don't follow
192 // ancestry, it's the very last revision in fname1 history 198 // ancestry, it's the very last revision in fname1 history
193 String lastRevOfFname1 = "369c0882d477c11424a62eb4b791e86d1d4b6769"; 199 String lastRevOfFname1 = "369c0882d477c11424a62eb4b791e86d1d4b6769";
194 errorCollector.assertEquals(lastRevOfFname1, h.lastChangesetReportedAtRename.get(0).getNodeid().toString()); 200 errorCollector.assertEquals(lastRevOfFname1, h.lastChangesetReportedAtRename.get(0).getNodeid().toString());
195 report("HgChangesetHandler(renames: true, ancestry:false)", h.getChanges(), true); 201 report("HgChangesetHandler(renames: true, ancestry:false)", h.getChanges(), true);
196 202 //
197 // TODO direction 203 // Direction
204 h = new CollectWithRenameHandler();
205 new HgLogCommand(repo).file(fname2, true, false).debugSwitch1().execute(h);
206 // Identical rename shall be reported, at the same moment
207 errorCollector.assertEquals(1, h.renames.size());
208 rename = h.renames.get(0);
209 errorCollector.assertEquals(fname1, rename.first().getPath().toString());
210 errorCollector.assertEquals(fname2, rename.second().getPath().toString());
211 errorCollector.assertEquals(1, h.lastChangesetReportedAtRename.size());
212 // new to old, recently reported would be the very first revision fname2 pops up
213 String firstRevOfFname2 = "27e7a69373b74d42e75f3211e56510ff17d01370";
214 errorCollector.assertEquals(firstRevOfFname2, h.lastChangesetReportedAtRename.get(0).getNodeid().toString());
215 report("HgChangesetHandler(renames: true, ancestry:false)", h.getChanges(), false);
216 //
198 // TODO TreeChangeHandler 217 // TODO TreeChangeHandler
199 } 218 }
200 219
201 @Test 220 @Test
202 public void testFollowAncestryNotRenames() throws Exception { 221 public void testFollowAncestryNotRenames() throws Exception {
226 } 245 }
227 CollectWithRenameHandler h = new CollectWithRenameHandler(); 246 CollectWithRenameHandler h = new CollectWithRenameHandler();
228 new HgLogCommand(repo).file(fname2, false, true).execute(h); 247 new HgLogCommand(repo).file(fname2, false, true).execute(h);
229 errorCollector.assertEquals(0, h.renames.size()); 248 errorCollector.assertEquals(0, h.renames.size());
230 report("HgChangesetHandler(renames: false, ancestry:true)", h.getChanges(), fname2Follow, true, errorCollector); 249 report("HgChangesetHandler(renames: false, ancestry:true)", h.getChanges(), fname2Follow, true, errorCollector);
231 250 //
232 // TODO direction 251 // Direction
252 h = new CollectWithRenameHandler();
253 new HgLogCommand(repo).file(fname2, false, true).debugSwitch1().execute(h);
254 report("HgChangesetHandler(renames: false, ancestry:true)", h.getChanges(), fname2Follow, false/*!!!*/, errorCollector);
255 //
233 // TODO TreeChangeHandler 256 // TODO TreeChangeHandler
234 } 257 }
235 258
236 /** 259 /**
237 * output identical to that of "hg log --follow" 260 * output identical to that of "hg log --follow"
254 errorCollector.assertEquals(1, h.lastChangesetReportedAtRename.size()); 277 errorCollector.assertEquals(1, h.lastChangesetReportedAtRename.size());
255 String fname1BranchRevision = "6e668ff2940acb250c8627843f8116166fe5d5cd"; 278 String fname1BranchRevision = "6e668ff2940acb250c8627843f8116166fe5d5cd";
256 errorCollector.assertEquals(fname1BranchRevision, h.lastChangesetReportedAtRename.get(0).getNodeid().toString()); 279 errorCollector.assertEquals(fname1BranchRevision, h.lastChangesetReportedAtRename.get(0).getNodeid().toString());
257 // finally, match output 280 // finally, match output
258 report("HgChangesetHandler(renames: true, ancestry:true)", h.getChanges(), true); 281 report("HgChangesetHandler(renames: true, ancestry:true)", h.getChanges(), true);
259 // TODO direction 282 //
283 // Switch direction and compare, order shall match that from console
284 h = new CollectWithRenameHandler();
285 new HgLogCommand(repo).file(fname2, true, true).debugSwitch1().execute(h);
286 // Identical rename event shall be reported
287 errorCollector.assertEquals(1, h.renames.size());
288 rename = h.renames.get(0);
289 errorCollector.assertEquals(fname1, rename.first().getPath().toString());
290 errorCollector.assertEquals(fname2, rename.second().getPath().toString());
291 // new to old, recently reported would be the very first revision fname2 pops up
292 String firstRevOfFname2 = "27e7a69373b74d42e75f3211e56510ff17d01370";
293 errorCollector.assertEquals(firstRevOfFname2, h.lastChangesetReportedAtRename.get(0).getNodeid().toString());
294 report("HgChangesetHandler(renames: true, ancestry:true)", h.getChanges(), false /*do not reorder console results !!!*/);
295 //
260 // TreeChangeHandler in #testChangesetTreeFollowRenameAndAncestry 296 // TreeChangeHandler in #testChangesetTreeFollowRenameAndAncestry
297 }
298
299 /**
300 * @see TestAuxUtilities#testChangelogCancelSupport()
301 */
302 @Test
303 public void testLogCommandCancelSupport() throws Exception {
304 repo = Configuration.get().find("branches-1"); // any repo with more revisions
305 class BaseCancel extends TestAuxUtilities.CancelAtValue implements HgChangesetHandler {
306 BaseCancel(int limit) {
307 super(limit);
308 }
309 public void cset(HgChangeset changeset) throws HgCallbackTargetException {
310 nextValue(changeset.getRevisionIndex());
311 }
312 };
313 class ImplementsCancel extends BaseCancel implements CancelSupport {
314 ImplementsCancel(int limit) {
315 super(limit);
316 }
317 public void checkCancelled() throws CancelledException {
318 cancelImpl.checkCancelled();
319 }
320 };
321 class AdaptsToCancel extends BaseCancel implements Adaptable {
322 AdaptsToCancel(int limit) {
323 super(limit);
324 }
325 public <T> T getAdapter(Class<T> adapterClass) {
326 if (adapterClass == CancelSupport.class) {
327 return adapterClass.cast(cancelImpl);
328 }
329 return null;
330 }
331 }
332
333 BaseCancel insp = new ImplementsCancel(3);
334 try {
335 new HgLogCommand(repo).execute(insp);
336 errorCollector.fail("CancelSupport as implemented iface");
337 } catch (CancelledException ex) {
338 errorCollector.assertEquals("CancelSupport as implemented iface", insp.stopValue, insp.lastSeen);
339 }
340 insp = new AdaptsToCancel(5);
341 try {
342 new HgLogCommand(repo).execute(insp);
343 errorCollector.fail("Adaptable to CancelSupport");
344 } catch (CancelledException ex) {
345 errorCollector.assertEquals("Adaptable to CancelSupport", insp.stopValue, insp.lastSeen);
346 }
347 insp = new BaseCancel(9);
348 try {
349 new HgLogCommand(repo).set(insp.cancelImpl).execute(insp);
350 errorCollector.fail("cmd#set(CancelSupport)");
351 } catch (CancelledException e) {
352 errorCollector.assertEquals("cmd#set(CancelSupport)", insp.stopValue, insp.lastSeen);
353 }
261 } 354 }
262 355
263 private void report(String what, List<HgChangeset> r, boolean reverseConsoleResult) { 356 private void report(String what, List<HgChangeset> r, boolean reverseConsoleResult) {
264 final List<Record> consoleResult = changelogParser.getResult(); 357 final List<Record> consoleResult = changelogParser.getResult();
265 report(what, r, consoleResult, reverseConsoleResult, errorCollector); 358 report(what, r, consoleResult, reverseConsoleResult, errorCollector);
276 if (!consoleResultItr.hasNext()) { 369 if (!consoleResultItr.hasNext()) {
277 errorCollector.addError(new AssertionError("Ran out of console results while there are still hg4j results")); 370 errorCollector.addError(new AssertionError("Ran out of console results while there are still hg4j results"));
278 break; 371 break;
279 } 372 }
280 Record cr = consoleResultItr.next(); 373 Record cr = consoleResultItr.next();
374 // flags, not separate checkThat() because when lists are large, and do not match,
375 // number of failures may slow down test process significantly
281 int x = cs.getRevisionIndex() == cr.changesetIndex ? 0x1 : 0; 376 int x = cs.getRevisionIndex() == cr.changesetIndex ? 0x1 : 0;
282 x |= cs.getDate().toString().equals(cr.date) ? 0x2 : 0; 377 x |= cs.getDate().toString().equals(cr.date) ? 0x2 : 0;
283 x |= cs.getNodeid().toString().equals(cr.changesetNodeid) ? 0x4 : 0; 378 x |= cs.getNodeid().toString().equals(cr.changesetNodeid) ? 0x4 : 0;
284 x |= cs.getUser().equals(cr.user) ? 0x8 : 0; 379 x |= cs.getUser().equals(cr.user) ? 0x8 : 0;
285 // need to do trim() on comment because command-line template does, and there are 380 // need to do trim() on comment because command-line template does, and there are
395 eh.run("hg", "log", "--debug", "-b", "default", "-b", "test", "--cwd", repo.getLocation()); 490 eh.run("hg", "log", "--debug", "-b", "default", "-b", "test", "--cwd", repo.getLocation());
396 report("log -b default -b test" , new HgLogCommand(repo).branch("default").branch("test").execute(), true); 491 report("log -b default -b test" , new HgLogCommand(repo).branch("default").branch("test").execute(), true);
397 } 492 }
398 493
399 //// 494 ////
400
401 private static class AdapterPlug implements Adaptable {
402 private final Map<Class<?>, Object> adapters = new HashMap<Class<?>, Object>();
403 private final List<Class<?>> adapterUses = new ArrayList<Class<?>>();
404
405 public <T> void attachAdapter(Class<T> adapterClass, T instance) {
406 adapters.put(adapterClass, instance);
407 }
408
409 public <T> T getAdapter(Class<T> adapterClass) {
410 Object instance = adapters.get(adapterClass);
411 if (instance != null) {
412 adapterUses.add(adapterClass);
413 return adapterClass.cast(instance);
414 }
415 return null;
416 }
417
418 public int getAdapterUse(Class<?> adapterClass) {
419 int uses = 0;
420 for (Class<?> c : adapterUses) {
421 if (c == adapterClass) {
422 uses++;
423 }
424 }
425 return uses;
426 }
427 }
428 495
429 private final class TreeCollectHandler extends AdapterPlug implements HgChangesetTreeHandler { 496 private final class TreeCollectHandler extends AdapterPlug implements HgChangesetTreeHandler {
430 private final LinkedList<HgChangeset> cmdResult = new LinkedList<HgChangeset>(); 497 private final LinkedList<HgChangeset> cmdResult = new LinkedList<HgChangeset>();
431 private final boolean reverseResult; 498 private final boolean reverseResult;
432 boolean checkPrevInChildren = false; 499 boolean checkPrevInChildren = false;