1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_VIEWS_ANIMATION_TEST_TEST_INK_DROP_ANIMATION_OBSERVER_HELPER_H_
#define UI_VIEWS_ANIMATION_TEST_TEST_INK_DROP_ANIMATION_OBSERVER_HELPER_H_
#include <algorithm>
#include <vector>
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/views/animation/ink_drop_animation_ended_reason.h"
namespace views::test {
// Context tracking helper that can be used with test implementations of
// ink drop animation observers.
template <typename ContextType>
class TestInkDropAnimationObserverHelper {
public:
TestInkDropAnimationObserverHelper()
: last_animation_started_context_(),
last_animation_ended_context_() {}
TestInkDropAnimationObserverHelper(
const TestInkDropAnimationObserverHelper&) = delete;
TestInkDropAnimationObserverHelper& operator=(
const TestInkDropAnimationObserverHelper&) = delete;
virtual ~TestInkDropAnimationObserverHelper() = default;
int last_animation_started_ordinal() const {
return last_animation_started_ordinal_;
}
ContextType last_animation_started_context() const {
return last_animation_started_context_;
}
int last_animation_ended_ordinal() const {
return last_animation_ended_ordinal_;
}
ContextType last_animation_ended_context() const {
return last_animation_ended_context_;
}
InkDropAnimationEndedReason last_animation_ended_reason() const {
return last_animation_ended_reason_;
}
void OnAnimationStarted(ContextType context) {
animation_started_contexts_.push_back(context);
last_animation_started_context_ = context;
last_animation_started_ordinal_ = GetNextOrdinal();
}
void OnAnimationEnded(ContextType context,
InkDropAnimationEndedReason reason) {
animation_ended_contexts_.push_back(context);
last_animation_ended_context_ = context;
last_animation_ended_ordinal_ = GetNextOrdinal();
last_animation_ended_reason_ = reason;
}
//
// Collection of assertion predicates to be used with GTest test assertions.
// i.e. EXPECT_TRUE/EXPECT_FALSE and the ASSERT_ counterparts.
//
// Example:
//
// TestInkDropAnimationObserverHelper<int> observer;
// event_source.set_observer(observer);
// EXPECT_TRUE(observer.AnimationHasNotStarted());
//
// Passes *_TRUE assertions when an AnimationStarted() event has been
// observed.
testing::AssertionResult AnimationHasStarted() {
if (last_animation_started_ordinal() > 0) {
return testing::AssertionSuccess()
<< "Animations were started at ordinal="
<< last_animation_started_ordinal() << ".";
}
return testing::AssertionFailure() << "Animations have not started.";
}
// Passes *_TRUE assertions when an AnimationStarted() event has NOT been
// observed.
testing::AssertionResult AnimationHasNotStarted() {
if (last_animation_started_ordinal() < 0) {
return testing::AssertionSuccess();
}
return testing::AssertionFailure()
<< "Animations were started at ordinal="
<< last_animation_started_ordinal() << ".";
}
// Passes *_TRUE assertions when an AnimationEnded() event has been observed.
testing::AssertionResult AnimationHasEnded() {
if (last_animation_ended_ordinal() > 0) {
return testing::AssertionSuccess()
<< "Animations were ended at ordinal="
<< last_animation_ended_ordinal() << ".";
}
return testing::AssertionFailure() << "Animations have not ended.";
}
// Passes *_TRUE assertions when an AnimationEnded() event has NOT been
// observed.
testing::AssertionResult AnimationHasNotEnded() {
if (last_animation_ended_ordinal() < 0) {
return testing::AssertionSuccess();
}
return testing::AssertionFailure() << "Animations were ended at ordinal="
<< last_animation_ended_ordinal() << ".";
}
// Passes *_TRUE assertions when |animation_started_context_| is the same as
// |expected_contexts|.
testing::AssertionResult AnimationStartedContextsMatch(
const std::vector<ContextType>& expected_contexts) {
return ContextsMatch(expected_contexts, animation_started_contexts_);
}
// Passes *_TRUE assertions when |animation_ended_context_| is the same as
// |expected_contexts|.
testing::AssertionResult AnimationEndedContextsMatch(
const std::vector<ContextType>& expected_contexts) {
return ContextsMatch(expected_contexts, animation_ended_contexts_);
}
private:
// Helper function that checks if |actual_contexts| is the same as
// |expected_contexts| returning appropriate AssertionResult.
testing::AssertionResult ContextsMatch(
const std::vector<ContextType>& expected_contexts,
const std::vector<ContextType>& actual_contexts) {
const bool match = std::ranges::equal(expected_contexts, actual_contexts);
testing::AssertionResult result =
match ? (testing::AssertionSuccess() << "Expected == Actual: {")
: (testing::AssertionFailure() << "Expected != Actual: {");
for (auto eit = expected_contexts.begin(), ait = actual_contexts.begin();
eit != expected_contexts.end() || ait != actual_contexts.end();) {
if (eit != expected_contexts.begin()) {
result << ", ";
}
const bool eexists = eit != expected_contexts.end();
const bool aexists = ait != actual_contexts.end();
const bool item_match = eexists && aexists && *eit == *ait;
result << (eexists ? ToString(*eit) : "<none>")
<< (item_match ? " == " : " != ")
<< (aexists ? ToString(*ait) : "<none>");
if (eexists) {
eit++;
}
if (aexists) {
ait++;
}
}
result << "}";
return result;
}
// Returns the next event ordinal. The first returned ordinal will be 1.
int GetNextOrdinal() const {
return std::max(1, std::max(last_animation_started_ordinal_,
last_animation_ended_ordinal_) +
1);
}
// The ordinal time of the last AnimationStarted() call.
int last_animation_started_ordinal_ = -1;
// List of contexts for which animation is started.
std::vector<ContextType> animation_started_contexts_;
// The |context| passed to the last call to AnimationStarted().
ContextType last_animation_started_context_;
// The ordinal time of the last AnimationEnded() call.
int last_animation_ended_ordinal_ = -1;
// List of contexts for which animation is ended.
std::vector<ContextType> animation_ended_contexts_;
// The |context| passed to the last call to AnimationEnded().
ContextType last_animation_ended_context_;
InkDropAnimationEndedReason last_animation_ended_reason_ =
InkDropAnimationEndedReason::SUCCESS;
};
} // namespace views::test
#endif // UI_VIEWS_ANIMATION_TEST_TEST_INK_DROP_ANIMATION_OBSERVER_HELPER_H_
|