[libc] Replace the use of gtest with a new light weight unittest framework.
[lldb.git] / libc / utils / UnitTest / Test.cpp
1 //===--------- Implementation of the base class for libc unittests --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "Test.h"
10
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/Support/raw_ostream.h"
13
14 namespace llvm_libc {
15 namespace testing {
16
17 // This need not be a class as all it has is a single read-write state variable.
18 // But, we make it class as then its implementation can be hidden from the
19 // header file.
20 class RunContext {
21 public:
22   enum RunResult { Result_Pass = 1, Result_Fail = 2 };
23
24   RunResult status() const { return Status; }
25
26   void markFail() { Status = Result_Fail; }
27
28 private:
29   RunResult Status = Result_Pass;
30 };
31
32 namespace internal {
33
34 template <typename ValType>
35 bool test(RunContext &Ctx, TestCondition Cond, ValType LHS, ValType RHS,
36           const char *LHSStr, const char *RHSStr, const char *File,
37           unsigned long Line) {
38   switch (Cond) {
39   case Cond_EQ:
40     if (LHS == RHS)
41       return true;
42
43     Ctx.markFail();
44     llvm::outs() << File << ":" << Line << ": FAILURE\n"
45                  << "      Expected: " << LHSStr << '\n'
46                  << "      Which is: " << LHS << '\n'
47                  << "To be equal to: " << RHSStr << '\n'
48                  << "      Which is: " << RHS << '\n';
49
50     return false;
51   case Cond_NE:
52     if (LHS != RHS)
53       return true;
54
55     Ctx.markFail();
56     llvm::outs() << File << ":" << Line << ": FAILURE\n"
57                  << "          Expected: " << LHSStr << '\n'
58                  << "          Which is: " << LHS << '\n'
59                  << "To be not equal to: " << RHSStr << '\n'
60                  << "          Which is: " << RHS << '\n';
61     return false;
62   case Cond_LT:
63     if (LHS < RHS)
64       return true;
65
66     Ctx.markFail();
67     llvm::outs() << File << ":" << Line << ": FAILURE\n"
68                  << "       Expected: " << LHSStr << '\n'
69                  << "       Which is: " << LHS << '\n'
70                  << "To be less than: " << RHSStr << '\n'
71                  << "       Which is: " << RHS << '\n';
72     return false;
73   case Cond_LE:
74     if (LHS <= RHS)
75       return true;
76
77     Ctx.markFail();
78     llvm::outs() << File << ":" << Line << ": FAILURE\n"
79                  << "                   Expected: " << LHSStr << '\n'
80                  << "                   Which is: " << LHS << '\n'
81                  << "To be less than or equal to: " << RHSStr << '\n'
82                  << "                   Which is: " << RHS << '\n';
83     return false;
84   case Cond_GT:
85     if (LHS > RHS)
86       return true;
87
88     Ctx.markFail();
89     llvm::outs() << File << ":" << Line << ": FAILURE\n"
90                  << "          Expected: " << LHSStr << '\n'
91                  << "          Which is: " << LHS << '\n'
92                  << "To be greater than: " << RHSStr << '\n'
93                  << "          Which is: " << RHS << '\n';
94     return false;
95   case Cond_GE:
96     if (LHS >= RHS)
97       return true;
98
99     Ctx.markFail();
100     llvm::outs() << File << ":" << Line << ": FAILURE\n"
101                  << "                      Expected: " << LHSStr << '\n'
102                  << "                      Which is: " << LHS << '\n'
103                  << "To be greater than or equal to: " << RHSStr << '\n'
104                  << "                      Which is: " << RHS << '\n';
105     return false;
106   default:
107     Ctx.markFail();
108     llvm::outs() << "Unexpected test condition.\n";
109     return false;
110   }
111 }
112
113 } // namespace internal
114
115 Test *Test::Start = nullptr;
116 Test *Test::End = nullptr;
117
118 void Test::addTest(Test *T) {
119   if (End == nullptr) {
120     Start = T;
121     End = T;
122     return;
123   }
124
125   End->Next = T;
126   End = T;
127 }
128
129 int Test::runTests() {
130   int TestCount = 0;
131   int FailCount = 0;
132   for (Test *T = Start; T != nullptr; T = T->Next, ++TestCount) {
133     const char *TestName = T->getName();
134     llvm::outs() << "[ RUN      ] " << TestName << '\n';
135     RunContext Ctx;
136     T->SetUp();
137     T->Run(Ctx);
138     T->TearDown();
139     auto Result = Ctx.status();
140     switch (Result) {
141     case RunContext::Result_Fail:
142       llvm::outs() << "[  FAILED  ] " << TestName << '\n';
143       ++FailCount;
144       break;
145     case RunContext::Result_Pass:
146       llvm::outs() << "[       OK ] " << TestName << '\n';
147       break;
148     }
149   }
150
151   llvm::outs() << "Ran " << TestCount << " tests. "
152                << " PASS: " << TestCount - FailCount << ' '
153                << " FAIL: " << FailCount << '\n';
154
155   return FailCount > 0 ? 1 : 0;
156 }
157
158 template bool Test::test<char, 0>(RunContext &Ctx, TestCondition Cond, char LHS,
159                                   char RHS, const char *LHSStr,
160                                   const char *RHSStr, const char *File,
161                                   unsigned long Line);
162
163 template bool Test::test<short, 0>(RunContext &Ctx, TestCondition Cond,
164                                    short LHS, short RHS, const char *LHSStr,
165                                    const char *RHSStr, const char *File,
166                                    unsigned long Line);
167
168 template bool Test::test<int, 0>(RunContext &Ctx, TestCondition Cond, int LHS,
169                                  int RHS, const char *LHSStr,
170                                  const char *RHSStr, const char *File,
171                                  unsigned long Line);
172
173 template bool Test::test<long, 0>(RunContext &Ctx, TestCondition Cond, long LHS,
174                                   long RHS, const char *LHSStr,
175                                   const char *RHSStr, const char *File,
176                                   unsigned long Line);
177
178 template bool Test::test<long long, 0>(RunContext &Ctx, TestCondition Cond,
179                                        long long LHS, long long RHS,
180                                        const char *LHSStr, const char *RHSStr,
181                                        const char *File, unsigned long Line);
182
183 template bool Test::test<unsigned char, 0>(RunContext &Ctx, TestCondition Cond,
184                                            unsigned char LHS, unsigned char RHS,
185                                            const char *LHSStr,
186                                            const char *RHSStr, const char *File,
187                                            unsigned long Line);
188
189 template bool
190 Test::test<unsigned short, 0>(RunContext &Ctx, TestCondition Cond,
191                               unsigned short LHS, unsigned short RHS,
192                               const char *LHSStr, const char *RHSStr,
193                               const char *File, unsigned long Line);
194
195 template bool Test::test<unsigned int, 0>(RunContext &Ctx, TestCondition Cond,
196                                           unsigned int LHS, unsigned int RHS,
197                                           const char *LHSStr,
198                                           const char *RHSStr, const char *File,
199                                           unsigned long Line);
200
201 template bool Test::test<unsigned long, 0>(RunContext &Ctx, TestCondition Cond,
202                                            unsigned long LHS, unsigned long RHS,
203                                            const char *LHSStr,
204                                            const char *RHSStr, const char *File,
205                                            unsigned long Line);
206
207 template bool Test::test<unsigned long long, 0>(
208     RunContext &Ctx, TestCondition Cond, unsigned long long LHS,
209     unsigned long long RHS, const char *LHSStr, const char *RHSStr,
210     const char *File, unsigned long Line);
211
212 bool Test::testStrEq(RunContext &Ctx, const char *LHS, const char *RHS,
213                      const char *LHSStr, const char *RHSStr, const char *File,
214                      unsigned long Line) {
215   return internal::test(Ctx, Cond_EQ, llvm::StringRef(LHS),
216                         llvm::StringRef(RHS), LHSStr, RHSStr, File, Line);
217 }
218
219 bool Test::testStrNe(RunContext &Ctx, const char *LHS, const char *RHS,
220                      const char *LHSStr, const char *RHSStr, const char *File,
221                      unsigned long Line) {
222   return internal::test(Ctx, Cond_NE, llvm::StringRef(LHS),
223                         llvm::StringRef(RHS), LHSStr, RHSStr, File, Line);
224 }
225
226 } // namespace testing
227 } // namespace llvm_libc
228
229 int main() { return llvm_libc::testing::Test::runTests(); }