#include "FormatTestUtils.h"
#include "clang/Format/Format.h"
#include "llvm/Support/Debug.h"
#include "gtest/gtest.h"
#define DEBUG_TYPE "format-test-json"
namespace clang {
namespace format {
class FormatTestJson : public ::testing::Test {
protected:
static std::string format(llvm::StringRef Code, unsigned Offset,
unsigned Length, const FormatStyle &Style) {
LLVM_DEBUG(llvm::errs() << "---\n");
LLVM_DEBUG(llvm::errs() << Code << "\n\n");
tooling::Replacements Replaces;
if (Style.isJson() && !Style.DisableFormat) {
auto Err = Replaces.add(
tooling::Replacement(tooling::Replacement("", 0, 0, "x = ")));
if (Err)
llvm::errs() << "Bad Json variable insertion\n";
}
auto ChangedCode = applyAllReplacements(Code, Replaces);
if (!ChangedCode)
llvm::errs() << "Bad Json varibale replacement\n";
StringRef NewCode = *ChangedCode;
std::vector<tooling::Range> Ranges(1, tooling::Range(0, NewCode.size()));
Replaces = reformat(Style, NewCode, Ranges);
auto Result = applyAllReplacements(NewCode, Replaces);
EXPECT_TRUE(static_cast<bool>(Result));
LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
return *Result;
}
static std::string
format(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {
return format(Code, 0, Code.size(), Style);
}
static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
Style.ColumnLimit = ColumnLimit;
return Style;
}
static void verifyFormatStable(llvm::StringRef Code,
const FormatStyle &Style) {
EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
}
static void
verifyFormat(llvm::StringRef Code,
const FormatStyle &Style = getLLVMStyle(FormatStyle::LK_Json)) {
verifyFormatStable(Code, Style);
EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
}
};
TEST_F(FormatTestJson, JsonRecord) {
verifyFormat("{}");
verifyFormat("{\n"
" \"name\": 1\n"
"}");
verifyFormat("{\n"
" \"name\": \"Foo\"\n"
"}");
verifyFormat("{\n"
" \"name\": {\n"
" \"value\": 1\n"
" }\n"
"}");
verifyFormat("{\n"
" \"name\": {\n"
" \"value\": 1\n"
" },\n"
" \"name\": {\n"
" \"value\": 2\n"
" }\n"
"}");
verifyFormat("{\n"
" \"name\": {\n"
" \"value\": [\n"
" 1,\n"
" 2,\n"
" ]\n"
" }\n"
"}");
verifyFormat("{\n"
" \"name\": {\n"
" \"value\": [\n"
" \"name\": {\n"
" \"value\": 1\n"
" },\n"
" \"name\": {\n"
" \"value\": 2\n"
" }\n"
" ]\n"
" }\n"
"}");
verifyFormat(R"({
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 27,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
})");
}
TEST_F(FormatTestJson, JsonArray) {
verifyFormat("[]");
verifyFormat("[\n"
" 1\n"
"]");
verifyFormat("[\n"
" 1,\n"
" 2\n"
"]");
verifyFormat("[\n"
" {},\n"
" {}\n"
"]");
verifyFormat("[\n"
" {\n"
" \"name\": 1\n"
" },\n"
" {}\n"
"]");
}
TEST_F(FormatTestJson, JsonNoStringSplit) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
Style.IndentWidth = 4;
verifyFormat(
"[\n"
" {\n"
" "
"\"naaaaaaaa\": \"foooooooooooooooooooooo oooooooooooooooooooooo\"\n"
" },\n"
" {}\n"
"]",
Style);
verifyFormat("[\n"
" {\n"
" "
"\"naaaaaaaa\": "
"\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
"oooooooooooooooooooooooooo\"\n"
" },\n"
" {}\n"
"]",
Style);
Style.ColumnLimit = 80;
verifyFormat("[\n"
" {\n"
" "
"\"naaaaaaaa\":\n"
" "
"\"foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"
"oooooooooooooooooooooooooo\"\n"
" },\n"
" {}\n"
"]",
Style);
}
TEST_F(FormatTestJson, DisableJsonFormat) {
FormatStyle Style = getLLVMStyle(FormatStyle::LK_Json);
verifyFormatStable("{}", Style);
verifyFormatStable("{\n"
" \"name\": 1\n"
"}",
Style);
Style.DisableFormat = true;
verifyFormatStable("{}", Style);
verifyFormatStable("{\n"
" \"name\": 1\n"
"}",
Style);
}
} }