Created
November 5, 2012 07:50
-
-
Save ralfw/4015879 to your computer and use it in GitHub Desktop.
Kata Word Wrap mit expliziten Aspekten
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Dynamic; | |
using NUnit.Framework; | |
namespace KataWordWrap | |
{ | |
[TestFixture()] | |
public class test_Wrapper | |
{ | |
[TestCase("word", 4, Result="word")] | |
[TestCase("word", 2, Result="wo\nrd")] | |
[TestCase("word", 3, Result = "wor\nd")] | |
[TestCase("wordword", 3, Result="wor\ndwo\nrd")] | |
[TestCase("word word", 4, Result="word\nword")] | |
[TestCase("word word", 5, Result="word\nword")] | |
[TestCase("word word", 6, Result="word\nword")] | |
[TestCase("word wo-rd", 8, Result = "word wo-\nrd")] | |
[TestCase("word word word", 6, Result="word\nword\nword")] | |
[TestCase("word word word", 11, Result="word word\nword")] | |
public string Wrap_single_text(string text, int maxCols) | |
{ | |
return Wrapper.Wrap(text, maxCols); | |
} | |
[TestCase("word11\nword21", 42, Result = "word11\nword21")] | |
[TestCase("word11 word12\nword21 word22", 10, Result="word11\nword12\nword21\nword22")] | |
public string Wrap_multiple_texts(string text, int maxCols) | |
{ | |
return Wrapper.Wrap(text, maxCols); | |
} | |
[TestCase("lineRemainder", 4, "line", "Remainder")] | |
[TestCase("line", 4, "line", "", Description = "End of text")] | |
[TestCase("line", 5, "line", "", Description = "End of text with not enough chars for full line")] | |
[TestCase("", 1, "", "")] | |
public void Break_off_next_line(string text, int maxCols, string line, string remainder) | |
{ | |
var t = Wrapper.Break_off_next_line(text, maxCols); | |
Assert.AreEqual(line, t.Line); | |
Assert.AreEqual(remainder, t.Remainder); | |
} | |
[TestCase("line", "remainder", "line", "remainder", Description = "Perfect break or word too long for line")] | |
[TestCase("line ", "remainder", "line", "remainder", Description = "Trailing space in line")] | |
[TestCase("line", " remainder", "line", "remainder", Description = "Leading space in remainder")] | |
[TestCase("line w", "ord remainder", "line", "word remainder", Description = "Word split at end of line")] | |
[TestCase("line w-", "ord remainder", "line w-", "ord remainder", Description = "Line ends on word breakpoint")] | |
[TestCase("line w-o", "rd remainder", "line w-", "ord remainder", Description = "Split word at breakpoint")] | |
public void Heal_split_word(string line, string remainder, string linedTrimmed, string remainderTrimmed) | |
{ | |
dynamic parts = new ExpandoObject(); | |
parts.Line = line; | |
parts.Remainder = remainder; | |
var healed = Wrapper.Heal_split_word(parts); | |
Assert.AreEqual(linedTrimmed, healed.Line); | |
Assert.AreEqual(remainderTrimmed, healed.Remainder); | |
} | |
[TestCase("", "line", "line", Description = "First line")] | |
[TestCase("new", "line", "new\nline", Description = "Second to last line")] | |
public void Append_line_to_new_text(string newText, string line, string newTextResult) | |
{ | |
Assert.AreEqual(newTextResult, Wrapper.Append_text(newText, line)); | |
} | |
[TestCase("a", 2, "a")] | |
[TestCase("a b", 3, "a b")] | |
[TestCase("a b", 4, "a b")] | |
[TestCase("a b c", 7, "a b c")] | |
[TestCase("a b c", 6, "a b c")] | |
public void Justify(string line, int maxCols, string justifiedLine) | |
{ | |
Assert.AreEqual(justifiedLine, Wrapper.Justify(line, maxCols)); | |
} | |
[TestCase("text1\ntext2", "text1", "text2")] | |
[TestCase("text", "text", "")] | |
public void Get_next_text(string multitext, string text, string remainder) | |
{ | |
var parts = Wrapper.Get_next_text(multitext); | |
Assert.AreEqual(text, parts.Text); | |
Assert.AreEqual(remainder, parts.Remainder); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Dynamic; | |
namespace KataWordWrap | |
{ | |
// http://codingdojo.org/cgi-bin/wiki.pl?KataWordWrap | |
public class Wrapper | |
{ | |
public static string Wrap(string text, int maxCols) | |
{ | |
return Wrap_multi_text("", text, maxCols); | |
} | |
private static string Wrap_multi_text(string newText, string remainder, int maxCols) | |
{ | |
if (remainder == "") return newText; | |
var parts = Get_next_text(remainder); | |
var wrapped = Wrap_remaining_text("", parts.Text, maxCols); | |
newText = Append_text(newText, wrapped); | |
return Wrap_multi_text(newText, parts.Remainder, maxCols); | |
} | |
internal static dynamic Get_next_text(string multitext) | |
{ | |
dynamic parts = new ExpandoObject(); | |
var eolIndex = multitext.IndexOf("\n"); | |
if (eolIndex < 0) | |
{ | |
parts.Text = multitext; | |
parts.Remainder = ""; | |
return parts; | |
} | |
parts.Text = multitext.Substring(0, eolIndex); | |
parts.Remainder = multitext.Substring(eolIndex + "\n".Length); | |
return parts; | |
} | |
private static string Wrap_remaining_text(string newText, string remainder, int maxCols) | |
{ | |
if (remainder == "") return newText; | |
var parts = Extract_line(remainder, maxCols); | |
parts.Line = Justify(parts.Line, maxCols); | |
newText = Append_text(newText, parts.Line); | |
return Wrap_remaining_text(newText, parts.Remainder, maxCols); | |
} | |
private static dynamic Extract_line(string text, int maxCols) | |
{ | |
var parts = Break_off_next_line(text, maxCols); | |
return Heal_split_word(parts); | |
} | |
internal static string Justify(string line, int maxCols) | |
{ | |
var number_of_spaces_to_insert = maxCols - line.Length; | |
var words = line.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries); | |
var wordIndex = 0; | |
while(words.Length > 1 && number_of_spaces_to_insert>0) | |
{ | |
words[wordIndex] = words[wordIndex] + ' '; | |
number_of_spaces_to_insert--; | |
wordIndex = (wordIndex + 1) % (words.Length-1); | |
} | |
return string.Join(" ", words); | |
} | |
internal static string Append_text(string newText, string line) | |
{ | |
return newText + (newText == "" ? "" : "\n") + line; | |
} | |
internal static dynamic Break_off_next_line(string text, int maxCols) | |
{ | |
var line = text.Substring(0, Math.Min(maxCols, text.Length)); | |
var remainder = maxCols < text.Length ? text.Substring(maxCols) : ""; | |
dynamic parts = new ExpandoObject(); | |
parts.Line = line; | |
parts.Remainder = remainder; | |
return parts; | |
} | |
internal static dynamic Heal_split_word(dynamic parts) | |
{ | |
return Has_a_word_been_split(parts) ? Rejoin_head_of_word_with_body_in_remainder(parts) | |
: Trim_line_and_remainder(parts); | |
} | |
private static bool Has_a_word_been_split(dynamic parts) | |
{ | |
return !parts.Line.EndsWith(" ") && !parts.Remainder.StartsWith(" "); | |
} | |
private static dynamic Rejoin_head_of_word_with_body_in_remainder(dynamic parts) | |
{ | |
return Line_ends_with_syllable(parts.Line) ? Rejoin_syllable(parts) | |
: Rejoin_word(parts); | |
} | |
private static bool Line_ends_with_syllable(string line) | |
{ | |
return line.LastIndexOf("-") > line.LastIndexOf(" "); | |
} | |
private static dynamic Rejoin_syllable(dynamic parts) | |
{ | |
var indexOfLastHyphen = parts.Line.LastIndexOf("-"); | |
if (!parts.Line.EndsWith("-") && indexOfLastHyphen >= 0) | |
{ | |
var headOfSplitWord = parts.Line.Substring(indexOfLastHyphen + 1); | |
parts.Line = parts.Line.Substring(0, indexOfLastHyphen + 1); | |
parts.Remainder = headOfSplitWord + parts.Remainder; | |
} | |
return parts; | |
} | |
private static dynamic Rejoin_word(dynamic parts) | |
{ | |
var indexOfLastSpace = parts.Line.LastIndexOf(" "); | |
if (indexOfLastSpace >= 0) | |
{ | |
var headOfSplitWord = parts.Line.Substring(indexOfLastSpace + 1); | |
parts.Line = parts.Line.Substring(0, indexOfLastSpace).TrimEnd(); | |
parts.Remainder = headOfSplitWord + parts.Remainder; | |
} | |
return parts; | |
} | |
private static dynamic Trim_line_and_remainder(dynamic parts) | |
{ | |
parts.Line = parts.Line.TrimEnd(); | |
parts.Remainder = parts.Remainder.TrimStart(); | |
return parts; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment