From ba4a3fae9346d528f85887c9badc5a54d973f33b Mon Sep 17 00:00:00 2001 From: Lubomír Sedlář Date: Apr 28 2018 07:53:50 +0000 Subject: Rename test directory This way it will be automatically included in the source tarball. Fixes: https://pagure.io/pag/issue/25 --- diff --git a/test/test_clone.py b/test/test_clone.py new file mode 100644 index 0000000..6281b5b --- /dev/null +++ b/test/test_clone.py @@ -0,0 +1,102 @@ +import unittest +import mock + +from click.testing import CliRunner + +from pag.commands.clone import clone + +EMPTY_RESPONSE = mock.Mock(json=lambda : { + 'total_projects': 0, + 'projects': [], +}) + +RESPONSE_WITH_REPO = mock.Mock(json=lambda: { + 'total_projects': 0, + 'projects': [{'name': 'fedmod', 'namespace': 'modularity'}], +}) + + +class CloneTest(unittest.TestCase): + def setUp(self): + self.runner = CliRunner() + self.maxDiff = None + self.patcher = mock.patch('requests.get') + self.mock_get = self.patcher.start() + self.mock_get.return_value = EMPTY_RESPONSE + + def tearDown(self): + self.patcher.stop() + + @mock.patch('pag.commands.clone.run') + def test_clone(self, run): + result = self.runner.invoke(clone, ['pag']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'clone', 'ssh://git@pagure.io/pag.git', 'pag'])] + ) + self.assertEqual(self.mock_get.call_args_list, []) + + @mock.patch('pag.commands.clone.run') + def test_clone_anonymous(self, run): + result = self.runner.invoke(clone, ['-a', 'pag']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'clone', 'https://pagure.io/pag.git', 'pag'])] + ) + self.assertEqual(self.mock_get.call_args_list, []) + + @mock.patch('pag.commands.clone.run') + def test_clone_fork(self, run): + result = self.runner.invoke(clone, ['ralph/pag']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'clone', 'ssh://git@pagure.io/forks/ralph/pag.git', 'pag'])] + ) + self.assertEqual(self.mock_get.call_args_list, + [mock.call(mock.ANY, {'namespace': 'ralph', 'name': 'pag'})]) + + @mock.patch('pag.commands.clone.run') + def test_clone_fork_anonymous(self, run): + result = self.runner.invoke(clone, ['-a', 'ralph/pag']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'clone', 'https://pagure.io/forks/ralph/pag.git', 'pag'])] + ) + self.assertEqual(self.mock_get.call_args_list, + [mock.call(mock.ANY, {'namespace': 'ralph', 'name': 'pag'})]) + + @mock.patch('pag.commands.clone.run') + def test_clone_namespace(self, run): + self.mock_get.return_value = RESPONSE_WITH_REPO + + result = self.runner.invoke(clone, ['modularity/fedmod']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'clone', 'ssh://git@pagure.io/modularity/fedmod.git', 'fedmod'])] + ) + self.assertEqual(self.mock_get.call_args_list, + [mock.call(mock.ANY, {'namespace': 'modularity', 'name': 'fedmod'})]) + + @mock.patch('pag.commands.clone.run') + def test_clone_namespace_anonymous(self, run): + self.mock_get.return_value = RESPONSE_WITH_REPO + + result = self.runner.invoke(clone, ['-a', 'modularity/fedmod']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'clone', 'https://pagure.io/modularity/fedmod.git', 'fedmod'])] + ) + self.assertEqual(self.mock_get.call_args_list, + [mock.call(mock.ANY, {'namespace': 'modularity', 'name': 'fedmod'})]) diff --git a/test/test_review.py b/test/test_review.py new file mode 100644 index 0000000..0985f9d --- /dev/null +++ b/test/test_review.py @@ -0,0 +1,187 @@ +import unittest +import mock + +from click.testing import CliRunner + +from pag.commands.review import review + + +# This is an abbreviated response from list pull request API that contains +# minimal amount of data needed. +LIST_RESPONSE = { + "requests": [ + { + "id": 2344, + "title": "Fix the API docs", + "user": {"name": "mprahl"} + }, + { + "id": 2343, + "title": ("Add ways to customize the gitolite configuration file " + "with snippets, and some extra details"), + "user": {"name": "pingou"} + } + ], + "total_requests": 2 +} + +# This is expected output when listing pull requests returns the data above. +LIST_OUTPUT = """ + 2344 mprahl Fix the API docs + 2343 pingou Add ways to customize the gitolite configuration file with + snippets, and some extra details +""".lstrip('\n') + +# Abbreviated response for listing details about a pull request. +GET_RESPONSE = { + "branch_from": "fix-api-docs", + "commit_stop": "a08f507b99afeda8b9d1f5cf2024eb723726924b", + "id": 2344, + "remote_git": None, + "repo_from": { + "fullname": "forks/mprahl/pagure", + }, +} + + +class ReviewTest(unittest.TestCase): + def setUp(self): + self.runner = CliRunner() + self.maxDiff = None + + @mock.patch('pag.commands.review.run') + @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'my-project') + def test_open_web(self, run): + run.side_effect = [ + (0, 'review/12/3\n'), + (0, ''), + ] + + with self.runner.isolated_filesystem(): + result = self.runner.invoke(review, ['--open']) + + self.assertEqual(result.exit_code, 0) + self.assertEqual( + run.call_args_list, + [mock.call( + ['git', 'rev-parse', '--abbrev-ref', 'HEAD'], echo=False), + mock.call( + ['xdg-open', 'https://pagure.io/my-project/pull-request/12'])] + ) + + @mock.patch('pag.commands.review.run') + def test_open_web_on_bad_branch(self, run): + run.return_value = (0, 'master\n') + + with self.runner.isolated_filesystem(): + result = self.runner.invoke(review, ['--open']) + + self.assertEqual(result.exit_code, 1) + self.assertIn('Not on a review branch', result.output) + + @mock.patch('pag.commands.review.list_pull_requests') + @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') + def test_list(self, list_pull_requests): + list_pull_requests.return_value = LIST_RESPONSE['requests'] + + result = self.runner.invoke(review, ['--list']) + + self.assertEqual( + list_pull_requests.call_args_list, + [mock.call('pagure')]) + self.assertEqual(result.exit_code, 0) + self.assertEqual(result.output, LIST_OUTPUT) + + @mock.patch('requests.get') + @mock.patch('pag.commands.review.run') + @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') + def test_checkout_new(self, run, get): + get.return_value = mock.Mock( + json=mock.Mock(return_value=GET_RESPONSE) + ) + run.side_effect = [ + (1, ''), + (0, ''), + (0, 'review/2344/1\n'), + (0, ''), + ] + + result = self.runner.invoke(review, ['2344']) + + self.assertEqual( + get.call_args_list, + [mock.call('https://pagure.io/api/0/pagure/pull-request/2344')]) + self.assertEqual( + run.call_args_list, + [mock.call(['git', 'branch', '--contains', + 'a08f507b99afeda8b9d1f5cf2024eb723726924b', + 'review/2344/*'], echo=False), + mock.call( + ['git', 'fetch', 'https://pagure.io/forks/mprahl/pagure.git', + 'fix-api-docs'], graceful=False), + mock.call(['git', 'branch', '--list', 'review/2344/*'], + echo=False, graceful=False), + mock.call(['git', 'checkout', '-b', 'review/2344/2', + 'FETCH_HEAD'], graceful=False), + ]) + self.assertEqual(result.exit_code, 0) + + @mock.patch('requests.get') + @mock.patch('pag.commands.review.run') + @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') + def test_checkout_existing(self, run, get): + get.return_value = mock.Mock( + json=mock.Mock(return_value=GET_RESPONSE) + ) + run.side_effect = [ + (0, 'review/2344/1\n'), + (0, ''), + ] + + result = self.runner.invoke(review, ['2344']) + + self.assertEqual( + get.call_args_list, + [mock.call('https://pagure.io/api/0/pagure/pull-request/2344')]) + self.assertEqual( + run.call_args_list, + [ + mock.call(['git', 'branch', '--contains', + 'a08f507b99afeda8b9d1f5cf2024eb723726924b', + 'review/2344/*'], echo=False), + mock.call(['git', 'checkout', 'review/2344/1'], graceful=False), + ]) + self.assertEqual(result.exit_code, 0) + + @mock.patch('pag.commands.review.run') + @mock.patch('pag.commands.review.list_pull_requests', new=lambda _: LIST_RESPONSE['requests']) + @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') + def test_cleanup_merged_branches(self, run): + run.return_value = (0, 'review/1/1\nreview/1/2\n') + + result = self.runner.invoke(review, ['--cleanup']) + + self.assertEqual(result.exit_code, 0) + + self.assertEqual( + run.call_args_list, + [ + mock.call(['git', 'branch', '--list', 'review/*'], echo=False), + mock.call(['git', 'branch', '-D', 'review/1/1', 'review/1/2']), + ]) + + @mock.patch('pag.commands.review.run') + @mock.patch('pag.commands.review.list_pull_requests', new=lambda _: LIST_RESPONSE['requests']) + @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') + def test_keep_branch_for_opened_pr(self, run): + run.return_value = (0, 'review/2344/1\nreview/2344/2\n') + + result = self.runner.invoke(review, ['--cleanup']) + + self.assertEqual(result.exit_code, 0) + + self.assertEqual( + run.call_args_list, + [ + mock.call(['git', 'branch', '--list', 'review/*'], echo=False), + ]) diff --git a/test/test_utils.py b/test/test_utils.py new file mode 100644 index 0000000..2f4a445 --- /dev/null +++ b/test/test_utils.py @@ -0,0 +1,113 @@ +import os +import shlex +import shutil +import subprocess +import tempfile +import unittest + +from pag import utils + + +class GitTestCase(unittest.TestCase): + """ + A base class for tests that need a git repo. It creates a temporary repo + with a single commit for each test and changes to that directory. + """ + + def cmd(self, cmd, cwd=None, *args, **kwargs): + print('$ %s' % ' '.join(shlex.quote(x) for x in cmd)) + cp = subprocess.run(cmd, *args, + cwd=cwd or self.repo, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True, + **kwargs) + print(cp.stdout) + + def setUp(self): + self.orig_path = os.getcwd() + # Create git repository with some basic content + self.repo = tempfile.mkdtemp(prefix='test_current_branch_') + self.cmd(['git', 'init']) + with open(os.path.join(self.repo, 'file'), 'w') as f: + f.write('') + self.cmd(['git', 'add', '.']) + self.cmd(['git', 'commit', '-m', 'Initial commit']) + # and chdir into it. + os.chdir(self.repo) + + def tearDown(self): + shutil.rmtree(self.repo) + # Change back to original working directory + os.chdir(self.orig_path) + + +class TestGetDefaultBranch(GitTestCase): + """ + This test treats the inherited repo as upstream and clones it into a + separate directory, in which it runs the actual function. It can check out + a different branch in the "upstream" repo and thus effectively change the + default branch. + """ + + def setUp(self): + super().setUp() + self.clone = tempfile.mkdtemp(prefix='cloned_repo_') + + def tearDown(self): + super().tearDown() + shutil.rmtree(self.clone) + + def _clone_to(self, remote, branch): + if branch != 'master': + self.cmd(['git', 'checkout', '-b', branch]) + self.cmd(['git', 'clone', self.repo, self.clone, '-o', remote]) + os.chdir(self.clone) + + def test_origin_master(self): + self._clone_to('origin', 'master') + + self.assertEqual(utils.get_default_upstream_branch(), 'master') + + def test_origin_develop(self): + self._clone_to('origin', 'develop') + + self.assertEqual(utils.get_default_upstream_branch(), 'develop') + + def test_upstream_master(self): + self._clone_to('upstream', 'master') + + self.assertEqual(utils.get_default_upstream_branch(), 'master') + + def test_upstream_develop(self): + self._clone_to('upstream', 'develop') + + self.assertEqual(utils.get_default_upstream_branch(), 'develop') + + def test_no_remote(self): + self.assertEqual(utils.get_default_upstream_branch(), None) + + +class TestGetCurrentBranch(GitTestCase): + + def test_single_branch(self): + self.cmd(['git', 'checkout', '-b', 'test']) + self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) + + self.assertEqual(utils.get_current_local_branch(), 'test') + + def test_multiple_branches(self): + # There are two branches pointing at the current commit. + self.cmd(['git', 'checkout', '-b', 'test']) + self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) + self.cmd(['git', 'checkout', '-b', 'another']) + + self.assertEqual(utils.get_current_local_branch(), 'another') + + def test_detached_head(self): + self.cmd(['git', 'checkout', '-b', 'test']) + self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) + self.cmd(['git', 'checkout', 'HEAD^']) + + with self.assertRaises(RuntimeError): + utils.get_current_local_branch() diff --git a/tests/test_clone.py b/tests/test_clone.py deleted file mode 100644 index 6281b5b..0000000 --- a/tests/test_clone.py +++ /dev/null @@ -1,102 +0,0 @@ -import unittest -import mock - -from click.testing import CliRunner - -from pag.commands.clone import clone - -EMPTY_RESPONSE = mock.Mock(json=lambda : { - 'total_projects': 0, - 'projects': [], -}) - -RESPONSE_WITH_REPO = mock.Mock(json=lambda: { - 'total_projects': 0, - 'projects': [{'name': 'fedmod', 'namespace': 'modularity'}], -}) - - -class CloneTest(unittest.TestCase): - def setUp(self): - self.runner = CliRunner() - self.maxDiff = None - self.patcher = mock.patch('requests.get') - self.mock_get = self.patcher.start() - self.mock_get.return_value = EMPTY_RESPONSE - - def tearDown(self): - self.patcher.stop() - - @mock.patch('pag.commands.clone.run') - def test_clone(self, run): - result = self.runner.invoke(clone, ['pag']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'clone', 'ssh://git@pagure.io/pag.git', 'pag'])] - ) - self.assertEqual(self.mock_get.call_args_list, []) - - @mock.patch('pag.commands.clone.run') - def test_clone_anonymous(self, run): - result = self.runner.invoke(clone, ['-a', 'pag']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'clone', 'https://pagure.io/pag.git', 'pag'])] - ) - self.assertEqual(self.mock_get.call_args_list, []) - - @mock.patch('pag.commands.clone.run') - def test_clone_fork(self, run): - result = self.runner.invoke(clone, ['ralph/pag']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'clone', 'ssh://git@pagure.io/forks/ralph/pag.git', 'pag'])] - ) - self.assertEqual(self.mock_get.call_args_list, - [mock.call(mock.ANY, {'namespace': 'ralph', 'name': 'pag'})]) - - @mock.patch('pag.commands.clone.run') - def test_clone_fork_anonymous(self, run): - result = self.runner.invoke(clone, ['-a', 'ralph/pag']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'clone', 'https://pagure.io/forks/ralph/pag.git', 'pag'])] - ) - self.assertEqual(self.mock_get.call_args_list, - [mock.call(mock.ANY, {'namespace': 'ralph', 'name': 'pag'})]) - - @mock.patch('pag.commands.clone.run') - def test_clone_namespace(self, run): - self.mock_get.return_value = RESPONSE_WITH_REPO - - result = self.runner.invoke(clone, ['modularity/fedmod']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'clone', 'ssh://git@pagure.io/modularity/fedmod.git', 'fedmod'])] - ) - self.assertEqual(self.mock_get.call_args_list, - [mock.call(mock.ANY, {'namespace': 'modularity', 'name': 'fedmod'})]) - - @mock.patch('pag.commands.clone.run') - def test_clone_namespace_anonymous(self, run): - self.mock_get.return_value = RESPONSE_WITH_REPO - - result = self.runner.invoke(clone, ['-a', 'modularity/fedmod']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'clone', 'https://pagure.io/modularity/fedmod.git', 'fedmod'])] - ) - self.assertEqual(self.mock_get.call_args_list, - [mock.call(mock.ANY, {'namespace': 'modularity', 'name': 'fedmod'})]) diff --git a/tests/test_review.py b/tests/test_review.py deleted file mode 100644 index 0985f9d..0000000 --- a/tests/test_review.py +++ /dev/null @@ -1,187 +0,0 @@ -import unittest -import mock - -from click.testing import CliRunner - -from pag.commands.review import review - - -# This is an abbreviated response from list pull request API that contains -# minimal amount of data needed. -LIST_RESPONSE = { - "requests": [ - { - "id": 2344, - "title": "Fix the API docs", - "user": {"name": "mprahl"} - }, - { - "id": 2343, - "title": ("Add ways to customize the gitolite configuration file " - "with snippets, and some extra details"), - "user": {"name": "pingou"} - } - ], - "total_requests": 2 -} - -# This is expected output when listing pull requests returns the data above. -LIST_OUTPUT = """ - 2344 mprahl Fix the API docs - 2343 pingou Add ways to customize the gitolite configuration file with - snippets, and some extra details -""".lstrip('\n') - -# Abbreviated response for listing details about a pull request. -GET_RESPONSE = { - "branch_from": "fix-api-docs", - "commit_stop": "a08f507b99afeda8b9d1f5cf2024eb723726924b", - "id": 2344, - "remote_git": None, - "repo_from": { - "fullname": "forks/mprahl/pagure", - }, -} - - -class ReviewTest(unittest.TestCase): - def setUp(self): - self.runner = CliRunner() - self.maxDiff = None - - @mock.patch('pag.commands.review.run') - @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'my-project') - def test_open_web(self, run): - run.side_effect = [ - (0, 'review/12/3\n'), - (0, ''), - ] - - with self.runner.isolated_filesystem(): - result = self.runner.invoke(review, ['--open']) - - self.assertEqual(result.exit_code, 0) - self.assertEqual( - run.call_args_list, - [mock.call( - ['git', 'rev-parse', '--abbrev-ref', 'HEAD'], echo=False), - mock.call( - ['xdg-open', 'https://pagure.io/my-project/pull-request/12'])] - ) - - @mock.patch('pag.commands.review.run') - def test_open_web_on_bad_branch(self, run): - run.return_value = (0, 'master\n') - - with self.runner.isolated_filesystem(): - result = self.runner.invoke(review, ['--open']) - - self.assertEqual(result.exit_code, 1) - self.assertIn('Not on a review branch', result.output) - - @mock.patch('pag.commands.review.list_pull_requests') - @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') - def test_list(self, list_pull_requests): - list_pull_requests.return_value = LIST_RESPONSE['requests'] - - result = self.runner.invoke(review, ['--list']) - - self.assertEqual( - list_pull_requests.call_args_list, - [mock.call('pagure')]) - self.assertEqual(result.exit_code, 0) - self.assertEqual(result.output, LIST_OUTPUT) - - @mock.patch('requests.get') - @mock.patch('pag.commands.review.run') - @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') - def test_checkout_new(self, run, get): - get.return_value = mock.Mock( - json=mock.Mock(return_value=GET_RESPONSE) - ) - run.side_effect = [ - (1, ''), - (0, ''), - (0, 'review/2344/1\n'), - (0, ''), - ] - - result = self.runner.invoke(review, ['2344']) - - self.assertEqual( - get.call_args_list, - [mock.call('https://pagure.io/api/0/pagure/pull-request/2344')]) - self.assertEqual( - run.call_args_list, - [mock.call(['git', 'branch', '--contains', - 'a08f507b99afeda8b9d1f5cf2024eb723726924b', - 'review/2344/*'], echo=False), - mock.call( - ['git', 'fetch', 'https://pagure.io/forks/mprahl/pagure.git', - 'fix-api-docs'], graceful=False), - mock.call(['git', 'branch', '--list', 'review/2344/*'], - echo=False, graceful=False), - mock.call(['git', 'checkout', '-b', 'review/2344/2', - 'FETCH_HEAD'], graceful=False), - ]) - self.assertEqual(result.exit_code, 0) - - @mock.patch('requests.get') - @mock.patch('pag.commands.review.run') - @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') - def test_checkout_existing(self, run, get): - get.return_value = mock.Mock( - json=mock.Mock(return_value=GET_RESPONSE) - ) - run.side_effect = [ - (0, 'review/2344/1\n'), - (0, ''), - ] - - result = self.runner.invoke(review, ['2344']) - - self.assertEqual( - get.call_args_list, - [mock.call('https://pagure.io/api/0/pagure/pull-request/2344')]) - self.assertEqual( - run.call_args_list, - [ - mock.call(['git', 'branch', '--contains', - 'a08f507b99afeda8b9d1f5cf2024eb723726924b', - 'review/2344/*'], echo=False), - mock.call(['git', 'checkout', 'review/2344/1'], graceful=False), - ]) - self.assertEqual(result.exit_code, 0) - - @mock.patch('pag.commands.review.run') - @mock.patch('pag.commands.review.list_pull_requests', new=lambda _: LIST_RESPONSE['requests']) - @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') - def test_cleanup_merged_branches(self, run): - run.return_value = (0, 'review/1/1\nreview/1/2\n') - - result = self.runner.invoke(review, ['--cleanup']) - - self.assertEqual(result.exit_code, 0) - - self.assertEqual( - run.call_args_list, - [ - mock.call(['git', 'branch', '--list', 'review/*'], echo=False), - mock.call(['git', 'branch', '-D', 'review/1/1', 'review/1/2']), - ]) - - @mock.patch('pag.commands.review.run') - @mock.patch('pag.commands.review.list_pull_requests', new=lambda _: LIST_RESPONSE['requests']) - @mock.patch('pag.commands.review.in_git_repo', new=lambda: 'pagure') - def test_keep_branch_for_opened_pr(self, run): - run.return_value = (0, 'review/2344/1\nreview/2344/2\n') - - result = self.runner.invoke(review, ['--cleanup']) - - self.assertEqual(result.exit_code, 0) - - self.assertEqual( - run.call_args_list, - [ - mock.call(['git', 'branch', '--list', 'review/*'], echo=False), - ]) diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index 2f4a445..0000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,113 +0,0 @@ -import os -import shlex -import shutil -import subprocess -import tempfile -import unittest - -from pag import utils - - -class GitTestCase(unittest.TestCase): - """ - A base class for tests that need a git repo. It creates a temporary repo - with a single commit for each test and changes to that directory. - """ - - def cmd(self, cmd, cwd=None, *args, **kwargs): - print('$ %s' % ' '.join(shlex.quote(x) for x in cmd)) - cp = subprocess.run(cmd, *args, - cwd=cwd or self.repo, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - universal_newlines=True, - **kwargs) - print(cp.stdout) - - def setUp(self): - self.orig_path = os.getcwd() - # Create git repository with some basic content - self.repo = tempfile.mkdtemp(prefix='test_current_branch_') - self.cmd(['git', 'init']) - with open(os.path.join(self.repo, 'file'), 'w') as f: - f.write('') - self.cmd(['git', 'add', '.']) - self.cmd(['git', 'commit', '-m', 'Initial commit']) - # and chdir into it. - os.chdir(self.repo) - - def tearDown(self): - shutil.rmtree(self.repo) - # Change back to original working directory - os.chdir(self.orig_path) - - -class TestGetDefaultBranch(GitTestCase): - """ - This test treats the inherited repo as upstream and clones it into a - separate directory, in which it runs the actual function. It can check out - a different branch in the "upstream" repo and thus effectively change the - default branch. - """ - - def setUp(self): - super().setUp() - self.clone = tempfile.mkdtemp(prefix='cloned_repo_') - - def tearDown(self): - super().tearDown() - shutil.rmtree(self.clone) - - def _clone_to(self, remote, branch): - if branch != 'master': - self.cmd(['git', 'checkout', '-b', branch]) - self.cmd(['git', 'clone', self.repo, self.clone, '-o', remote]) - os.chdir(self.clone) - - def test_origin_master(self): - self._clone_to('origin', 'master') - - self.assertEqual(utils.get_default_upstream_branch(), 'master') - - def test_origin_develop(self): - self._clone_to('origin', 'develop') - - self.assertEqual(utils.get_default_upstream_branch(), 'develop') - - def test_upstream_master(self): - self._clone_to('upstream', 'master') - - self.assertEqual(utils.get_default_upstream_branch(), 'master') - - def test_upstream_develop(self): - self._clone_to('upstream', 'develop') - - self.assertEqual(utils.get_default_upstream_branch(), 'develop') - - def test_no_remote(self): - self.assertEqual(utils.get_default_upstream_branch(), None) - - -class TestGetCurrentBranch(GitTestCase): - - def test_single_branch(self): - self.cmd(['git', 'checkout', '-b', 'test']) - self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) - - self.assertEqual(utils.get_current_local_branch(), 'test') - - def test_multiple_branches(self): - # There are two branches pointing at the current commit. - self.cmd(['git', 'checkout', '-b', 'test']) - self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) - self.cmd(['git', 'checkout', '-b', 'another']) - - self.assertEqual(utils.get_current_local_branch(), 'another') - - def test_detached_head(self): - self.cmd(['git', 'checkout', '-b', 'test']) - self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) - self.cmd(['git', 'checkout', 'HEAD^']) - - with self.assertRaises(RuntimeError): - utils.get_current_local_branch()