Table of Contents
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.
I recommend that you create a file with <YOUR_USERNAME>.<NAME_OF_KATA>.ts
and <YOUR_USERNAME>.<NAME_OF_KATA>.spec.ts
for the test. 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.
- Highest number
- Power of two
- Add all numbers
- Filter even numbers
- Alphabetical
- Fruit counter
- Grouper
- Fizz buzz
- Calculator
- Prime numbers
- Caesar's cypher
- Change calculator
- Word wrap
- 99 bottles
- 99 bottles OOP
- Install NodeJS
- Fork project
- Clone your project
git clone https://github.com/cesalberca/katas.git
- cd into it
cd katas
- Install dependencies
npm i
- Run tests
npm test:watch
- Code!
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 <YOUR_USERNAME>.<NAME_OF_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 './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 <YOUR_USERNAME>.<NAME_OF_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.
If you have an interesting solution create a PR to this project with the name of the file like this: <YOUR_USERNAME>.<NAME_OF_KATA>.ts
.