# Session 7: Language Dialects and Useful Tools
[slide online](https://hackmd.io/@e8KGkGmbTPWKGH_D_dy9DA/SkbOl-S_o)
---
## Language dialects
### TypeScript > Pros
- Type related bugs can be caught before running the code
- Self-documenting code
- Improved IDE tooling
---
## Language dialects
### TypeScript > Cons
- Extra configuration steps
- You have to write more code
---
## Useful tools
### Node > Motivation
- Being able to run JavaScript outside of the browser
- As a result, JavaScript can be used for:
- Writing useful scripts
- Building backend servers
- Building desktop apps (using tools like [Electron](https://www.electronjs.org/))
- Building smartphone apps (using tools like [React Native](https://reactnative.dev/))
---
## Useful tools
### Node > Setup
1. Install a version manager for Node
- [nvm](https://github.com/nvm-sh/nvm) (Linux / MacOS)
- [nvm-windows](https://github.com/coreybutler/nvm-windows) (Windows)
1. Install the latest LTS version of Node using the version manager
1. Check that Node was properly installed
```
node -v
```
1. Run JavaScript files
```
node index.js
```
---
## Useful tools
### Package manager > Motivation
- Build projects faster using open source libraries
- Manage project dependencies
- Manage project metadata
- Manage project scripts
---
## Useful tools
### Package manager > Options
- [NPM](https://www.npmjs.com/)
- [Yarn](https://yarnpkg.com/)
- [pNpm](https://pnpm.io/)
---
## Useful tools
### Package manager > npm
```
.
├── node_modules/
├── package.json
└── package-lock.json
```
---
## Useful tools
### Package manager > npm
- Initializing project metadata
```
npm init
```
- Installing a package
```
npm install <package>
```
- Installing all packages
```
npm install
```
---
## Useful tools
### Package manager > npm
- Removing a package
```
npm remove <package>
```
- Installing a development package
```
npm install -D <package>
```
- Installing a global package
```
npm install -g <package>
```
---
## Useful tools
### Package manager > npm
- Running a lifecycle script
```
npm <script-name>
```
- Running a custom script
```
npm run <script-name>
```
---
## Useful tools
### Formatter > Motivation
- Make the code more readable
- Improve team collaboration by using a standard convention
- All source control diffs are meaningful (since there is no need for style chages)
- You free up mental bandwidth to focus on more challenging problems
---
## Useful tools
### Formatter > Options
- [Prettier](https://prettier.io/)
- [ESLint](https://eslint.org/) (only some rules)
---
## Useful tools
### Formatter > Prettier setup
1. Install
```bash
npm i -D prettier
```
1. (Optional) Create a `.prettierignore` file
1. (Optional) Add a script to run Prettier in `package.json`
1. (Optional) Add it to your code editor
- [VSCode](https://github.com/prettier/prettier-vscode)
---
## Useful tools
### Formatter > Prettier commands
- Check format without overwriting
```bash
npx prettier --check [file|dir|glob]
```
- Check format AND overwrite the files
```bash
npx prettier --write [file|dir|glob]
```
---
## Useful tools
### Linter > Motivation
- Find possible code problems
- Patterns that look like bugs
- Unnecessary code
- Confusing logic
---
## Useful tools
### Linter > Options
- ESLint
---
## Useful tools
### Linter > ESLint setup
1. Install
```bash
npm init @eslint/config
```
1. (Optional) Install [configuration preset](https://github.com/prettier/eslint-config-prettier#installation)
```bash
npm install --save-dev eslint-config-prettier
```
1. (Optional) Set up the preset in `.eslintrc.[json|js|yml]`
```javascript
{
"extends": [
"some-other-config-you-use",
"prettier"
]
}
```
---
## Useful tools
### Linter > ESLint setup
4. (Optional) Add a script in `package.json` to run ESLint
1. (Optional) Add it to your code editor
- [VSCode](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
---
## Useful tools
### Linter > ESLint commands
- Check code without overwriting
```bash
npx eslint [file|dir|glob]
```
- Check code AND overwrite the files
```bash
npx prettier --fix [file|dir|glob]
```
---
## Useful tools
### Testing libraries > Motivation
- Quality Assurance
- The program works as expected under expected conditions
- The program works as expected under edge cases
- Modifications don't break previous versions
- Documentation
- Simplifies debugging process
---
## Useful tools
### Testing libraries > Types of tests
```mermaid
flowchart TB
0(Software testing)-->1(Automated)
0-->2(Manual)
2-->5(Functional)
1-->3
1-->4
3(Unit tests)
4(e2e/Functional tests)
```
---
## Useful tools
### Testing libraries > Test structure
```mermaid
flowchart LR
0(Arrange)-->1(Act)-->2(Assert)
```
---
## Useful tools
### Testing libraries > Types of libraries
```mermaid
flowchart TB
0(Testing libraries)-->1(Mocks)
0-->2
0-->3
2(Test runner)
3(Assertions)
```
---
## Useful tools
### Testing libraries > Options
- [Jest](https://github.com/facebook/jest)
- [Vitest](https://github.com/vitest-dev/vitest)
- [Jasmine](https://github.com/jasmine/jasmine)
- [Tape](https://github.com/ljharb/tape)
---
## Useful tools
### Testing libraries > Jest installation
1. Install
```bash
npm install --save-dev jest
```
1. (Optional) Add a test script
```javascript
"test": "npx jest"
```
---
## Useful tools
### Testing libraries > Jest configuration
- `jest.config.js|ts|mjs|cjs|json`
- `"jest"` key in `package.json`
- `setupFiles`
- `setupFilesAfterEnv`
- Have access to Jest globals
---
## Useful tools
### Testing libraries > Jest test files
- Patterns matched by default
- `**/__tests__/**/*.[jt]s?(x)`
- `**/?(*.)+(spec|test).[jt]s?(x)`
- Configuration options
- `testMatch: string[]`
- `testRegex: string[]`
- `testPathIgnorePatterns: string[]`
---
## Useful tools
### Testing libraries > Jest commands
- Running the entire test suite
```bash
jest
```
- Running tests in a specific file or directory
```bash
jest path/to/tests
```
---
## Useful tools
### Testing libraries > Jest commands
- Using watch mode
```bash
jest --watch [glob|path]
```
- Collecting coverage
```bash
jest --coverage [glob|path]
```
---
## Useful tools > Testing libraries
### Jest API > Test suite structure
- `it(<description>, <fn>[, <timeout>])`/`test(<description>, <fn>[, <timeout>])`
- `it.only(<description>, <fn>[, <timeout>])`
- `it.skip(<description>, <fn>[, <timeout>])`
- `it.todo(<description>)`
---
## Useful tools > Testing libraries
### Jest API > Test suite structure
- `describe(<description>, <fn>)`
- `describe.only(<description>, <fn>)`
- `describe.skip(<description>, <fn>)`
---
## Useful tools > Testing libraries
### Jest API > Test suite structure
- `beforeAll(<fn>[, <timeout>])`
- `beforeEach(<fn>[, <timeout>])`
- `afterEach(<fn>[, <timeout>])`
- `afterAll(<fn>[, <timeout>])`
---
## Useful tools > Testing libraries
### Jest API > Mocking modules
- `jest.mock(<modulePath>[, <factory>[, <options>]])`
---
## Useful tools > Testing libraries
### Jest API > Mocking functions
- `jest.fn([implementation])`
- `jest.spyOn(<object>, <methodName>[, <accessType])`
---
## Useful tools > Testing libraries
### Jest API > MockFunction type > Mock info
- `<mockFn>.mock.calls`
- `<mockFn>.mock.lastCall`
- `<mockFn>.mock.results`
- `<mockFn>.mock.contexts`
---
## Useful tools > Testing libraries
### Jest API > MockFunction type > Shortcuts
- `<mockFn>.mockReturnThis()`
- `<mockFn>.mockReturnValue(<value>)`
- `<mockFn>.mockReturnValueOnce(<value>)`
- Can be chained
---
## Useful tools > Testing libraries
### Jest API > MockFunction type > Shortcuts
- `<mockFn>.mockResolvedValue(<value>)`
- `<mockFn>.mockResolvedValueOnce(<value>)`
- `<mockFn>.mockRejectedValue(<value>)`
- `<mockFn>.mockRejectedValueOnce(<value>)`
---
## Useful tools > Testing libraries
### Jest API > MockFunction type > Resets
- `<mockFn>.mockReset()`
- `jest.resetAllMocks()`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Basic API
- `expect(<value>)`
- `.toBe(<value>)`
- `.toEqual(<value>)`
- `.toThrow([err|errType|errMsg|errMsgRegex])`
- `.not`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Asynchronous calls
- `.resolves`
- `.rejects`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Asynchronous calls
```javascript
test("resolves to lemon", () => {
return expect(Promise.resolve("lemon")).resolves.toBe("lemon");
});
test("resolves to lemon", async () => {
await expect(Promise.resolve("lemon")).resolves.toBe("lemon");
});
```
---
## Useful tools > Testing libraries
### Jest API > Assertions > Numbers
- `.toBeCloseTo(<number>[, <numOfDigits>])`
- `.toBeGreaterThan(<number>)`
- `.toBeGreaterThanOrEqual(<number>)`
- `.toBeLessThan(<number>)`
- `.toBeLessThanOrEqual(<number>)`
- `.toBeNaN()`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Strings
- `.toMatch(<pattern>)`
- `.toContain(<substring>)`
- `.toHaveLength(<number>)`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Booleans/defined
- `.toBeFalsy()`
- `.toBeTruthy()`
- `.toBeDefined()`
- `.toBeUndefined()`
- `.toBeNull()`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Arrays
- `.toContain(<item>)`
- `.toContainEqual(<item>)`
- `.toHaveLength(<number>)`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Objects
- `.toHaveProperty(<keyPath>[, <value>])`
- `.toBeInstanceOf(<class>)`
- `.toMatchObject(<object>)`
- `<object>` properties can be either values or matchers ([e.g.](https://jestjs.io/docs/expect#tomatchobjectobject))
---
## Useful tools > Testing libraries
### Jest API > Assertions > Function calls
```javascript
expect(<mockFn>).<assertion>
```
---
## Useful tools > Testing libraries
### Jest API > Assertions > Function calls
- `.toBeCalled()`
- `.toBeCalledTimes(number)`
- `.toBeCalledWith(arg1, arg2, ...)`
- `.lastCalledWith(arg1, arg2, ...)`
- `.nthCalledWith(nthCall, arg1, arg2, ....)`
---
## Useful tools > Testing libraries
### Jest API > Assertions > Function calls
- `.toReturn()`
- `.toReturnTimes(number)`
- `.toReturnWith(value)`
- `.lastReturnedWith(value)`
- `.nthReturnedWith(nthCall, value)`
---
## Wrapping up
- Topics covered
- Node
- Package manager
- Formatter
- Linter
- Testing libraries
- Next session
- Coming up...
- Schedule
---
{"metaMigratedAt":"2023-06-17T16:38:46.183Z","metaMigratedFrom":"YAML","title":"Session 7: Language Dialects and Useful Tools","breaks":true,"contributors":"[{\"id\":\"7bc28690-699b-4cf5-8a18-7fc3fddcbd0c\",\"add\":11039,\"del\":223}]"}