Skip to content

Commit

Permalink
Merge pull request #11 from onelikeandidie/main
Browse files Browse the repository at this point in the history
Improved Documentaion
  • Loading branch information
Unisergius authored Nov 25, 2023
2 parents 8907b33 + b139c7a commit 8657953
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 24 deletions.
102 changes: 85 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,127 @@
# simple-math-api-exercise

Node.js + express + typescript math api
Node.js + Express + TypeScript math api

Here's a skeleton for us to clone in the 6th fCC meetup in Ikea

## Development

This project requires Node.JS installed, a javascript runtime that runs code
inside a v8 engine without a browser. See more on how to install it at
[nodejs.org](https://nodejs.org/en).

Clone it and start from there.

```sh
git clone https://github.com/Unisergius/simple-math-api-exercise.git
# or over ssh
git clone [email protected]:Unisergius/simple-math-api-exercise.git
```

To install this project's dependencies, you have to run the following command
from a terminal inside the project's directory.

```sh
# change into the git's directory if needed
cd simple-math-api-exercise
# install dependencies
npm install
```

Installs node_modules folder, what some may know it for vendors folder. Express, dotenv, typescript and all its dependencies are installed.
This installs the node dependencies into the node_modules directory, what some
may know them as vendors folder.

Useful links:
The dependencies for this project are bellow with a few links on how they work
and their documentaion:

* [Express 4 API](https://expressjs.com/en/4x/api.html)
* [TypeScript](https://www.typescriptlang.org/)
* [Jest 29.5 Docs](https://jestjs.io/docs/29.5/getting-started)

Compile typescript to dist folder
Node.js executes JavaScript code, but as you can see this project uses
TypeScript as its scripting language. What this means is that our code is type
checked using TypeScript but needs to be compiled for Node.js to be able to
read our code.

To compile the code to JavaScript you can run the build command using npm. This
is actually running the TypeScript compiler using `tsc`, the reason to not
directly run the `tsc` command is that you may not have TypeScript installed
globally in your system. This is actually good since it forces your machine to
run the TypeScript compiler for the verison defined in the dependencies.

```sh
npm run build
```

Run test
Our server is written is Express, a Node.js library that facilitates the
handling of http requests to a server in JavaScript. Our handlers are all
inside of the [index.ts](./index.ts) file. Go take a look.

To start the Express application, run the following command:


```sh
npm run test
npm start
# or if you need to rebuild and run again
npm run build && npm start
```

Run test coverage
To change the `port` the web server runs on, you can create a copy of the
`.env.example` file and rename it to `.env`, then write the port into the
variable.

```sh
npm run test:coverage
```dotenv
PORT=8080
```

Run our Math API
Antoher way to set the port without the need to create a `.env` file is to
set the enviroment variable like bellow

```sh
npm run start
export PORT=8080
npm start
# or just
PORT=8080 npm start
```

----
## Testing

Based on [Setup node express typescript server](https://blog.logrocket.com/how-to-set-up-node-typescript-express/)
Now that we have the basics of how to run the application, we need to test make
the application bullet-proof. This project includes Jest as a dependency and
has some simple tests inside the [__test__](./__test__) directory to make sure
our math library works like intended.

Start from scratch
To just run the tests, run the following command:

```sh
npm init -y
npm run test
```

Jest includes a tool to check if you've covered all of your possible use cases
within your code. This type of checking is called Code Coverage, where your
code is analysed by a software that checks every possible coditional path
inside of your code, then checks which paths your tests actually run through
and when it finishes it outputs a percentage value of how much of your code is
actually covered by test cases. To read more about code coverage, you can read
the [wikipedia article](https://en.wikipedia.org/wiki/Code_coverage).

To run the coverage check, run the following command:

```sh
npm install express dotenv
npm run test:coverage
```

## From Scratch

This project is based on a logrocket article:
[Setup node express typescript server](https://blog.logrocket.com/how-to-set-up-node-typescript-express/),
to start from scratch:

```sh
# Initialize a npm project
npm init -y
# Install deployment dependencies
npm install express dotenv
# Install development dependencies
npm i -D typescript @types/express @types/node
```
```
27 changes: 26 additions & 1 deletion __test__/math.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,36 @@ import {
subtractTwoNumbers
} from '../math.handler';

/*
This file includes a battery of test for the math library we created. Using
Jest, we can describe a group of tests and run them.
@see Jest's Docs: https://jestjs.io/
*/

// 'describe' groups tests so that they appear together when ran
describe('test math handler', (): void => {
// The test function will execute the closure given watching for any errors
// thrown
test('add two numbers', (): void => {
expect(addTwoNumbers(29, 3)).toBe(32);
// This test is simple, what we want to know is if the number 29 and the
// number 3 using this function will result in the number 32. This is a
// very crude test to test our function as it could just be always giving
// out the number 32!
let a = 29, b = 3;
let result = addTwoNumbers(a, b);
// The expect function will return a Jest object with the result we gave it
// to actually test if the result we gave it is what we want, we need to use
// the `toBe` method of the object to assert equality. If the values are not
// equal, an error will be thrown, shown in the Jest cli
expect(result).toBe(32);
// In reality, the 'add two numbers' test would be a group of tests, for
// edge cases, like adding negative numbers, adding numbers with different
// signs, adding floating point numbers, adding NaN numbers, adding
// infinities, passing strings into the parameters or other types.
});

// The following tests have been collapsed for brevety
test('divide two numbers', (): void => {
expect(divideTwoNumbers(10, 2)).toBe(5);
});
Expand Down
39 changes: 36 additions & 3 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,61 @@
import express, { Express, Request, Response } from 'express';
// Import our library
import {
addTwoNumbers,
divideTwoNumbers,
subtractTwoNumbers
} from './math.handler';

/*
This file creates and sets up the routes available to the exposed http server
using express.js
@see Express.js Docs: http://expressjs.com/
*/

// Create the Express application
const app: Express = express();

// This is how you setup a simple GET handler
app.get('/', (req: Request, res: Response) => {
// With express, we can respond with JSON directly without having to
// `JSON.stringify()` response. You might want to do this if you're building
// an API
res.json({ message: 'Hello World!' });
});

// This GET route is very flexible, it will answer any request going to
// `/sum/*/*` and assign the wildcards into the parameters with the key given
app.get('/sum/:a/:b', (req: Request, res: Response) => {
// Extract the request parameters
const { a, b } = { a: req.params.a, b: req.params.b };
// TODO: Error check `a` and `b` for non-numeric values
// Run our sum function from the math library
const sum = addTwoNumbers(Number(a), Number(b));
res.json({ message: 'Sum Operation', operation: 'success', a, b, sum });
// Respond in JSON
res.json({
message: 'Sum Operation',
operation: 'success',
a,
b,
sum
});
});

// Handler for the division route.
app.get('/div/:a/:b', (req: Request, res: Response) => {
const { a, b } = { a: req.params.a, b: req.params.b };
const c = divideTwoNumbers(Number(a), Number(b));
res.json({ message: 'Div Operation', operation: 'success', a, b, c });
const division = divideTwoNumbers(Number(a), Number(b));
res.json({
message: 'Div Operation',
operation: 'success',
a,
b,
c: division
});
});

// Handler for the subtraction route
app.get('/subtract/:a/:b', (req: Request, res: Response) => {
const { a, b } = { a: Number(req.params.a), b: Number(req.params.b) };
const subtraction = subtractTwoNumbers(Number(a), Number(b));
Expand Down
12 changes: 11 additions & 1 deletion math.handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
/*
This file contains our wonderful maths library
@see Math documentation: https://en.wikipedia.org/wiki/Mathematics
*/

const addTwoNumbers = (a: number, b: number): number => a + b;

const divideTwoNumbers = (a: number, b: number): number => a / b;

const subtractTwoNumbers = (a: number, b: number): number => a - b;

export { addTwoNumbers, divideTwoNumbers, subtractTwoNumbers };
export {
addTwoNumbers,
divideTwoNumbers,
subtractTwoNumbers
};
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
"jest": {
"preset": "ts-jest",
"testEnvironment": "node",
"setupFilesAfterEnv": []
"setupFilesAfterEnv": [],
"testPathIgnorePatterns": [
"node_modules/",
"dist/"
]
},
"repository": {
"type": "git",
Expand All @@ -38,4 +42,4 @@
"ts-jest": "^29.0.5",
"typescript": "^5.0.2"
}
}
}
9 changes: 9 additions & 0 deletions server.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import dotenv from 'dotenv';
import { app } from './index';

/*
This file imports the actual routes from our index file
@see ./index.ts
*/

// Import .env file as enviroment variables
dotenv.config();

// Check which port the server should run on
const port = process.env.PORT || 8000;

// Listen on the port to accept http connections
app.listen(port, () => {
console.log(`Server running on port http://localhost:${port}`);
});

0 comments on commit 8657953

Please sign in to comment.