diff --git a/.github/workflows/check-pr-size.yml b/.github/workflows/check-pr-size.yml index 5b62fb2..8b730e0 100644 --- a/.github/workflows/check-pr-size.yml +++ b/.github/workflows/check-pr-size.yml @@ -6,7 +6,6 @@ on: jobs: check_pr_size: - if: false runs-on: ubuntu-latest timeout-minutes: 1 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bff7d9b..ea8d238 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,26 +1,43 @@ # Contributing +## Table of Contents + +- [Architecture](#architecture) +- [Code](#code) + - [File template](#file-template) + - [Testing](#testing) + - [Imports](#imports) + - [Use function instead of arrow functions by default](#use-function-instead-of-arrow-functions-by-default) + - [Use object props instead of multiple props](#use-object-props-instead-of-multiple-props) + - [Never use return types if the function infers the type correctly](#never-use-return-types-if-the-function-infers-the-type-correctly) + - [Logger](#logger) + - [Comments](#comments) + - [Frontend](#frontend) + ## Architecture ``` -backend -| core - | logger - | utils -| infra - | drive-server-wip - | sqlite - sqlite.module.ts - | services - function1.ts - function2.ts -| features - | backups - | sync - sync.module.ts - | services - function1.ts - function2.ts +📁 backend + 📁 core + 📁 logger + 📁 utils + 📁 infra + 📁 drive-server-wip + 📁 sqlite + 📄 sqlite.module.ts + 📁 services + 📄 function1.ts + 📄 function2.ts + 📁 features + 📁 backups + 📁 sync + 📄 sync.module.ts + 📁 services + 📄 function1.ts + 📄 function2.ts +📁 frontend + 📁 core + 📁 api ``` ## Code @@ -28,10 +45,7 @@ backend ### File template ```ts -type Props = { - prop1: A; - prop2: B; -}; +type Props = { prop1: A; prop2: B }; export function fn({ prop1, prop2 }: Props) {} ``` @@ -136,3 +150,33 @@ logger.debug({ * Whenever we change something, we should retain the comments from the previous version to see the history of the decision. */ ``` + +### Frontend + +We'll follow a structure similar to Angular's with services and components. The service will be a hook that manages all the logic. Both the service and the component will be stored in the same file. + +```ts +export function useComponent() { + const { t } = useI18n(); + const { data, status } = useCustomHook(); + + const value = useMemo(() => { + switch (status) { + case 'loading': + return t('loading'); + case 'error': + return ''; + case 'success': { + return data; + } + } + }, [status]); + + return { value }; +} + +export function Component() { + const { value } = useComponent(); + return
{value}
; +} +``` diff --git a/docs/TESTING.md b/docs/TESTING.md index 06b818f..a3bc98e 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -1,5 +1,19 @@ # Testing +## Table of Contents + +- [Types](#types) +- [Describe](#describe) +- [Mocks](#mocks) +- [Assert](#assert) +- [Structure](#structure) +- [Frontend](#frontend) + +## Types + +- Unit tests (`service.test.ts`). It just tests the service function inside the file and mocks all other functions. +- Infra tests (`anything.infra.test.ts`). It tests multiple functions and not only a service function or it is a long test. We want to keep these tests in a separate runner so as not to block the main runner with slow tests. + ## Describe Use `name-of-file` in describe. Why? @@ -22,7 +36,7 @@ describe('name-of-file', () => { const depMock = partialSpyOn(depModule, 'dep'); beforeEach(() => { - depMock.mockReturnValue('first'); + depMock.mockReturnValue('value'); }); }); ``` @@ -36,12 +50,12 @@ describe('name-of-file', () => { const depMock = deepMocked(dep); beforeEach(() => { - depMock.mockReturnValue('first'); + depMock.mockReturnValue('value'); }); }); ``` -## Expect +## Assert To check the calls of a depMock we use `call` (just one call) or `calls` (0 or more calls). We use only `toHaveLength`, `toBe`, `toMatchObject` and `toStrictEqual` for assertions. @@ -59,9 +73,14 @@ describe('name-of-file', () => { expect(res).toBe(); expect(res).toMatchObject(); expect(res).toStrictEqual(); + + call(depMock).toBe(); call(depMock).toMatchObject(); + call(depMock).toStrictEqual(); + calls(depMock).toHaveLength(); calls(depMock).toMatchObject(); + calls(depMock).toStrictEqual(); }); }); ``` @@ -79,21 +98,49 @@ describe('name-of-file', () => { let props: Parameters