diff --git a/.gitignore b/.gitignore index 90a2baa..e398e3f 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,5 @@ build/ *.egg-info/ tags env +htmlcov diff --git a/dotdrop/installer.py b/dotdrop/installer.py index 7e9ebad..1b41ee4 100644 --- a/dotdrop/installer.py +++ b/dotdrop/installer.py @@ -103,7 +103,7 @@ class Installer: if os.path.isfile(dst): msg = ''.join([ - 'Remove regular file "{}" and ', + 'Remove regular file {} and ', 'replace with empty directory?', ]).format(dst) diff --git a/tests/test_install.py b/tests/test_install.py index 51e0368..956cc41 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -6,6 +6,7 @@ basic unittest for the install function import os import unittest +from unittest.mock import MagicMock, patch import filecmp from dotdrop.config import Cfg @@ -227,6 +228,160 @@ exec bspwm tempcontent = open(dst10, 'r').read().rstrip() self.assertTrue(tempcontent == profile) + def test_link_children(self): + + # create source dir + src_dir = get_tempdir() + self.assertTrue(os.path.exists(src_dir)) + self.addCleanup(clean, src_dir) + + # where dotfiles will be installed + dst_dir = get_tempdir() + self.assertTrue(os.path.exists(dst_dir)) + self.addCleanup(clean, dst_dir) + + # create 3 random files in source + srcs = [create_random_file(src_dir)[0] for _ in range(3)] + + installer = Installer() + installer.linkall(templater=MagicMock(), src=src_dir, dst=dst_dir, + actions=[]) + + # Ensure all destination files point to source + for src in srcs: + dst = os.path.join(dst_dir, src) + self.assertEqual(os.path.realpath(dst), src) + + def test_fails_without_src(self): + src = '/some/non/existant/file' + + installer = Installer() + logger = MagicMock() + installer.log.err = logger + + res = installer.linkall(templater=MagicMock(), + src=src, + dst='/dev/null', actions=[]) + + self.assertEqual(res, []) + logger.assert_called_with('source dotfile does not exist: {}' + .format(src)) + + def test_fails_when_src_file(self): + + # create source dir + src_dir = get_tempdir() + self.assertTrue(os.path.exists(src_dir)) + self.addCleanup(clean, src_dir) + + src = create_random_file(src_dir)[0] + + logger = MagicMock() + installer = Installer() + installer.log.err = logger + + # pass src file not src dir + res = installer.linkall(templater=MagicMock(), src=src, dst='/dev/null', + actions=[]) + + # ensure nothing performed + self.assertEqual(res, []) + # ensure logger logged error + logger.assert_called_with('source dotfile is not a directory: {}' + .format(src)) + + def test_creates_dst(self): + src_dir = get_tempdir() + self.assertTrue(os.path.exists(src_dir)) + self.addCleanup(clean, src_dir) + + # where dotfiles will be installed + dst_dir = get_tempdir() + self.addCleanup(clean, dst_dir) + + # move dst dir to new (uncreated) dir in dst + dst_dir = os.path.join(dst_dir, get_string(6)) + self.assertFalse(os.path.exists(dst_dir)) + + installer = Installer() + installer.linkall(templater=MagicMock(), src=src_dir, dst=dst_dir, + actions=[]) + + # ensure dst dir created + self.assertTrue(os.path.exists(dst_dir)) + + def test_prompts_to_replace_dst(self): + + # create source dir + src_dir = get_tempdir() + self.assertTrue(os.path.exists(src_dir)) + self.addCleanup(clean, src_dir) + + # where dotfiles will be installed + dst_dir = get_tempdir() + self.addCleanup(clean, dst_dir) + + # Create destination file to be replaced + dst = os.path.join(dst_dir, get_string(6)) + with open(dst, 'w'): + pass + self.assertTrue(os.path.isfile(dst)) + + # setup mocks + ask = MagicMock() + ask.return_value = True + + # setup installer + installer = Installer() + installer.safe = True + installer.log.ask = ask + + installer.linkall(templater=MagicMock(), src=src_dir, dst=dst, + actions=[]) + + # ensure destination now a directory + self.assertTrue(os.path.isdir(dst)) + + # ensure prompted + ask.assert_called_with( + 'Remove regular file {} and replace with empty directory?' + .format(dst)) + + @patch('dotdrop.installer.Templategen') + def test_runs_templater(self, mocked_templategen): + + # create source dir + src_dir = get_tempdir() + self.assertTrue(os.path.exists(src_dir)) + self.addCleanup(clean, src_dir) + + # where dotfiles will be installed + dst_dir = get_tempdir() + self.assertTrue(os.path.exists(dst_dir)) + self.addCleanup(clean, dst_dir) + + # create 3 random files in source + srcs = [create_random_file(src_dir)[0] for _ in range(3)] + + # setup installer and mocks + installer = Installer() + templater = MagicMock() + templater.generate.return_value = b'content' + # make templategen treat everything as a template + mocked_templategen.is_template.return_value = True + + installer.linkall(templater=templater, src=src_dir, dst=dst_dir, + actions=[]) + + for src in srcs: + dst = os.path.join(dst_dir, os.path.basename(src)) + + # ensure dst is link + self.assertTrue(os.path.islink(dst)) + # ensure dst not directly linked to src + # TODO: maybe check that its actually linked to template folder + self.assertNotEqual(os.path.realpath(dst), src) + def main(): unittest.main()