Skip to content

Instantly share code, notes, and snippets.

@nwjsmith
Created January 3, 2012 02:19
Show Gist options
  • Save nwjsmith/1553137 to your computer and use it in GitHub Desktop.
Save nwjsmith/1553137 to your computer and use it in GitHub Desktop.
# You write a class called Wrapper, that has a single static function named
# wrap that takes two arguments, a string, and a column number. The function
# returns the string, but with line breaks inserted at just the right places
# to make sure that no line is longer than the column number. You try to break
# lines at word boundaries.
#
# Like a word processor, break the line by replacing the last space in a line
# with a newline.
class Wrapper
WHITESPACE = /\s/
NEWLINE = "\n"
def self.wrap(string, column)
new(string, column).wrap
end
def initialize(string, column)
raise ColumnError, "column must be greater than 1" unless column > 1
@string, @column = string.gsub(WHITESPACE, " "), column
end
def wrap
return @string unless @column <= @string.length
prior_whitespace = nil
line_length = 0
@string.each_char.each_with_index do |character, index|
if character.match(WHITESPACE)
prior_whitespace = index
end
if line_length == @column
if !prior_whitespace.nil?
@string[prior_whitespace] = NEWLINE
line_length = index - prior_whitespace
else
@string[index, 0] = NEWLINE
end
else
line_length += 1
end
end
end
class ColumnError < StandardError; end
end
describe Wrapper do
context ".wrap" do
it "takes a string and a column number" do
expect {
Wrapper.wrap "foo bar", 3
}.not_to raise_error(ArgumentError)
end
context "when the column number is greater than the string's length" do
it "returns the string unmodified" do
Wrapper.wrap("foo bar", 100).should == "foo bar"
end
end
context "when the column number is less than 1" do
it "raises a ColumnError" do
expect {
Wrapper.wrap("foo bar", 0).should == "foo bar"
}.to raise_error(Wrapper::ColumnError)
end
end
context "when there's whitespace at the column number" do
it "replaces the character with a newline" do
Wrapper.wrap("foo bar", 4).should == "foo\nbar"
end
end
context "when there's a word character at the column number" do
it "replaces prior whitespace character with a newline" do
Wrapper.wrap("foo bar baz", 10).should == "foo bar\nbaz"
end
end
context "when there is no whitespace character prior to the column break" do
it "doesn't break at the column" do
Wrapper.wrap("bar", 2).should == "ba\nr"
end
end
it "breaks at each multiple of the column number" do
Wrapper.wrap("foo bar baz", 4).should == "foo\nbar\nbaz"
end
context "when a line is shorter than the column size" do
it "inserts a newline in the appropriate location" do
Wrapper.wrap("baz hello there, ruby hack night", 10).should == "baz hello\nthere,\nruby hack\nnight"
end
end
context "when passed an empty string" do
it "returns an empty string" do
Wrapper.wrap("", 2).should == ""
end
end
context "when passed a string with a non-printed character" do
it "breaks it as if it were whitespace" do
Wrapper.wrap("foo\0 bar", 4).should == "foo\0\nbar"
end
end
context "when passed a string with a newline character" do
it "treats the newline as a wordbreak" do
Wrapper.wrap("word\nword word", 9).should == "word word\nword"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment