File: GoogleTestLib.h

package info (click to toggle)
edk2 2025.11-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 338,536 kB
  • sloc: ansic: 2,166,376; asm: 270,725; perl: 235,301; python: 149,839; sh: 34,744; cpp: 23,311; makefile: 3,326; pascal: 1,602; xml: 806; lisp: 35; ruby: 16; sed: 6; tcl: 4
file content (187 lines) | stat: -rw-r--r-- 6,732 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/** @file
  GoogleTestLib class with APIs from the googletest project

  Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef GOOGLE_TEST_LIB_H_
#define GOOGLE_TEST_LIB_H_

//
// For Windows/clang builds if _MSC_VER is not defined, then set to
// Visual Studio 2015 value of 1900
//
#if defined (__clang__) && defined (_WIN32)
  #ifndef _MSC_VER
#define _MSC_VER  1900
  #endif
#endif

#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <cstring>
#include <iomanip>

//
// For all use of GoogleTestLib, make sure NULL is defined to nullptr to
// support matching any unit test pointer value to NULL.
//
#ifdef NULL
  #undef NULL
#define NULL  nullptr
#endif

using ::testing::Throws;
using ::testing::ThrowsMessage;
using ::testing::HasSubstr;

//
// Extended macros for testing exceptions with a specific description string
// in the exception message.  Typically used to check that the expression
// that generates an ASSERT() matches the expected expression.
//
// NOTE: Windows/CLANG builds with ASAN enabled generate an exception
// due to the generated exception string being NULL. An alternate implementation
// of these macros is provided for Windows/CLANG builds that disables ASAN
// checks in a function that uses try/catch for the expected exception type
// and provides the correct exception string for comparison.
//
#if defined (__clang__) && defined (_WIN32)
#define EXPECT_THROW_MESSAGE(statement, description)            \
  [&]() __attribute__((no_sanitize_address)){                   \
    try {                                                       \
      (statement);                                              \
      FAIL() << "Exception not thrown";                         \
    } catch (const std::runtime_error& ex) {                    \
      EXPECT_THAT (                                             \
        std::string(ex.what()),                                 \
        HasSubstr(description)                                  \
        );                                                      \
    } catch(...) {                                              \
      FAIL() << "Unexpected exception";                         \
    }                                                           \
  }()
#define ASSERT_THROW_MESSAGE(statement, description)            \
  [&]() __attribute__((no_sanitize_address)){                   \
    try {                                                       \
      (statement);                                              \
      FAIL() << "Exception not thrown";                         \
    } catch (const std::runtime_error& ex) {                    \
      ASSERT_THAT (                                             \
        std::string(ex.what()),                                 \
        HasSubstr(description)                                  \
        );                                                      \
    } catch(...) {                                              \
      FAIL() << "Unexpected exception";                         \
    }                                                           \
  }()
#else
#define EXPECT_THROW_MESSAGE(statement, description)            \
  EXPECT_THAT (                                                 \
    [&]() { statement; },                                       \
    ThrowsMessage<std::runtime_error>(HasSubstr (description))  \
    )
#define ASSERT_THROW_MESSAGE(statement, description)            \
  ASSERT_THAT (                                                 \
    [&]() { statement; },                                       \
    ThrowsMessage<std::runtime_error>(HasSubstr (description))  \
    )
#endif

extern "C" {
  #include <Uefi.h>
}

//////////////////////////////////////////////////////////////////////////////
// Below are the action extensions to GoogleTest and gmock for EDK2 types.
// These actions are intended to be used in EXPECT_CALL (and related gmock
// macros) to support assignments to output arguments in the expected call.
//

// Action to support pointer types to a buffer (such as UINT8* or VOID*)
ACTION_TEMPLATE (
  SetArgBuffer,
  HAS_1_TEMPLATE_PARAMS (size_t, ArgNum),
  AND_2_VALUE_PARAMS (Buffer, ByteSize)
  ) {
  auto  ArgBuffer = std::get<ArgNum>(args);

  std::memcpy (ArgBuffer, Buffer, ByteSize);
}

//////////////////////////////////////////////////////////////////////////////
// Below are the matcher extensions to GoogleTest and gmock for EDK2 types.
// These matchers are intended to be used in EXPECT_CALL (and related gmock
// macros) to support comparisons to input arguments in the expected call.
//
// Note that these matchers can also be used in the EXPECT_THAT or ASSERT_THAT
// macros to compare whether two values are equal.
//

// Matcher to support pointer types to a buffer (such as UINT8* or VOID* or
// any structure pointer)
MATCHER_P2 (
  BufferEq,
  Buffer,
  ByteSize,
  std::string ("buffer data to ") + (negation ? "not " : "") + "be the same"
  ) {
  UINT8  *Actual   = (UINT8 *)arg;
  UINT8  *Expected = (UINT8 *)Buffer;

  for (size_t i = 0; i < ByteSize; i++) {
    if (Actual[i] != Expected[i]) {
      *result_listener << "byte at offset " << i
      << " does not match expected. [" << std::hex
      << "Actual: 0x" << std::setw (2) << std::setfill ('0')
      << (unsigned int)Actual[i] << ", "
      << "Expected: 0x" << std::setw (2) << std::setfill ('0')
      << (unsigned int)Expected[i] << "]";
      return false;
    }
  }

  *result_listener << "all bytes match";
  return true;
}

// Matcher to support CHAR16* type
MATCHER_P (
  Char16StrEq,
  String,
  std::string ("strings to ") + (negation ? "not " : "") + "be the same"
  ) {
  CHAR16  *Actual   = (CHAR16 *)arg;
  CHAR16  *Expected = (CHAR16 *)String;

  for (size_t i = 0; Actual[i] != 0; i++) {
    if (Actual[i] != Expected[i]) {
      *result_listener << "character at offset " << i
      << " does not match expected. [" << std::hex
      << "Actual: 0x" << std::setw (4) << std::setfill ('0')
      << Actual[i];

      if (std::isprint (Actual[i])) {
        *result_listener << " ('" << (char)Actual[i] << "')";
      }

      *result_listener << ", Expected: 0x" << std::setw (4) << std::setfill ('0')
      << Expected[i];

      if (std::isprint (Expected[i])) {
        *result_listener << " ('" << (char)Expected[i] << "')";
      }

      *result_listener << "]";

      return false;
    }
  }

  *result_listener << "strings match";
  return true;
}

#endif