Skip to content

Latest commit

 

History

History
304 lines (281 loc) · 21.7 KB

STANDARDS.md

File metadata and controls

304 lines (281 loc) · 21.7 KB

Coding Standards

This page is our at-a-glance master list of all of our coding standards.

ID Scheme

This is guided by the idea that good conversations are impossible if it isn't clear which standard(s) are being discussed.

  • Every coding standard as a unique ID.
  • Once assigned, this ID will not change.
  • If the meaning of the coding standard changes over time, it will be given a new ID.
  • Our IDs numeric, and use the x.y.z structure:
    • x is the impact level
      • 1. for key
      • 2. for major
      • 3. for minor
    • y is the category
      • numbers are assigned in the order that we invent the categories
    • z is the next available number in that category

Impact Levels

This is guided by the idea that, "if everything is top priority, then nothing is top priority."

We've split the coding standards up into three different levels of importance.

Level Description
Key These are the items that define our purpose.
Major Getting these right first time avoids significant bugs, expensive rework, and backwards-compatibility breaks.
Minor These are consistency / stylistic / philosophical points.

Categories

To make it easier to find things, we've broken up the coding standards into these groups:

Category ID Description
Coding Conventions .9. Ensures a consistent coding style over time.
Data Guarantees .11. Ensures end-users can enforce data contracts reliably.
Data Guards .12. Ensures end-users and maintainers can build data guarantees reliably.
Documentation .1. Helps end-users and the maintainers understand the what, the how, and the why.
Errors .2. Ensures our code handles failure in a consistent, production-friendly manner.
Functions .8. Ensures consistent behaviour from our public module API (and our internal API too).
Naming Conventions .3. Ensures a consistent and tidier public module API (and our internal API too).
Package Management .4. Ensures a consistent approach to packages over time.
Protocols & Extensions .10. Ensures a consistent approach to extending types.
Smart Constructors .14. Ensures our types really are safe types.
Types .6. Ensures our types make for great building blocks.
Type Guarantees .13. Ensures end-users and maintainers can enforce type contracts reliably.
Type Guards .7. Ensures end-users have the type guards they need when they need them.
Unit Tests .5. Ensures we ship less bugs and regressions.

Here they are, listed by ID order too:

Category ID Description
Documentation .1. Helps end-users and the maintainers understand the what, the how, and the why.
Errors .2. Ensures our code handles failure in a consistent, production-friendly manner.
Naming Conventions .3. Ensures a consistent and tidier public module API (and our internal API too).
Package Management .4. Ensures a consistent approach to packages over time.
Unit Tests .5. Ensures we ship less bugs and regressions.
Types .6. Ensures our types make for great building blocks.
Type Guards .7. Ensures end-users have the type guards they need when they need them.
Functions .8. Ensures consistent behaviour from our public module API (and our internal API too).
Coding Conventions .9. Ensures a consistent coding style over time.
Protocols & Extensions .10. Ensures a consistent approach to extending types.
Data Guarantees .11. Ensures end-users can enforce data contracts reliably.
Data Guards .12. Ensures end-users and maintainers can build data guarantees reliably.
Type Guarantees .13. Ensures end-users and maintainers can enforce type contracts reliably.
Smart Constructors .14. Ensures our types really are safe types.

Impacted Areas

Coding standards must not exist for the sake of it. Each critera must address an issue in one (or more) of these areas:

Area Impact
Adoption These issues make it harder for people to use our projects in their own work.
Contributions These issues make it harder for people to contribute to our projects.
Correctness These issues make it harder to write code that works as intended.
Governance These issues make it harder to run the project.
Project Maintenance These issues make it harder to keep code up-to-date.
Robustness These issues make it harder to write code that copes with the unexpected or unintended.
Security These issues lead to breaches in data or unauthorised actions.
Testability These issues make it harder to provide meaningful tests.

Key Criteria

Priority ID Category Criteria Impacts
Key 1.2.1 Errors Every function that has error conditions must accept an OnError handler. Adoption, Robustness
Key 1.2.2 Errors Only throw AppErrors. Adoption, Robustness
Key 1.3.1 Naming Conventions All names must be racially-neutral. Adoption
Key 1.4.1 Package Management Do not ship any code that isn't for production use. Project Maintenance, Security
Key 1.5.1 Unit Tests All code must have 100% code coverage. Adoption, Contributions, Correctness, Project Maintenance, Robustness
Key 1.6.1 Types All instantiable types must have a smart constructor. Robustness
Key 1.6.2 Types Every instantiable type must have a type guard. Adoption, Robustness, Testability
Key 1.6.3 Types Every instantiable type must have a type guarantee. Adoption, Robustness, Testability

Major Criteria

Priority ID Category Criteria Impacts
Major 2.3.1 Naming Conventions All functions and methods that return a function must be called buildXXX(). Adoption
Major 2.3.2 Naming Conventions All smart constructors must be prefixed with makeXXX(). Adoption
Major 2.3.3 Naming Conventions All type guards must be prefixed with isXXX(). Adoption
Major 2.3.4 Naming Conventions All type guarantees must be prefixed with mustBeXXX(). Adoption
Major 2.4.1 Package Management Export the entire public API from the API's top-level index file. Adoption, Project Maintenance
Major 2.5.1 Unit Tests Use mocks as a last resort. Correctness, Project Maintenance, Robustness
Major 2.6.1 Types All base classes must have a protected constructor. Robustness, Project Maintenance
Major 2.6.2 Types All generic types must provide an AnyXXX type. Adoption, Robustness
Major 2.6.3 Types All public constructors must be smart constructors. Adoption, Robustness
Major 2.7.1 Type Guards Type guards must not accept the any type. Use unknown instead. Robustness
Major 2.8.1 Functions All function signatures must follow the same pattern. Adoption, Correctness, Robustness, Testability
Major 2.8.2 Functions Functions should use dependency injection. Adoption, Testability
Major 2.8.3 Functions Every mandatory dependency must be a named function parameter. Correctness
Major 2.8.4 Functions Every user-supplied input must be a named parameter. Adoption, Correctness
Major 2.8.5 Functions Avoid optional user-supplied inputs. Adoption, Project Maintenance, Testability
Major 2.8.6 Functions User-supplied options must be a single options parameter. Project Maintenance
Major 2.8.7 Functions Every property of the user-supplied options parameter must be optional. Project Maintenance
Major 2.8.8 Functions Ever user-supplied option must have a default value. Adoption, Testability
Major 2.8.9 Functions Functional options must be captured as a rest parameter. Adoption
Major 2.8.10 Functions Define DEFAULT_OPTIONS for every function that cannot meet 2.8.7.
Major 2.10.1 Protocols and Extensions Every protocol interface must define an implementsXXX() method. Adoption, Robustness

Minor Criteria

Priority ID Category Criteria Impacts
Minor 3.1.1 Documentation Every exported item must have a docblock. Adoption, Project Maintenance
Minor 3.1.2 Documentation Docblocks must begin with the name of the item they document. Adoption
Minor 3.1.3 Documentation Docblocks must use whole sentences. Adoption
Minor 3.1.4 Documentation Docblocks must use Typedoc tags. Adoption, Contributions, Project Maintenance
Minor 3.1.5 Documentation Write docblocks for overridden methods. Adoption
Minor 3.1.6 Documentation Write docblocks for methods inherited from interfaces. Adoption
Minor 3.3.1 Naming Conventions Every function or method must start with <verb><noun>. Adoption
Minor 3.3.2 Naming Conventions Use camelCase for all function names. Adoption, Contributions
Minor 3.3.3 Naming Conventions Use camelCase for all variable names. Adoption, Contributions
Minor 3.3.4 Naming Conventions Use SCREAMING_SNAKE_CASE for all constants. Adoption, Contributions
Minor 3.3.5 Naming Conventions Use PascalCase for all interface names. Adoption, Contributions
Minor 3.3.6 Naming Conventions Use camelCase for all interface property names. Adoption, Contributions
Minor 3.3.7 Naming Conventions Use PascalCase for all class names. Adoption, Contributions
Minor 3.3.8 Naming Conventions Use camelCase for all class property names. Adoption, Contributions
Minor 3.3.9 Naming Conventions Prefix private and protected class attributes with an underscore. Adoption, Contributions
Minor 3.3.10 Naming Conventions All Error class names must end with Error. Adoption, Contributions
Minor 3.3.11 Naming Conventions All user-supplied option classes/interface names must end with Options. Adoption, Contributions
Minor 3.3.12 Naming Conventions Do not name anything blacklist or whitelist. Adoption
Minor 3.3.13 Naming Conventions All default options must be called XXX_DEFAULT_OPTIONS. Adoption, Project Maintenance
Minor 3.3.14 Naming Conventions All default values must be called DEFAULT_XXX. Adoption
Minor 3.4.1 Package Management Every module folder must have an index file. Project Maintenance
Minor 3.4.2 Package Management Index files must only export the public API. Adoption, Project Maintenance
Minor 3.4.3 Package Management Put each safe type into its own folder. Project Maintenance
Minor 3.4.4 Package Management Put exported classes in their own files. Contributions, Project Maintenance
Minor 3.4.5 Package Management Put exported functions in their own files. Contributions, Project Maintenance
Minor 3.4.6 Package Management Put exported types in their own files. Contributions, Project Maintenance
Minor 3.4.7 Package Management Put exported default values in their own file. Contributions, Project Maintenance
Minor 3.5.1 Unit Tests Put fixtures into a folder called _fixtures. Project Maintenance
Minor 3.6.1 Types Every interface that is meant to be implemented must define an implementsXXX() method. Robustness
Minor 3.6.2 Types Do not create static factory methods. Adoption, Project Maintenance
Minor 3.7.1 Type Guards Every type guard must have a unit test that proves it is a type predicate. Robustness
Minor 3.8.1 Functions Create a type for your function's user-supplied options. Adoption
Minor 3.8.2 Functions Limit user-supplied options to optional dependencies. Correctness, Project Maintenance, Testability
Minor 3.8.3 Functions Use DEFAULT_DATA_PATH for all optional data path parameters. Adoption