FCC Speedrun — #2 Pomodoro Clock

Sharad Jain
Chingu
Published in
4 min readJan 6, 2019

If you don’t know about FCC speedrun then you can read about it here. This challenge was taken by our team as a project for chingu winter cohort. You can read the post about our first project here.

First react project for the group

Weather app was fairly straightforward for the group which did not require much technical knowledge and hence we knew what needed to be done from the first day. But, Pomodoro project had so much going on that we did not know where to start.

I re-read user stories and requirements several times and also looked at some amazing implementations online like Pomodoro-tracker and tomatotimers. User stories looked to the point but that did not convey how would the timer work, live apps looked awesome but that not infer how they decided what to show and when. A week later when a teammate finally pushed a commit which was the initial prototype of working clock, it looked wrong as the whole logic resided in a single place “App.js”. But this was crucial in the sense that this initial implementation forced us to re-think and design the app in react way.

Independent React Components

We created a rough diagram and identified each component and properties that it needed. Now, we divided tasks according to components rather than user stories. This gave each of us independent components to work on while integration would happen later in separate tasks. Each component displayed texts or attribute while it was responsible for maintaining that part of the component. e.g. Our session configurator had an increment and a decrement button. Anytime any of the buttons was pressed, this component was responsible for changing its timer value and also pass it on to parent component informing of the change. This became a huge challenge as we had to maintain properties and states in one component while also deciding which one to use and when. This is when we decided to...

Removing states from child components

Component for break length configurator

In break length configurator we were earlier passing start value and then we were also maintaining the state of this value when any of the buttons got pressed. Also, this new value needs to be passed to parent component as well for it to maintain it’s state as well.

Now instead of that, we removed the state and passed display value as a prop and parent component was responsible for maintaining display value whenever a change is communicated from the time configurator component. Our code for this component simplified so much that we were able to reuse this same component for another configurator without much change. Also, it became easier to introduce a new feature like disable which did not need a component’s state.

import React, { Component } from 'react';

class ReusableTimeConfigurationComponent extends Component {

onIncrementButtonClick = () => {
this.props.onChange(this.props.timeLength + this.props.minimumChange)
};

onDecrementButtonClick = () => {
this.props.onChange(this.props.timeLength - this.props.minimumChange)
};

get incrementButtonDisabled() {
return (this.props.timeLength >= this.props.maximumLength || this.props.isDisabled);
}

get decrementButtonDisabled() {
return (this.props.timeLength <= this.props.minimumLength || this.props.isDisabled);
}

get timeString() {
let minutes = Math.floor(this.props.timeLength / 60);
return minutes > 9 ? minutes : ` ${minutes}`
}

render() {
return (
<div className={'length-configuration'}>
<span className={'label'}>{this.props.labelName}</span>

<button className={'decrement btn rounded-button'}
onClick={this.onDecrementButtonClick}
disabled={this.decrementButtonDisabled}>
<span>-</span>
</button>

<span className={'time'}>{this.timeString}</span>

<button className={'increment btn rounded-button'}
onClick={this.onIncrementButtonClick}
disabled={this.incrementButtonDisabled}>
<span>+</span>
</button>
</div>
);
}
}

export default ReusableTimeConfigurationComponent;

Test, Jest, Enzyme and Code coverage

This was my first time using jest and I loved its snapshot feature. Imagine writing assertions for every single word that is displayed on component render with a single “.toMatchSnapshot()”. This was my first test for every component that I wrote, it was easy to review and update.

Code coverage is easy to set up with jest. You need to pass “ — coverage” flag to jest which will report code coverage stats after tests are run. If you are using create react app then tweak test command like this in package.json

"test": "react-scripts test --coverage"
Code coverage on the console

If you want to enforce a code coverage threshold on your team i.e. minimum test coverage percentage on the actual code then you can add these configurations in package.json under jest

"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!<rootDir>/node_modules/",
"!<rootDir>/path/to/dir/"
],
"coverageThreshold": {
"global": {
"branches": 70,
"functions": 85,
"lines": 66,
"statements": 66
}
},
"coverageReporters": [
"text"
]
}
}

This would fail your test command until code coverage thresholds are met. For our case, we updated them with test coverage number we were able to meet but we plan to enforce it to 95% for our next project.

My teammate Denis has also posted on his experience working on this project here.

--

--