Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ textwrap = ">=0.13"
serde_yaml = "0.9"
serde = { version = "1", features = ["derive"] }
encoding = "0.2.33"
unicode-general-category = "1"

[target.'cfg(unix)'.dependencies]
nix = { workspace = true, features = ["fs"] }
Expand Down
143 changes: 33 additions & 110 deletions breezy/tests/test_utextwrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,67 +20,38 @@
from .. import tests, utextwrap

# Japanese "Good morning".
# Each character have double width. So total 8 width on console.
_str_d = "\u304a\u306f\u3088\u3046"
# Each character has double width. So total 8 width on console.
_str_d = "おはよう"

_str_s = "hello"

# Combine single width characters and double width characters.
_str_sd = _str_s + _str_d
_str_ds = _str_d + _str_s


class TestUTextWrap(tests.TestCase):
def check_width(self, text, expected_width):
w = utextwrap.UTextWrapper()
self.assertEqual(
w._width(text),
expected_width,
"Width of %r should be %d" % (text, expected_width),
)

def test_width(self):
self.check_width(_str_d, 8)
self.check_width(_str_sd, 13)

def check_cut(self, text, width, pos):
w = utextwrap.UTextWrapper()
self.assertEqual((text[:pos], text[pos:]), w._cut(text, width))

def test_cut(self):
s = _str_sd
self.check_cut(s, 0, 0)
self.check_cut(s, 1, 1)
self.check_cut(s, 5, 5)
self.check_cut(s, 6, 5)
self.check_cut(s, 7, 6)
self.check_cut(s, 12, 8)
self.check_cut(s, 13, 9)
self.check_cut(s, 14, 9)
self.check_cut("A" * 5, 3, 3)

def test_split(self):
w = utextwrap.UTextWrapper()
self.assertEqual(list(_str_d), w._split(_str_d))
self.assertEqual([_str_s] + list(_str_d), w._split(_str_sd))
self.assertEqual(list(_str_d) + [_str_s], w._split(_str_ds))

def test_wrap(self):
def test_wrap_double_width(self):
# A run of double width characters breaks between any two of them.
self.assertEqual(list(_str_d), utextwrap.wrap(_str_d, 1))
self.assertEqual(list(_str_d), utextwrap.wrap(_str_d, 2))
self.assertEqual(list(_str_d), utextwrap.wrap(_str_d, 3))
self.assertEqual(
list(_str_d), utextwrap.wrap(_str_d, 3, break_long_words=False)
)

def test_wrap_mixed_width(self):
# "hello" fills a width-5 line, then the double-width run packs two
# characters per line.
self.assertEqual([_str_s, _str_d[:2], _str_d[2:]], utextwrap.wrap(_str_sd, 5))


class TestUTextFill(tests.TestCase):
def test_fill_simple(self):
# Test only can call fill() because it's just '\n'.join(wrap(text)).
self.assertEqual(f"{_str_d[:2]}\n{_str_d[2:]}", utextwrap.fill(_str_d, 4))

def test_fill_with_breaks(self):
# Demonstrate complicated case.
# Demonstrate a complicated case where double-width characters are
# split across lines while single-width words wrap normally.
text = "spam ham egg spamhamegg" + _str_d + " spam" + _str_d * 2
self.assertEqual(
"\n".join(
Expand All @@ -105,8 +76,7 @@ def test_fill_without_breaks(self):
"spam ham",
"egg",
"spamhamegg",
# border between single width and double
# width.
# border between single width and double width.
_str_d,
"spam" + _str_d[:2],
_str_d[2:] + _str_d[:2],
Expand All @@ -117,7 +87,6 @@ def test_fill_without_breaks(self):
)

def test_fill_indent_with_breaks(self):
w = utextwrap.UTextWrapper(8, initial_indent=" " * 4, subsequent_indent=" " * 4)
self.assertEqual(
"\n".join(
[
Expand All @@ -127,12 +96,12 @@ def test_fill_indent_with_breaks(self):
" " + _str_d[3],
]
),
w.fill(_str_sd),
utextwrap.fill(
_str_sd, 8, initial_indent=" " * 4, subsequent_indent=" " * 4
),
)

def test_fill_indent_without_breaks(self):
w = utextwrap.UTextWrapper(8, initial_indent=" " * 4, subsequent_indent=" " * 4)
w.break_long_words = False
self.assertEqual(
"\n".join(
[
Expand All @@ -141,82 +110,36 @@ def test_fill_indent_without_breaks(self):
" " + _str_d[2:],
]
),
w.fill(_str_sd),
)

def test_fill_indent_without_breaks_with_fixed_width(self):
w = utextwrap.UTextWrapper(8, initial_indent=" " * 4, subsequent_indent=" " * 4)
w.break_long_words = False
w.width = 3
self.assertEqual(
"\n".join(
[
" hello",
" " + _str_d[0],
" " + _str_d[1],
" " + _str_d[2],
" " + _str_d[3],
]
utextwrap.fill(
_str_sd,
8,
initial_indent=" " * 4,
subsequent_indent=" " * 4,
break_long_words=False,
),
w.fill(_str_sd),
)


class TestUTextWrapAmbiWidth(tests.TestCase):
_cyrill_char = "\u0410" # east_asian_width() == 'A'

def test_ambiwidth1(self):
w = utextwrap.UTextWrapper(4, ambiguous_width=1)
s = self._cyrill_char * 8
self.assertEqual([self._cyrill_char * 4] * 2, w.wrap(s))
self.assertEqual(
[self._cyrill_char * 4] * 2, utextwrap.wrap(s, 4, ambiguous_width=1)
)

def test_ambiwidth2(self):
w = utextwrap.UTextWrapper(4, ambiguous_width=2)
s = self._cyrill_char * 8
self.assertEqual([self._cyrill_char * 2] * 4, w.wrap(s))


# Regression test with Python's test_textwrap
# Note that some distribution including Ubuntu doesn't install
# Python's test suite.
try:
from test import test_textwrap

def override_textwrap_symbols(testcase):
# Override the symbols imported by test_textwrap so it uses our own
# replacements.
testcase.overrideAttr(test_textwrap, "TextWrapper", utextwrap.UTextWrapper)
testcase.overrideAttr(test_textwrap, "wrap", utextwrap.wrap)
testcase.overrideAttr(test_textwrap, "fill", utextwrap.fill)

def setup_both(testcase, base_class, reused_class):
super(base_class, testcase).setUp()
override_textwrap_symbols(testcase)
reused_class.setUp(testcase)

class TestWrap(tests.TestCase, test_textwrap.WrapTestCase):
def setUp(self):
setup_both(self, TestWrap, test_textwrap.WrapTestCase)

class TestLongWord(tests.TestCase, test_textwrap.LongWordTestCase):
def setUp(self):
setup_both(self, TestLongWord, test_textwrap.LongWordTestCase)

class TestIndent(tests.TestCase, test_textwrap.IndentTestCases):
def setUp(self):
setup_both(self, TestIndent, test_textwrap.IndentTestCases)


except ImportError:
self.assertEqual(
[self._cyrill_char * 2] * 4, utextwrap.wrap(s, 4, ambiguous_width=2)
)

class TestWrap(tests.TestCase): # type: ignore
def test_wrap(self):
raise tests.TestSkipped("test.test_textwrap is not available.")

class TestLongWord(tests.TestCase): # type: ignore
def test_longword(self):
raise tests.TestSkipped("test.test_textwrap is not available.")
class TestUTextWrapErrors(tests.TestCase):
def test_invalid_width(self):
self.assertRaises(ValueError, utextwrap.wrap, "hello", 0)
self.assertRaises(ValueError, utextwrap.wrap, "hello", -1)

class TestIndent(tests.TestCase): # type: ignore
def test_indent(self):
raise tests.TestSkipped("test.test_textwrap is not available.")
def test_invalid_ambiguous_width(self):
self.assertRaises(ValueError, utextwrap.wrap, "hello", 4, ambiguous_width=3)
Loading
Loading