Skip to content

Coding Guidelines

earonesty edited this page May 9, 2023 · 2 revisions

Coding Guidelines

General

New Projects

  • Master branch must require code reviews and passing tests

  • All new projects must have a full CI pipeline, including linters, tests

  • Coverage enforcement is required (even a ui should be "load checked", etc.)

  • If a project has dependencies, it must use and commit a lockfile of some sort

Object-Oriented Design

  • Avoid global variables & long parameter lists

  • Limit dependencies of an object (entities an object depends on).

  • Limit an object's dependents (entities that depend on an object).

  • Prefer composition over inheritance.

  • Prefer inheritance over callbacks and branches.

  • Prefer small methods. Between one and five lines when it makes sense

  • Prefer small classes with a single, well-defined responsibility. When a
    class exceeds 100 lines, it may be doing too many things.

  • Tell, don't ask.

Opening files, using API's:

  • No system should ever hit the internet/connect to network, open a file that might be on a network drive, etc. ... as a precondition for startup. Missing network/internet needs to be gracefully handled at any time and for any reason.

  • When opening a file or reading data from the internet in any way, assume it contains deliberately constructed malicious data. Write a test to prove that appropriate exceptions are thrown, and are gracefully handled.

  • When doing IPC, assume the other service can be down. Ensure timeouts & failures are handled.

Typescript

  • Start new projects with Typescript
  • Use maps, not objects
  • Minimize state rerendering using mobx (or whatever tool, redux, etc)
  • No default exports
  • No require cycles
  • No relative imports unless necessary to avoid require cycles or if in same folder
  • Filenames for React components should be the name of the primary export (e.g. RootNavigator.tsx)
  • Imports should be sorted via TypeScript Import Sorter (VSCode extension) from 'Michael' [TODO: Extract config for use with other editors]

Testing

  • Avoid testing private methods.

  • Use intermediate assertions about state during test progression.

  • When at all possible, put your debug logs in the test, not in the code.

  • Use both integration tests and unit tests not one or the other.

  • Don't evade coverage checks.

  • It's always better not to use mocks and use fixtures instead where posible

  • Feel free to test with a "temp server" or "fast/inline nostr relay"

  • Feel free to "hot test" or "integration test", but please mark/tag the test so they can be run separately.

  • Ideally, integration tests should not contribute to coverage minimums.

Sqlite

  • [Index foreign keys].

  • Constrain most columns as [NOT NULL].

  • In a SQL view, only select columns you need (i.e., no SELECT table.*).

  • Use an ORDER BY clause on queries where the results will be displayed to a
    user, as queries without one may return results in a changing, arbitrary
    order.

  • Never put meaningful or computed data in the "id" or "primary key" field of a table.

  • Sqlite need not be considered a "relational database", depending on what you're doing with it.

    • Use as key-value store is OK

    • Use as indexed "blob storage" instead of filesystem is OK

CI/CD & Scripts

  • No complex bash scripts. Scripts that are complex enough to need stuff like functions and loops should be moved into a language suitable for complexity and testing, like python or node.

  • No one-off complex scripts. Scripts that manage deployments, requirements, etc should, ideally be abstracted and run in many projects.... rather than each project having its own requirements, versioning and deployments systems. This is especially true for libraries.

Web

  • Avoid rendering delays caused by synchronous javascript hits.

  • Use UTF-8 only

Changes to this document

To add new standards:

  • First make sure your proposal doesn't suck. Coding standards that suck have the following attributes:

  • Open up a slack discussion with at least 3 other devs and propose one or more additions or changes. Include the CTO and the Engineering Manager.

  • Edit this page with the verbiage everyone agrees on.