xref: /llvm-project/clang/unittests/Format/FormatTestCSharp.cpp (revision 0ffb3dd33ee1a50a6ab5db80bb8caee9133e66dc)
1cbb726d0SPaul Hoad //===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
2cbb726d0SPaul Hoad //
3cbb726d0SPaul Hoad // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cbb726d0SPaul Hoad // See https://llvm.org/LICENSE.txt for license information.
5cbb726d0SPaul Hoad // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cbb726d0SPaul Hoad //
7cbb726d0SPaul Hoad //===----------------------------------------------------------------------===//
8cbb726d0SPaul Hoad 
9cbb726d0SPaul Hoad #include "FormatTestUtils.h"
10cbb726d0SPaul Hoad #include "clang/Format/Format.h"
11cbb726d0SPaul Hoad #include "llvm/Support/Debug.h"
12cbb726d0SPaul Hoad #include "gtest/gtest.h"
13cbb726d0SPaul Hoad 
14cbb726d0SPaul Hoad #define DEBUG_TYPE "format-test"
15cbb726d0SPaul Hoad 
16cbb726d0SPaul Hoad namespace clang {
17cbb726d0SPaul Hoad namespace format {
18cbb726d0SPaul Hoad 
19cbb726d0SPaul Hoad class FormatTestCSharp : public ::testing::Test {
20cbb726d0SPaul Hoad protected:
21cbb726d0SPaul Hoad   static std::string format(llvm::StringRef Code, unsigned Offset,
22cbb726d0SPaul Hoad                             unsigned Length, const FormatStyle &Style) {
23cbb726d0SPaul Hoad     LLVM_DEBUG(llvm::errs() << "---\n");
24cbb726d0SPaul Hoad     LLVM_DEBUG(llvm::errs() << Code << "\n\n");
25cbb726d0SPaul Hoad     std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
26cbb726d0SPaul Hoad     tooling::Replacements Replaces = reformat(Style, Code, Ranges);
27cbb726d0SPaul Hoad     auto Result = applyAllReplacements(Code, Replaces);
28cbb726d0SPaul Hoad     EXPECT_TRUE(static_cast<bool>(Result));
29cbb726d0SPaul Hoad     LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
30cbb726d0SPaul Hoad     return *Result;
31cbb726d0SPaul Hoad   }
32cbb726d0SPaul Hoad 
33cbb726d0SPaul Hoad   static std::string
34cbb726d0SPaul Hoad   format(llvm::StringRef Code,
35a2f963bbSPaul Hoad          const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
36cbb726d0SPaul Hoad     return format(Code, 0, Code.size(), Style);
37cbb726d0SPaul Hoad   }
38cbb726d0SPaul Hoad 
39cbb726d0SPaul Hoad   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
40a2f963bbSPaul Hoad     FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
41cbb726d0SPaul Hoad     Style.ColumnLimit = ColumnLimit;
42cbb726d0SPaul Hoad     return Style;
43cbb726d0SPaul Hoad   }
44cbb726d0SPaul Hoad 
45cbb726d0SPaul Hoad   static void verifyFormat(
46cbb726d0SPaul Hoad       llvm::StringRef Code,
47a2f963bbSPaul Hoad       const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
48cbb726d0SPaul Hoad     EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
49cbb726d0SPaul Hoad     EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
50cbb726d0SPaul Hoad   }
51cbb726d0SPaul Hoad };
52cbb726d0SPaul Hoad 
53cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpClass) {
54a2f963bbSPaul Hoad   verifyFormat("public class SomeClass\n"
55a2f963bbSPaul Hoad                "{\n"
56a2f963bbSPaul Hoad                "    void f()\n"
57a2f963bbSPaul Hoad                "    {\n"
58a2f963bbSPaul Hoad                "    }\n"
59a2f963bbSPaul Hoad                "    int g()\n"
60a2f963bbSPaul Hoad                "    {\n"
61a2f963bbSPaul Hoad                "        return 0;\n"
62a2f963bbSPaul Hoad                "    }\n"
63a2f963bbSPaul Hoad                "    void h()\n"
64a2f963bbSPaul Hoad                "    {\n"
65a2f963bbSPaul Hoad                "        while (true)\n"
66a2f963bbSPaul Hoad                "            f();\n"
67a2f963bbSPaul Hoad                "        for (;;)\n"
68a2f963bbSPaul Hoad                "            f();\n"
69a2f963bbSPaul Hoad                "        if (true)\n"
70a2f963bbSPaul Hoad                "            f();\n"
71cbb726d0SPaul Hoad                "    }\n"
72cbb726d0SPaul Hoad                "}");
73f40a7972SJonathan Coe 
74f40a7972SJonathan Coe   // Ensure that small and empty classes are handled correctly with condensed
75f40a7972SJonathan Coe   // (Google C++-like) brace-breaking style.
76f40a7972SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
77f40a7972SJonathan Coe   Style.BreakBeforeBraces = FormatStyle::BS_Attach;
78f40a7972SJonathan Coe 
79f40a7972SJonathan Coe   verifyFormat("public class SomeEmptyClass {}", Style);
80f40a7972SJonathan Coe 
81f40a7972SJonathan Coe   verifyFormat("public class SomeTinyClass {\n"
82f40a7972SJonathan Coe                "  int X;\n"
83f40a7972SJonathan Coe                "}",
84f40a7972SJonathan Coe                Style);
85f40a7972SJonathan Coe   verifyFormat("private class SomeTinyClass {\n"
86f40a7972SJonathan Coe                "  int X;\n"
87f40a7972SJonathan Coe                "}",
88f40a7972SJonathan Coe                Style);
89f40a7972SJonathan Coe   verifyFormat("protected class SomeTinyClass {\n"
90f40a7972SJonathan Coe                "  int X;\n"
91f40a7972SJonathan Coe                "}",
92f40a7972SJonathan Coe                Style);
93f40a7972SJonathan Coe   verifyFormat("internal class SomeTinyClass {\n"
94f40a7972SJonathan Coe                "  int X;\n"
95f40a7972SJonathan Coe                "}",
96f40a7972SJonathan Coe                Style);
97cbb726d0SPaul Hoad }
98cbb726d0SPaul Hoad 
99cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, AccessModifiers) {
100a2f963bbSPaul Hoad   verifyFormat("public String toString()\n"
101a2f963bbSPaul Hoad                "{\n"
102a2f963bbSPaul Hoad                "}");
103a2f963bbSPaul Hoad   verifyFormat("private String toString()\n"
104a2f963bbSPaul Hoad                "{\n"
105a2f963bbSPaul Hoad                "}");
106a2f963bbSPaul Hoad   verifyFormat("protected String toString()\n"
107a2f963bbSPaul Hoad                "{\n"
108a2f963bbSPaul Hoad                "}");
109a2f963bbSPaul Hoad   verifyFormat("internal String toString()\n"
110a2f963bbSPaul Hoad                "{\n"
111a2f963bbSPaul Hoad                "}");
112cbb726d0SPaul Hoad 
113a2f963bbSPaul Hoad   verifyFormat("public override String toString()\n"
114a2f963bbSPaul Hoad                "{\n"
115a2f963bbSPaul Hoad                "}");
116a2f963bbSPaul Hoad   verifyFormat("private override String toString()\n"
117a2f963bbSPaul Hoad                "{\n"
118a2f963bbSPaul Hoad                "}");
119a2f963bbSPaul Hoad   verifyFormat("protected override String toString()\n"
120a2f963bbSPaul Hoad                "{\n"
121a2f963bbSPaul Hoad                "}");
122a2f963bbSPaul Hoad   verifyFormat("internal override String toString()\n"
123a2f963bbSPaul Hoad                "{\n"
124a2f963bbSPaul Hoad                "}");
125cbb726d0SPaul Hoad 
126a2f963bbSPaul Hoad   verifyFormat("internal static String toString()\n"
127a2f963bbSPaul Hoad                "{\n"
128a2f963bbSPaul Hoad                "}");
129cbb726d0SPaul Hoad }
130cbb726d0SPaul Hoad 
131cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
132cbb726d0SPaul Hoad   verifyFormat("foo("
133cbb726d0SPaul Hoad                "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
134cbb726d0SPaul Hoad                "aaaaaa\");");
135cbb726d0SPaul Hoad }
136cbb726d0SPaul Hoad 
137cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
138cbb726d0SPaul Hoad   verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
139cbb726d0SPaul Hoad   // @"ABC\" + ToString("B") - handle embedded \ in literal string at
140cbb726d0SPaul Hoad   // the end
141cbb726d0SPaul Hoad   //
142cbb726d0SPaul Hoad   /*
143cbb726d0SPaul Hoad    * After removal of Lexer change we are currently not able
144cbb726d0SPaul Hoad    * To handle these cases
145cbb726d0SPaul Hoad    verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
146cbb726d0SPaul Hoad    verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
147cbb726d0SPaul Hoad    verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
148cbb726d0SPaul Hoad    verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
149cbb726d0SPaul Hoad   */
150cbb726d0SPaul Hoad }
151cbb726d0SPaul Hoad 
152cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
153cbb726d0SPaul Hoad   verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
154cbb726d0SPaul Hoad   verifyFormat("foo($\"aaaa{A}\");");
155cbb726d0SPaul Hoad   verifyFormat(
156cbb726d0SPaul Hoad       "foo($\"aaaa{A}"
157cbb726d0SPaul Hoad       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
158cbb726d0SPaul Hoad   verifyFormat("Name = $\"{firstName} {lastName}\";");
159cbb726d0SPaul Hoad 
160cbb726d0SPaul Hoad   // $"ABC\" + ToString("B") - handle embedded \ in literal string at
161cbb726d0SPaul Hoad   // the end
162cbb726d0SPaul Hoad   verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
163cbb726d0SPaul Hoad   verifyFormat("$\"{domain}\\\\{user}\"");
164cbb726d0SPaul Hoad   verifyFormat(
165cbb726d0SPaul Hoad       "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
166cbb726d0SPaul Hoad }
167cbb726d0SPaul Hoad 
168cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpFatArrows) {
169cbb726d0SPaul Hoad   verifyFormat("Task serverTask = Task.Run(async() => {");
170cbb726d0SPaul Hoad   verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
171cbb726d0SPaul Hoad }
172cbb726d0SPaul Hoad 
173c3af063cSJonathan Coe TEST_F(FormatTestCSharp, CSharpConditionalExpressions) {
174c3af063cSJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
175c3af063cSJonathan Coe   // conditional expression is not seen as a NullConditional.
176c3af063cSJonathan Coe   verifyFormat("var y = A < B ? -1 : 1;", Style);
177c3af063cSJonathan Coe }
178c3af063cSJonathan Coe 
179cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpNullConditional) {
1804c056583SPaul Hoad   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1814c056583SPaul Hoad   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
1824c056583SPaul Hoad 
183cbb726d0SPaul Hoad   verifyFormat(
184cbb726d0SPaul Hoad       "public Person(string firstName, string lastName, int? age = null)");
185cbb726d0SPaul Hoad 
1864c056583SPaul Hoad   verifyFormat("foo () {\n"
1874c056583SPaul Hoad                "  switch (args?.Length) {}\n"
1884c056583SPaul Hoad                "}",
1894c056583SPaul Hoad                Style);
1904c056583SPaul Hoad 
1914c056583SPaul Hoad   verifyFormat("switch (args?.Length) {}", Style);
192cbb726d0SPaul Hoad 
193a2f963bbSPaul Hoad   verifyFormat("public static void Main(string[] args)\n"
194a2f963bbSPaul Hoad                "{\n"
195a2f963bbSPaul Hoad                "    string dirPath = args?[0];\n"
196a2f963bbSPaul Hoad                "}");
1974c056583SPaul Hoad 
1984c056583SPaul Hoad   Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
1994c056583SPaul Hoad 
2004c056583SPaul Hoad   verifyFormat("switch(args?.Length) {}", Style);
201cbb726d0SPaul Hoad }
202cbb726d0SPaul Hoad 
203cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, Attributes) {
204cbb726d0SPaul Hoad   verifyFormat("[STAThread]\n"
205a2f963bbSPaul Hoad                "static void Main(string[] args)\n"
206a2f963bbSPaul Hoad                "{\n"
207a2f963bbSPaul Hoad                "}");
208cbb726d0SPaul Hoad 
209cbb726d0SPaul Hoad   verifyFormat("[TestMethod]\n"
210a2f963bbSPaul Hoad                "private class Test\n"
211a2f963bbSPaul Hoad                "{\n"
212a2f963bbSPaul Hoad                "}");
213cbb726d0SPaul Hoad 
214cbb726d0SPaul Hoad   verifyFormat("[TestMethod]\n"
215a2f963bbSPaul Hoad                "protected class Test\n"
216a2f963bbSPaul Hoad                "{\n"
217a2f963bbSPaul Hoad                "}");
218cbb726d0SPaul Hoad 
219cbb726d0SPaul Hoad   verifyFormat("[TestMethod]\n"
220a2f963bbSPaul Hoad                "internal class Test\n"
221a2f963bbSPaul Hoad                "{\n"
222a2f963bbSPaul Hoad                "}");
223cbb726d0SPaul Hoad 
224cbb726d0SPaul Hoad   verifyFormat("[TestMethod]\n"
225a2f963bbSPaul Hoad                "class Test\n"
226a2f963bbSPaul Hoad                "{\n"
227a2f963bbSPaul Hoad                "}");
228cbb726d0SPaul Hoad 
229cbb726d0SPaul Hoad   verifyFormat("[TestMethod]\n"
230cbb726d0SPaul Hoad                "[DeploymentItem(\"Test.txt\")]\n"
231a2f963bbSPaul Hoad                "public class Test\n"
232a2f963bbSPaul Hoad                "{\n"
233a2f963bbSPaul Hoad                "}");
234cbb726d0SPaul Hoad 
235cbb726d0SPaul Hoad   verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
236cbb726d0SPaul Hoad                "[System.Runtime.InteropServices.ComVisible(true)]\n"
237a2f963bbSPaul Hoad                "public sealed class STAThreadAttribute : Attribute\n"
238a2f963bbSPaul Hoad                "{\n"
239a2f963bbSPaul Hoad                "}");
240cbb726d0SPaul Hoad 
241cbb726d0SPaul Hoad   verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
242cbb726d0SPaul Hoad                "provided port\")]\n"
243a2f963bbSPaul Hoad                "class Test\n"
244a2f963bbSPaul Hoad                "{\n"
245a2f963bbSPaul Hoad                "}");
246cbb726d0SPaul Hoad 
247cbb726d0SPaul Hoad   verifyFormat("[TestMethod]\n"
248f22b0727SJonathan Coe                "public string Host { set; get; }");
249cbb726d0SPaul Hoad 
250ffb48d48Smydeveloperday   // Adjacent properties should not cause line wrapping issues
251ffb48d48Smydeveloperday   verifyFormat("[JsonProperty(\"foo\")]\n"
252ffb48d48Smydeveloperday                "public string Foo { set; get; }\n"
253ffb48d48Smydeveloperday                "[JsonProperty(\"bar\")]\n"
254ffb48d48Smydeveloperday                "public string Bar { set; get; }\n"
255ffb48d48Smydeveloperday                "[JsonProperty(\"bar\")]\n"
256ffb48d48Smydeveloperday                "protected string Bar { set; get; }\n"
257ffb48d48Smydeveloperday                "[JsonProperty(\"bar\")]\n"
258ffb48d48Smydeveloperday                "internal string Bar { set; get; }");
259ffb48d48Smydeveloperday 
260ffb48d48Smydeveloperday   // Multiple attributes should always be split (not just the first ones)
261ffb48d48Smydeveloperday   verifyFormat("[XmlIgnore]\n"
262ffb48d48Smydeveloperday                "[JsonProperty(\"foo\")]\n"
263ffb48d48Smydeveloperday                "public string Foo { set; get; }");
264ffb48d48Smydeveloperday 
265ffb48d48Smydeveloperday   verifyFormat("[XmlIgnore]\n"
266ffb48d48Smydeveloperday                "[JsonProperty(\"foo\")]\n"
267ffb48d48Smydeveloperday                "public string Foo { set; get; }\n"
268ffb48d48Smydeveloperday                "[XmlIgnore]\n"
269ffb48d48Smydeveloperday                "[JsonProperty(\"bar\")]\n"
270ffb48d48Smydeveloperday                "public string Bar { set; get; }");
271ffb48d48Smydeveloperday 
272ffb48d48Smydeveloperday   verifyFormat("[XmlIgnore]\n"
273ffb48d48Smydeveloperday                "[ScriptIgnore]\n"
274ffb48d48Smydeveloperday                "[JsonProperty(\"foo\")]\n"
275ffb48d48Smydeveloperday                "public string Foo { set; get; }\n"
276ffb48d48Smydeveloperday                "[XmlIgnore]\n"
277ffb48d48Smydeveloperday                "[ScriptIgnore]\n"
278ffb48d48Smydeveloperday                "[JsonProperty(\"bar\")]\n"
279ffb48d48Smydeveloperday                "public string Bar { set; get; }");
280ffb48d48Smydeveloperday 
281cbb726d0SPaul Hoad   verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
282cbb726d0SPaul Hoad                "listening on provided host\")]\n"
283f22b0727SJonathan Coe                "public string Host { set; get; }");
28450d8977cSJonathan Coe 
28550d8977cSJonathan Coe   verifyFormat(
28650d8977cSJonathan Coe       "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n"
28750d8977cSJonathan Coe       "// The const char* returned by hello_world must not be deleted.\n"
28850d8977cSJonathan Coe       "private static extern IntPtr HelloFromCpp();)");
289ca1fd460SJonathan Coe 
290b46f925dSJonathan Coe   // Class attributes go on their own line and do not affect layout of
291b46f925dSJonathan Coe   // interfaces. Line wrapping decisions previously caused each interface to be
292b46f925dSJonathan Coe   // on its own line.
293b46f925dSJonathan Coe   verifyFormat("[SomeAttribute]\n"
294b46f925dSJonathan Coe                "[SomeOtherAttribute]\n"
295b46f925dSJonathan Coe                "public class A : IShape, IAnimal, IVehicle\n"
296b46f925dSJonathan Coe                "{\n"
297b46f925dSJonathan Coe                "    int X;\n"
298b46f925dSJonathan Coe                "}");
299b46f925dSJonathan Coe 
300b46f925dSJonathan Coe   // Attributes in a method declaration do not cause line wrapping.
301b46f925dSJonathan Coe   verifyFormat("void MethodA([In][Out] ref double x)\n"
302b46f925dSJonathan Coe                "{\n"
303b46f925dSJonathan Coe                "}");
304b46f925dSJonathan Coe 
305ffb48d48Smydeveloperday   verifyFormat("void MethodA([In, Out] ref double x)\n"
306ffb48d48Smydeveloperday                "{\n"
307ffb48d48Smydeveloperday                "}");
308ffb48d48Smydeveloperday 
309ffb48d48Smydeveloperday   verifyFormat("void MethodA([In, Out] double[] x)\n"
310ffb48d48Smydeveloperday                "{\n"
311ffb48d48Smydeveloperday                "}");
312ffb48d48Smydeveloperday 
313ffb48d48Smydeveloperday   verifyFormat("void MethodA([In] double[] x)\n"
314ffb48d48Smydeveloperday                "{\n"
315ffb48d48Smydeveloperday                "}");
316ffb48d48Smydeveloperday 
317ffb48d48Smydeveloperday   verifyFormat("void MethodA(int[] x)\n"
318ffb48d48Smydeveloperday                "{\n"
319ffb48d48Smydeveloperday                "}");
320ffb48d48Smydeveloperday   verifyFormat("void MethodA(int[][] x)\n"
321ffb48d48Smydeveloperday                "{\n"
322ffb48d48Smydeveloperday                "}");
323ffb48d48Smydeveloperday   verifyFormat("void MethodA([] x)\n"
324ffb48d48Smydeveloperday                "{\n"
325ffb48d48Smydeveloperday                "}");
326ffb48d48Smydeveloperday 
327ffb48d48Smydeveloperday   verifyFormat("public void Log([CallerLineNumber] int line = -1, "
328ffb48d48Smydeveloperday                "[CallerFilePath] string path = null,\n"
329ffb48d48Smydeveloperday                "                [CallerMemberName] string name = null)\n"
330ffb48d48Smydeveloperday                "{\n"
331ffb48d48Smydeveloperday                "}");
332ffb48d48Smydeveloperday 
3339f8a7e82SJonathan Coe   // [] in an attribute do not cause premature line wrapping or indenting.
3349f8a7e82SJonathan Coe   verifyFormat(R"(//
3359f8a7e82SJonathan Coe public class A
3369f8a7e82SJonathan Coe {
3379f8a7e82SJonathan Coe     [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)]
3389f8a7e82SJonathan Coe     [DoNotSerialize]
3399f8a7e82SJonathan Coe     public Data MemberVariable;
3409f8a7e82SJonathan Coe })");
3419f8a7e82SJonathan Coe 
342ca1fd460SJonathan Coe   //  Unwrappable lines go on a line of their own.
343ca1fd460SJonathan Coe   // 'target:' is not treated as a label.
344ca1fd460SJonathan Coe   // Modify Style to enforce a column limit.
345ca1fd460SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
346ca1fd460SJonathan Coe   Style.ColumnLimit = 10;
347ca1fd460SJonathan Coe   verifyFormat(R"([assembly:InternalsVisibleTo(
348ca1fd460SJonathan Coe     "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])",
349ca1fd460SJonathan Coe                Style);
350cbb726d0SPaul Hoad }
351cbb726d0SPaul Hoad 
352719087bbSPaul Hoad TEST_F(FormatTestCSharp, CSharpUsing) {
353719087bbSPaul Hoad   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
354719087bbSPaul Hoad   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
355719087bbSPaul Hoad   verifyFormat("public void foo () {\n"
356719087bbSPaul Hoad                "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
3571e0174a9SKrasimir Georgiev                "  using () {}\n"
358719087bbSPaul Hoad                "}",
359719087bbSPaul Hoad                Style);
360719087bbSPaul Hoad 
3611e0174a9SKrasimir Georgiev   // Ensure clang-format affects top-level snippets correctly.
3624c056583SPaul Hoad   verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
3634c056583SPaul Hoad                Style);
3644c056583SPaul Hoad 
365719087bbSPaul Hoad   Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
366719087bbSPaul Hoad   verifyFormat("public void foo() {\n"
367719087bbSPaul Hoad                "  using(StreamWriter sw = new StreamWriter(filenameB)) {}\n"
3681e0174a9SKrasimir Georgiev                "  using() {}\n"
369719087bbSPaul Hoad                "}",
370719087bbSPaul Hoad                Style);
3714c056583SPaul Hoad 
3721e0174a9SKrasimir Georgiev   // Ensure clang-format affects top-level snippets correctly.
3731e0174a9SKrasimir Georgiev   verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}",
3741e0174a9SKrasimir Georgiev                Style);
3751e0174a9SKrasimir Georgiev 
3761e0174a9SKrasimir Georgiev   Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
3771e0174a9SKrasimir Georgiev   verifyFormat("public void foo() {\n"
3781e0174a9SKrasimir Georgiev                "  using (StreamWriter sw = new StreamWriter(filenameA)) {}\n"
3791e0174a9SKrasimir Georgiev                "  using () {}\n"
3801e0174a9SKrasimir Georgiev                "}",
3811e0174a9SKrasimir Georgiev                Style);
3821e0174a9SKrasimir Georgiev 
3831e0174a9SKrasimir Georgiev   // Ensure clang-format affects top-level snippets correctly.
3841e0174a9SKrasimir Georgiev   verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}",
3851e0174a9SKrasimir Georgiev                Style);
3861e0174a9SKrasimir Georgiev 
3871e0174a9SKrasimir Georgiev   Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses;
3881e0174a9SKrasimir Georgiev   verifyFormat("public void foo() {\n"
3891e0174a9SKrasimir Georgiev                "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
3901e0174a9SKrasimir Georgiev                "  using() {}\n"
3911e0174a9SKrasimir Georgiev                "}",
3921e0174a9SKrasimir Georgiev                Style);
3931e0174a9SKrasimir Georgiev 
3941e0174a9SKrasimir Georgiev   // Ensure clang-format affects top-level snippets correctly.
3954c056583SPaul Hoad   verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
3964c056583SPaul Hoad                Style);
397719087bbSPaul Hoad }
398719087bbSPaul Hoad 
399cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpRegions) {
400cbb726d0SPaul Hoad   verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
401cbb726d0SPaul Hoad                "aaaaaaaaaaaaaaa long region");
402cbb726d0SPaul Hoad }
403cbb726d0SPaul Hoad 
404cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
405ed367b9dSmydeveloperday   // AfterEnum is true by default.
406ed367b9dSmydeveloperday   verifyFormat("public enum var\n"
407ed367b9dSmydeveloperday                "{\n"
408292058a5SAaron Smith                "    none,\n"
409292058a5SAaron Smith                "    @string,\n"
410292058a5SAaron Smith                "    bool,\n"
411292058a5SAaron Smith                "    @enum\n"
412292058a5SAaron Smith                "}");
413cbb726d0SPaul Hoad }
414cbb726d0SPaul Hoad 
415cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
416cbb726d0SPaul Hoad   verifyFormat("var test = ABC ?? DEF");
417cbb726d0SPaul Hoad   verifyFormat("string myname = name ?? \"ABC\";");
418cbb726d0SPaul Hoad   verifyFormat("return _name ?? \"DEF\";");
419cbb726d0SPaul Hoad }
420cbb726d0SPaul Hoad 
421a437befaSEliza Velasquez TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) {
422a437befaSEliza Velasquez   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
423a437befaSEliza Velasquez   Style.SpaceBeforeAssignmentOperators = true;
424a437befaSEliza Velasquez 
425a437befaSEliza Velasquez   verifyFormat(R"(test ??= ABC;)", Style);
426a437befaSEliza Velasquez   verifyFormat(R"(test ??= true;)", Style);
427a437befaSEliza Velasquez 
428a437befaSEliza Velasquez   Style.SpaceBeforeAssignmentOperators = false;
429a437befaSEliza Velasquez 
430a437befaSEliza Velasquez   verifyFormat(R"(test??= ABC;)", Style);
431a437befaSEliza Velasquez   verifyFormat(R"(test??= true;)", Style);
432a437befaSEliza Velasquez }
433a437befaSEliza Velasquez 
434a437befaSEliza Velasquez TEST_F(FormatTestCSharp, CSharpNullForgiving) {
435a437befaSEliza Velasquez   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
436a437befaSEliza Velasquez 
437a437befaSEliza Velasquez   verifyFormat("var test = null!;", Style);
438a437befaSEliza Velasquez   verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style);
439a437befaSEliza Velasquez   verifyFormat("int test = (1! + 2 + bar! + foo())!", Style);
440a437befaSEliza Velasquez   verifyFormat(R"(test ??= !foo!;)", Style);
441a437befaSEliza Velasquez   verifyFormat("test = !bar! ?? !foo!;", Style);
442a437befaSEliza Velasquez   verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && "
443a437befaSEliza Velasquez                "!false! && !bar()! + (!foo()))!",
444a437befaSEliza Velasquez                Style);
445a437befaSEliza Velasquez 
446a437befaSEliza Velasquez   // Check that line break keeps identifier with the bang.
447a437befaSEliza Velasquez   Style.ColumnLimit = 14;
448a437befaSEliza Velasquez 
449a437befaSEliza Velasquez   verifyFormat("var test =\n"
450a437befaSEliza Velasquez                "    foo!;",
451a437befaSEliza Velasquez                Style);
452a437befaSEliza Velasquez }
453a437befaSEliza Velasquez 
454a2f963bbSPaul Hoad TEST_F(FormatTestCSharp, AttributesIndentation) {
455a2f963bbSPaul Hoad   FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
456a2f963bbSPaul Hoad   Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
457a2f963bbSPaul Hoad 
458a2f963bbSPaul Hoad   verifyFormat("[STAThread]\n"
459a2f963bbSPaul Hoad                "static void Main(string[] args)\n"
460a2f963bbSPaul Hoad                "{\n"
461a2f963bbSPaul Hoad                "}",
462a2f963bbSPaul Hoad                Style);
463a2f963bbSPaul Hoad 
464a2f963bbSPaul Hoad   verifyFormat("[STAThread]\n"
465a2f963bbSPaul Hoad                "void "
466a2f963bbSPaul Hoad                "veryLooooooooooooooongFunctionName(string[] args)\n"
467a2f963bbSPaul Hoad                "{\n"
468a2f963bbSPaul Hoad                "}",
469a2f963bbSPaul Hoad                Style);
470a2f963bbSPaul Hoad 
471a2f963bbSPaul Hoad   verifyFormat("[STAThread]\n"
472a2f963bbSPaul Hoad                "veryLoooooooooooooooooooongReturnType "
473a2f963bbSPaul Hoad                "veryLooooooooooooooongFunctionName(string[] args)\n"
474a2f963bbSPaul Hoad                "{\n"
475a2f963bbSPaul Hoad                "}",
476a2f963bbSPaul Hoad                Style);
477a2f963bbSPaul Hoad 
478a2f963bbSPaul Hoad   verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n"
479a2f963bbSPaul Hoad                "public override X Y()\n"
480a2f963bbSPaul Hoad                "{\n"
481a2f963bbSPaul Hoad                "}\n",
482a2f963bbSPaul Hoad                Style);
483a2f963bbSPaul Hoad 
484a2f963bbSPaul Hoad   verifyFormat("[SuppressMessage]\n"
485a2f963bbSPaul Hoad                "public X Y()\n"
486a2f963bbSPaul Hoad                "{\n"
487a2f963bbSPaul Hoad                "}\n",
488a2f963bbSPaul Hoad                Style);
489a2f963bbSPaul Hoad 
490a2f963bbSPaul Hoad   verifyFormat("[SuppressMessage]\n"
491a2f963bbSPaul Hoad                "public override X Y()\n"
492a2f963bbSPaul Hoad                "{\n"
493a2f963bbSPaul Hoad                "}\n",
494a2f963bbSPaul Hoad                Style);
495a2f963bbSPaul Hoad 
496a2f963bbSPaul Hoad   verifyFormat("public A(B b) : base(b)\n"
497a2f963bbSPaul Hoad                "{\n"
498a2f963bbSPaul Hoad                "    [SuppressMessage]\n"
499a2f963bbSPaul Hoad                "    public override X Y()\n"
500a2f963bbSPaul Hoad                "    {\n"
501a2f963bbSPaul Hoad                "    }\n"
502a2f963bbSPaul Hoad                "}\n",
503a2f963bbSPaul Hoad                Style);
5042f209ccfSmydeveloperday 
5052f209ccfSmydeveloperday   verifyFormat("public A : Base\n"
5062f209ccfSmydeveloperday                "{\n"
5072f209ccfSmydeveloperday                "}\n"
5082f209ccfSmydeveloperday                "[Test]\n"
5092f209ccfSmydeveloperday                "public Foo()\n"
5102f209ccfSmydeveloperday                "{\n"
5112f209ccfSmydeveloperday                "}\n",
5122f209ccfSmydeveloperday                Style);
5132f209ccfSmydeveloperday 
5142f209ccfSmydeveloperday   verifyFormat("namespace\n"
5152f209ccfSmydeveloperday                "{\n"
5162f209ccfSmydeveloperday                "public A : Base\n"
5172f209ccfSmydeveloperday                "{\n"
5182f209ccfSmydeveloperday                "}\n"
5192f209ccfSmydeveloperday                "[Test]\n"
5202f209ccfSmydeveloperday                "public Foo()\n"
5212f209ccfSmydeveloperday                "{\n"
5222f209ccfSmydeveloperday                "}\n"
5232f209ccfSmydeveloperday                "}\n",
5242f209ccfSmydeveloperday                Style);
525a2f963bbSPaul Hoad }
526a2f963bbSPaul Hoad 
5274c056583SPaul Hoad TEST_F(FormatTestCSharp, CSharpSpaceBefore) {
5284c056583SPaul Hoad   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
5294c056583SPaul Hoad   Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
5304c056583SPaul Hoad 
5314c056583SPaul Hoad   verifyFormat("List<string> list;", Style);
5324c056583SPaul Hoad   verifyFormat("Dictionary<string, string> dict;", Style);
5334c056583SPaul Hoad 
5344c056583SPaul Hoad   verifyFormat("for (int i = 0; i < size (); i++) {\n"
5354c056583SPaul Hoad                "}",
5364c056583SPaul Hoad                Style);
5374c056583SPaul Hoad   verifyFormat("foreach (var x in y) {\n"
5384c056583SPaul Hoad                "}",
5394c056583SPaul Hoad                Style);
5404c056583SPaul Hoad   verifyFormat("switch (x) {}", Style);
5414c056583SPaul Hoad   verifyFormat("do {\n"
5424c056583SPaul Hoad                "} while (x);",
5434c056583SPaul Hoad                Style);
5444c056583SPaul Hoad 
5454c056583SPaul Hoad   Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
5464c056583SPaul Hoad 
5474c056583SPaul Hoad   verifyFormat("List<string> list;", Style);
5484c056583SPaul Hoad   verifyFormat("Dictionary<string, string> dict;", Style);
5494c056583SPaul Hoad 
5504c056583SPaul Hoad   verifyFormat("for(int i = 0; i < size(); i++) {\n"
5514c056583SPaul Hoad                "}",
5524c056583SPaul Hoad                Style);
5534c056583SPaul Hoad   verifyFormat("foreach(var x in y) {\n"
5544c056583SPaul Hoad                "}",
5554c056583SPaul Hoad                Style);
5564c056583SPaul Hoad   verifyFormat("switch(x) {}", Style);
5574c056583SPaul Hoad   verifyFormat("do {\n"
5584c056583SPaul Hoad                "} while(x);",
5594c056583SPaul Hoad                Style);
5604c056583SPaul Hoad }
5614c056583SPaul Hoad 
562d82adf32Smydeveloperday TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) {
563d82adf32Smydeveloperday   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
564d82adf32Smydeveloperday 
565d82adf32Smydeveloperday   verifyFormat("(int)x / y;", Style);
566d82adf32Smydeveloperday 
567d82adf32Smydeveloperday   Style.SpaceAfterCStyleCast = true;
568d82adf32Smydeveloperday   verifyFormat("(int) x / y;", Style);
569d82adf32Smydeveloperday }
570d82adf32Smydeveloperday 
57136a8f7f6SKrasimir Georgiev TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) {
57236a8f7f6SKrasimir Georgiev   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
57336a8f7f6SKrasimir Georgiev 
574f9f0919dSJonathan Coe   verifyFormat(R"(string str = @"""";)", Style);
575f9f0919dSJonathan Coe   verifyFormat(R"(string str = @"""Hello world""";)", Style);
576f9f0919dSJonathan Coe   verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style);
577*0ffb3dd3Sowenca   verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
57836a8f7f6SKrasimir Georgiev }
57936a8f7f6SKrasimir Georgiev 
5809d212e83SJonathan Coe TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) {
5819d212e83SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
5829d212e83SJonathan Coe 
5839d212e83SJonathan Coe   verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style);
5849d212e83SJonathan Coe   verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style);
5859d212e83SJonathan Coe   verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style);
5869d212e83SJonathan Coe }
5879d212e83SJonathan Coe 
588f9f0919dSJonathan Coe TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) {
589f9f0919dSJonathan Coe   // Use MS style as Google Style inserts a line break before multiline strings.
590f9f0919dSJonathan Coe 
591f9f0919dSJonathan Coe   // verifyFormat does not understand multiline C# string-literals
592f9f0919dSJonathan Coe   // so check the format explicitly.
593f9f0919dSJonathan Coe 
594f9f0919dSJonathan Coe   FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
595f9f0919dSJonathan Coe 
596f9f0919dSJonathan Coe   std::string Code = R"(string s1 = $@"some code:
597f9f0919dSJonathan Coe   class {className} {{
598f9f0919dSJonathan Coe     {className}() {{}}
599f9f0919dSJonathan Coe   }}";)";
600f9f0919dSJonathan Coe 
601f9f0919dSJonathan Coe   EXPECT_EQ(Code, format(Code, Style));
602f9f0919dSJonathan Coe 
603f9f0919dSJonathan Coe   // Multiline string in the middle of a function call.
604f9f0919dSJonathan Coe   Code = R"(
605f9f0919dSJonathan Coe var x = foo(className, $@"some code:
606f9f0919dSJonathan Coe   class {className} {{
607f9f0919dSJonathan Coe     {className}() {{}}
608f9f0919dSJonathan Coe   }}",
609f9f0919dSJonathan Coe             y);)"; // y aligned with `className` arg.
610f9f0919dSJonathan Coe 
611f9f0919dSJonathan Coe   EXPECT_EQ(Code, format(Code, Style));
612f9f0919dSJonathan Coe 
613f9f0919dSJonathan Coe   // Interpolated string with embedded multiline string.
614f9f0919dSJonathan Coe   Code = R"(Console.WriteLine($"{string.Join(@",
615f9f0919dSJonathan Coe 		", values)}");)";
616f9f0919dSJonathan Coe 
617f9f0919dSJonathan Coe   EXPECT_EQ(Code, format(Code, Style));
618f9f0919dSJonathan Coe }
619f9f0919dSJonathan Coe 
6207117066bSJonathan Coe TEST_F(FormatTestCSharp, CSharpLambdas) {
6217117066bSJonathan Coe   FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
6227117066bSJonathan Coe   FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
6237117066bSJonathan Coe 
6247117066bSJonathan Coe   verifyFormat(R"(//
6257117066bSJonathan Coe class MyClass {
6267117066bSJonathan Coe   Action<string> greet = name => {
6277117066bSJonathan Coe     string greeting = $"Hello {name}!";
6287117066bSJonathan Coe     Console.WriteLine(greeting);
6297117066bSJonathan Coe   };
6307117066bSJonathan Coe })",
6317117066bSJonathan Coe                GoogleStyle);
6327117066bSJonathan Coe 
6337117066bSJonathan Coe   // Microsoft Style:
6347117066bSJonathan Coe   // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas
6357117066bSJonathan Coe   verifyFormat(R"(//
6367117066bSJonathan Coe class MyClass
6377117066bSJonathan Coe {
6387117066bSJonathan Coe     Action<string> greet = name =>
6397117066bSJonathan Coe     {
6407117066bSJonathan Coe         string greeting = $"Hello {name}!";
6417117066bSJonathan Coe         Console.WriteLine(greeting);
6427117066bSJonathan Coe     };
6437117066bSJonathan Coe })",
6447117066bSJonathan Coe                MicrosoftStyle);
645f9937106Smydeveloperday 
646f9937106Smydeveloperday   verifyFormat("void bar()\n"
647f9937106Smydeveloperday                "{\n"
648f9937106Smydeveloperday                "    Function(Val, (Action)(() =>\n"
649f9937106Smydeveloperday                "                           {\n"
650f9937106Smydeveloperday                "                               lock (mylock)\n"
651f9937106Smydeveloperday                "                               {\n"
652f9937106Smydeveloperday                "                                   if (true)\n"
653f9937106Smydeveloperday                "                                   {\n"
654f9937106Smydeveloperday                "                                       A.Remove(item);\n"
655f9937106Smydeveloperday                "                                   }\n"
656f9937106Smydeveloperday                "                               }\n"
657f9937106Smydeveloperday                "                           }));\n"
658f9937106Smydeveloperday                "}",
659f9937106Smydeveloperday                MicrosoftStyle);
660f9937106Smydeveloperday 
661f9937106Smydeveloperday   verifyFormat("void baz()\n"
662f9937106Smydeveloperday                "{\n"
663f9937106Smydeveloperday                "    Function(Val, (Action)(() =>\n"
664f9937106Smydeveloperday                "                           {\n"
665f9937106Smydeveloperday                "                               using (var a = new Lock())\n"
666f9937106Smydeveloperday                "                               {\n"
667f9937106Smydeveloperday                "                                   if (true)\n"
668f9937106Smydeveloperday                "                                   {\n"
669f9937106Smydeveloperday                "                                       A.Remove(item);\n"
670f9937106Smydeveloperday                "                                   }\n"
671f9937106Smydeveloperday                "                               }\n"
672f9937106Smydeveloperday                "                           }));\n"
673f9937106Smydeveloperday                "}",
674f9937106Smydeveloperday                MicrosoftStyle);
675f9937106Smydeveloperday 
676f9937106Smydeveloperday   verifyFormat("void baz()\n"
677f9937106Smydeveloperday                "{\n"
678f9937106Smydeveloperday                "    Function(Val, (Action)(() =>\n"
679f9937106Smydeveloperday                "                           {\n"
680f9937106Smydeveloperday                "                               if (true)\n"
681f9937106Smydeveloperday                "                               {\n"
682f9937106Smydeveloperday                "                                   A.Remove(item);\n"
683f9937106Smydeveloperday                "                               }\n"
684f9937106Smydeveloperday                "                           }));\n"
685f9937106Smydeveloperday                "}",
686f9937106Smydeveloperday                MicrosoftStyle);
687f9937106Smydeveloperday 
688f9937106Smydeveloperday   verifyFormat("void baz()\n"
689f9937106Smydeveloperday                "{\n"
690f9937106Smydeveloperday                "    Function(Val, (Action)(() =>\n"
691f9937106Smydeveloperday                "                           {\n"
692f9937106Smydeveloperday                "                               do\n"
693f9937106Smydeveloperday                "                               {\n"
694f9937106Smydeveloperday                "                                   A.Remove(item);\n"
695f9937106Smydeveloperday                "                               } while (true)\n"
696f9937106Smydeveloperday                "                           }));\n"
697f9937106Smydeveloperday                "}",
698f9937106Smydeveloperday                MicrosoftStyle);
699f9937106Smydeveloperday 
700f9937106Smydeveloperday   verifyFormat("void baz()\n"
701f9937106Smydeveloperday                "{\n"
702f9937106Smydeveloperday                "    Function(Val, (Action)(() =>\n"
703f9937106Smydeveloperday                "                           { A.Remove(item); }));\n"
704f9937106Smydeveloperday                "}",
705f9937106Smydeveloperday                MicrosoftStyle);
706f9937106Smydeveloperday 
707f9937106Smydeveloperday   verifyFormat("void bar()\n"
708f9937106Smydeveloperday                "{\n"
709f9937106Smydeveloperday                "    Function(Val, (() =>\n"
710f9937106Smydeveloperday                "                   {\n"
711f9937106Smydeveloperday                "                       lock (mylock)\n"
712f9937106Smydeveloperday                "                       {\n"
713f9937106Smydeveloperday                "                           if (true)\n"
714f9937106Smydeveloperday                "                           {\n"
715f9937106Smydeveloperday                "                               A.Remove(item);\n"
716f9937106Smydeveloperday                "                           }\n"
717f9937106Smydeveloperday                "                       }\n"
718f9937106Smydeveloperday                "                   }));\n"
719f9937106Smydeveloperday                "}",
720f9937106Smydeveloperday                MicrosoftStyle);
721f9937106Smydeveloperday   verifyFormat("void bar()\n"
722f9937106Smydeveloperday                "{\n"
723f9937106Smydeveloperday                "    Function((() =>\n"
724f9937106Smydeveloperday                "              {\n"
725f9937106Smydeveloperday                "                  lock (mylock)\n"
726f9937106Smydeveloperday                "                  {\n"
727f9937106Smydeveloperday                "                      if (true)\n"
728f9937106Smydeveloperday                "                      {\n"
729f9937106Smydeveloperday                "                          A.Remove(item);\n"
730f9937106Smydeveloperday                "                      }\n"
731f9937106Smydeveloperday                "                  }\n"
732f9937106Smydeveloperday                "              }));\n"
733f9937106Smydeveloperday                "}",
734f9937106Smydeveloperday                MicrosoftStyle);
735f9937106Smydeveloperday 
736f9937106Smydeveloperday   MicrosoftStyle.IndentWidth = 2;
737f9937106Smydeveloperday   verifyFormat("void bar()\n"
738f9937106Smydeveloperday                "{\n"
739f9937106Smydeveloperday                "  Function((() =>\n"
740f9937106Smydeveloperday                "            {\n"
741f9937106Smydeveloperday                "              lock (mylock)\n"
742f9937106Smydeveloperday                "              {\n"
743f9937106Smydeveloperday                "                if (true)\n"
744f9937106Smydeveloperday                "                {\n"
745f9937106Smydeveloperday                "                  A.Remove(item);\n"
746f9937106Smydeveloperday                "                }\n"
747f9937106Smydeveloperday                "              }\n"
748f9937106Smydeveloperday                "            }));\n"
749f9937106Smydeveloperday                "}",
750f9937106Smydeveloperday                MicrosoftStyle);
751f9937106Smydeveloperday   verifyFormat("void bar() {\n"
752f9937106Smydeveloperday                "  Function((() => {\n"
753f9937106Smydeveloperday                "    lock (mylock) {\n"
754f9937106Smydeveloperday                "      if (true) {\n"
755f9937106Smydeveloperday                "        A.Remove(item);\n"
756f9937106Smydeveloperday                "      }\n"
757f9937106Smydeveloperday                "    }\n"
758f9937106Smydeveloperday                "  }));\n"
759f9937106Smydeveloperday                "}",
760f9937106Smydeveloperday                GoogleStyle);
7617117066bSJonathan Coe }
7627117066bSJonathan Coe 
763163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) {
764163c13feSPeter Stys   FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
765163c13feSPeter Stys   FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
766163c13feSPeter Stys 
767163c13feSPeter Stys   verifyFormat(R"(//
768163c13feSPeter Stys public class Sample
769163c13feSPeter Stys {
770163c13feSPeter Stys     public void Test()
771163c13feSPeter Stys     {
772163c13feSPeter Stys         while (true)
773163c13feSPeter Stys         {
774163c13feSPeter Stys             preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
775163c13feSPeter Stys             CodeThatFollowsLambda();
776163c13feSPeter Stys             IsWellAligned();
777163c13feSPeter Stys         }
778163c13feSPeter Stys     }
779163c13feSPeter Stys })",
780163c13feSPeter Stys                MicrosoftStyle);
781163c13feSPeter Stys 
782163c13feSPeter Stys   verifyFormat(R"(//
783163c13feSPeter Stys public class Sample {
784163c13feSPeter Stys   public void Test() {
785163c13feSPeter Stys     while (true) {
786163c13feSPeter Stys       preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
787163c13feSPeter Stys       CodeThatFollowsLambda();
788163c13feSPeter Stys       IsWellAligned();
789163c13feSPeter Stys     }
790163c13feSPeter Stys   }
791163c13feSPeter Stys })",
792163c13feSPeter Stys                GoogleStyle);
793163c13feSPeter Stys }
794163c13feSPeter Stys 
795163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) {
796163c13feSPeter Stys   FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
797163c13feSPeter Stys   FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
798163c13feSPeter Stys 
799163c13feSPeter Stys   verifyFormat(R"(//
800163c13feSPeter Stys public class Test
801163c13feSPeter Stys {
802163c13feSPeter Stys     private static void ComplexLambda(BuildReport protoReport)
803163c13feSPeter Stys     {
804163c13feSPeter Stys         allSelectedScenes =
805163c13feSPeter Stys             veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled)
806163c13feSPeter Stys                 .Select(scene => scene.path)
807163c13feSPeter Stys                 .ToArray();
808163c13feSPeter Stys         if (allSelectedScenes.Count == 0)
809163c13feSPeter Stys         {
810163c13feSPeter Stys             return;
811163c13feSPeter Stys         }
812163c13feSPeter Stys         Functions();
813163c13feSPeter Stys         AreWell();
814163c13feSPeter Stys         Aligned();
815163c13feSPeter Stys         AfterLambdaBlock();
816163c13feSPeter Stys     }
817163c13feSPeter Stys })",
818163c13feSPeter Stys                MicrosoftStyle);
819163c13feSPeter Stys 
820163c13feSPeter Stys   verifyFormat(R"(//
821163c13feSPeter Stys public class Test {
822163c13feSPeter Stys   private static void ComplexLambda(BuildReport protoReport) {
823163c13feSPeter Stys     allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds
824163c13feSPeter Stys                             .Where(scene => scene.enabled)
825163c13feSPeter Stys                             .Select(scene => scene.path)
826163c13feSPeter Stys                             .ToArray();
827163c13feSPeter Stys     if (allSelectedScenes.Count == 0) {
828163c13feSPeter Stys       return;
829163c13feSPeter Stys     }
830163c13feSPeter Stys     Functions();
831163c13feSPeter Stys     AreWell();
832163c13feSPeter Stys     Aligned();
833163c13feSPeter Stys     AfterLambdaBlock();
834163c13feSPeter Stys   }
835163c13feSPeter Stys })",
836163c13feSPeter Stys                GoogleStyle);
837163c13feSPeter Stys }
838163c13feSPeter Stys 
839163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) {
840163c13feSPeter Stys   FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
841163c13feSPeter Stys   FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
842163c13feSPeter Stys 
843163c13feSPeter Stys   verifyFormat(R"(//
844163c13feSPeter Stys public class Test
845163c13feSPeter Stys {
846163c13feSPeter Stys     private static void MultipleLambdas(BuildReport protoReport)
847163c13feSPeter Stys     {
848163c13feSPeter Stys         allSelectedScenes =
849163c13feSPeter Stys             veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled)
850163c13feSPeter Stys                 .Select(scene => scene.path)
851163c13feSPeter Stys                 .ToArray();
852163c13feSPeter Stys         preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
853163c13feSPeter Stys         if (allSelectedScenes.Count == 0)
854163c13feSPeter Stys         {
855163c13feSPeter Stys             return;
856163c13feSPeter Stys         }
857163c13feSPeter Stys         Functions();
858163c13feSPeter Stys         AreWell();
859163c13feSPeter Stys         Aligned();
860163c13feSPeter Stys         AfterLambdaBlock();
861163c13feSPeter Stys     }
862163c13feSPeter Stys })",
863163c13feSPeter Stys                MicrosoftStyle);
864163c13feSPeter Stys 
865163c13feSPeter Stys   verifyFormat(R"(//
866163c13feSPeter Stys public class Test {
867163c13feSPeter Stys   private static void MultipleLambdas(BuildReport protoReport) {
868163c13feSPeter Stys     allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds
869163c13feSPeter Stys                             .Where(scene => scene.enabled)
870163c13feSPeter Stys                             .Select(scene => scene.path)
871163c13feSPeter Stys                             .ToArray();
872163c13feSPeter Stys     preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
873163c13feSPeter Stys     if (allSelectedScenes.Count == 0) {
874163c13feSPeter Stys       return;
875163c13feSPeter Stys     }
876163c13feSPeter Stys     Functions();
877163c13feSPeter Stys     AreWell();
878163c13feSPeter Stys     Aligned();
879163c13feSPeter Stys     AfterLambdaBlock();
880163c13feSPeter Stys   }
881163c13feSPeter Stys })",
882163c13feSPeter Stys                GoogleStyle);
883163c13feSPeter Stys }
884163c13feSPeter Stys 
8850bb60e29SJonathan Coe TEST_F(FormatTestCSharp, CSharpObjectInitializers) {
8860bb60e29SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
8870bb60e29SJonathan Coe 
888a11ff39bSJonathan Coe   // Start code fragments with a comment line so that C++ raw string literals
8890bb60e29SJonathan Coe   // as seen are identical to expected formatted code.
8900bb60e29SJonathan Coe 
8910bb60e29SJonathan Coe   verifyFormat(R"(//
8920bb60e29SJonathan Coe Shape[] shapes = new[] {
8930bb60e29SJonathan Coe   new Circle {
8940bb60e29SJonathan Coe     Radius = 2.7281,
8950bb60e29SJonathan Coe     Colour = Colours.Red,
8960bb60e29SJonathan Coe   },
8970bb60e29SJonathan Coe   new Square {
8980bb60e29SJonathan Coe     Side = 101.1,
8990bb60e29SJonathan Coe     Colour = Colours.Yellow,
9000bb60e29SJonathan Coe   },
9010bb60e29SJonathan Coe };)",
9020bb60e29SJonathan Coe                Style);
9030bb60e29SJonathan Coe 
9040bb60e29SJonathan Coe   // Omitted final `,`s will change the formatting.
9050bb60e29SJonathan Coe   verifyFormat(R"(//
9060bb60e29SJonathan Coe Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red },
907eb682b80SJonathan Coe                          new Square { Side = 101.1, Colour = Colours.Yellow } };)",
9080bb60e29SJonathan Coe                Style);
9097d2fdd3fSJonathan Coe 
9107d2fdd3fSJonathan Coe   // Lambdas can be supplied as initialiser arguments.
9117d2fdd3fSJonathan Coe   verifyFormat(R"(//
9127d2fdd3fSJonathan Coe private Transformer _transformer = new X.Y {
9137d2fdd3fSJonathan Coe   Filler = (Shape shape) => { return new Transform.Fill(shape, RED); },
9147d2fdd3fSJonathan Coe   Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); },
9157d2fdd3fSJonathan Coe };)",
9167d2fdd3fSJonathan Coe                Style);
9170c28a093SJonathan Coe 
9180c28a093SJonathan Coe   // Dictionary initialisation.
9190c28a093SJonathan Coe   verifyFormat(R"(//
9200c28a093SJonathan Coe var myDict = new Dictionary<string, string> {
9210c28a093SJonathan Coe   ["name"] = _donald,
9220c28a093SJonathan Coe   ["age"] = Convert.ToString(DateTime.Today.Year - 1934),
9230c28a093SJonathan Coe   ["type"] = _duck,
9240c28a093SJonathan Coe };)",
9250c28a093SJonathan Coe                Style);
9260bb60e29SJonathan Coe }
9270bb60e29SJonathan Coe 
9285e1a026cSJonathan Coe TEST_F(FormatTestCSharp, CSharpArrayInitializers) {
9295e1a026cSJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
9305e1a026cSJonathan Coe 
9315e1a026cSJonathan Coe   verifyFormat(R"(//
9325e1a026cSJonathan Coe private MySet<Node>[] setPoints = {
9335e1a026cSJonathan Coe   new Point<Node>(),
9345e1a026cSJonathan Coe   new Point<Node>(),
9355e1a026cSJonathan Coe };)",
9365e1a026cSJonathan Coe                Style);
9375e1a026cSJonathan Coe }
9385e1a026cSJonathan Coe 
939a11ff39bSJonathan Coe TEST_F(FormatTestCSharp, CSharpNamedArguments) {
940a11ff39bSJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
941a11ff39bSJonathan Coe 
942a11ff39bSJonathan Coe   verifyFormat(R"(//
9439520bf14SJonathan Coe PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)",
944a11ff39bSJonathan Coe                Style);
945a11ff39bSJonathan Coe 
946a11ff39bSJonathan Coe   // Ensure that trailing comments do not cause problems.
947a11ff39bSJonathan Coe   verifyFormat(R"(//
948a11ff39bSJonathan Coe PrintOrderDetails(orderNum: 31, productName: "Red Mug",  // comment
949a11ff39bSJonathan Coe                   sellerName: "Gift Shop");)",
950a11ff39bSJonathan Coe                Style);
9517dfe0cc7SJonathan Coe 
9527dfe0cc7SJonathan Coe   verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style);
953a11ff39bSJonathan Coe }
954a11ff39bSJonathan Coe 
9552bd6974aSJonathan Coe TEST_F(FormatTestCSharp, CSharpPropertyAccessors) {
9562bd6974aSJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
9572bd6974aSJonathan Coe 
9582bd6974aSJonathan Coe   verifyFormat("int Value { get }", Style);
9592bd6974aSJonathan Coe   verifyFormat("int Value { get; }", Style);
9602bd6974aSJonathan Coe   verifyFormat("int Value { internal get; }", Style);
9612bd6974aSJonathan Coe   verifyFormat("int Value { get; } = 0", Style);
9622bd6974aSJonathan Coe   verifyFormat("int Value { set }", Style);
9632bd6974aSJonathan Coe   verifyFormat("int Value { set; }", Style);
9647a54fcebSMarek Kurdej   verifyFormat("int Value { init; }", Style);
9652bd6974aSJonathan Coe   verifyFormat("int Value { internal set; }", Style);
9662bd6974aSJonathan Coe   verifyFormat("int Value { set; } = 0", Style);
9672bd6974aSJonathan Coe   verifyFormat("int Value { get; set }", Style);
9687a54fcebSMarek Kurdej   verifyFormat("int Value { get; init; }", Style);
9692bd6974aSJonathan Coe   verifyFormat("int Value { set; get }", Style);
9702bd6974aSJonathan Coe   verifyFormat("int Value { get; private set; }", Style);
9712bd6974aSJonathan Coe   verifyFormat("int Value { get; set; }", Style);
9722bd6974aSJonathan Coe   verifyFormat("int Value { get; set; } = 0", Style);
9732bd6974aSJonathan Coe   verifyFormat("int Value { internal get; internal set; }", Style);
9742bd6974aSJonathan Coe 
9752bd6974aSJonathan Coe   // Do not wrap expression body definitions.
9762bd6974aSJonathan Coe   verifyFormat(R"(//
9772bd6974aSJonathan Coe public string Name {
9782bd6974aSJonathan Coe   get => _name;
9792bd6974aSJonathan Coe   set => _name = value;
9802bd6974aSJonathan Coe })",
9812bd6974aSJonathan Coe                Style);
9827a54fcebSMarek Kurdej   verifyFormat(R"(//
9837a54fcebSMarek Kurdej public string Name {
9847a54fcebSMarek Kurdej   init => _name = value;
9857a54fcebSMarek Kurdej   get => _name;
9867a54fcebSMarek Kurdej })",
9877a54fcebSMarek Kurdej                Style);
9887a54fcebSMarek Kurdej   verifyFormat(R"(//
9897a54fcebSMarek Kurdej public string Name {
9907a54fcebSMarek Kurdej   set => _name = value;
9917a54fcebSMarek Kurdej   get => _name;
9927a54fcebSMarek Kurdej })",
9937a54fcebSMarek Kurdej                Style);
99444ad58b9SJonathan Coe 
99544ad58b9SJonathan Coe   // Examples taken from
99644ad58b9SJonathan Coe   // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
99744ad58b9SJonathan Coe   verifyFormat(R"(
99844ad58b9SJonathan Coe // Expression body definitions
99944ad58b9SJonathan Coe public class SaleItem {
100044ad58b9SJonathan Coe   public decimal Price {
100144ad58b9SJonathan Coe     get => _cost;
100244ad58b9SJonathan Coe     set => _cost = value;
100344ad58b9SJonathan Coe   }
100444ad58b9SJonathan Coe })",
100544ad58b9SJonathan Coe                Style);
100644ad58b9SJonathan Coe 
100744ad58b9SJonathan Coe   verifyFormat(R"(
100844ad58b9SJonathan Coe // Properties with backing fields
100944ad58b9SJonathan Coe class TimePeriod {
101044ad58b9SJonathan Coe   public double Hours {
101144ad58b9SJonathan Coe     get { return _seconds / 3600; }
101244ad58b9SJonathan Coe     set {
101344ad58b9SJonathan Coe       if (value < 0 || value > 24)
10149520bf14SJonathan Coe         throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24.");
101544ad58b9SJonathan Coe       _seconds = value * 3600;
101644ad58b9SJonathan Coe     }
101744ad58b9SJonathan Coe   }
101844ad58b9SJonathan Coe })",
101944ad58b9SJonathan Coe                Style);
102044ad58b9SJonathan Coe 
102144ad58b9SJonathan Coe   verifyFormat(R"(
102244ad58b9SJonathan Coe // Auto-implemented properties
102344ad58b9SJonathan Coe public class SaleItem {
102444ad58b9SJonathan Coe   public decimal Price { get; set; }
102544ad58b9SJonathan Coe })",
102644ad58b9SJonathan Coe                Style);
102744ad58b9SJonathan Coe 
102844ad58b9SJonathan Coe   // Add column limit to wrap long lines.
102944ad58b9SJonathan Coe   Style.ColumnLimit = 100;
103044ad58b9SJonathan Coe 
103144ad58b9SJonathan Coe   // Examples with assignment to default value.
103244ad58b9SJonathan Coe   verifyFormat(R"(
103344ad58b9SJonathan Coe // Long assignment to default value
103444ad58b9SJonathan Coe class MyClass {
103544ad58b9SJonathan Coe   public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } =
103644ad58b9SJonathan Coe       VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
103744ad58b9SJonathan Coe                                      DefaultThirdArgument);
103844ad58b9SJonathan Coe })",
103944ad58b9SJonathan Coe                Style);
104044ad58b9SJonathan Coe 
104144ad58b9SJonathan Coe   verifyFormat(R"(
104244ad58b9SJonathan Coe // Long assignment to default value with expression body
104344ad58b9SJonathan Coe class MyClass {
104444ad58b9SJonathan Coe   public override VeryLongNamedTypeIndeed VeryLongNamedValue {
104544ad58b9SJonathan Coe     get => veryLongNamedField;
104644ad58b9SJonathan Coe     set => veryLongNamedField = value;
104744ad58b9SJonathan Coe   } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
104844ad58b9SJonathan Coe                                      DefaultThirdArgument);
104944ad58b9SJonathan Coe })",
105044ad58b9SJonathan Coe                Style);
10518fa743abSJonathan Coe 
10528fa743abSJonathan Coe   // Brace wrapping and single-lining of accessor can be controlled by config.
10538fa743abSJonathan Coe   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
10548fa743abSJonathan Coe   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
10558fa743abSJonathan Coe   Style.BraceWrapping.AfterFunction = true;
10568fa743abSJonathan Coe 
10578fa743abSJonathan Coe   verifyFormat(R"(//
10588fa743abSJonathan Coe class TimePeriod {
10598fa743abSJonathan Coe   public double Hours
10608fa743abSJonathan Coe   {
10618fa743abSJonathan Coe     get {
10628fa743abSJonathan Coe       return _seconds / 3600;
10638fa743abSJonathan Coe     }
10648fa743abSJonathan Coe     set {
10658fa743abSJonathan Coe       _seconds = value * 3600;
10668fa743abSJonathan Coe     }
10678fa743abSJonathan Coe   }
10688fa743abSJonathan Coe })",
10698fa743abSJonathan Coe                Style);
1070f22b0727SJonathan Coe 
1071f22b0727SJonathan Coe   // Microsoft style trivial property accessors have no line break before the
1072f22b0727SJonathan Coe   // opening brace.
1073f22b0727SJonathan Coe   auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
1074f22b0727SJonathan Coe   verifyFormat(R"(//
1075f22b0727SJonathan Coe public class SaleItem
1076f22b0727SJonathan Coe {
1077f22b0727SJonathan Coe     public decimal Price { get; set; }
1078f22b0727SJonathan Coe })",
1079f22b0727SJonathan Coe                MicrosoftStyle);
1080e8c5fea2SJonathan Coe }
1081e8c5fea2SJonathan Coe 
1082f537a409SMarek Kurdej TEST_F(FormatTestCSharp, DefaultLiteral) {
1083f537a409SMarek Kurdej   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1084f537a409SMarek Kurdej 
1085f537a409SMarek Kurdej   verifyFormat(
1086f537a409SMarek Kurdej       "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style);
1087f537a409SMarek Kurdej   verifyFormat("System.Numerics.Complex fillValue = default;", Style);
1088f537a409SMarek Kurdej   verifyFormat("int Value { get } = default;", Style);
1089f537a409SMarek Kurdej   verifyFormat("int Value { get } = default!;", Style);
1090f537a409SMarek Kurdej   verifyFormat(R"(//
1091f537a409SMarek Kurdej public record Person {
1092f537a409SMarek Kurdej   public string GetInit { get; init; } = default!;
1093f537a409SMarek Kurdej };)",
1094f537a409SMarek Kurdej                Style);
1095f537a409SMarek Kurdej   verifyFormat(R"(//
1096f537a409SMarek Kurdej public record Person {
1097f537a409SMarek Kurdej   public string GetSet { get; set; } = default!;
1098f537a409SMarek Kurdej };)",
1099f537a409SMarek Kurdej                Style);
1100f537a409SMarek Kurdej }
1101f537a409SMarek Kurdej 
1102e8c5fea2SJonathan Coe TEST_F(FormatTestCSharp, CSharpSpaces) {
1103e8c5fea2SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1104e8c5fea2SJonathan Coe   Style.SpaceBeforeSquareBrackets = false;
1105e8c5fea2SJonathan Coe   Style.SpacesInSquareBrackets = false;
1106e8c5fea2SJonathan Coe   Style.SpaceBeforeCpp11BracedList = true;
1107e8c5fea2SJonathan Coe   Style.Cpp11BracedListStyle = false;
1108e8c5fea2SJonathan Coe   Style.SpacesInContainerLiterals = false;
110907c1978bSJonathan Coe   Style.SpaceAfterCStyleCast = false;
1110e8c5fea2SJonathan Coe 
1111e8c5fea2SJonathan Coe   verifyFormat(R"(new Car { "Door", 0.1 })", Style);
1112e8c5fea2SJonathan Coe   verifyFormat(R"(new Car { 0.1, "Door" })", Style);
1113e8c5fea2SJonathan Coe   verifyFormat(R"(new string[] { "A" })", Style);
1114e8c5fea2SJonathan Coe   verifyFormat(R"(new string[] {})", Style);
1115e8c5fea2SJonathan Coe   verifyFormat(R"(new Car { someVariableName })", Style);
1116e8c5fea2SJonathan Coe   verifyFormat(R"(new Car { someVariableName })", Style);
1117e8c5fea2SJonathan Coe   verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)",
1118e8c5fea2SJonathan Coe                Style);
1119e8c5fea2SJonathan Coe   verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style);
1120e8c5fea2SJonathan Coe   verifyFormat(R"(bool[] xs = { true, true };)", Style);
1121e8c5fea2SJonathan Coe   verifyFormat(R"(taskContext.Factory.Run(async () => doThing(args);)", Style);
1122e8c5fea2SJonathan Coe   verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style);
1123548e540dSJonathan Coe   verifyFormat(R"(private float[,] Values;)", Style);
11245c917bd9SJonathan Coe   verifyFormat(R"(Result this[Index x] => Foo(x);)", Style);
1125548e540dSJonathan Coe 
112604336adaSJonathan Coe   verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style);
11277443f86eSJonathan Coe   verifyFormat(R"(var (key, value))", Style);
112804336adaSJonathan Coe 
1129047898c9SJonathan Coe   // `&&` is not seen as a reference.
1130047898c9SJonathan Coe   verifyFormat(R"(A == typeof(X) && someBool)", Style);
1131047898c9SJonathan Coe 
113207c1978bSJonathan Coe   // Not seen as a C-style cast.
113307c1978bSJonathan Coe   verifyFormat(R"(//
113407c1978bSJonathan Coe foreach ((A a, B b) in someList) {
113507c1978bSJonathan Coe })",
113607c1978bSJonathan Coe                Style);
113707c1978bSJonathan Coe 
1138a6794991SJonathan Coe   // space after lock in `lock (processes)`.
1139a6794991SJonathan Coe   verifyFormat("lock (process)", Style);
1140a6794991SJonathan Coe 
1141548e540dSJonathan Coe   Style.SpacesInSquareBrackets = true;
1142548e540dSJonathan Coe   verifyFormat(R"(private float[ , ] Values;)", Style);
11439c4afce7SJonathan Coe   verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
114404336adaSJonathan Coe   verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
11455f104a80SŁukasz Krawczyk 
11465f104a80SŁukasz Krawczyk   // Method returning tuple
11475f104a80SŁukasz Krawczyk   verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
11485f104a80SŁukasz Krawczyk   verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
11495f104a80SŁukasz Krawczyk   verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
11505f104a80SŁukasz Krawczyk   verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
11515f104a80SŁukasz Krawczyk   verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
11525f104a80SŁukasz Krawczyk   verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
11535f104a80SŁukasz Krawczyk   verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
11545f104a80SŁukasz Krawczyk   verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
11555f104a80SŁukasz Krawczyk   verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
11565f104a80SŁukasz Krawczyk   verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
11575f104a80SŁukasz Krawczyk   verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
11585f104a80SŁukasz Krawczyk   verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
11595f52a93bSJonathan Coe }
11605f52a93bSJonathan Coe 
11615f52a93bSJonathan Coe TEST_F(FormatTestCSharp, CSharpNullableTypes) {
11625f52a93bSJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
11635f52a93bSJonathan Coe   Style.SpacesInSquareBrackets = false;
11645f52a93bSJonathan Coe 
1165fe61bc1aSJonathan Coe   verifyFormat(R"(//
1166fe61bc1aSJonathan Coe public class A {
11679520bf14SJonathan Coe   void foo() {
11689520bf14SJonathan Coe     int? value = some.bar();
11699520bf14SJonathan Coe   }
1170fe61bc1aSJonathan Coe })",
1171fe61bc1aSJonathan Coe                Style); // int? is nullable not a conditional expression.
1172fe61bc1aSJonathan Coe 
1173fe61bc1aSJonathan Coe   verifyFormat(R"(void foo(int? x, int? y, int? z) {})",
1174fe61bc1aSJonathan Coe                Style); // Nullables in function definitions.
1175fe61bc1aSJonathan Coe 
11765f52a93bSJonathan Coe   verifyFormat(R"(public float? Value;)", Style); // no space before `?`.
1177fe61bc1aSJonathan Coe 
11785f52a93bSJonathan Coe   verifyFormat(R"(int?[] arr = new int?[10];)",
11795f52a93bSJonathan Coe                Style); // An array of a nullable type.
11801fb9c298SJonathan Coe 
11811fb9c298SJonathan Coe   verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
11821fb9c298SJonathan Coe 
11831fb9c298SJonathan Coe   verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics.
1184ec725b30SEliza Velasquez 
1185ec725b30SEliza Velasquez   verifyFormat(R"(//
1186ec725b30SEliza Velasquez public interface I {
1187ec725b30SEliza Velasquez   int? Function();
1188ec725b30SEliza Velasquez })",
1189ec725b30SEliza Velasquez                Style); // Interface methods.
1190ec725b30SEliza Velasquez 
1191ec725b30SEliza Velasquez   Style.ColumnLimit = 10;
1192ec725b30SEliza Velasquez   verifyFormat(R"(//
1193ec725b30SEliza Velasquez public VeryLongType? Function(
1194ec725b30SEliza Velasquez     int arg1,
1195ec725b30SEliza Velasquez     int arg2) {
1196ec725b30SEliza Velasquez   //
1197ec725b30SEliza Velasquez })",
1198ec725b30SEliza Velasquez                Style); // ? sticks with identifier.
11992bd6974aSJonathan Coe }
12002bd6974aSJonathan Coe 
1201736fef97SJonathan Coe TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
1202736fef97SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1203736fef97SJonathan Coe 
1204736fef97SJonathan Coe   // Do not format array subscript operators as attributes.
1205b28ed9ceSJonathan Coe   verifyFormat(R"(//
1206b28ed9ceSJonathan Coe if (someThings[index].Contains(myThing)) {
1207b28ed9ceSJonathan Coe })",
1208b28ed9ceSJonathan Coe                Style);
1209b28ed9ceSJonathan Coe 
1210b28ed9ceSJonathan Coe   verifyFormat(R"(//
1211b28ed9ceSJonathan Coe if (someThings[i][j][k].Contains(myThing)) {
1212b28ed9ceSJonathan Coe })",
1213b28ed9ceSJonathan Coe                Style);
1214736fef97SJonathan Coe }
1215736fef97SJonathan Coe 
1216dcbcec48SJonathan Coe TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) {
1217dcbcec48SJonathan Coe   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1218dcbcec48SJonathan Coe 
121900dc97f1Smydeveloperday   EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord);
122000dc97f1Smydeveloperday 
122100dc97f1Smydeveloperday   verifyFormat("class ItemFactory<T>\n"
122200dc97f1Smydeveloperday                "    where T : new() {\n"
122300dc97f1Smydeveloperday                "}",
1224ece7e95fSmydeveloperday                Style);
1225dcbcec48SJonathan Coe 
122600dc97f1Smydeveloperday   verifyFormat("class Dictionary<TKey, TVal>\n"
122700dc97f1Smydeveloperday                "    where TKey : IComparable<TKey>\n"
122800dc97f1Smydeveloperday                "    where TVal : IMyInterface {\n"
122900dc97f1Smydeveloperday                "  public void MyMethod<T>(T t)\n"
123000dc97f1Smydeveloperday                "      where T : IMyInterface {\n"
123100dc97f1Smydeveloperday                "    doThing();\n"
123200dc97f1Smydeveloperday                "  }\n"
123300dc97f1Smydeveloperday                "}",
1234dcbcec48SJonathan Coe                Style);
123578e2a3c6SJonathan Coe 
123600dc97f1Smydeveloperday   verifyFormat("class ItemFactory<T>\n"
123700dc97f1Smydeveloperday                "    where T : new(), IAnInterface<T>, IAnotherInterface<T>, "
123800dc97f1Smydeveloperday                "IAnotherInterfaceStill<T> {\n"
123900dc97f1Smydeveloperday                "}",
1240d1b412aeSJonathan Coe                Style);
1241d1b412aeSJonathan Coe 
1242d1b412aeSJonathan Coe   Style.ColumnLimit = 50; // Force lines to be wrapped.
1243d1b412aeSJonathan Coe   verifyFormat(R"(//
1244d1b412aeSJonathan Coe class ItemFactory<T, U>
1245d1b412aeSJonathan Coe     where T : new(),
1246d1b412aeSJonathan Coe               IAnInterface<T>,
1247d1b412aeSJonathan Coe               IAnotherInterface<T, U>,
124800dc97f1Smydeveloperday               IAnotherInterfaceStill<T, U> {
124900dc97f1Smydeveloperday })",
125078e2a3c6SJonathan Coe                Style);
12510574030cSKrasimir Georgiev 
12520574030cSKrasimir Georgiev   // In other languages `where` can be used as a normal identifier.
12530574030cSKrasimir Georgiev   // This example is in C++!
12540574030cSKrasimir Georgiev   verifyFormat(R"(//
12550574030cSKrasimir Georgiev class A {
12560574030cSKrasimir Georgiev   int f(int where) {}
12570574030cSKrasimir Georgiev };)",
12580574030cSKrasimir Georgiev                getGoogleStyle(FormatStyle::LK_Cpp));
1259dcbcec48SJonathan Coe }
1260dcbcec48SJonathan Coe 
1261ed367b9dSmydeveloperday TEST_F(FormatTestCSharp, CSharpAfterEnum) {
1262ed367b9dSmydeveloperday   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1263ed367b9dSmydeveloperday   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1264ed367b9dSmydeveloperday   Style.BraceWrapping.AfterEnum = false;
1265ed367b9dSmydeveloperday   Style.AllowShortEnumsOnASingleLine = false;
1266ed367b9dSmydeveloperday 
1267ed367b9dSmydeveloperday   verifyFormat("enum MyEnum {\n"
1268ed367b9dSmydeveloperday                "  Foo,\n"
1269ed367b9dSmydeveloperday                "  Bar,\n"
1270ed367b9dSmydeveloperday                "}",
1271ed367b9dSmydeveloperday                Style);
1272ed367b9dSmydeveloperday   verifyFormat("internal enum MyEnum {\n"
1273ed367b9dSmydeveloperday                "  Foo,\n"
1274ed367b9dSmydeveloperday                "  Bar,\n"
1275ed367b9dSmydeveloperday                "}",
1276ed367b9dSmydeveloperday                Style);
1277ed367b9dSmydeveloperday   verifyFormat("public enum MyEnum {\n"
1278ed367b9dSmydeveloperday                "  Foo,\n"
1279ed367b9dSmydeveloperday                "  Bar,\n"
1280ed367b9dSmydeveloperday                "}",
1281ed367b9dSmydeveloperday                Style);
1282ed367b9dSmydeveloperday   verifyFormat("protected enum MyEnum {\n"
1283ed367b9dSmydeveloperday                "  Foo,\n"
1284ed367b9dSmydeveloperday                "  Bar,\n"
1285ed367b9dSmydeveloperday                "}",
1286ed367b9dSmydeveloperday                Style);
1287ed367b9dSmydeveloperday   verifyFormat("private enum MyEnum {\n"
1288ed367b9dSmydeveloperday                "  Foo,\n"
1289ed367b9dSmydeveloperday                "  Bar,\n"
1290ed367b9dSmydeveloperday                "}",
1291ed367b9dSmydeveloperday                Style);
1292ed367b9dSmydeveloperday 
1293ed367b9dSmydeveloperday   Style.BraceWrapping.AfterEnum = true;
1294ed367b9dSmydeveloperday   Style.AllowShortEnumsOnASingleLine = false;
1295ed367b9dSmydeveloperday 
1296ed367b9dSmydeveloperday   verifyFormat("enum MyEnum\n"
1297ed367b9dSmydeveloperday                "{\n"
1298ed367b9dSmydeveloperday                "  Foo,\n"
1299ed367b9dSmydeveloperday                "  Bar,\n"
1300ed367b9dSmydeveloperday                "}",
1301ed367b9dSmydeveloperday                Style);
1302ed367b9dSmydeveloperday   verifyFormat("internal enum MyEnum\n"
1303ed367b9dSmydeveloperday                "{\n"
1304ed367b9dSmydeveloperday                "  Foo,\n"
1305ed367b9dSmydeveloperday                "  Bar,\n"
1306ed367b9dSmydeveloperday                "}",
1307ed367b9dSmydeveloperday                Style);
1308ed367b9dSmydeveloperday   verifyFormat("public enum MyEnum\n"
1309ed367b9dSmydeveloperday                "{\n"
1310ed367b9dSmydeveloperday                "  Foo,\n"
1311ed367b9dSmydeveloperday                "  Bar,\n"
1312ed367b9dSmydeveloperday                "}",
1313ed367b9dSmydeveloperday                Style);
1314ed367b9dSmydeveloperday   verifyFormat("protected enum MyEnum\n"
1315ed367b9dSmydeveloperday                "{\n"
1316ed367b9dSmydeveloperday                "  Foo,\n"
1317ed367b9dSmydeveloperday                "  Bar,\n"
1318ed367b9dSmydeveloperday                "}",
1319ed367b9dSmydeveloperday                Style);
1320ed367b9dSmydeveloperday   verifyFormat("private enum MyEnum\n"
1321ed367b9dSmydeveloperday                "{\n"
1322ed367b9dSmydeveloperday                "  Foo,\n"
1323ed367b9dSmydeveloperday                "  Bar,\n"
1324ed367b9dSmydeveloperday                "}",
1325ed367b9dSmydeveloperday                Style);
1326ed367b9dSmydeveloperday   verifyFormat("/* Foo */ private enum MyEnum\n"
1327ed367b9dSmydeveloperday                "{\n"
1328ed367b9dSmydeveloperday                "  Foo,\n"
1329ed367b9dSmydeveloperday                "  Bar,\n"
1330ed367b9dSmydeveloperday                "}",
1331ed367b9dSmydeveloperday                Style);
1332ed367b9dSmydeveloperday   verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n"
1333ed367b9dSmydeveloperday                "{\n"
1334ed367b9dSmydeveloperday                "  Foo,\n"
1335ed367b9dSmydeveloperday                "  Bar,\n"
1336ed367b9dSmydeveloperday                "}",
1337ed367b9dSmydeveloperday                Style);
1338ed367b9dSmydeveloperday }
1339ed367b9dSmydeveloperday 
1340ed367b9dSmydeveloperday TEST_F(FormatTestCSharp, CSharpAfterClass) {
1341ed367b9dSmydeveloperday   FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1342ed367b9dSmydeveloperday   Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1343ed367b9dSmydeveloperday   Style.BraceWrapping.AfterClass = false;
1344ed367b9dSmydeveloperday 
1345ed367b9dSmydeveloperday   verifyFormat("class MyClass {\n"
1346ed367b9dSmydeveloperday                "  int a;\n"
1347ed367b9dSmydeveloperday                "  int b;\n"
1348ed367b9dSmydeveloperday                "}",
1349ed367b9dSmydeveloperday                Style);
1350ed367b9dSmydeveloperday   verifyFormat("internal class MyClass {\n"
1351ed367b9dSmydeveloperday                "  int a;\n"
1352ed367b9dSmydeveloperday                "  int b;\n"
1353ed367b9dSmydeveloperday                "}",
1354ed367b9dSmydeveloperday                Style);
1355ed367b9dSmydeveloperday   verifyFormat("public class MyClass {\n"
1356ed367b9dSmydeveloperday                "  int a;\n"
1357ed367b9dSmydeveloperday                "  int b;\n"
1358ed367b9dSmydeveloperday                "}",
1359ed367b9dSmydeveloperday                Style);
1360ed367b9dSmydeveloperday   verifyFormat("protected class MyClass {\n"
1361ed367b9dSmydeveloperday                "  int a;\n"
1362ed367b9dSmydeveloperday                "  int b;\n"
1363ed367b9dSmydeveloperday                "}",
1364ed367b9dSmydeveloperday                Style);
1365ed367b9dSmydeveloperday   verifyFormat("private class MyClass {\n"
1366ed367b9dSmydeveloperday                "  int a;\n"
1367ed367b9dSmydeveloperday                "  int b;\n"
1368ed367b9dSmydeveloperday                "}",
1369ed367b9dSmydeveloperday                Style);
1370ed367b9dSmydeveloperday 
1371ed367b9dSmydeveloperday   verifyFormat("interface Interface {\n"
1372ed367b9dSmydeveloperday                "  int a;\n"
1373ed367b9dSmydeveloperday                "  int b;\n"
1374ed367b9dSmydeveloperday                "}",
1375ed367b9dSmydeveloperday                Style);
1376ed367b9dSmydeveloperday   verifyFormat("internal interface Interface {\n"
1377ed367b9dSmydeveloperday                "  int a;\n"
1378ed367b9dSmydeveloperday                "  int b;\n"
1379ed367b9dSmydeveloperday                "}",
1380ed367b9dSmydeveloperday                Style);
1381ed367b9dSmydeveloperday   verifyFormat("public interface Interface {\n"
1382ed367b9dSmydeveloperday                "  int a;\n"
1383ed367b9dSmydeveloperday                "  int b;\n"
1384ed367b9dSmydeveloperday                "}",
1385ed367b9dSmydeveloperday                Style);
1386ed367b9dSmydeveloperday   verifyFormat("protected interface Interface {\n"
1387ed367b9dSmydeveloperday                "  int a;\n"
1388ed367b9dSmydeveloperday                "  int b;\n"
1389ed367b9dSmydeveloperday                "}",
1390ed367b9dSmydeveloperday                Style);
1391ed367b9dSmydeveloperday   verifyFormat("private interface Interface {\n"
1392ed367b9dSmydeveloperday                "  int a;\n"
1393ed367b9dSmydeveloperday                "  int b;\n"
1394ed367b9dSmydeveloperday                "}",
1395ed367b9dSmydeveloperday                Style);
1396ed367b9dSmydeveloperday 
1397ed367b9dSmydeveloperday   Style.BraceWrapping.AfterClass = true;
1398ed367b9dSmydeveloperday 
1399ed367b9dSmydeveloperday   verifyFormat("class MyClass\n"
1400ed367b9dSmydeveloperday                "{\n"
1401ed367b9dSmydeveloperday                "  int a;\n"
1402ed367b9dSmydeveloperday                "  int b;\n"
1403ed367b9dSmydeveloperday                "}",
1404ed367b9dSmydeveloperday                Style);
1405ed367b9dSmydeveloperday   verifyFormat("internal class MyClass\n"
1406ed367b9dSmydeveloperday                "{\n"
1407ed367b9dSmydeveloperday                "  int a;\n"
1408ed367b9dSmydeveloperday                "  int b;\n"
1409ed367b9dSmydeveloperday                "}",
1410ed367b9dSmydeveloperday                Style);
1411ed367b9dSmydeveloperday   verifyFormat("public class MyClass\n"
1412ed367b9dSmydeveloperday                "{\n"
1413ed367b9dSmydeveloperday                "  int a;\n"
1414ed367b9dSmydeveloperday                "  int b;\n"
1415ed367b9dSmydeveloperday                "}",
1416ed367b9dSmydeveloperday                Style);
1417ed367b9dSmydeveloperday   verifyFormat("protected class MyClass\n"
1418ed367b9dSmydeveloperday                "{\n"
1419ed367b9dSmydeveloperday                "  int a;\n"
1420ed367b9dSmydeveloperday                "  int b;\n"
1421ed367b9dSmydeveloperday                "}",
1422ed367b9dSmydeveloperday                Style);
1423ed367b9dSmydeveloperday   verifyFormat("private class MyClass\n"
1424ed367b9dSmydeveloperday                "{\n"
1425ed367b9dSmydeveloperday                "  int a;\n"
1426ed367b9dSmydeveloperday                "  int b;\n"
1427ed367b9dSmydeveloperday                "}",
1428ed367b9dSmydeveloperday                Style);
1429ed367b9dSmydeveloperday 
1430ed367b9dSmydeveloperday   verifyFormat("interface MyInterface\n"
1431ed367b9dSmydeveloperday                "{\n"
1432ed367b9dSmydeveloperday                "  int a;\n"
1433ed367b9dSmydeveloperday                "  int b;\n"
1434ed367b9dSmydeveloperday                "}",
1435ed367b9dSmydeveloperday                Style);
1436ed367b9dSmydeveloperday   verifyFormat("internal interface MyInterface\n"
1437ed367b9dSmydeveloperday                "{\n"
1438ed367b9dSmydeveloperday                "  int a;\n"
1439ed367b9dSmydeveloperday                "  int b;\n"
1440ed367b9dSmydeveloperday                "}",
1441ed367b9dSmydeveloperday                Style);
1442ed367b9dSmydeveloperday   verifyFormat("public interface MyInterface\n"
1443ed367b9dSmydeveloperday                "{\n"
1444ed367b9dSmydeveloperday                "  int a;\n"
1445ed367b9dSmydeveloperday                "  int b;\n"
1446ed367b9dSmydeveloperday                "}",
1447ed367b9dSmydeveloperday                Style);
1448ed367b9dSmydeveloperday   verifyFormat("protected interface MyInterface\n"
1449ed367b9dSmydeveloperday                "{\n"
1450ed367b9dSmydeveloperday                "  int a;\n"
1451ed367b9dSmydeveloperday                "  int b;\n"
1452ed367b9dSmydeveloperday                "}",
1453ed367b9dSmydeveloperday                Style);
1454ed367b9dSmydeveloperday   verifyFormat("private interface MyInterface\n"
1455ed367b9dSmydeveloperday                "{\n"
1456ed367b9dSmydeveloperday                "  int a;\n"
1457ed367b9dSmydeveloperday                "  int b;\n"
1458ed367b9dSmydeveloperday                "}",
1459ed367b9dSmydeveloperday                Style);
1460ed367b9dSmydeveloperday   verifyFormat("/* Foo */ private interface MyInterface\n"
1461ed367b9dSmydeveloperday                "{\n"
1462ed367b9dSmydeveloperday                "  int a;\n"
1463ed367b9dSmydeveloperday                "  int b;\n"
1464ed367b9dSmydeveloperday                "}",
1465ed367b9dSmydeveloperday                Style);
1466ed367b9dSmydeveloperday   verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n"
1467ed367b9dSmydeveloperday                "{\n"
1468ed367b9dSmydeveloperday                "  int a;\n"
1469ed367b9dSmydeveloperday                "  int b;\n"
1470ed367b9dSmydeveloperday                "}",
1471ed367b9dSmydeveloperday                Style);
1472ed367b9dSmydeveloperday }
1473ed367b9dSmydeveloperday 
14746e58d14eSmydeveloperday TEST_F(FormatTestCSharp, NamespaceIndentation) {
14756e58d14eSmydeveloperday   FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
14766e58d14eSmydeveloperday   Style.NamespaceIndentation = FormatStyle::NI_None;
14776e58d14eSmydeveloperday 
14786e58d14eSmydeveloperday   verifyFormat("namespace A\n"
14796e58d14eSmydeveloperday                "{\n"
14806e58d14eSmydeveloperday                "public interface Name1\n"
14816e58d14eSmydeveloperday                "{\n"
14826e58d14eSmydeveloperday                "}\n"
14836e58d14eSmydeveloperday                "}\n",
14846e58d14eSmydeveloperday                Style);
14856e58d14eSmydeveloperday 
14866e58d14eSmydeveloperday   verifyFormat("namespace A.B\n"
14876e58d14eSmydeveloperday                "{\n"
14886e58d14eSmydeveloperday                "public interface Name1\n"
14896e58d14eSmydeveloperday                "{\n"
14906e58d14eSmydeveloperday                "}\n"
14916e58d14eSmydeveloperday                "}\n",
14926e58d14eSmydeveloperday                Style);
14936e58d14eSmydeveloperday 
14946e58d14eSmydeveloperday   Style.NamespaceIndentation = FormatStyle::NI_Inner;
14956e58d14eSmydeveloperday 
14966e58d14eSmydeveloperday   verifyFormat("namespace A\n"
14976e58d14eSmydeveloperday                "{\n"
14986e58d14eSmydeveloperday                "namespace B\n"
14996e58d14eSmydeveloperday                "{\n"
15006e58d14eSmydeveloperday                "    public interface Name1\n"
15016e58d14eSmydeveloperday                "    {\n"
15026e58d14eSmydeveloperday                "    }\n"
15036e58d14eSmydeveloperday                "}\n"
15046e58d14eSmydeveloperday                "}\n",
15056e58d14eSmydeveloperday                Style);
15066e58d14eSmydeveloperday 
15076e58d14eSmydeveloperday   Style.NamespaceIndentation = FormatStyle::NI_All;
15086e58d14eSmydeveloperday 
15096e58d14eSmydeveloperday   verifyFormat("namespace A.B\n"
15106e58d14eSmydeveloperday                "{\n"
15116e58d14eSmydeveloperday                "    public interface Name1\n"
15126e58d14eSmydeveloperday                "    {\n"
15136e58d14eSmydeveloperday                "    }\n"
15146e58d14eSmydeveloperday                "}\n",
15156e58d14eSmydeveloperday                Style);
15166e58d14eSmydeveloperday 
15176e58d14eSmydeveloperday   verifyFormat("namespace A\n"
15186e58d14eSmydeveloperday                "{\n"
15196e58d14eSmydeveloperday                "    namespace B\n"
15206e58d14eSmydeveloperday                "    {\n"
15216e58d14eSmydeveloperday                "        public interface Name1\n"
15226e58d14eSmydeveloperday                "        {\n"
15236e58d14eSmydeveloperday                "        }\n"
15246e58d14eSmydeveloperday                "    }\n"
15256e58d14eSmydeveloperday                "}\n",
15266e58d14eSmydeveloperday                Style);
15276e58d14eSmydeveloperday }
15286e58d14eSmydeveloperday 
1529ebed0ca7Smydeveloperday TEST_F(FormatTestCSharp, SwitchExpression) {
1530ebed0ca7Smydeveloperday   FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
1531ebed0ca7Smydeveloperday   verifyFormat("int x = a switch {\n"
1532ebed0ca7Smydeveloperday                "    1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n"
1533ebed0ca7Smydeveloperday                "    2 => 1,\n"
1534ebed0ca7Smydeveloperday                "    _ => 2\n"
1535ebed0ca7Smydeveloperday                "};\n",
1536ebed0ca7Smydeveloperday                Style);
1537ebed0ca7Smydeveloperday }
1538ebed0ca7Smydeveloperday 
1539a94aab12Smydeveloperday TEST_F(FormatTestCSharp, EmptyShortBlock) {
1540a94aab12Smydeveloperday   auto Style = getLLVMStyle();
1541a94aab12Smydeveloperday   Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
1542a94aab12Smydeveloperday 
1543a94aab12Smydeveloperday   verifyFormat("try {\n"
1544a94aab12Smydeveloperday                "  doA();\n"
1545a94aab12Smydeveloperday                "} catch (Exception e) {\n"
1546a94aab12Smydeveloperday                "  e.printStackTrace();\n"
1547a94aab12Smydeveloperday                "}\n",
1548a94aab12Smydeveloperday                Style);
1549a94aab12Smydeveloperday 
1550a94aab12Smydeveloperday   verifyFormat("try {\n"
1551a94aab12Smydeveloperday                "  doA();\n"
1552a94aab12Smydeveloperday                "} catch (Exception e) {}\n",
1553a94aab12Smydeveloperday                Style);
1554a94aab12Smydeveloperday }
1555a94aab12Smydeveloperday 
15567af11989SMarek Kurdej TEST_F(FormatTestCSharp, ShortFunctions) {
15577af11989SMarek Kurdej   FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
15587af11989SMarek Kurdej   Style.NamespaceIndentation = FormatStyle::NI_All;
15597af11989SMarek Kurdej   Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
15607af11989SMarek Kurdej   verifyFormat("interface Interface {\n"
15617af11989SMarek Kurdej                "  void f() { return; }\n"
15627af11989SMarek Kurdej                "};",
15637af11989SMarek Kurdej                Style);
15647af11989SMarek Kurdej   verifyFormat("public interface Interface {\n"
15657af11989SMarek Kurdej                "  void f() { return; }\n"
15667af11989SMarek Kurdej                "};",
15677af11989SMarek Kurdej                Style);
15687af11989SMarek Kurdej   verifyFormat("namespace {\n"
15697af11989SMarek Kurdej                "  void f() {\n"
15707af11989SMarek Kurdej                "    return;\n"
15717af11989SMarek Kurdej                "  }\n"
15727af11989SMarek Kurdej                "};",
15737af11989SMarek Kurdej                Style);
15747af11989SMarek Kurdej   // "union" is not a keyword in C#.
15757af11989SMarek Kurdej   verifyFormat("namespace union {\n"
15767af11989SMarek Kurdej                "  void f() {\n"
15777af11989SMarek Kurdej                "    return;\n"
15787af11989SMarek Kurdej                "  }\n"
15797af11989SMarek Kurdej                "};",
15807af11989SMarek Kurdej                Style);
15817af11989SMarek Kurdej }
15827af11989SMarek Kurdej 
1583cbb726d0SPaul Hoad } // namespace format
1584cbb726d0SPaul Hoad } // end namespace clang
1585