Skip to content

Coding standards

Jelle edited this page Dec 21, 2020 · 17 revisions

Variables

  • We use pascalCase for variables.
  • Global non-constant variables are not allowed.
  • If a variable shouldn't or can't change, we use const to declare it. Otherwise we use let. We never use var.

Indentation

  • We use a tab size of 4 spaces. We use spaces and not tabs.

Functions and control statements

We format functions and control statements like this:

function helloWorld() {
    // empty line
    let helloworld1 = "hi1";
    let helloworld2 = "hi2";
    // empty line
    if(something === 2) {
        // code here
    } else {
        // code here
    }
    // empty line
}

exception - when returning on invalid states

function exception(){
    // no empty line
    if(theFunctionCanReturnInstantly) return;
    // code here
}

Arrow functions

We use arrow functions if we require the this scope. In nested functions it's almost always the case that the this context is required to be captured. This is an example of an arrow function and how we format them:

const self = this;
const arrowFunction = (arg) => {
   assert(self === this);
   return `[example function output] arg: ${arg}`;
}

Vue elements

We format Vue templates like this:

<template>
  <main class="exampleMain">

    <div class="exampleDiv">
      <exampleButton
        attributes="exampleAttribute"
      />
    </div>

    <div class="exampleDiv2">
      <exampleButton2
        attributes="exampleAttribute2"
      />
    </div>

  </main>
</template>

We format Vue scripts like this:

<script>
import example from 'example';

export default {
    name: 'Example',
    components: {
        Example: Example
    },

    data: function() {
        return {
            exampleVariable: exampleValue,
        };
    },
};
</script>

We format Vue styles like this:

<style>
.example_button {
  display: inline-block;
  colour: #FFFFFF;
}

#exampleID{
    width: 700px;
    height: 700px;
    overflow: hidden;
}
</style>

Backend

For the backend we use TypeScript. We try to always define types, and we don't use the any-type unless absolutely neccesary. A function with typescript is formatted like this:

const someFunction = (arg: string) => {
   return `[example] arg:${arg}`;
}

Routes

  • For routes we always use lowercase names
  • It's preferred for the routes to support post-requests instead of get-requests
  • When code in routes has to be re-used alot, middleware is used
  • We don't wrap responses in another object. The response data will just be contained in the body of the response.
  • All routes are clearly commented with apiDoc comments.
  • Routes check cornercases like this example:
    if(yourRequestData === undefined) 
        return res.status(400).json({error: 'Not all fields are present in the post body.'});

Branches

When to branch

  • Whenever creating a functionality another branch should be created.
  • If a functionality composes multiple smaller functions new branches need to be made
  • An exception can be made when the smaller function can be done in a few lines.

Branch naming

  • The name of a branch should be sprint-sprintNumber-functionality-subfunctionality-etc.-...

When to merge

  • A branch should be merged when the functionality is ready.

How to merge

  • For merging a pull request needs to be made and a reviewer needs to be selected.
  • The reviewer needs to test the code and either accept, edit or deny it.
  • If the reviewer does not accept the code and the code isnt easily fixed the code should be denied.
  • If this happens the reviewer needs to clearly state what doesnt work and what has to change.

Comments

Formatting
  • We format clarifying or declaring comments like // comment here
  • For comments that show the scope we use //scope, for example //if.
When to comment
  • We only use scope comments when the scope is hard to read for any programmer. Scope comments are for example //if.
  • For nontrivial calculations a comment is expected that specifies the result of the calculation. For example:
    //calculate length of vector
    var length = Math.sqrt(Math.pow(vec.x,2), Math.pow(vec.y,2));
  • The comments for functions are with specified parameters. For example:
        /**
         * Moves the caret to the desired place. This could be a selection.
         *
         * @param {EditorState} explanation
         * @param {CarotState} explanation
         * @return {number} explanation
         */

Commits

Where to commit
  • All commit should be done on a branch created for a single functionality and the commit has to regard that functionality.
  • An exception is when a bugfix is made regarding other code, this is no problem but it should be mentioned in the commit message.
When to commit
  • You have to commit when you change any functionality, documentation, or fix a bug.
  • A good indicator of a good commit is when you can describe what you did very well in one simple sentence. For example: "set the appearance of the login button to fit blue color theme".
Commit messages
  • For bugfixes we use the [BUGFIX] prefix in commits. The message will specify what bug was fixed.
  • Any other commits need to briefly describe the change made. If the changes can't be briefly described, multiple commits are probably needed to clarify the changes.

Testing

We try to maintain a 80% unit test coverage before merging. Each pull request has to specify how to run the corresponding unit tests.

The goal is to ensure that the master branch is always a working version. These tests help with ensuring this.

Clone this wiki locally