namespace testing {
template <typename T>
-bool equals(const cpp::span<T> &Span1, const cpp::span<T> &Span2) {
- if (Span1.size() != Span2.size())
+bool equals(const cpp::span<T> &Span1, const cpp::span<T> &Span2,
+ bool &mismatch_size, size_t &mismatch_index) {
+ if (Span1.size() != Span2.size()) {
+ mismatch_size = true;
return false;
+ }
for (size_t Index = 0; Index < Span1.size(); ++Index)
- if (Span1[Index] != Span2[Index])
+ if (Span1[Index] != Span2[Index]) {
+ mismatch_index = Index;
return false;
+ }
return true;
}
bool MemoryMatcher::match(MemoryView actualValue) {
actual = actualValue;
- return equals(expected, actual);
+ return equals(expected, actual, mismatch_size, mismatch_index);
}
void display(testutils::StreamWrapper &Stream, char C) {
}
void MemoryMatcher::explainError(testutils::StreamWrapper &Stream) {
- Stream << "expected :";
- display(Stream, expected);
- Stream << '\n';
- Stream << "actual :";
- display(Stream, actual);
- Stream << '\n';
+ if (mismatch_size) {
+ Stream << "Size mismatch :";
+ Stream << "expected : ";
+ Stream << expected.size();
+ Stream << '\n';
+ Stream << "actual : ";
+ Stream << actual.size();
+ Stream << '\n';
+ } else {
+ Stream << "Mismatch at position : ";
+ Stream << mismatch_index;
+ Stream << " / ";
+ Stream << expected.size();
+ Stream << "\n";
+ Stream << "expected :";
+ display(Stream, expected);
+ Stream << '\n';
+ Stream << "actual :";
+ display(Stream, actual);
+ Stream << '\n';
+ }
}
} // namespace testing
class MemoryMatcher : public __llvm_libc::testing::Matcher<MemoryView> {
MemoryView expected;
MemoryView actual;
+ bool mismatch_size = false;
+ size_t mismatch_index = -1;
public:
MemoryMatcher(MemoryView expectedValue) : expected(expectedValue) {}
#define EXPECT_MEM_EQ(expected, actual) \
EXPECT_THAT(actual, __llvm_libc::memory::testing::MemoryMatcher(expected))
+#define ASSERT_MEM_EQ(expected, actual) \
+ ASSERT_THAT(actual, __llvm_libc::memory::testing::MemoryMatcher(expected))
#endif // LLVM_LIBC_UTILS_UNITTEST_MEMORY_MATCHER_H