~aleteoryx/muditaos

aad6c64a54471c693ca4760ed352b2b4979432a0 — Piotr Tański 5 years ago f611184
[EGD-6415] Do not silently crash on empty image name

Image should not silently crash with empty or incorrect image name.
M enabled_unittests => enabled_unittests +4 -0
@@ 162,6 162,10 @@ TESTS_LIST["catch2-gui"]="
    gui::Item on input flow test;
    gui::Window on input flow test;
    Set size tests;
    Constructing with empty image name;
    Setting an empty image name;
    Setting an incorrect image name;
    Setting an incorrect image id;
    Parsing English input language;
    Parsing numeric keyboard;
    Getting charKey after clicking button twice;

M module-gui/gui/core/ImageManager.cpp => module-gui/gui/core/ImageManager.cpp +11 -6
@@ 1,4 1,4 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

/*


@@ 203,17 203,22 @@ namespace gui

    ImageMap *ImageManager::getImageMap(uint32_t id)
    {
        if (id >= imageMaps.size())
            return nullptr;
        if (id >= imageMaps.size()) {
            LOG_FATAL("Unable to find an image by id: %" PRIu32, id);
            throw ImageNotFound{"Image could not be found."};
        }
        return imageMaps[id];
    }
    uint32_t ImageManager::getImageMapID(const std::string &name)
    {
        for (uint32_t i = 0; i < imageMaps.size(); i++) {
            if (name.compare(imageMaps[i]->getName()) == 0)
        for (uint32_t i = 0; i < imageMaps.size(); ++i) {
            if (imageMaps[i]->getName() == name) {
                return i;
            }
        }
        return 0;

        LOG_FATAL("Unable to find an image: %s", name.c_str());
        throw ImageNotFound{"Image could not be found."};
    }

} /* namespace gui */

M module-gui/gui/core/ImageManager.hpp => module-gui/gui/core/ImageManager.hpp +7 -12
@@ 1,15 1,7 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

/*
 * ImageManager.hpp
 *
 *  Created on: 18 maj 2019
 *      Author: robert
 */

#ifndef GUI_CORE_PIXMAPMANAGER_HPP_
#define GUI_CORE_PIXMAPMANAGER_HPP_
#pragma once

#include <vector>
#include <string>


@@ 20,6 12,11 @@

namespace gui
{
    class ImageNotFound : public std::runtime_error
    {
      public:
        using std::runtime_error::runtime_error;
    };

    class ImageManager
    {


@@ 50,5 47,3 @@ namespace gui
    };

} /* namespace gui */

#endif /* GUI_CORE_PIXMAPMANAGER_HPP_ */

M module-gui/gui/widgets/Image.cpp => module-gui/gui/widgets/Image.cpp +18 -6
@@ 3,11 3,11 @@

#include "Image.hpp"
#include "DrawCommand.hpp"
#include "PixMap.hpp"
#include "BoundingBox.hpp"
#include "ImageManager.hpp"

#include <utf8/UTF8.hpp>
#include <module-utils/log/log.hpp>

namespace gui
{


@@ 39,7 39,13 @@ namespace gui

    bool Image::set(int id)
    {
        imageMap = ImageManager::getInstance().getImageMap(id);
        auto map = ImageManager::getInstance().getImageMap(id);
        if (map == nullptr) {
            LOG_ERROR("Unable to get an image map for id: %d", id);
            return false;
        }

        imageMap = map;
        auto w   = imageMap->getWidth();
        auto h   = imageMap->getHeight();
        setMinimumWidth(w);


@@ 50,14 56,21 @@ namespace gui

    void Image::set(const UTF8 &name)
    {
        if (name.length()) {
            int id = ImageManager::getInstance().getImageMapID(name.c_str());
            set(id);
        if (name.empty()) {
            return;
        }

        const auto id = ImageManager::getInstance().getImageMapID(name);
        set(id);
    }

    void Image::buildDrawListImplementation(std::list<Command> &commands)
    {
        if (imageMap == nullptr) {
            LOG_ERROR("Unable to draw the image: ImageMap does not exist.");
            return;
        }

        auto img = std::make_unique<DrawImage>();
        // image
        img->origin = {drawArea.x, drawArea.y};


@@ 66,7 79,6 @@ namespace gui
        img->areaY = img->origin.y;
        img->areaW = drawArea.w;
        img->areaH = drawArea.h;

        img->imageID = this->imageMap->getID();

        commands.emplace_back(std::move(img));

M module-gui/test/test-catch/CMakeLists.txt => module-gui/test/test-catch/CMakeLists.txt +1 -0
@@ 7,6 7,7 @@ add_catch2_executable(
                test-context.cpp
                test-gui-callbacks.cpp
                test-gui-resizes.cpp
                test-gui-image.cpp
                ../mock/TestWindow.cpp
                ../mock/InitializedFontManager.cpp
        test-language-input-parser.cpp

A module-gui/test/test-catch/test-gui-image.cpp => module-gui/test/test-catch/test-gui-image.cpp +46 -0
@@ 0,0 1,46 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <catch2/catch.hpp>
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file

#include <list>

#include <module-gui/gui/core/DrawCommand.hpp>
#include <module-gui/gui/core/ImageManager.hpp>
#include <module-gui/gui/widgets/Image.hpp>

TEST_CASE("Constructing with empty image name")
{
    constexpr auto imageName = "";
    gui::Image image{nullptr, imageName};

    std::list<gui::Command> commands;
    image.buildDrawListImplementation(commands);
    REQUIRE(commands.empty());
}

TEST_CASE("Setting an empty image name")
{
    constexpr auto imageName = "";
    gui::Image image{};
    image.set(imageName);

    std::list<gui::Command> commands;
    image.buildDrawListImplementation(commands);
    REQUIRE(commands.empty());
}

TEST_CASE("Setting an incorrect image name")
{
    constexpr auto imageName = "ABC";
    gui::Image image{};
    REQUIRE_THROWS(image.set(imageName));
}

TEST_CASE("Setting an incorrect image id")
{
    constexpr auto imageId = 1000;
    gui::Image image{};
    REQUIRE_THROWS(image.set(imageId));
}