test.test_cli   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 63
dl 0
loc 106
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A CliTests.test_successful_proc() 0 11 2
A CliTests.test_webbrowser_not_found() 0 15 2
A CliTests.test_unsuccessful_proc() 0 19 2
A CliUtilsTest.test_parse_traceback_reversed() 0 3 1
A CliUtilsTest.test_get_search_url() 0 6 1
A CliUtilsTest.test_parse_traceback_empty_str() 0 3 1
A CliUtilsTest.test_parse_traceback() 0 3 1
A CliTests.test_no_commands() 0 5 2
A CliTests.test_file_not_found_proc() 0 6 2
1
import io
2
import subprocess
3
import unittest
4
5
from contextlib import redirect_stdout
6
from unittest import mock
7
8
from qdbg import get_search_url
9
from qdbg import main
10
from qdbg import parse_traceback
11
from qdbg import QdbgError
12
13
14
class CliTests(unittest.TestCase):
15
    """
16
    Tests associated with the main cli interface
17
    """
18
19
    @mock.patch("subprocess.run")
20
    def test_successful_proc(self, mock_proc: mock.MagicMock) -> None:
21
        """Test that a successful process runs"""
22
        mock_proc.return_value = subprocess.CompletedProcess(
23
            args=[], returncode=0, stdout=b"mock stdout"
24
        )
25
26
        with redirect_stdout(io.StringIO()) as f:
27
            main(args=["cmd"])
28
29
        self.assertEqual(f.getvalue(), "mock stdout\n")
30
31
    @mock.patch("subprocess.run")
32
    def test_file_not_found_proc(self, mock_proc: mock.MagicMock) -> None:
33
        """Test that file not found error is caught"""
34
        mock_proc.side_effect = FileNotFoundError
35
        with self.assertRaises(SystemExit):
36
            main(args=["cmd"])
37
38
    @mock.patch("subprocess.run")
39
    def test_no_commands(self, mock_proc: mock.MagicMock) -> None:
40
        """Test that an exception is raised if no command is provided"""
41
        with self.assertRaises(QdbgError):
42
            main(args=[])
43
44
    @mock.patch("webbrowser.open_new_tab")
45
    @mock.patch("subprocess.run")
46
    def test_webbrowser_not_found(
47
        self, mock_open_new_tab: mock.MagicMock, mock_proc: mock.MagicMock
48
    ) -> None:
49
        """Test for when no browser is found"""
50
        mock_proc.return_value = subprocess.CompletedProcess(
51
            args=[], returncode=1, stderr=b""
52
        )
53
54
        # Result if webbrowser.open_new_tab fails
55
        mock_open_new_tab.return_value = False
56
57
        with self.assertRaises(QdbgError):
58
            main(args=["cmd"])
59
60
    @mock.patch("webbrowser.open_new_tab")
61
    @mock.patch("qdbg.cli.get_search_url")
62
    @mock.patch("subprocess.run")
63
    def test_unsuccessful_proc(
64
        self,
65
        mock_proc: mock.MagicMock,
66
        mock_get_search_url: mock.MagicMock,
67
        mock_open_new_tab: mock.MagicMock,
68
    ) -> None:
69
        """Test process that fails and a browser tab is expected to open"""
70
        mock_proc.return_value = subprocess.CompletedProcess(
71
            args=[], returncode=1, stderr=b""
72
        )
73
        mock_get_search_url.return_value = "search_url"
74
75
        with self.assertRaises(SystemExit):
76
            main(args=["cmd"])
77
78
        mock_open_new_tab.assert_called_once_with(url="search_url")
79
80
81
class CliUtilsTest(unittest.TestCase):
82
    """
83
    Tests associated with cli utilities
84
    """
85
86
    trace = "line1\nline2\nline3"
87
88
    def test_parse_traceback_empty_str(self) -> None:
89
        """Test with empty string arg"""
90
        self.assertEqual(parse_traceback(stderr=""), "")
91
92
    def test_parse_traceback(self) -> None:
93
        """Expect to get the last line of the trace"""
94
        self.assertEqual(parse_traceback(stderr=self.trace), "line3")
95
96
    def test_parse_traceback_reversed(self) -> None:
97
        """Expect to get the first line of the trace"""
98
        self.assertEqual(parse_traceback(stderr=self.trace, from_bottom=False), "line1")
99
100
    @mock.patch("qdbg.cli.parse_traceback")
101
    def test_get_search_url(self, mock_parse_traceback: mock.MagicMock) -> None:
102
        """Test that the appropriate url is created"""
103
        mock_parse_traceback.return_value = "error"
104
        url = get_search_url(cmd="python", stderr="error")
105
        self.assertEqual(url, "https://you.com/search?q=python+error")
106