Use platform-appropriate newlines in JSON output.

BUG=15462
TEST=base_unittests, unit_tests, check newlines in bookmarks file
Review URL: http://codereview.chromium.org/147220

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19418 0039d316-1c4b-4281-b951-d872f2087c98
Esse commit está contido em:
mark@chromium.org
2009-06-26 21:17:24 +00:00
commit 006d1091cb
16 arquivos alterados com 188 adições e 49 exclusões
@@ -0,0 +1,3 @@
The next line is blank.
But this one isn't.
@@ -0,0 +1,3 @@
The next line is blank.
But this one isn't.
+1
Ver Arquivo
@@ -0,0 +1 @@
This file is the same.
+2
Ver Arquivo
@@ -0,0 +1,2 @@
The first line is the same.
The second line is different.
+2
Ver Arquivo
@@ -0,0 +1,2 @@
The first line is the same.
The second line is not.
+42 -3
Ver Arquivo
@@ -129,21 +129,60 @@ bool ContentsEqual(const FilePath& filename1, const FilePath& filename2) {
file1.read(buffer1, BUFFER_SIZE);
file2.read(buffer2, BUFFER_SIZE);
if ((file1.eof() && !file2.eof()) ||
(!file1.eof() && file2.eof()) ||
if ((file1.eof() != file2.eof()) ||
(file1.gcount() != file2.gcount()) ||
(memcmp(buffer1, buffer2, file1.gcount()))) {
file1.close();
file2.close();
return false;
}
} while (!file1.eof() && !file2.eof());
} while (!file1.eof() || !file2.eof());
file1.close();
file2.close();
return true;
}
bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2) {
std::ifstream file1(filename1.value().c_str(), std::ios::in);
std::ifstream file2(filename2.value().c_str(), std::ios::in);
// Even if both files aren't openable (and thus, in some sense, "equal"),
// any unusable file yields a result of "false".
if (!file1.is_open() || !file2.is_open())
return false;
do {
std::string line1, line2;
getline(file1, line1);
getline(file2, line2);
// Check for mismatched EOF states, or any error state.
if ((file1.eof() != file2.eof()) ||
file1.bad() || file2.bad()) {
return false;
}
// Trim all '\r' and '\n' characters from the end of the line.
std::string::size_type end1 = line1.find_last_not_of("\r\n");
if (end1 == std::string::npos)
line1.clear();
else if (end1 + 1 < line1.length())
line1.erase(end1 + 1);
std::string::size_type end2 = line2.find_last_not_of("\r\n");
if (end2 == std::string::npos)
line2.clear();
else if (end2 + 1 < line2.length())
line2.erase(end2 + 1);
if (line1 != line2)
return false;
} while (!file1.eof() || !file2.eof());
return true;
}
bool ReadFileToString(const FilePath& path, std::string* contents) {
FILE* file = OpenFile(path, "rb");
if (!file) {
+4
Ver Arquivo
@@ -212,6 +212,10 @@ bool ContentsEqual(const FilePath& filename1,
bool ContentsEqual(const std::wstring& filename1,
const std::wstring& filename2);
// Returns true if the contents of the two text files given are equal, false
// otherwise. This routine treats "\r\n" and "\n" as equivalent.
bool TextContentsEqual(const FilePath& filename1, const FilePath& filename2);
// Read the file at |path| into |contents|, returning true on success.
// Useful for unit tests.
bool ReadFileToString(const FilePath& path, std::string* contents);
+50
Ver Arquivo
@@ -629,6 +629,56 @@ TEST_F(ReadOnlyFileUtilTest, ContentsEqual) {
EXPECT_FALSE(file_util::ContentsEqual(binary_file, binary_file_diff));
}
TEST_F(ReadOnlyFileUtilTest, TextContentsEqual) {
FilePath data_dir;
ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &data_dir));
data_dir = data_dir.Append(FILE_PATH_LITERAL("base"))
.Append(FILE_PATH_LITERAL("data"))
.Append(FILE_PATH_LITERAL("file_util_unittest"));
ASSERT_TRUE(file_util::PathExists(data_dir));
FilePath original_file =
data_dir.Append(FILE_PATH_LITERAL("original.txt"));
FilePath same_file =
data_dir.Append(FILE_PATH_LITERAL("same.txt"));
FilePath crlf_file =
data_dir.Append(FILE_PATH_LITERAL("crlf.txt"));
FilePath shortened_file =
data_dir.Append(FILE_PATH_LITERAL("shortened.txt"));
FilePath different_file =
data_dir.Append(FILE_PATH_LITERAL("different.txt"));
FilePath different_first_file =
data_dir.Append(FILE_PATH_LITERAL("different_first.txt"));
FilePath different_last_file =
data_dir.Append(FILE_PATH_LITERAL("different_last.txt"));
FilePath first1_file =
data_dir.Append(FILE_PATH_LITERAL("first1.txt"));
FilePath first2_file =
data_dir.Append(FILE_PATH_LITERAL("first2.txt"));
FilePath empty1_file =
data_dir.Append(FILE_PATH_LITERAL("empty1.txt"));
FilePath empty2_file =
data_dir.Append(FILE_PATH_LITERAL("empty2.txt"));
FilePath blank_line_file =
data_dir.Append(FILE_PATH_LITERAL("blank_line.txt"));
FilePath blank_line_crlf_file =
data_dir.Append(FILE_PATH_LITERAL("blank_line_crlf.txt"));
EXPECT_TRUE(file_util::TextContentsEqual(original_file, same_file));
EXPECT_TRUE(file_util::TextContentsEqual(original_file, crlf_file));
EXPECT_FALSE(file_util::TextContentsEqual(original_file, shortened_file));
EXPECT_FALSE(file_util::TextContentsEqual(original_file, different_file));
EXPECT_FALSE(file_util::TextContentsEqual(original_file,
different_first_file));
EXPECT_FALSE(file_util::TextContentsEqual(original_file,
different_last_file));
EXPECT_FALSE(file_util::TextContentsEqual(first1_file, first2_file));
EXPECT_TRUE(file_util::TextContentsEqual(empty1_file, empty2_file));
EXPECT_FALSE(file_util::TextContentsEqual(original_file, empty1_file));
EXPECT_TRUE(file_util::TextContentsEqual(blank_line_file,
blank_line_crlf_file));
}
// We don't need equivalent functionality outside of Windows.
#if defined(OS_WIN)
TEST_F(FileUtilTest, ResolveShortcutTest) {
+20
Ver Arquivo
@@ -308,6 +308,26 @@ TEST(JSONReaderTest, Reading) {
root2.reset(JSONReader::Read(
"{\"number\":9.87654321, \"null\":null , \"\\x53\" : \"str\", }", true));
ASSERT_TRUE(root2.get());
EXPECT_TRUE(root->Equals(root2.get()));
// Test newline equivalence.
root2.reset(JSONReader::Read(
"{\n"
" \"number\":9.87654321,\n"
" \"null\":null,\n"
" \"\\x53\":\"str\",\n"
"}\n", true));
ASSERT_TRUE(root2.get());
EXPECT_TRUE(root->Equals(root2.get()));
root2.reset(JSONReader::Read(
"{\r\n"
" \"number\":9.87654321,\r\n"
" \"null\":null,\r\n"
" \"\\x53\":\"str\",\r\n"
"}\r\n", true));
ASSERT_TRUE(root2.get());
EXPECT_TRUE(root->Equals(root2.get()));
// Test nesting
+5 -1
Ver Arquivo
@@ -9,7 +9,11 @@
#include "base/values.h"
#include "base/string_escape.h"
const char kPrettyPrintLineEnding[] = "\r\n";
#if defined(OS_WIN)
static const char kPrettyPrintLineEnding[] = "\r\n";
#else
static const char kPrettyPrintLineEnding[] = "\n";
#endif
/* static */
void JSONWriter::Write(const Value* const node,
+15 -6
Ver Arquivo
@@ -43,7 +43,7 @@ TEST(JSONWriterTest, Writing) {
JSONWriter::Write(root, false, &output_js);
ASSERT_EQ("-0.8", output_js);
delete root;
// Writer unittests like empty list/dict nesting,
// list list nesting, etc.
DictionaryValue root_dict;
@@ -56,13 +56,22 @@ TEST(JSONWriterTest, Writing) {
list->Append(inner_list);
list->Append(Value::CreateBooleanValue(true));
// Test the pretty-printer.
JSONWriter::Write(&root_dict, false, &output_js);
ASSERT_EQ("{\"list\":[{\"inner int\":10},[],true]}", output_js);
JSONWriter::Write(&root_dict, true, &output_js);
ASSERT_EQ("{\r\n"
" \"list\": [ {\r\n"
" \"inner int\": 10\r\n"
" }, [ ], true ]\r\n"
"}\r\n",
// The pretty-printer uses a different newline style on Windows than on
// other platforms.
#if defined(OS_WIN)
#define JSON_NEWLINE "\r\n"
#else
#define JSON_NEWLINE "\n"
#endif
ASSERT_EQ("{" JSON_NEWLINE
" \"list\": [ {" JSON_NEWLINE
" \"inner int\": 10" JSON_NEWLINE
" }, [ ], true ]" JSON_NEWLINE
"}" JSON_NEWLINE,
output_js);
#undef JSON_NEWLINE
}
+4 -2
Ver Arquivo
@@ -293,7 +293,8 @@ TEST_F(JSONFileValueSerializerTest, Roundtrip) {
ASSERT_TRUE(file_util::PathExists(written_file_path));
// Now compare file contents.
EXPECT_TRUE(file_util::ContentsEqual(original_file_path, written_file_path));
EXPECT_TRUE(file_util::TextContentsEqual(original_file_path,
written_file_path));
EXPECT_TRUE(file_util::Delete(written_file_path, false));
}
@@ -321,7 +322,8 @@ TEST_F(JSONFileValueSerializerTest, RoundtripNested) {
ASSERT_TRUE(file_util::PathExists(written_file_path));
// Now compare file contents.
EXPECT_TRUE(file_util::ContentsEqual(original_file_path, written_file_path));
EXPECT_TRUE(file_util::TextContentsEqual(original_file_path,
written_file_path));
EXPECT_TRUE(file_util::Delete(written_file_path, false));
}
+1 -1
Ver Arquivo
@@ -145,7 +145,7 @@ TEST_F(PrefServiceTest, Basic) {
FilePath golden_output_file = data_dir_.AppendASCII("write.golden.json");
ASSERT_TRUE(file_util::PathExists(golden_output_file));
ASSERT_TRUE(prefs.SavePersistentPrefs());
EXPECT_TRUE(file_util::ContentsEqual(golden_output_file, output_file));
EXPECT_TRUE(file_util::TextContentsEqual(golden_output_file, output_file));
ASSERT_TRUE(file_util::Delete(output_file, false));
}
+11 -11
Ver Arquivo
@@ -1,11 +1,11 @@
{
"homepage": "http://www.cnn.com",
"long_int": {
"pref": "214748364842"
},
"some_directory": "/usr/sbin/",
"tabs": {
"max_tabs": 10,
"new_windows_in_tabs": false
}
}
{
"homepage": "http://www.cnn.com",
"long_int": {
"pref": "214748364842"
},
"some_directory": "/usr/sbin/",
"tabs": {
"max_tabs": 10,
"new_windows_in_tabs": false
}
}
+17 -17
Ver Arquivo
@@ -1,17 +1,17 @@
{
"bool": true,
"dict": {
"bool": true,
"dict": {
"bees": "knees",
"cats": "meow"
},
"foos": "bar",
"list": [ 3.4, "second", null ]
},
"int": 42,
"list": [ 1, 2 ],
"null": null,
"real": 3.14,
"string": "hello"
}
{
"bool": true,
"dict": {
"bool": true,
"dict": {
"bees": "knees",
"cats": "meow"
},
"foos": "bar",
"list": [ 3.4, "second", null ]
},
"int": 42,
"list": [ 1, 2 ],
"null": null,
"real": 3.14,
"string": "hello"
}
+8 -8
Ver Arquivo
@@ -1,8 +1,8 @@
{
"bool": true,
"int": 42,
"list": [ 1, 2 ],
"null": null,
"real": 3.14,
"string": "hello"
}
{
"bool": true,
"int": 42,
"list": [ 1, 2 ],
"null": null,
"real": 3.14,
"string": "hello"
}