brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 5a78499 Raw
164 lines · c
1//===- unittest/Format/FormatTestBase.h - Formatting test base classs -----===//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//  This file defines the base class for format tests.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_UNITTESTS_FORMAT_FORMATTESTBASE_H14#define LLVM_CLANG_UNITTESTS_FORMAT_FORMATTESTBASE_H15 16#include "FormatTestUtils.h"17 18#include "clang/Format/Format.h"19#include "llvm/Support/Debug.h"20#include "gtest/gtest.h"21 22namespace clang {23namespace format {24namespace test {25 26#define DEBUG_TYPE "format-test-base"27 28class FormatTestBase : public testing::Test {29protected:30  enum StatusCheck { SC_ExpectComplete, SC_ExpectIncomplete, SC_DoNotCheck };31 32  virtual FormatStyle getDefaultStyle() const { return getLLVMStyle(); }33 34  virtual std::string messUp(StringRef Code) const {35    return test::messUp(Code);36  }37 38  std::string format(StringRef Code,39                     const std::optional<FormatStyle> &Style = {},40                     StatusCheck CheckComplete = SC_ExpectComplete,41                     const std::vector<tooling::Range> &Ranges = {}) {42    LLVM_DEBUG(llvm::errs() << "---\n");43    LLVM_DEBUG(llvm::errs() << Code << "\n\n");44    auto NonEmptyRanges =45        !Ranges.empty()46            ? Ranges47            : std::vector<tooling::Range>{1, tooling::Range(0, Code.size())};48    auto UsedStyle = Style ? Style.value() : getDefaultStyle();49    FormattingAttemptStatus Status;50    tooling::Replacements Replaces =51        reformat(UsedStyle, Code, NonEmptyRanges, "<stdin>", &Status);52    if (CheckComplete != SC_DoNotCheck) {53      bool ExpectedCompleteFormat = CheckComplete == SC_ExpectComplete;54      EXPECT_EQ(ExpectedCompleteFormat, Status.FormatComplete)55          << Code << "\n\n";56    }57    ReplacementCount = Replaces.size();58    auto Result = applyAllReplacements(Code, Replaces);59    EXPECT_TRUE(static_cast<bool>(Result));60    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");61    return *Result;62  }63 64  FormatStyle getStyleWithColumns(FormatStyle Style,65                                  unsigned ColumnLimit) const {66    Style.ColumnLimit = ColumnLimit;67    return Style;68  }69 70  FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) const {71    return getStyleWithColumns(getLLVMStyle(), ColumnLimit);72  }73 74  FormatStyle getGoogleStyleWithColumns(unsigned ColumnLimit) const {75    return getStyleWithColumns(getGoogleStyle(), ColumnLimit);76  }77 78  FormatStyle getTextProtoStyleWithColumns(unsigned ColumnLimit) const {79    return getStyleWithColumns(getGoogleStyle(FormatStyle::LK_TextProto),80                               ColumnLimit);81  }82 83  bool _verifyFormat(const char *File, int Line, StringRef Expected,84                     StringRef Code,85                     const std::optional<FormatStyle> &Style = {},86                     const std::vector<tooling::Range> &Ranges = {}) {87    testing::ScopedTrace t(File, Line, testing::Message() << Code.str());88    const auto ExpectedCode{Expected.str()};89    auto FormattedCode{format(Code, Style, SC_ExpectComplete, Ranges)};90    EXPECT_EQ(ExpectedCode, FormattedCode);91    if (ExpectedCode != FormattedCode)92      return false;93    if (Expected != Code) {94      FormattedCode = format(Expected, Style, SC_ExpectComplete, Ranges);95      EXPECT_EQ(ExpectedCode, FormattedCode) << "Expected code is not stable";96      if (ExpectedCode != FormattedCode)97        return false;98    }99    auto UsedStyle = Style ? Style.value() : getDefaultStyle();100    if (UsedStyle.Language == FormatStyle::LK_Cpp) {101      // Objective-C++ is a superset of C++, so everything checked for C++102      // needs to be checked for Objective-C++ as well.103      FormatStyle ObjCStyle = UsedStyle;104      ObjCStyle.Language = FormatStyle::LK_ObjC;105      // FIXME: Additional messUp is superfluous.106      FormattedCode = format(Code, ObjCStyle, SC_ExpectComplete, Ranges);107      EXPECT_EQ(ExpectedCode, FormattedCode);108      if (ExpectedCode != FormattedCode)109        return false;110    }111    return true;112  }113 114  void _verifyFormat(const char *File, int Line, StringRef Code,115                     const std::optional<FormatStyle> &Style = {}) {116    if (!_verifyFormat(File, Line, Code, Code, Style))117      return;118    if (const auto MessedUpCode{messUp(Code)}; MessedUpCode != Code)119      _verifyFormat(File, Line, Code, MessedUpCode, Style);120  }121 122  void _verifyIncompleteFormat(const char *File, int Line, StringRef Code,123                               const std::optional<FormatStyle> &Style = {}) {124    testing::ScopedTrace t(File, Line, testing::Message() << Code.str());125    EXPECT_EQ(Code.str(), format(messUp(Code), Style, SC_ExpectIncomplete));126  }127 128  void129  _verifyIndependentOfContext(const char *File, int Line, StringRef Text,130                              const std::optional<FormatStyle> &Style = {}) {131    _verifyFormat(File, Line, Text, Style);132    _verifyFormat(File, Line, Twine("void f() { " + Text + " }").str(), Style);133  }134 135  void _verifyNoChange(const char *File, int Line, StringRef Code,136                       const std::optional<FormatStyle> &Style = {}) {137    _verifyFormat(File, Line, Code, Code, Style);138  }139 140  /// Verify that clang-format does not crash on the given input.141  void verifyNoCrash(StringRef Code,142                     const std::optional<FormatStyle> &Style = {}) {143    format(Code, Style, SC_DoNotCheck);144  }145 146  int ReplacementCount;147};148 149#undef DEBUG_TYPE150 151#define verifyIndependentOfContext(...)                                        \152  _verifyIndependentOfContext(__FILE__, __LINE__, __VA_ARGS__)153#define verifyIncompleteFormat(...)                                            \154  _verifyIncompleteFormat(__FILE__, __LINE__, __VA_ARGS__)155#define verifyNoChange(...) _verifyNoChange(__FILE__, __LINE__, __VA_ARGS__)156#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)157#define verifyGoogleFormat(Code) verifyFormat(Code, getGoogleStyle())158 159} // namespace test160} // namespace format161} // namespace clang162 163#endif164