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 <NAME>.<KATA>.ts
and <NAME>.<KATA>.spec.ts
for the test, where <NAME>
is the main characteristic of the Kata and <KATA>
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.
- Highest number
- Power of two
- Add all numbers
- Fizz buzz
- forEach
- Filter even numbers
- Flat
- Alphabetical
- Fruit counter
- Grouper
- Range
- Calculator
- Prime numbers
- Caesar's cypher
- Change calculator
- Christmas tree
- Word wrap
- 99 bottles
- Fork project on Github
- Clone your project
git clone https://github.com/<YOUR_USER>/katas.git
- Create a branch from
main
where you'll work,dev
for example. - Track remote upstream branch:
git remote add upstream https://github.com/cesalberca/katas.git
. - To update changes from upstream:
git pull upstream main
. - 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>
tomain
. If you want to bring a single commit from your dev branch you can use cherry-pick. - Install NodeJS
- cd into it
cd katas
. - Install dependencies
npm i
. - Run tests once with
npm test
(or constantly withnpm run test:watch
). - Code your solutions inside the directories
my-solutions
.
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.
If you have an interesting solution create a PR to this project with the name of the file like this: <NAME>.<KATA>.ts
.