Skip to content

Commit

Permalink
[Autofill] Simplify Suggestions matchers
Browse files Browse the repository at this point in the history
This CL replaces a matcher class and its use-cases with compositions
of standard matchers. It continues what started as a by-product in
crrev.com/c/4506405.

Bug: 1007974
Change-Id: I736e51c85a43e0843fd3e581692b7cff56a16ace
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4571036
Reviewed-by: Mohamed Amir Yosef <mamir@chromium.org>
Commit-Queue: Christoph Schwering <schwering@google.com>
Cr-Commit-Position: refs/heads/main@{#1151793}
  • Loading branch information
schwering authored and Chromium LUCI CQ committed Jun 1, 2023
1 parent 0fb1dc2 commit 5619545
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -886,11 +886,6 @@ TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateFillFieldWithValue) {
TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIcon) {
IssueOnQuery();

auto element_icons = testing::ElementsAre(std::string(),
#if !BUILDFLAG(IS_ANDROID)
std::string(),
#endif
testing::StartsWith("googlePay"));
AutofillClient::PopupOpenArgs open_args;
EXPECT_CALL(autofill_client_, ShowAutofillPopup)
.WillOnce(testing::SaveArg<0>(&open_args));
Expand All @@ -904,11 +899,18 @@ TEST_F(AutofillExternalDelegateUnitTest, ShouldShowGooglePayIcon) {
field_id_, autofill_item, AutoselectFirstSuggestion(false), true);

// On Desktop, the GPay icon should be stored in the store indicator icon.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
EXPECT_THAT(open_args.suggestions, SuggestionVectorIconsAre(element_icons));
#else
#if BUILDFLAG(IS_ANDROID)
EXPECT_THAT(open_args.suggestions,
SuggestionVectorStoreIndicatorIconsAre(element_icons));
SuggestionVectorIconsAre(std::string(),
testing::StartsWith("googlePay")));
#elif BUILDFLAG(IS_IOS)
EXPECT_THAT(open_args.suggestions,
SuggestionVectorIconsAre(std::string(), std::string(),
testing::StartsWith("googlePay")));
#else
EXPECT_THAT(open_args.suggestions, SuggestionVectorStoreIndicatorIconsAre(
std::string(), std::string(),
testing::StartsWith("googlePay")));
#endif
EXPECT_FALSE(open_args.autoselect_first_suggestion);
}
Expand All @@ -917,11 +919,6 @@ TEST_F(AutofillExternalDelegateUnitTest,
ShouldNotShowGooglePayIconIfSuggestionsContainLocalCards) {
IssueOnQuery();

auto element_icons = testing::ElementsAre(std::string(),
#if !BUILDFLAG(IS_ANDROID)
std::string(),
#endif
"settingsIcon");
AutofillClient::PopupOpenArgs open_args;
EXPECT_CALL(autofill_client_, ShowAutofillPopup)
.WillOnce(testing::SaveArg<0>(&open_args));
Expand All @@ -933,20 +930,17 @@ TEST_F(AutofillExternalDelegateUnitTest,
// This should call ShowAutofillPopup.
external_delegate_->OnSuggestionsReturned(
field_id_, autofill_item, AutoselectFirstSuggestion(false), false);
EXPECT_THAT(open_args.suggestions, SuggestionVectorIconsAre(element_icons));
EXPECT_THAT(open_args.suggestions, SuggestionVectorIconsAre(std::string(),
#if !BUILDFLAG(IS_ANDROID)
std::string(),
#endif
"settingsIcon"));
EXPECT_FALSE(open_args.autoselect_first_suggestion);
}

TEST_F(AutofillExternalDelegateUnitTest, ShouldUseNewSettingName) {
IssueOnQuery();

auto element_main_texts = testing::ElementsAre(
Suggestion::Text(std::u16string(), Suggestion::Text::IsPrimary(true)),
#if !BUILDFLAG(IS_ANDROID)
Suggestion::Text(std::u16string(), Suggestion::Text::IsPrimary(false)),
#endif
Suggestion::Text(l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE),
Suggestion::Text::IsPrimary(true)));
AutofillClient::PopupOpenArgs open_args;
EXPECT_CALL(autofill_client_, ShowAutofillPopup)
.WillOnce(testing::SaveArg<0>(&open_args));
Expand All @@ -959,8 +953,16 @@ TEST_F(AutofillExternalDelegateUnitTest, ShouldUseNewSettingName) {
// This should call ShowAutofillPopup.
external_delegate_->OnSuggestionsReturned(field_id_, autofill_item,
AutoselectFirstSuggestion(false));
EXPECT_THAT(open_args.suggestions,
SuggestionVectorMainTextsAre(element_main_texts));
EXPECT_THAT(
open_args.suggestions,
SuggestionVectorMainTextsAre(
Suggestion::Text(std::u16string(), Suggestion::Text::IsPrimary(true)),
#if !BUILDFLAG(IS_ANDROID)
Suggestion::Text(std::u16string(),
Suggestion::Text::IsPrimary(false)),
#endif
Suggestion::Text(l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE),
Suggestion::Text::IsPrimary(true))));
EXPECT_FALSE(open_args.autoselect_first_suggestion);
}

Expand Down Expand Up @@ -991,16 +993,6 @@ TEST_F(AutofillExternalDelegateCardsFromAccountTest,
ShouldShowCardsFromAccountOptionWithCards) {
IssueOnQuery();

auto element_main_texts = testing::ElementsAre(
Suggestion::Text(std::u16string(), Suggestion::Text::IsPrimary(true)),
Suggestion::Text(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS),
Suggestion::Text::IsPrimary(true)),
#if !BUILDFLAG(IS_ANDROID)
Suggestion::Text(std::u16string(), Suggestion::Text::IsPrimary(false)),
#endif
Suggestion::Text(l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE),
Suggestion::Text::IsPrimary(true)));
AutofillClient::PopupOpenArgs open_args;
EXPECT_CALL(autofill_client_, ShowAutofillPopup)
.WillOnce(testing::SaveArg<0>(&open_args));
Expand All @@ -1012,8 +1004,19 @@ TEST_F(AutofillExternalDelegateCardsFromAccountTest,

external_delegate_->OnSuggestionsReturned(field_id_, autofill_item,
AutoselectFirstSuggestion(false));
EXPECT_THAT(open_args.suggestions,
SuggestionVectorMainTextsAre(element_main_texts));
EXPECT_THAT(
open_args.suggestions,
SuggestionVectorMainTextsAre(
Suggestion::Text(std::u16string(), Suggestion::Text::IsPrimary(true)),
Suggestion::Text(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS),
Suggestion::Text::IsPrimary(true)),
#if !BUILDFLAG(IS_ANDROID)
Suggestion::Text(std::u16string(),
Suggestion::Text::IsPrimary(false)),
#endif
Suggestion::Text(l10n_util::GetStringUTF16(IDS_AUTOFILL_MANAGE),
Suggestion::Text::IsPrimary(true))));
EXPECT_FALSE(open_args.autoselect_first_suggestion);
}

Expand All @@ -1024,17 +1027,16 @@ TEST_F(AutofillExternalDelegateCardsFromAccountTest,
ShouldShowCardsFromAccountOptionWithoutCards) {
IssueOnQuery();

auto element_main_texts = testing::ElementsAre(Suggestion::Text(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS),
Suggestion::Text::IsPrimary(true)));
AutofillClient::PopupOpenArgs open_args;
EXPECT_CALL(autofill_client_, ShowAutofillPopup)
.WillOnce(testing::SaveArg<0>(&open_args));

external_delegate_->OnSuggestionsReturned(
field_id_, std::vector<Suggestion>(), AutoselectFirstSuggestion(false));
EXPECT_THAT(open_args.suggestions,
SuggestionVectorMainTextsAre(element_main_texts));
SuggestionVectorMainTextsAre(Suggestion::Text(
l10n_util::GetStringUTF16(IDS_AUTOFILL_SHOW_ACCOUNT_CARDS),
Suggestion::Text::IsPrimary(true))));
EXPECT_FALSE(open_args.autoselect_first_suggestion);
}

Expand Down
91 changes: 17 additions & 74 deletions components/autofill/core/browser/ui/suggestion_test_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,41 @@
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SUGGESTION_TEST_HELPERS_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_UI_SUGGESTION_TEST_HELPERS_H_

#include <string>

#include "components/autofill/core/browser/ui/suggestion.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace autofill {

// Gmock matcher that allows checking a member of the Suggestion class in a
// vector. This wraps a GMock container matcher, converts the suggestion
// members to a vector, and then runs the container matcher against the result
// to test an argument. See SuggestionVectorMainTextsAre() below.
template <typename EltType>
class SuggestionVectorMembersAreMatcher
: public testing::MatcherInterface<const std::vector<Suggestion>&> {
public:
typedef std::vector<EltType> Container;
typedef testing::Matcher<Container> ContainerMatcher;

SuggestionVectorMembersAreMatcher(const ContainerMatcher& seq_matcher,
EltType Suggestion::*elt)
: container_matcher_(seq_matcher), element_(elt) {}

bool MatchAndExplain(const std::vector<Suggestion>& suggestions,
testing::MatchResultListener* listener) const override {
Container container;
for (const auto& suggestion : suggestions)
container.push_back(suggestion.*element_);
return container_matcher_.MatchAndExplain(container, listener);
}

void DescribeTo(::std::ostream* os) const override {
container_matcher_.DescribeTo(os);
}

void DescribeNegationTo(::std::ostream* os) const override {
container_matcher_.DescribeNegationTo(os);
}

private:
ContainerMatcher container_matcher_;
EltType Suggestion::*element_;
};

// Use this matcher to compare a sequence vector's IDs to a list. In an
// EXPECT_CALL statement, use the following for an vector<Suggestion> argument
// to compare the IDs against a constant list:
// SuggestionVectorIdsAre(1, 2, 3, 4)
template <class... Matchers>
inline auto SuggestionVectorIdsAre(const Matchers&... matchers) {
return ::testing::ElementsAre(
::testing::Field("frontend_id", &Suggestion::frontend_id, matchers)...);
}

// Use this matcher to compare a sequence vector's main_texts to a list. In an
// EXPECT_CALL statement, use the following for an vector<Suggestion> argument
// to compare the IDs against a constant list:
// SuggestionVectorMainTextsAre(testing::ElementsAre(text1, text2, text3,
// text4))
template <class EltsAreMatcher>
inline testing::Matcher<const std::vector<Suggestion>&>
SuggestionVectorMainTextsAre(const EltsAreMatcher& elts_are_matcher) {
return testing::MakeMatcher(
new SuggestionVectorMembersAreMatcher<Suggestion::Text>(
elts_are_matcher, &Suggestion::main_text));
template <class... Matchers>
inline auto SuggestionVectorMainTextsAre(const Matchers&... matchers) {
return ::testing::ElementsAre(
::testing::Field("main_text", &Suggestion::main_text, matchers)...);
}

// Like SuggestionVectorMainTextsAre above, but tests the labels.
template <class EltsAreMatcher>
inline testing::Matcher<const std::vector<Suggestion>&>
SuggestionVectorLabelsAre(const EltsAreMatcher& elts_are_matcher) {
return testing::MakeMatcher(new SuggestionVectorMembersAreMatcher<
std::vector<std::vector<Suggestion::Text>>>(
elts_are_matcher, &Suggestion::labels));
template <class... Matchers>
inline auto SuggestionVectorLabelsContains(const Matchers&... matchers) {
return ::testing::Contains(
::testing::Field("labels", &Suggestion::labels, matchers)...);
}

// Like SuggestionVectorMainTextsAre above, but tests the icons.
template <class EltsAreMatcher>
inline testing::Matcher<const std::vector<Suggestion>&>
SuggestionVectorIconsAre(const EltsAreMatcher& elts_are_matcher) {
return testing::MakeMatcher(
new SuggestionVectorMembersAreMatcher<std::string>(elts_are_matcher,
&Suggestion::icon));
template <class... Matchers>
inline auto SuggestionVectorIconsAre(const Matchers&... matchers) {
return ::testing::ElementsAre(
::testing::Field("icon", &Suggestion::icon, matchers)...);
}

// Like SuggestionVectorMainTextsAre above, but tests the trailing_icon.
template <class EltsAreMatcher>
inline testing::Matcher<const std::vector<Suggestion>&>
SuggestionVectorStoreIndicatorIconsAre(const EltsAreMatcher& elts_are_matcher) {
return testing::MakeMatcher(
new SuggestionVectorMembersAreMatcher<std::string>(
elts_are_matcher, &Suggestion::trailing_icon));
template <class... Matchers>
inline auto SuggestionVectorStoreIndicatorIconsAre(
const Matchers&... matchers) {
return ::testing::ElementsAre(
::testing::Field("icon", &Suggestion::trailing_icon, matchers)...);
}

} // namespace autofill
Expand Down

0 comments on commit 5619545

Please sign in to comment.