summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py66
-rw-r--r--tests/pathutils.py22
-rw-r--r--tests/test_basic.py439
-rw-r--r--tests/test_cli.py10
-rw-r--r--tests/test_core.py18
-rw-r--r--tests/test_dotfile.py164
-rw-r--r--tests/test_repository.py161
7 files changed, 513 insertions, 367 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
index 41f8995..7fc2cc4 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,16 +1,62 @@
+import os
import pytest
-from click.testing import CliRunner
+from dotfiles.utils import compare_path as samefile
-from dotfiles.repository import Repository
+def _touch(fname, times=None):
+ with open(fname, 'a'):
+ os.utime(fname, times)
-@pytest.fixture(scope='function', params=['', 'home'])
-def repo(request, tmpdir):
- path = str(tmpdir.ensure_dir('repo'))
- home = str(tmpdir.ensure_dir(request.param))
- return Repository(path, home)
+class HomeDirectory(object):
-@pytest.fixture(scope='function')
-def runner():
- return CliRunner()
+ DEFAULT_REPOSITORY = 'dotfiles'
+
+ def __init__(self, path, repo=None, contents=None):
+ self.path = path
+ if not repo:
+ self.repo = os.path.join(path, self.DEFAULT_REPOSITORY)
+ if contents:
+ self.setup(contents)
+
+ def setup(self, contents):
+ repo = os.path.join(self.path, self.repo)
+ os.mkdir(repo)
+
+ for link, link_should_exist in contents.items():
+
+ target = os.path.join('%s/%s' % (repo, link[1:]))
+ _touch(target)
+
+ if link_should_exist:
+ os.symlink(target, os.path.join(self.path, link))
+
+ self.verify(contents)
+
+ def verify(self, contents):
+ __tracebackhide__ = True
+
+ for link, link_should_exist in contents.items():
+
+ target = os.path.join(self.path, '%s/%s' % (self.repo, link[1:]))
+
+ if not os.path.exists(target):
+ pytest.fail("missing expected repo file \"%s\"" % target)
+
+ link = os.path.join(self.path, link)
+ link_exists = os.path.exists(link)
+
+ if link_should_exist:
+ if not link_exists:
+ pytest.fail("missing expected symlink \"%s\"" % link)
+ if not samefile(link, target):
+ pytest.fail("\"%s\" does not link to \"%s\"" %
+ (link, target))
+
+ elif link_exists:
+ pytest.fail("found unexpected symlink \"%s\"" % link)
+
+
+@pytest.fixture
+def homedir(tmpdir):
+ return HomeDirectory(str(tmpdir))
diff --git a/tests/pathutils.py b/tests/pathutils.py
deleted file mode 100644
index 87f82af..0000000
--- a/tests/pathutils.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# TODO: docstrings
-# XXX: can this move into tests/?
-
-
-def is_file(path):
- return path.is_file() and not path.is_symlink()
-
-
-def is_link(path):
- return path.is_file() and path.is_symlink()
-
-
-def mkdir(path):
- try:
- path.mkdir(parents=True)
- except FileExistsError:
- pass
-
-
-def touch(path):
- mkdir(path.parent)
- path.touch()
diff --git a/tests/test_basic.py b/tests/test_basic.py
new file mode 100644
index 0000000..41d1c0e
--- /dev/null
+++ b/tests/test_basic.py
@@ -0,0 +1,439 @@
+from __future__ import with_statement
+
+import os
+import pytest
+import shutil
+import tempfile
+import unittest
+
+from dotfiles.cli import dispatch
+from dotfiles.core import Dotfiles
+from dotfiles.utils import is_link_to
+
+
+def touch(fname, times=None):
+ with open(fname, 'a'):
+ os.utime(fname, times)
+
+
+class DotfilesTestCase(unittest.TestCase):
+
+ def setUp(self):
+ """Create a temporary home directory."""
+
+ self.homedir = tempfile.mkdtemp()
+
+ # Create a repository for the tests to use.
+ self.repository = os.path.join(self.homedir, 'Dotfiles')
+ os.mkdir(self.repository)
+
+ def tearDown(self):
+ """Delete the temporary home directory and its contents."""
+
+ shutil.rmtree(self.homedir)
+
+ def assertPathEqual(self, path1, path2):
+ self.assertEqual(
+ os.path.realpath(path1),
+ os.path.realpath(path2))
+
+ def test_force_sync_directory(self):
+ """Test forced sync when the dotfile is a directory.
+
+ I installed the lastpass chrome extension which stores a socket in
+ ~/.lastpass. So I added that directory as an external to /tmp and
+ attempted a forced sync. An error occurred because sync() calls
+ os.remove() as it mistakenly assumes the dotfile is a file and not
+ a directory.
+ """
+
+ os.mkdir(os.path.join(self.homedir, '.lastpass'))
+ externals = {'.lastpass': '/tmp'}
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals=externals, packages=[],
+ dry_run=False)
+
+ dotfiles.sync(force=True)
+
+ self.assertPathEqual(
+ os.path.join(self.homedir, '.lastpass'),
+ '/tmp')
+
+ def test_dispatch(self):
+ """Test that the force option is handed on to the sync method."""
+
+ class MockDotfiles(object):
+ def sync(self, files=None, force=False):
+ assert force
+
+ class MockNamespace(object):
+ def __init__(self):
+ self.action = 'sync'
+ self.force = True
+
+ dispatch(MockDotfiles(), MockNamespace(), [])
+
+ def test_move_repository(self):
+ """Test the move() method for a Dotfiles repository."""
+
+ touch(os.path.join(self.repository, 'bashrc'))
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], force=True, externals={}, packages=[],
+ dry_run=False)
+
+ dotfiles.sync()
+
+ # Make sure sync() did the right thing.
+ self.assertPathEqual(
+ os.path.join(self.homedir, '.bashrc'),
+ os.path.join(self.repository, 'bashrc'))
+
+ target = os.path.join(self.homedir, 'MyDotfiles')
+
+ dotfiles.move(target)
+
+ self.assertTrue(os.path.exists(os.path.join(target, 'bashrc')))
+ self.assertPathEqual(
+ os.path.join(self.homedir, '.bashrc'),
+ os.path.join(target, 'bashrc'))
+
+ def test_force_sync_directory_symlink(self):
+ """Test a forced sync on a directory symlink.
+
+ A bug was reported where a user wanted to replace a dotfile repository
+ with an other one. They had a .vim directory in their home directory
+ which was obviously also a symbolic link. This caused:
+
+ OSError: Cannot call rmtree on a symbolic link
+ """
+
+ # Create a dotfile symlink to some directory
+ os.mkdir(os.path.join(self.homedir, 'vim'))
+ os.symlink(os.path.join(self.homedir, 'vim'),
+ os.path.join(self.homedir, '.vim'))
+
+ # Create a vim directory in the repository. This will cause the above
+ # symlink to be overwritten on sync.
+ os.mkdir(os.path.join(self.repository, 'vim'))
+
+ # Make sure the symlink points to the correct location.
+ self.assertPathEqual(
+ os.path.join(self.homedir, '.vim'),
+ os.path.join(self.homedir, 'vim'))
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=[], dry_run=False)
+
+ dotfiles.sync(force=True)
+
+ # The symlink should now point to the directory in the repository.
+ self.assertPathEqual(
+ os.path.join(self.homedir, '.vim'),
+ os.path.join(self.repository, 'vim'))
+
+ def test_glob_ignore_pattern(self):
+ """ Test that the use of glob pattern matching works in the ignores list.
+
+ The following repo dir exists:
+
+ myscript.py
+ myscript.pyc
+ myscript.pyo
+ bashrc
+ bashrc.swp
+ vimrc
+ vimrc.swp
+ install.sh
+
+ Using the glob pattern dotfiles should have the following sync result in home:
+
+ .myscript.py -> Dotfiles/myscript.py
+ .bashrc -> Dotfiles/bashrc
+ .vimrc -> Dotfiles/vimrc
+
+ """
+ ignore = ['*.swp', '*.py?', 'install.sh']
+
+ all_repo_files = (
+ ('myscript.py', '.myscript.py'),
+ ('myscript.pyc', None),
+ ('myscript.pyo', None),
+ ('bashrc', '.bashrc'),
+ ('bashrc.swp', None),
+ ('vimrc', '.vimrc'),
+ ('vimrc.swp', None),
+ ('install.sh', None)
+ )
+
+ all_dotfiles = [f for f in all_repo_files if f[1] is not None]
+
+ for original, symlink in all_repo_files:
+ touch(os.path.join(self.repository, original))
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=ignore, externals={}, packages=[],
+ dry_run=False)
+
+ dotfiles.sync()
+
+ # Now check that the files that should have a symlink
+ # point to the correct file and are the only files that
+ # exist in the home dir.
+ self.assertEqual(
+ sorted(os.listdir(self.homedir)),
+ sorted([f[1] for f in all_dotfiles] + ['Dotfiles']))
+
+ for original, symlink in all_dotfiles:
+ self.assertPathEqual(
+ os.path.join(self.repository, original),
+ os.path.join(self.homedir, symlink))
+
+ def test_packages(self):
+ """
+ Test packages.
+ """
+ files = ['foo', 'package/bar']
+ symlinks = ['.foo', '.package/bar']
+ join = os.path.join
+
+ # Create files
+ for filename in files:
+ path = join(self.repository, filename)
+ dirname = os.path.dirname(path)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ touch(path)
+
+ # Create Dotfiles object
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=['package'],
+ dry_run=False)
+
+ # Create symlinks in homedir
+ dotfiles.sync()
+
+ # Verify it created what we expect
+ def check_all(files, symlinks):
+ self.assertTrue(os.path.isdir(join(self.homedir, '.package')))
+ for src, dst in zip(files, symlinks):
+ self.assertTrue(is_link_to(join(self.homedir, dst),
+ join(self.repository, src)))
+ check_all(files, symlinks)
+
+ # Add files to the repository
+ new_files = [join(self.homedir, f) for f in ['.bar', '.package/foo']]
+ for filename in new_files:
+ path = join(self.homedir, filename)
+ touch(path)
+ new_repo_files = ['bar', 'package/foo']
+ dotfiles.add(new_files)
+ check_all(files + new_repo_files, symlinks + new_files)
+
+ # Remove them from the repository
+ dotfiles.remove(new_files)
+ check_all(files, symlinks)
+
+ # Move the repository
+ self.repository = join(self.homedir, 'Dotfiles2')
+ dotfiles.move(self.repository)
+ check_all(files, symlinks)
+
+ def test_missing_package(self):
+ """
+ Test a non-existent package.
+ """
+
+ package_file = '.package/bar'
+
+ # Create Dotfiles object
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=['package'],
+ dry_run=False)
+
+ path = os.path.join(self.homedir, package_file)
+ dirname = os.path.dirname(path)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ touch(path)
+
+ dotfiles.add([os.path.join(self.homedir, package_file)])
+
+ def test_single_sync(self):
+ """
+ Test syncing a single file in the repo
+
+ The following repo dir exists:
+
+ bashrc
+ netrc
+ vimrc
+
+ Syncing only vimrc should have the folowing sync result in home:
+
+ .vimrc -> Dotfiles/vimrc
+
+ """
+
+ # define the repository contents
+ repo_files = (
+ ('bashrc', False),
+ ('netrc', False),
+ ('vimrc', True))
+
+ # populate the repository
+ for dotfile, _ in repo_files:
+ touch(os.path.join(self.repository, dotfile))
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=[],
+ dry_run=False)
+
+ # sync only certain dotfiles
+ for dotfile, should_sync in repo_files:
+ if should_sync:
+ dotfiles.sync(files=['.%s' % dotfile])
+
+ # verify home directory contents
+ for dotfile, should_sync in repo_files:
+ if should_sync:
+ self.assertPathEqual(
+ os.path.join(self.repository, dotfile),
+ os.path.join(self.homedir, '.%s' % dotfile))
+ else:
+ self.assertFalse(os.path.exists(
+ os.path.join(self.homedir, dotfile)))
+
+
+ def test_missing_remove(self):
+ """Test removing a dotfile that's been removed from the repository."""
+
+ repo_file = os.path.join(self.repository, 'testdotfile')
+
+ touch(repo_file)
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=[],
+ dry_run=False)
+
+ dotfiles.sync()
+
+ # remove the dotfile from the repository, homedir symlink is now broken
+ os.remove(repo_file)
+
+ # remove the broken symlink
+ dotfiles.remove(['.testdotfile'])
+
+ # verify symlink was removed
+ self.assertFalse(os.path.exists(
+ os.path.join(self.homedir, '.testdotfile')))
+
+
+ def test_add_package(self):
+ """
+ Test adding a package that isn't already in the repository
+
+ """
+
+ package_dir = os.path.join(self.homedir,
+ '.%s/%s' % ('config', 'gtk-3.0'))
+
+ os.makedirs(package_dir)
+ touch('%s/testfile' % package_dir)
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=['config'],
+ dry_run=False, quiet=True)
+
+ # This should fail, you should not be able to add dotfiles that are
+ # defined to be packages.
+ dotfiles.add(['.config'])
+ self.assertFalse(os.path.islink(os.path.join(self.homedir, '.config')))
+
+ def test_no_dot_prefix(self):
+ # define the repository contents
+ repo_files = ('bashrc', 'netrc', 'vimrc')
+
+ # populate the repository
+ for dotfile in repo_files:
+ touch(os.path.join(self.repository, dotfile))
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=[],
+ dry_run=False, no_dot_prefix=True)
+
+ dotfiles.sync()
+
+ # verify home directory contents
+ for dotfile in repo_files:
+ self.assertPathEqual(
+ os.path.join(self.repository, dotfile),
+ os.path.join(self.homedir, dotfile))
+
+ @pytest.mark.xfail()
+ def test_add_package_file(self):
+ """
+ Test adding a package that isn't already in the repository
+
+ """
+
+ package_dir = os.path.join(self.homedir,
+ '.%s/%s' % ('config', 'gtk-3.0'))
+
+ os.makedirs(package_dir)
+ touch('%s/testfile' % package_dir)
+
+ dotfiles = Dotfiles(
+ homedir=self.homedir, path=self.repository,
+ prefix='', ignore=[], externals={}, packages=['config'],
+ dry_run=False)
+
+ # This should succeed and the directory structure in the repository
+ # should be created since it didn't already exist.
+ dotfiles.add(['.config/gtk-3.0'])
+ self.assertTrue(os.path.islink(
+ os.path.join(self.homedir, '.config/gtk-3.0')))
+
+
+ @pytest.mark.xfail()
+ def test_package_and_prefix(self):
+ """Test syncing a package when using a non-default prefix."""
+
+ package_dir = os.path.join(self.repository, '.config/awesome')
+ os.makedirs(package_dir)
+ touch('%s/testfile' % package_dir)
+
+ dotfiles = Dotfiles(homedir=self.homedir,
+ path=self.repository,
+ prefix='.',
+ ignore=[],
+ externals={},
+ packages=['.config'],
+ dry_run=False,
+ quiet=True)
+
+ dotfiles.sync()
+
+ expected = os.path.join(self.homedir, ".config")
+ self.assertTrue(os.path.isdir(expected))
+
+ expected = os.path.join(expected, "awesome")
+ self.assertTrue(os.path.islink(expected))
+
+ expected = os.path.join(expected, "testfile")
+ self.assertTrue(os.path.isfile(expected))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_cli.py b/tests/test_cli.py
deleted file mode 100644
index 64f9266..0000000
--- a/tests/test_cli.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from dotfiles.cli import cli
-
-
-class TestCli(object):
-
- def test_status(self, runner, repo, monkeypatch):
-
- result = runner.invoke(cli, ['-r', str(repo.path), 'status'])
- assert not result.exception
- assert result.output == ''
diff --git a/tests/test_core.py b/tests/test_core.py
new file mode 100644
index 0000000..640cac9
--- /dev/null
+++ b/tests/test_core.py
@@ -0,0 +1,18 @@
+from dotfiles.core import Dotfiles as Repository
+
+
+def test_sync(homedir):
+ """Basic sync operation."""
+
+ contents = {'.foo': True,
+ '.bar': True,
+ '.baz': False}
+
+ homedir.setup(contents)
+
+ Repository(path=homedir.repo,
+ homedir=homedir.path).sync()
+
+ # .baz should now exist and link to the correct location
+ contents['.baz'] = True
+ homedir.verify(contents)
diff --git a/tests/test_dotfile.py b/tests/test_dotfile.py
deleted file mode 100644
index d992bdb..0000000
--- a/tests/test_dotfile.py
+++ /dev/null
@@ -1,164 +0,0 @@
-import pytest
-
-from pathlib import Path
-from dotfiles.dotfile import Dotfile
-from dotfiles.pathutils import is_file, is_link, touch, mkdir
-from dotfiles.exceptions import TargetExists, IsSymlink, \
- TargetMissing, NotASymlink, Exists
-
-
-def _make_dotfile(repo, name, target=None):
- return Dotfile(repo.homedir.joinpath(name),
- repo.path.joinpath(target if target else name))
-
-
-@pytest.mark.parametrize('name', ['.a'])
-def test_str(repo, name):
- dotfile = _make_dotfile(repo, name, '.b')
- assert dotfile.name == repo.homedir / name
-
-
-@pytest.mark.parametrize('name', ['.foo'])
-def test_short_name(repo, name):
- dotfile = _make_dotfile(repo, name)
- assert dotfile.name == repo.homedir / name
- assert dotfile.short_name(repo.homedir) == Path(name)
-
-
-def test_is_present(repo):
- dotfile = _make_dotfile(repo, '.foo')
- assert not dotfile.is_present()
- # TODO: more
-
-
-def test_state(repo):
- dotfile = _make_dotfile(repo, '.vimrc', 'vimrc')
- assert dotfile.state == 'error'
-
- dotfile.target.touch()
- dotfile.name.symlink_to(dotfile.target)
- assert dotfile.state == 'ok'
-
- dotfile.name.unlink()
- assert dotfile.state == 'missing'
-
- dotfile.name.touch()
- assert dotfile.state == 'ok'
-
- dotfile.name.write_text('test content')
- assert dotfile.state == 'conflict'
-
- dotfile.target.write_text('test content')
- assert dotfile.state == 'ok'
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_add(repo, path):
- dotfile = _make_dotfile(repo, path)
-
- touch(dotfile.name)
- touch(dotfile.target)
-
- with pytest.raises(TargetExists):
- dotfile.add()
- dotfile.target.unlink()
-
- dotfile.add()
- assert is_link(dotfile.name)
- assert is_file(dotfile.target)
- assert dotfile.name.samefile(dotfile.target)
-
- with pytest.raises(IsSymlink):
- dotfile.add()
- assert is_file(dotfile.target)
- assert dotfile.name.samefile(dotfile.target)
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_remove(repo, path):
- dotfile = _make_dotfile(repo, path)
-
- # py.path.local(dotfile.name.dirname).ensure_dir()
- # dotfile.name.mksymlinkto(dotfile.target)
- # dotfile.name.parent.mkdir(parents=True)
- mkdir(dotfile.name.parent)
- dotfile.name.symlink_to(dotfile.target)
-
- with pytest.raises(TargetMissing):
- dotfile.remove()
-
- # dotfile.target.ensure()
- # dotfile.target.touch()
- touch(dotfile.target)
- dotfile.remove()
-
- # assert dotfile.target.check(exists=0)
- # assert dotfile.name.check(file=1, link=0)
- assert not dotfile.target.exists()
- assert is_file(dotfile.name)
-
- with pytest.raises(NotASymlink):
- dotfile.remove()
-
- # assert dotfile.target.check(exists=0)
- # assert dotfile.name.check(file=1, link=0)
- assert not dotfile.target.exists()
- assert is_file(dotfile.name)
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_link(repo, path):
- dotfile = _make_dotfile(repo, path)
-
- with pytest.raises(TargetMissing):
- dotfile.link()
-
- touch(dotfile.target)
- dotfile.link()
-
- assert is_file(dotfile.target)
- assert is_link(dotfile.name)
- assert dotfile.name.samefile(dotfile.target)
-
- with pytest.raises(Exists):
- dotfile.link()
-
- assert is_file(dotfile.target)
- assert is_link(dotfile.name)
- assert dotfile.name.samefile(dotfile.target)
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_unlink(repo, path):
- dotfile = _make_dotfile(repo, path)
-
- with pytest.raises(NotASymlink):
- dotfile.unlink()
-
- # py.path.local(dotfile.name.dirname).ensure_dir()
- # dotfile.name.mksymlinkto(dotfile.target)
- mkdir(dotfile.name.parent)
- dotfile.name.symlink_to(dotfile.target)
-
- with pytest.raises(TargetMissing):
- dotfile.unlink()
-
- # dotfile.target.ensure()
- touch(dotfile.target)
- dotfile.unlink()
-
- assert is_file(dotfile.target)
- assert not dotfile.name.exists()
-
- with pytest.raises(NotASymlink):
- dotfile.unlink()
-
- assert is_file(dotfile.target)
- assert not dotfile.name.exists()
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_copy(repo, path):
- pass
- # dotfile = _make_dotfile(repo, path)
- # TODO
diff --git a/tests/test_repository.py b/tests/test_repository.py
deleted file mode 100644
index cdf3c72..0000000
--- a/tests/test_repository.py
+++ /dev/null
@@ -1,161 +0,0 @@
-import pytest
-
-from pathlib import Path
-from dotfiles.exceptions import NotRootedInHome, TargetIgnored, \
- IsDirectory, InRepository
-from dotfiles.repository import Repository, \
- REMOVE_LEADING_DOT, IGNORE_PATTERNS
-
-
-def test_repo_create(repo):
- repo.path.rmdir()
- assert not repo.path.exists()
-
- Repository(repo.path, repo.homedir)
- assert repo.path.exists()
- assert repo.path.is_dir()
-
-
-@pytest.mark.parametrize('dot', [REMOVE_LEADING_DOT, not REMOVE_LEADING_DOT])
-@pytest.mark.parametrize('ignore', [IGNORE_PATTERNS, ['foo', 'bar', 'baz']])
-def test_params(repo, dot, ignore):
-
- _repo = Repository(repo.path,
- homedir=repo.homedir,
- remove_leading_dot=dot,
- ignore_patterns=ignore)
-
- assert _repo.path == repo.path
- assert _repo.homedir == repo.homedir
- assert _repo.remove_leading_dot == dot
- assert _repo.ignore_patterns == ignore
-
-
-def test_contents(repo):
- assert repo.contents() == []
-
- target_a = repo.path / 'a'
- target_b = repo.path / 'b/b'
- target_c = repo.path / 'c/c/c'
-
- target_b.parent.mkdir()
- target_c.parent.mkdir(parents=True)
-
- target_a.touch()
- target_b.touch()
- target_c.touch()
-
- contents = repo.contents()
-
- assert contents[0].target == target_a
- assert contents[1].target == target_b
- assert contents[2].target == target_c
-
-
-def test_str(repo):
-
- Path(repo.path / 'a').touch()
- Path(repo.path / 'b').touch()
- Path(repo.path / 'c').touch()
-
- assert str(repo) == (
- '%s\n%s\n%s' % (repo.homedir / '.a',
- repo.homedir / '.b',
- repo.homedir / '.c'))
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_dotfile_path(repo, path):
-
- repo.remove_leading_dot = False
- assert (repo._dotfile_path(repo.path / path) ==
- repo.homedir / path)
-
- repo.remove_leading_dot = True
- assert (repo._dotfile_path(repo.path / path) ==
- repo.homedir / ('.%s' % path))
-
-
-@pytest.mark.parametrize('path', ['.foo', '.foo/bar/baz'])
-def test_dotfile_target(repo, path):
-
- repo.remove_leading_dot = False
- assert (repo._dotfile_target(repo.homedir / path) ==
- repo.path / path)
-
- repo.remove_leading_dot = True
- assert (repo._dotfile_target(repo.homedir / path) ==
- repo.path / path[1:])
-
-
-def test_dotfile(repo):
-
- with pytest.raises(NotRootedInHome):
- repo._dotfile(Path('/tmp/foo'))
-
- with pytest.raises(TargetIgnored):
- repo.ignore_patterns = ['.foo']
- repo.remove_leading_dot = False
- repo._dotfile(repo.homedir / '.foo')
-
- with pytest.raises(TargetIgnored):
- repo.ignore_patterns = ['foo']
- repo._dotfile(repo.homedir / '.bar/foo')
-
- with pytest.raises(IsDirectory):
- dir = repo.homedir / '.config'
- dir.mkdir()
- repo._dotfile(dir)
-
- # The repo fixture is parametrized, we can only expect InRepository
- # exception when the repository is contained in the home directory.
- if repo.path.parent == repo.homedir.name:
- with pytest.raises(InRepository):
- repo._dotfile(repo.path / '.foo/bar')
-
-
-def test_dotfiles(repo):
-
- subdir_a = repo.homedir / '.dir'
- subdir_b = repo.homedir / '.dir/foo'
-
- for subdir in [subdir_a, subdir_b]:
- subdir.mkdir()
-
- file_a = repo.homedir / '.baz'
- file_b = subdir_a / 'bar'
- file_c = subdir_a / 'boo'
- file_d = subdir_b / 'bat'
- file_e = subdir_b / 'buz'
-
- for file in [file_a, file_b, file_c, file_d, file_e]:
- file.touch()
-
- dotfiles = repo.dotfiles([str(file_a), str(subdir_a)])
-
- assert len(dotfiles) == 5
-
- for file in [file_a, file_b, file_c, file_d, file_e]:
- assert str(file) in map(str, dotfiles)
-
-
-def test_prune(repo):
- dir_a = repo.path / '.a/a'
- dir_b = repo.path / '.b/b/b/b'
- dir_c = repo.path / '.c/c/c/c/c/c/c/c'
-
- for dir in [dir_a, dir_b, dir_c]:
- dir.mkdir(parents=True)
-
- repo.prune()
- contents = [x for x in repo.path.rglob('*')]
- assert len(contents) == 0
-
- # verify ignored directories are excluded from pruning
- dir_d = repo.path / '.git'
- dir_d.mkdir()
-
- repo.prune()
- contents = [x for x in repo.path.rglob('*')]
- assert str(dir_d) in map(str, contents)
- assert len(contents) == 1