Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

TriangleClassifier

  1. Créez le répertoire TP9/ avec la structure suivante :

TP9/
├── include/
│    └── triangle-classifier.h
├── source/
│    ├── triangle-classifier.cpp
│    └── main.cpp
├── tests/
│    ├── include/
│    │    └── triangle-classifier-test.h
│    └── source/
│         ├── triangle-classifier-test.cpp
│         └── main.cpp
└── makefile
  1. Recopiez les codes suivants pour les différents fichiers.

makefile
triangle-classifier.cpp
triangle-classifier.h
source/main.cpp
EXECUTABLE = triangle-classifier
TEST_EXECUTABLE = triangle-classifier-tests

CXX = g++
CXXFLAGS = -std=c++17 -Iinclude
TEST_CXXFLAGS = -std=c++17 -Iinclude -Itests/include

SOURCES = $(wildcard source/*.cpp)
TEST_SOURCES = $(wildcard tests/source/*.cpp)

OBJECTS = $(patsubst source/%.cpp,build/objects/%.o,$(SOURCES))
TEST_OBJECTS = $(patsubst tests/source/%.cpp,build/tests/objects/%.o,$(TEST_SOURCES))

DEPENDENCIES = $(patsubst source/%.cpp,build/dependencies/%.d,$(SOURCES))
TEST_DEPENDENCIES = $(patsubst tests/source/%.cpp,build/tests/dependencies/%.d,$(TEST_SOURCES))

SRC_OBJECTS_NO_MAIN = $(filter-out build/objects/main.o,$(OBJECTS))

all: build/binaries/$(EXECUTABLE)

build:
	mkdir -p build/objects build/dependencies build/binaries build/tests/objects build/tests/dependencies build/tests/binaries

build/binaries/$(EXECUTABLE): $(OBJECTS) | build
	$(CXX) $(OBJECTS) -o build/binaries/$(EXECUTABLE)

build/tests/binaries/$(TEST_EXECUTABLE): $(SRC_OBJECTS_NO_MAIN) $(TEST_OBJECTS) | build
	$(CXX) $(SRC_OBJECTS_NO_MAIN) $(TEST_OBJECTS) -o build/tests/binaries/$(TEST_EXECUTABLE)

build/objects/%.o: source/%.cpp | build
	$(CXX) $(CXXFLAGS) -MMD -MF build/dependencies/$*.d -c $< -o $@

build/tests/objects/%.o: tests/source/%.cpp | build
	$(CXX) $(TEST_CXXFLAGS) -MMD -MF build/tests/dependencies/$*.d -c $< -o $@

clean:
	rm -rf build

run:
	./build/binaries/$(EXECUTABLE)

tests: build/tests/binaries/$(TEST_EXECUTABLE)
	./build/tests/binaries/$(TEST_EXECUTABLE)

.PHONY: all build clean run tests

-include $(DEPENDENCIES)
-include $(TEST_DEPENDENCIES)
triangle-classifier-test.cpp
triangle-classifier-test.h
tests/source/main.cpp
#include "triangle-classifier.h"
#include "triangle-classifier-test.h"
#include <iostream>
#include <cassert>

void TriangleClassifierTest::runTests() {
    std::cout << "All tests passed\n";
}
  1. Lisez la documentation de la classe TriangleClassifier.

  2. Implémentez les tests de la fonction classifyTriangle dans triangle-classifier-test.cpp.

  3. Si vous avez bien écrit vos tests, les implémentations fautives suivantes de classifyTriangle ne devraient pas passer tous les tests :

côté négatif non traité
une seule inégalité triangulaire
un triangle équilatéral est isocèle ?
une seule paire de côté traitée
std::string TriangleClassifier::classifyTriangle(int firstSide, int secondSide, int thirdSide) {
    if (firstSide == secondSide) {
		return "isosceles";
    }

	if (firstSide == secondSide && secondSide == thirdSide) {
		return "equilateral";
	}

    return "scalene";
}
  1. Voici une implémentation correcte de la fonction classifyTriangle qui devrait passer tous les tests.

triangle-classifier.cpp
#include "triangle-classifier.h"
#include <string>

static bool isTriangleInvalid(int firstSide, int secondSide, int thirdSide) {
    bool hasNonPositiveSide = (firstSide <= 0 || secondSide <= 0 || thirdSide <= 0);

    bool violatesTriangleInequality = (firstSide + secondSide <= thirdSide) || (firstSide + thirdSide <= secondSide) || (secondSide + thirdSide <= firstSide);

    return hasNonPositiveSide || violatesTriangleInequality;
}

static bool isTriangleEquilateral(int firstSide, int secondSide, int thirdSide) {
    return firstSide == secondSide && secondSide == thirdSide;
}

static bool isTriangleIsosceles(int firstSide, int secondSide, int thirdSide) {
    return firstSide == secondSide || firstSide == thirdSide || secondSide == thirdSide;
}

std::string TriangleClassifier::classifyTriangle(int firstSide, int secondSide, int thirdSide) {
    std::string result = "scalene";

    bool isInvalid = isTriangleInvalid(firstSide, secondSide, thirdSide);
    bool isEquilateral = isTriangleEquilateral(firstSide, secondSide, thirdSide);
    bool isIsosceles = isTriangleIsosceles(firstSide, secondSide, thirdSide);

    if (isInvalid) {
        result = "invalid";
    }

    if (!isInvalid && isEquilateral) {
        result = "equilateral";
    }

    if (!isInvalid && !isEquilateral && isIsosceles) {
        result = "isosceles";
    }

    return result;
}
À retenir
  • Écrire des tests unitaires static void sans arguments avec la convention methodName_StateUnderTest_ExpectedBehavior.

  • Utiliser assert dans les tests unitaires pour comparer la sortie attendue et la sortie obtenue d’une fonction.