Commit f1b689af authored by Mariia Shvedchenko's avatar Mariia Shvedchenko Committed by Commit Bot

[Autofill] Returns all patterns that match given language and fieldtype.

This CL provides new structure MatchingPattern that replace using
single regular expressions, but store more information about concret
pattern. Also it contains splitted MatchType into MactchFieldTypes
and MatchAttributes and sceleton of PatternProvider class.


Change-Id: I5acebf12aafaca67ae87260b2c897bdf35a38bea
Bug: 1121990
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2385282Reviewed-by: default avatarChristoph Schwering <schwering@google.com>
Reviewed-by: default avatarMatthias Körber <koerber@google.com>
Commit-Queue: Mariia Shvedchenko <mariiash@google.com>
Cr-Commit-Position: refs/heads/master@{#806125}
parent 6950e600
......@@ -123,6 +123,8 @@ static_library("browser") {
"form_data_importer.h",
"form_parsing/address_field.cc",
"form_parsing/address_field.h",
"form_parsing/autofill_parsing_utils.cc",
"form_parsing/autofill_parsing_utils.h",
"form_parsing/autofill_scanner.cc",
"form_parsing/autofill_scanner.h",
"form_parsing/credit_card_field.cc",
......@@ -181,6 +183,8 @@ static_library("browser") {
"metrics/form_event_logger_base.cc",
"metrics/form_event_logger_base.h",
"metrics/form_events.h",
"pattern_provider/pattern_provider.cc",
"pattern_provider/pattern_provider.h",
"payments/account_info_getter.h",
"payments/autofill_offer_manager.cc",
"payments/autofill_offer_manager.h",
......@@ -612,6 +616,7 @@ source_set("unit_tests") {
"logging/log_buffer_submitter_unittest.cc",
"logging/log_manager_unittest.cc",
"logging/log_router_unittest.cc",
"pattern_provider/pattern_provider_unittest.cc",
"payments/credit_card_access_manager_unittest.cc",
"payments/credit_card_cvc_authenticator_unittest.cc",
"payments/credit_card_save_manager_unittest.cc",
......
// Copyright 2020 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/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
namespace autofill {
MatchingPattern::MatchingPattern() = default;
MatchingPattern::MatchingPattern(const MatchingPattern& mp) = default;
MatchingPattern& MatchingPattern::operator=(const MatchingPattern& mp) =
default;
MatchingPattern::~MatchingPattern() = default;
autofill::MatchingPattern GetCompanyPatternEn() {
autofill::MatchingPattern m_p;
m_p.pattern_identifier = "kCompanyPatternEn";
m_p.positive_pattern = "company|business|organization|organisation";
m_p.positive_score = 1.1f;
m_p.negative_pattern = "";
m_p.match_field_attributes = autofill::MATCH_NAME;
m_p.match_field_input_types = autofill::MATCH_TEXT;
m_p.language = "en";
return m_p;
}
autofill::MatchingPattern GetCompanyPatternDe() {
autofill::MatchingPattern m_p;
m_p.pattern_identifier = "kCompanyPatternDe";
m_p.positive_pattern = "|(?<!con)firma|firmenname";
m_p.positive_score = 1.1f;
m_p.negative_pattern = "";
m_p.match_field_attributes = autofill::MATCH_LABEL | autofill::MATCH_NAME;
m_p.match_field_input_types = autofill::MATCH_TEXT;
m_p.language = "de";
return m_p;
}
} // namespace autofill
\ No newline at end of file
// Copyright 2020 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.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_AUTOFILL_PARSING_UTILS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_FORM_PARSING_AUTOFILL_PARSING_UTILS_H_
#include <string>
namespace autofill {
// A bit-field used for matching specific parts of a field in question.
// Attributes.
enum MatchAttributes {
MATCH_LABEL = 1 << 0,
MATCH_NAME = 1 << 1,
MATCH_ATTRIBUTES_DEFAULT = MATCH_LABEL | MATCH_NAME,
};
// A bit-field used for matching specific parts of a field in question.
// Input types.
enum MatchFieldTypes {
MATCH_TEXT = 1 << 2,
MATCH_EMAIL = 1 << 3,
MATCH_TELEPHONE = 1 << 4,
MATCH_SELECT = 1 << 5,
MATCH_TEXT_AREA = 1 << 6,
MATCH_PASSWORD = 1 << 7,
MATCH_NUMBER = 1 << 8,
MATCH_SEARCH = 1 << 9,
MATCH_ALL_INPUTS = MATCH_TEXT | MATCH_EMAIL | MATCH_TELEPHONE | MATCH_SELECT |
MATCH_TEXT_AREA | MATCH_PASSWORD | MATCH_NUMBER |
MATCH_SEARCH,
// By default match label and name for input/text types.
MATCH_INPUTS_DEFAULT = MATCH_TEXT,
};
constexpr int MATCH_DEFAULT = MATCH_ATTRIBUTES_DEFAULT | MATCH_INPUTS_DEFAULT;
// Structure for a better organization of data and regular expressions
// for autofill regex_constants. In the future, to implement faster
// changes without global updates also for having a quick possibility
// to recognize incorrect matches.
struct MatchingPattern {
MatchingPattern();
MatchingPattern(const MatchingPattern& mp);
MatchingPattern& operator=(const MatchingPattern& mp);
~MatchingPattern();
std::string pattern_identifier;
std::string positive_pattern;
float positive_score = 1.1f;
std::string negative_pattern;
int match_field_attributes;
int match_field_input_types;
std::string language;
};
// Use these functions instead of storing "non standats type" constants that
// bots might complaining over.
MatchingPattern GetCompanyPatternEn();
MatchingPattern GetCompanyPatternDe();
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_DATA_MODEL_AUTOFILL_PARSING_UTILS_H_
......@@ -159,10 +159,10 @@ bool FormField::ParseField(AutofillScanner* scanner,
return ParseFieldSpecifics(scanner, pattern, MATCH_DEFAULT, match, logging);
}
// static
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging) {
if (scanner->IsEnd())
......@@ -170,10 +170,25 @@ bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const AutofillField* field = scanner->Cursor();
if (!MatchesFormControlType(field->form_control_type, match_type))
if (!MatchesFormControlType(field->form_control_type,
match_field_input_types))
return false;
return MatchAndAdvance(scanner, pattern, match_type, match, logging);
return MatchAndAdvance(scanner, pattern, match_field_attributes,
match_field_input_types, match, logging);
}
// static
bool FormField::ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
AutofillField** match,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return ParseFieldSpecifics(scanner, pattern, match_field_attributes,
match_field_types, match, logging);
}
// static
......@@ -196,14 +211,15 @@ void FormField::AddClassification(const AutofillField* field,
candidates.AddFieldCandidate(type, score);
}
// static.
bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging) {
AutofillField* field = scanner->Cursor();
if (FormField::Match(field, pattern, match_type, logging)) {
if (FormField::Match(field, pattern, match_field_attributes,
match_field_input_types, logging)) {
if (match)
*match = field;
scanner->Advance();
......@@ -213,22 +229,35 @@ bool FormField::MatchAndAdvance(AutofillScanner* scanner,
return false;
}
// static
bool FormField::Match(const AutofillField* field,
// static.
bool FormField::MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_type,
AutofillField** match,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return MatchAndAdvance(scanner, pattern, match_field_attributes,
match_field_types, match, logging);
}
bool FormField::Match(const AutofillField* field,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
const RegExLogging& logging) {
bool found_match = false;
base::StringPiece match_type_string;
base::StringPiece16 value;
base::string16 match;
if ((match_type & FormField::MATCH_LABEL) &&
if ((match_field_attributes & MATCH_LABEL) &&
MatchesPattern(field->label, pattern, &match)) {
found_match = true;
match_type_string = "Match in label";
value = field->label;
} else if ((match_type & FormField::MATCH_NAME) &&
} else if ((match_field_attributes & MATCH_NAME) &&
MatchesPattern(field->parseable_name(), pattern, &match)) {
found_match = true;
match_type_string = "Match in name";
......@@ -251,6 +280,18 @@ bool FormField::Match(const AutofillField* field,
return found_match;
}
// static
bool FormField::Match(const AutofillField* field,
const base::string16& pattern,
int match_type,
const RegExLogging& logging) {
int match_field_attributes = match_type & 0b11;
int match_field_types = match_type & ~0b11;
return Match(field, pattern, match_field_attributes, match_field_types,
logging);
}
// static
void FormField::ParseFormFieldsPass(ParseFunction parse,
const std::vector<AutofillField*>& fields,
......
......@@ -12,6 +12,7 @@
#include "base/macros.h"
#include "base/strings/string16.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
#include "components/autofill/core/browser/form_parsing/field_candidates.h"
namespace autofill {
......@@ -45,29 +46,6 @@ class FormField {
LogManager* log_manager = nullptr);
protected:
// A bit-field used for matching specific parts of a field in question.
enum MatchType {
// Attributes.
MATCH_LABEL = 1 << 0,
MATCH_NAME = 1 << 1,
// Input types.
MATCH_TEXT = 1 << 2,
MATCH_EMAIL = 1 << 3,
MATCH_TELEPHONE = 1 << 4,
MATCH_SELECT = 1 << 5,
MATCH_TEXT_AREA = 1 << 6,
MATCH_PASSWORD = 1 << 7,
MATCH_NUMBER = 1 << 8,
MATCH_SEARCH = 1 << 9,
MATCH_ALL_INPUTS = MATCH_TEXT | MATCH_EMAIL | MATCH_TELEPHONE |
MATCH_SELECT | MATCH_TEXT_AREA | MATCH_PASSWORD |
MATCH_NUMBER | MATCH_SEARCH,
// By default match label and name for input/text types.
MATCH_DEFAULT = MATCH_LABEL | MATCH_NAME | MATCH_TEXT,
};
// Initial values assigned to FieldCandidates by their corresponding parsers.
static const float kBaseEmailParserScore;
static const float kBasePhoneParserScore;
......@@ -99,6 +77,15 @@ class FormField {
AutofillField** match,
const RegExLogging& logging = {});
// The same as ParseFieldSpecifics but with splitted match_types into
// MatchAttributes and MatchFieldTypes.
static bool ParseFieldSpecifics(AutofillScanner* scanner,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging = {});
// Attempts to parse a field with an empty label. Returns true
// on success and fills |match| with a pointer to the field.
static bool ParseEmptyLabel(AutofillScanner* scanner, AutofillField** match);
......@@ -139,13 +126,30 @@ class FormField {
AutofillField** match,
const RegExLogging& logging = {});
// Matches the regular expression |pattern| against the components of |field|
// as specified in the |match_type| bit field (see |MatchType|).
// The same as MatchAndAdvance but with splitted match_types into
// MatchAttributes and MatchFieldTypes.
static bool MatchAndAdvance(AutofillScanner* scanner,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
AutofillField** match,
const RegExLogging& logging = {});
// Matches the regular expression |pattern| against the components of
// |field| as specified in the |match_type| bit field (see |MatchType|).
static bool Match(const AutofillField* field,
const base::string16& pattern,
int match_type,
const RegExLogging& logging = {});
// The same as Match but with splitted match_types into MatchAttributes
// and MatchFieldTypes.
static bool Match(const AutofillField* field,
const base::string16& pattern,
int match_field_attributes,
int match_field_input_types,
const RegExLogging& logging = {});
// Perform a "pass" over the |fields| where each pass uses the supplied
// |parse| method to match content to a given field type.
// |fields| is both an input and an output parameter. Upon exit |fields|
......
......@@ -23,109 +23,91 @@ TEST(FormFieldTest, Match) {
AutofillField field;
// Empty strings match.
EXPECT_TRUE(
FormField::Match(&field, base::string16(), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, base::string16(), MATCH_LABEL));
// Empty pattern matches non-empty string.
field.label = ASCIIToUTF16("a");
EXPECT_TRUE(
FormField::Match(&field, base::string16(), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, base::string16(), MATCH_LABEL));
// Strictly empty pattern matches empty string.
field.label = base::string16();
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^$"), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^$"), MATCH_LABEL));
// Strictly empty pattern does not match non-empty string.
field.label = ASCIIToUTF16("a");
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^$"), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^$"), MATCH_LABEL));
// Non-empty pattern doesn't match empty string.
field.label = base::string16();
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("a"), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("a"), MATCH_LABEL));
// Beginning of line.
field.label = ASCIIToUTF16("head_tail");
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^head"), FormField::MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^tail"), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^head"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^tail"), MATCH_LABEL));
// End of line.
field.label = ASCIIToUTF16("head_tail");
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("head$"), FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("tail$"), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("head$"), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("tail$"), MATCH_LABEL));
// Exact.
field.label = ASCIIToUTF16("head_tail");
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^head$"), FormField::MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("^tail$"), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("^head_tail$"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^head$"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("^tail$"), MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("^head_tail$"), MATCH_LABEL));
// Escaped dots.
field.label = ASCIIToUTF16("m.i.");
// Note: This pattern is misleading as the "." characters are wild cards.
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("m.i."), FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m.i."), MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."), MATCH_LABEL));
field.label = ASCIIToUTF16("mXiX");
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("m.i."), FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("m.i."), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("m\\.i\\."), MATCH_LABEL));
// Repetition.
field.label = ASCIIToUTF16("headtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXXXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.*tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.*tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headtail");
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("head.+tail"),
FormField::MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.+tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
field.label = ASCIIToUTF16("headXXXtail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head.+tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head.+tail"), MATCH_LABEL));
// Alternation.
field.label = ASCIIToUTF16("head_tail");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head|other"),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("tail|other"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("bad|good"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("head|other"), MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("tail|other"), MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("bad|good"), MATCH_LABEL));
// Case sensitivity.
field.label = ASCIIToUTF16("xxxHeAd_tAiLxxx");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head_tail"),
FormField::MATCH_LABEL));
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("head_tail"), MATCH_LABEL));
// Word boundaries.
field.label = ASCIIToUTF16("contains word:");
EXPECT_TRUE(FormField::Match(&field, ASCIIToUTF16("\\bword\\b"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcon\\b"),
FormField::MATCH_LABEL));
EXPECT_TRUE(
FormField::Match(&field, ASCIIToUTF16("\\bword\\b"), MATCH_LABEL));
EXPECT_FALSE(
FormField::Match(&field, ASCIIToUTF16("\\bcon\\b"), MATCH_LABEL));
// Make sure the circumflex in 'crepe' is not treated as a word boundary.
field.label = base::UTF8ToUTF16("cr\xC3\xAApe");
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcr\\b"),
FormField::MATCH_LABEL));
EXPECT_FALSE(FormField::Match(&field, ASCIIToUTF16("\\bcr\\b"), MATCH_LABEL));
}
// Test that we ignore checkable elements.
......
// Copyright 2020 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/autofill/core/browser/pattern_provider/pattern_provider.h"
#include <algorithm>
#include <iostream>
#include <string>
#include "components/autofill/core/browser/autofill_type.h"
namespace autofill {
PatternProvider::PatternProvider(autofill::ServerFieldType type) {
autofill::MatchingPattern kCompanyPatternEn = autofill::GetCompanyPatternEn();
autofill::MatchingPattern kCompanyPatternDe = autofill::GetCompanyPatternDe();
patterns_[AutofillType(COMPANY_NAME).ToString()]["en"] = kCompanyPatternEn;
patterns_[AutofillType(COMPANY_NAME).ToString()]["de"] = kCompanyPatternDe;
}
PatternProvider::~PatternProvider() {
patterns_.clear();
}
autofill::MatchingPattern PatternProvider::GetSingleMatchPattern(
autofill::ServerFieldType type,
const std::string& page_language) {
base::StringPiece type_s = autofill::FieldTypeToStringPiece(type);
return patterns_[type_s.as_string()][page_language];
}
} // namespace autofill
// Copyright 2020 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.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
#include <string>
#include "base/macros.h"
#include "base/synchronization/lock.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/form_parsing/autofill_parsing_utils.h"
#include "components/autofill/core/common/autofill_regex_constants.h"
#include "third_party/re2/src/re2/re2.h"
namespace autofill {
class PatternProvider {
public:
PatternProvider();
PatternProvider(ServerFieldType type, const std::string& page_language);
explicit PatternProvider(ServerFieldType type);
~PatternProvider();
// Provides us with all patterns that can match our field type and page
// language.
const std::vector<MatchingPattern>& GetMatchPatterns(
ServerFieldType type,
const std::string& page_language);
const std::vector<MatchingPattern>& GetMatchPatterns(
const std::string& pattern_name,
const std::string& page_launguage);
// Provides us with all patterns that can match our field type.
const std::vector<MatchingPattern>& GetAllPatternsBaseOnType(
ServerFieldType type);
// Function that returns pattern that match our field type and page language.
MatchingPattern GetSingleMatchPattern(ServerFieldType type,
const std::string& page_language);
private:
// Func to sort the incoming map by score.
void SortPatternsByScore(std::vector<MatchingPattern>& patterns);
// Local map to store patterns keyed by field type and page language.
std::map<std::string, std::map<std::string, MatchingPattern>> patterns_;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PATTERN_PROVIDER_PATTERN_PROVIDER_H_
\ No newline at end of file
// Copyright 2020 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/autofill/core/browser/pattern_provider/pattern_provider.h"
#include <stddef.h>
#include <map>
#include <string>
#include <vector>
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
bool operator==(const MatchingPattern& mp1, const MatchingPattern& mp2) {
return (mp1.language == mp2.language &&
mp1.match_field_attributes == mp2.match_field_attributes &&
mp1.match_field_input_types == mp2.match_field_input_types &&
mp1.negative_pattern == mp2.negative_pattern &&
mp1.pattern_identifier == mp2.pattern_identifier &&
mp1.positive_pattern == mp2.positive_pattern &&
mp1.positive_score == mp2.positive_score);
}
TEST(AutofillPatternProvider, Single_Match) {
MatchingPattern kCompanyPatternEn = GetCompanyPatternEn();
MatchingPattern kCompanyPatternDe = GetCompanyPatternDe();
PatternProvider pattern_provider(COMPANY_NAME);
EXPECT_EQ(pattern_provider.GetSingleMatchPattern(COMPANY_NAME, "en"),
kCompanyPatternEn);
EXPECT_EQ(pattern_provider.GetSingleMatchPattern(COMPANY_NAME, "de"),
kCompanyPatternDe);
}
} // namespace autofill
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment