xref: /llvm-project/clang/unittests/Format/FormatTestJson.cpp (revision 8b7881a084d0bc26499cf93e4ac45b59257a03b3)
1 //===- unittest/Format/FormatTestJson.cpp - Formatting tests for Json     -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "FormatTestUtils.h"
10 #include "clang/Format/Format.h"
11 #include "llvm/Support/Debug.h"
12 #include "gtest/gtest.h"
13 
14 #define DEBUG_TYPE "format-test-json"
15 
16 namespace clang {
17 namespace format {
18 
19 class FormatTestJson : public ::testing::Test {
20 protected:
21   static std::string format(llvm::StringRef Code, unsigned Offset,
22                             unsigned Length, const FormatStyle &Style) {
23     LLVM_DEBUG(llvm::errs() << "---\n");
24     LLVM_DEBUG(llvm::errs() << Code << "\n\n");
25 
26     tooling::Replacements Replaces;
27 
28     // Mock up what ClangFormat.cpp will do for JSON by adding a variable
29     // to trick JSON into being JavaScript
30     if (Style.isJson()) {
31       auto Err = Replaces.add(
32           tooling::Replacement(tooling::Replacement("", 0, 0, "x = ")));
33       if (Err) {
34         llvm::errs() << "Bad Json variable insertion\n";
35       }
36     }
37     auto ChangedCode = applyAllReplacements(Code, Replaces);
38     if (!ChangedCode) {
39       llvm::errs() << "Bad Json varibale replacement\n";
40     }
41     StringRef NewCode = *ChangedCode;
42 
43     std::vector<tooling::Range> Ranges(1, tooling::Range(0, NewCode.size()));
44     Replaces = reformat(Style, NewCode, Ranges);
45     auto Result = applyAllReplacements(NewCode, Replaces);
46     EXPECT_TRUE(static_cast<bool>(Result));
47     LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
48     return *Result;
49   }
50 
51   static std::string
52   format(llvm::StringRef Code,
53          const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {
54     return format(Code, 0, Code.size(), Style);
55   }
56 
57   static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
58     FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
59     Style.ColumnLimit = ColumnLimit;
60     return Style;
61   }
62 
63   static void
64   verifyFormat(llvm::StringRef Code,
65                const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {
66     EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
67     EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
68   }
69 };
70 
71 TEST_F(FormatTestJson, JsonRecord) {
72   verifyFormat("{}");
73   verifyFormat("{\n"
74                "  \"name\": 1\n"
75                "}");
76   verifyFormat("{\n"
77                "  \"name\": \"Foo\"\n"
78                "}");
79   verifyFormat("{\n"
80                "  \"name\": {\n"
81                "    \"value\": 1\n"
82                "  }\n"
83                "}");
84   verifyFormat("{\n"
85                "  \"name\": {\n"
86                "    \"value\": 1\n"
87                "  },\n"
88                "  \"name\": {\n"
89                "    \"value\": 2\n"
90                "  }\n"
91                "}");
92   verifyFormat("{\n"
93                "  \"name\": {\n"
94                "    \"value\": [\n"
95                "      1,\n"
96                "      2,\n"
97                "    ]\n"
98                "  }\n"
99                "}");
100   verifyFormat("{\n"
101                "  \"name\": {\n"
102                "    \"value\": [\n"
103                "      \"name\": {\n"
104                "        \"value\": 1\n"
105                "      },\n"
106                "      \"name\": {\n"
107                "        \"value\": 2\n"
108                "      }\n"
109                "    ]\n"
110                "  }\n"
111                "}");
112   verifyFormat(R"({
113   "firstName": "John",
114   "lastName": "Smith",
115   "isAlive": true,
116   "age": 27,
117   "address": {
118     "streetAddress": "21 2nd Street",
119     "city": "New York",
120     "state": "NY",
121     "postalCode": "10021-3100"
122   },
123   "phoneNumbers": [
124     {
125       "type": "home",
126       "number": "212 555-1234"
127     },
128     {
129       "type": "office",
130       "number": "646 555-4567"
131     }
132   ],
133   "children": [],
134   "spouse": null
135 })");
136 }
137 
138 TEST_F(FormatTestJson, JsonArray) {
139   verifyFormat("[]");
140   verifyFormat("[\n"
141                "  1\n"
142                "]");
143   verifyFormat("[\n"
144                "  1,\n"
145                "  2\n"
146                "]");
147   verifyFormat("[\n"
148                "  {},\n"
149                "  {}\n"
150                "]");
151   verifyFormat("[\n"
152                "  {\n"
153                "    \"name\": 1\n"
154                "  },\n"
155                "  {}\n"
156                "]");
157 }
158 
159 TEST_F(FormatTestJson, JsonNoStringSplit) {
160   FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
161   Style.IndentWidth = 4;
162   verifyFormat(
163       "[\n"
164       "    {\n"
165       "        "
166       "\"naaaaaaaa\": \"foooooooooooooooooooooo oooooooooooooooooooooo\"\n"
167       "    },\n"
168       "    {}\n"
169       "]",
170       Style);
171   verifyFormat("[\n"
172                "    {\n"
173                "        "
174                "\"naaaaaaaa\": "
175                "\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
176                "oooooooooooooooooooooooooo\"\n"
177                "    },\n"
178                "    {}\n"
179                "]",
180                Style);
181 
182   Style.ColumnLimit = 80;
183   verifyFormat("[\n"
184                "    {\n"
185                "        "
186                "\"naaaaaaaa\":\n"
187                "            "
188                "\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
189                "oooooooooooooooooooooooooo\"\n"
190                "    },\n"
191                "    {}\n"
192                "]",
193                Style);
194 }
195 
196 } // namespace format
197 } // end namespace clang
198