136 lines · cpp
1//===-- lib/Testing/testing.cpp ---------------------------------*- C++ -*-===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Testing/testing.h"10#include "llvm/Support/raw_ostream.h"11#include <cstdarg>12#include <cstdio>13#include <cstdlib>14 15namespace testing {16 17namespace {18int passes{0};19int failures{0};20} // namespace21 22static void BitBucket(const char *, ...) {}23 24static void PrintFailureDetails(const char *format, ...) {25 va_list ap;26 va_start(ap, format);27 fputs("\t", stderr);28 vfprintf(stderr, format, ap);29 va_end(ap);30 fputc('\n', stderr);31}32 33FailureDetailPrinter Test(34 const char *file, int line, const char *predicate, bool pass) {35 if (pass) {36 ++passes;37 return BitBucket;38 } else {39 ++failures;40 fprintf(stderr, "%s:%d: FAIL: %s\n", file, line, predicate);41 return PrintFailureDetails;42 }43}44 45FailureDetailPrinter Match(const char *file, int line, std::uint64_t want,46 const char *gots, std::uint64_t got) {47 if (want == got) {48 ++passes;49 return BitBucket;50 } else {51 ++failures;52 fprintf(stderr, "%s:%d: FAIL: %s == 0x%jx, not 0x%jx\n", file, line, gots,53 static_cast<std::uintmax_t>(got), static_cast<std::uintmax_t>(want));54 return PrintFailureDetails;55 }56}57 58FailureDetailPrinter Match(const char *file, int line, const char *want,59 const char *gots, const std::string &got) {60 if (want == got) {61 ++passes;62 return BitBucket;63 } else {64 ++failures;65 fprintf(stderr, "%s:%d: FAIL: %s == \"%s\", not \"%s\"\n", file, line, gots,66 got.data(), want);67 return PrintFailureDetails;68 }69}70 71FailureDetailPrinter Match(const char *file, int line, const std::string &want,72 const char *gots, const std::string &got) {73 return Match(file, line, want.data(), gots, got);74}75 76FailureDetailPrinter Compare(const char *file, int line, const char *xs,77 const char *rel, const char *ys, std::uint64_t x, std::uint64_t y) {78 while (*rel == ' ') {79 ++rel;80 }81 bool pass{false};82 if (*rel == '<') {83 if (rel[1] == '=') {84 pass = x <= y;85 } else {86 pass = x < y;87 }88 } else if (*rel == '>') {89 if (rel[1] == '=') {90 pass = x >= y;91 } else {92 pass = x > y;93 }94 } else if (*rel == '=') {95 pass = x == y;96 } else if (*rel == '!') {97 pass = x != y;98 }99 if (pass) {100 ++passes;101 return BitBucket;102 } else {103 ++failures;104 fprintf(stderr, "%s:%d: FAIL: %s[0x%jx] %s %s[0x%jx]\n", file, line, xs,105 static_cast<std::uintmax_t>(x), rel, ys,106 static_cast<std::uintmax_t>(y));107 return PrintFailureDetails;108 }109}110 111int Complete() {112 if (failures == 0) {113 if (passes == 1) {114 llvm::outs() << "single test PASSES\n";115 } else {116 llvm::outs() << "all " << passes << " tests PASS\n";117 }118 passes = 0;119 return EXIT_SUCCESS;120 } else {121 if (passes == 1) {122 llvm::errs() << "1 test passes, ";123 } else {124 llvm::errs() << passes << " tests pass, ";125 }126 if (failures == 1) {127 llvm::errs() << "1 test FAILS\n";128 } else {129 llvm::errs() << failures << " tests FAIL\n";130 }131 passes = failures = 0;132 return EXIT_FAILURE;133 }134}135} // namespace testing136