275 lines · cpp
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-exception6//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 16namespace clang {17namespace format {18 19class FormatTestJson : public testing::Test {20protected:21 static std::string format(StringRef Code, unsigned Offset, unsigned Length,22 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 variable29 // to trick JSON into being JavaScript30 if (Style.isJson() && !Style.DisableFormat) {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 auto ChangedCode = applyAllReplacements(Code, Replaces);37 if (!ChangedCode)38 llvm::errs() << "Bad Json varibale replacement\n";39 StringRef NewCode = *ChangedCode;40 41 std::vector<tooling::Range> Ranges(1, tooling::Range(0, NewCode.size()));42 Replaces = reformat(Style, NewCode, Ranges);43 auto Result = applyAllReplacements(NewCode, Replaces);44 EXPECT_TRUE(static_cast<bool>(Result));45 LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");46 return *Result;47 }48 49 static std::string50 format(StringRef Code,51 const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {52 return format(Code, 0, Code.size(), Style);53 }54 55 static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {56 FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);57 Style.ColumnLimit = ColumnLimit;58 return Style;59 }60 61 static void verifyFormatStable(StringRef Code, const FormatStyle &Style) {62 EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";63 }64 65 static void66 verifyFormat(StringRef Code,67 const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {68 verifyFormatStable(Code, Style);69 EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));70 }71};72 73TEST_F(FormatTestJson, JsonRecord) {74 verifyFormat("{}");75 verifyFormat("{\n"76 " \"name\": 1\n"77 "}");78 verifyFormat("{\n"79 " \"name\": \"Foo\"\n"80 "}");81 verifyFormat("{\n"82 " \"name\": {\n"83 " \"value\": 1\n"84 " }\n"85 "}");86 verifyFormat("{\n"87 " \"name\": {\n"88 " \"value\": 1\n"89 " },\n"90 " \"name\": {\n"91 " \"value\": 2\n"92 " }\n"93 "}");94 verifyFormat("{\n"95 " \"name\": {\n"96 " \"value\": [\n"97 " 1,\n"98 " 2,\n"99 " ]\n"100 " }\n"101 "}");102 verifyFormat("{\n"103 " \"name\": {\n"104 " \"value\": [\n"105 " \"name\": {\n"106 " \"value\": 1\n"107 " },\n"108 " \"name\": {\n"109 " \"value\": 2\n"110 " }\n"111 " ]\n"112 " }\n"113 "}");114 verifyFormat(R"({115 "firstName": "John",116 "lastName": "Smith",117 "isAlive": true,118 "age": 27,119 "address": {120 "streetAddress": "21 2nd Street",121 "city": "New York",122 "state": "NY",123 "postalCode": "10021-3100"124 },125 "phoneNumbers": [126 {127 "type": "home",128 "number": "212 555-1234"129 },130 {131 "type": "office",132 "number": "646 555-4567"133 }134 ],135 "children": [],136 "spouse": null137})");138}139 140TEST_F(FormatTestJson, JsonArray) {141 verifyFormat("[]");142 verifyFormat("[\n"143 " 1\n"144 "]");145 verifyFormat("[\n"146 " 1,\n"147 " 2\n"148 "]");149 verifyFormat("[\n"150 " {},\n"151 " {}\n"152 "]");153 verifyFormat("[\n"154 " {\n"155 " \"name\": 1\n"156 " },\n"157 " {}\n"158 "]");159}160 161TEST_F(FormatTestJson, JsonArrayOneLine) {162 FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);163 Style.BreakArrays = false;164 Style.SpacesInContainerLiterals = false;165 verifyFormat("[]", Style);166 verifyFormat("[1]", Style);167 verifyFormat("[1, 2]", Style);168 verifyFormat("[1, 2, 3]", Style);169 verifyFormat("[1, 2, 3, 4]", Style);170 verifyFormat("[1, 2, 3, 4, 5]", Style);171 172 verifyFormat("[\n"173 " 1,\n"174 " 2,\n"175 " {\n"176 " A: 1\n"177 " }\n"178 "]",179 Style);180}181 182TEST_F(FormatTestJson, JsonNoStringSplit) {183 FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);184 Style.IndentWidth = 4;185 verifyFormat(186 "[\n"187 " {\n"188 " "189 "\"naaaaaaaa\": \"foooooooooooooooooooooo oooooooooooooooooooooo\"\n"190 " },\n"191 " {}\n"192 "]",193 Style);194 verifyFormat("[\n"195 " {\n"196 " "197 "\"naaaaaaaa\": "198 "\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"199 "oooooooooooooooooooooooooo\"\n"200 " },\n"201 " {}\n"202 "]",203 Style);204 205 Style.ColumnLimit = 80;206 verifyFormat("[\n"207 " {\n"208 " "209 "\"naaaaaaaa\":\n"210 " "211 "\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"212 "oooooooooooooooooooooooooo\"\n"213 " },\n"214 " {}\n"215 "]",216 Style);217}218 219TEST_F(FormatTestJson, DisableJsonFormat) {220 FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);221 verifyFormatStable("{}", Style);222 verifyFormatStable("{\n"223 " \"name\": 1\n"224 "}",225 Style);226 227 // Since we have to disable formatting to run this test, we shall refrain from228 // calling test::messUp lest we change the unformatted code and cannot format229 // it back to how it started.230 Style.DisableFormat = true;231 verifyFormatStable("{}", Style);232 verifyFormatStable("{\n"233 " \"name\": 1\n"234 "}",235 Style);236}237 238TEST_F(FormatTestJson, SpaceBeforeJsonColon) {239 FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);240 verifyFormatStable("{\n"241 " \"name\": 1\n"242 "}",243 Style);244 245 Style.SpaceBeforeJsonColon = true;246 verifyFormatStable("{}", Style);247 verifyFormatStable("{\n"248 " \"name\" : 1\n"249 "}",250 Style);251}252 253TEST_F(FormatTestJson, StartsWithWhitespaces) {254 FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);255 EXPECT_EQ("{\n"256 " \"name\": 1\n"257 "}",258 format(" {\n"259 " \"name\": 1\n"260 "}",261 Style));262 263 // FIXME: The block below is over-indented.264 EXPECT_EQ(" {\n"265 " \"name\": 1\n"266 " }",267 format("\n{\n"268 " \"name\": 1\n"269 "}",270 Style));271}272 273} // namespace format274} // end namespace clang275