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