public
Created

Unit Testing Question Code

  • Download Gist
lexicon.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
class Lexicon
Pair = Struct.new(:token, :word)
Direction = %w(north south east west down up left right back)
Verb = %w(go stop kill eat)
Stop = %w(the in of from at it)
Noun = %w(door bear princess cabinet)
 
def initialize()
end
 
def scan(phrase)
word_set = phrase.split(' ')
result = []
for word in word_set
if Direction.include?(word)
result.push(Pair.new(:direction, word))
elsif Verb.include?(word)
result.push(Pair.new(:verb, word))
elsif Stop.include?(word)
result.push(Pair.new(:stop, word))
elsif Noun.include?(word)
result.push(Pair.new(:noun, word))
elsif convert_number(word) != nil
word = convert_number(word)
result.push(Pair.new(:number, word))
else
result.push(Pair.new(:error, word))
end
end
return result
end
def convert_number(s)
begin
Integer(s)
rescue ArgumentError
nil
end
end
end
sentence.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
class ParserError < Exception
end
 
class Sentence
def initialize(subject, verb, object)
# remember we take Pair.new(:noun, "princess") structs and convert them
@subject = subject.word
@verb = verb.word
@object = object.word
end
end
 
def peek(word_list)
begin
word_list.first.token
rescue
nil
end
end
 
def match(word_list, expecting)
word = word_list.shift
if word.token == expecting
word
else
nil
end
end
 
def skip_word(word_list, token)
while peek(word_list) == token
match(word_list, token)
end
end
 
def parse_verb(word_list)
skip_word(word_list, :stop)
if peek(word_list) == :verb
return match(word_list, :verb)
else
raise ParserError.new("Expected a verb next.")
end
end
 
def parse_object(word_list)
skip_word(word_list, :stop)
next_word = peek(word_list)
if next_word == :noun
return match(word_list, :noun)
end
if next_word == :direction
return match(word_list, :direction)
else
raise ParserError.new("Expected a noun or direction next.")
end
end
 
def parse_subject(word_list, subj)
verb = parse_verb(word_list)
obj = parse_object(word_list)
return Sentence.new(subj, veb, obj)
end
 
def parse_sentence(word_list)
skip_word(word_list, :stop)
start = peek(word_list)
if start == :noun
subj = match(word_list, :noun)
return parse_subject(word_list, subj)
elsif start == :verb
# assume the subject is the player then
return parse_subject(word_list, Pair.new(:noun, "player"))
else
return ParserError.new("Must start with subject, object, or verb not: #{start}")
end
end
test_sentence.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
require 'test/unit'
require_relative '../lib/lexicon'
require_relative '../lib/sentence'
 
class SentenceTests < Test::Unit::TestCase
Pair = Lexicon::Pair
def test_peek
assert_equal(peek([Pair.new(:verb, 'go')]), :verb)
end
def test_match
test_list = [Pair.new(:verb, 'go')]
assert_equal(match(test_list, :verb), Pair.new(:verb, 'go'))
big_list = [Pair.new(:verb, 'go'), Pair.new(:noun, 'king'), Pair.new(:stop, 'is')]
assert_equal(match(big_list, :noun), nil)
end
 
def test_skip_word
small_list = [Pair.new(:verb, 'go'), Pair.new(:verb, 'do')]
skip_word(small_list, :verb)
assert_equal([],small_list)
big_list = [Pair.new(:verb, 'go'), Pair.new(:noun, 'king')]
skip_word(big_list, :verb)
assert_equal([Pair.new(:noun, 'king')], big_list)
end
def test_parse_verb
list_one = [Pair.new(:verb, 'go'), Pair.new(:noun, 'king')]
assert_equal(parse_verb(list_one), Pair.new(:verb, 'go'))
list_two = [Pair.new(:noun, 'player') ,Pair.new(:verb, 'go'), Pair.new(:noun, 'king')]
assert_raise(ParserError.new("Expected a verb next.")) {parse_verb(list_two)}
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.