diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-07-17 07:26:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2021-07-17 07:26:43 +0000 |
commit | 8fd7f9bfed753dbaa5543747569b4c2543aff03d (patch) | |
tree | 1b8854ec7e68bb7daf7e8b7db657669d930a99be /tests/test_main.py | |
parent | Releasing debian version 0.12.9-1. (diff) | |
download | gita-8fd7f9bfed753dbaa5543747569b4c2543aff03d.tar.xz gita-8fd7f9bfed753dbaa5543747569b4c2543aff03d.zip |
Merging upstream version 0.15.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/test_main.py')
-rw-r--r-- | tests/test_main.py | 271 |
1 files changed, 210 insertions, 61 deletions
diff --git a/tests/test_main.py b/tests/test_main.py index ad501f7..490f5d2 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,28 +1,102 @@ +import os import pytest -from unittest.mock import patch, mock_open +from unittest.mock import patch from pathlib import Path import argparse +import asyncio import shlex from gita import __main__ -from gita import utils, info +from gita import utils, info, common from conftest import ( - PATH_FNAME, PATH_FNAME_EMPTY, PATH_FNAME_CLASH, GROUP_FNAME, + PATH_FNAME, PATH_FNAME_EMPTY, PATH_FNAME_CLASH, GROUP_FNAME, PATH_FNAME_MAIN, async_mock, TEST_DIR, ) +@patch('gita.utils.get_repos', return_value={'aa'}) +def test_group_name(_): + got = __main__._group_name('xx') + assert got == 'xx' + with pytest.raises(SystemExit): + __main__._group_name('aa') + + +class TestAdd: + + @pytest.mark.parametrize('input, expected', [ + (['add', '.'], ''), + (['add', '-m', '.'], 'm'), + ]) + @patch('gita.common.get_config_fname') + def test_add(self, mock_path_fname, tmp_path, input, expected): + def side_effect(input, _=None): + return tmp_path / f'{input}.txt' + mock_path_fname.side_effect = side_effect + utils.get_repos.cache_clear() + __main__.main(input) + utils.get_repos.cache_clear() + got = utils.get_repos() + assert len(got) == 1 + assert got['gita']['type'] == expected + + @patch('gita.utils.is_git', return_value=True) + def test_add_main(self, _, tmp_path, monkeypatch, tmpdir): + def side_effect(root=None): + if root is None: + return os.path.join(tmp_path, "gita") + else: + return os.path.join(root, ".gita") + + def desc(repos, **_): + print(len(repos), repos.keys()) + assert len(repos) > 0 + for r, prop in repos.items(): + if prop['type'] == 'm': + assert 'test_add_main' in r + break + else: + assert 0, 'no main repo found' + return '' + + monkeypatch.setattr(common, 'get_config_dir', side_effect) + monkeypatch.setattr(utils, 'describe', desc) + + utils.get_repos.cache_clear() + + with tmpdir.as_cwd(): + __main__.main(['add', '-m', '.']) + utils.get_repos.cache_clear() + __main__.main(['ll']) + + +@pytest.mark.parametrize('path_fname, expected', [ + (PATH_FNAME, ''), + (PATH_FNAME_CLASH, "repo2: ['--haha', '--pp']\n"), + ]) +@patch('gita.utils.is_git', return_value=True) +@patch('gita.utils.get_groups', return_value={}) +@patch('gita.common.get_config_fname') +def test_flags(mock_path_fname, _, __, path_fname, expected, capfd): + mock_path_fname.return_value = path_fname + utils.get_repos.cache_clear() + __main__.main(['flags']) + out, err = capfd.readouterr() + assert err == '' + assert out == expected + + class TestLsLl: @patch('gita.common.get_config_fname') - def testLl(self, mock_path_fname, capfd, tmp_path): + def test_ll(self, mock_path_fname, capfd, tmp_path): """ functional test """ # avoid modifying the local configuration - def side_effect(input): + def side_effect(input, _=None): return tmp_path / f'{input}.txt' - #mock_path_fname.return_value = tmp_path / 'path_config.txt' mock_path_fname.side_effect = side_effect + utils.get_repos.cache_clear() __main__.main(['add', '.']) out, err = capfd.readouterr() assert err == '' @@ -52,11 +126,11 @@ class TestLsLl: __main__.main(['ls', 'gita']) out, err = capfd.readouterr() assert err == '' - assert out.strip() == utils.get_repos()['gita'] + assert out.strip() == utils.get_repos()['gita']['path'] - def testLs(self, monkeypatch, capfd): + def test_ls(self, monkeypatch, capfd): monkeypatch.setattr(utils, 'get_repos', - lambda: {'repo1': '/a/', 'repo2': '/b/'}) + lambda: {'repo1': {'path': '/a/'}, 'repo2': {'path': '/b/'}}) monkeypatch.setattr(utils, 'describe', lambda x: x) __main__.main(['ls']) out, err = capfd.readouterr() @@ -69,21 +143,24 @@ class TestLsLl: @pytest.mark.parametrize('path_fname, expected', [ (PATH_FNAME, - "repo1 cmaster dsu\x1b[0m msg\nrepo2 cmaster dsu\x1b[0m msg\nxxx cmaster dsu\x1b[0m msg\n"), + "repo1 cmaster dsu\x1b[0m msg \nrepo2 cmaster dsu\x1b[0m msg \nxxx cmaster dsu\x1b[0m msg \n"), (PATH_FNAME_EMPTY, ""), + (PATH_FNAME_MAIN, + '\x1b[4mmain1\x1b[0m cmaster dsu\x1b[0m msg \nxx cmaster dsu\x1b[0m msg \n'), (PATH_FNAME_CLASH, - "repo1 cmaster dsu\x1b[0m msg\nrepo2 cmaster dsu\x1b[0m msg\nx/repo1 cmaster dsu\x1b[0m msg\n" + "repo1 cmaster dsu\x1b[0m msg \nrepo2 cmaster dsu\x1b[0m msg \n" ), ]) @patch('gita.utils.is_git', return_value=True) @patch('gita.info.get_head', return_value="master") @patch('gita.info._get_repo_status', return_value=("d", "s", "u", "c")) @patch('gita.info.get_commit_msg', return_value="msg") + @patch('gita.info.get_commit_time', return_value="") @patch('gita.common.get_config_fname') - def testWithPathFiles(self, mock_path_fname, _0, _1, _2, _3, path_fname, + def test_with_path_files(self, mock_path_fname, _0, _1, _2, _3, _4, path_fname, expected, capfd): - def side_effect(input): - if input == 'repo_path': + def side_effect(input, _=None): + if input == 'repos.csv': return path_fname return f'/{input}' mock_path_fname.side_effect = side_effect @@ -95,25 +172,63 @@ class TestLsLl: assert out == expected +@pytest.mark.parametrize('input, expected', [ + ({'repo1': {'path': '/a/'}, 'repo2': {'path': '/b/'}}, ''), + ]) @patch('subprocess.run') -@patch('gita.utils.get_repos', return_value={'repo1': '/a/', 'repo2': '/b/'}) -def test_freeze(_, mock_run, capfd): +@patch('gita.utils.get_repos') +def test_freeze(mock_repos, mock_run, input, expected, capfd): + mock_repos.return_value = input __main__.main(['freeze']) assert mock_run.call_count == 2 out, err = capfd.readouterr() assert err == '' - assert out == ',repo1,/a/\n,repo2,/b/\n' + assert out == expected + + +@patch('gita.utils.parse_clone_config', return_value=[ + ['git@github.com:user/repo.git', 'repo', '/a/repo']]) +@patch('gita.utils.run_async', new=async_mock()) +@patch('subprocess.run') +def test_clone(*_): + asyncio.set_event_loop(asyncio.new_event_loop()) + args = argparse.Namespace() + args.fname = ['freeze_filename'] + args.preserve_path = None + __main__.f_clone(args) + mock_run = utils.run_async.mock + assert mock_run.call_count == 1 + cmds = ['git', 'clone', 'git@github.com:user/repo.git'] + mock_run.assert_called_once_with('repo', Path.cwd(), cmds) + + +@patch('gita.utils.parse_clone_config', return_value=[ + ['git@github.com:user/repo.git', 'repo', '/a/repo']]) +@patch('gita.utils.run_async', new=async_mock()) +@patch('subprocess.run') +def test_clone_with_preserve_path(*_): + asyncio.set_event_loop(asyncio.new_event_loop()) + args = argparse.Namespace() + args.fname = ['freeze_filename'] + args.preserve_path = True + __main__.f_clone(args) + mock_run = utils.run_async.mock + assert mock_run.call_count == 1 + cmds = ['git', 'clone', 'git@github.com:user/repo.git', '/a/repo'] + mock_run.assert_called_once_with('repo', Path.cwd(), cmds) @patch('os.path.isfile', return_value=True) @patch('gita.common.get_config_fname', return_value='some path') -@patch('gita.utils.get_repos', return_value={'repo1': '/a/', 'repo2': '/b/'}) +@patch('gita.utils.get_repos', return_value={'repo1': {'path': '/a/', 'type': ''}, + 'repo2': {'path': '/b/', 'type': ''}}) @patch('gita.utils.write_to_repo_file') def test_rm(mock_write, *_): args = argparse.Namespace() args.repo = ['repo1'] __main__.f_rm(args) - mock_write.assert_called_once_with({'repo2': '/b/'}, 'w') + mock_write.assert_called_once_with( + {'repo2': {'path': '/b/', 'type': ''}}, 'w') def test_not_add(): @@ -121,17 +236,19 @@ def test_not_add(): __main__.main(['add', '/home/some/repo/']) -@patch('gita.utils.get_repos', return_value={'repo2': '/d/efg'}) +@patch('gita.utils.get_repos', return_value={'repo2': {'path': '/d/efg', + 'flags': []}}) @patch('subprocess.run') def test_fetch(mock_run, *_): + asyncio.set_event_loop(asyncio.new_event_loop()) __main__.main(['fetch']) - mock_run.assert_called_once_with(['git', 'fetch'], cwd='/d/efg') + mock_run.assert_called_once_with(['git', 'fetch'], cwd='/d/efg', shell=False) @patch( 'gita.utils.get_repos', return_value={ - 'repo1': '/a/bc', - 'repo2': '/d/efg' + 'repo1': {'path': '/a/bc', 'flags': []}, + 'repo2': {'path': '/d/efg', 'flags': []} }) @patch('gita.utils.run_async', new=async_mock()) @patch('subprocess.run') @@ -149,28 +266,28 @@ def test_async_fetch(*_): 'diff --name-only --staged', "commit -am 'lala kaka'", ]) -@patch('gita.utils.get_repos', return_value={'repo7': 'path7'}) +@patch('gita.utils.get_repos', return_value={'repo7': {'path': 'path7', 'flags': []}}) @patch('subprocess.run') def test_superman(mock_run, _, input): mock_run.reset_mock() args = ['super', 'repo7'] + shlex.split(input) __main__.main(args) expected_cmds = ['git'] + shlex.split(input) - mock_run.assert_called_once_with(expected_cmds, cwd='path7') + mock_run.assert_called_once_with(expected_cmds, cwd='path7', shell=False) @pytest.mark.parametrize('input', [ 'diff --name-only --staged', "commit -am 'lala kaka'", ]) -@patch('gita.utils.get_repos', return_value={'repo7': 'path7'}) +@patch('gita.utils.get_repos', return_value={'repo7': {'path': 'path7', 'flags': []}}) @patch('subprocess.run') def test_shell(mock_run, _, input): mock_run.reset_mock() - args = ['shell', 'repo7'] + shlex.split(input) + args = ['shell', 'repo7', input] __main__.main(args) - expected_cmds = shlex.split(input) - mock_run.assert_called_once_with(expected_cmds, cwd='path7', check=True, stderr=-2, stdout=-1) + expected_cmds = input + mock_run.assert_called_once_with(expected_cmds, cwd='path7', check=True, shell=True, stderr=-2, stdout=-1) class TestContext: @@ -184,21 +301,21 @@ class TestContext: @patch('gita.utils.get_context', return_value=Path('gname.context')) @patch('gita.utils.get_groups', return_value={'gname': ['a', 'b']}) - def testDisplayContext(self, _, __, capfd): + def test_display_context(self, _, __, capfd): __main__.main(['context']) out, err = capfd.readouterr() assert err == '' assert 'gname: a b\n' == out @patch('gita.utils.get_context') - def testReset(self, mock_ctx): + def test_reset(self, mock_ctx): __main__.main(['context', 'none']) mock_ctx.return_value.unlink.assert_called() @patch('gita.utils.get_context', return_value=None) @patch('gita.common.get_config_dir', return_value=TEST_DIR) @patch('gita.utils.get_groups', return_value={'lala': ['b'], 'kaka': []}) - def testSetFirstTime(self, *_): + def test_set_first_time(self, *_): ctx = TEST_DIR / 'lala.context' assert not ctx.is_file() __main__.main(['context', 'lala']) @@ -208,7 +325,7 @@ class TestContext: @patch('gita.common.get_config_dir', return_value=TEST_DIR) @patch('gita.utils.get_groups', return_value={'lala': ['b'], 'kaka': []}) @patch('gita.utils.get_context') - def testSetSecondTime(self, mock_ctx, *_): + def test_set_second_time(self, mock_ctx, *_): __main__.main(['context', 'kaka']) mock_ctx.return_value.rename.assert_called() @@ -216,7 +333,7 @@ class TestContext: class TestGroupCmd: @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) - def testLs(self, _, capfd): + def test_ls(self, _, capfd): args = argparse.Namespace() args.to_group = None args.group_cmd = 'ls' @@ -227,7 +344,7 @@ class TestGroupCmd: assert 'xx yy\n' == out @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) - def testLl(self, _, capfd): + def test_ll(self, _, capfd): args = argparse.Namespace() args.to_group = None args.group_cmd = None @@ -239,7 +356,7 @@ class TestGroupCmd: @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) @patch('gita.utils.write_to_groups_file') - def testRename(self, mock_write, _): + def test_rename(self, mock_write, _): args = argparse.Namespace() args.gname = 'xx' args.new_name = 'zz' @@ -250,7 +367,7 @@ class TestGroupCmd: mock_write.assert_called_once_with(expected, 'w') @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) - def testRenameError(self, *_): + def test_rename_error(self, *_): args = argparse.Namespace() args.gname = 'xx' args.new_name = 'yy' @@ -266,7 +383,7 @@ class TestGroupCmd: @patch('gita.utils.get_repos', return_value={'a': '', 'b': '', 'c': '', 'd': ''}) @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) @patch('gita.utils.write_to_groups_file') - def testRm(self, mock_write, _, __, input, expected): + def test_rm(self, mock_write, _, __, input, expected): utils.get_groups.cache_clear() args = ['group', 'rm'] + shlex.split(input) __main__.main(args) @@ -275,7 +392,7 @@ class TestGroupCmd: @patch('gita.utils.get_repos', return_value={'a': '', 'b': '', 'c': '', 'd': ''}) @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) @patch('gita.utils.write_to_groups_file') - def testAdd(self, mock_write, *_): + def test_add(self, mock_write, *_): args = argparse.Namespace() args.to_group = ['a', 'c'] args.group_cmd = 'add' @@ -287,7 +404,7 @@ class TestGroupCmd: @patch('gita.utils.get_repos', return_value={'a': '', 'b': '', 'c': '', 'd': ''}) @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) @patch('gita.utils.write_to_groups_file') - def testAddToExisting(self, mock_write, *_): + def test_add_to_existing(self, mock_write, *_): args = argparse.Namespace() args.to_group = ['a', 'c'] args.group_cmd = 'add' @@ -300,7 +417,7 @@ class TestGroupCmd: @patch('gita.utils.get_repos', return_value={'a': '', 'b': '', 'c': '', 'd': ''}) @patch('gita.common.get_config_fname', return_value=GROUP_FNAME) @patch('gita.utils.write_to_groups_file') - def testRmRepo(self, mock_write, *_): + def test_rm_repo(self, mock_write, *_): args = argparse.Namespace() args.from_group = ['a', 'c'] args.group_cmd = 'rmrepo' @@ -310,6 +427,21 @@ class TestGroupCmd: mock_write.assert_called_once_with( {'xx': ['b'], 'yy': ['a', 'c', 'd']}, 'w') + @patch('gita.common.get_config_fname') + def test_integration(self, mock_path_fname, tmp_path, capfd): + def side_effect(input, _=None): + return tmp_path / f'{input}.csv' + mock_path_fname.side_effect = side_effect + + __main__.main('add .'.split()) + utils.get_repos.cache_clear() + __main__.main('group add gita -n test'.split()) + utils.get_groups.cache_clear() + __main__.main('ll test'.split()) + out, err = capfd.readouterr() + assert err == '' + assert 'gita' in out + @patch('gita.utils.is_git', return_value=True) @patch('gita.common.get_config_fname', return_value=PATH_FNAME) @@ -319,44 +451,61 @@ def test_rename(mock_rename, _, __): args = ['rename', 'repo1', 'abc'] __main__.main(args) mock_rename.assert_called_once_with( - {'repo1': '/a/bcd/repo1', 'repo2': '/e/fgh/repo2', - 'xxx': '/a/b/c/repo3'}, + {'repo1': {'path': '/a/bcd/repo1', 'type': '', 'flags': []}, + 'xxx': {'path': '/a/b/c/repo3', 'type': '', 'flags': []}, + 'repo2': {'path': '/e/fgh/repo2', 'type': '', 'flags': []}}, 'repo1', 'abc') class TestInfo: @patch('gita.common.get_config_fname', return_value='') - def testLl(self, _, capfd): + def test_ll(self, _, capfd): args = argparse.Namespace() args.info_cmd = None __main__.f_info(args) out, err = capfd.readouterr() - assert 'In use: branch,commit_msg\nUnused: path\n' == out + assert 'In use: branch,commit_msg,commit_time\nUnused: path\n' == out assert err == '' - @patch('gita.common.get_config_fname', return_value='') - @patch('yaml.dump') - def testAdd(self, mock_dump, _): + @patch('gita.common.get_config_fname') + def test_add(self, mock_get_fname, tmpdir): args = argparse.Namespace() args.info_cmd = 'add' args.info_item = 'path' - with patch('builtins.open', mock_open(), create=True): + with tmpdir.as_cwd(): + csv_config = Path.cwd() / 'info.csv' + mock_get_fname.return_value = csv_config __main__.f_info(args) - mock_dump.assert_called_once() - args, kwargs = mock_dump.call_args - assert args[0] == ['branch', 'commit_msg', 'path'] - assert kwargs == {'default_flow_style': None} + items = info.get_info_items() + assert items == ['branch', 'commit_msg', 'commit_time', 'path'] - @patch('gita.common.get_config_fname', return_value='') - @patch('yaml.dump') - def testRm(self, mock_dump, _): + @patch('gita.common.get_config_fname') + def test_rm(self, mock_get_fname, tmpdir): args = argparse.Namespace() args.info_cmd = 'rm' args.info_item = 'commit_msg' - with patch('builtins.open', mock_open(), create=True): + with tmpdir.as_cwd(): + csv_config = Path.cwd() / 'info.csv' + mock_get_fname.return_value = csv_config __main__.f_info(args) - mock_dump.assert_called_once() - args, kwargs = mock_dump.call_args - assert args[0] == ['branch'] - assert kwargs == {'default_flow_style': None} + items = info.get_info_items() + assert items == ['branch', 'commit_time'] + + +@patch('gita.common.get_config_fname') +def test_set_color(mock_get_fname, tmpdir): + args = argparse.Namespace() + args.color_cmd = 'set' + args.color = 'redrum' # this color doesn't exist + args.situation = 'in-sync' + with tmpdir.as_cwd(): + csv_config = Path.cwd() / 'colors.csv' + mock_get_fname.return_value = csv_config + __main__.f_color(args) + info.get_color_encoding.cache_clear() # avoid side effect + items = info.get_color_encoding() + info.get_color_encoding.cache_clear() # avoid side effect + assert items == {'no-remote': 'white', 'in-sync': 'redrum', + 'diverged': 'red', 'local-ahead': 'purple', + 'remote-ahead': 'yellow'} |