Repository: mgeisler/textwrap (language: rust)

Issue:
Word broken even though it would fit on line
This test case fails, even though the `"qqqqqqqqq"` word is only 9 characters long:
```rust
    #[test]
    fn test_very_ragged() {
        // Example of inputs that produce very ragged output with the
        // greedy algorithm.
        assert_eq!(wrap("a b c d e f g h i j k l m n o p qqqqqqqqq", 10),
                   vec!["a b c d e", "f g h i j", "k l m n o", "p", "qqqqqqqqq"]);
    }
```
It fails with
```
---- tests::test_very_ragged stdout ----
	thread 'tests::test_very_ragged' panicked at 'assertion failed: `(left == right)`
  left: `["a b c d e", "f g h i j", "k l m n o", "p qqqqqqqq", "q"]`,
 right: `["a b c d e", "f g h i j", "k l m n o", "p", "qqqqqqqqq"]`', src/lib.rs:1080:8
```


Discussion / hints:
Bisecting shows that this was introduced back in version 0.7.0 in commit 4313d5814a2bc70012c1838aee01ee392af4fc8b (_Wrapper::wrap: return Vec<Cow<str>> instead of Vec<String>_).
The above test case can be simplified to just
```rust
#[test]
fn test_very_ragged() {
    assert_eq!(textwrap::wrap("aaabbbccc x yyyzzzwww", 9),
               vec!["aaabbbccc", "x", "yyyzzzwww"]);
}
```


Fix patch:
diff --git a/README.md b/README.md
index 87007338..04e6f413 100644
--- a/README.md
+++ b/README.md
@@ -186,6 +186,10 @@ This section lists the largest changes per release.
 Due to a change in the libc crate, the minimum version of Rust we test
 against is now 1.9.0.
 
+Issues closed:
+
+* Fixed [#99][issue-99]: Word broken even though it would fit on line.
+
 ### Version 0.9.0 — October 5th, 2017
 
 The dependency on `term_size` is now optional, and by default this
@@ -325,5 +329,6 @@ Contributions will be accepted under the same license.
 [issue-59]: https://github.com/mgeisler/textwrap/issues/59
 [issue-61]: https://github.com/mgeisler/textwrap/issues/61
 [issue-81]: https://github.com/mgeisler/textwrap/issues/81
+[issue-99]: https://github.com/mgeisler/textwrap/issues/99
 [issue-101]: https://github.com/mgeisler/textwrap/issues/101
 [mit]: LICENSE
diff --git a/src/lib.rs b/src/lib.rs
index ed30d614..42949926 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -634,6 +634,7 @@ impl<'a> WrapIterImpl<'a> {
             } else if self.line_width + char_width > wrapper.width {
                 // There is no room for this character on the current
                 // line. Try to split the final word.
+                self.in_whitespace = false;
                 let remaining_text = &self.source[self.split + self.split_len..];
                 let final_word = match remaining_text
                           .find(|ch: char| ch.is_whitespace() && ch != NBSP) {
@@ -980,6 +981,14 @@ mod tests {
         assert_eq!(wrap("foo               bar", 5), vec!["foo", "bar"]);
     }
 
+    #[test]
+    fn test_issue_99() {
+        // We did not reset the in_whitespace flag correctly and did
+        // not handle single-character words after a line break.
+        assert_eq!(wrap("aaabbbccc x yyyzzzwww", 9),
+                   vec!["aaabbbccc", "x", "yyyzzzwww"]);
+    }
+
     #[test]
     fn wide_character_handling() {
         assert_eq!(wrap("Hello, World!", 15), vec!["Hello, World!"]);


Test patch: