/katas

TypeScript Katas to practice TDD and programming

Primary LanguageTypeScriptMIT LicenseMIT

Katas

GitHub Workflow Status David GitHub Prettier Coverage

Table of Contents

Introduction

JavaScript/TypeScript Katas you can use to hone your skills as a developer! Try and follow TDD by doing the tests first and then implement the functionality to make that test pass.

Katas

I recommend that you create a file with <NAME>.<KATA>.ts and <NAME>.<KATA>.spec.ts for the test, where <NAME> is the main characteristic of the Kata and <NAME> is the name of the Kata. Only if you find yourself stuck you might check the answer.

You can tackle the Katas in whatever order you may choose. The order specified here has more to do with difficulty of the Kata.

Setup

  1. Fork project on Github
  2. Clone your project git clone https://github.com/<YOUR_USER>/katas.git
  3. Create a branch from main where you'll work, dev for example.
  4. Track remote upstream branch: git remote add upstream https://github.com/cesalberca/katas.git.
  5. To update changes from upstream: git pull upstream main.
  6. To propose changes you have to go to main branch, make a new branch from it, commit changes and then, on Github, make a Pull request from <YOUR_BRANCH> to main. If you want to bring a single commit from your dev branch you can use cherry-pick.
  7. Install NodeJS
  8. cd into it cd katas.
  9. Install dependencies npm i.
  10. Run tests once with npm test (or constantly with npm run test:watch).
  11. Code your solutions inside the directories my-solutions.

Workflow

Always start with the tests. Think about a good great test name and start with the expect. For instance, lets think about a functionality that gives us the highest number of an array.

We create the file <NAME>.<KATA>.spec.ts in highest-number/solutions. A first test could be:

describe('getHighestNumber', () => {
    it('should get the highest number given an array of one number', () => {
        expect(actual).toBe(42)
    })
})

Notice that there isn't even an actual symbol declared. Thinking about the expect first let us focus on the functionality, and the assertion that we want to make.

Now let's finish the test:

import { getHighestNumber } from './src/highest-number'

describe('getHighestNumber', () => {
    it('should get the highest number given an array of one number', () => {
        const given = [42]

        const actual = getHighestNumber(given)

        expect(actual).toBe(42)
    })
})

Time to implement the function getHighestNumber inside a file we create in highest-number/solutions named <NAME>.<KATA>.ts:

export function getHighestNumber(numbers: number[]): number {
    return numbers[0]
}

Perfect! The test passes! Now it's a perfect time to make a commit.

Now, you might think this is utterly incomplete, right? Well, it depends, if all the arrays we received were of one position this function will be perfect. What we should do now, is add another test that makes our assumptions incorrect. And that's what we are going to do:

it('should get the highest number given an array of several numbers', () => {
    const given = [1, 3, 2]

    const actual = getHighestNumber(given)

    expect(actual).toBe(3)
})

Now we run all the tests and we get an error, proving that our function needs to change in order to make the new test pass.

Because we have the previous test, whenever we change the functionality we should run the tests in order to make sure we didn't break the previous functionality:

export function getHighestNumber(numbers: number[]): number {
    let highestNumber = numbers[0]

    for (let i = 0; i < numbers.length; i++) {
        if (numbers[i] > highestNumber) {
            highestNumber = numbers[i]
        }
    }

    return highestNumber
}

Great! Time to commit again. However, we can always improve our code without changing it's functionality. That's what we call refactoring. Let's just do that:

export function getHighestNumber(numbers: number[]): number {
    return numbers.slice().sort()[numbers.length - 1]
}

If we run the tests they should still be green!

Note: We did a slice before sort because sort mutates the original array and we don't want that.

Contributing

If you have an interesting solution create a PR to this project with the name of the file like this: <NAME>.<KATA>.ts.