test_console.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import subprocess # noqa: F401
  2. import pytest
  3. from pandas.io.formats.console import detect_console_encoding
  4. from pandas.io.formats.terminal import _get_terminal_size_tput
  5. class MockEncoding(object): # TODO(py27): replace with mock
  6. """
  7. Used to add a side effect when accessing the 'encoding' property. If the
  8. side effect is a str in nature, the value will be returned. Otherwise, the
  9. side effect should be an exception that will be raised.
  10. """
  11. def __init__(self, encoding):
  12. super(MockEncoding, self).__init__()
  13. self.val = encoding
  14. @property
  15. def encoding(self):
  16. return self.raise_or_return(self.val)
  17. @staticmethod
  18. def raise_or_return(val):
  19. if isinstance(val, str):
  20. return val
  21. else:
  22. raise val
  23. @pytest.mark.parametrize('empty,filled', [
  24. ['stdin', 'stdout'],
  25. ['stdout', 'stdin']
  26. ])
  27. def test_detect_console_encoding_from_stdout_stdin(monkeypatch, empty, filled):
  28. # Ensures that when sys.stdout.encoding or sys.stdin.encoding is used when
  29. # they have values filled.
  30. # GH 21552
  31. with monkeypatch.context() as context:
  32. context.setattr('sys.{}'.format(empty), MockEncoding(''))
  33. context.setattr('sys.{}'.format(filled), MockEncoding(filled))
  34. assert detect_console_encoding() == filled
  35. @pytest.mark.parametrize('encoding', [
  36. AttributeError,
  37. IOError,
  38. 'ascii'
  39. ])
  40. def test_detect_console_encoding_fallback_to_locale(monkeypatch, encoding):
  41. # GH 21552
  42. with monkeypatch.context() as context:
  43. context.setattr('locale.getpreferredencoding', lambda: 'foo')
  44. context.setattr('sys.stdout', MockEncoding(encoding))
  45. assert detect_console_encoding() == 'foo'
  46. @pytest.mark.parametrize('std,locale', [
  47. ['ascii', 'ascii'],
  48. ['ascii', Exception],
  49. [AttributeError, 'ascii'],
  50. [AttributeError, Exception],
  51. [IOError, 'ascii'],
  52. [IOError, Exception]
  53. ])
  54. def test_detect_console_encoding_fallback_to_default(monkeypatch, std, locale):
  55. # When both the stdout/stdin encoding and locale preferred encoding checks
  56. # fail (or return 'ascii', we should default to the sys default encoding.
  57. # GH 21552
  58. with monkeypatch.context() as context:
  59. context.setattr(
  60. 'locale.getpreferredencoding',
  61. lambda: MockEncoding.raise_or_return(locale)
  62. )
  63. context.setattr('sys.stdout', MockEncoding(std))
  64. context.setattr('sys.getdefaultencoding', lambda: 'sysDefaultEncoding')
  65. assert detect_console_encoding() == 'sysDefaultEncoding'
  66. @pytest.mark.parametrize("size", ['', ['']])
  67. def test_terminal_unknown_dimensions(monkeypatch, size, mocker):
  68. def communicate(*args, **kwargs):
  69. return size
  70. monkeypatch.setattr('subprocess.Popen', mocker.Mock())
  71. monkeypatch.setattr('subprocess.Popen.return_value.returncode', None)
  72. monkeypatch.setattr(
  73. 'subprocess.Popen.return_value.communicate', communicate)
  74. result = _get_terminal_size_tput()
  75. assert result is None