Skip to content

Commit

Permalink
Merge pull request #1 from 3tilley/mintty-tests
Browse files Browse the repository at this point in the history
Mintty tests
  • Loading branch information
SSE4 authored Oct 26, 2021
2 parents f81f237 + a538f63 commit 5314bd8
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 11 deletions.
25 changes: 17 additions & 8 deletions colorama/ansitowin32.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
from io import UnsupportedOperation
import re
import sys
import os
Expand All @@ -19,6 +20,12 @@
winterm = WinTerm()


class FileNameInfo(ctypes.Structure):
"""Struct to get FileNameInfo from the win32api"""
_fields_ = [('FileNameLength', ctypes.c_ulong),
('FileName', ctypes.c_wchar * 40)]


def is_msys_cygwin_tty(stream):
if not hasattr(stream, "fileno"):
return False
Expand All @@ -29,24 +36,26 @@ def is_msys_cygwin_tty(stream):
if msvcrt is None:
return False

fileno = stream.fileno()
handle = msvcrt.get_osfhandle(fileno)
FileNameInfo = 2
try:
fileno = stream.fileno()
except UnsupportedOperation:
# StringIO for example has the fileno attribute but doesn't support calling it
return False

class FILE_NAME_INFO(ctypes.Structure):
_fields_ = [('FileNameLength', ctypes.c_ulong),
('FileName', ctypes.c_wchar * 40)]
handle = msvcrt.get_osfhandle(fileno)
FILE_NAME_INFO = 2

info = FILE_NAME_INFO()
info = FileNameInfo()
ret = ctypes.windll.kernel32.GetFileInformationByHandleEx(handle,
FileNameInfo,
FILE_NAME_INFO,
ctypes.byref(info),
ctypes.sizeof(info))
if ret == 0:
return False

msys_pattern = r"\\msys-[0-9a-f]{16}-pty\d-(to|from)-master"
cygwin_pattern = r"\\cygwin-[0-9a-f]{16}-pty\d-(to|from)-master"

return re.match(msys_pattern, info.FileName) is not None or \
re.match(cygwin_pattern, info.FileName) is not None

Expand Down
72 changes: 69 additions & 3 deletions colorama/tests/isatty_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
import sys
from unittest import TestCase, main
from io import StringIO
from unittest import TestCase, main, skipUnless

from ..ansitowin32 import StreamWrapper, AnsiToWin32
from .utils import pycharm, replace_by, replace_original_by, StreamTTY, StreamNonTTY
from mock import patch, PropertyMock

from ..ansitowin32 import StreamWrapper, AnsiToWin32, is_msys_cygwin_tty, FileNameInfo
from .utils import pycharm, replace_by, replace_original_by, StreamTTY, StreamNonTTY, StreamNonTTYWithFileNo


def is_a_tty(stream):
Expand Down Expand Up @@ -52,6 +55,69 @@ def test_withPycharmStreamWrapped(self):
self.assertTrue(AnsiToWin32(sys.stdout).stream.isatty())
self.assertTrue(AnsiToWin32(sys.stderr).stream.isatty())

@patch("colorama.ansitowin32.is_msys_cygwin_tty", return_value=False)
def test_isattyCorrectForMintty(self, mock_fn):
self.assertFalse(is_a_tty(StreamTTY()))
self.assertFalse(is_a_tty(StreamNonTTY()))
mock_fn.assert_called_once()

@patch("colorama.ansitowin32.is_msys_cygwin_tty", return_value=True)
def test_isattyCorrectForMintty(self, mock_fn):
self.assertTrue(is_a_tty(StreamNonTTY()))
self.assertTrue(is_a_tty(StreamTTY()))
mock_fn.assert_called()

class MinttyTest(TestCase):
"""Tests for the detection of mintty / msys/ cygwin
They're arguably a little brittle to the exact detection implementation, so can be refactored
if the implementation changes.
"""

@patch("colorama.ansitowin32.msvcrt", None)
def test_falseNotOnWindows(self):
self.assertFalse(is_msys_cygwin_tty(StreamNonTTYWithFileNo()))

def test_falseForIoString(self):
self.assertFalse(is_msys_cygwin_tty(StringIO()))

@skipUnless(sys.platform.startswith("win"), "requires Windows")
@patch("ctypes.windll.kernel32", None)
def test_falseIfKernelModuleUnavailable(self):
self.assertFalse(is_msys_cygwin_tty(StreamNonTTYWithFileNo()))

@skipUnless(sys.platform.startswith("win"), "requires Windows")
@patch("ctypes.windll.kernel32.GetFileInformationByHandleEx", return_value=0)
@patch("msvcrt.get_osfhandle", return_value=10)
def test_falseIfWin32CallFails(self, mock_win32_call, mock_handle_call):
self.assertFalse(is_msys_cygwin_tty(StreamNonTTYWithFileNo()))

@skipUnless(sys.platform.startswith("win"), "requires Windows")
@patch("ctypes.windll.kernel32.GetFileInformationByHandleEx", return_value=1)
@patch("msvcrt.get_osfhandle", return_value=1000)
def test_trueForMsys(self, mock_file_call, mock_handle_call):

with patch.object(FileNameInfo, "FileName", new_callable=PropertyMock) as mock_filename_info:
mock_filename_info.return_value = r"\msys-0000000000000000-pty3-to-master"
self.assertTrue(is_msys_cygwin_tty(StreamNonTTYWithFileNo()))

@skipUnless(sys.platform.startswith("win"), "requires Windows")
@patch("ctypes.windll.kernel32.GetFileInformationByHandleEx", return_value=1)
@patch("msvcrt.get_osfhandle", return_value=1000)
def test_trueForCygwin(self, mock_file_call, mock_handle_call):

with patch.object(FileNameInfo, "FileName", new_callable=PropertyMock) as mock_filename_info:
mock_filename_info.return_value = r"\cygwin-0000000000000000-pty3-to-master"
self.assertTrue(is_msys_cygwin_tty(StreamNonTTYWithFileNo()))

@skipUnless(sys.platform.startswith("win"), "requires Windows")
@patch("ctypes.windll.kernel32.GetFileInformationByHandleEx", return_value=1)
@patch("msvcrt.get_osfhandle", return_value=1000)
def test_falseForAnythingElse(self, mock_file_call, mock_handle_call):

with patch.object(FileNameInfo, "FileName", new_callable=PropertyMock) as mock_filename_info:
mock_filename_info.return_value = r"\random-0000000000000000-pty3-to-master"
self.assertFalse(is_msys_cygwin_tty(StreamNonTTYWithFileNo()))

if __name__ == '__main__':
main()
7 changes: 7 additions & 0 deletions colorama/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ class StreamNonTTY(StringIO):
def isatty(self):
return False

class StreamNonTTYWithFileNo(StringIO):
def isatty(self):
return False

def fileno(self):
return 10

@contextmanager
def osname(name):
orig = os.name
Expand Down

0 comments on commit 5314bd8

Please sign in to comment.