Begin forwarded message: > From: "Wai-Ming S. Li" <WLi / thoughtworks.com> > Date: April 17, 2005 6:51:43 PM CDT > To: submission / rubyquiz.com > Subject: Please Forward: Ruby Quiz Subumission > > > This is my solution to the Madlabs Quiz and the unit tests. > > Best Regards, > Steve Li. > > ----------------------------------------------------------------------- > --------------------------------------------- > Madlibs.rb > class Story > attr_accessor :placeholders > > def initialize(base) > @placeholders = [] > > story_parts = [] > match = Placeholder.getPattern().match(base) > reuseMap = {} > while(match != nil) > story_parts << match.pre_match > placeholderString = match[1] > placeholder = Placeholder.new(placeholderString, > story_parts.size) > > # if name is reused > if reuseMap[placeholder.name] == nil > @placeholders << placeholder > > # if the name is reusable, add it to the reuse table > if placeholder.reusable() > reuseMap[placeholder.name] = placeholder > end > > # replace the placeholder with the system generated position > string > story_parts << get_position_string(story_parts.size.to_s) > else > # for reuse placeholder, > # replace the placeholder with the system generated position > string for the referenced placeholder > story_parts << > get_position_string(reuseMap[placeholder.name].position.to_s) > end > > remaind = match.post_match > match = Placeholder.getPattern().match(match.post_match) > if (match == nil) > story_parts << remaind > end > end > > @base = story_parts.join("") > end > > def to_s > result = @base > @placeholders.each do |placeholder| > > result.gsub! > (Regexp.new(get_position_string(placeholder.position.to_s)), > placeholder.value) > end > return result > end > > def get_position_string(position) > "%%" + position.to_s + "%%" > end > end > > class Placeholder > attr_accessor :name, :display_name, :position, :value > > def initialize(placeholderString, position) > @value = "" > @position = position > > if placeholderString.include?(":") > @name = placeholderString.split(":")[0] > @display_name = placeholderString.split(":")[1] > else > @name = placeholderString > @display_name = placeholderString > end > end > > def getTemplate() > > Regexp.new("\\(\\(\\s*(#{name}|#{name}\\s*: > \\s*#{display_name})\\s*\\)\\)") > end > > def Placeholder.getPattern() > /\(\(([^)]*)\)\)/ > end > > def getValueQuestion() > "Give me #{display_name}: " > end > > def reusable() > name != display_name > end > end > > if $0 == __FILE__ > # read story from standard input > story_string = "" > ARGF.each_line do |line| > story_string += line > end > > # create story > story = Story.new(story_string) > > # request uesr to enter the corresponding value for each placeholder > print "There are #{story.placeholders.size} placeholders.\n" > story.placeholders.each do |placeholder| > print placeholder.getValueQuestion() > placeholder.value = gets().chop() > end > > # display the story > print story.to_s, "\n" > end > > ----------------------------------------------------------------------- > --------------------------------------------- > UnitTest; > MadlibsTest.rb > require 'runit/testcase' > require 'Madlibs' > > class TestMadlibs < RUNIT::TestCase > def testStoryTemplate() > # parse simple story > # e.g. "Our favorite language is ((a gemstone))." > template = "Our favorite language is ((a gemstone))." > story = Story.new(template) > > # should return a Story with symbol name='a gemstome' and > alias=nil > assert_equals(1, story.placeholders.size) > assert_not_nil(story.placeholders[0]) > assert_equals("a gemstone", story.placeholders[0].display_name) > end > > def testStoryTemplateWithAlias() > # parse story with name alias > # e.g. "Our favorite language is ((gem:a gemstone)). We think > ((gem)) is > # better than ((a gemstone))." > template = "Our favorite language is ((gem:a gemstone)). " > template += "We think ((gem)) is better then ((a gemstone))." > story = Story.new(template) > > # should return a Story with 2 symbole > # Symbol 1: name = 'gem' alias='a gemstome' > # Symbol 2: name = 'a gemstome' > assert_equals(2, story.placeholders.size) > assert_not_nil(story.placeholders[0]) > assert_equals("gem", story.placeholders[0].name) > assert_equals("a gemstone", story.placeholders[0].display_name) > assert_not_nil(story.placeholders[1]) > assert_equals("a gemstone", story.placeholders[1].name) > assert_equals("a gemstone", story.placeholders[1].display_name) > end > > def testStoryGeneration() > # give: Our favorite language is ((a gemstone))." > # input: gemstone = Ruby > # result: ur favorite language is Ruby." > String template = "Our favorite language is ((a gemstone))." > story = Story.new(template) > story.placeholders[0].value = "Ruby" > assert_equals("Our favorite language is Ruby.", story.to_s()) > end > > def testStoryGenerationWithAlias() > # given: Our favorite language is ((gem:a gemstone)). > # e think ((gem)) is better than ((a > gemstone))." > # input: gemstone = Ruby, a genstone = Emerald > # given: Our favorite language is Ruby. > # e think Ruby is better than Emerald." > template = "Our favorite language is ((gem:a gemstone)). " > template += "We think ((gem)) is better then ((a gemstone))." > story = Story.new(template) > story.placeholders[0].value = "Ruby" > story.placeholders[1].value = "Emerald" > assert_equals("Our favorite language is Ruby. We think Ruby is > better then Emerald.", story.to_s()) > end > end > > if $0 == __FILE__ > require 'runit/cui/testrunner' > RUNIT::CUI::TestRunner.run(TestMadlibs.suite) > end