| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/autofill/core/common/autofill_util.h" | 5 #include "components/autofill/core/common/autofill_util.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "components/autofill/core/common/autofill_switches.h" | 12 #include "components/autofill/core/common/autofill_switches.h" |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 | 14 |
| 15 namespace autofill { | 15 namespace autofill { |
| 16 | 16 |
| 17 // Tests for FieldIsSuggestionSubstringStartingOnTokenBoundary(). | 17 // Tests for FieldIsSuggestionSubstringStartingOnTokenBoundary(). |
| 18 TEST(AutofillUtilTest, FieldIsSuggestionSubstringStartingOnTokenBoundary) { | 18 struct FieldIsTokenBoundarySubstringCase { |
| 19 const char* const field_suggestion; |
| 20 const char* const field_contents; |
| 21 const bool case_sensitive; |
| 22 const bool expected_result; |
| 23 }; |
| 24 |
| 25 class FieldIsTokenBoundarySubstringCaseTest |
| 26 : public testing::TestWithParam<FieldIsTokenBoundarySubstringCase> {}; |
| 27 |
| 28 TEST_P(FieldIsTokenBoundarySubstringCaseTest, |
| 29 FieldIsSuggestionSubstringStartingOnTokenBoundary) { |
| 19 // FieldIsSuggestionSubstringStartingOnTokenBoundary should not work yet | 30 // FieldIsSuggestionSubstringStartingOnTokenBoundary should not work yet |
| 20 // without a flag. | 31 // without a flag. |
| 21 EXPECT_FALSE(FieldIsSuggestionSubstringStartingOnTokenBoundary( | 32 EXPECT_FALSE(FieldIsSuggestionSubstringStartingOnTokenBoundary( |
| 22 base::ASCIIToUTF16("ab@cd.b"), base::ASCIIToUTF16("b"), false)); | 33 base::ASCIIToUTF16("ab@cd.b"), base::ASCIIToUTF16("b"), false)); |
| 23 | 34 |
| 24 // Token matching is currently behind a flag. | 35 // Token matching is currently behind a flag. |
| 25 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 36 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 26 switches::kEnableSuggestionsWithSubstringMatch); | 37 switches::kEnableSuggestionsWithSubstringMatch); |
| 27 | 38 |
| 28 const struct { | 39 auto test_case = GetParam(); |
| 29 const char* const field_suggestion; | 40 SCOPED_TRACE(testing::Message() |
| 30 const char* const field_contents; | 41 << "suggestion = " << test_case.field_suggestion |
| 31 bool case_sensitive; | 42 << ", contents = " << test_case.field_contents |
| 32 bool expected_result; | 43 << ", case_sensitive = " << test_case.case_sensitive); |
| 33 } kTestCases[] = { | |
| 34 {"ab@cd.b", "a", false, true}, | |
| 35 {"ab@cd.b", "b", false, true}, | |
| 36 {"ab@cd.b", "Ab", false, true}, | |
| 37 {"ab@cd.b", "Ab", true, false}, | |
| 38 {"ab@cd.b", "cd", true, true}, | |
| 39 {"ab@cd.b", "d", false, false}, | |
| 40 {"ab@cd.b", "b@", true, false}, | |
| 41 {"ab@cd.b", "ab", false, true}, | |
| 42 {"ab@cd.b", "cd.b", true, true}, | |
| 43 {"ab@cd.b", "b@cd", false, false}, | |
| 44 {"ab@cd.b", "ab@c", false, true}, | |
| 45 {"ba.a.ab", "a.a", false, true}, | |
| 46 {"", "ab", false, false}, | |
| 47 {"", "ab", true, false}, | |
| 48 {"ab", "", false, true}, | |
| 49 {"ab", "", true, true}, | |
| 50 }; | |
| 51 | 44 |
| 52 for (const auto& test_case : kTestCases) { | 45 EXPECT_EQ(test_case.expected_result, |
| 53 SCOPED_TRACE(testing::Message() | 46 FieldIsSuggestionSubstringStartingOnTokenBoundary( |
| 54 << "suggestion = " << test_case.field_suggestion | 47 base::ASCIIToUTF16(test_case.field_suggestion), |
| 55 << ", contents = " << test_case.field_contents | 48 base::ASCIIToUTF16(test_case.field_contents), |
| 56 << ", case_sensitive = " << test_case.case_sensitive); | 49 test_case.case_sensitive)); |
| 57 | |
| 58 EXPECT_EQ(test_case.expected_result, | |
| 59 FieldIsSuggestionSubstringStartingOnTokenBoundary( | |
| 60 base::ASCIIToUTF16(test_case.field_suggestion), | |
| 61 base::ASCIIToUTF16(test_case.field_contents), | |
| 62 test_case.case_sensitive)); | |
| 63 } | |
| 64 } | 50 } |
| 65 | 51 |
| 52 INSTANTIATE_TEST_CASE_P( |
| 53 AutofillUtilTest, |
| 54 FieldIsTokenBoundarySubstringCaseTest, |
| 55 testing::Values( |
| 56 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "a", false, true}, |
| 57 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "b", false, true}, |
| 58 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "Ab", false, true}, |
| 59 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "Ab", true, false}, |
| 60 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "cd", true, true}, |
| 61 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "d", false, false}, |
| 62 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "b@", true, false}, |
| 63 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "ab", false, true}, |
| 64 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "cd.b", true, true}, |
| 65 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "b@cd", false, false}, |
| 66 FieldIsTokenBoundarySubstringCase{"ab@cd.b", "ab@c", false, true}, |
| 67 FieldIsTokenBoundarySubstringCase{"ba.a.ab", "a.a", false, true}, |
| 68 FieldIsTokenBoundarySubstringCase{"", "ab", false, false}, |
| 69 FieldIsTokenBoundarySubstringCase{"", "ab", true, false}, |
| 70 FieldIsTokenBoundarySubstringCase{"ab", "", false, true}, |
| 71 FieldIsTokenBoundarySubstringCase{"ab", "", true, true})); |
| 72 |
| 66 // Tests for GetTextSelectionStart(). | 73 // Tests for GetTextSelectionStart(). |
| 67 TEST(AutofillUtilTest, GetTextSelectionStart) { | 74 struct GetTextSelectionStartCase { |
| 68 const size_t kInvalid = base::string16::npos; | 75 const char* const field_suggestion; |
| 69 const struct { | 76 const char* const field_contents; |
| 70 const char* const field_suggestion; | 77 const bool case_sensitive; |
| 71 const char* const field_contents; | 78 const size_t expected_start; |
| 72 bool case_sensitive; | 79 }; |
| 73 size_t expected_start; | |
| 74 } kTestCases[] = { | |
| 75 {"ab@cd.b", "a", false, 1}, | |
| 76 {"ab@cd.b", "A", true, kInvalid}, | |
| 77 {"ab@cd.b", "Ab", false, 2}, | |
| 78 {"ab@cd.b", "Ab", true, kInvalid}, | |
| 79 {"ab@cd.b", "cd", false, 5}, | |
| 80 {"ab@cd.b", "ab@c", false, 4}, | |
| 81 {"ab@cd.b", "cd.b", false, 7}, | |
| 82 {"ab@cd.b", "b@cd", false, kInvalid}, | |
| 83 {"ab@cd.b", "b", false, 7}, | |
| 84 {"ba.a.ab", "a.a", false, 6}, | |
| 85 {"texample@example.com", "example", false, 16}, | |
| 86 }; | |
| 87 | 80 |
| 88 for (const auto& test_case : kTestCases) { | 81 class GetTextSelectionStartTest |
| 89 SCOPED_TRACE(testing::Message() | 82 : public testing::TestWithParam<GetTextSelectionStartCase> {}; |
| 90 << "suggestion = " << test_case.field_suggestion | |
| 91 << ", contents = " << test_case.field_contents | |
| 92 << ", case_sensitive = " << test_case.case_sensitive); | |
| 93 | 83 |
| 94 EXPECT_EQ( | 84 TEST_P(GetTextSelectionStartTest, GetTextSelectionStart) { |
| 95 test_case.expected_start, | 85 auto test_case = GetParam(); |
| 96 GetTextSelectionStart(base::ASCIIToUTF16(test_case.field_suggestion), | 86 SCOPED_TRACE(testing::Message() |
| 97 base::ASCIIToUTF16(test_case.field_contents), | 87 << "suggestion = " << test_case.field_suggestion |
| 98 test_case.case_sensitive)); | 88 << ", contents = " << test_case.field_contents |
| 99 } | 89 << ", case_sensitive = " << test_case.case_sensitive); |
| 90 EXPECT_EQ( |
| 91 test_case.expected_start, |
| 92 GetTextSelectionStart(base::ASCIIToUTF16(test_case.field_suggestion), |
| 93 base::ASCIIToUTF16(test_case.field_contents), |
| 94 test_case.case_sensitive)); |
| 100 } | 95 } |
| 101 | 96 |
| 97 INSTANTIATE_TEST_CASE_P( |
| 98 AutofillUtilTest, |
| 99 GetTextSelectionStartTest, |
| 100 testing::Values( |
| 101 GetTextSelectionStartCase{"ab@cd.b", "a", false, 1}, |
| 102 GetTextSelectionStartCase{"ab@cd.b", "A", true, base::string16::npos}, |
| 103 GetTextSelectionStartCase{"ab@cd.b", "Ab", false, 2}, |
| 104 GetTextSelectionStartCase{"ab@cd.b", "Ab", true, base::string16::npos}, |
| 105 GetTextSelectionStartCase{"ab@cd.b", "cd", false, 5}, |
| 106 GetTextSelectionStartCase{"ab@cd.b", "ab@c", false, 4}, |
| 107 GetTextSelectionStartCase{"ab@cd.b", "cd.b", false, 7}, |
| 108 GetTextSelectionStartCase{"ab@cd.b", "b@cd", false, |
| 109 base::string16::npos}, |
| 110 GetTextSelectionStartCase{"ab@cd.b", "b", false, 7}, |
| 111 GetTextSelectionStartCase{"ba.a.ab", "a.a", false, 6}, |
| 112 GetTextSelectionStartCase{"texample@example.com", "example", false, |
| 113 16})); |
| 114 |
| 102 // Tests for LowercaseAndTokenizeAttributeString | 115 // Tests for LowercaseAndTokenizeAttributeString |
| 103 TEST(AutofillUtilTest, LowercaseAndTokenizeAttributeString) { | 116 struct LowercaseAndTokenizeAttributeStringCase { |
| 104 const struct { | 117 const char* const attribute; |
| 105 const char* const attribute; | 118 std::vector<std::string> tokens; |
| 106 std::vector<std::string> tokens; | 119 }; |
| 107 } kTestCases[] = { | |
| 108 // Test leading and trailing whitespace, test tabs and newlines | |
| 109 {"foo bar baz", {"foo", "bar", "baz"}}, | |
| 110 {" foo bar baz ", {"foo", "bar", "baz"}}, | |
| 111 {"foo\tbar baz ", {"foo", "bar", "baz"}}, | |
| 112 {"foo\nbar baz ", {"foo", "bar", "baz"}}, | |
| 113 | 120 |
| 114 // Test different forms of capitalization | 121 class LowercaseAndTokenizeAttributeStringTest |
| 115 {"FOO BAR BAZ", {"foo", "bar", "baz"}}, | 122 : public testing::TestWithParam<LowercaseAndTokenizeAttributeStringCase> {}; |
| 116 {"foO baR bAz", {"foo", "bar", "baz"}}, | |
| 117 | 123 |
| 118 // Test collapsing of multiple whitespace characters in a row | 124 TEST_P(LowercaseAndTokenizeAttributeStringTest, |
| 119 {" \t\t\n\n ", std::vector<std::string>()}, | 125 LowercaseAndTokenizeAttributeStringTest) { |
| 120 {"foO baR bAz", {"foo", "bar", "baz"}}, | 126 auto test_case = GetParam(); |
| 121 }; | 127 SCOPED_TRACE(testing::Message() << "attribute = " << test_case.attribute); |
| 122 | 128 |
| 123 for (const auto& test_case : kTestCases) { | 129 EXPECT_EQ(test_case.tokens, |
| 124 SCOPED_TRACE(testing::Message() << "attribute = " << test_case.attribute); | 130 LowercaseAndTokenizeAttributeString(test_case.attribute)); |
| 131 } |
| 125 | 132 |
| 126 EXPECT_EQ(test_case.tokens, | 133 INSTANTIATE_TEST_CASE_P( |
| 127 LowercaseAndTokenizeAttributeString(test_case.attribute)); | 134 AutofillUtilTest, |
| 128 } | 135 LowercaseAndTokenizeAttributeStringTest, |
| 129 } | 136 testing::Values( |
| 137 // Test leading and trailing whitespace, test tabs and newlines |
| 138 LowercaseAndTokenizeAttributeStringCase{"foo bar baz", |
| 139 {"foo", "bar", "baz"}}, |
| 140 LowercaseAndTokenizeAttributeStringCase{" foo bar baz ", |
| 141 {"foo", "bar", "baz"}}, |
| 142 LowercaseAndTokenizeAttributeStringCase{"foo\tbar baz ", |
| 143 {"foo", "bar", "baz"}}, |
| 144 LowercaseAndTokenizeAttributeStringCase{"foo\nbar baz ", |
| 145 {"foo", "bar", "baz"}}, |
| 146 |
| 147 // Test different forms of capitalization |
| 148 LowercaseAndTokenizeAttributeStringCase{"FOO BAR BAZ", |
| 149 {"foo", "bar", "baz"}}, |
| 150 LowercaseAndTokenizeAttributeStringCase{"foO baR bAz", |
| 151 {"foo", "bar", "baz"}}, |
| 152 |
| 153 // Test collapsing of multiple whitespace characters in a row |
| 154 LowercaseAndTokenizeAttributeStringCase{" \t\t\n\n ", |
| 155 std::vector<std::string>()}, |
| 156 LowercaseAndTokenizeAttributeStringCase{"foO baR bAz", |
| 157 {"foo", "bar", "baz"}})); |
| 158 |
| 130 } // namespace autofill | 159 } // namespace autofill |
| OLD | NEW |