forked from OSchip/llvm-project
[libc] Replace the use of gtest with a new light weight unittest framework.
Header files included wrongly using <...> are now included using the internal path names as the new unittest framework allows us to do so. Reviewers: phosek, abrachet Differential Revision: https://reviews.llvm.org/D72743
This commit is contained in:
parent
1d568bf960
commit
c7453fad06
|
@ -339,10 +339,9 @@ function(add_libc_unittest target_name)
|
|||
target_include_directories(
|
||||
${target_name}
|
||||
PRIVATE
|
||||
${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include
|
||||
${LLVM_MAIN_SRC_DIR}/utils/unittest/googlemock/include
|
||||
${LIBC_SOURCE_DIR}
|
||||
${LIBC_BUILD_DIR}
|
||||
${LIBC_BUILD_DIR}/include
|
||||
)
|
||||
|
||||
if(library_deps)
|
||||
|
@ -357,7 +356,7 @@ function(add_libc_unittest target_name)
|
|||
gtest
|
||||
)
|
||||
|
||||
target_link_libraries(${target_name} PRIVATE gtest_main gtest)
|
||||
target_link_libraries(${target_name} PRIVATE LibcUnitTest LLVMSupport)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${target_name}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SRC_STRING_STRCAT_H
|
||||
#define LLVM_LIBC_SRC_STRING_STRCAT_H
|
||||
|
||||
#include <string.h>
|
||||
#include "include/string.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SRC_STRING_STRCPY_H
|
||||
#define LLVM_LIBC_SRC_STRING_STRCPY_H
|
||||
|
||||
#include <string.h>
|
||||
#include "include/string.h"
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/sys/mman/mmap.h"
|
||||
#include "include/sys/syscall.h" // For syscall numbers.
|
||||
#include "src/__support/common.h"
|
||||
#include "src/errno/llvmlibc_errno.h"
|
||||
|
||||
#include "src/unistd/syscall.h" // For internal syscall function.
|
||||
|
||||
#include <sys/syscall.h> // For syscall numbers.
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
// This function is currently linux only. It has to be refactored suitably if
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SRC_SYS_MMAN_MMAP_H
|
||||
#define LLVM_LIBC_SRC_SYS_MMAN_MMAP_H
|
||||
|
||||
#include <sys/mman.h> // For size_t and off_t
|
||||
#include "include/sys/mman.h" // For size_t and off_t
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/sys/mman/munmap.h"
|
||||
#include "include/sys/syscall.h" // For syscall numbers.
|
||||
#include "src/__support/common.h"
|
||||
#include "src/errno/llvmlibc_errno.h"
|
||||
|
||||
#include "src/unistd/syscall.h" // For internal syscall function.
|
||||
|
||||
#include <sys/syscall.h> // For syscall numbers.
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
// This function is currently linux only. It has to be refactored suitably if
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef LLVM_LIBC_SRC_SYS_MMAN_MUNMAP_H
|
||||
#define LLVM_LIBC_SRC_SYS_MMAN_MUNMAP_H
|
||||
|
||||
#include <sys/mman.h> // For size_t
|
||||
#include "include/sys/mman.h" // For size_t.
|
||||
|
||||
namespace __llvm_libc {
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/unistd/syscall.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/errno/llvmlibc_errno.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(ErrnoTest, Basic) {
|
||||
int test_val = 123;
|
||||
|
|
|
@ -6,25 +6,23 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/string/strcat.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(StrCatTest, EmptyDest) {
|
||||
std::string abc = "abc";
|
||||
const char *abc = "abc";
|
||||
char dest[4];
|
||||
|
||||
dest[0] = '\0';
|
||||
|
||||
char *result = __llvm_libc::strcat(dest, abc.c_str());
|
||||
char *result = __llvm_libc::strcat(dest, abc);
|
||||
ASSERT_EQ(dest, result);
|
||||
ASSERT_EQ(std::string(dest), abc);
|
||||
ASSERT_EQ(std::string(dest).size(), abc.size());
|
||||
ASSERT_STREQ(dest, result);
|
||||
ASSERT_STREQ(dest, abc);
|
||||
}
|
||||
|
||||
TEST(StrCatTest, NonEmptyDest) {
|
||||
std::string abc = "abc";
|
||||
const char *abc = "abc";
|
||||
char dest[7];
|
||||
|
||||
dest[0] = 'x';
|
||||
|
@ -32,8 +30,8 @@ TEST(StrCatTest, NonEmptyDest) {
|
|||
dest[2] = 'z';
|
||||
dest[3] = '\0';
|
||||
|
||||
char *result = __llvm_libc::strcat(dest, abc.c_str());
|
||||
char *result = __llvm_libc::strcat(dest, abc);
|
||||
ASSERT_EQ(dest, result);
|
||||
ASSERT_EQ(std::string(dest), std::string("xyz") + abc);
|
||||
ASSERT_EQ(std::string(dest).size(), abc.size() + 3);
|
||||
ASSERT_STREQ(dest, result);
|
||||
ASSERT_STREQ(dest, "xyzabc");
|
||||
}
|
||||
|
|
|
@ -6,31 +6,29 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "src/string/strcpy.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(StrCpyTest, EmptyDest) {
|
||||
std::string abc = "abc";
|
||||
const char *abc = "abc";
|
||||
char dest[4];
|
||||
|
||||
char *result = __llvm_libc::strcpy(dest, abc.c_str());
|
||||
char *result = __llvm_libc::strcpy(dest, abc);
|
||||
ASSERT_EQ(dest, result);
|
||||
ASSERT_EQ(std::string(dest), abc);
|
||||
ASSERT_EQ(std::string(dest).size(), abc.size());
|
||||
ASSERT_STREQ(dest, result);
|
||||
ASSERT_STREQ(dest, abc);
|
||||
}
|
||||
|
||||
TEST(StrCpyTest, OffsetDest) {
|
||||
std::string abc = "abc";
|
||||
const char *abc = "abc";
|
||||
char dest[7];
|
||||
|
||||
dest[0] = 'x';
|
||||
dest[1] = 'y';
|
||||
dest[2] = 'z';
|
||||
|
||||
char *result = __llvm_libc::strcpy(dest + 3, abc.c_str());
|
||||
char *result = __llvm_libc::strcpy(dest + 3, abc);
|
||||
ASSERT_EQ(dest + 3, result);
|
||||
ASSERT_EQ(std::string(dest), std::string("xyz") + abc);
|
||||
ASSERT_EQ(std::string(dest).size(), abc.size() + 3);
|
||||
ASSERT_STREQ(dest + 3, result);
|
||||
ASSERT_STREQ(dest, "xyzabc");
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ add_libc_unittest(
|
|||
SRCS
|
||||
mmap_test.cpp
|
||||
DEPENDS
|
||||
errno_h
|
||||
sys_mman_h
|
||||
mmap
|
||||
munmap
|
||||
__errno_location
|
||||
|
|
|
@ -6,14 +6,12 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "include/errno.h"
|
||||
#include "include/sys/mman.h"
|
||||
#include "src/errno/llvmlibc_errno.h"
|
||||
#include "src/sys/mman/mmap.h"
|
||||
#include "src/sys/mman/munmap.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "errno.h"
|
||||
#include "sys/mman.h"
|
||||
#include "utils/UnitTest/Test.h"
|
||||
|
||||
TEST(MMapTest, NoError) {
|
||||
size_t alloc_size = 128;
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
add_subdirectory(HdrGen)
|
||||
add_subdirectory(UnitTest)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
add_llvm_library(
|
||||
LibcUnitTest
|
||||
Test.cpp
|
||||
Test.h
|
||||
)
|
|
@ -0,0 +1,229 @@
|
|||
//===--------- Implementation of the base class for libc unittests --------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Test.h"
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm_libc {
|
||||
namespace testing {
|
||||
|
||||
// This need not be a class as all it has is a single read-write state variable.
|
||||
// But, we make it class as then its implementation can be hidden from the
|
||||
// header file.
|
||||
class RunContext {
|
||||
public:
|
||||
enum RunResult { Result_Pass = 1, Result_Fail = 2 };
|
||||
|
||||
RunResult status() const { return Status; }
|
||||
|
||||
void markFail() { Status = Result_Fail; }
|
||||
|
||||
private:
|
||||
RunResult Status = Result_Pass;
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename ValType>
|
||||
bool test(RunContext &Ctx, TestCondition Cond, ValType LHS, ValType RHS,
|
||||
const char *LHSStr, const char *RHSStr, const char *File,
|
||||
unsigned long Line) {
|
||||
switch (Cond) {
|
||||
case Cond_EQ:
|
||||
if (LHS == RHS)
|
||||
return true;
|
||||
|
||||
Ctx.markFail();
|
||||
llvm::outs() << File << ":" << Line << ": FAILURE\n"
|
||||
<< " Expected: " << LHSStr << '\n'
|
||||
<< " Which is: " << LHS << '\n'
|
||||
<< "To be equal to: " << RHSStr << '\n'
|
||||
<< " Which is: " << RHS << '\n';
|
||||
|
||||
return false;
|
||||
case Cond_NE:
|
||||
if (LHS != RHS)
|
||||
return true;
|
||||
|
||||
Ctx.markFail();
|
||||
llvm::outs() << File << ":" << Line << ": FAILURE\n"
|
||||
<< " Expected: " << LHSStr << '\n'
|
||||
<< " Which is: " << LHS << '\n'
|
||||
<< "To be not equal to: " << RHSStr << '\n'
|
||||
<< " Which is: " << RHS << '\n';
|
||||
return false;
|
||||
case Cond_LT:
|
||||
if (LHS < RHS)
|
||||
return true;
|
||||
|
||||
Ctx.markFail();
|
||||
llvm::outs() << File << ":" << Line << ": FAILURE\n"
|
||||
<< " Expected: " << LHSStr << '\n'
|
||||
<< " Which is: " << LHS << '\n'
|
||||
<< "To be less than: " << RHSStr << '\n'
|
||||
<< " Which is: " << RHS << '\n';
|
||||
return false;
|
||||
case Cond_LE:
|
||||
if (LHS <= RHS)
|
||||
return true;
|
||||
|
||||
Ctx.markFail();
|
||||
llvm::outs() << File << ":" << Line << ": FAILURE\n"
|
||||
<< " Expected: " << LHSStr << '\n'
|
||||
<< " Which is: " << LHS << '\n'
|
||||
<< "To be less than or equal to: " << RHSStr << '\n'
|
||||
<< " Which is: " << RHS << '\n';
|
||||
return false;
|
||||
case Cond_GT:
|
||||
if (LHS > RHS)
|
||||
return true;
|
||||
|
||||
Ctx.markFail();
|
||||
llvm::outs() << File << ":" << Line << ": FAILURE\n"
|
||||
<< " Expected: " << LHSStr << '\n'
|
||||
<< " Which is: " << LHS << '\n'
|
||||
<< "To be greater than: " << RHSStr << '\n'
|
||||
<< " Which is: " << RHS << '\n';
|
||||
return false;
|
||||
case Cond_GE:
|
||||
if (LHS >= RHS)
|
||||
return true;
|
||||
|
||||
Ctx.markFail();
|
||||
llvm::outs() << File << ":" << Line << ": FAILURE\n"
|
||||
<< " Expected: " << LHSStr << '\n'
|
||||
<< " Which is: " << LHS << '\n'
|
||||
<< "To be greater than or equal to: " << RHSStr << '\n'
|
||||
<< " Which is: " << RHS << '\n';
|
||||
return false;
|
||||
default:
|
||||
Ctx.markFail();
|
||||
llvm::outs() << "Unexpected test condition.\n";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
Test *Test::Start = nullptr;
|
||||
Test *Test::End = nullptr;
|
||||
|
||||
void Test::addTest(Test *T) {
|
||||
if (End == nullptr) {
|
||||
Start = T;
|
||||
End = T;
|
||||
return;
|
||||
}
|
||||
|
||||
End->Next = T;
|
||||
End = T;
|
||||
}
|
||||
|
||||
int Test::runTests() {
|
||||
int TestCount = 0;
|
||||
int FailCount = 0;
|
||||
for (Test *T = Start; T != nullptr; T = T->Next, ++TestCount) {
|
||||
const char *TestName = T->getName();
|
||||
llvm::outs() << "[ RUN ] " << TestName << '\n';
|
||||
RunContext Ctx;
|
||||
T->SetUp();
|
||||
T->Run(Ctx);
|
||||
T->TearDown();
|
||||
auto Result = Ctx.status();
|
||||
switch (Result) {
|
||||
case RunContext::Result_Fail:
|
||||
llvm::outs() << "[ FAILED ] " << TestName << '\n';
|
||||
++FailCount;
|
||||
break;
|
||||
case RunContext::Result_Pass:
|
||||
llvm::outs() << "[ OK ] " << TestName << '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
llvm::outs() << "Ran " << TestCount << " tests. "
|
||||
<< " PASS: " << TestCount - FailCount << ' '
|
||||
<< " FAIL: " << FailCount << '\n';
|
||||
|
||||
return FailCount > 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
template bool Test::test<char, 0>(RunContext &Ctx, TestCondition Cond, char LHS,
|
||||
char RHS, const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<short, 0>(RunContext &Ctx, TestCondition Cond,
|
||||
short LHS, short RHS, const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<int, 0>(RunContext &Ctx, TestCondition Cond, int LHS,
|
||||
int RHS, const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<long, 0>(RunContext &Ctx, TestCondition Cond, long LHS,
|
||||
long RHS, const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<long long, 0>(RunContext &Ctx, TestCondition Cond,
|
||||
long long LHS, long long RHS,
|
||||
const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line);
|
||||
|
||||
template bool Test::test<unsigned char, 0>(RunContext &Ctx, TestCondition Cond,
|
||||
unsigned char LHS, unsigned char RHS,
|
||||
const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool
|
||||
Test::test<unsigned short, 0>(RunContext &Ctx, TestCondition Cond,
|
||||
unsigned short LHS, unsigned short RHS,
|
||||
const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line);
|
||||
|
||||
template bool Test::test<unsigned int, 0>(RunContext &Ctx, TestCondition Cond,
|
||||
unsigned int LHS, unsigned int RHS,
|
||||
const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<unsigned long, 0>(RunContext &Ctx, TestCondition Cond,
|
||||
unsigned long LHS, unsigned long RHS,
|
||||
const char *LHSStr,
|
||||
const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
template bool Test::test<unsigned long long, 0>(
|
||||
RunContext &Ctx, TestCondition Cond, unsigned long long LHS,
|
||||
unsigned long long RHS, const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line);
|
||||
|
||||
bool Test::testStrEq(RunContext &Ctx, const char *LHS, const char *RHS,
|
||||
const char *LHSStr, const char *RHSStr, const char *File,
|
||||
unsigned long Line) {
|
||||
return internal::test(Ctx, Cond_EQ, llvm::StringRef(LHS),
|
||||
llvm::StringRef(RHS), LHSStr, RHSStr, File, Line);
|
||||
}
|
||||
|
||||
bool Test::testStrNe(RunContext &Ctx, const char *LHS, const char *RHS,
|
||||
const char *LHSStr, const char *RHSStr, const char *File,
|
||||
unsigned long Line) {
|
||||
return internal::test(Ctx, Cond_NE, llvm::StringRef(LHS),
|
||||
llvm::StringRef(RHS), LHSStr, RHSStr, File, Line);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace llvm_libc
|
||||
|
||||
int main() { return llvm_libc::testing::Test::runTests(); }
|
|
@ -0,0 +1,217 @@
|
|||
//===------------------ Base class for libc unittests -----------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// This file should stricly not include any other file. Not even standard
|
||||
// library headers.
|
||||
|
||||
namespace llvm_libc {
|
||||
namespace testing {
|
||||
|
||||
// We define our own EnableIf and IsIntegerType traits because we do not want to
|
||||
// include even the standard header <type_traits>.
|
||||
template <bool B, typename T> struct EnableIf;
|
||||
template <typename T> struct EnableIf<true, T> { typedef T Type; };
|
||||
|
||||
template <bool B, typename T>
|
||||
using EnableIfType = typename EnableIf<B, T>::Type;
|
||||
|
||||
template <typename Type> struct IsIntegerType {
|
||||
static const bool Value = false;
|
||||
};
|
||||
|
||||
template <> struct IsIntegerType<char> { static const bool Value = true; };
|
||||
template <> struct IsIntegerType<unsigned char> {
|
||||
static const bool Value = true;
|
||||
};
|
||||
|
||||
template <> struct IsIntegerType<short> { static const bool Value = true; };
|
||||
template <> struct IsIntegerType<unsigned short> {
|
||||
static const bool Value = true;
|
||||
};
|
||||
|
||||
template <> struct IsIntegerType<int> { static const bool Value = true; };
|
||||
template <> struct IsIntegerType<unsigned int> {
|
||||
static const bool Value = true;
|
||||
};
|
||||
|
||||
template <> struct IsIntegerType<long> { static const bool Value = true; };
|
||||
template <> struct IsIntegerType<unsigned long> {
|
||||
static const bool Value = true;
|
||||
};
|
||||
|
||||
template <> struct IsIntegerType<long long> { static const bool Value = true; };
|
||||
template <> struct IsIntegerType<unsigned long long> {
|
||||
static const bool Value = true;
|
||||
};
|
||||
|
||||
template <typename T> struct IsPointerType;
|
||||
|
||||
template <typename T> struct IsPointerType<T *> {
|
||||
static const bool Value = true;
|
||||
};
|
||||
|
||||
class RunContext;
|
||||
|
||||
// Only the following conditions are supported. Notice that we do not have
|
||||
// a TRUE or FALSE condition. That is because, C library funtions do not
|
||||
// return, but use integral return values to indicate true or false
|
||||
// conditions. Hence, it is more appropriate to use the other comparison
|
||||
// condtions for such cases.
|
||||
enum TestCondition {
|
||||
Cond_None,
|
||||
Cond_EQ,
|
||||
Cond_NE,
|
||||
Cond_LT,
|
||||
Cond_LE,
|
||||
Cond_GT,
|
||||
Cond_GE,
|
||||
};
|
||||
|
||||
namespace internal {
|
||||
|
||||
template <typename ValType>
|
||||
bool test(RunContext &Ctx, TestCondition Cond, ValType LHS, ValType RHS,
|
||||
const char *LHSStr, const char *RHSStr, const char *File,
|
||||
unsigned long Line);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// NOTE: One should not create instances and call methods on them directly. One
|
||||
// should use the macros TEST or TEST_F to write test cases.
|
||||
class Test {
|
||||
private:
|
||||
Test *Next = nullptr;
|
||||
|
||||
public:
|
||||
virtual ~Test() {}
|
||||
virtual void SetUp() {}
|
||||
virtual void TearDown() {}
|
||||
|
||||
static int runTests();
|
||||
|
||||
protected:
|
||||
static void addTest(Test *T);
|
||||
|
||||
// We make use of a template function, with |LHS| and |RHS| as explicit
|
||||
// parameters, for enhanced type checking. Other gtest like test unittest
|
||||
// frameworks have a similar functions which takes a boolean argument
|
||||
// instead of the explicit |LHS| and |RHS| arguments. This boolean argument
|
||||
// is the result of the |Cond| operation on |LHS| and |RHS|. Though not bad,
|
||||
// mismatched |LHS| and |RHS| types can potentially succeed because of type
|
||||
// promotion.
|
||||
template <typename ValType,
|
||||
EnableIfType<IsIntegerType<ValType>::Value, ValType> = 0>
|
||||
static bool test(RunContext &Ctx, TestCondition Cond, ValType LHS,
|
||||
ValType RHS, const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line) {
|
||||
return internal::test(Ctx, Cond, LHS, RHS, LHSStr, RHSStr, File, Line);
|
||||
}
|
||||
|
||||
template <typename ValType,
|
||||
EnableIfType<IsPointerType<ValType>::Value, ValType> = nullptr>
|
||||
static bool test(RunContext &Ctx, TestCondition Cond, ValType LHS,
|
||||
ValType RHS, const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line) {
|
||||
return internal::test(Ctx, Cond, (unsigned long long)LHS,
|
||||
(unsigned long long)RHS, LHSStr, RHSStr, File, Line);
|
||||
}
|
||||
|
||||
static bool testStrEq(RunContext &Ctx, const char *LHS, const char *RHS,
|
||||
const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line);
|
||||
|
||||
static bool testStrNe(RunContext &Ctx, const char *LHS, const char *RHS,
|
||||
const char *LHSStr, const char *RHSStr,
|
||||
const char *File, unsigned long Line);
|
||||
|
||||
private:
|
||||
virtual void Run(RunContext &Ctx) = 0;
|
||||
virtual const char *getName() const = 0;
|
||||
|
||||
static Test *Start;
|
||||
static Test *End;
|
||||
};
|
||||
|
||||
} // namespace testing
|
||||
} // namespace llvm_libc
|
||||
|
||||
#define TEST(SuiteName, TestName) \
|
||||
class SuiteName##_##TestName : public llvm_libc::testing::Test { \
|
||||
public: \
|
||||
SuiteName##_##TestName() { addTest(this); } \
|
||||
void Run(llvm_libc::testing::RunContext &) override; \
|
||||
const char *getName() const override { return #SuiteName "." #TestName; } \
|
||||
}; \
|
||||
SuiteName##_##TestName SuiteName##_##TestName##_Instance; \
|
||||
void SuiteName##_##TestName::Run(llvm_libc::testing::RunContext &Ctx)
|
||||
|
||||
#define TEST_F(SuiteClass, TestName) \
|
||||
class SuiteClass##_##TestName : public SuiteClass { \
|
||||
public: \
|
||||
SuiteClass##_##TestName() { addTest(this); } \
|
||||
void Run(llvm_libc::testing::RunContext &) override; \
|
||||
const char *getName() const override { return #SuiteClass "." #TestName; } \
|
||||
}; \
|
||||
SuiteClass##_##TestName SuiteClass##_##TestName##_Instance; \
|
||||
void SuiteClass##_##TestName::Run(llvm_libc::testing::RunContext &Ctx)
|
||||
|
||||
#define EXPECT_EQ(LHS, RHS) \
|
||||
llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_EQ, (LHS), \
|
||||
(RHS), #LHS, #RHS, __FILE__, __LINE__)
|
||||
#define ASSERT_EQ(LHS, RHS) \
|
||||
if (!EXPECT_EQ(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_NE(LHS, RHS) \
|
||||
llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_NE, (LHS), \
|
||||
(RHS), #LHS, #RHS, __FILE__, __LINE__)
|
||||
#define ASSERT_NE(LHS, RHS) \
|
||||
if (!EXPECT_NE(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_LT(LHS, RHS) \
|
||||
llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_LT, (LHS), \
|
||||
(RHS), #LHS, #RHS, __FILE__, __LINE__)
|
||||
#define ASSERT_LT(LHS, RHS) \
|
||||
if (!EXPECT_LT(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_LE(LHS, RHS) \
|
||||
llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_LE, (LHS), \
|
||||
(RHS), #LHS, #RHS, __FILE__, __LINE__)
|
||||
#define ASSERT_LE(LHS, RHS) \
|
||||
if (!EXPECT_LE(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_GT(LHS, RHS) \
|
||||
llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_GT, (LHS), \
|
||||
(RHS), #LHS, #RHS, __FILE__, __LINE__)
|
||||
#define ASSERT_GT(LHS, RHS) \
|
||||
if (!EXPECT_GT(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_GE(LHS, RHS) \
|
||||
llvm_libc::testing::Test::test(Ctx, llvm_libc::testing::Cond_GE, (LHS), \
|
||||
(RHS), #LHS, #RHS, __FILE__, __LINE__)
|
||||
#define ASSERT_GE(LHS, RHS) \
|
||||
if (!EXPECT_GE(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_STREQ(LHS, RHS) \
|
||||
llvm_libc::testing::Test::testStrEq(Ctx, (LHS), (RHS), #LHS, #RHS, __FILE__, \
|
||||
__LINE__)
|
||||
#define ASSERT_STREQ(LHS, RHS) \
|
||||
if (!EXPECT_STREQ(LHS, RHS)) \
|
||||
return
|
||||
|
||||
#define EXPECT_STRNE(LHS, RHS) \
|
||||
llvm_libc::testing::Test::testStrNe(Ctx, (LHS), (RHS), #LHS, #RHS, __FILE__, \
|
||||
__LINE__)
|
||||
#define ASSERT_STRNE(LHS, RHS) \
|
||||
if (!EXPECT_STRNE(LHS, RHS)) \
|
||||
return
|
Loading…
Reference in New Issue