Clang Project

clang_source_code/unittests/Format/FormatTestCSharp.cpp
1//===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
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 "FormatTestUtils.h"
10#include "clang/Format/Format.h"
11#include "llvm/Support/Debug.h"
12#include "gtest/gtest.h"
13
14#define DEBUG_TYPE "format-test"
15
16namespace clang {
17namespace format {
18
19class FormatTestCSharp : public ::testing::Test {
20protected:
21  static std::string format(llvm::StringRef Code, unsigned Offset,
22                            unsigned Length, const FormatStyle &Style) {
23    LLVM_DEBUG(llvm::errs() << "---\n");
24    LLVM_DEBUG(llvm::errs() << Code << "\n\n");
25    std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
26    tooling::Replacements Replaces = reformat(Style, Code, Ranges);
27    auto Result = applyAllReplacements(Code, Replaces);
28    EXPECT_TRUE(static_cast<bool>(Result));
29    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
30    return *Result;
31  }
32
33  static std::string
34  format(llvm::StringRef Code,
35         const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_CSharp)) {
36    return format(Code, 0, Code.size(), Style);
37  }
38
39  static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
40    FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
41    Style.ColumnLimit = ColumnLimit;
42    return Style;
43  }
44
45  static void verifyFormat(
46      llvm::StringRef Code,
47      const FormatStyle &Style = getGoogleStyle(FormatStyle::LK_CSharp)) {
48    EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
49    EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
50  }
51};
52
53TEST_F(FormatTestCSharp, CSharpClass) {
54  verifyFormat("public class SomeClass {\n"
55               "  void f() {}\n"
56               "  int g() { return 0; }\n"
57               "  void h() {\n"
58               "    while (true) f();\n"
59               "    for (;;) f();\n"
60               "    if (true) f();\n"
61               "  }\n"
62               "}");
63}
64
65TEST_F(FormatTestCSharp, AccessModifiers) {
66  verifyFormat("public String toString() {}");
67  verifyFormat("private String toString() {}");
68  verifyFormat("protected String toString() {}");
69  verifyFormat("internal String toString() {}");
70
71  verifyFormat("public override String toString() {}");
72  verifyFormat("private override String toString() {}");
73  verifyFormat("protected override String toString() {}");
74  verifyFormat("internal override String toString() {}");
75
76  verifyFormat("internal static String toString() {}");
77}
78
79TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
80  verifyFormat("foo("
81               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
82               "aaaaaa\");");
83}
84
85TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
86  verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
87  // @"ABC\" + ToString("B") - handle embedded \ in literal string at
88  // the end
89  //
90  /*
91   * After removal of Lexer change we are currently not able
92   * To handle these cases
93   verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
94   verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
95   verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
96   verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
97  */
98}
99
100TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
101  verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
102  verifyFormat("foo($\"aaaa{A}\");");
103  verifyFormat(
104      "foo($\"aaaa{A}"
105      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
106  verifyFormat("Name = $\"{firstName} {lastName}\";");
107
108  // $"ABC\" + ToString("B") - handle embedded \ in literal string at
109  // the end
110  verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
111  verifyFormat("$\"{domain}\\\\{user}\"");
112  verifyFormat(
113      "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
114}
115
116TEST_F(FormatTestCSharp, CSharpFatArrows) {
117  verifyFormat("Task serverTask = Task.Run(async() => {");
118  verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
119}
120
121TEST_F(FormatTestCSharp, CSharpNullConditional) {
122  verifyFormat(
123      "public Person(string firstName, string lastName, int? age=null)");
124
125  verifyFormat("switch(args?.Length)");
126
127  verifyFormat("public static void Main(string[] args) { string dirPath "
128               "= args?[0]; }");
129}
130
131TEST_F(FormatTestCSharp, Attributes) {
132  verifyFormat("[STAThread]\n"
133               "static void\n"
134               "Main(string[] args) {}");
135
136  verifyFormat("[TestMethod]\n"
137               "private class Test {}");
138
139  verifyFormat("[TestMethod]\n"
140               "protected class Test {}");
141
142  verifyFormat("[TestMethod]\n"
143               "internal class Test {}");
144
145  verifyFormat("[TestMethod]\n"
146               "class Test {}");
147
148  verifyFormat("[TestMethod]\n"
149               "[DeploymentItem(\"Test.txt\")]\n"
150               "public class Test {}");
151
152  verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
153               "[System.Runtime.InteropServices.ComVisible(true)]\n"
154               "public sealed class STAThreadAttribute : Attribute {}");
155
156  verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
157               "provided port\")]\n"
158               "class Test {}");
159
160  verifyFormat("[TestMethod]\n"
161               "public string Host {\n  set;\n  get;\n}");
162
163  verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
164               "listening on provided host\")]\n"
165               "public string Host {\n  set;\n  get;\n}");
166}
167
168TEST_F(FormatTestCSharp, CSharpRegions) {
169  verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
170               "aaaaaaaaaaaaaaa long region");
171}
172
173TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
174  verifyFormat("public enum var { none, @string, bool, @enum }");
175}
176
177TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
178  verifyFormat("var test = ABC ?? DEF");
179  verifyFormat("string myname = name ?? \"ABC\";");
180  verifyFormat("return _name ?? \"DEF\";");
181}
182
183} // namespace format
184} // end namespace clang
185