blob: 69c4dbccf8c1b82a52409e75f3aaf83c3857ad30 [file] [log] [blame]
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2005, Giovanni Bajo
# All rights reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
import sys, os
import types
import re
import unittest
from StringIO import StringIO
import shutil
import svnmerge
import stat
import atexit
import getopt
import locale
####
# IMPORTANT NOTE TO TEST AUTHORS
#
# Any quoted strings inside the arguments of the parameter "cmd" must
# be enclosed in double-, not single-quotes, so that the command parser
# knows to keep them together. For example, do not write this:
# launch("svn ci -m 'log comment'") # BAD
# ...but one of these:
# launch('svn ci -m "log comment"') # GOOD
# launch("svn ci -m \"log comment\"") # GOOD, but why?
# Otherwise, you get an error saying
# '<path>/comment' is not under version control
# ...when running the tests on Windows.
####
# True/False constants are Python 2.2+
try:
True, False
except NameError:
True, False = 1, 0
class StringIOWithEncoding(StringIO):
def __init__(self):
StringIO.__init__(self)
self.encoding = sys.stdout.encoding
class TestCase_kwextract(unittest.TestCase):
def test_basic(self):
self.assertEqual(svnmerge.kwextract("$Rev: 134 rasky $"), "134 rasky")
self.assertEqual(svnmerge.kwextract("$Date: 2005-09-25 13:45 CET+1$"),
"2005-09-25 13:45 CET+1")
def test_failure(self):
self.assertEqual(svnmerge.kwextract("$Rev: $"), "<unknown>")
self.assertEqual(svnmerge.kwextract("$Date$"), "<unknown>")
def reset_svnmerge():
svnmerge.opts = svnmerge.default_opts.copy()
svnmerge._cache_svninfo = {}
svnmerge._cache_reporoot = {}
svnmerge.PathIdentifier.locobjs = {}
svnmerge.PathIdentifier.repo_hints = {}
class TestCase_launch(unittest.TestCase):
if os.name == "nt":
cmd = "attrib"
else:
cmd = "ls"
def test_basic(self):
out = svnmerge.launch(self.cmd)
self.assert_(out)
for o in out:
self.assertEqual(o[-1], "\n")
def test_failure(self):
self.assertRaises(svnmerge.LaunchError, svnmerge.launch, self.cmd*10)
def test_failurecode(self):
try:
svnmerge.launch(self.cmd*10)
except svnmerge.LaunchError as (ret, cmd, out):
self.assertNotEqual(ret, 0)
self.assertNotEqual(ret, None)
self.assert_(out)
self.assertEqual(cmd, self.cmd*10)
else:
self.fail("svnmerge.launch did not cause a LaunchError as expected")
class TestCase_PrefixLines(unittest.TestCase):
def test_basic(self):
self.assertEqual("zz\n", svnmerge.prefix_lines("zz", "\n"))
self.assertEqual("zzfoo\n", svnmerge.prefix_lines("zz", "foo\n"))
self.assertEqual("zzfoo\nzzbar\n", svnmerge.prefix_lines("zz", "foo\nbar\n"))
self.assertEqual("zz\nzzfoo\n", svnmerge.prefix_lines("zz", "\nfoo\n"))
self.assertEqual("zz\nzzfoo\nzzbar\n", svnmerge.prefix_lines("zz", "\nfoo\nbar\n"))
class TestCase_RevisionSet(unittest.TestCase):
def test_constr_string(self):
rs = svnmerge.RevisionSet("10- 15, 12-48,2 ")
self.assert_(17 in rs)
self.assert_(2 in rs)
self.assert_(9 not in rs)
rs = svnmerge.RevisionSet("10: 15, 12:48,2 ")
self.assert_(17 in rs)
self.assert_(2 in rs)
self.assert_(9 not in rs)
def test_constr_dict(self):
rs = svnmerge.RevisionSet({18:1, 24:1, 25:1, 43:1})
self.assert_(24 in rs)
self.assert_(18 in rs)
self.assert_(44 not in rs)
def test_constr_error(self):
self.assertRaises(ValueError, svnmerge.RevisionSet, "10-12-15")
self.assertRaises(ValueError, svnmerge.RevisionSet, "10;12-15")
self.assertRaises(ValueError, svnmerge.RevisionSet, "10,foo,3-15")
self.assertRaises(ValueError, svnmerge.RevisionSet, "10:12:15")
self.assertRaises(ValueError, svnmerge.RevisionSet, "10;12:15")
self.assertRaises(ValueError, svnmerge.RevisionSet, "10,foo,3:15")
def test_normalized(self):
rs = svnmerge.RevisionSet("8-15,16-18, 4-6, 9, 18, 1-1, 3-3")
self.assertEqual(rs.normalized(), [(1,1), (3,6), (8,18)])
self.assertEqual(str(rs), "1,3-6,8-18")
rs = svnmerge.RevisionSet("8:15,16:18, 4:6, 9, 18, 1:1, 3:3")
self.assertEqual(rs.normalized(), [(1,1), (3,6), (8,18)])
self.assertEqual(str(rs), "1,3-6,8-18")
def test_sorted(self):
"Test the sorted() function of the RevisionSet class."
rs = svnmerge.RevisionSet("8-15,16-18, 4-6, 9, 18, 1-1, 3-3")
self.assertEqual(rs.sorted(), [1, 3, 4, 5, 6, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18])
rs = svnmerge.RevisionSet("8:15,16:18, 4:6, 9, 18, 1:1, 3:3")
self.assertEqual(rs.sorted(), [1, 3, 4, 5, 6, 8, 9, 10, 11,
12, 13, 14, 15, 16, 17, 18])
def test_length(self):
rs = svnmerge.RevisionSet("3-8")
self.assertEqual(len(rs), 6)
rs = svnmerge.RevisionSet("3-8,4-10")
self.assertEqual(len(rs), 8)
rs = svnmerge.RevisionSet("1,3,5")
self.assertEqual(len(rs), 3)
rs = svnmerge.RevisionSet("3:8")
self.assertEqual(len(rs), 6)
rs = svnmerge.RevisionSet("3:8,4:10")
self.assertEqual(len(rs), 8)
rs = svnmerge.RevisionSet("1,3,5")
self.assertEqual(len(rs), 3)
def test_iter(self):
try:
iter
except NameError:
pass
else:
rs = svnmerge.RevisionSet("4-13,1-5,34,20-22,18-21")
self.assertEqual(list(iter(rs)), range(1,14)+range(18,23)+[34])
rs = svnmerge.RevisionSet("4:13,1:5,34,20:22,18:21")
self.assertEqual(list(iter(rs)), range(1,14)+range(18,23)+[34])
def test_union(self):
rs = svnmerge.RevisionSet("3-8,4-10") | svnmerge.RevisionSet("7-14,1")
self.assertEqual(str(rs), "1,3-14")
rs = svnmerge.RevisionSet("3:8,4:10") | svnmerge.RevisionSet("7:14,1")
self.assertEqual(str(rs), "1,3-14")
def test_subtraction(self):
rs = svnmerge.RevisionSet("3-8,4-10") - svnmerge.RevisionSet("7-14,1")
self.assertEqual(str(rs), "3-6")
rs = svnmerge.RevisionSet("3:8,4:10") - svnmerge.RevisionSet("7:14,1")
self.assertEqual(str(rs), "3-6")
def test_constr_empty(self):
rs = svnmerge.RevisionSet("")
self.assertEqual(str(rs), "")
class TestCase_PathIdentifier(unittest.TestCase):
rrp = "/trunk/contrib/client-side/svnmerge"
uuid = "65390229-12b7-0310-b90b-f21a5aa7ec8e"
uuidrl = 'uuid://'+uuid+rrp
url= "http://svn.apache.org/repos/asf/subversion/trunk/contrib/client-side/svnmerge"
ext = "uuid://65390229-12b7-0310-b90b-f21a5aa7ec8e/trunk/contrib/client-side/svnmerge"
def try_pathid(self, rrp, uuid, url, ext, expected_str, expected_formats):
l = svnmerge.PathIdentifier(rrp, uuid, url, ext)
self.assertEqual(str(l), expected_str,
"str() gave '%s' instead of '%s'" % (str(l), expected_str))
for k, v in expected_formats.items():
self.assertEqual(l.format(k), v,
"format('%s') gave '%s' instead of '%s'" % (k, l.format(k), v))
reset_svnmerge()
def test_PathIdentifier_just_path(self):
self.try_pathid(self.rrp, None, None, None,
self.rrp, { 'path' : self.rrp })
def test_PathIdentifier_uuid(self):
self.try_pathid(self.rrp, self.uuid, None, None,
self.uuidrl, { 'path' : self.rrp, 'uuid' : self.uuidrl })
def test_PathIdentifier_url(self):
self.try_pathid(self.rrp, None, self.url, None,
self.url, { 'path' : self.rrp, 'url' : self.url })
def test_PathIdentifier_prefer_url(self):
self.try_pathid(self.rrp, self.uuid, self.url, None,
self.url, { 'path' : self.rrp, 'url' : self.url, 'uuid' : self.uuidrl })
def test_PathIdentifier_external_form(self):
self.try_pathid(self.rrp, self.uuid, self.url, self.ext,
self.ext, { 'path' : self.rrp, 'url' : self.url, 'uuid' : self.uuidrl })
class TestCase_MinimalMergeIntervals(unittest.TestCase):
def test_basic(self):
rs = svnmerge.RevisionSet("4-8,12,18,24")
phantom = svnmerge.RevisionSet("8-11,13-16,19-23")
revs = svnmerge.minimal_merge_intervals(rs, phantom)
self.assertEqual(revs, [(4,12), (18,24)])
class TestCase_SvnMerge(unittest.TestCase):
def svnmerge(self, cmds, *args, **kwargs):
return self.svnmerge2(cmds.split(), *args, **kwargs)
def svnmerge2(self, args, error=False, match=None, nonmatch=None):
# svnmerge's get_commit_log method needs the "encoding" method of
# sys.stdout, which is not provided by StringIO
out = StringIOWithEncoding()
sys.stdout = sys.stderr = out
try:
try:
# Clear svnmerge's internal caches before running any
# commands.
reset_svnmerge()
ret = svnmerge.main(args)
except SystemExit as e:
ret = e.code
finally:
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
if ret is None:
ret = 0
if error:
self.assertNotEqual(ret, 0,
"svnmerge did not fail, with this output:\n%s" % out.getvalue())
else:
self.assertEqual(ret, 0,
"svnmerge failed, with this output:\n%s" % out.getvalue())
if match is not None:
self.assert_(re.search(match, out.getvalue()),
"pattern %r not found in output:\n%s" % (match, out.getvalue()))
if nonmatch is not None:
self.assert_(not re.search(nonmatch, out.getvalue()),
"pattern %r found in output:\n%s" % (nonmatch, out.getvalue()))
return out.getvalue()
def _parseoutput(self, ret, out, error=False, match=None, nonmatch=None):
if error:
self.assertNotEqual(ret,
0,
"svnmerge did not fail, with this output:\n%s" % out)
else:
self.assertEqual(ret,
0,
"svnmerge failed, with this output:\n%s" % out)
if match is not None:
self.assert_(re.search(match, out),
"pattern %r not found in output:\n%s" % (match, out))
if nonmatch is not None:
self.assert_(not re.search(nonmatch, out),
"pattern %r found in output:\n%s" % (nonmatch, out))
return out
def launch(self, cmd, **kwargs):
try:
out = svnmerge.launch(cmd, split_lines=False)
except svnmerge.LaunchError as (ret, cmd, out):
return self._parseoutput(ret, out, **kwargs)
return self._parseoutput(0, out, **kwargs)
class TestCase_CommandLineOptions(TestCase_SvnMerge):
def test_empty(self):
self.svnmerge("")
def test_help_commands(self):
self.svnmerge("help")
self.svnmerge("--help")
self.svnmerge("-h")
for cmd in svnmerge.command_table.keys():
self.svnmerge("help %s" % cmd)
self.svnmerge("%s --help" % cmd)
self.svnmerge("%s -h" % cmd)
def test_wrong_commands(self):
self.svnmerge("asijdoiasjd", error=True)
self.svnmerge("help asijdoiasjd", error=True)
def test_wrong_option(self):
self.svnmerge("--asdsad", error=True)
self.svnmerge("help --asdsad", error=True)
self.svnmerge("init --asdsad", error=True)
self.svnmerge("--asdsad init", error=True)
def test_version(self):
out = self.svnmerge("--version")
self.assert_(out.find("Giovanni Bajo") >= 0)
out = self.svnmerge("-V")
self.assert_(out.find("Giovanni Bajo") >= 0)
out = self.svnmerge("init -V")
self.assert_(out.find("Giovanni Bajo") >= 0)
def temp_path():
try:
return os.environ["TEMP"]
except KeyError:
pass
if os.name == "posix":
return "/tmp"
return "."
def rmtree(path):
def onerror(func, path, excinfo):
if func in [os.remove, os.rmdir]:
if os.path.exists(path):
os.chmod(path, stat.S_IWRITE)
func(path)
if os.path.isdir(path):
shutil.rmtree(path, onerror=onerror)
def get_template_path():
p = os.path.join(temp_path(), "__svnmerge_test_template")
return os.path.abspath(p)
def get_test_path():
p = os.path.join(temp_path(), "__svnmerge_test")
return os.path.abspath(p)
def abspath_to_url(path):
assert path == os.path.abspath(path)
path = path.replace("\\", "/")
if path[0] != '/':
path = '/' + path
return "file://" + path
class TestCase_TestRepo(TestCase_SvnMerge):
def setUp(self):
"""Creates a working copy of a branch at r13 with the
following structure, containing revisions (3-6, 13):
test-branch/
test1
test2
test3
...from a repository with the following structure:
Path Created rev
---- -----------
/ 0
trunk/ 3
test1 4
test2 5
test3 6
test4 9
test5 10
branches/ 1
testYYY-branch/ 11 (renamed from testXXX-branch in 12)
test1 4
test2 5
test3 6
test-branch/ 13 (copied from trunk@6)
test1 4
test2 5
test3 6
tags/ 2
"""
self.cwd = os.getcwd()
reset_svnmerge()
test_path = get_test_path()
template_path = get_template_path()
self.template_path = template_path
self.test_path = test_path
self.template_repo_path = os.path.join(template_path, "repo")
self.template_repo_url = abspath_to_url(self.template_repo_path)
self.test_repo_path = os.path.join(test_path, "repo")
self.test_repo_url = abspath_to_url(self.test_repo_path)
if not os.path.isdir(template_path):
rmtree(template_path)
os.makedirs(template_path)
os.chdir(template_path)
self.multilaunch("""
svnadmin create --fs-type fsfs %(TEMPLATE_REPO_PATH)s
svn mkdir -m "create /branches" %(TEMPLATE_REPO_URL)s/branches
svn mkdir -m "create /tags" %(TEMPLATE_REPO_URL)s/tags
svn mkdir -m "create /trunk" %(TEMPLATE_REPO_URL)s/trunk
svn co %(TEMPLATE_REPO_URL)s/trunk trunk
""")
os.chdir("trunk")
open("test1", "w").write("test 1")
open("test2", "w").write("test 2")
open("test3", "w").write("test 3")
open("test4", "w").write("test 4")
open("test5", "w").write("test 5")
self.multilaunch("""
svn add test1
svn ci -m "add test1"
svn add test2
svn ci -m "add test2"
svn add test3
svn ci -m "add test3"
svn mkdir -m "create /foobar" %(TEMPLATE_REPO_URL)s/foobar
svn rm -m "remove /foobar" %(TEMPLATE_REPO_URL)s/foobar
svn add test4
svn ci -m "add test4"
svn add test5
svn ci -m "add test5"
svn cp -r6 -m "create branch" %(TEMPLATE_REPO_URL)s/trunk %(TEMPLATE_REPO_URL)s/branches/testXXX-branch
svn mv -m "rename branch" %(TEMPLATE_REPO_URL)s/branches/testXXX-branch %(TEMPLATE_REPO_URL)s/branches/testYYY-branch
svn cp -r6 -m "create branch" %(TEMPLATE_REPO_URL)s/trunk %(TEMPLATE_REPO_URL)s/branches/test-branch
""")
os.chdir("..")
self.launch("svn co %(TEMPLATE_REPO_URL)s/branches/test-branch")
os.chdir(self.cwd)
rmtree(self.test_path)
shutil.copytree(self.template_path, self.test_path)
os.chdir(self.test_path)
# Relocate the test working copies from using the template
# repository to the test repository so the template repository
# is not affected by commits.
self.launch("svn switch --relocate %(TEMPLATE_REPO_URL)s %(TEST_REPO_URL)s trunk test-branch")
os.chdir("test-branch")
# Always remove the template directory when the tests have
# completed.
atexit.register(lambda: rmtree(template_path))
def tearDown(self):
os.chdir(self.cwd)
rmtree(self.test_path)
def command_dict(self):
return {
"TEMPLATE_PATH": self.template_path,
"TEMPLATE_REPO_PATH": self.template_repo_path,
"TEMPLATE_REPO_URL": self.template_repo_url,
"TEST_PATH": self.test_path,
"TEST_REPO_PATH": self.test_repo_path,
"TEST_REPO_URL": self.test_repo_url,
}
def launch(self, cmd, *args, **kwargs):
cmd = cmd % self.command_dict()
return TestCase_SvnMerge.launch(self, cmd, *args, **kwargs)
def multilaunch(self, cmds):
for cmd in cmds.split("\n"):
cmd = cmd.strip()
if len(cmd) > 0:
svnmerge.launch(cmd % self.command_dict())
def revert(self):
self.multilaunch("svn revert -R .")
def getproperty(self):
out = svnmerge.launch("svn pg %s ." % svnmerge.opts["prop"])
if len(out) == 0:
return None
else:
return out[0].strip()
def getBlockedProperty(self):
out = svnmerge.launch("svn pg %s ." % svnmerge.opts["block-prop"])
if len(out) == 0:
return None
else:
return out[0].strip()
def testNoWc(self):
os.mkdir("foo")
os.chdir("foo")
self.svnmerge("init", error=True, match=r"working dir")
self.svnmerge("avail", error=True, match=r"working dir")
self.svnmerge("integrated", error=True, match=r"working dir")
self.svnmerge("merge", error=True, match=r"working dir")
self.svnmerge("block", error=True, match=r"working dir")
self.svnmerge("unblock", error=True, match=r"working dir")
def testCheckNoIntegrationInfo(self):
self.svnmerge("avail", error=True, match=r"no integration")
self.svnmerge("integrated", error=True, match=r"no integration")
self.svnmerge("merge", error=True, match=r"no integration")
self.svnmerge("block", error=True, match=r"no integration")
self.svnmerge("unblock", error=True, match=r"no integration")
def testSelfReferentialInit(self):
self.svnmerge2(["init", self.test_repo_url + "/branches/test-branch"],
error=True, match=r"cannot init integration source")
def testAvailURL(self):
# Initialize svnmerge
self.svnmerge("init")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
self.svnmerge("avail %s/branches/test-branch" % self.test_repo_url, match=r"\A9-10$")
def testBlocked(self):
# Initialize svnmerge
self.svnmerge("init")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
# Block revisions that have already been merged
self.svnmerge("block -r5", error=True, match=r"no available revisions")
# Block phantom revisions
self.svnmerge("block -r8", error=True, match=r"no available revisions")
# Block available revisions
self.svnmerge("block -r9", match=r"'svnmerge-blocked' set")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
# Check that the revision is still available
self.svnmerge("avail", match=r"\A10$")
# Check that the revision was blocked correctly
self.svnmerge("avail -B", match=r"\A9$")
# Check that both revisions are available with avail -A
self.svnmerge("avail -A", match=r"\A9-10$")
# Block all remaining revisions
self.svnmerge("block", match=r"'svnmerge-blocked' set")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
# Check that all revisions were blocked correctly
self.svnmerge("avail -B", match=r"\A9-10$")
# Check that all revisions are available using avail -A
self.svnmerge("avail -A", match=r"\A9-10$")
# Check that no revisions are available, now that they have
# been blocked
self.svnmerge("avail", match=r"\A\Z")
# Unblock all revisions
self.svnmerge("unblock", match=r"'svnmerge-blocked' deleted")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
# Check that all revisions are available
self.svnmerge("avail", match=r"\A9-10$")
self.svnmerge("avail -A", match=r"\A9-10$")
# Check that no revisions are blocked
self.svnmerge("avail -B", match=r"\A$")
def testTransitiveMerge(self):
"""
Test a merge of a change from testYYY-branch -> test-branch -> trunk
"""
os.chdir("..")
self.launch("svn co %(TEST_REPO_URL)s/branches/testYYY-branch testYYY-branch")
os.chdir("trunk")
self.launch("svn up")
self.svnmerge("init ../test-branch")
self.launch('svn ci -m "init test-branch -> trunk"',
match=r"Committed revision 14")
os.chdir("../test-branch")
self.svnmerge("init -r 1-6 ../testYYY-branch")
self.launch('svn ci -m "init testYYY-branch -> test-branch"',
match=r"Committed revision 15")
os.chdir("../testYYY-branch")
open("test6", "w").write("test6")
self.launch("svn add test6")
self.launch('svn ci -m "add test6"',
match=r"Committed revision 16")
os.chdir("../test-branch")
self.svnmerge("merge -r 16")
self.launch('svn ci -m "merge r16"',
match=r"Committed revision 17")
#os.chdir("../test-branch")
open("test5", "w").write("test5")
self.launch("svn add test5")
self.launch('svn ci -m "add test5"',
match=r"Committed revision 18")
os.chdir("../trunk")
self.svnmerge("block -r 18")
self.launch('svn ci -m "block r18"',
match=r"Committed revision 19")
#os.chdir("../trunk")
out = self.svnmerge("merge -r 17")
self.launch('svn ci -m "merge r17 from test-branch"',
match=r"Committed revision 20")
p = self.getproperty()
self.assertEqual(p, '/branches/test-branch:1-13,17')
p = self.getBlockedProperty()
self.assertEqual(p, '/branches/test-branch:18')
def testTransitiveMergeWithBlock(self):
"""
Test a merge of a change from testYYY-branch -> test-branch -> trunk
"""
os.chdir("..")
self.launch("svn co %(TEST_REPO_URL)s/branches/testYYY-branch testYYY-branch")
os.chdir("trunk")
self.launch("svn up")
self.svnmerge("init ../test-branch")
self.launch('svn ci -m "init test-branch -> trunk"',
match=r"Committed revision 14")
os.chdir("../test-branch")
self.svnmerge("init -r 1-6 ../testYYY-branch")
self.launch('svn ci -m "init testYYY-branch -> test-branch"',
match=r"Committed revision 15")
os.chdir("../testYYY-branch")
open("test4", "w").write("test4")
self.launch("svn add test4")
self.launch('svn ci -m "add test4"',
match=r"Committed revision 16")
os.chdir("../test-branch")
self.svnmerge("block -r 16")
self.launch('svn ci -m "block r16"',
match=r"Committed revision 17")
#os.chdir("../test-branch")
open("test5", "w").write("test5")
self.launch("svn add test5")
self.launch('svn ci -m "add test5"',
match=r"Committed revision 18")
os.chdir("../trunk")
self.svnmerge("block -r 18")
self.launch('svn ci -m "block r18"',
match=r"Committed revision 19")
#os.chdir("../trunk")
self.svnmerge("merge -r 17")
self.launch('svn ci -m "merge r17 from test-branch"',
match=r"Committed revision 20")
p = self.getproperty()
self.assertEqual(p, '/branches/test-branch:1-13,17')
p = self.getBlockedProperty()
self.assertEqual(p, '/branches/test-branch:18')
def testBasic(self):
self.svnmerge("init")
p = self.getproperty()
self.assertEqual("/trunk:1-6", p)
self.svnmerge("avail", match=r"\A9-10$")
self.svnmerge("avail -v", match=r"phantom.*7-8")
self.svnmerge("avail -B", match=r"\A$")
self.svnmerge("avail -A", match=r"\A9-10$")
self.svnmerge("avail --log", match=r"| r7.*| r8")
self.svnmerge("avail --diff -r9", match=r"Index: test4")
self.svnmerge("avail --log -r5", match=r"\A\Z")
self.svnmerge("avail --diff -r5", match=r"\A\Z")
self.svnmerge("integrated", match=r"^3-6$")
self.svnmerge("integrated --log -r5", match=r"| r5 ")
self.svnmerge("integrated --diff -r5", match=r"Index: test2")
def test_log_msg_suggest(self):
self.svnmerge("init -vf commit-log.txt", match=r"wrote commit message")
self.assert_(os.path.exists("commit-log.txt"))
os.remove("commit-log.txt")
def testInitForce(self):
open("test1", "a").write("foo")
self.svnmerge("init", error=True, match=r"clean")
self.svnmerge("init -F")
p = self.getproperty()
self.assertEqual("/trunk:1-6", p)
def testUninit(self):
"""Test that uninit works, for both merged and blocked revisions."""
os.chdir("..")
self.launch("svn co %(TEST_REPO_URL)s/branches/testYYY-branch testYYY-branch")
os.chdir("trunk")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 13")
self.svnmerge2(["init", "-r1-13",
self.test_repo_url + "/branches/test-branch"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 14")
self.svnmerge2(["init", self.test_repo_url + "/branches/testYYY-branch"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 15")
# Create changes on test-branch that we can block
os.chdir("..")
os.chdir("test-branch")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 15")
open("test1", "w").write("test 1-changed_on_test-branch")
self.launch("svn commit -m \"Change to test1 on test-branch\"",
match=r"Committed revision 16")
# Create changes on testYYY-branch that we can block
os.chdir("..")
os.chdir("testYYY-branch")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 16")
open("test2", "w").write("test 2-changed_on_testYYY-branch")
self.launch("svn commit -m \"Change to test2 on testYYY-branch\"",
match=r"Committed revision 17")
# Block changes from both branches on the trunk
os.chdir("..")
os.chdir("trunk")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 17")
self.svnmerge("block -S testYYY-branch", match=r"'svnmerge-blocked' set")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 18")
self.svnmerge("block -S test-branch", match=r"'svnmerge-blocked' set")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 19")
# Do the uninit
self.svnmerge2(["uninit", "--source", self.test_repo_url + "/branches/testYYY-branch"])
# Check that the merged property for testYYY-branch was removed, but
# not for test-branch
pmerged = self.getproperty()
self.assertEqual("/branches/test-branch:1-13", pmerged)
# Check that the blocked property for testYYY-branch was removed, but
# not for test-branch
pblocked = self.getBlockedProperty()
self.assertEqual("/branches/test-branch:16", pblocked)
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 20")
self.svnmerge2(["uninit", "--source", self.test_repo_url + "/branches/test-branch"])
# Check that the merged and blocked properties for test-branch have been removed too
pmerged = self.getproperty()
self.assertEqual(None, pmerged)
pblocked = self.getBlockedProperty()
self.assertEqual(None, pblocked)
def testUninitForce(self):
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
self.svnmerge2(["init", self.test_repo_url + "/branches/testYYY-branch"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision")
p = self.getproperty()
# properties come back in arbitrary order, so search for them individually
self.assertTrue(re.search("/branches/testYYY-branch:1-\d+?", p))
self.assertTrue(re.search("/trunk:1-\d+?", p))
open("test1", "a").write("foo")
self.svnmerge("uninit --source " + self.test_repo_url + "/branches/testYYY-branch",
error=True, match=r"clean")
self.svnmerge("uninit -F --source " + self.test_repo_url + "/branches/testYYY-branch")
p = self.getproperty()
self.assert_(re.search("^/trunk:1-\d+", p))
def testCheckNoCopyfrom(self):
os.chdir("..")
os.chdir("trunk")
self.svnmerge("init", error=True, match=r"no copyfrom")
def testInitScenarios(self):
""" Run various scenarios w/ svnmerge.py init and verify
the default values that are set as the integrated
revisions."""
# Run init with branch as merge source and trunk as merge target
os.chdir("..")
os.chdir("trunk")
self.svnmerge("init ../test-branch")
# Verify range ends at rev in which branch was created
self.launch("svn proplist -v", match=r":1-13")
self.revert()
# Run init with TRUNK as merge source and BRANCH as merge target
os.chdir("..")
os.chdir("test-branch")
self.svnmerge("init ../trunk")
# Verify range ends at rev of trunk which was copied to create branch
self.launch("svn proplist -v", match=r":1-6")
self.revert()
# Same thing, but with no explicit parameter (should work implicitly)
self.svnmerge("init")
# Verify range ends at rev of trunk which was copied to create branch
self.launch("svn proplist -v", match=r":1-6")
self.revert()
# Run init with TRUNK as merge src, & any other branch which is not
# a copy of trunk (or the source from which trunk was copied)
# as the merge target.
os.chdir("../trunk")
os.chdir("..")
self.launch('svn mkdir -m "create /other" %(TEST_REPO_URL)s/other') # creates r14
self.launch("svn co %(TEST_REPO_URL)s/other")
os.chdir("other")
self.svnmerge("init ../trunk")
# Verify integrated range ends with merge source's latest rev as of
# the time of initialization:
self.launch("svn proplist -v", match=r":1-14")
self.revert()
# Run init w/ explicit parms; verify them
self.svnmerge("init -r 1-999 ../trunk")
self.launch("svn proplist -v", match=r":1-999")
def testTrimmedAvailMerge(self):
"""Check that both avail and merge do not search for phantom revs too hard."""
self.svnmerge("init")
self.svnmerge("avail -vv -r8-9", match=r"svn --non-interactive log.*-r8:9")
self.svnmerge("merge -F -vv -r8-9", match=r"svn --non-interactive log.*-r8:9")
self.svnmerge("avail -vv -r2", nonmatch=r"svn log")
self.svnmerge("integrated", match=r"^3-6,8-9$")
def testMergeRecordOnly(self):
"""Check that flagging revisions as manually merged works."""
self.svnmerge("init")
self.svnmerge("avail -vv -r9", match=r"svn --non-interactive log.*-r9:9")
self.svnmerge("merge --record-only -F -vv -r9",
nonmatch=r"svn merge -r 8:9")
self.svnmerge("avail -r9", match=r"\A$")
self.svnmerge("integrated", match=r"^3-6,9$")
self.svnmerge("integrated -r9", match=r"^9$")
def testBidirectionalMerges(self):
"""Check that reflected revisions are recognized properly for bidirectional merges."""
os.chdir("..")
os.chdir("test-branch")
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
os.chdir("..")
os.chdir("trunk")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 14")
self.svnmerge2(["init", "-r1-14",
self.test_repo_url + "/branches/test-branch"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 15")
os.remove("svnmerge-commit-message.txt")
open("test1", "w").write("test 1-changed_on_trunk")
self.launch("svn commit -m \"Change to test1 on trunk\"",
match=r"Committed revision 16")
self.svnmerge("integrated", match=r"^13-14$")
os.chdir("..")
os.chdir("test-branch")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 16")
# test-branch was copied from trunk's r6. So non-phantom revs
# since that point should still be available to merge from
# trunk to test-branch:
self.svnmerge("avail -vv", match=r"\n9-10,16$")
self.svnmerge("merge -vv", match=r"svn --non-interactive merge --force -r 15:16")
p = self.getproperty()
self.assertEqual("/trunk:1-16", p)
self.svnmerge("integrated", match=r"^3-16$")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 17")
os.remove("svnmerge-commit-message.txt")
open("test1", "w").write("test 1-changed_on_branch_after_merge_from_trunk")
self.launch("svn commit -m \"Change to test1 on branch\"",
match=r"Committed revision 18")
os.chdir("..")
os.chdir("trunk")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 18")
# Check reflected revision is excluded with --bidirectional
self.svnmerge("avail -vv --bidirectional", match=r"\n18$")
# and without --bidirectional.
self.svnmerge("avail -vv", match=r"\n18$")
self.svnmerge("merge -vv", match=r"svn --non-interactive merge --force -r 17:18")
p = self.getproperty()
self.assertEqual("/branches/test-branch:1-18", p)
self.svnmerge("integrated", match=r"^13-18$")
def testBidirectionalMergesMultiBranch(self):
"""Check that merges from a second branch are not considered reflected for other branches."""
os.chdir("..")
self.multilaunch("""
svn cp -m "Create test-branch2" %(TEST_REPO_URL)s/trunk %(TEST_REPO_URL)s/branches/test-branch2
svn co %(TEST_REPO_URL)s/branches/test-branch2 test-branch2
""")
os.chdir("test-branch")
self.svnmerge2(["init", "-r1-13", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 15")
os.remove("svnmerge-commit-message.txt")
os.chdir("..")
os.chdir("test-branch2")
self.svnmerge2(["init", "-r1-14", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 16")
os.remove("svnmerge-commit-message.txt")
os.chdir("..")
os.chdir("trunk")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 16")
self.svnmerge2(["init", "-r1-16",
self.test_repo_url + "/branches/test-branch"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 17")
os.remove("svnmerge-commit-message.txt")
self.svnmerge2(["init", "-r1-17",
self.test_repo_url + "/branches/test-branch2"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 18")
os.remove("svnmerge-commit-message.txt")
os.chdir("..")
os.chdir("test-branch2")
open("test1", "w").write("test 1-changed_on_branch2")
self.launch("svn commit -m \"Change to test1 on branch2\"",
match=r"Committed revision 19")
os.chdir("..")
os.chdir("trunk")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 19")
# Merge into trunk
self.svnmerge("merge -vv -S /branches/test-branch2",
match=r"merge --force -r 18:19")
p = self.getproperty()
# allow properties to come back in arbitrary order
self.assertTrue(re.search("/branches/test-branch2:1-19", p))
self.assertTrue(re.search("/branches/test-branch:1-16", p))
self.svnmerge("integrated -S branch2", match=r"^14-19$")
self.svnmerge("integrated -S ../test-branch", match=r"^13-16$")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 20")
os.remove("svnmerge-commit-message.txt")
os.chdir("..")
os.chdir("test-branch")
# Not using switch, so must update to get latest repository rev.
self.launch("svn update", match=r"At revision 20")
# Initialized revs should not be available for merge
self.svnmerge("avail -v", match=r"initialized.*17-18")
# Latest revision on trunk which was merged from test-branch2
# should be available for test-branch with --bidirectional flag.
self.svnmerge("avail -vv --bidirectional", match=r"merged are:\n20$")
# and also without the --bidirectional flag.
self.svnmerge("avail -vv", match=r"merged are:\n20$")
self.svnmerge("merge -vv", match=r"merge --force -r 19:20")
p = self.getproperty()
self.assertEqual("/trunk:1-20", p)
self.svnmerge("integrated", match=r"^3-20$")
def testRollbackWithoutInit(self):
"""Rollback should error out if invoked prior to init"""
self.svnmerge("rollback -vv -S ../trunk",
error = True,
match = r"no integration info available for path")
def testRollbackOutsidePossibleRange(self):
"""`svnmerge rollback' should error out if range contains revisions prior to
SOURCE creation date."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
expected_error = r"""Specified revision range falls out of the rollback range."""
self.svnmerge("rollback -vv -S ../trunk -r 2-14",
error = True,
match = expected_error)
def testRollbackWithoutRevisionOpt(self):
"""`svnmerge rollback' should error out if -r option is not given"""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
self.svnmerge("rollback -vv -S ../trunk",
error = True,
match = r"The '-r' option is mandatory for rollback")
def testInitAndRollbackRecordOnly(self):
"""Init svnmerge, modify source head, merge, rollback --record-only."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
# Rollback record-only
expected_output = r"property 'svnmerge-integrated' set on '.'"
detested_output = r"""
D test2
D test3"""
self.svnmerge("rollback -vv --record-only -S ../trunk -r5-7",
match = expected_output,
nonmatch = detested_output)
def testInitAndRollback(self):
"""Init svnmerge, modify source head, merge, rollback."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
# Svnmerge rollback r5-7
expected_output = "D\s+test2\s+D\s+test3"
self.svnmerge("rollback -vv -S ../trunk -r5-7",
match = expected_output)
def testMergeAndRollbackEmptyRevisionRange(self):
"""Init svnmerge, modify source head, merge, rollback where no merge
occurred."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
# Make changes to trunk
os.chdir("../trunk")
open("newfile", "w").close()
self.launch("svn add newfile")
self.launch('svn commit -m "Adding newfile"', match=r"Committed revision 15")
open("anothernewfile", "w").close()
self.launch("svn add anothernewfile")
self.launch('svn commit -m "Adding anothernewfile"', match=r"Committed revision 16")
# Svnmerge block r15,16
os.chdir("../test-branch")
self.launch("svn up ..",
error = False)
self.svnmerge("block -r 15,16 -S ../trunk")
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 17")
self.svnmerge("merge -S ../trunk")
self.launch("svn commit -F svnmerge-commit-message.txt")
# Svnmerge rollback r15-16
self.svnmerge("rollback -vv -S ../trunk -r15-16",
error = False,
match = r"Nothing to rollback in revision range r15-16")
def testMergeAndRollback(self):
"""Init svnmerge, modify source head, merge, rollback."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
# Make changes to trunk
os.chdir("../trunk")
open("newfile", "w").close()
self.launch("svn add newfile")
self.launch('svn commit -m "Adding newfile"', match=r"Committed revision 15")
# Svnmerge merge r15
os.chdir("../test-branch")
self.svnmerge("merge -r 15 -S ../trunk")
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 16")
# Svnmerge rollback r15
self.svnmerge("rollback -vv -S ../trunk -r15",
match = r"-r 15:14")
def testBlockMergeAndRollback(self):
"""Init svnmerge, block, modify head, merge, rollback."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
# Make changes to trunk
os.chdir("../trunk")
open("newfile", "w").close()
self.launch("svn add newfile")
self.launch('svn commit -m "Adding newfile"', match=r"Committed revision 15")
open("anothernewfile", "w").close()
self.launch("svn add anothernewfile")
self.launch('svn commit -m "Adding anothernewfile"', match=r"Committed revision 16")
# Svnmerge block r16, merge r15
os.chdir("../test-branch")
self.launch("svn up ..",
error = False)
self.svnmerge("block -r 16 -S ../trunk")
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 17")
self.svnmerge("merge -S ../trunk",
nonmatch = r"A anothernewfile",
match = r"A newfile")
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 18")
# Svnmerge rollback revision range 15-18 (in effect only 15,17)
self.svnmerge("rollback -vv -S ../trunk -r15-18",
nonmatch = r"D anothernewfile")
def testMergeWithPotentialPropertyConflict(self):
"""Init branch B, merge changes from branch A to branch B,
init branch C, and attempt a merge of changes from branch B to
branch C."""
# Initialize merge info for test-branch.
self.svnmerge2(["init", "-r 3-6", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
# Make a change to trunk.
os.chdir("../trunk")
open("newfile", "w").close()
self.launch("svn add newfile")
self.launch('svn commit -m "Adding newfile"',
match=r"Committed revision 15")
# Merge a change from trunk to test-branch.
os.chdir("../test-branch")
self.svnmerge("merge -r 15 -S ../trunk")
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 16")
# Get a WC for testYYY-branch.
os.chdir("..")
self.launch("svn co %s/branches/testYYY-branch" % self.test_repo_url)
os.chdir("testYYY-branch")
# Initialize merge info for testYYY-branch.
self.svnmerge2(["init", "-r 13",
self.test_repo_url + "/branches/test-branch"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 17")
os.remove("svnmerge-commit-message.txt")
### FIXME: Unfortunately, we're getting a conflict for the
### merge info property in the following svnmerge invocation
### due to Subversion's (reasonable) lack of property value
### merging (which isn't possible without knowing a property's
### MIME type)
# Attempt a merge of changes from test-branch to
# testYYY-branch.
self.svnmerge("merge -r 16 -S ../test-branch")
try:
self.launch("svn commit -F svnmerge-commit-message.txt",
match=r"Committed revision 18")
except AssertionError:
self.assert_(os.path.isfile("dir_conflicts.prej"))
def testCommitMessageEncoding(self):
"""Init svnmerge, modify source head and commit with a message
containing non-ASCII caracters, merge, commit, and verify the commit
message was correctly encoded."""
# Initialize svnmerge
self.svnmerge2(["init", self.test_repo_url + "/trunk"])
self.launch("svn commit -F svnmerge-commit-message.txt",
match = r"Committed revision 14")
os.remove("svnmerge-commit-message.txt")
commit_msg = u"adição no repositório"
input_encoding = locale.getdefaultlocale()[1]
output_encoding = sys.stdout.encoding
# Create a file
os.chdir("../trunk")
open("newfile", "w").close()
# Create a message containing non-ASCII caracters. The message will be
# kept inside a file, so we don't need to worry about Python or the OS
# converting the command line before it's sent to svn
msg_file = open('msg.txt', 'w')
msg_file.write(commit_msg.encode(input_encoding))
msg_file.close()
# Add the file and commit with the message above
self.launch("svn add newfile")
self.launch('svn commit -F msg.txt', match="Committed revision 15")
os.remove('msg.txt')
# Check the message was properly encoded by svn (this will currently
# only work if the user config file does not override log-encoding)
self.launch('svn log -r 15', match=commit_msg.encode(output_encoding))
# Merge changes into the branch commiting with the message provided by
# svnmerge
os.chdir("../test-branch")
self.svnmerge("merge")
self.launch("svn commit -F svnmerge-commit-message.txt",
match="Committed revision 16")
# The procedure above should have not misencoded the message
self.launch('svn log -r 16', match=commit_msg.encode(output_encoding))
def test_pathid_fns(self):
# (see also TestCase_pathid_fns for tests that don't need a repos)
os.chdir("..")
self.assertEqual(svnmerge.pathid_to_url( "/branches/testYYY-branch", "./trunk"),
"%s/branches/testYYY-branch" % self.test_repo_url)
self.assertTrue(
svnmerge.equivalent_pathids("/branches/testYYY-branch",
"/branches/testYYY-branch",
"./trunk"))
self.assertFalse(
svnmerge.equivalent_pathids("/branches/test-branch",
"/branches/testYYY-branch",
"./trunk"))
def test_invalid_url(self):
self.svnmerge2(["init", self.test_repo_url + "/trunk"]) # warm up svnmerge
self.assertEqual(svnmerge.get_svninfo("file://foo/bar"), {})
def test_dict_from_revlist_prop(self):
locdict = svnmerge.dict_from_revlist_prop("/trunk:1-10 uuid://65390229-12b7-0310-b90b-f21a5aa7ec8e/branches/foo:20-30")
for k, v in locdict.items():
if str(k) == '/trunk':
self.assertEqual(str(v), '1-10')
elif str(k) == 'uuid://65390229-12b7-0310-b90b-f21a5aa7ec8e/branches/foo':
self.assertEqual(str(v), '20-30')
else:
self.fail("Unknown pathid '%s'" % k)
def test_pathid_fns(self):
os.chdir("..")
# run svnmerge once to get things rolling
self.svnmerge("init", error=True)
branch = svnmerge.PathIdentifier.from_target("test-branch")
trunk = svnmerge.PathIdentifier.from_target("trunk")
yy = svnmerge.PathIdentifier.from_target("%s/branches/testYYY-branch" % self.test_repo_url)
branchurl = svnmerge.PathIdentifier.from_target("%s/branches/test-branch" % self.test_repo_url)
trunkurl = svnmerge.PathIdentifier.from_target("%s/trunk" % self.test_repo_url)
self.assertTrue(branchurl == branch)
self.assertFalse(branchurl != branch)
self.assertTrue(trunkurl == trunk)
self.assertTrue(yy != trunk)
def test_PathIdentifier_hint_url(self):
os.chdir("..")
# prime the cache with our repo URL
svnmerge.PathIdentifier.hint(self.test_repo_url + '/trunk')
expected = svnmerge.PathIdentifier.locobjs['/trunk']
# and then we should get the same pathid for all of these
self.assertEqual(expected, svnmerge.PathIdentifier.from_target('trunk'))
self.assertEqual(expected, svnmerge.PathIdentifier.from_target(self.test_repo_url + '/trunk'))
def test_is_pathid(self):
os.chdir("..")
l = svnmerge.PathIdentifier.from_target('trunk')
self.assertTrue(svnmerge.is_pathid(l))
def testOptionOrder(self):
"""Make sure you can intermix command name, arguments and options in any order."""
# this is under TestCase_TestRepo because it assumes that '.' is a svn working dir
self.svnmerge("--log avail",
error=True,
match=r"no integration info") # accepted
self.svnmerge("-l avail",
error=True,
match=r"no integration info") # accepted
self.svnmerge("-r123 merge",
error=True,
match=r"no integration info") # accepted
self.svnmerge("-s -v -r92481 merge",
error=True,
match=r"no integration info") # accepted
self.svnmerge("--log merge",
error=True,
match=r"option --log not recognized")
self.svnmerge("--diff foobar", error=True, match=r"foobar")
# This requires gnu_getopt support to be parsed
if hasattr(getopt, "gnu_getopt"):
self.svnmerge("-r123 merge . --log",
error=True,
match=r"option --log not recognized")
if __name__ == "__main__":
# If an existing template repository and working copy for testing
# exists, then always remove it. This prevents any problems if
# this test suite is modified and there exists an older template
# directory that may be used. This will also prevent problems if
# in a previous run of this script, the template was being created
# when the script was canceled, leaving it in an inconsistent
# state.
template_path = get_template_path()
if os.path.exists(template_path):
rmtree(template_path)
unittest.main()