ErrorMessageFinder.h 3.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AzCore/Debug/TraceMessageBus.h>
  10. #include <AzCore/std/string/string.h>
  11. #include <AzCore/std/string/string_view.h>
  12. namespace UnitTest
  13. {
  14. //! This utility for unit tests listens for expected error messages. Just fill it with a list of messages
  15. //! and the number of times each message should occur. If a message is expected, it will be counted.
  16. //! If a message is not expected, it will be passed through the normal error handling process and
  17. //! your test will fail. When the object is destructed or when you call CheckExpectedErrorsFound(),
  18. //! if any expected error messages were not received the expected number of times, it will report the
  19. //! discrepancy and your test will fail.
  20. //! Note the expected error messages are sub-strings and not case sensitive, so an exact match isn't required.
  21. class ErrorMessageFinder : public AZ::Debug::TraceMessageBus::Handler
  22. {
  23. public:
  24. ErrorMessageFinder();
  25. ~ErrorMessageFinder();
  26. explicit ErrorMessageFinder(AZStd::string_view message, uint32_t expectedCount = 1);
  27. void AddExpectedErrorMessage(AZStd::string_view message, uint32_t expectedCount = 1);
  28. //! Use this function to prevent specific error messages from causing your test to fail
  29. //! but also don't require the message to occur. This can be a good way to deal with
  30. //! errors that occur outside the code you are testing, but are potential side-effects.
  31. //! Use caution when setting matchSubstring=true because you could accidentally ignore
  32. //! too many messages if the 'message' string is something too short.
  33. void AddIgnoredErrorMessage(AZStd::string_view message, bool matchSubstring = false);
  34. //! Reset the ErrorMessageFinder, clearing all expected errors messages, and all collected data.
  35. void Reset();
  36. //! Reset the received message counts for your expected error messages. The expected
  37. //! messages and expected counts will remain the same.
  38. void ResetCounts();
  39. //! Check whether all expected messages were received and fail if not. This will be called
  40. //! automatically in the destructor if you don't call this yourself.
  41. void CheckExpectedErrorsFound();
  42. //! Call this function to stop intercepting errors
  43. void Disable();
  44. private:
  45. struct ExpectedError
  46. {
  47. AZStd::string m_message;
  48. uint32_t m_expectedCount = 0;
  49. uint32_t m_gotCount = 0;
  50. };
  51. struct OptionalError
  52. {
  53. AZStd::string m_message;
  54. bool m_allowSubstring = false;
  55. };
  56. bool OnPreAssert(const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
  57. bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
  58. bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) override;
  59. // Using a callback allows us to unit test the ErrorMessageFinder class itself
  60. friend class ErrorMessageFinderTests;
  61. using FailureCallback = AZStd::function<void(const AZStd::string&)>;
  62. static void ReportFailure(const AZStd::string&);
  63. FailureCallback m_reportFailure;
  64. /// Common implementation for various bus functions that can report error messages
  65. bool OnTrace(AZStd::string_view message);
  66. AZStd::vector<ExpectedError> m_expectedErrors;
  67. AZStd::vector<OptionalError> m_optionalErrors;
  68. bool m_checked = false;
  69. bool m_disabled = false;
  70. };
  71. } // namespace UnitTest