16f6f88ffSksyx //===- DefinitionBlockSeparatorTest.cpp - Formatting unit tests -----------===//
26f6f88ffSksyx //
36f6f88ffSksyx // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
46f6f88ffSksyx // See https://llvm.org/LICENSE.txt for license information.
56f6f88ffSksyx // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66f6f88ffSksyx //
76f6f88ffSksyx //===----------------------------------------------------------------------===//
86f6f88ffSksyx
96f6f88ffSksyx #include "FormatTestUtils.h"
106f6f88ffSksyx #include "clang/Format/Format.h"
116f6f88ffSksyx
126f6f88ffSksyx #include "llvm/Support/Debug.h"
136f6f88ffSksyx #include "gtest/gtest.h"
146f6f88ffSksyx
156f6f88ffSksyx #define DEBUG_TYPE "definition-block-separator-test"
166f6f88ffSksyx
176f6f88ffSksyx namespace clang {
186f6f88ffSksyx namespace format {
196f6f88ffSksyx namespace {
206f6f88ffSksyx
21*1c58208dSOwen Pan class DefinitionBlockSeparatorTest : public testing::Test {
226f6f88ffSksyx protected:
236f6f88ffSksyx static std::string
separateDefinitionBlocks(StringRef Code,const std::vector<tooling::Range> & Ranges,const FormatStyle & Style=getLLVMStyle ())24*1c58208dSOwen Pan separateDefinitionBlocks(StringRef Code,
256f6f88ffSksyx const std::vector<tooling::Range> &Ranges,
266f6f88ffSksyx const FormatStyle &Style = getLLVMStyle()) {
276f6f88ffSksyx LLVM_DEBUG(llvm::errs() << "---\n");
286f6f88ffSksyx LLVM_DEBUG(llvm::errs() << Code << "\n\n");
296f6f88ffSksyx tooling::Replacements Replaces = reformat(Style, Code, Ranges, "<stdin>");
306f6f88ffSksyx auto Result = applyAllReplacements(Code, Replaces);
316f6f88ffSksyx EXPECT_TRUE(static_cast<bool>(Result));
326f6f88ffSksyx LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
336f6f88ffSksyx return *Result;
346f6f88ffSksyx }
356f6f88ffSksyx
366f6f88ffSksyx static std::string
separateDefinitionBlocks(StringRef Code,const FormatStyle & Style=getLLVMStyle ())37*1c58208dSOwen Pan separateDefinitionBlocks(StringRef Code,
386f6f88ffSksyx const FormatStyle &Style = getLLVMStyle()) {
396f6f88ffSksyx return separateDefinitionBlocks(
406f6f88ffSksyx Code,
416f6f88ffSksyx /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
426f6f88ffSksyx }
436f6f88ffSksyx
_verifyFormat(const char * File,int Line,StringRef Code,const FormatStyle & Style=getLLVMStyle (),StringRef ExpectedCode="",bool Inverse=true)44*1c58208dSOwen Pan static void _verifyFormat(const char *File, int Line, StringRef Code,
456f6f88ffSksyx const FormatStyle &Style = getLLVMStyle(),
46*1c58208dSOwen Pan StringRef ExpectedCode = "", bool Inverse = true) {
47*1c58208dSOwen Pan testing::ScopedTrace t(File, Line, testing::Message() << Code.str());
486f6f88ffSksyx bool HasOriginalCode = true;
496f6f88ffSksyx if (ExpectedCode == "") {
506f6f88ffSksyx ExpectedCode = Code;
516f6f88ffSksyx HasOriginalCode = false;
526f6f88ffSksyx }
536f6f88ffSksyx
54b58616c2SMarek Kurdej EXPECT_EQ(ExpectedCode, separateDefinitionBlocks(ExpectedCode, Style))
55b58616c2SMarek Kurdej << "Expected code is not stable";
56b58616c2SMarek Kurdej if (Inverse) {
576f6f88ffSksyx FormatStyle InverseStyle = Style;
586f6f88ffSksyx if (Style.SeparateDefinitionBlocks == FormatStyle::SDS_Always)
596f6f88ffSksyx InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
606f6f88ffSksyx else
616f6f88ffSksyx InverseStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
62311a00c3SMarek Kurdej EXPECT_NE(ExpectedCode,
63311a00c3SMarek Kurdej separateDefinitionBlocks(ExpectedCode, InverseStyle))
646f6f88ffSksyx << "Inverse formatting makes no difference";
65b58616c2SMarek Kurdej }
666f6f88ffSksyx std::string CodeToFormat =
676f6f88ffSksyx HasOriginalCode ? Code.str() : removeEmptyLines(Code);
686f6f88ffSksyx std::string Result = separateDefinitionBlocks(CodeToFormat, Style);
69311a00c3SMarek Kurdej EXPECT_EQ(ExpectedCode, Result) << "Test failed. Formatted:\n" << Result;
706f6f88ffSksyx }
716f6f88ffSksyx
removeEmptyLines(StringRef Code)72*1c58208dSOwen Pan static std::string removeEmptyLines(StringRef Code) {
736f6f88ffSksyx std::string Result = "";
746f6f88ffSksyx for (auto Char : Code.str()) {
756f6f88ffSksyx if (Result.size()) {
766f6f88ffSksyx auto LastChar = Result.back();
776f6f88ffSksyx if ((Char == '\n' && LastChar == '\n') ||
78554efc22Sowenca (Char == '\r' && (LastChar == '\r' || LastChar == '\n'))) {
796f6f88ffSksyx continue;
806f6f88ffSksyx }
81554efc22Sowenca }
826f6f88ffSksyx Result.push_back(Char);
836f6f88ffSksyx }
846f6f88ffSksyx return Result;
856f6f88ffSksyx }
866f6f88ffSksyx };
876f6f88ffSksyx
8869ecd248SMarek Kurdej #define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
8969ecd248SMarek Kurdej
TEST_F(DefinitionBlockSeparatorTest,Basic)906f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, Basic) {
916f6f88ffSksyx FormatStyle Style = getLLVMStyle();
926f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
936f6f88ffSksyx verifyFormat("int foo(int i, int j) {\n"
946f6f88ffSksyx " int r = i + j;\n"
956f6f88ffSksyx " return r;\n"
966f6f88ffSksyx "}\n"
976f6f88ffSksyx "\n"
986f6f88ffSksyx "int bar(int j, int k) {\n"
996f6f88ffSksyx " int r = j + k;\n"
1006f6f88ffSksyx " return r;\n"
1016f6f88ffSksyx "}",
1026f6f88ffSksyx Style);
1036f6f88ffSksyx
1046f6f88ffSksyx verifyFormat("struct foo {\n"
1056f6f88ffSksyx " int i, j;\n"
1066f6f88ffSksyx "};\n"
1076f6f88ffSksyx "\n"
1086f6f88ffSksyx "struct bar {\n"
1096f6f88ffSksyx " int j, k;\n"
1106f6f88ffSksyx "};",
1116f6f88ffSksyx Style);
1126f6f88ffSksyx
113a70549aeSksyx verifyFormat("union foo {\n"
114a70549aeSksyx " int i, j;\n"
115a70549aeSksyx "};\n"
116a70549aeSksyx "\n"
117a70549aeSksyx "union bar {\n"
118a70549aeSksyx " int j, k;\n"
119a70549aeSksyx "};",
120a70549aeSksyx Style);
121a70549aeSksyx
1226f6f88ffSksyx verifyFormat("class foo {\n"
1236f6f88ffSksyx " int i, j;\n"
1246f6f88ffSksyx "};\n"
1256f6f88ffSksyx "\n"
1266f6f88ffSksyx "class bar {\n"
1276f6f88ffSksyx " int j, k;\n"
1286f6f88ffSksyx "};",
1296f6f88ffSksyx Style);
1306f6f88ffSksyx
1316f6f88ffSksyx verifyFormat("namespace foo {\n"
1326f6f88ffSksyx "int i, j;\n"
1336f6f88ffSksyx "}\n"
1346f6f88ffSksyx "\n"
1356f6f88ffSksyx "namespace bar {\n"
1366f6f88ffSksyx "int j, k;\n"
1376f6f88ffSksyx "}",
1386f6f88ffSksyx Style);
1396f6f88ffSksyx
1406f6f88ffSksyx verifyFormat("enum Foo { FOO, BAR };\n"
1416f6f88ffSksyx "\n"
14288934a82SOwen Pan "enum Bar { FOOBAR, BARFOO };",
1436f6f88ffSksyx Style);
1445e5efd8aSksyx
1455e5efd8aSksyx FormatStyle BreakAfterReturnTypeStyle = Style;
146d821650eSrmarker BreakAfterReturnTypeStyle.BreakAfterReturnType = FormatStyle::RTBS_All;
1475e5efd8aSksyx // Test uppercased long typename
1485e5efd8aSksyx verifyFormat("class Foo {\n"
1495e5efd8aSksyx " void\n"
1505e5efd8aSksyx " Bar(int t, int p) {\n"
1515e5efd8aSksyx " int r = t + p;\n"
1525e5efd8aSksyx " return r;\n"
1535e5efd8aSksyx " }\n"
1545e5efd8aSksyx "\n"
1555e5efd8aSksyx " HRESULT\n"
1565e5efd8aSksyx " Foobar(int t, int p) {\n"
1575e5efd8aSksyx " int r = t * p;\n"
1585e5efd8aSksyx " return r;\n"
1595e5efd8aSksyx " }\n"
16088934a82SOwen Pan "}",
1615e5efd8aSksyx BreakAfterReturnTypeStyle);
1625e5efd8aSksyx }
1635e5efd8aSksyx
TEST_F(DefinitionBlockSeparatorTest,FormatConflict)1645e5efd8aSksyx TEST_F(DefinitionBlockSeparatorTest, FormatConflict) {
1655e5efd8aSksyx FormatStyle Style = getLLVMStyle();
1665e5efd8aSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
167*1c58208dSOwen Pan StringRef Code = "class Test {\n"
1685e5efd8aSksyx "public:\n"
1695e5efd8aSksyx " static void foo() {\n"
1705e5efd8aSksyx " int t;\n"
1715e5efd8aSksyx " return 1;\n"
1725e5efd8aSksyx " }\n"
1735e5efd8aSksyx "};";
1745e5efd8aSksyx std::vector<tooling::Range> Ranges = {1, tooling::Range(0, Code.size())};
1755e5efd8aSksyx EXPECT_EQ(reformat(Style, Code, Ranges, "<stdin>").size(), 0u);
1765e5efd8aSksyx }
1775e5efd8aSksyx
TEST_F(DefinitionBlockSeparatorTest,CommentBlock)1785e5efd8aSksyx TEST_F(DefinitionBlockSeparatorTest, CommentBlock) {
1795e5efd8aSksyx FormatStyle Style = getLLVMStyle();
1805e5efd8aSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
1815e5efd8aSksyx std::string Prefix = "enum Foo { FOO, BAR };\n"
1825e5efd8aSksyx "\n"
1835e5efd8aSksyx "/*\n"
1845e5efd8aSksyx "test1\n"
1855e5efd8aSksyx "test2\n"
1865e5efd8aSksyx "*/\n"
1875e5efd8aSksyx "int foo(int i, int j) {\n"
1885e5efd8aSksyx " int r = i + j;\n"
1895e5efd8aSksyx " return r;\n"
1905e5efd8aSksyx "}\n";
1915e5efd8aSksyx std::string Suffix = "enum Bar { FOOBAR, BARFOO };\n"
1925e5efd8aSksyx "\n"
1935e5efd8aSksyx "/* Comment block in one line*/\n"
1945e5efd8aSksyx "int bar3(int j, int k) {\n"
1955e5efd8aSksyx " // A comment\n"
1965e5efd8aSksyx " int r = j % k;\n"
1975e5efd8aSksyx " return r;\n"
1985e5efd8aSksyx "}\n";
1995e5efd8aSksyx std::string CommentedCode = "/*\n"
2005e5efd8aSksyx "int bar2(int j, int k) {\n"
2015e5efd8aSksyx " int r = j / k;\n"
2025e5efd8aSksyx " return r;\n"
2035e5efd8aSksyx "}\n"
2045e5efd8aSksyx "*/\n";
2055e5efd8aSksyx verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode + "\n" +
2065e5efd8aSksyx removeEmptyLines(Suffix),
2075e5efd8aSksyx Style, Prefix + "\n" + CommentedCode + "\n" + Suffix);
2085e5efd8aSksyx verifyFormat(removeEmptyLines(Prefix) + "\n" + CommentedCode +
2095e5efd8aSksyx removeEmptyLines(Suffix),
2105e5efd8aSksyx Style, Prefix + "\n" + CommentedCode + Suffix);
2116f6f88ffSksyx }
2126f6f88ffSksyx
TEST_F(DefinitionBlockSeparatorTest,UntouchBlockStartStyle)213ee25a327Sksyx TEST_F(DefinitionBlockSeparatorTest, UntouchBlockStartStyle) {
214ee25a327Sksyx // Returns a std::pair of two strings, with the first one for passing into
215ee25a327Sksyx // Always test and the second one be the expected result of the first string.
216ee25a327Sksyx auto MakeUntouchTest = [&](std::string BlockHeader, std::string BlockChanger,
217ee25a327Sksyx std::string BlockFooter, bool BlockEndNewLine) {
218ee25a327Sksyx std::string CodePart1 = "enum Foo { FOO, BAR };\n"
219ee25a327Sksyx "\n"
220ee25a327Sksyx "/*\n"
221ee25a327Sksyx "test1\n"
222ee25a327Sksyx "test2\n"
223ee25a327Sksyx "*/\n"
224ee25a327Sksyx "int foo(int i, int j) {\n"
225ee25a327Sksyx " int r = i + j;\n"
226ee25a327Sksyx " return r;\n"
227ee25a327Sksyx "}\n";
228ee25a327Sksyx std::string CodePart2 = "/* Comment block in one line*/\n"
229ee25a327Sksyx "enum Bar { FOOBAR, BARFOO };\n"
230ee25a327Sksyx "\n"
231ee25a327Sksyx "int bar3(int j, int k) {\n"
232ee25a327Sksyx " // A comment\n"
233ee25a327Sksyx " int r = j % k;\n"
234ee25a327Sksyx " return r;\n"
235ee25a327Sksyx "}\n";
236ee25a327Sksyx std::string CodePart3 = "int bar2(int j, int k) {\n"
237ee25a327Sksyx " int r = j / k;\n"
238ee25a327Sksyx " return r;\n"
239ee25a327Sksyx "}\n";
240ee25a327Sksyx std::string ConcatAll = BlockHeader + CodePart1 + BlockChanger + CodePart2 +
241ee25a327Sksyx BlockFooter + (BlockEndNewLine ? "\n" : "") +
242ee25a327Sksyx CodePart3;
243ee25a327Sksyx return std::make_pair(BlockHeader + removeEmptyLines(CodePart1) +
244ee25a327Sksyx BlockChanger + removeEmptyLines(CodePart2) +
245ee25a327Sksyx BlockFooter + removeEmptyLines(CodePart3),
246ee25a327Sksyx ConcatAll);
247ee25a327Sksyx };
248ee25a327Sksyx
249ee25a327Sksyx FormatStyle AlwaysStyle = getLLVMStyle();
250ee25a327Sksyx AlwaysStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
251ee25a327Sksyx
252ee25a327Sksyx FormatStyle NeverStyle = getLLVMStyle();
253ee25a327Sksyx NeverStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
254ee25a327Sksyx
2555e5efd8aSksyx auto TestKit = MakeUntouchTest("/* FOOBAR */\n"
2565e5efd8aSksyx "#ifdef FOO\n\n",
2575e5efd8aSksyx "\n#elifndef BAR\n\n", "\n#endif\n\n", false);
258ee25a327Sksyx verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
259ee25a327Sksyx verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
260ee25a327Sksyx
2615e5efd8aSksyx TestKit = MakeUntouchTest("/* FOOBAR */\n"
2625e5efd8aSksyx "#ifdef FOO\n",
2635e5efd8aSksyx "#elifndef BAR\n", "#endif\n", false);
264ee25a327Sksyx verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
265ee25a327Sksyx verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
266ee25a327Sksyx
267ee25a327Sksyx TestKit = MakeUntouchTest("namespace Ns {\n\n",
268ee25a327Sksyx "\n} // namespace Ns\n\n"
269ee25a327Sksyx "namespace {\n\n",
270ee25a327Sksyx "\n} // namespace\n", true);
271ee25a327Sksyx verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
272ee25a327Sksyx verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
273ee25a327Sksyx
274ee25a327Sksyx TestKit = MakeUntouchTest("namespace Ns {\n",
275ee25a327Sksyx "} // namespace Ns\n\n"
276ee25a327Sksyx "namespace {\n",
277ee25a327Sksyx "} // namespace\n", true);
278ee25a327Sksyx verifyFormat(TestKit.first, AlwaysStyle, TestKit.second);
279ee25a327Sksyx verifyFormat(TestKit.second, NeverStyle, removeEmptyLines(TestKit.second));
280ee25a327Sksyx }
281ee25a327Sksyx
TEST_F(DefinitionBlockSeparatorTest,Always)2826f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, Always) {
2836f6f88ffSksyx FormatStyle Style = getLLVMStyle();
2846f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
28558a71c66SOwen Pan
28658a71c66SOwen Pan verifyFormat("// clang-format off\n"
28758a71c66SOwen Pan "template<class T>\n"
28858a71c66SOwen Pan "concept C = not A<S<T>>;\n"
28958a71c66SOwen Pan "// clang-format on\n"
29058a71c66SOwen Pan "\n"
29158a71c66SOwen Pan "struct E {};",
29258a71c66SOwen Pan Style);
29358a71c66SOwen Pan
2946f6f88ffSksyx std::string Prefix = "namespace {\n";
295ee25a327Sksyx std::string Infix = "\n"
296ee25a327Sksyx "// Enum test1\n"
297ee25a327Sksyx "// Enum test2\n"
298ee25a327Sksyx "enum Foo { FOO, BAR };\n"
2996f6f88ffSksyx "\n"
300ee25a327Sksyx "/*\n"
301ee25a327Sksyx "test1\n"
302ee25a327Sksyx "test2\n"
303ee25a327Sksyx "*/\n"
3045e5efd8aSksyx "/*const*/ int foo(int i, int j) {\n"
3056f6f88ffSksyx " int r = i + j;\n"
3066f6f88ffSksyx " return r;\n"
3076f6f88ffSksyx "}\n"
3086f6f88ffSksyx "\n"
309ee25a327Sksyx "// Foobar\n"
3106f6f88ffSksyx "int i, j, k;\n"
3116f6f88ffSksyx "\n"
312ee25a327Sksyx "// Comment for function\n"
313ee25a327Sksyx "// Comment line 2\n"
314ee25a327Sksyx "// Comment line 3\n"
3156f6f88ffSksyx "int bar(int j, int k) {\n"
3165e5efd8aSksyx " {\n"
3176f6f88ffSksyx " int r = j * k;\n"
3186f6f88ffSksyx " return r;\n"
3196f6f88ffSksyx " }\n"
3205e5efd8aSksyx "}\n"
3216f6f88ffSksyx "\n"
322ee25a327Sksyx "int bar2(int j, int k) {\n"
323ee25a327Sksyx " int r = j / k;\n"
324ee25a327Sksyx " return r;\n"
325ee25a327Sksyx "}\n"
326ee25a327Sksyx "\n"
327ee25a327Sksyx "/* Comment block in one line*/\n"
3286f6f88ffSksyx "enum Bar { FOOBAR, BARFOO };\n"
329ee25a327Sksyx "\n"
3305e5efd8aSksyx "int bar3(int j, int k, const enum Bar b) {\n"
331ee25a327Sksyx " // A comment\n"
332ee25a327Sksyx " int r = j % k;\n"
333a70549aeSksyx " if (struct S = getS()) {\n"
334a70549aeSksyx " // if condition\n"
335a70549aeSksyx " }\n"
336ee25a327Sksyx " return r;\n"
337ee25a327Sksyx "}\n";
338ee25a327Sksyx std::string Postfix = "\n"
339ee25a327Sksyx "} // namespace\n"
340ee25a327Sksyx "\n"
341ee25a327Sksyx "namespace T {\n"
342ee25a327Sksyx "int i, j, k;\n"
343ee25a327Sksyx "} // namespace T";
344ee25a327Sksyx verifyFormat(Prefix + removeEmptyLines(Infix) + removeEmptyLines(Postfix),
345ee25a327Sksyx Style, Prefix + Infix + Postfix);
3466f6f88ffSksyx }
3476f6f88ffSksyx
TEST_F(DefinitionBlockSeparatorTest,Never)3486f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, Never) {
3496f6f88ffSksyx FormatStyle Style = getLLVMStyle();
3506f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Never;
3516f6f88ffSksyx std::string Prefix = "namespace {\n";
352ee25a327Sksyx std::string Postfix = "// Enum test1\n"
353ee25a327Sksyx "// Enum test2\n"
354ee25a327Sksyx "enum Foo { FOO, BAR };\n"
3556f6f88ffSksyx "\n"
356ee25a327Sksyx "/*\n"
357ee25a327Sksyx "test1\n"
358ee25a327Sksyx "test2\n"
359ee25a327Sksyx "*/\n"
3605e5efd8aSksyx "/*const*/ int foo(int i, int j) {\n"
3616f6f88ffSksyx " int r = i + j;\n"
3626f6f88ffSksyx " return r;\n"
3636f6f88ffSksyx "}\n"
3646f6f88ffSksyx "\n"
365ee25a327Sksyx "// Foobar\n"
3666f6f88ffSksyx "int i, j, k;\n"
3676f6f88ffSksyx "\n"
368ee25a327Sksyx "// Comment for function\n"
369ee25a327Sksyx "// Comment line 2\n"
370ee25a327Sksyx "// Comment line 3\n"
3716f6f88ffSksyx "int bar(int j, int k) {\n"
3725e5efd8aSksyx " {\n"
3736f6f88ffSksyx " int r = j * k;\n"
3746f6f88ffSksyx " return r;\n"
3756f6f88ffSksyx " }\n"
3765e5efd8aSksyx "}\n"
3776f6f88ffSksyx "\n"
378ee25a327Sksyx "int bar2(int j, int k) {\n"
379ee25a327Sksyx " int r = j / k;\n"
380ee25a327Sksyx " return r;\n"
381ee25a327Sksyx "}\n"
382ee25a327Sksyx "\n"
383ee25a327Sksyx "/* Comment block in one line*/\n"
3846f6f88ffSksyx "enum Bar { FOOBAR, BARFOO };\n"
385ee25a327Sksyx "\n"
3865e5efd8aSksyx "int bar3(int j, int k, const enum Bar b) {\n"
387ee25a327Sksyx " // A comment\n"
388ee25a327Sksyx " int r = j % k;\n"
389a70549aeSksyx " if (struct S = getS()) {\n"
390a70549aeSksyx " // if condition\n"
391a70549aeSksyx " }\n"
392ee25a327Sksyx " return r;\n"
393ee25a327Sksyx "}\n"
3946f6f88ffSksyx "} // namespace";
3956f6f88ffSksyx verifyFormat(Prefix + "\n\n\n" + Postfix, Style,
3966f6f88ffSksyx Prefix + removeEmptyLines(Postfix));
3976f6f88ffSksyx }
3986f6f88ffSksyx
TEST_F(DefinitionBlockSeparatorTest,OpeningBracketOwnsLine)3996f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, OpeningBracketOwnsLine) {
4006f6f88ffSksyx FormatStyle Style = getLLVMStyle();
4016f6f88ffSksyx Style.BreakBeforeBraces = FormatStyle::BS_Allman;
4026f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
403ee25a327Sksyx verifyFormat("namespace NS\n"
404ee25a327Sksyx "{\n"
405ee25a327Sksyx "// Enum test1\n"
406ee25a327Sksyx "// Enum test2\n"
407ee25a327Sksyx "enum Foo\n"
4086f6f88ffSksyx "{\n"
4096f6f88ffSksyx " FOO,\n"
4106f6f88ffSksyx " BAR\n"
4116f6f88ffSksyx "};\n"
4126f6f88ffSksyx "\n"
413ee25a327Sksyx "/*\n"
414ee25a327Sksyx "test1\n"
415ee25a327Sksyx "test2\n"
416ee25a327Sksyx "*/\n"
4175e5efd8aSksyx "/*const*/ int foo(int i, int j)\n"
4186f6f88ffSksyx "{\n"
4196f6f88ffSksyx " int r = i + j;\n"
4206f6f88ffSksyx " return r;\n"
4216f6f88ffSksyx "}\n"
4226f6f88ffSksyx "\n"
423ee25a327Sksyx "// Foobar\n"
4246f6f88ffSksyx "int i, j, k;\n"
4256f6f88ffSksyx "\n"
426ee25a327Sksyx "// Comment for function\n"
427ee25a327Sksyx "// Comment line 2\n"
428ee25a327Sksyx "// Comment line 3\n"
4296f6f88ffSksyx "int bar(int j, int k)\n"
4306f6f88ffSksyx "{\n"
4315e5efd8aSksyx " {\n"
4326f6f88ffSksyx " int r = j * k;\n"
4336f6f88ffSksyx " return r;\n"
4346f6f88ffSksyx " }\n"
4355e5efd8aSksyx "}\n"
4366f6f88ffSksyx "\n"
437ee25a327Sksyx "int bar2(int j, int k)\n"
438ee25a327Sksyx "{\n"
439ee25a327Sksyx " int r = j / k;\n"
440ee25a327Sksyx " return r;\n"
441ee25a327Sksyx "}\n"
442ee25a327Sksyx "\n"
4436f6f88ffSksyx "enum Bar\n"
4446f6f88ffSksyx "{\n"
4456f6f88ffSksyx " FOOBAR,\n"
4466f6f88ffSksyx " BARFOO\n"
447ee25a327Sksyx "};\n"
448ee25a327Sksyx "\n"
4495e5efd8aSksyx "int bar3(int j, int k, const enum Bar b)\n"
450ee25a327Sksyx "{\n"
451ee25a327Sksyx " // A comment\n"
452ee25a327Sksyx " int r = j % k;\n"
453a70549aeSksyx " if (struct S = getS())\n"
454a70549aeSksyx " {\n"
455a70549aeSksyx " // if condition\n"
456a70549aeSksyx " }\n"
457ee25a327Sksyx " return r;\n"
458ee25a327Sksyx "}\n"
459ee25a327Sksyx "} // namespace NS",
4606f6f88ffSksyx Style);
4616f6f88ffSksyx }
4626f6f88ffSksyx
TEST_F(DefinitionBlockSeparatorTest,TryBlocks)463b58616c2SMarek Kurdej TEST_F(DefinitionBlockSeparatorTest, TryBlocks) {
464b58616c2SMarek Kurdej FormatStyle Style = getLLVMStyle();
465b58616c2SMarek Kurdej Style.BreakBeforeBraces = FormatStyle::BS_Allman;
466b58616c2SMarek Kurdej Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
467b58616c2SMarek Kurdej verifyFormat("void FunctionWithInternalTry()\n"
468b58616c2SMarek Kurdej "{\n"
469b58616c2SMarek Kurdej " try\n"
470b58616c2SMarek Kurdej " {\n"
471b58616c2SMarek Kurdej " return;\n"
472b58616c2SMarek Kurdej " }\n"
473b58616c2SMarek Kurdej " catch (const std::exception &)\n"
474b58616c2SMarek Kurdej " {\n"
475b58616c2SMarek Kurdej " }\n"
476b58616c2SMarek Kurdej "}",
477b58616c2SMarek Kurdej Style, "", /*Inverse=*/false);
478b58616c2SMarek Kurdej verifyFormat("void FunctionWithTryBlock()\n"
479b58616c2SMarek Kurdej "try\n"
480b58616c2SMarek Kurdej "{\n"
481b58616c2SMarek Kurdej " return;\n"
482b58616c2SMarek Kurdej "}\n"
483b58616c2SMarek Kurdej "catch (const std::exception &)\n"
484b58616c2SMarek Kurdej "{\n"
485b58616c2SMarek Kurdej "}",
486b58616c2SMarek Kurdej Style, "", /*Inverse=*/false);
487b58616c2SMarek Kurdej }
488b58616c2SMarek Kurdej
TEST_F(DefinitionBlockSeparatorTest,Leave)4896f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, Leave) {
4906f6f88ffSksyx FormatStyle Style = getLLVMStyle();
4916f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Leave;
4926f6f88ffSksyx Style.MaxEmptyLinesToKeep = 3;
4936f6f88ffSksyx std::string LeaveAs = "namespace {\n"
4946f6f88ffSksyx "\n"
495ee25a327Sksyx "// Enum test1\n"
496ee25a327Sksyx "// Enum test2\n"
4976f6f88ffSksyx "enum Foo { FOO, BAR };\n"
4986f6f88ffSksyx "\n\n\n"
499ee25a327Sksyx "/*\n"
500ee25a327Sksyx "test1\n"
501ee25a327Sksyx "test2\n"
502ee25a327Sksyx "*/\n"
5035e5efd8aSksyx "/*const*/ int foo(int i, int j) {\n"
5046f6f88ffSksyx " int r = i + j;\n"
5056f6f88ffSksyx " return r;\n"
5066f6f88ffSksyx "}\n"
5076f6f88ffSksyx "\n"
508ee25a327Sksyx "// Foobar\n"
5096f6f88ffSksyx "int i, j, k;\n"
5106f6f88ffSksyx "\n"
511ee25a327Sksyx "// Comment for function\n"
512ee25a327Sksyx "// Comment line 2\n"
513ee25a327Sksyx "// Comment line 3\n"
5146f6f88ffSksyx "int bar(int j, int k) {\n"
5155e5efd8aSksyx " {\n"
5166f6f88ffSksyx " int r = j * k;\n"
5176f6f88ffSksyx " return r;\n"
5186f6f88ffSksyx " }\n"
5195e5efd8aSksyx "}\n"
5206f6f88ffSksyx "\n"
521ee25a327Sksyx "int bar2(int j, int k) {\n"
522ee25a327Sksyx " int r = j / k;\n"
523ee25a327Sksyx " return r;\n"
524ee25a327Sksyx "}\n"
525ee25a327Sksyx "\n"
526ee25a327Sksyx "// Comment for inline enum\n"
5276f6f88ffSksyx "enum Bar { FOOBAR, BARFOO };\n"
5285e5efd8aSksyx "int bar3(int j, int k, const enum Bar b) {\n"
529ee25a327Sksyx " // A comment\n"
530ee25a327Sksyx " int r = j % k;\n"
531a70549aeSksyx " if (struct S = getS()) {\n"
532a70549aeSksyx " // if condition\n"
533a70549aeSksyx " }\n"
534ee25a327Sksyx " return r;\n"
535ee25a327Sksyx "}\n"
5366f6f88ffSksyx "} // namespace";
5376f6f88ffSksyx verifyFormat(LeaveAs, Style, LeaveAs);
5386f6f88ffSksyx }
5396f6f88ffSksyx
TEST_F(DefinitionBlockSeparatorTest,CSharp)5406f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, CSharp) {
5416f6f88ffSksyx FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
5426f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
5436f6f88ffSksyx Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
5446f6f88ffSksyx Style.AllowShortEnumsOnASingleLine = false;
5456f6f88ffSksyx verifyFormat("namespace {\r\n"
5466f6f88ffSksyx "public class SomeTinyClass {\r\n"
5476f6f88ffSksyx " int X;\r\n"
5486f6f88ffSksyx "}\r\n"
5496f6f88ffSksyx "\r\n"
5506f6f88ffSksyx "public class AnotherTinyClass {\r\n"
5516f6f88ffSksyx " int Y;\r\n"
5526f6f88ffSksyx "}\r\n"
5536f6f88ffSksyx "\r\n"
5546f6f88ffSksyx "internal static String toString() {\r\n"
5556f6f88ffSksyx "}\r\n"
5566f6f88ffSksyx "\r\n"
557ee25a327Sksyx "// Comment for enum\r\n"
5586f6f88ffSksyx "public enum var {\r\n"
5596f6f88ffSksyx " none,\r\n"
5606f6f88ffSksyx " @string,\r\n"
5616f6f88ffSksyx " bool,\r\n"
5626f6f88ffSksyx " @enum\r\n"
5636f6f88ffSksyx "}\r\n"
5646f6f88ffSksyx "\r\n"
565ee25a327Sksyx "// Test\r\n"
5666f6f88ffSksyx "[STAThread]\r\n"
5676f6f88ffSksyx "static void Main(string[] args) {\r\n"
5686f6f88ffSksyx " Console.WriteLine(\"HelloWorld\");\r\n"
5696f6f88ffSksyx "}\r\n"
5706f6f88ffSksyx "\r\n"
5716f6f88ffSksyx "static decimal Test() {\r\n"
5726f6f88ffSksyx "}\r\n"
5736f6f88ffSksyx "}\r\n"
5746f6f88ffSksyx "\r\n"
5756f6f88ffSksyx "public class FoobarClass {\r\n"
5766f6f88ffSksyx " int foobar;\r\n"
5776f6f88ffSksyx "}",
5786f6f88ffSksyx Style);
5796f6f88ffSksyx }
5806f6f88ffSksyx
TEST_F(DefinitionBlockSeparatorTest,JavaScript)5816f6f88ffSksyx TEST_F(DefinitionBlockSeparatorTest, JavaScript) {
5826f6f88ffSksyx FormatStyle Style = getLLVMStyle(FormatStyle::LK_JavaScript);
5836f6f88ffSksyx Style.SeparateDefinitionBlocks = FormatStyle::SDS_Always;
5846f6f88ffSksyx Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
5856f6f88ffSksyx Style.AllowShortEnumsOnASingleLine = false;
5866f6f88ffSksyx verifyFormat("export const enum Foo {\n"
5876f6f88ffSksyx " A = 1,\n"
5886f6f88ffSksyx " B\n"
5896f6f88ffSksyx "}\n"
5906f6f88ffSksyx "\n"
5916f6f88ffSksyx "export function A() {\n"
5926f6f88ffSksyx "}\n"
5936f6f88ffSksyx "\n"
5946f6f88ffSksyx "export default function B() {\n"
5956f6f88ffSksyx "}\n"
5966f6f88ffSksyx "\n"
5976f6f88ffSksyx "export function C() {\n"
5986f6f88ffSksyx "}\n"
5996f6f88ffSksyx "\n"
6006f6f88ffSksyx "var t, p, q;\n"
6016f6f88ffSksyx "\n"
6026f6f88ffSksyx "export abstract class X {\n"
6036f6f88ffSksyx " y: number;\n"
6046f6f88ffSksyx "}\n"
6056f6f88ffSksyx "\n"
6066f6f88ffSksyx "export const enum Bar {\n"
6076f6f88ffSksyx " D = 1,\n"
6086f6f88ffSksyx " E\n"
6096f6f88ffSksyx "}",
6106f6f88ffSksyx Style);
6116f6f88ffSksyx }
6126f6f88ffSksyx } // namespace
6136f6f88ffSksyx } // namespace format
6146f6f88ffSksyx } // namespace clang
615