blob: 77992dda01e3d84c145b6ae10bbab0877b5b55be [file] [log] [blame]
// Copyright 2019 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 "chrome/browser/ui/views/tabs/tab_animation.h"
#include <utility>
#include "base/bind.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "chrome/browser/ui/tabs/tab_types.h"
#include "chrome/browser/ui/views/tabs/tab_animation_state.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
constexpr base::TimeDelta kZeroDuration = base::TimeDelta::FromMilliseconds(0);
} // namespace
class TabAnimationTest : public testing::Test {
public:
TabAnimationTest()
: env_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
float CurrentPinnedness(const TabAnimation& animation) {
return animation.GetCurrentState().pinnedness();
}
base::test::TaskEnvironment env_;
};
TEST_F(TabAnimationTest, StaticAnimationDoesNotChange) {
TabAnimationState static_state = TabAnimationState::ForIdealTabState(
TabOpen::kOpen, TabPinned::kUnpinned, TabActive::kInactive, 0);
TabAnimation static_animation(static_state, base::BindOnce([]() {}));
EXPECT_EQ(kZeroDuration, static_animation.GetTimeRemaining());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
static_animation.GetTimeRemaining());
EXPECT_EQ(static_state.pinnedness(), CurrentPinnedness(static_animation));
env_.FastForwardBy(TabAnimation::kAnimationDuration);
EXPECT_EQ(static_state.pinnedness(), CurrentPinnedness(static_animation));
}
TEST_F(TabAnimationTest, AnimationAnimates) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabOpen::kOpen, TabPinned::kUnpinned, TabActive::kInactive, 0);
TabAnimationState target_state = initial_state.WithPinned(TabPinned::kPinned);
TabAnimation animation(initial_state, base::BindOnce([]() {}));
animation.AnimateTo(target_state);
EXPECT_LT(kZeroDuration, animation.GetTimeRemaining());
EXPECT_EQ(initial_state.pinnedness(), CurrentPinnedness(animation));
env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0);
EXPECT_LT(kZeroDuration, animation.GetTimeRemaining());
EXPECT_LT(initial_state.pinnedness(), CurrentPinnedness(animation));
EXPECT_LT(CurrentPinnedness(animation), target_state.pinnedness());
env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0);
EXPECT_EQ(target_state.pinnedness(), CurrentPinnedness(animation));
}
TEST_F(TabAnimationTest, CompletedAnimationSnapsToTarget) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabOpen::kOpen, TabPinned::kUnpinned, TabActive::kInactive, 0);
TabAnimationState target_state = initial_state.WithPinned(TabPinned::kPinned);
TabAnimation animation(initial_state, base::BindOnce([]() {}));
animation.AnimateTo(target_state);
animation.CompleteAnimation();
EXPECT_EQ(kZeroDuration, animation.GetTimeRemaining());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(0), animation.GetTimeRemaining());
EXPECT_EQ(target_state.pinnedness(), CurrentPinnedness(animation));
}
TEST_F(TabAnimationTest, ReplacedAnimationRestartsDuration) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabOpen::kOpen, TabPinned::kUnpinned, TabActive::kInactive, 0);
TabAnimationState target_state = initial_state.WithPinned(TabPinned::kPinned);
TabAnimation animation(initial_state, base::BindOnce([]() {}));
animation.AnimateTo(target_state);
env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0);
TabAnimationState reversal_state = animation.GetCurrentState();
animation.AnimateTo(initial_state);
EXPECT_EQ(reversal_state.pinnedness(), CurrentPinnedness(animation));
EXPECT_EQ(TabAnimation::kAnimationDuration, animation.GetTimeRemaining());
}
TEST_F(TabAnimationTest, RetargetedAnimationKeepsDuration) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabOpen::kOpen, TabPinned::kUnpinned, TabActive::kInactive, 0);
TabAnimationState target_state = initial_state.WithPinned(TabPinned::kPinned);
TabAnimation animation(initial_state, base::BindOnce([]() {}));
animation.AnimateTo(target_state);
env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0);
EXPECT_EQ(TabAnimation::kAnimationDuration / 2.0,
animation.GetTimeRemaining());
animation.RetargetTo(initial_state);
EXPECT_EQ(TabAnimation::kAnimationDuration / 2.0,
animation.GetTimeRemaining());
env_.FastForwardBy(TabAnimation::kAnimationDuration);
EXPECT_EQ(initial_state.pinnedness(), CurrentPinnedness(animation));
}
TEST_F(TabAnimationTest, TestNotifyCloseCompleted) {
class TabClosedDetector {
public:
void NotifyTabClosed() { was_closed_ = true; }
bool was_closed_ = false;
};
TabAnimationState static_state = TabAnimationState::ForIdealTabState(
TabOpen::kOpen, TabPinned::kUnpinned, TabActive::kInactive, 0);
TabClosedDetector tab_closed_detector;
TabAnimation animation(
static_state, base::BindOnce(&TabClosedDetector::NotifyTabClosed,
base::Unretained(&tab_closed_detector)));
EXPECT_FALSE(tab_closed_detector.was_closed_);
animation.NotifyCloseCompleted();
EXPECT_TRUE(tab_closed_detector.was_closed_);
}