diff options
Diffstat (limited to 'org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk')
18 files changed, 3193 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/AlwaysEmptyRevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/AlwaysEmptyRevQueueTest.java new file mode 100644 index 0000000000..d752501c12 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/AlwaysEmptyRevQueueTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +public class AlwaysEmptyRevQueueTest extends RevWalkTestCase { + private final AbstractRevQueue q = AbstractRevQueue.EMPTY_QUEUE; + + public void testEmpty() throws Exception { + assertNull(q.next()); + assertTrue(q.everbodyHasFlag(RevWalk.UNINTERESTING)); + assertFalse(q.anybodyHasFlag(RevWalk.UNINTERESTING)); + assertEquals(0, q.outputType()); + } + + public void testClear() throws Exception { + q.clear(); + testEmpty(); + } + + public void testAddFails() throws Exception { + try { + q.add(commit()); + fail("Did not throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + // expected result + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java new file mode 100644 index 0000000000..b3a92951b6 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/DateRevQueueTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +public class DateRevQueueTest extends RevQueueTestCase<DateRevQueue> { + protected DateRevQueue create() { + return new DateRevQueue(); + } + + public void testEmpty() throws Exception { + super.testEmpty(); + assertNull(q.peek()); + assertEquals(Generator.SORT_COMMIT_TIME_DESC, q.outputType()); + } + + public void testCloneEmpty() throws Exception { + q = new DateRevQueue(AbstractRevQueue.EMPTY_QUEUE); + assertNull(q.next()); + } + + public void testInsertOutOfOrder() throws Exception { + final RevCommit a = parse(commit()); + final RevCommit b = parse(commit(10, a)); + final RevCommit c1 = parse(commit(5, b)); + final RevCommit c2 = parse(commit(-50, b)); + + q.add(c2); + q.add(a); + q.add(b); + q.add(c1); + + assertCommit(c1, q.next()); + assertCommit(b, q.next()); + assertCommit(a, q.next()); + assertCommit(c2, q.next()); + assertNull(q.next()); + } + + public void testInsertTie() throws Exception { + final RevCommit a = parse(commit()); + final RevCommit b = parse(commit(0, a)); + { + q = create(); + q.add(a); + q.add(b); + + assertCommit(a, q.next()); + assertCommit(b, q.next()); + assertNull(q.next()); + } + { + q = create(); + q.add(b); + q.add(a); + + assertCommit(b, q.next()); + assertCommit(a, q.next()); + assertNull(q.next()); + } + } + + public void testCloneFIFO() throws Exception { + final RevCommit a = parse(commit()); + final RevCommit b = parse(commit(200, a)); + final RevCommit c = parse(commit(200, b)); + + final FIFORevQueue src = new FIFORevQueue(); + src.add(a); + src.add(b); + src.add(c); + + q = new DateRevQueue(src); + assertFalse(q.everbodyHasFlag(RevWalk.UNINTERESTING)); + assertFalse(q.anybodyHasFlag(RevWalk.UNINTERESTING)); + assertCommit(c, q.peek()); + assertCommit(c, q.peek()); + + assertCommit(c, q.next()); + assertCommit(b, q.next()); + assertCommit(a, q.next()); + assertNull(q.next()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java new file mode 100644 index 0000000000..3f4daab9f6 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FIFORevQueueTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.util.ArrayList; + +public class FIFORevQueueTest extends RevQueueTestCase<FIFORevQueue> { + protected FIFORevQueue create() { + return new FIFORevQueue(); + } + + public void testEmpty() throws Exception { + super.testEmpty(); + assertEquals(0, q.outputType()); + } + + public void testCloneEmpty() throws Exception { + q = new FIFORevQueue(AbstractRevQueue.EMPTY_QUEUE); + assertNull(q.next()); + } + + public void testAddLargeBlocks() throws Exception { + final ArrayList<RevCommit> lst = new ArrayList<RevCommit>(); + for (int i = 0; i < 3 * BlockRevQueue.Block.BLOCK_SIZE; i++) { + final RevCommit c = commit(); + lst.add(c); + q.add(c); + } + for (int i = 0; i < lst.size(); i++) + assertSame(lst.get(i), q.next()); + } + + public void testUnpopAtFront() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(); + final RevCommit c = commit(); + + q.add(a); + q.unpop(b); + q.unpop(c); + + assertSame(c, q.next()); + assertSame(b, q.next()); + assertSame(a, q.next()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java new file mode 100644 index 0000000000..d199f04ccb --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/FooterLineTest.java @@ -0,0 +1,323 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.util.List; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.RepositoryTestCase; + +public class FooterLineTest extends RepositoryTestCase { + public void testNoFooters_EmptyBody() { + final RevCommit commit = parse(""); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testNoFooters_NewlineOnlyBody1() { + final RevCommit commit = parse("\n"); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testNoFooters_NewlineOnlyBody5() { + final RevCommit commit = parse("\n\n\n\n\n"); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testNoFooters_OneLineBodyNoLF() { + final RevCommit commit = parse("this is a commit"); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testNoFooters_OneLineBodyWithLF() { + final RevCommit commit = parse("this is a commit\n"); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testNoFooters_ShortBodyNoLF() { + final RevCommit commit = parse("subject\n\nbody of commit"); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testNoFooters_ShortBodyWithLF() { + final RevCommit commit = parse("subject\n\nbody of commit\n"); + final List<FooterLine> footers = commit.getFooterLines(); + assertNotNull(footers); + assertEquals(0, footers.size()); + } + + public void testSignedOffBy_OneUserNoLF() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Signed-off-by: A. U. Thor <a@example.com>"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("A. U. Thor <a@example.com>", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); + } + + public void testSignedOffBy_OneUserWithLF() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Signed-off-by: A. U. Thor <a@example.com>\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("A. U. Thor <a@example.com>", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); + } + + public void testSignedOffBy_IgnoreWhitespace() { + // We only ignore leading whitespace on the value, trailing + // is assumed part of the value. + // + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Signed-off-by: A. U. Thor <a@example.com> \n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("A. U. Thor <a@example.com> ", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); + } + + public void testEmptyValueNoLF() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Signed-off-by:"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("", f.getValue()); + assertNull(f.getEmailAddress()); + } + + public void testEmptyValueWithLF() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Signed-off-by:\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("", f.getValue()); + assertNull(f.getEmailAddress()); + } + + public void testShortKey() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "K:V\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("K", f.getKey()); + assertEquals("V", f.getValue()); + assertNull(f.getEmailAddress()); + } + + public void testNonDelimtedEmail() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Acked-by: re@example.com\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Acked-by", f.getKey()); + assertEquals("re@example.com", f.getValue()); + assertEquals("re@example.com", f.getEmailAddress()); + } + + public void testNotEmail() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + "\n" + + "Acked-by: Main Tain Er\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(1, footers.size()); + + f = footers.get(0); + assertEquals("Acked-by", f.getKey()); + assertEquals("Main Tain Er", f.getValue()); + assertNull(f.getEmailAddress()); + } + + public void testSignedOffBy_ManyUsers() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + + "Not-A-Footer-Line: this line must not be read as a footer\n" + + "\n" // paragraph break, now footers appear in final block + + "Signed-off-by: A. U. Thor <a@example.com>\n" + + "CC: <some.mailing.list@example.com>\n" + + "Acked-by: Some Reviewer <sr@example.com>\n" + + "Signed-off-by: Main Tain Er <mte@example.com>\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(4, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("A. U. Thor <a@example.com>", f.getValue()); + assertEquals("a@example.com", f.getEmailAddress()); + + f = footers.get(1); + assertEquals("CC", f.getKey()); + assertEquals("<some.mailing.list@example.com>", f.getValue()); + assertEquals("some.mailing.list@example.com", f.getEmailAddress()); + + f = footers.get(2); + assertEquals("Acked-by", f.getKey()); + assertEquals("Some Reviewer <sr@example.com>", f.getValue()); + assertEquals("sr@example.com", f.getEmailAddress()); + + f = footers.get(3); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("Main Tain Er <mte@example.com>", f.getValue()); + assertEquals("mte@example.com", f.getEmailAddress()); + } + + public void testSignedOffBy_SkipNonFooter() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + + "Not-A-Footer-Line: this line must not be read as a footer\n" + + "\n" // paragraph break, now footers appear in final block + + "Signed-off-by: A. U. Thor <a@example.com>\n" + + "CC: <some.mailing.list@example.com>\n" + + "not really a footer line but we'll skip it anyway\n" + + "Acked-by: Some Reviewer <sr@example.com>\n" + + "Signed-off-by: Main Tain Er <mte@example.com>\n"); + final List<FooterLine> footers = commit.getFooterLines(); + FooterLine f; + + assertNotNull(footers); + assertEquals(4, footers.size()); + + f = footers.get(0); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("A. U. Thor <a@example.com>", f.getValue()); + + f = footers.get(1); + assertEquals("CC", f.getKey()); + assertEquals("<some.mailing.list@example.com>", f.getValue()); + + f = footers.get(2); + assertEquals("Acked-by", f.getKey()); + assertEquals("Some Reviewer <sr@example.com>", f.getValue()); + + f = footers.get(3); + assertEquals("Signed-off-by", f.getKey()); + assertEquals("Main Tain Er <mte@example.com>", f.getValue()); + } + + public void testFilterFootersIgnoreCase() { + final RevCommit commit = parse("subject\n\nbody of commit\n" + + "Not-A-Footer-Line: this line must not be read as a footer\n" + + "\n" // paragraph break, now footers appear in final block + + "Signed-Off-By: A. U. Thor <a@example.com>\n" + + "CC: <some.mailing.list@example.com>\n" + + "Acked-by: Some Reviewer <sr@example.com>\n" + + "signed-off-by: Main Tain Er <mte@example.com>\n"); + final List<String> footers = commit.getFooterLines("signed-off-by"); + + assertNotNull(footers); + assertEquals(2, footers.size()); + + assertEquals("A. U. Thor <a@example.com>", footers.get(0)); + assertEquals("Main Tain Er <mte@example.com>", footers.get(1)); + } + + private RevCommit parse(final String msg) { + final StringBuilder buf = new StringBuilder(); + buf.append("tree " + ObjectId.zeroId().name() + "\n"); + buf.append("author A. U. Thor <a@example.com> 1 +0000\n"); + buf.append("committer A. U. Thor <a@example.com> 1 +0000\n"); + buf.append("\n"); + buf.append(msg); + + final RevWalk walk = new RevWalk(db); + walk.setRetainBody(true); + final RevCommit c = new RevCommit(ObjectId.zeroId()); + c.parseCanonical(walk, Constants.encode(buf.toString())); + return c; + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java new file mode 100644 index 0000000000..7676a71503 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/LIFORevQueueTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.util.ArrayList; +import java.util.Collections; + +public class LIFORevQueueTest extends RevQueueTestCase<LIFORevQueue> { + protected LIFORevQueue create() { + return new LIFORevQueue(); + } + + public void testEmpty() throws Exception { + super.testEmpty(); + assertEquals(0, q.outputType()); + } + + public void testCloneEmpty() throws Exception { + q = new LIFORevQueue(AbstractRevQueue.EMPTY_QUEUE); + assertNull(q.next()); + } + + public void testAddLargeBlocks() throws Exception { + final ArrayList<RevCommit> lst = new ArrayList<RevCommit>(); + for (int i = 0; i < 3 * BlockRevQueue.Block.BLOCK_SIZE; i++) { + final RevCommit c = commit(); + lst.add(c); + q.add(c); + } + Collections.reverse(lst); + for (int i = 0; i < lst.size(); i++) + assertSame(lst.get(i), q.next()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java new file mode 100644 index 0000000000..7dddeee205 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/ObjectWalkTest.java @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +public class ObjectWalkTest extends RevWalkTestCase { + protected ObjectWalk objw; + + protected RevWalk createRevWalk() { + return objw = new ObjectWalk(db); + } + + public void testNoCommits() throws Exception { + assertNull(objw.next()); + assertNull(objw.nextObject()); + } + + public void testTwoCommitsEmptyTree() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + markStart(b); + + assertCommit(b, objw.next()); + assertCommit(a, objw.next()); + assertNull(objw.next()); + + assertSame(emptyTree, objw.nextObject()); + assertNull(objw.nextObject()); + } + + public void testOneCommitOneTreeTwoBlob() throws Exception { + final RevBlob f0 = blob("0"); + final RevBlob f1 = blob("1"); + final RevTree t = tree(file("0", f0), file("1", f1), file("2", f1)); + final RevCommit a = commit(t); + markStart(a); + + assertCommit(a, objw.next()); + assertNull(objw.next()); + + assertSame(t, objw.nextObject()); + assertSame(f0, objw.nextObject()); + assertSame(f1, objw.nextObject()); + assertNull(objw.nextObject()); + } + + public void testTwoCommitTwoTreeTwoBlob() throws Exception { + final RevBlob f0 = blob("0"); + final RevBlob f1 = blob("1"); + final RevBlob f2 = blob("0v2"); + final RevTree ta = tree(file("0", f0), file("1", f1), file("2", f1)); + final RevTree tb = tree(file("0", f2), file("1", f1), file("2", f1)); + final RevCommit a = commit(ta); + final RevCommit b = commit(tb, a); + markStart(b); + + assertCommit(b, objw.next()); + assertCommit(a, objw.next()); + assertNull(objw.next()); + + assertSame(tb, objw.nextObject()); + assertSame(f2, objw.nextObject()); + assertSame(f1, objw.nextObject()); + + assertSame(ta, objw.nextObject()); + assertSame(f0, objw.nextObject()); + + assertNull(objw.nextObject()); + } + + public void testTwoCommitDeepTree1() throws Exception { + final RevBlob f0 = blob("0"); + final RevBlob f1 = blob("0v2"); + final RevTree ta = tree(file("a/b/0", f0)); + final RevTree tb = tree(file("a/b/1", f1)); + final RevCommit a = commit(ta); + final RevCommit b = commit(tb, a); + markStart(b); + + assertCommit(b, objw.next()); + assertCommit(a, objw.next()); + assertNull(objw.next()); + + assertSame(tb, objw.nextObject()); + assertSame(get(tb, "a"), objw.nextObject()); + assertSame(get(tb, "a/b"), objw.nextObject()); + assertSame(f1, objw.nextObject()); + + assertSame(ta, objw.nextObject()); + assertSame(get(ta, "a"), objw.nextObject()); + assertSame(get(ta, "a/b"), objw.nextObject()); + assertSame(f0, objw.nextObject()); + + assertNull(objw.nextObject()); + } + + public void testTwoCommitDeepTree2() throws Exception { + final RevBlob f1 = blob("1"); + final RevTree ta = tree(file("a/b/0", f1), file("a/c/q", f1)); + final RevTree tb = tree(file("a/b/1", f1), file("a/c/q", f1)); + final RevCommit a = commit(ta); + final RevCommit b = commit(tb, a); + markStart(b); + + assertCommit(b, objw.next()); + assertCommit(a, objw.next()); + assertNull(objw.next()); + + assertSame(tb, objw.nextObject()); + assertSame(get(tb, "a"), objw.nextObject()); + assertSame(get(tb, "a/b"), objw.nextObject()); + assertSame(f1, objw.nextObject()); + assertSame(get(tb, "a/c"), objw.nextObject()); + + assertSame(ta, objw.nextObject()); + assertSame(get(ta, "a"), objw.nextObject()); + assertSame(get(ta, "a/b"), objw.nextObject()); + + assertNull(objw.nextObject()); + } + + public void testCull() throws Exception { + final RevBlob f1 = blob("1"); + final RevBlob f2 = blob("2"); + final RevBlob f3 = blob("3"); + final RevBlob f4 = blob("4"); + + final RevTree ta = tree(file("a/1", f1), file("c/3", f3)); + final RevCommit a = commit(ta); + + final RevTree tb = tree(file("a/1", f2), file("c/3", f3)); + final RevCommit b1 = commit(tb, a); + final RevCommit b2 = commit(tb, b1); + + final RevTree tc = tree(file("a/1", f4)); + final RevCommit c1 = commit(tc, a); + final RevCommit c2 = commit(tc, c1); + + markStart(b2); + markUninteresting(c2); + + assertCommit(b2, objw.next()); + assertCommit(b1, objw.next()); + assertNull(objw.next()); + + assertTrue(a.has(RevFlag.UNINTERESTING)); + assertTrue(ta.has(RevFlag.UNINTERESTING)); + assertTrue(f1.has(RevFlag.UNINTERESTING)); + assertTrue(f3.has(RevFlag.UNINTERESTING)); + + assertSame(tb, objw.nextObject()); + assertSame(get(tb, "a"), objw.nextObject()); + assertSame(f2, objw.nextObject()); + assertNull(objw.nextObject()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java new file mode 100644 index 0000000000..b7e84419c9 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevCommitParseTest.java @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2008-2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.io.ByteArrayOutputStream; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.RepositoryTestCase; + +public class RevCommitParseTest extends RepositoryTestCase { + public void testParse_NoParents() throws Exception { + final ObjectId treeId = id("9788669ad918b6fcce64af8882fc9a81cb6aba67"); + final String authorName = "A U. Thor"; + final String authorEmail = "a_u_thor@example.com"; + final int authorTime = 1218123387; + + final String committerName = "C O. Miter"; + final String committerEmail = "comiter@example.com"; + final int committerTime = 1218123390; + final StringBuilder body = new StringBuilder(); + + body.append("tree "); + body.append(treeId.name()); + body.append("\n"); + + body.append("author "); + body.append(authorName); + body.append(" <"); + body.append(authorEmail); + body.append("> "); + body.append(authorTime); + body.append(" +0700\n"); + + body.append("committer "); + body.append(committerName); + body.append(" <"); + body.append(committerEmail); + body.append("> "); + body.append(committerTime); + body.append(" -0500\n"); + + body.append("\n"); + + final RevWalk rw = new RevWalk(db); + final RevCommit c; + + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + assertNull(c.getTree()); + assertNull(c.parents); + + c.parseCanonical(rw, body.toString().getBytes("UTF-8")); + assertNotNull(c.getTree()); + assertEquals(treeId, c.getTree().getId()); + assertSame(rw.lookupTree(treeId), c.getTree()); + + assertNotNull(c.parents); + assertEquals(0, c.parents.length); + assertEquals("", c.getFullMessage()); + + final PersonIdent cAuthor = c.getAuthorIdent(); + assertNotNull(cAuthor); + assertEquals(authorName, cAuthor.getName()); + assertEquals(authorEmail, cAuthor.getEmailAddress()); + + final PersonIdent cCommitter = c.getCommitterIdent(); + assertNotNull(cCommitter); + assertEquals(committerName, cCommitter.getName()); + assertEquals(committerEmail, cCommitter.getEmailAddress()); + } + + private RevCommit create(final String msg) throws Exception { + final StringBuilder b = new StringBuilder(); + b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"); + b.append("author A U. Thor <a_u_thor@example.com> 1218123387 +0700\n"); + b.append("committer C O. Miter <c@example.com> 1218123390 -0500\n"); + b.append("\n"); + b.append(msg); + + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toString().getBytes("UTF-8")); + return c; + } + + public void testParse_WeirdHeaderOnlyCommit() throws Exception { + final StringBuilder b = new StringBuilder(); + b.append("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"); + b.append("author A U. Thor <a_u_thor@example.com> 1218123387 +0700\n"); + b.append("committer C O. Miter <c@example.com> 1218123390 -0500\n"); + + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toString().getBytes("UTF-8")); + + assertEquals("", c.getFullMessage()); + assertEquals("", c.getShortMessage()); + } + + public void testParse_implicit_UTF8_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8")); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("UTF-8")); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertSame(Constants.CHARSET, c.getEncoding()); + assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); + assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); + assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c.getFullMessage()); + } + + public void testParse_implicit_mixed_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8")); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("ISO-8859-1")); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertSame(Constants.CHARSET, c.getEncoding()); + assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); + assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); + assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c.getFullMessage()); + } + + /** + * Test parsing of a commit whose encoding is given and works. + * + * @throws Exception + */ + public void testParse_explicit_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("EUC-JP")); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("EUC-JP")); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("EUC-JP")); + b.write("encoding euc_JP\n".getBytes("EUC-JP")); + b.write("\n".getBytes("EUC-JP")); + b.write("\u304d\u308c\u3044\n".getBytes("EUC-JP")); + b.write("\n".getBytes("EUC-JP")); + b.write("Hi\n".getBytes("EUC-JP")); + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("EUC-JP", c.getEncoding().name()); + assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); + assertEquals("\u304d\u308c\u3044", c.getShortMessage()); + assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage()); + } + + /** + * This is a twisted case, but show what we expect here. We can revise the + * expectations provided this case is updated. + * + * What happens here is that an encoding us given, but data is not encoded + * that way (and we can detect it), so we try other encodings. + * + * @throws Exception + */ + public void testParse_explicit_bad_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8")); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("ISO-8859-1")); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8")); + b.write("encoding EUC-JP\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Hi\n".getBytes("UTF-8")); + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("EUC-JP", c.getEncoding().name()); + assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); + assertEquals("\u304d\u308c\u3044", c.getShortMessage()); + assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage()); + } + + /** + * This is a twisted case too, but show what we expect here. We can revise the + * expectations provided this case is updated. + * + * What happens here is that an encoding us given, but data is not encoded + * that way (and we can detect it), so we try other encodings. Here data could + * actually be decoded in the stated encoding, but we override using UTF-8. + * + * @throws Exception + */ + public void testParse_explicit_bad_encoded2() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("tree 9788669ad918b6fcce64af8882fc9a81cb6aba67\n".getBytes("UTF-8")); + b.write("author F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n".getBytes("UTF-8")); + b.write("committer C O. Miter <c@example.com> 1218123390 -0500\n".getBytes("UTF-8")); + b.write("encoding ISO-8859-1\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Hi\n".getBytes("UTF-8")); + final RevCommit c; + c = new RevCommit(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); // bogus id + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("ISO-8859-1", c.getEncoding().name()); + assertEquals("F\u00f6r fattare", c.getAuthorIdent().getName()); + assertEquals("\u304d\u308c\u3044", c.getShortMessage()); + assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage()); + } + + public void testParse_NoMessage() throws Exception { + final String msg = ""; + final RevCommit c = create(msg); + assertEquals(msg, c.getFullMessage()); + assertEquals(msg, c.getShortMessage()); + } + + public void testParse_OnlyLFMessage() throws Exception { + final RevCommit c = create("\n"); + assertEquals("\n", c.getFullMessage()); + assertEquals("", c.getShortMessage()); + } + + public void testParse_ShortLineOnlyNoLF() throws Exception { + final String shortMsg = "This is a short message."; + final RevCommit c = create(shortMsg); + assertEquals(shortMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_ShortLineOnlyEndLF() throws Exception { + final String shortMsg = "This is a short message."; + final String fullMsg = shortMsg + "\n"; + final RevCommit c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_ShortLineOnlyEmbeddedLF() throws Exception { + final String fullMsg = "This is a\nshort message."; + final String shortMsg = fullMsg.replace('\n', ' '); + final RevCommit c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_ShortLineOnlyEmbeddedAndEndingLF() throws Exception { + final String fullMsg = "This is a\nshort message.\n"; + final String shortMsg = "This is a short message."; + final RevCommit c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_GitStyleMessage() throws Exception { + final String shortMsg = "This fixes a bug."; + final String body = "We do it with magic and pixie dust and stuff.\n" + + "\n" + "Signed-off-by: A U. Thor <author@example.com>\n"; + final String fullMsg = shortMsg + "\n" + "\n" + body; + final RevCommit c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + private static ObjectId id(final String str) { + return ObjectId.fromString(str); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java new file mode 100644 index 0000000000..13f1cfc4cc --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevFlagSetTest.java @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.util.Arrays; +import java.util.Iterator; + +public class RevFlagSetTest extends RevWalkTestCase { + public void testEmpty() { + final RevFlagSet set = new RevFlagSet(); + assertEquals(0, set.mask); + assertEquals(0, set.size()); + assertNotNull(set.iterator()); + assertFalse(set.iterator().hasNext()); + } + + public void testAddOne() { + final String flagName = "flag"; + final RevFlag flag = rw.newFlag(flagName); + assertTrue(0 != flag.mask); + assertSame(flagName, flag.name); + + final RevFlagSet set = new RevFlagSet(); + assertTrue(set.add(flag)); + assertFalse(set.add(flag)); + assertEquals(flag.mask, set.mask); + assertEquals(1, set.size()); + final Iterator<RevFlag> i = set.iterator(); + assertTrue(i.hasNext()); + assertSame(flag, i.next()); + assertFalse(i.hasNext()); + } + + public void testAddTwo() { + final RevFlag flag1 = rw.newFlag("flag_1"); + final RevFlag flag2 = rw.newFlag("flag_2"); + assertTrue((flag1.mask & flag2.mask) == 0); + + final RevFlagSet set = new RevFlagSet(); + assertTrue(set.add(flag1)); + assertTrue(set.add(flag2)); + assertEquals(flag1.mask | flag2.mask, set.mask); + assertEquals(2, set.size()); + } + + public void testContainsAll() { + final RevFlag flag1 = rw.newFlag("flag_1"); + final RevFlag flag2 = rw.newFlag("flag_2"); + final RevFlagSet set1 = new RevFlagSet(); + assertTrue(set1.add(flag1)); + assertTrue(set1.add(flag2)); + + assertTrue(set1.containsAll(set1)); + assertTrue(set1.containsAll(Arrays + .asList(new RevFlag[] { flag1, flag2 }))); + + final RevFlagSet set2 = new RevFlagSet(); + set2.add(rw.newFlag("flag_3")); + assertFalse(set1.containsAll(set2)); + } + + public void testEquals() { + final RevFlag flag1 = rw.newFlag("flag_1"); + final RevFlag flag2 = rw.newFlag("flag_2"); + final RevFlagSet set = new RevFlagSet(); + assertTrue(set.add(flag1)); + assertTrue(set.add(flag2)); + + assertTrue(new RevFlagSet(set).equals(set)); + assertTrue(new RevFlagSet(Arrays.asList(new RevFlag[] { flag1, flag2 })) + .equals(set)); + } + + public void testRemove() { + final RevFlag flag1 = rw.newFlag("flag_1"); + final RevFlag flag2 = rw.newFlag("flag_2"); + final RevFlagSet set = new RevFlagSet(); + assertTrue(set.add(flag1)); + assertTrue(set.add(flag2)); + + assertTrue(set.remove(flag1)); + assertFalse(set.remove(flag1)); + assertEquals(flag2.mask, set.mask); + assertFalse(set.contains(flag1)); + } + + public void testContains() { + final RevFlag flag1 = rw.newFlag("flag_1"); + final RevFlag flag2 = rw.newFlag("flag_2"); + final RevFlagSet set = new RevFlagSet(); + set.add(flag1); + assertTrue(set.contains(flag1)); + assertFalse(set.contains(flag2)); + assertFalse(set.contains("bob")); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java new file mode 100644 index 0000000000..87ecaa8c53 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevObjectTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.Constants; + +public class RevObjectTest extends RevWalkTestCase { + public void testId() throws Exception { + final RevCommit a = commit(); + assertSame(a, a.getId()); + } + + public void testEqualsIsIdentity() throws Exception { + final RevCommit a1 = commit(); + final RevCommit b1 = commit(); + + assertTrue(a1.equals(a1)); + assertTrue(a1.equals((Object) a1)); + assertFalse(a1.equals(b1)); + + assertFalse(a1.equals(a1.copy())); + assertFalse(a1.equals((Object) a1.copy())); + assertFalse(a1.equals("")); + + final RevWalk rw2 = new RevWalk(db); + final RevCommit a2 = rw2.parseCommit(a1); + final RevCommit b2 = rw2.parseCommit(b1); + assertNotSame(a1, a2); + assertNotSame(b1, b2); + + assertFalse(a1.equals(a2)); + assertFalse(b1.equals(b2)); + + assertEquals(a1.hashCode(), a2.hashCode()); + assertEquals(b1.hashCode(), b2.hashCode()); + + assertTrue(AnyObjectId.equals(a1, a2)); + assertTrue(AnyObjectId.equals(b1, b2)); + } + + public void testRevObjectTypes() throws Exception { + assertEquals(Constants.OBJ_TREE, emptyTree.getType()); + assertEquals(Constants.OBJ_COMMIT, commit().getType()); + assertEquals(Constants.OBJ_BLOB, blob("").getType()); + assertEquals(Constants.OBJ_TAG, tag("emptyTree", emptyTree).getType()); + } + + public void testHasRevFlag() throws Exception { + final RevCommit a = commit(); + assertFalse(a.has(RevFlag.UNINTERESTING)); + a.flags |= RevWalk.UNINTERESTING; + assertTrue(a.has(RevFlag.UNINTERESTING)); + } + + public void testHasAnyFlag() throws Exception { + final RevCommit a = commit(); + final RevFlag flag1 = rw.newFlag("flag1"); + final RevFlag flag2 = rw.newFlag("flag2"); + final RevFlagSet s = new RevFlagSet(); + s.add(flag1); + s.add(flag2); + + assertFalse(a.hasAny(s)); + a.flags |= flag1.mask; + assertTrue(a.hasAny(s)); + } + + public void testHasAllFlag() throws Exception { + final RevCommit a = commit(); + final RevFlag flag1 = rw.newFlag("flag1"); + final RevFlag flag2 = rw.newFlag("flag2"); + final RevFlagSet s = new RevFlagSet(); + s.add(flag1); + s.add(flag2); + + assertFalse(a.hasAll(s)); + a.flags |= flag1.mask; + assertFalse(a.hasAll(s)); + a.flags |= flag2.mask; + assertTrue(a.hasAll(s)); + } + + public void testAddRevFlag() throws Exception { + final RevCommit a = commit(); + final RevFlag flag1 = rw.newFlag("flag1"); + final RevFlag flag2 = rw.newFlag("flag2"); + assertEquals(0, a.flags); + + a.add(flag1); + assertEquals(flag1.mask, a.flags); + + a.add(flag2); + assertEquals(flag1.mask | flag2.mask, a.flags); + } + + public void testAddRevFlagSet() throws Exception { + final RevCommit a = commit(); + final RevFlag flag1 = rw.newFlag("flag1"); + final RevFlag flag2 = rw.newFlag("flag2"); + final RevFlagSet s = new RevFlagSet(); + s.add(flag1); + s.add(flag2); + + assertEquals(0, a.flags); + + a.add(s); + assertEquals(flag1.mask | flag2.mask, a.flags); + } + + public void testRemoveRevFlag() throws Exception { + final RevCommit a = commit(); + final RevFlag flag1 = rw.newFlag("flag1"); + final RevFlag flag2 = rw.newFlag("flag2"); + a.add(flag1); + a.add(flag2); + assertEquals(flag1.mask | flag2.mask, a.flags); + a.remove(flag2); + assertEquals(flag1.mask, a.flags); + } + + public void testRemoveRevFlagSet() throws Exception { + final RevCommit a = commit(); + final RevFlag flag1 = rw.newFlag("flag1"); + final RevFlag flag2 = rw.newFlag("flag2"); + final RevFlag flag3 = rw.newFlag("flag3"); + final RevFlagSet s = new RevFlagSet(); + s.add(flag1); + s.add(flag2); + a.add(flag3); + a.add(s); + assertEquals(flag1.mask | flag2.mask | flag3.mask, a.flags); + a.remove(s); + assertEquals(flag3.mask, a.flags); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java new file mode 100644 index 0000000000..24e84b041d --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevQueueTestCase.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +public abstract class RevQueueTestCase<T extends AbstractRevQueue> extends + RevWalkTestCase { + protected T q; + + public void setUp() throws Exception { + super.setUp(); + q = create(); + } + + protected abstract T create(); + + public void testEmpty() throws Exception { + assertNull(q.next()); + assertTrue(q.everbodyHasFlag(RevWalk.UNINTERESTING)); + assertFalse(q.anybodyHasFlag(RevWalk.UNINTERESTING)); + } + + public void testClear() throws Exception { + final RevCommit a = parse(commit()); + final RevCommit b = parse(commit(a)); + + q.add(a); + q.add(b); + q.clear(); + assertNull(q.next()); + } + + public void testHasFlags() throws Exception { + final RevCommit a = parse(commit()); + final RevCommit b = parse(commit(a)); + + q.add(a); + q.add(b); + + assertFalse(q.everbodyHasFlag(RevWalk.UNINTERESTING)); + assertFalse(q.anybodyHasFlag(RevWalk.UNINTERESTING)); + + a.flags |= RevWalk.UNINTERESTING; + assertFalse(q.everbodyHasFlag(RevWalk.UNINTERESTING)); + assertTrue(q.anybodyHasFlag(RevWalk.UNINTERESTING)); + + b.flags |= RevWalk.UNINTERESTING; + assertTrue(q.everbodyHasFlag(RevWalk.UNINTERESTING)); + assertTrue(q.anybodyHasFlag(RevWalk.UNINTERESTING)); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java new file mode 100644 index 0000000000..8800536d27 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevTagParseTest.java @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2008-2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.io.ByteArrayOutputStream; + +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.RepositoryTestCase; + +public class RevTagParseTest extends RepositoryTestCase { + public void testTagBlob() throws Exception { + testOneType(Constants.OBJ_BLOB); + } + + public void testTagTree() throws Exception { + testOneType(Constants.OBJ_TREE); + } + + public void testTagCommit() throws Exception { + testOneType(Constants.OBJ_COMMIT); + } + + public void testTagTag() throws Exception { + testOneType(Constants.OBJ_TAG); + } + + private void testOneType(final int typeCode) throws Exception { + final ObjectId id = id("9788669ad918b6fcce64af8882fc9a81cb6aba67"); + final StringBuilder b = new StringBuilder(); + b.append("object " + id.name() + "\n"); + b.append("type " + Constants.typeString(typeCode) + "\n"); + b.append("tag v1.2.3.4.5\n"); + b.append("tagger A U. Thor <a_u_thor@example.com> 1218123387 +0700\n"); + b.append("\n"); + + final RevWalk rw = new RevWalk(db); + final RevTag c; + + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + assertNull(c.getObject()); + assertNull(c.getTagName()); + + c.parseCanonical(rw, b.toString().getBytes("UTF-8")); + assertNotNull(c.getObject()); + assertEquals(id, c.getObject().getId()); + assertSame(rw.lookupAny(id, typeCode), c.getObject()); + } + + public void testParseAllFields() throws Exception { + final ObjectId treeId = id("9788669ad918b6fcce64af8882fc9a81cb6aba67"); + final String name = "v1.2.3.4.5"; + final String taggerName = "A U. Thor"; + final String taggerEmail = "a_u_thor@example.com"; + final int taggerTime = 1218123387; + + final StringBuilder body = new StringBuilder(); + + body.append("object "); + body.append(treeId.name()); + body.append("\n"); + + body.append("type tree\n"); + + body.append("tag "); + body.append(name); + body.append("\n"); + + body.append("tagger "); + body.append(taggerName); + body.append(" <"); + body.append(taggerEmail); + body.append("> "); + body.append(taggerTime); + body.append(" +0700\n"); + + body.append("\n"); + + final RevWalk rw = new RevWalk(db); + final RevTag c; + + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + assertNull(c.getObject()); + assertNull(c.getTagName()); + + c.parseCanonical(rw, body.toString().getBytes("UTF-8")); + assertNotNull(c.getObject()); + assertEquals(treeId, c.getObject().getId()); + assertSame(rw.lookupTree(treeId), c.getObject()); + + assertNotNull(c.getTagName()); + assertEquals(name, c.getTagName()); + assertEquals("", c.getFullMessage()); + + final PersonIdent cTagger = c.getTaggerIdent(); + assertNotNull(cTagger); + assertEquals(taggerName, cTagger.getName()); + assertEquals(taggerEmail, cTagger.getEmailAddress()); + } + + private RevTag create(final String msg) throws Exception { + final StringBuilder b = new StringBuilder(); + b.append("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n"); + b.append("type tree\n"); + b.append("tag v1.2.3.4.5\n"); + b.append("tagger A U. Thor <a_u_thor@example.com> 1218123387 +0700\n"); + b.append("\n"); + b.append(msg); + + final RevTag c; + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toString().getBytes("UTF-8")); + return c; + } + + public void testParse_implicit_UTF8_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" + .getBytes("UTF-8")); + b.write("type tree\n".getBytes("UTF-8")); + b.write("tag v1.2.3.4.5\n".getBytes("UTF-8")); + + b + .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" + .getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + final RevTag c; + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); + assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); + assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c + .getFullMessage()); + } + + public void testParse_implicit_mixed_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" + .getBytes("UTF-8")); + b.write("type tree\n".getBytes("UTF-8")); + b.write("tag v1.2.3.4.5\n".getBytes("UTF-8")); + b + .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" + .getBytes("ISO-8859-1")); + b.write("\n".getBytes("UTF-8")); + b.write("Sm\u00f6rg\u00e5sbord\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + final RevTag c; + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); + assertEquals("Sm\u00f6rg\u00e5sbord", c.getShortMessage()); + assertEquals("Sm\u00f6rg\u00e5sbord\n\n\u304d\u308c\u3044\n", c + .getFullMessage()); + } + + /** + * Test parsing of a commit whose encoding is given and works. + * + * @throws Exception + */ + public void testParse_explicit_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" + .getBytes("EUC-JP")); + b.write("type tree\n".getBytes("EUC-JP")); + b.write("tag v1.2.3.4.5\n".getBytes("EUC-JP")); + b + .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" + .getBytes("EUC-JP")); + b.write("encoding euc_JP\n".getBytes("EUC-JP")); + b.write("\n".getBytes("EUC-JP")); + b.write("\u304d\u308c\u3044\n".getBytes("EUC-JP")); + b.write("\n".getBytes("EUC-JP")); + b.write("Hi\n".getBytes("EUC-JP")); + final RevTag c; + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); + assertEquals("\u304d\u308c\u3044", c.getShortMessage()); + assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage()); + } + + /** + * This is a twisted case, but show what we expect here. We can revise the + * expectations provided this case is updated. + * + * What happens here is that an encoding us given, but data is not encoded + * that way (and we can detect it), so we try other encodings. + * + * @throws Exception + */ + public void testParse_explicit_bad_encoded() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" + .getBytes("UTF-8")); + b.write("type tree\n".getBytes("UTF-8")); + b.write("tag v1.2.3.4.5\n".getBytes("UTF-8")); + b + .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" + .getBytes("ISO-8859-1")); + b.write("encoding EUC-JP\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Hi\n".getBytes("UTF-8")); + final RevTag c; + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); + assertEquals("\u304d\u308c\u3044", c.getShortMessage()); + assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage()); + } + + /** + * This is a twisted case too, but show what we expect here. We can revise + * the expectations provided this case is updated. + * + * What happens here is that an encoding us given, but data is not encoded + * that way (and we can detect it), so we try other encodings. Here data + * could actually be decoded in the stated encoding, but we override using + * UTF-8. + * + * @throws Exception + */ + public void testParse_explicit_bad_encoded2() throws Exception { + final ByteArrayOutputStream b = new ByteArrayOutputStream(); + b.write("object 9788669ad918b6fcce64af8882fc9a81cb6aba67\n" + .getBytes("UTF-8")); + b.write("type tree\n".getBytes("UTF-8")); + b.write("tag v1.2.3.4.5\n".getBytes("UTF-8")); + b + .write("tagger F\u00f6r fattare <a_u_thor@example.com> 1218123387 +0700\n" + .getBytes("UTF-8")); + b.write("encoding ISO-8859-1\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("\u304d\u308c\u3044\n".getBytes("UTF-8")); + b.write("\n".getBytes("UTF-8")); + b.write("Hi\n".getBytes("UTF-8")); + final RevTag c; + c = new RevTag(id("9473095c4cb2f12aefe1db8a355fe3fafba42f67")); + c.parseCanonical(new RevWalk(db), b.toByteArray()); + + assertEquals("F\u00f6r fattare", c.getTaggerIdent().getName()); + assertEquals("\u304d\u308c\u3044", c.getShortMessage()); + assertEquals("\u304d\u308c\u3044\n\nHi\n", c.getFullMessage()); + } + + public void testParse_NoMessage() throws Exception { + final String msg = ""; + final RevTag c = create(msg); + assertEquals(msg, c.getFullMessage()); + assertEquals(msg, c.getShortMessage()); + } + + public void testParse_OnlyLFMessage() throws Exception { + final RevTag c = create("\n"); + assertEquals("\n", c.getFullMessage()); + assertEquals("", c.getShortMessage()); + } + + public void testParse_ShortLineOnlyNoLF() throws Exception { + final String shortMsg = "This is a short message."; + final RevTag c = create(shortMsg); + assertEquals(shortMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_ShortLineOnlyEndLF() throws Exception { + final String shortMsg = "This is a short message."; + final String fullMsg = shortMsg + "\n"; + final RevTag c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_ShortLineOnlyEmbeddedLF() throws Exception { + final String fullMsg = "This is a\nshort message."; + final String shortMsg = fullMsg.replace('\n', ' '); + final RevTag c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_ShortLineOnlyEmbeddedAndEndingLF() throws Exception { + final String fullMsg = "This is a\nshort message.\n"; + final String shortMsg = "This is a short message."; + final RevTag c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + public void testParse_GitStyleMessage() throws Exception { + final String shortMsg = "This fixes a bug."; + final String body = "We do it with magic and pixie dust and stuff.\n" + + "\n" + "Signed-off-by: A U. Thor <author@example.com>\n"; + final String fullMsg = shortMsg + "\n" + "\n" + body; + final RevTag c = create(fullMsg); + assertEquals(fullMsg, c.getFullMessage()); + assertEquals(shortMsg, c.getShortMessage()); + } + + private static ObjectId id(final String str) { + return ObjectId.fromString(str); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java new file mode 100644 index 0000000000..9e879c5f0d --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkCullTest.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +public class RevWalkCullTest extends RevWalkTestCase { + public void testProperlyCullAllAncestors1() throws Exception { + // Credit goes to Junio C Hamano <gitster@pobox.com> for this + // test case in git-core (t/t6009-rev-list-parent.sh) + // + // We induce a clock skew so two is dated before one. + // + final RevCommit a = commit(); + final RevCommit b = commit(-2400, a); + final RevCommit c = commit(b); + final RevCommit d = commit(c); + + markStart(a); + markUninteresting(d); + assertNull(rw.next()); + } + + public void testProperlyCullAllAncestors2() throws Exception { + // Despite clock skew on c1 being very old it should not + // produce, neither should a or b, or any part of that chain. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(-5, b); + final RevCommit c2 = commit(10, b); + final RevCommit d = commit(c1, c2); + + markStart(d); + markUninteresting(c1); + assertCommit(d, rw.next()); + assertCommit(c2, rw.next()); + assertNull(rw.next()); + } + + public void testProperlyCullAllAncestors_LongHistory() throws Exception { + final RevCommit a = commit(); + RevCommit b = commit(a); + for (int i = 0; i < 24; i++) { + b = commit(b); + if ((i & 2) == 0) + markUninteresting(b); + } + final RevCommit c = commit(b); + + markStart(c); + markUninteresting(b); + assertCommit(c, rw.next()); + assertNull(rw.next()); + + // We should have aborted before we got back so far that "a" + // would be parsed. Thus, its parents shouldn't be allocated. + // + assertNull(a.parents); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFilterTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFilterTest.java new file mode 100644 index 0000000000..db4c38e72b --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkFilterTest.java @@ -0,0 +1,297 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.io.IOException; +import java.util.Date; + +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; +import org.eclipse.jgit.errors.StopWalkException; +import org.eclipse.jgit.revwalk.filter.AndRevFilter; +import org.eclipse.jgit.revwalk.filter.CommitTimeRevFilter; +import org.eclipse.jgit.revwalk.filter.NotRevFilter; +import org.eclipse.jgit.revwalk.filter.OrRevFilter; +import org.eclipse.jgit.revwalk.filter.RevFilter; + +public class RevWalkFilterTest extends RevWalkTestCase { + private static final MyAll MY_ALL = new MyAll(); + + public void testFilter_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(RevFilter.ALL); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testFilter_Negate_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(RevFilter.ALL.negate()); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_NOT_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(NotRevFilter.create(RevFilter.ALL)); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_NONE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(RevFilter.NONE); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_NOT_NONE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(NotRevFilter.create(RevFilter.NONE)); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testFilter_ALL_And_NONE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(AndRevFilter.create(RevFilter.ALL, RevFilter.NONE)); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_NONE_And_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(AndRevFilter.create(RevFilter.NONE, RevFilter.ALL)); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_ALL_Or_NONE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(OrRevFilter.create(RevFilter.ALL, RevFilter.NONE)); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testFilter_NONE_Or_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(OrRevFilter.create(RevFilter.NONE, RevFilter.ALL)); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testFilter_MY_ALL_And_NONE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(AndRevFilter.create(MY_ALL, RevFilter.NONE)); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_NONE_And_MY_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(AndRevFilter.create(RevFilter.NONE, MY_ALL)); + markStart(c); + assertNull(rw.next()); + } + + public void testFilter_MY_ALL_Or_NONE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(OrRevFilter.create(MY_ALL, RevFilter.NONE)); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testFilter_NONE_Or_MY_ALL() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + + rw.setRevFilter(OrRevFilter.create(RevFilter.NONE, MY_ALL)); + markStart(c); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testFilter_NO_MERGES() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(b); + final RevCommit c2 = commit(b); + final RevCommit d = commit(c1, c2); + final RevCommit e = commit(d); + + rw.setRevFilter(RevFilter.NO_MERGES); + markStart(e); + assertCommit(e, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testCommitTimeRevFilter() throws Exception { + final RevCommit a = commit(); + tick(100); + + final RevCommit b = commit(a); + tick(100); + + Date since = new Date(nowTick); + final RevCommit c1 = commit(b); + tick(100); + + final RevCommit c2 = commit(b); + tick(100); + + Date until = new Date(nowTick); + final RevCommit d = commit(c1, c2); + tick(100); + + final RevCommit e = commit(d); + + { + RevFilter after = CommitTimeRevFilter.after(since); + assertNotNull(after); + rw.setRevFilter(after); + markStart(e); + assertCommit(e, rw.next()); + assertCommit(d, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertNull(rw.next()); + } + + { + RevFilter before = CommitTimeRevFilter.before(until); + assertNotNull(before); + rw.reset(); + rw.setRevFilter(before); + markStart(e); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + { + RevFilter between = CommitTimeRevFilter.between(since, until); + assertNotNull(between); + rw.reset(); + rw.setRevFilter(between); + markStart(e); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertNull(rw.next()); + } + } + + private static class MyAll extends RevFilter { + @Override + public RevFilter clone() { + return this; + } + + @Override + public boolean include(RevWalk walker, RevCommit cmit) + throws StopWalkException, MissingObjectException, + IncorrectObjectTypeException, IOException { + return true; + } + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java new file mode 100644 index 0000000000..10c9f9b12e --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkMergeBaseTest.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import org.eclipse.jgit.revwalk.filter.RevFilter; +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +public class RevWalkMergeBaseTest extends RevWalkTestCase { + public void testNone() throws Exception { + final RevCommit c1 = commit(commit(commit())); + final RevCommit c2 = commit(commit(commit())); + + rw.setRevFilter(RevFilter.MERGE_BASE); + markStart(c1); + markStart(c2); + assertNull(rw.next()); + } + + public void testDisallowTreeFilter() throws Exception { + final RevCommit c1 = commit(); + final RevCommit c2 = commit(); + + rw.setRevFilter(RevFilter.MERGE_BASE); + rw.setTreeFilter(TreeFilter.ANY_DIFF); + markStart(c1); + markStart(c2); + try { + assertNull(rw.next()); + fail("did not throw IllegalStateException"); + } catch (IllegalStateException ise) { + // expected result + } + } + + public void testSimple() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(commit(commit(commit(commit(b))))); + final RevCommit c2 = commit(commit(commit(commit(commit(b))))); + + rw.setRevFilter(RevFilter.MERGE_BASE); + markStart(c1); + markStart(c2); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } + + public void testMultipleHeads_SameBase1() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(commit(commit(commit(commit(b))))); + final RevCommit c2 = commit(commit(commit(commit(commit(b))))); + final RevCommit c3 = commit(commit(commit(b))); + + rw.setRevFilter(RevFilter.MERGE_BASE); + markStart(c1); + markStart(c2); + markStart(c3); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } + + public void testMultipleHeads_SameBase2() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + final RevCommit d1 = commit(commit(commit(commit(commit(b))))); + final RevCommit d2 = commit(commit(commit(commit(commit(c))))); + final RevCommit d3 = commit(commit(commit(c))); + + rw.setRevFilter(RevFilter.MERGE_BASE); + markStart(d1); + markStart(d2); + markStart(d3); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } + + public void testCrissCross() throws Exception { + // See http://marc.info/?l=git&m=111463358500362&w=2 for a nice + // description of what this test is creating. We don't have a + // clean merge base for d,e as they each merged the parents b,c + // in different orders. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(a); + final RevCommit d = commit(b, c); + final RevCommit e = commit(c, b); + + rw.setRevFilter(RevFilter.MERGE_BASE); + markStart(d); + markStart(e); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertNull(rw.next()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter1Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter1Test.java new file mode 100644 index 0000000000..986a886566 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter1Test.java @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.util.Collections; + +import org.eclipse.jgit.treewalk.filter.AndTreeFilter; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +public class RevWalkPathFilter1Test extends RevWalkTestCase { + protected void filter(final String path) { + rw.setTreeFilter(AndTreeFilter.create(PathFilterGroup + .createFromStrings(Collections.singleton(path)), + TreeFilter.ANY_DIFF)); + } + + public void testEmpty_EmptyTree() throws Exception { + final RevCommit a = commit(); + filter("a"); + markStart(a); + assertNull(rw.next()); + } + + public void testEmpty_NoMatch() throws Exception { + final RevCommit a = commit(tree(file("0", blob("0")))); + filter("a"); + markStart(a); + assertNull(rw.next()); + } + + public void testSimple1() throws Exception { + final RevCommit a = commit(tree(file("0", blob("0")))); + filter("0"); + markStart(a); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testEdits_MatchNone() throws Exception { + final RevCommit a = commit(tree(file("0", blob("a")))); + final RevCommit b = commit(tree(file("0", blob("b"))), a); + final RevCommit c = commit(tree(file("0", blob("c"))), b); + final RevCommit d = commit(tree(file("0", blob("d"))), c); + filter("a"); + markStart(d); + assertNull(rw.next()); + } + + public void testEdits_MatchAll() throws Exception { + final RevCommit a = commit(tree(file("0", blob("a")))); + final RevCommit b = commit(tree(file("0", blob("b"))), a); + final RevCommit c = commit(tree(file("0", blob("c"))), b); + final RevCommit d = commit(tree(file("0", blob("d"))), c); + filter("0"); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testStringOfPearls_FilePath1() throws Exception { + final RevCommit a = commit(tree(file("d/f", blob("a")))); + final RevCommit b = commit(tree(file("d/f", blob("a"))), a); + final RevCommit c = commit(tree(file("d/f", blob("b"))), b); + filter("d/f"); + markStart(c); + + assertCommit(c, rw.next()); + assertEquals(1, c.getParentCount()); + assertCommit(a, c.getParent(0)); // b was skipped + + assertCommit(a, rw.next()); + assertEquals(0, a.getParentCount()); + assertNull(rw.next()); + } + + public void testStringOfPearls_FilePath2() throws Exception { + final RevCommit a = commit(tree(file("d/f", blob("a")))); + final RevCommit b = commit(tree(file("d/f", blob("a"))), a); + final RevCommit c = commit(tree(file("d/f", blob("b"))), b); + final RevCommit d = commit(tree(file("d/f", blob("b"))), c); + filter("d/f"); + markStart(d); + + // d was skipped + assertCommit(c, rw.next()); + assertEquals(1, c.getParentCount()); + assertCommit(a, c.getParent(0)); // b was skipped + + assertCommit(a, rw.next()); + assertEquals(0, a.getParentCount()); + assertNull(rw.next()); + } + + public void testStringOfPearls_DirPath2() throws Exception { + final RevCommit a = commit(tree(file("d/f", blob("a")))); + final RevCommit b = commit(tree(file("d/f", blob("a"))), a); + final RevCommit c = commit(tree(file("d/f", blob("b"))), b); + final RevCommit d = commit(tree(file("d/f", blob("b"))), c); + filter("d"); + markStart(d); + + // d was skipped + assertCommit(c, rw.next()); + assertEquals(1, c.getParentCount()); + assertCommit(a, c.getParent(0)); // b was skipped + + assertCommit(a, rw.next()); + assertEquals(0, a.getParentCount()); + assertNull(rw.next()); + } + + public void testStringOfPearls_FilePath3() throws Exception { + final RevCommit a = commit(tree(file("d/f", blob("a")))); + final RevCommit b = commit(tree(file("d/f", blob("a"))), a); + final RevCommit c = commit(tree(file("d/f", blob("b"))), b); + final RevCommit d = commit(tree(file("d/f", blob("b"))), c); + final RevCommit e = commit(tree(file("d/f", blob("b"))), d); + final RevCommit f = commit(tree(file("d/f", blob("b"))), e); + final RevCommit g = commit(tree(file("d/f", blob("b"))), f); + final RevCommit h = commit(tree(file("d/f", blob("b"))), g); + final RevCommit i = commit(tree(file("d/f", blob("c"))), h); + filter("d/f"); + markStart(i); + + assertCommit(i, rw.next()); + assertEquals(1, i.getParentCount()); + assertCommit(c, i.getParent(0)); // h..d was skipped + + assertCommit(c, rw.next()); + assertEquals(1, c.getParentCount()); + assertCommit(a, c.getParent(0)); // b was skipped + + assertCommit(a, rw.next()); + assertEquals(0, a.getParentCount()); + assertNull(rw.next()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java new file mode 100644 index 0000000000..73d41eae64 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkPathFilter6012Test.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.HashMap; + +import org.eclipse.jgit.treewalk.filter.AndTreeFilter; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; +import org.eclipse.jgit.treewalk.filter.TreeFilter; + +// Note: Much of this test case is broken as it depends upon +// the graph applying topological sorting *before* doing merge +// simplification. It also depends upon a difference between +// full history and non-full history for a path, something we +// don't quite yet have a distiction for in JGit. +// +public class RevWalkPathFilter6012Test extends RevWalkTestCase { + private static final String pA = "pA", pF = "pF", pE = "pE"; + + private RevCommit a, b, c, d, e, f, g, h, i; + + private HashMap<RevCommit, String> byName; + + public void setUp() throws Exception { + super.setUp(); + + // Test graph was stolen from git-core t6012-rev-list-simplify + // (by Junio C Hamano in 65347030590bcc251a9ff2ed96487a0f1b9e9fa8) + // + final RevBlob zF = blob("zF"); + final RevBlob zH = blob("zH"); + final RevBlob zI = blob("zI"); + final RevBlob zS = blob("zS"); + final RevBlob zY = blob("zY"); + + a = commit(tree(file(pF, zH))); + b = commit(tree(file(pF, zI)), a); + c = commit(tree(file(pF, zI)), a); + d = commit(tree(file(pA, zS), file(pF, zI)), c); + parse(d); + e = commit(d.getTree(), d, b); + f = commit(tree(file(pA, zS), file(pE, zY), file(pF, zI)), e); + parse(f); + g = commit(tree(file(pE, zY), file(pF, zI)), b); + h = commit(f.getTree(), g, f); + i = commit(tree(file(pA, zS), file(pE, zY), file(pF, zF)), h); + + byName = new HashMap<RevCommit, String>(); + for (Field z : RevWalkPathFilter6012Test.class.getDeclaredFields()) { + if (z.getType() == RevCommit.class) + byName.put((RevCommit) z.get(this), z.getName()); + } + } + + protected void check(final RevCommit... order) throws Exception { + markStart(i); + final StringBuilder act = new StringBuilder(); + for (final RevCommit z : rw) { + final String name = byName.get(z); + assertNotNull(name); + act.append(name); + act.append(' '); + } + final StringBuilder exp = new StringBuilder(); + for (final RevCommit z : order) { + final String name = byName.get(z); + assertNotNull(name); + exp.append(name); + exp.append(' '); + } + assertEquals(exp.toString(), act.toString()); + } + + protected void filter(final String path) { + rw.setTreeFilter(AndTreeFilter.create(PathFilterGroup + .createFromStrings(Collections.singleton(path)), + TreeFilter.ANY_DIFF)); + } + + public void test1() throws Exception { + // TODO --full-history + check(i, h, g, f, e, d, c, b, a); + } + + public void test2() throws Exception { + // TODO --full-history + filter(pF); + // TODO fix broken test + // check(i, h, e, c, b, a); + } + + public void test3() throws Exception { + // TODO --full-history + rw.sort(RevSort.TOPO); + filter(pF); + // TODO fix broken test + // check(i, h, e, c, b, a); + } + + public void test4() throws Exception { + // TODO --full-history + rw.sort(RevSort.COMMIT_TIME_DESC); + filter(pF); + // TODO fix broken test + // check(i, h, e, c, b, a); + } + + public void test5() throws Exception { + // TODO --simplify-merges + filter(pF); + // TODO fix broken test + // check(i, e, c, b, a); + } + + public void test6() throws Exception { + filter(pF); + check(i, b, a); + } + + public void test7() throws Exception { + rw.sort(RevSort.TOPO); + filter(pF); + check(i, b, a); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java new file mode 100644 index 0000000000..0d3e0cf5aa --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkSortTest.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +public class RevWalkSortTest extends RevWalkTestCase { + public void testSort_Default() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(1, a); + final RevCommit c = commit(1, b); + final RevCommit d = commit(1, c); + + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testSort_COMMIT_TIME_DESC() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + final RevCommit d = commit(c); + + rw.sort(RevSort.COMMIT_TIME_DESC); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testSort_REVERSE() throws Exception { + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(b); + final RevCommit d = commit(c); + + rw.sort(RevSort.REVERSE); + markStart(d); + assertCommit(a, rw.next()); + assertCommit(b, rw.next()); + assertCommit(c, rw.next()); + assertCommit(d, rw.next()); + assertNull(rw.next()); + } + + public void testSort_COMMIT_TIME_DESC_OutOfOrder1() throws Exception { + // Despite being out of order time-wise, a strand-of-pearls must + // still maintain topological order. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c = commit(-5, b); + final RevCommit d = commit(10, c); + assertTrue(parse(a).getCommitTime() < parse(d).getCommitTime()); + assertTrue(parse(c).getCommitTime() < parse(b).getCommitTime()); + + rw.sort(RevSort.COMMIT_TIME_DESC); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testSort_COMMIT_TIME_DESC_OutOfOrder2() throws Exception { + // c1 is back dated before its parent. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(-5, b); + final RevCommit c2 = commit(10, b); + final RevCommit d = commit(c1, c2); + + rw.sort(RevSort.COMMIT_TIME_DESC); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertCommit(c1, rw.next()); + assertNull(rw.next()); + } + + public void testSort_TOPO() throws Exception { + // c1 is back dated before its parent. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(-5, b); + final RevCommit c2 = commit(10, b); + final RevCommit d = commit(c1, c2); + + rw.sort(RevSort.TOPO); + markStart(d); + assertCommit(d, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(b, rw.next()); + assertCommit(a, rw.next()); + assertNull(rw.next()); + } + + public void testSort_TOPO_REVERSE() throws Exception { + // c1 is back dated before its parent. + // + final RevCommit a = commit(); + final RevCommit b = commit(a); + final RevCommit c1 = commit(-5, b); + final RevCommit c2 = commit(10, b); + final RevCommit d = commit(c1, c2); + + rw.sort(RevSort.TOPO); + rw.sort(RevSort.REVERSE, true); + markStart(d); + assertCommit(a, rw.next()); + assertCommit(b, rw.next()); + assertCommit(c1, rw.next()); + assertCommit(c2, rw.next()); + assertCommit(d, rw.next()); + assertNull(rw.next()); + } +} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java new file mode 100644 index 0000000000..50fbce41aa --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/revwalk/RevWalkTestCase.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2009, Google Inc. + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package org.eclipse.jgit.revwalk; + +import java.util.Collections; +import java.util.Date; + +import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.dircache.DirCacheEntry; +import org.eclipse.jgit.lib.Commit; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.ObjectWriter; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.RepositoryTestCase; +import org.eclipse.jgit.lib.Tag; +import org.eclipse.jgit.lib.Tree; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; + +/** Support for tests of the {@link RevWalk} class. */ +public abstract class RevWalkTestCase extends RepositoryTestCase { + protected ObjectWriter ow; + + protected RevTree emptyTree; + + protected long nowTick; + + protected RevWalk rw; + + public void setUp() throws Exception { + super.setUp(); + ow = new ObjectWriter(db); + rw = createRevWalk(); + emptyTree = rw.parseTree(ow.writeTree(new Tree(db))); + nowTick = 1236977987000L; + } + + protected RevWalk createRevWalk() { + return new RevWalk(db); + } + + protected void tick(final int secDelta) { + nowTick += secDelta * 1000L; + } + + protected RevBlob blob(final String content) throws Exception { + return rw.lookupBlob(ow.writeBlob(Constants.encode(content))); + } + + protected DirCacheEntry file(final String path, final RevBlob blob) + throws Exception { + final DirCacheEntry e = new DirCacheEntry(path); + e.setFileMode(FileMode.REGULAR_FILE); + e.setObjectId(blob); + return e; + } + + protected RevTree tree(final DirCacheEntry... entries) throws Exception { + final DirCache dc = DirCache.newInCore(); + final DirCacheBuilder b = dc.builder(); + for (final DirCacheEntry e : entries) + b.add(e); + b.finish(); + return rw.lookupTree(dc.writeTree(ow)); + } + + protected RevObject get(final RevTree tree, final String path) + throws Exception { + final TreeWalk tw = new TreeWalk(db); + tw.setFilter(PathFilterGroup.createFromStrings(Collections + .singleton(path))); + tw.reset(tree); + while (tw.next()) { + if (tw.isSubtree() && !path.equals(tw.getPathString())) { + tw.enterSubtree(); + continue; + } + final ObjectId entid = tw.getObjectId(0); + final FileMode entmode = tw.getFileMode(0); + return rw.lookupAny(entid, entmode.getObjectType()); + } + fail("Can't find " + path + " in tree " + tree.name()); + return null; // never reached. + } + + protected RevCommit commit(final RevCommit... parents) throws Exception { + return commit(1, emptyTree, parents); + } + + protected RevCommit commit(final RevTree tree, final RevCommit... parents) + throws Exception { + return commit(1, tree, parents); + } + + protected RevCommit commit(final int secDelta, final RevCommit... parents) + throws Exception { + return commit(secDelta, emptyTree, parents); + } + + protected RevCommit commit(final int secDelta, final RevTree tree, + final RevCommit... parents) throws Exception { + tick(secDelta); + final Commit c = new Commit(db); + c.setTreeId(tree); + c.setParentIds(parents); + c.setAuthor(new PersonIdent(jauthor, new Date(nowTick))); + c.setCommitter(new PersonIdent(jcommitter, new Date(nowTick))); + c.setMessage(""); + return rw.lookupCommit(ow.writeCommit(c)); + } + + protected RevTag tag(final String name, final RevObject dst) + throws Exception { + final Tag t = new Tag(db); + t.setType(Constants.typeString(dst.getType())); + t.setObjId(dst.toObjectId()); + t.setTag(name); + t.setTagger(new PersonIdent(jcommitter, new Date(nowTick))); + t.setMessage(""); + return (RevTag) rw.lookupAny(ow.writeTag(t), Constants.OBJ_TAG); + } + + protected <T extends RevObject> T parse(final T t) throws Exception { + rw.parseBody(t); + return t; + } + + protected void markStart(final RevCommit commit) throws Exception { + rw.markStart(commit); + } + + protected void markUninteresting(final RevCommit commit) throws Exception { + rw.markUninteresting(commit); + } + + protected void assertCommit(final RevCommit exp, final RevCommit act) { + assertSame(exp, act); + } +} |