# -*- coding: utf-8 -*- # Copyright (C) 2012-2018 Red Hat, Inc. # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # the GNU General Public License v.2, or (at your option) any later version. # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY expressed or implied, including the implied warranties of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. You should have received a copy of the # GNU General Public License along with this program; if not, write to the # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. Any Red Hat trademarks that are incorporated in the # source code or documentation are not subject to the GNU General Public # License and may only be used or replicated with the express permission of # Red Hat, Inc. # from __future__ import absolute_import from __future__ import unicode_literals import sys import unittest import dnf.i18n from dnf.pycomp import PY3 from dnf.i18n import fill_exact_width, textwrap_fill import tests.support from tests.support import mock UC_TEXT = 'Šířka' # means 'Width' in Czech UC_TEXT_OSERROR = 'Soubor již existuje' # 'File already exists' STR_TEXT_OSERROR = 'Soubor již existuje' @mock.patch('locale.setlocale') class TestLocale(tests.support.TestCase): def test_setup_locale(self, mock_setlocale): dnf.i18n.setup_locale() self.assertTrue(1 <= mock_setlocale.call_count <= 2) class TestStdout(tests.support.TestCase): def test_setup_stdout(self): # No stdout output can be seen when sys.stdout is patched, debug msgs, # etc. included. with mock.patch('sys.stdout', spec=('write', 'isatty')): retval = dnf.i18n.setup_stdout() self.assertFalse(retval) with mock.patch('sys.stdout') as mock_stdout: mock_stdout.encoding = None retval = dnf.i18n.setup_stdout() self.assertFalse(retval) with mock.patch('sys.stdout') as mock_stdout: mock_stdout.encoding = 'UTF-8' retval = dnf.i18n.setup_stdout() self.assertTrue(retval) with mock.patch('sys.stdout') as mock_stdout: mock_stdout.encoding = 'ISO-8859-2' retval = dnf.i18n.setup_stdout() self.assertFalse(retval) def test_stream(self): fileobj = dnf.pycomp.StringIO() stream = dnf.i18n.UnicodeStream(fileobj, "ISO-8859-2") stream.write(UC_TEXT) output = fileobj.getvalue() self.assertEqual(output, u'\u0160\xed\u0159ka' if PY3 else b'\xa9\xed\xf8ka') self.assertEqual(len(output), len(UC_TEXT)) class TestInput(tests.support.TestCase): @unittest.skipIf(PY3, "builtin input accepts unicode and bytes") def test_assumption(self): """ Test that raw_input() always fails on a unicode string with accented characters. If this is not the case we might not need i18n.input() as a raw_input() wrapper. """ if sys.stdout.isatty(): # Only works when stdout is a terminal (and not captured in some # way, for instance when nosetests is run without the -s switch). self.assertRaises(UnicodeEncodeError, raw_input, UC_TEXT) class TestConversion(tests.support.TestCase): @mock.patch('dnf.i18n._guess_encoding', return_value='utf-8') def test_ucd(self, _unused): s = UC_TEXT.encode('utf8') # the assumption is this string can't be simply converted back to # unicode: u = dnf.i18n.ucd(s) self.assertEqual(u, UC_TEXT) # test a sample OSError, typically constructed with an error code and a # utf-8 encoded string: obj = OSError(17, 'Soubor již existuje') expected = u"[Errno 17] %s" % UC_TEXT_OSERROR self.assertEqual(dnf.i18n.ucd(obj), expected) # ucd() should return unicode unmodified self.assertEqual(dnf.i18n.ucd(expected), expected) def test_download_error_unicode(self): err_map = {"e1": ["x", "y"]} err = dnf.exceptions.DownloadError(err_map) self.assertEqual("e1: x\ne1: y", str(err)) self.assertEqual("e1: x\ne1: y", dnf.i18n.ucd(err)) @mock.patch('locale.getpreferredencoding', return_value='ANSI_X3.4-1968') def test_ucd_acii(self, _unused): s = UC_TEXT.encode('utf8') # ascii coding overridden by utf8 u = dnf.i18n.ucd(s) self.assertEqual(u, UC_TEXT) @mock.patch('dnf.i18n._guess_encoding', return_value='utf-8') def test_ucd_skip(self, _unused): s = UC_TEXT.encode('iso-8859-2') # not decoded chars are skipped u = dnf.i18n.ucd(s) self.assertEqual(u, "ka") class TestFormatedOutput(tests.support.TestCase): def test_fill_exact_width(self): msg = "message" pre = "<" suf = ">" self.assertEqual("%-*.*s" % (5, 10, msg), fill_exact_width(msg, 5, 10)) self.assertEqual("重uř ", fill_exact_width("重uř", 5, 10)) self.assertEqual("%10.5s" % msg, fill_exact_width(msg, 10, 5, left=False)) self.assertEqual("%s%.5s%s" % (pre, msg, suf), fill_exact_width(msg, 0, 5, prefix=pre, suffix=suf)) def test_exact_width(self): self.assertEqual(dnf.i18n.exact_width("重uř"), 4) def test_textwrap_fill(self): msg = "12345 67890" one_line = textwrap_fill(msg, 12) self.assertEqual(one_line, "12345 67890") two_lines = textwrap_fill(msg, 7, subsequent_indent=">>") self.assertEqual(two_lines, "12345\n>>67890") asian_msg = "重重 uř" self.assertEqual(textwrap_fill(asian_msg, 7), asian_msg) asian_two_lines = textwrap_fill("重重\nuř", 5, subsequent_indent=">>") self.assertEqual(asian_two_lines, "重重\n>>uř")