Skip to content

Instantly share code, notes, and snippets.

@nicholasjhenry
Created February 9, 2016 21:49
Show Gist options
  • Select an option

  • Save nicholasjhenry/fdf0ef749051f84fbfb3 to your computer and use it in GitHub Desktop.

Select an option

Save nicholasjhenry/fdf0ef749051f84fbfb3 to your computer and use it in GitHub Desktop.
IODA Wrapper Kata
class Wrapper
def wrap(text, max_line_length)
words = split_words(text)
words = split_long_words(words, max_line_length)
create_lines_from_words(words, max_line_length)
end
private
def split_words(text)
text.split(" ")
end
def create_lines_from_words(words, max_line_length)
words
.each_with_object([[]]) { |word, lines| add_word_to_lines(word, lines, max_line_length) }
.map { |lines| lines.join(" ") }
.join("\n")
end
def split_long_words(words, max_line_length)
words.flat_map do |word|
if word.length > max_line_length
split_long_word(word, max_line_length)
else
word
end
end
end
def split_long_word(word, max_line_length)
(word.length / max_line_length.to_f).ceil.times.map do |i|
word.slice(i * max_line_length, max_line_length)
end
end
def add_word_to_lines(word, lines, max_line_length)
line = lines.last
if (line + Array(word)).join(" ").length <= max_line_length
line << word
else
lines << Array(word)
end
end
end
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.define_derived_metadata do |meta|
meta[:aggregate_failures] = true unless meta.key?(:aggregate_failures)
end
end
RSpec.describe "Acceptance tests" do
it "wraps popular texts" do
wrap(
"The quick brown fox jumps over the lazy dog", 9,
"The quick\nbrown fox\njumps\nover the\nlazy dog"
)
wrap("Mary had a little lamb", 5, "Mary\nhad a\nlittl\ne\nlamb")
end
it "wrap words short than line" do
wrap("zeile1 zeile2", 6, "zeile1\nzeile2")
wrap("zeile1 zeile2", 7, "zeile1\nzeile2")
wrap("zeile1 zeile2", 8, "zeile1\nzeile2")
wrap("zeile1 z zeile2", 8, "zeile1 z\nzeile2")
end
it "wrap words longer than the line" do
wrap("zeile", 5, "zeile")
wrap("zeile1zeile2", 6, "zeile1\nzeile2")
wrap("zeile1zeile2zeile3", 6, "zeile1\nzeile2\nzeile3")
end
end
RSpec.describe "wrapper" do
it "wrap words fitting in line" do
sut = Wrapper.new
result = sut.wrap("zeile1 zeile2", 6)
expect(result).to eq("zeile1\nzeile2")
end
it "split words too long for the line" do
sut = Wrapper.new
expect(sut).to receive("split_long_words").with(%w(zeile1zeile2), 6)
.and_return(%w(zeile1 zeile2))
result = sut.wrap("zeile1zeile2", 6)
expect(result).to eq("zeile1\nzeile2")
end
it "splits string into words at spaces" do
psut = Wrapper.new
result = psut.send(:split_words, "zeile1 zeile2")
expect(%w(zeile1 zeile2)).to eq(result)
end
it "all words fit into a single line" do
psut = Wrapper.new
result = psut.send(:create_lines_from_words, %w(a b), 3)
expect(result).to eq("a b")
end
it "more words than fit into a line" do
psut = Wrapper.new
result = psut.send(:create_lines_from_words, %w(a b c), 3)
expect(result).to eq("a b\nc")
end
it "pass on words fitting in line" do
psut = Wrapper.new
result = psut.send(:split_long_words, %w(a bc), 2)
expect(result).to eq(%w(a bc))
end
it "also split long words" do
psut = Wrapper.new
expect(psut).to receive(:split_long_word).with("bcd", 2).and_return(%w(bc d))
expect(psut).to receive(:split_long_word).with("efgh", 2).and_return(%w(ef gh))
result = psut.send(:split_long_words, %w(a bcd efgh b), 2)
expect(result).to eq(%w(a bc d ef gh b))
end
it "splits long a long word" do
psut = Wrapper.new
result = psut.send(:split_long_word, "abcde", 2)
expect(result).to eq(%w(ab cd e))
end
end
def wrap(text, max_line_length, expected)
sut = Wrapper.new
result = sut.wrap(text, max_line_length)
expect(result).to eq(expected)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment