Day 90: Red, Green, Refactor. Progress

I think I finally made some progress and wrapped my head around TDD. Watching others use Test Driven Development definitely helped to bridge the gap between what I was doing and what is the norm. This approach to coding definitely does not favor beautiful code from the start. It takes a hyper realistic approach and puts functionality at the forefront. It was hard for me to wrap my head around writing tests until I took myself out of the developer position and started thinking like an end user. Once I changed my perspective, I was able to write the test descriptions (which are probably not perfect) without worrying about code. Then I filled in the test expectations with what I thought the code might end up looking like. This was all possible after knowing that I can always refactor without breaking the TDD model.

I still have a lot to learn with TDD implementation but at least I finally made some tangible progress. Now I just need to practice switching between the developer perspective and the end-user perspective. Hopefully that works for me moving forward.

TLDR;

Okay, so here are the highlights of what I did:

  • JavaScript -> Watched videos on Test Driven Development (TDD) to learn what I am missing in the process and how I can implement it successfully in my project. The examples provided in the videos I watched were not the best (tbh) but they did provide some insight into how to execute while using TDD. The “Red, Green, Refactor” mantra was really helpful in connecting the dots for me.
  • Practice -> Continued working on the Battleship project. Finally made some progress by writing the initial tests for the Ship Object. I don’t know if I did everything correctly but so far the “Fail” stage is done. Now to code to make all my tests “Pass”.

Tests

import constructShip from './ship'

/*
 * Ship:
 *  - setCoordinates(array of grid cell coordinates)
 *  - hit(coordinate on the ship that was hit)
 *  - isSunk() -> true / false
 *  - getLength() -> number
 *
 *  Q: What should the constructShip Function (a.k.a. factory) do?
 *  A: It should return a Ship Object.
 *
 *  Q: What should the Ship Object be able to do?
 *  A: It should be able to:
 *     - Provide information about the ship
 *       - Get the status of the ship as Sunken or NOT
 *       - Get the length of the ship
 *
 *     - Set information about the ship
 *       - Set the coordinates of the ship
 *       - Set the position's on the ship as hit
 *  
 *  Q: What arguments do I need to provide to the constructShip 
 *     function to produce a ship object.
 * */

describe('Test Ship Constructor methods and properties', () => {

  test('Can get the length from the ship object', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    expect(testShip.getLength()).toBe(3)
  })

  test('Can hit a position on the ship', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    expect(testShip.hit(0, 0)).toBe(true)
  })

  test('Cannot hit a position that does not exist on the ship', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    expect(testShip.hit(2, 0)).toBe(false)
  })

  test('Can see that the ship is NOT sunk when NOT ALL positions have been hit', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    expect(testShip.isSunk()).toBe(false)
  })

  test('Can see that the ship is sunk when ALL positions have been hit', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    testShip.hit(0,0)
    testShip.hit(0,1)
    testShip.hit(0,2)
    expect(testShip.isSunk()).toBe(true)
  })

  test('Can see that a position on the ship is hit or not', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    testShip.hit(0,0)
    
    expect(testShip.isHit(0,0)).toBe(true)
    expect(testShip.isHit(0,1)).toBe(false)
  })

  test('Can see that the coordinates of the ship have been set', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    expect(testShip.isCoordinatesSet()).toBe(true)
  })

  test('Can see that the coordinates of the ship have NOT been set', () => {
    const testShip = constructShip(3)
    expect(testShip.isCoordinatesSet()).toBe(false)
  })

  test('Can set the coordinates of the ship if they have NOT been set', () => {
    const testShip = constructShip(3)

    expect(testShip.isCoordinatesSet()).toBe(false)

    testShip.setCoordinates([[0,0],[0,1],[0,2]])

    expect(testShip.isCoordinatesSet()).toBe(true)
  })

  test('Cannot set the coordinates of the ship if they HAVE been set', () => {
    const testShip = constructShip(3, [[0,0],[0,1],[0,2]])
    expect(testShip.setCoordinates([[0,1],[0,2],[0,3]])).toThrow('Ship Coordinates have already been set')
  })
})


Goal For Round 7 of the #100DaysofCode Challenge

This is my seventh round of the “#100daysofcode” challenge. I will be continuing my work from round five and round six into round seven. I am currently working through the book “Cracking the Coding Interview” by Gayle Laakmann McDowell. My goal is to become more familiar with algorithms and data structures. This goal was derived from my goal to better understand operating systems and key programs that I use in the terminal regularly e.g. Git. This goal was in turn derived from my desire to better understand the fundamental tools used for coding outside of popular GUIs. This in turn was derived from my desire to be a better back-end developer.

I have no idea if my path is correct but I am walking down this road anyways. Worst case scenario I learn a whole bunch of stuff that will help me out on my own personal projects.