Code Documentation

O presente artigo serve para explicar todos os tópicos relativos à documentação de código do lado do cliente.

Overview

O code documentation tem como objetivo principal documentar o código desenvolvidos nas várias bibliotecas da camada cliente disponibilizadas pela equipa de framework. Difere de outros tipos de documentação por estar focada na documentação do código e não da arquitetura da aplicação.

É gerada automaticamente, tendo como base a arquitetura de software associada à ferramenta angular e vários comentários que vão sendo deixados ao longo do código.

Utiliza a ferramenta CompoDoc que gera documentação estática na aplicação.

Estrutura da documentação

A documentação é dividida por um Getting started, seguido de um conjunto de secções para os modulos, componentes, diretivas, classes, serviços injetaveis e interfaces terminando numa seção Miscellenous e outra para o Documentation coverage.

Getting started

Overview do projeto onde mostra o número de módulos, componentes, diretivas, serviços, pipes, classes e interfaces e ainda como se relaciona entre si.

Mostra ainda quais as bibliotecas que depende e ainda os passos a seguir para ser consumida.

Modules, Components, Directives, Classes, Injectables and Interfaces

Permite obter mais informações à cerca dos modulos, componenets, directivas, classes, injetáveis e interfaces existentes. Utiliza gráficos e extratos de código fonte seja ele typescript ou html.

Existe um gráfico interativo chamado DOMTree que através de grafos, mostra as várias dependências entre os elementos da DOM e entre os vários componentes angular.

Segue-se um exemplo de um gráfico DOMTree:

Miscellneous

Secção onde se encontra informação relativa a todas as partes da biblioteca que não se enquadram em nenhum das secções faladas anteriormente. São enquadrados os enumeráveis, funções e variáveis que não estão associadas a nenhuma classe.

Documentation coverage

Mostra informação sobre quanto código está coberto por comentários uteis à documentação. É possível ver a percentagem documentada de todo o código ou a percentagem documentada por ficheiro.

A imagem abaixo mostra um extrato do relatório de cobertura de documentação:

Onde se encontra?

Neste momento apenas a biblioteca ngcore usufrui da geração automática de documentação.

Para ter acesso, é necessário seguir os seguintes passos: 1. Aceder à biblioteca; 2. Executar o comando npm generate-docs 3. Aceder à pasta documentation que se foi gerada para a raiz do projeto ngcore 4. Abrir o ficheiro índex.html num browser

Como documentar?

Para documentar basta usar a sintaxe JSDoc tags.

Ao documentar utilizando JSDoc tags, está a disponibilizar um conjunto de comentários que também são interpretados por alguns editores (como o caso do vscode) e que ajudam ativamente no desenvolvimento de código, mostrando informação através da utilização de IntelliSense.

Segue-se um extrato de código que mostra um exemplo de como documentar o código:

export class ViewState {

    /** Id of the draft that the view state is associated with  */
    draftId: string;
    /** DOM Id element which the view is focus  */
    domElementId: string;
    /** Index line in case of the dom element is inside of a grid */
    gridLineIndex: number;
    /** List of expanders that are open  */
    openedExpanders: Array<string>;
    /** Extension Id that is visible  */
    extensionId: string;
    /** Grid Id in case of the dom element is inside of a grid  */
    gridId: string;

    /**   
     * Id of the draft that the view state is associated with
     * @param draftId Id of the draft that the view state is associated with
     * @param elementId DOM Id element which the view is focus
     * @param openedExpanders List of expanders that are open
     * @param extensionId Extension Id that is visible
     * @param gridLineIndex Index line in case of the dom Element is inside of a grid
    */
    constructor(draftId: string, domElementId: string = "", openedExpanders: Array<string> = new Array<string>(), 
                extensionId:string="", gridLineIndex:number = -1, gridId: string = "") {
        this.domElementId = domElementId;
        this.draftId = draftId;
        this.extensionId = extensionId;
        this.gridLineIndex = gridLineIndex;
        this.gridId = gridId;
        if(openedExpanders)
            this.openedExpanders = openedExpanders;
        else
            this.openedExpanders = new Array<string>();
    }

    /**
    * Verifies if two view states are equal
    * @param viewState Object that represents the view state
    * @return true/false it case of the two view states are equal or not
    */
    equals(viewState: ViewState): boolean {
        return viewState && this.draftId === viewState.draftId;
    }

    /**
    * Verifies if two view states are not equal
    * @param viewState Object that represents the view state
    * @return true/false it case of the two view states are equal or not
    */
    notEquals(viewState: ViewState): boolean{
        return !this.equals(viewState);
    }

    /**
    * Removes an expander by it's Id
    * @param expanderID Id of the expander
    */
    removeOpenedExpander(expanderId: string): void{
        this.openedExpanders = this.openedExpanders.filter(exId => exId !== expanderId);
    }

    /**
    * Adds an expander by it's Id
    * @param expanderID Id of the expander
    */
    addOpenedExpander(expanderID: string): void{
        if(expanderID) {
            this.removeOpenedExpander(expanderID);
            this.openedExpanders.push(expanderID);
        }
    }

    /**
    * Verifies if the expander is opened.
    * @param expanderID Id of the expander
    * @return true/false meaning if it is open or not.
    */
    isExpanderOpened(expanderID: string): boolean {
        return this.openedExpanders.find(id => id === expanderID) !== undefined;
    }
}