You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Gems/Atom/RPI/Code/Tests/Common/ErrorMessageFinder.h

88 lines
3.8 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Debug/TraceMessageBus.h>
#include <AzCore/std/string/string.h>
#include <AzCore/std/string/string_view.h>
namespace UnitTest
{
//! This utility for unit tests listens for expected error messages. Just fill it with a list of messages
//! and the number of times each message should occur. If a message is expected, it will be counted.
//! If a message is not expected, it will be passed through the normal error handling process and
//! your test will fail. When the object is destructed or when you call CheckExpectedErrorsFound(),
//! if any expected error messages were not received the expected number of times, it will report the
//! discrepancy and your test will fail.
//! Note the expected error messages are sub-strings and not case sensitive, so an exact match isn't required.
class ErrorMessageFinder : public AZ::Debug::TraceMessageBus::Handler
{
public:
ErrorMessageFinder();
~ErrorMessageFinder();
explicit ErrorMessageFinder(AZStd::string_view message, uint32_t expectedCount = 1);
void AddExpectedErrorMessage(AZStd::string_view message, uint32_t expectedCount = 1);
//! Use this function to prevent specific error messages from causing your test to fail
//! but also don't require the message to occur. This can be a good way to deal with
//! errors that occur outside the code you are testing, but are potential side-effects.
//! Use caution when setting matchSubstring=true because you could accidentally ignore
//! too many messages if the 'message' string is something too short.
void AddIgnoredErrorMessage(AZStd::string_view message, bool matchSubstring = false);
//! Reset the ErrorMessageFinder, clearing all expected errors messages, and all collected data.
void Reset();
//! Reset the received message counts for your expected error messages. The expected
//! messages and expected counts will remain the same.
void ResetCounts();
//! Check whether all expected messages were received and fail if not. This will be called
//! automatically in the destructor if you don't call this yourself.
void CheckExpectedErrorsFound();
//! Call this function to stop intercepting errors
void Disable();
private:
struct ExpectedError
{
AZStd::string m_message;
uint32_t m_expectedCount = 0;
uint32_t m_gotCount = 0;
};
struct OptionalError
{
AZStd::string m_message;
bool m_allowSubstring = false;
};
bool OnPreAssert(const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
// Using a callback allows us to unit test the ErrorMessageFinder class itself
friend class ErrorMessageFinderTests;
using FailureCallback = AZStd::function<void(const AZStd::string&)>;
static void ReportFailure(const AZStd::string&);
FailureCallback m_reportFailure;
/// Common implementation for various bus functions that can report error messages
bool OnTrace(AZStd::string_view message);
AZStd::vector<ExpectedError> m_expectedErrors;
AZStd::vector<OptionalError> m_optionalErrors;
bool m_checked = false;
bool m_disabled = false;
};
} // namespace UnitTest