| Index: components/password_manager/core/browser/import/csv_reader_unittest.cc
|
| diff --git a/components/password_manager/core/browser/import/csv_reader_unittest.cc b/components/password_manager/core/browser/import/csv_reader_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7e707c4d8b34c9baf52782d6d89ac45ab03d4147
|
| --- /dev/null
|
| +++ b/components/password_manager/core/browser/import/csv_reader_unittest.cc
|
| @@ -0,0 +1,253 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "components/password_manager/core/browser/import/csv_reader.h"
|
| +
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace password_manager {
|
| +
|
| +TEST(CSVReaderTest, EmptyCSV) {
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + EXPECT_TRUE(CSVReader::Read(std::string(), &column_names, &records));
|
| + EXPECT_EQ(0u, column_names.size());
|
| + EXPECT_EQ(0u, records.size());
|
| +}
|
| +
|
| +TEST(CSVReaderTest, SingleColumn) {
|
| + const char kTestCSVInput[] =
|
| + "foo\n"
|
| + "alpha\n"
|
| + "beta\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + EXPECT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("foo"));
|
| + ASSERT_EQ(2u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("foo", "alpha")));
|
| + EXPECT_THAT(records[1], testing::ElementsAre(
|
| + std::make_pair("foo", "beta")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, HeaderOnly) {
|
| + const char kTestCSVInput[] =
|
| + "foo,bar\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("foo", "bar"));
|
| + EXPECT_EQ(0u, records.size());
|
| +}
|
| +
|
| +TEST(CSVReaderTest, HeaderAndSimpleRecords) {
|
| + const char kTestCSVInput[] =
|
| + "foo,bar,baz\n"
|
| + "alpha,beta,gamma\n"
|
| + "delta,epsilon,zeta\n";
|
| +
|
| + // We also initialize output arguments here to be non-empty so as to verify
|
| + // that they get overwritten.
|
| + std::vector<std::string> column_names(3);
|
| + std::vector<CSVReader::ColumnNameToValueMap> records(4);
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("foo", "bar", "baz"));
|
| + ASSERT_EQ(2u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("bar", "beta"),
|
| + std::make_pair("baz", "gamma"),
|
| + std::make_pair("foo", "alpha")));
|
| + EXPECT_THAT(records[1], testing::ElementsAre(
|
| + std::make_pair("bar", "epsilon"),
|
| + std::make_pair("baz", "zeta"),
|
| + std::make_pair("foo", "delta")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, ExtraSpacesArePreserved) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + " alpha beta , \n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(1u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", " alpha beta "),
|
| + std::make_pair("right", " ")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, CharactersOutsideASCIIPrintableArePreservedAsIs) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + "\x07\t\x0B\x1F,\u0024\u00A2\u20AC\U00024B62\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(1u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + // Characters below 0x20: bell, horizontal + vertical tab, unit separator.
|
| + std::make_pair("left", "\x07\t\x0B\x1F"),
|
| + // Unicode code points having 1..4 byte UTF-8 representation: dollar sign,
|
| + // cent sign, euro sign, CJK unified ideograph for [ce`i] in Han script.
|
| + std::make_pair("right", "\u0024\u00A2\u20AC\U00024B62")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, EnclosingDoubleQuotesAreTrimmed) {
|
| + const char kTestCSVInput[] =
|
| + "\"left\",\"right\"\n"
|
| + "\"alpha\",\"beta\"\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(1u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", "alpha"),
|
| + std::make_pair("right", "beta")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, SeparatorsInsideDoubleQuotesAreTreatedVerbatim) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + "\"A\rB\",\"B\nC\"\n"
|
| + "\"C\r\nD\",\"D\n\"\n"
|
| + "\",\",\",,\"\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(3u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", "A\rB"),
|
| + std::make_pair("right", "B\nC")));
|
| + EXPECT_THAT(records[1], testing::ElementsAre(
|
| + std::make_pair("left", "C\nD"),
|
| + std::make_pair("right", "D\n")));
|
| + EXPECT_THAT(records[2], testing::ElementsAre(
|
| + std::make_pair("left", ","),
|
| + std::make_pair("right", ",,")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, EscapedDoubleQuotes) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + "\"\",\"\"\"\"\"\"\n"
|
| + "\"\"\"\",\"A\"\"B\"\"\"\"C\"\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(2u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", ""),
|
| + std::make_pair("right", "\"\"")));
|
| + EXPECT_THAT(records[1], testing::ElementsAre(
|
| + std::make_pair("left", "\""),
|
| + std::make_pair("right", "A\"B\"\"C")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, InconsistentFieldsCountIsTreatedGracefully) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + "A\n"
|
| + "B,C,D\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(2u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", "A"),
|
| + std::make_pair("right", "")));
|
| + EXPECT_THAT(records[1], testing::ElementsAre(
|
| + std::make_pair("left", "B"),
|
| + std::make_pair("right", "C")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, SupportMissingNewLineAtEOF) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + "alpha,beta";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(1u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", "alpha"),
|
| + std::make_pair("right", "beta")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, EmptyFields) {
|
| + const char kTestCSVInput[] =
|
| + "left,middle,right\n"
|
| + "alpha,beta,\n"
|
| + ",,gamma\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "middle", "right"));
|
| + ASSERT_EQ(2u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", "alpha"),
|
| + std::make_pair("middle", "beta"),
|
| + std::make_pair("right", "")));
|
| + EXPECT_THAT(records[1], testing::ElementsAre(
|
| + std::make_pair("left", ""),
|
| + std::make_pair("middle", ""),
|
| + std::make_pair("right", "gamma")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, CRLFTreatedAsAndConvertedToLF) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\r\n"
|
| + "\"\r\",\"\r\n\"\r\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_TRUE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +
|
| + EXPECT_THAT(column_names, testing::ElementsAre("left", "right"));
|
| + ASSERT_EQ(1u, records.size());
|
| + EXPECT_THAT(records[0], testing::ElementsAre(
|
| + std::make_pair("left", "\r"),
|
| + std::make_pair("right", "\n")));
|
| +}
|
| +
|
| +TEST(CSVReaderTest, FailureWhenEOFInsideQuotes) {
|
| + const char kTestCSVInput[] =
|
| + "left,right\n"
|
| + "\"alpha\",\"unmatched\n";
|
| +
|
| + std::vector<std::string> column_names;
|
| + std::vector<CSVReader::ColumnNameToValueMap> records;
|
| + ASSERT_FALSE(CSVReader::Read(kTestCSVInput, &column_names, &records));
|
| +}
|
| +
|
| +} // namespace password_manager
|
|
|