sampi / kiwisson

kiwisson - T9 predictive text technology
https://kiwisson.sampi.io/
0 stars 0 forks source link

Build Status Greenkeeper badge Commitizen friendly

kiwisson

kiwisson is a small web app that emulates T9 predictive text technology. Typing numbers will be predicted to become words and with the * key, alternative suggestions can be shown.

View Demo - https://kiwisson.sampi.io/

kiwisson

Getting started

Installation

create-react-app

The app is bootstrapped using the create-react-app toolkit so if you're familiar with it, you can jump in right away.

Getting the code

To serve the app on your local machine, you need to run the following commands:

git clone git@github.com:sampi/kiwisson.git
cd kiwisson
npm ci

Starting the app

Now you're ready to start the app!

npm start

localhost:3000 will open automatically in your browser and you can start using the app.

Testing

Running tests

Unit tests

kiwisson uses Jest for unit testing and all elements are rendered by React. Because this is such a small project and all the components are quite tightly coupled, there was no need to use shallow DOM rendering.

To run the unit tests:

npm run test

If you're into fancy colorful code coverage tables:

npm run test -- --coverage

Integration tests

kiwisson uses Cypress for integration tests.

To run the integration tests:

npm run build && npm run test:cypress

You can also see previous runs on the Cypress Dashboard

Testing strategy

Because this app is very simple, the React components themselves didn't need too much testing.

Each component has at least one simple test to make sure it renders without crashing. If there is any functionality within the app that would warrant testing, because it's not functionality of React itself, then there is at least one test covering that feature.

For integration testing, the whole UI is tested, but it looks very similar to the unit tests of the mock server.

Continuous integration

Every time code is pushed to the master branch or a PR is created, unit and integration tests are triggered, in addition to pushing the latest code GitHub Pages and tagging releases with Semantic Release if a new version is warranted.

Deployment

To create an optimized production build of the app, just run:

npm run build

This will create a minified version of the page in /build and it doesn't require a backend to run.

GitHub Pages

The app is hosted on GitHub Pages and it's really easy to update what is served from there, just run:

npm run deploy
Semantic Release

This repository follows the Commitizen commit guidelines, and enforces them using commitlint. This way, it's easy to tell programmatically when to bump the version and what to bump it to. It also helps to generate the changelog and create a GitHub release. Whenever code is merged to the master branch, Semantic Release will parse new commits and will publish a release if necessary.

I personally feel that this type of restriction on commit messages is a bit too much, but I also understand that it's valuable to have a consistent style of commits from all developers and to be able to easily generate version numbers automatically.

Structure

I prefer to organize files by domain and not by type, so you won't find the classic components and containers folders in this app! Especially not, if it's this small of a project.

CSS

Due to the size and complexity of this project, there was no need to use any CSS methodologies, so I went with the simplest solution. I am using CSS Custom Properties, to have all variables, that might require tweaking and are repeated across the code, in a single place. I didn't want to eject to add PostCSS plugins that transform code using CSS Custom Properties to include hardcoded values as well, so IE11 support is dropped.

The app is sort of responsive, as long as the aspect ratio doesn't go above 860/962, the UI scales with the browser. If it does get wider than this configuration, the keyboard and screen will be locked to the middle of the screen and margins will stretch on both sides.

Technologies

Things that didn't make it

I have overestimated the amount of free time I will have for this project, so some of the things I really wanted to do didn't happen.

Here's a list of things that didn't make it:

The task

Task description

The task was to implement a number to word list converted in the style of T9 with a React frontend and optionally a Node backend.

My solution

I started by imagining how I would like this app to look like, and decided that imitation a retro phone would be fitting.

I set up a basic create-react-app project and started with the keyboard and a screen. I've added some styling to it until it looked alright. I knew I wanted to use Hooks, and I've discovered that Context will also fit here perfectly.

I then wrote the unit tests and set up the CI build pipeline.

In the end, I've added comments, integration tests and wrote this README.

It was fun to make something that looks ugly on purpose and to stack so many backgrounds and box-shadows on top of each other to create a weird "real" feeling.

The code itself is kind of short, but I've tried to explain all of my reasoning in this file, I hope that it will all make sense.