Manasi Salvi

TDD Lesson 2

This month’s blogging has been a little slow because it is taking a while for me to get my head around TDD. I have no complaints though because this has been another steep learning curve requiring a significant amount of external research.

Continuing on from the last post, I have been working through writing the code for a given test with two assertions. In this post I’m working through the second assertion - which took a while.

To recap the test was: test_lexicon.rb

require 'ex48/lexicon.rb'
require "test/unit"

class TestLexicon < Test::Unit::TestCase

  def test_directions()
    assert_equal(Lexicon.scan("north"), [['direction', 'north']])
    result = Lexicon.scan("north south east")

    assert_equal(result, [['direction', 'north'],
           ['direction', 'south'],
           ['direction', 'east']])
  end
end

The corresponding code that I wrote was: lexicon.rb

class Lexicon

	 	@@hash = {
	 		'direction' => ['south', 'north', 'east']
		}

	def self.scan(sentence)
		words = sentence.split(' ')
		result = [] # this array should contain arrays of [key word]

		words.each do |word|
			element = [] # push this array of [key,word] to the result array
				@@hash.each do |key, value|
					if value.include?(word)
					element = [key, word]
					result.push(element) 
					end
				end
		end
				return result
	end
		
end

The error I kept receiving was:

Started
F
===========================================================================================================================
/Users/wickinot/Code/learnrubythehardway/ex48/tests/test_lexicon.rb:11:in `test_directions'
      8:     assert_equal(Lexicon.scan("north"), [['direction', 'north']])
      9:     result = Lexicon.scan("north south east")
     10: 
  => 11:     assert_equal(result, [['direction', 'north'], 
     12:     	['direction', 'south'],['direction', 'east']])
     13:   end
     14: end
<[["direction", "north"]]> expected but was
<[["direction", "north"], ["direction", "south"], ["direction", "east"]]>

diff:
? [["direction", "north"], ["direction", "south"], ["direction", "east"]]
Failure: test_directions(TestLexicon)
===========================================================================================================================

Finished in 0.008249 seconds.
---------------------------------------------------------------------------------------------------------------------------
1 tests, 1 assertions, 1 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
---------------------------------------------------------------------------------------------------------------------------
121.23 tests/s, 121.23 assertions/s
rake aborted!

The reason for the error was that the code was not pushing the element array to the result array. This is because I missed that I never specified the element array. To figure out the solution I did do a lot of research on the internet and also came across another excellent resource - a book called Eloquent Ruby by Russ Olsen. Though these resources did not give me the answer to the solution, they did make me research and understand hashes and arrays and iteration on a deeper level. For example, the hash code is a lot less repetitive.

TDD Lesson 1

For the last two weeks I have been working on test driven development (or TDD). It has been a challenging experience working my way through exercise 48 - building a Lexicon.

So far I’ve only written code for the first ‘asser_equal’ in the test provided in the book. Here are the learnings so far:

Tackling the first two points took me the longest. Once I had that figured out, the coding part became much easier. This is only step one of the problem so far - more to come!

The test was: test_lexicon.rb

require 'ex48/lexicon.rb'
require "test/unit"

class TestLexicon < Test::Unit::TestCase

  def test_directions()
    assert_equal(Lexicon.scan("north"), [['direction', 'north']])
    result = Lexicon.scan("north south east")

    #assert_equal(result, [['direction', 'north'],
           ['direction', 'south'],
           ['direction', 'east']])
  end
end

The corresponding code that I wrote was: lexicon.rb

#split sentence/user input into words
#take each of the words and #if word matches the value in the direction hash, 
#wrong : return it as an array of array with (word, [[direction, word]]) pairing.
#right: return an array of [value, word]
#right: push this array to the empty mega array of arrays.
#make sure to return result

class Lexicon
	 	@@hash = {
			'north' => 'direction',
			'south' => 'direction',
			'east' => 'direction'
		}

	def self.scan(sentence)
		words = sentence.split
		result = []

		words.each do |word|
			@@hash.each do |key, value|
				if key.include?(word)
					element = [value, word]
					result.push(element)
				end
				return result
			end
		end
	end
end