Mercurial > hg4j
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; |