Skip to content

Code Style

Nick Bolton edited this page Jul 31, 2024 · 52 revisions

Formatting

Our code formatting is enforced via CI which runs the scripts/lint_cmake.py and script/lint_clang.py scripts to ensure that all files match our code style. If your IDE doesn't support formatting, you can use --format on either of those scripts to format your code.

  • CLang (C/C++/Objective-C): .clang-format - LLVM with a few minor tweaks.
  • CMake: cmake-format.yaml - Standard with a few minor tweaks.
  • Python: Use black

Naming

  1. Member variables should be prefixed with m_helloWorld
  2. Pointers should begin with a lower case p, e.g. m_pHelloWorld
  3. Getters should not have get prefixed, e.g. helloWorld()
  4. Setters should have set prefixed, e.g. setHelloWorld(...)
  5. Enum values and constants should begin with k, e.g. kHelloWorld
  6. Class filenames should be pascal case, e.g. HelloWorld.cpp
  7. Files with many classes or functions should be snake case, e.g. hello_world.cpp
  8. Unit test names should follow the function-input-output pattern, e.g. helloWorld_fooIn_barOut
  9. The word "deps" should be used to mean "dependencies"

Qt naming

  1. Qt controls should be named m_p<type><description>, e.g. m_pLabelSpecificThing
  2. Qt signals should indicate that something happened, e.g. somethingHappened
  3. Qt slots should always begin with on
  4. Manual Qt slots should not follow the autoconnection convention (on_foo_bar)
  5. Manual Qt slots should include both the signal origin and signal name, e.g. onOriginSomethingHappened

Organization

  1. .cpp files should be ordered:
    • Copyright
    • Headers
    • using
    • Constants
    • Free functions
    • Class members
  2. Headers should be ordered in separate groups of:
    • Header file for the .cpp file
    • For Qt, the _ui.h file
    • Project header files
    • 3rd party lib and system headers
  3. Getters should be grouped together
  4. Setters should be grouped together
  5. Getters and setters should not be paired

Unit tests

  1. Use ctor dependency injection (e.g. std::function or a Deps struct)
  2. A unit test body should follow the AAA (arrange-act-assert) pattern, e.g.:
    auto foo = "hello";
    auto bar = "world";
    
    auto baz = combine(foo, bar);
    
    EXPECT_EQ(baz, "hello world");
    
  3. A unit test should test only one scenario and expectation
    • Split test scenarios into separate test functions

Exceptions

  1. Do not allow exceptions to propagate to Qt (instead, use qFatal())
    • Remember: qFatal can be ignored on Windows, but not on macOS/Linux
  2. Do use exceptions for exceptional situations (things that should not happen)
  3. Do not use exceptions for validation (e.g. if a user input value is unexpected)
Clone this wiki locally