Calculadora - um exemplo completo

Agora vamos a um exemplo completo de uma calculadora de áreas.

Para esse exemplo, é necessário o foxmake instalado na sua máquina (ou ele incluído no seu projeto). Acesse a página do projeto em: documentação do foxmake.

Vamos lá:

  1. Crie um o arquivo "calc.h" com o seguinte conteúdo:

    src/calc/calc.h
    #ifndef CALC_H
    #define CALC_H
    
    namespace calc {
    
        double square_area( double side );
    
        double rectangle_area( double base, double height );
    
        double triangle_area( double base, double height );
        
        double circle_area( double radius );
    
    }
    
    #endif
    
  2. Agora crie o seguinte arquivo "calc.cpp" o seguinte conteúdo:

    src/calc/calc.cpp
    #include "calc.h"
    
    #include <cmath>
    
    namespace calc {
        
        double square_area( double side ) {
            return side * side;
        }
    
        double rectangle_area( double base, double height ) {
            return base * height;
        }
    
        double triangle_area( double base, double height ) {
            return ( base * height ) / 2.0f;
        }
    
        double circle_area( double radius ) {
            return M_PI * pow( radius, 2.0f );
        }
    
    }
    
  3. Crie agora o arquivo main.cpp com o seguinte conteúdo:

    src/main.cpp
    #include "calc/calc.h"
    
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    
    int main() {
        cout << "  Calculadora de areas" << endl;
        cout << endl;
        cout << "  (1) Area do quadrado" << endl;
        cout << "  (2) Area do retangulo" << endl;
        cout << "  (3) Area do triangulo" << endl;
        cout << "  (4) Area do circulo" << endl;
        cout << endl;
    
        int op;
        cout << "Informe a opcao >> " << std::flush;
        cin >> op;
    
        cout << endl;
    
        double side;
        double base;
        double height;
        double radius;
        double area;
    
        cout << std::fixed << std::setprecision( 4 );
    
        switch ( op ) {
            case 1:
                cout << "Informe o lado do quadrado: " << std::flush;
                cin >> side;
                
                area = calc::square_area( side );
    
                cout << endl;
                cout << "A area do quadrado eh: " << area << endl;
                break;
            case 2:
                cout << "Informe a base do retangulo: " << std::flush;
                cin >> base;
                cout << "Informe a altura do retangulo: " << std::flush;
                cin >> height;
    
                area = calc::rectangle_area( base, height );
    
                cout << endl;
                cout << "A area do retangulo eh: " << area << endl;
                break;
            case 3:
                cout << "Informe a base do triangulo: " << std::flush;
                cin >> base;
                cout << "Informe a altura do triangulo: " << std::flush;
                cin >> height;
    
                area = calc::triangle_area( base, height );
    
                cout << endl;
                cout << "A area do triangulo eh: " << area << endl;
                break;
            case 4:
                cout << "Informe o raio do circulo: " << std::flush;
                cin >> radius;
                
                area = calc::circle_area( radius );
    
                cout << endl;
                cout << "A area do circulo eh: " << area << endl;
                break;
            default:
                cout << "Voce informou uma opcao invalida." << endl;
        }
    
        cout << endl;
        cout << "Fim do calculo de area..." << endl;
    }
    
  4. Agora vamos criar os arquivos de teste.
    Crie o arquivo "calctests.h" com o seguinte conteúdo:

    test/calc/calctests.h
    #include <xutest/xutest.h>
    
    #include "calc/calc.h"
    #include <cmath>
    
    TEST_CASE( square_area_test, CalcTests ) {
        ASSERT_EQUALS( calc::square_area( 10 ), 100, );
        ASSERT_EQUALS( calc::square_area( -1 ), 1, );
        ASSERT_EQUALS( calc::square_area( 0 ), 0, );
        ASSERT_EQUALS( calc::square_area( 2.5 ), 6.25, );
    }
    
    TEST_CASE( rectangle_area_test, CalcTests ) {
        ASSERT_EQUALS( calc::rectangle_area( 10, 10 ), 100, );
        ASSERT_EQUALS( calc::rectangle_area( -1, 20 ), -20, );
        ASSERT_EQUALS( calc::rectangle_area( 0, 10 ), 0, );
        ASSERT_EQUALS( calc::rectangle_area( 2.5, 10 ), 25, );
    }
    
    TEST_CASE( triangle_area_test, CalcTests ) {
        ASSERT_EQUALS( calc::triangle_area( 10, 10 ), 50, );
        ASSERT_EQUALS( calc::triangle_area( -1, 20 ), -10, );
        ASSERT_EQUALS( calc::triangle_area( 0, 10 ), 0, );
        ASSERT_EQUALS( calc::triangle_area( 2.5, 10 ), 12.5, );
    }
    
    TEST_CASE( circle_area_test, CalcTests ) {
        ASSERT_EQUALS( calc::circle_area( 10 ), M_PI * 100, );
        ASSERT_EQUALS( calc::circle_area( -1 ), M_PI, );
        ASSERT_EQUALS( calc::circle_area( 0 ), 0, );
        ASSERT_EQUALS( calc::circle_area( 2.5 ), M_PI * 6.25, );
    }
    
  5. Agora crie o arquivo "main.cpp" na pasta "test" com o seguinte conteúdo:

    test/main.cpp
    #include "calc/calctests.h"
    
    #include <xutest/xutest.h>
    
    int main() {
        RUN_ALL_TEST_CASES();
        return 0;
    }
    
  6. Agora só falta o arquivo foxmakeFile. Crie ele com o seguinte conteúdo:

    foxmakeFile
    IF os == "windows"
        output.file.name=calculator.exe
    ENDIF
    IF os != "windows"
        output.file.name=calculator
    ENDIF
    
    src.dir=src
    test.dir=test
    build.dir=build
    obj.dir=obj
    bin.dir=bin
    
    IF os != "windows"
        test.linker.params=-ldl -rdynamic
    ENDIF
    
    test.libs=xutest
    

Feito isso você deve ter a seguinte estrutura de arquivos em seu projeto:

calculator
├── foxmakeFile
├── src
│   ├── calc
│   │   ├── calc.cpp
│   │   └── calc.h
│   └── main.cpp
└── test
    ├── calc
    │   └── calctests.h
    └── main.cpp

Agora você pode executar o build com foxmake. Execute o seguinte:

foxmake testbuildall

Você deverá ver a seguinte saída:

Se quiser rodar o projeto, execute:

foxmake buildall
./build/calculator

Se estiver no windows, substitua ./build/calculator por .\build\calculator.exe

Agora você deve ver a seguinte saída:

Como rodar sem o foxmake

Para rodar sem o foxmake, você pode colocar o conteúdo dos testes na pasta src e utilizar os argumentos da linha de comandos para executar os testes caso, por exemplo, seja passado o argumento "test". Vamos ao exemplo. Você pode fazer o seguinte:

#include "test/calctests.h"

#include <xutest/xutest.h>
#include <cstring>

/* Código do main.cpp */

int main( int argc, char* argv[] ) {
    if ( argc == 2 ) {
        if ( strcmp( argv[ 1 ], "test" ) == 0 ) {
            RUN_ALL_TEST_CASES();
            return 0;
        }
    }

    /* Restante do código fonte do main.cpp */
    return 0;
}

Para baixar o exemplo desta página, acesse:

Download: calculator.zip.

Finalizando...

E assim chegamos ao final do exemplo de calculadora de áreas completo. Espero que tenha gostado das aulas e, agora, divirta-se com o xutest e, o foxmake combina muito bem com ele!