From ba3f2a416cab345bf357abc979a77fe80d7058fe Mon Sep 17 00:00:00 2001 From: Evan Martin Date: Wed, 27 Jul 2011 09:59:22 -0700 Subject: ninja.py: fix the new test and pass the test From a patch from Elazar Leibovich . --- misc/ninja.py | 26 +++++++++++++++++++++----- misc/ninja_test.py | 23 +++++++++++++++-------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/misc/ninja.py b/misc/ninja.py index 38b13c9..2c9d818 100644 --- a/misc/ninja.py +++ b/misc/ninja.py @@ -55,12 +55,28 @@ class Writer(object): return outputs def _line(self, text, indent=0): + """Write 'text' word-wrapped at self.width characters.""" + leading_space = ' ' * indent while len(text) > self.width: - space = text.rfind(' ', 0, self.width - 4) - assert space != -1 # TODO: handle if no space found. - self.output.write(text[0:space] + ' $\n') - text = ' ' * (indent+2) + text[space:].lstrip() - self.output.write(text + '\n') + # The text is too wide; wrap if possible. + + # Find the rightmost space that would obey our width constraint. + available_space = self.width - len(leading_space) - len(' $') + space = text.rfind(' ', 0, available_space) + if space < 0: + # No such space; just use the first space we can find. + space = text.find(' ', available_space) + if space < 0: + # Give up on breaking. + break + + self.output.write(leading_space + text[0:space] + ' $\n') + text = text[space+1:] + + # Subsequent lines are continuations, so indent them. + leading_space = ' ' * (indent+2) + + self.output.write(leading_space + text + '\n') def _as_list(self, input): if input is None: diff --git a/misc/ninja_test.py b/misc/ninja_test.py index 555f189..44c6230 100755 --- a/misc/ninja_test.py +++ b/misc/ninja_test.py @@ -20,26 +20,33 @@ from StringIO import StringIO import ninja LONGWORD = 'a' * 10 +INDENT = ' ' class TestLineWordWrap(unittest.TestCase): def setUp(self): self.out = StringIO() - self.n = ninja.Writer(self.out, width=5) + self.n = ninja.Writer(self.out, width=8) def test_single_long_word(self): # We shouldn't wrap a single long word. self.n._line(LONGWORD) - self.assertEqual(LONGWORD, self.out.getvalue()) + self.assertEqual(LONGWORD + '\n', self.out.getvalue()) def test_few_long_words(self): # We should wrap a line where the second word is overlong. self.n._line(' '.join(['x', LONGWORD, 'y'])) - self.assertEqual('x \n' + LONGWORD + '\ny', self.out.getvalue()) - - def test_few_long_words_space(self): - # We should also wrap indented lines. - self.n._line(' '.join(['x', LONGWORD, 'y']), indent=2) - self.assertEqual('x \n ' + LONGWORD + '\n y', self.out.getvalue()) + self.assertEqual(' $\n'.join(['x', + INDENT + LONGWORD, + INDENT + 'y']) + '\n', + self.out.getvalue()) + + def test_few_long_words_indented(self): + # Check wrapping in the presence of indenting. + self.n._line(' '.join(['x', LONGWORD, 'y']), indent=1) + self.assertEqual(' $\n'.join([' ' + 'x', + ' ' + INDENT + LONGWORD, + ' ' + INDENT + 'y']) + '\n', + self.out.getvalue()) if __name__ == '__main__': unittest.main() -- cgit v0.12