diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 00000000..e4b05bc1 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,37 @@ +name: Python Tests + +on: + - push + +jobs: + test: + runs-on: ubuntu-latest + + container: + image: ubuntu:22.04 + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install binary dependencies + run: apt update && apt install -y git bzr fossil mercurial subversion + env: + DEBIAN_FRONTEND: noninteractive + + - name: Install Python dependencies + run: python -m pip install -r requirements-dev.txt + + - name: Run Python Tests + run: python -m pytest --junitxml=test-results.xml + + - name: Publish Test Report + uses: mikepenz/action-junit-report@v4 + if: success() || failure() # always run even if the previous step fails + with: + report_paths: 'test-results.xml' diff --git a/powerline_shell/segments/uptime.py b/powerline_shell/segments/uptime.py index 1c030611..4108ee60 100644 --- a/powerline_shell/segments/uptime.py +++ b/powerline_shell/segments/uptime.py @@ -1,19 +1,19 @@ import subprocess import re -from ..utils import BasicSegment, decode +from ..utils import BasicSegment class Segment(BasicSegment): def add_to_powerline(self): powerline = self.powerline try: - output = decode(subprocess.check_output(['uptime'], stderr=subprocess.STDOUT)) - raw_uptime = re.search('(?<=up).+(?=,\s+\d+\s+user)', output).group(0) - day_search = re.search('\d+(?=\s+day)', output) + output = subprocess.check_output(['uptime'], stderr=subprocess.STDOUT) + raw_uptime = re.search(r'(?<=up).+(?=,\s+\d+\s+user)', output).group(0) + day_search = re.search(r'\d+(?=\s+day)', output) days = '' if not day_search else '%sd ' % day_search.group(0) - hour_search = re.search('\d{1,2}(?=\:)', raw_uptime) + hour_search = re.search(r'\d{1,2}(?=\:)', raw_uptime) hours = '' if not hour_search else '%sh ' % hour_search.group(0) - minutes = re.search('(?<=\:)\d{1,2}|\d{1,2}(?=\s+min)', raw_uptime).group(0) + minutes = re.search(r'(?<=\:)\d{1,2}|\d{1,2}(?=\s+min)', raw_uptime).group(0) uptime = u' %s%s%sm \u2191 ' % (days, hours, minutes) powerline.append(uptime, powerline.theme.CWD_FG, powerline.theme.PATH_BG) except OSError: diff --git a/requirements-dev.txt b/requirements-dev.txt index 59d5eef7..b440b50a 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,3 @@ -nose>=1.3.7 -mock>=1.3.0 sh>=1.11 -parameterized>=0.6.1 \ No newline at end of file +parameterized>=0.6.1 +pytest diff --git a/test/color_compliment_test.py b/test/color_compliment_test.py index 47f72d07..e022c1ed 100644 --- a/test/color_compliment_test.py +++ b/test/color_compliment_test.py @@ -7,7 +7,7 @@ def build_inputs(): # Build 768 hex/rgb values to test against getOppositeColor - input_bytes = map(hex, xrange(pow(2,8))) + input_bytes = list(map(hex, range(pow(2,8)))) input_list = [] for x in input_bytes: diff --git a/test/cwd_test.py b/test/cwd_test.py index ed52dc36..00ae5faf 100644 --- a/test/cwd_test.py +++ b/test/cwd_test.py @@ -1,8 +1,11 @@ import unittest -import mock +from unittest import mock import os import tempfile import shutil + +import sh + import powerline_shell as p @@ -33,9 +36,9 @@ def test_nonexistent_warns(self, warn, getenv): @mock.patch('powerline_shell.warn') def test_falls_back_to_getcwd(self, warn, getenv): getenv.return_value = None - os.chdir(self.dirname) - self.assertEqual(p.get_valid_cwd(), self.dirname) - self.assertEqual(warn.call_count, 0) + with sh.pushd(self.dirname): + self.assertEqual(p.get_valid_cwd(), self.dirname) + self.assertEqual(warn.call_count, 0) @mock.patch('os.getenv') @mock.patch('powerline_shell.warn') @@ -44,10 +47,10 @@ def test_nonexistent_getcwd_warns(self, warn, getenv): getenv.return_value = None os.mkdir(subdir) - os.chdir(subdir) - os.rmdir(subdir) + with sh.pushd(subdir): + os.rmdir(subdir) - with self.assertRaises(SystemExit) as e: - p.get_valid_cwd() + with self.assertRaises(SystemExit) as e: + p.get_valid_cwd() - self.assertEqual(warn.call_count, 1) + self.assertEqual(warn.call_count, 1) diff --git a/test/segments_test/bzr_test.py b/test/segments_test/bzr_test.py index 73dbebae..813a41a4 100644 --- a/test/segments_test/bzr_test.py +++ b/test/segments_test/bzr_test.py @@ -1,5 +1,7 @@ import unittest -import mock +from contextlib import ExitStack + +from unittest import mock import tempfile import shutil import sh @@ -28,14 +30,20 @@ def setUp(self): }) self.dirname = tempfile.mkdtemp() - sh.cd(self.dirname) - sh.bzr("init-repo", ".") - sh.mkdir("trunk") - sh.cd("trunk") - sh.bzr("init") + with sh.pushd(self.dirname): + sh.bzr("init-repo", ".") + sh.mkdir("trunk") + + with sh.pushd(self.dirname + "/trunk"): + sh.bzr("init") + sh.bzr("whoami", "--branch", '"Example "') self.segment = bzr.Segment(self.powerline, {}) + with ExitStack() as stack: + self._resource = stack.enter_context(sh.pushd(self.dirname + "/trunk")) + self.addCleanup(stack.pop_all().close) + def tearDown(self): shutil.rmtree(self.dirname) @@ -45,9 +53,8 @@ def _add_and_commit(self, filename): sh.bzr("commit", "-m", "add file " + filename) def _checkout_new_branch(self, branch): - sh.cd("..") - sh.bzr("branch", "trunk", branch) - sh.cd(branch) + with sh.pushd(self.dirname): + sh.bzr("branch", "trunk", branch) @mock.patch("powerline_shell.utils.get_PATH") def test_bzr_not_installed(self, get_PATH): @@ -71,12 +78,14 @@ def test_trunk(self): def test_different_branch(self): self._add_and_commit("foo") self._checkout_new_branch("bar") - self.segment.start() - self.segment.add_to_powerline() - self.assertEqual(self.powerline.append.call_args[0][0], " bar ") + with sh.pushd(self.dirname + "/bar"): + self.segment.start() + self.segment.add_to_powerline() + self.assertEqual(self.powerline.append.call_args[0][0], " bar ") @mock.patch('powerline_shell.segments.bzr._get_bzr_status') def test_all(self, check_output): for stdout, result in test_cases: - stats = bzr.parse_bzr_stats(stdout) - self.assertEquals(result, stats) + with sh.pushd(self.dirname + "/trunk"): + stats = bzr.parse_bzr_stats(stdout) + self.assertEqual(result, stats) diff --git a/test/segments_test/fossil_test.py b/test/segments_test/fossil_test.py index 34f914af..dd45b923 100644 --- a/test/segments_test/fossil_test.py +++ b/test/segments_test/fossil_test.py @@ -1,5 +1,8 @@ import unittest -import mock +from contextlib import ExitStack +from os import environ + +from unittest import mock import tempfile import shutil import sh @@ -17,6 +20,7 @@ class FossilTest(unittest.TestCase): + @mock.patch.dict(environ, {"USER": "root"}) def setUp(self): self.powerline = mock.MagicMock() self.powerline.segment_conf.side_effect = dict_side_effect_fn({ @@ -24,12 +28,16 @@ def setUp(self): }) self.dirname = tempfile.mkdtemp() - sh.cd(self.dirname) - sh.fossil("init", "test.fossil") - sh.fossil("open", "test.fossil") + with sh.pushd(self.dirname): + sh.fossil("init", "test.fossil") + sh.fossil("open", "test.fossil") self.segment = fossil.Segment(self.powerline, {}) + with ExitStack() as stack: + self._resource = stack.enter_context(sh.pushd(self.dirname)) + self.addCleanup(stack.pop_all().close) + def tearDown(self): shutil.rmtree(self.dirname) @@ -55,12 +63,14 @@ def test_non_fossil_directory(self): self.segment.add_to_powerline() self.assertEqual(self.powerline.append.call_count, 0) + @mock.patch.dict(environ, {"USER": "root"}) def test_standard(self): self._add_and_commit("foo") self.segment.start() self.segment.add_to_powerline() self.assertEqual(self.powerline.append.call_args[0][0], " trunk ") + @mock.patch.dict(environ, {"USER": "root"}) def test_different_branch(self): self._add_and_commit("foo") self._checkout_new_branch("bar") @@ -72,4 +82,4 @@ def test_different_branch(self): def test_all(self, check_output): for stdout, result in test_cases.items(): stats = fossil.parse_fossil_stats([stdout]) - self.assertEquals(result, stats) + self.assertEqual(result, stats) diff --git a/test/segments_test/git_stash_test.py b/test/segments_test/git_stash_test.py index 1b228cd6..3285f906 100644 --- a/test/segments_test/git_stash_test.py +++ b/test/segments_test/git_stash_test.py @@ -1,5 +1,7 @@ import unittest -import mock +from contextlib import ExitStack + +from unittest import mock import tempfile import shutil import sh @@ -12,11 +14,17 @@ class GitStashTest(unittest.TestCase): def setUp(self): self.powerline = mock.MagicMock() self.dirname = tempfile.mkdtemp() - sh.cd(self.dirname) - sh.git("init", ".") + with sh.pushd(self.dirname): + sh.git("init", ".") + sh.git("config", "user.name", "Test") + sh.git("config", "user.email", "example@example.com") self.segment = git_stash.Segment(self.powerline, {}) + with ExitStack() as stack: + self._resource = stack.enter_context(sh.pushd(self.dirname)) + self.addCleanup(stack.pop_all().close) + def tearDown(self): shutil.rmtree(self.dirname) diff --git a/test/segments_test/git_test.py b/test/segments_test/git_test.py index 373fd68f..b4e94aea 100644 --- a/test/segments_test/git_test.py +++ b/test/segments_test/git_test.py @@ -1,5 +1,7 @@ import unittest -import mock +from contextlib import ExitStack + +from unittest import mock import tempfile import shutil import sh @@ -16,11 +18,18 @@ def setUp(self): }) self.dirname = tempfile.mkdtemp() - sh.cd(self.dirname) - sh.git("init", ".") + with sh.pushd(self.dirname): + sh.git("init", ".") + sh.git("config", "user.name", "Test") + sh.git("config", "user.email", "example@example.com") self.segment = git.Segment(self.powerline, {}) + with ExitStack() as stack: + self._resource = stack.enter_context(sh.pushd(self.dirname)) + self.addCleanup(stack.pop_all().close) + + def tearDown(self): shutil.rmtree(self.dirname) @@ -57,7 +66,7 @@ def test_master_branch(self): self._add_and_commit("foo") self.segment.start() self.segment.add_to_powerline() - self.assertEqual(self.powerline.append.call_args[0][0], ' master ') + self.assertIn(self.powerline.append.call_args[0][0], [' master ', ' main ']) def test_different_branch(self): self._add_and_commit("foo") diff --git a/test/segments_test/hg_test.py b/test/segments_test/hg_test.py index 004eac9c..27944e95 100644 --- a/test/segments_test/hg_test.py +++ b/test/segments_test/hg_test.py @@ -1,5 +1,7 @@ import unittest -import mock +from contextlib import ExitStack + +from unittest import mock import tempfile import shutil import sh @@ -26,11 +28,15 @@ def setUp(self): }) self.dirname = tempfile.mkdtemp() - sh.cd(self.dirname) - sh.hg("init", ".") + with sh.pushd(self.dirname): + sh.hg("init", ".") self.segment = hg.Segment(self.powerline, {}) + with ExitStack() as stack: + self._resource = stack.enter_context(sh.pushd(self.dirname)) + self.addCleanup(stack.pop_all().close) + def tearDown(self): shutil.rmtree(self.dirname) @@ -72,4 +78,4 @@ def test_different_branch(self): def test_all(self, check_output): for stdout, result in test_cases.items(): stats = hg.parse_hg_stats([stdout]) - self.assertEquals(result, stats) + self.assertEqual(result, stats) diff --git a/test/segments_test/hostname_test.py b/test/segments_test/hostname_test.py index 05ae1f1b..43f2b59f 100644 --- a/test/segments_test/hostname_test.py +++ b/test/segments_test/hostname_test.py @@ -1,5 +1,5 @@ import unittest -import mock +from unittest import mock import powerline_shell.segments.hostname as hostname from powerline_shell.themes.default import Color from argparse import Namespace diff --git a/test/segments_test/svn_test.py b/test/segments_test/svn_test.py index d7d821f8..d615ad8f 100644 --- a/test/segments_test/svn_test.py +++ b/test/segments_test/svn_test.py @@ -1,7 +1,9 @@ import tempfile import unittest import shutil -import mock +from contextlib import ExitStack + +from unittest import mock import sh import powerline_shell.segments.svn as svn from ..testing_utils import dict_side_effect_fn @@ -15,18 +17,24 @@ def setUp(self): ("vcs", "show_symbol"): False, }) - self.dirname = tempfile.mkdtemp() - sh.cd(self.dirname) - # sh.svn("init", ".") + self.upstream_dir = tempfile.mkdtemp() + self.checkout_dir = tempfile.mkdtemp() + sh.svnadmin("create", self.upstream_dir) + sh.svn("checkout", f"file://{self.upstream_dir}", self.checkout_dir) self.segment = svn.Segment(self.powerline, {}) + with ExitStack() as stack: + self._resource = stack.enter_context(sh.pushd(self.checkout_dir)) + self.addCleanup(stack.pop_all().close) + def tearDown(self): - shutil.rmtree(self.dirname) + shutil.rmtree(self.upstream_dir) + shutil.rmtree(self.checkout_dir) @mock.patch("powerline_shell.utils.get_PATH") def test_svn_not_installed(self, get_PATH): - get_PATH.return_value = "" # so svn can't be found + get_PATH.return_value = "" # so svn can't be found self.segment.start() self.segment.add_to_powerline() self.assertEqual(self.powerline.append.call_count, 0) diff --git a/test/segments_test/uptime_test.py b/test/segments_test/uptime_test.py index 676b193e..b515e7e3 100644 --- a/test/segments_test/uptime_test.py +++ b/test/segments_test/uptime_test.py @@ -1,5 +1,5 @@ import unittest -import mock +from unittest import mock import powerline_shell.segments.uptime as uptime test_cases = {