xref: /llvm-project/clang/unittests/Format/FormatTestJson.cpp (revision 1c58208d899285318c89e069268145c85ec33368)
18b7881a0Smydeveloperday //===- unittest/Format/FormatTestJson.cpp - Formatting tests for Json     -===//
28b7881a0Smydeveloperday //
38b7881a0Smydeveloperday // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48b7881a0Smydeveloperday // See https://llvm.org/LICENSE.txt for license information.
58b7881a0Smydeveloperday // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68b7881a0Smydeveloperday //
78b7881a0Smydeveloperday //===----------------------------------------------------------------------===//
88b7881a0Smydeveloperday 
98b7881a0Smydeveloperday #include "FormatTestUtils.h"
108b7881a0Smydeveloperday #include "clang/Format/Format.h"
118b7881a0Smydeveloperday #include "llvm/Support/Debug.h"
128b7881a0Smydeveloperday #include "gtest/gtest.h"
138b7881a0Smydeveloperday 
148b7881a0Smydeveloperday #define DEBUG_TYPE "format-test-json"
158b7881a0Smydeveloperday 
168b7881a0Smydeveloperday namespace clang {
178b7881a0Smydeveloperday namespace format {
188b7881a0Smydeveloperday 
19*1c58208dSOwen Pan class FormatTestJson : public testing::Test {
208b7881a0Smydeveloperday protected:
format(StringRef Code,unsigned Offset,unsigned Length,const FormatStyle & Style)21*1c58208dSOwen Pan   static std::string format(StringRef Code, unsigned Offset, unsigned Length,
22*1c58208dSOwen Pan                             const FormatStyle &Style) {
238b7881a0Smydeveloperday     LLVM_DEBUG(llvm::errs() << "---\n");
248b7881a0Smydeveloperday     LLVM_DEBUG(llvm::errs() << Code << "\n\n");
258b7881a0Smydeveloperday 
268b7881a0Smydeveloperday     tooling::Replacements Replaces;
278b7881a0Smydeveloperday 
288b7881a0Smydeveloperday     // Mock up what ClangFormat.cpp will do for JSON by adding a variable
298b7881a0Smydeveloperday     // to trick JSON into being JavaScript
3063a56576SAndrew Smith     if (Style.isJson() && !Style.DisableFormat) {
318b7881a0Smydeveloperday       auto Err = Replaces.add(
328b7881a0Smydeveloperday           tooling::Replacement(tooling::Replacement("", 0, 0, "x = ")));
3334ce42feSMarek Kurdej       if (Err)
348b7881a0Smydeveloperday         llvm::errs() << "Bad Json variable insertion\n";
358b7881a0Smydeveloperday     }
368b7881a0Smydeveloperday     auto ChangedCode = applyAllReplacements(Code, Replaces);
3734ce42feSMarek Kurdej     if (!ChangedCode)
388b7881a0Smydeveloperday       llvm::errs() << "Bad Json varibale replacement\n";
398b7881a0Smydeveloperday     StringRef NewCode = *ChangedCode;
408b7881a0Smydeveloperday 
418b7881a0Smydeveloperday     std::vector<tooling::Range> Ranges(1, tooling::Range(0, NewCode.size()));
428b7881a0Smydeveloperday     Replaces = reformat(Style, NewCode, Ranges);
438b7881a0Smydeveloperday     auto Result = applyAllReplacements(NewCode, Replaces);
448b7881a0Smydeveloperday     EXPECT_TRUE(static_cast<bool>(Result));
458b7881a0Smydeveloperday     LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
468b7881a0Smydeveloperday     return *Result;
478b7881a0Smydeveloperday   }
488b7881a0Smydeveloperday 
498b7881a0Smydeveloperday   static std::string
format(StringRef Code,const FormatStyle & Style=getLLVMStyle (FormatStyle::LK_Json))50*1c58208dSOwen Pan   format(StringRef Code,
518b7881a0Smydeveloperday          const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {
528b7881a0Smydeveloperday     return format(Code, 0, Code.size(), Style);
538b7881a0Smydeveloperday   }
548b7881a0Smydeveloperday 
getStyleWithColumns(unsigned ColumnLimit)558b7881a0Smydeveloperday   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
568b7881a0Smydeveloperday     FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
578b7881a0Smydeveloperday     Style.ColumnLimit = ColumnLimit;
588b7881a0Smydeveloperday     return Style;
598b7881a0Smydeveloperday   }
608b7881a0Smydeveloperday 
verifyFormatStable(StringRef Code,const FormatStyle & Style)61*1c58208dSOwen Pan   static void verifyFormatStable(StringRef Code, const FormatStyle &Style) {
6263a56576SAndrew Smith     EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
6363a56576SAndrew Smith   }
6463a56576SAndrew Smith 
658b7881a0Smydeveloperday   static void
verifyFormat(StringRef Code,const FormatStyle & Style=getLLVMStyle (FormatStyle::LK_Json))66*1c58208dSOwen Pan   verifyFormat(StringRef Code,
678b7881a0Smydeveloperday                const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {
6863a56576SAndrew Smith     verifyFormatStable(Code, Style);
698b7881a0Smydeveloperday     EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
708b7881a0Smydeveloperday   }
718b7881a0Smydeveloperday };
728b7881a0Smydeveloperday 
TEST_F(FormatTestJson,JsonRecord)738b7881a0Smydeveloperday TEST_F(FormatTestJson, JsonRecord) {
748b7881a0Smydeveloperday   verifyFormat("{}");
758b7881a0Smydeveloperday   verifyFormat("{\n"
768b7881a0Smydeveloperday                "  \"name\": 1\n"
778b7881a0Smydeveloperday                "}");
788b7881a0Smydeveloperday   verifyFormat("{\n"
798b7881a0Smydeveloperday                "  \"name\": \"Foo\"\n"
808b7881a0Smydeveloperday                "}");
818b7881a0Smydeveloperday   verifyFormat("{\n"
828b7881a0Smydeveloperday                "  \"name\": {\n"
838b7881a0Smydeveloperday                "    \"value\": 1\n"
848b7881a0Smydeveloperday                "  }\n"
858b7881a0Smydeveloperday                "}");
868b7881a0Smydeveloperday   verifyFormat("{\n"
878b7881a0Smydeveloperday                "  \"name\": {\n"
888b7881a0Smydeveloperday                "    \"value\": 1\n"
898b7881a0Smydeveloperday                "  },\n"
908b7881a0Smydeveloperday                "  \"name\": {\n"
918b7881a0Smydeveloperday                "    \"value\": 2\n"
928b7881a0Smydeveloperday                "  }\n"
938b7881a0Smydeveloperday                "}");
948b7881a0Smydeveloperday   verifyFormat("{\n"
958b7881a0Smydeveloperday                "  \"name\": {\n"
968b7881a0Smydeveloperday                "    \"value\": [\n"
978b7881a0Smydeveloperday                "      1,\n"
988b7881a0Smydeveloperday                "      2,\n"
998b7881a0Smydeveloperday                "    ]\n"
1008b7881a0Smydeveloperday                "  }\n"
1018b7881a0Smydeveloperday                "}");
1028b7881a0Smydeveloperday   verifyFormat("{\n"
1038b7881a0Smydeveloperday                "  \"name\": {\n"
1048b7881a0Smydeveloperday                "    \"value\": [\n"
1058b7881a0Smydeveloperday                "      \"name\": {\n"
1068b7881a0Smydeveloperday                "        \"value\": 1\n"
1078b7881a0Smydeveloperday                "      },\n"
1088b7881a0Smydeveloperday                "      \"name\": {\n"
1098b7881a0Smydeveloperday                "        \"value\": 2\n"
1108b7881a0Smydeveloperday                "      }\n"
1118b7881a0Smydeveloperday                "    ]\n"
1128b7881a0Smydeveloperday                "  }\n"
1138b7881a0Smydeveloperday                "}");
1148b7881a0Smydeveloperday   verifyFormat(R"({
1158b7881a0Smydeveloperday   "firstName": "John",
1168b7881a0Smydeveloperday   "lastName": "Smith",
1178b7881a0Smydeveloperday   "isAlive": true,
1188b7881a0Smydeveloperday   "age": 27,
1198b7881a0Smydeveloperday   "address": {
1208b7881a0Smydeveloperday     "streetAddress": "21 2nd Street",
1218b7881a0Smydeveloperday     "city": "New York",
1228b7881a0Smydeveloperday     "state": "NY",
1238b7881a0Smydeveloperday     "postalCode": "10021-3100"
1248b7881a0Smydeveloperday   },
1258b7881a0Smydeveloperday   "phoneNumbers": [
1268b7881a0Smydeveloperday     {
1278b7881a0Smydeveloperday       "type": "home",
1288b7881a0Smydeveloperday       "number": "212 555-1234"
1298b7881a0Smydeveloperday     },
1308b7881a0Smydeveloperday     {
1318b7881a0Smydeveloperday       "type": "office",
1328b7881a0Smydeveloperday       "number": "646 555-4567"
1338b7881a0Smydeveloperday     }
1348b7881a0Smydeveloperday   ],
1358b7881a0Smydeveloperday   "children": [],
1368b7881a0Smydeveloperday   "spouse": null
1378b7881a0Smydeveloperday })");
1388b7881a0Smydeveloperday }
1398b7881a0Smydeveloperday 
TEST_F(FormatTestJson,JsonArray)1408b7881a0Smydeveloperday TEST_F(FormatTestJson, JsonArray) {
1418b7881a0Smydeveloperday   verifyFormat("[]");
1428b7881a0Smydeveloperday   verifyFormat("[\n"
1438b7881a0Smydeveloperday                "  1\n"
1448b7881a0Smydeveloperday                "]");
1458b7881a0Smydeveloperday   verifyFormat("[\n"
1468b7881a0Smydeveloperday                "  1,\n"
1478b7881a0Smydeveloperday                "  2\n"
1488b7881a0Smydeveloperday                "]");
1498b7881a0Smydeveloperday   verifyFormat("[\n"
1508b7881a0Smydeveloperday                "  {},\n"
1518b7881a0Smydeveloperday                "  {}\n"
1528b7881a0Smydeveloperday                "]");
1538b7881a0Smydeveloperday   verifyFormat("[\n"
1548b7881a0Smydeveloperday                "  {\n"
1558b7881a0Smydeveloperday                "    \"name\": 1\n"
1568b7881a0Smydeveloperday                "  },\n"
1578b7881a0Smydeveloperday                "  {}\n"
1588b7881a0Smydeveloperday                "]");
1598b7881a0Smydeveloperday }
1608b7881a0Smydeveloperday 
TEST_F(FormatTestJson,JsonArrayOneLine)16195b39471Smydeveloperday TEST_F(FormatTestJson, JsonArrayOneLine) {
16295b39471Smydeveloperday   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
16395b39471Smydeveloperday   Style.BreakArrays = false;
16495b39471Smydeveloperday   Style.SpacesInContainerLiterals = false;
16595b39471Smydeveloperday   verifyFormat("[]", Style);
16695b39471Smydeveloperday   verifyFormat("[1]", Style);
16795b39471Smydeveloperday   verifyFormat("[1, 2]", Style);
16895b39471Smydeveloperday   verifyFormat("[1, 2, 3]", Style);
16995b39471Smydeveloperday   verifyFormat("[1, 2, 3, 4]", Style);
17095b39471Smydeveloperday   verifyFormat("[1, 2, 3, 4, 5]", Style);
17195b39471Smydeveloperday 
17295b39471Smydeveloperday   verifyFormat("[\n"
17395b39471Smydeveloperday                "  1,\n"
17495b39471Smydeveloperday                "  2,\n"
17595b39471Smydeveloperday                "  {\n"
17695b39471Smydeveloperday                "    A: 1\n"
17795b39471Smydeveloperday                "  }\n"
17895b39471Smydeveloperday                "]",
17995b39471Smydeveloperday                Style);
18095b39471Smydeveloperday }
18195b39471Smydeveloperday 
TEST_F(FormatTestJson,JsonNoStringSplit)1828b7881a0Smydeveloperday TEST_F(FormatTestJson, JsonNoStringSplit) {
1838b7881a0Smydeveloperday   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
1848b7881a0Smydeveloperday   Style.IndentWidth = 4;
1858b7881a0Smydeveloperday   verifyFormat(
1868b7881a0Smydeveloperday       "[\n"
1878b7881a0Smydeveloperday       "    {\n"
1888b7881a0Smydeveloperday       "        "
1898b7881a0Smydeveloperday       "\"naaaaaaaa\": \"foooooooooooooooooooooo oooooooooooooooooooooo\"\n"
1908b7881a0Smydeveloperday       "    },\n"
1918b7881a0Smydeveloperday       "    {}\n"
1928b7881a0Smydeveloperday       "]",
1938b7881a0Smydeveloperday       Style);
1948b7881a0Smydeveloperday   verifyFormat("[\n"
1958b7881a0Smydeveloperday                "    {\n"
1968b7881a0Smydeveloperday                "        "
1978b7881a0Smydeveloperday                "\"naaaaaaaa\": "
1988b7881a0Smydeveloperday                "\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
1998b7881a0Smydeveloperday                "oooooooooooooooooooooooooo\"\n"
2008b7881a0Smydeveloperday                "    },\n"
2018b7881a0Smydeveloperday                "    {}\n"
2028b7881a0Smydeveloperday                "]",
2038b7881a0Smydeveloperday                Style);
2048b7881a0Smydeveloperday 
2058b7881a0Smydeveloperday   Style.ColumnLimit = 80;
2068b7881a0Smydeveloperday   verifyFormat("[\n"
2078b7881a0Smydeveloperday                "    {\n"
2088b7881a0Smydeveloperday                "        "
2098b7881a0Smydeveloperday                "\"naaaaaaaa\":\n"
2108b7881a0Smydeveloperday                "            "
2118b7881a0Smydeveloperday                "\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
2128b7881a0Smydeveloperday                "oooooooooooooooooooooooooo\"\n"
2138b7881a0Smydeveloperday                "    },\n"
2148b7881a0Smydeveloperday                "    {}\n"
2158b7881a0Smydeveloperday                "]",
2168b7881a0Smydeveloperday                Style);
2178b7881a0Smydeveloperday }
2188b7881a0Smydeveloperday 
TEST_F(FormatTestJson,DisableJsonFormat)21963a56576SAndrew Smith TEST_F(FormatTestJson, DisableJsonFormat) {
22063a56576SAndrew Smith   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
22163a56576SAndrew Smith   verifyFormatStable("{}", Style);
22263a56576SAndrew Smith   verifyFormatStable("{\n"
22363a56576SAndrew Smith                      "  \"name\": 1\n"
22463a56576SAndrew Smith                      "}",
22563a56576SAndrew Smith                      Style);
22663a56576SAndrew Smith 
22763a56576SAndrew Smith   // Since we have to disable formatting to run this test, we shall refrain from
22863a56576SAndrew Smith   // calling test::messUp lest we change the unformatted code and cannot format
22963a56576SAndrew Smith   // it back to how it started.
23063a56576SAndrew Smith   Style.DisableFormat = true;
23163a56576SAndrew Smith   verifyFormatStable("{}", Style);
23263a56576SAndrew Smith   verifyFormatStable("{\n"
23363a56576SAndrew Smith                      "  \"name\": 1\n"
23463a56576SAndrew Smith                      "}",
23563a56576SAndrew Smith                      Style);
23663a56576SAndrew Smith }
23763a56576SAndrew Smith 
TEST_F(FormatTestJson,SpaceBeforeJsonColon)238af98f3b1Smydeveloperday TEST_F(FormatTestJson, SpaceBeforeJsonColon) {
239af98f3b1Smydeveloperday   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
240af98f3b1Smydeveloperday   verifyFormatStable("{\n"
241af98f3b1Smydeveloperday                      "  \"name\": 1\n"
242af98f3b1Smydeveloperday                      "}",
243af98f3b1Smydeveloperday                      Style);
244af98f3b1Smydeveloperday 
245af98f3b1Smydeveloperday   Style.SpaceBeforeJsonColon = true;
246af98f3b1Smydeveloperday   verifyFormatStable("{}", Style);
247af98f3b1Smydeveloperday   verifyFormatStable("{\n"
248af98f3b1Smydeveloperday                      "  \"name\" : 1\n"
249af98f3b1Smydeveloperday                      "}",
250af98f3b1Smydeveloperday                      Style);
251af98f3b1Smydeveloperday }
252af98f3b1Smydeveloperday 
TEST_F(FormatTestJson,StartsWithWhitespaces)25351f6a166SOwen Pan TEST_F(FormatTestJson, StartsWithWhitespaces) {
25451f6a166SOwen Pan   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
25551f6a166SOwen Pan   EXPECT_EQ("{\n"
25651f6a166SOwen Pan             "  \"name\": 1\n"
25751f6a166SOwen Pan             "}",
25851f6a166SOwen Pan             format(" {\n"
25951f6a166SOwen Pan                    "  \"name\": 1\n"
26051f6a166SOwen Pan                    "}",
26151f6a166SOwen Pan                    Style));
26251f6a166SOwen Pan 
26351f6a166SOwen Pan   // FIXME: The block below is over-indented.
26451f6a166SOwen Pan   EXPECT_EQ("    {\n"
26551f6a166SOwen Pan             "      \"name\": 1\n"
26651f6a166SOwen Pan             "    }",
26751f6a166SOwen Pan             format("\n{\n"
26851f6a166SOwen Pan                    "  \"name\": 1\n"
26951f6a166SOwen Pan                    "}",
27051f6a166SOwen Pan                    Style));
27151f6a166SOwen Pan }
27251f6a166SOwen Pan 
2738b7881a0Smydeveloperday } // namespace format
2748b7881a0Smydeveloperday } // end namespace clang
275