blob: ce704600f3c70c5a9602845ff271d3b38c5981e2 [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 "base/bind.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.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::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
base::test::ScopedTaskEnvironment::NowSource::
MAIN_THREAD_MOCK_TIME) {}
float PinnednessOf(TabAnimationState state) { return state.pinnedness_; }
base::test::ScopedTaskEnvironment env_;
};
TEST_F(TabAnimationTest, StaticAnimationDoesNotChange) {
TabAnimationState static_state = TabAnimationState::ForIdealTabState(
TabAnimationState::TabOpenness::kOpen,
TabAnimationState::TabPinnedness::kUnpinned,
TabAnimationState::TabActiveness::kInactive, 0);
TabAnimation static_animation =
TabAnimation::ForStaticState(static_state, base::BindOnce([]() {}));
EXPECT_EQ(kZeroDuration, static_animation.GetTimeRemaining());
EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
static_animation.GetTimeRemaining());
EXPECT_EQ(PinnednessOf(static_state),
PinnednessOf(static_animation.GetCurrentState()));
env_.FastForwardBy(TabAnimation::kAnimationDuration);
EXPECT_EQ(PinnednessOf(static_state),
PinnednessOf(static_animation.GetCurrentState()));
}
TEST_F(TabAnimationTest, AnimationAnimates) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabAnimationState::TabOpenness::kOpen,
TabAnimationState::TabPinnedness::kUnpinned,
TabAnimationState::TabActiveness::kInactive, 0);
TabAnimationState target_state =
initial_state.WithPinnedness(TabAnimationState::TabPinnedness::kPinned);
TabAnimation animation =
TabAnimation::ForStaticState(initial_state, base::BindOnce([]() {}));
animation.AnimateTo(target_state);
EXPECT_LT(kZeroDuration, animation.GetTimeRemaining());
EXPECT_EQ(PinnednessOf(initial_state),
PinnednessOf(animation.GetCurrentState()));
env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0);
EXPECT_LT(kZeroDuration, animation.GetTimeRemaining());
EXPECT_LT(PinnednessOf(initial_state),
PinnednessOf(animation.GetCurrentState()));
EXPECT_LT(PinnednessOf(animation.GetCurrentState()),
PinnednessOf(target_state));
env_.FastForwardBy(TabAnimation::kAnimationDuration / 2.0);
EXPECT_EQ(PinnednessOf(target_state),
PinnednessOf(animation.GetCurrentState()));
}
TEST_F(TabAnimationTest, CompletedAnimationSnapsToTarget) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabAnimationState::TabOpenness::kOpen,
TabAnimationState::TabPinnedness::kUnpinned,
TabAnimationState::TabActiveness::kInactive, 0);
TabAnimationState target_state =
initial_state.WithPinnedness(TabAnimationState::TabPinnedness::kPinned);
TabAnimation animation =
TabAnimation::ForStaticState(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(PinnednessOf(target_state),
PinnednessOf(animation.GetCurrentState()));
}
TEST_F(TabAnimationTest, ReplacedAnimationRestartsDuration) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabAnimationState::TabOpenness::kOpen,
TabAnimationState::TabPinnedness::kUnpinned,
TabAnimationState::TabActiveness::kInactive, 0);
TabAnimationState target_state =
initial_state.WithPinnedness(TabAnimationState::TabPinnedness::kPinned);
TabAnimation animation =
TabAnimation::ForStaticState(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(PinnednessOf(reversal_state),
PinnednessOf(animation.GetCurrentState()));
EXPECT_EQ(TabAnimation::kAnimationDuration, animation.GetTimeRemaining());
}
TEST_F(TabAnimationTest, RetargetedAnimationKeepsDuration) {
TabAnimationState initial_state = TabAnimationState::ForIdealTabState(
TabAnimationState::TabOpenness::kOpen,
TabAnimationState::TabPinnedness::kUnpinned,
TabAnimationState::TabActiveness::kInactive, 0);
TabAnimationState target_state =
initial_state.WithPinnedness(TabAnimationState::TabPinnedness::kPinned);
TabAnimation animation =
TabAnimation::ForStaticState(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(PinnednessOf(initial_state),
PinnednessOf(animation.GetCurrentState()));
}
TEST_F(TabAnimationTest, TestNotifyCloseCompleted) {
class TabClosedDetector {
public:
void NotifyTabClosed() { was_closed_ = true; }
bool was_closed_ = false;
};
TabAnimationState static_state = TabAnimationState::ForIdealTabState(
TabAnimationState::TabOpenness::kOpen,
TabAnimationState::TabPinnedness::kUnpinned,
TabAnimationState::TabActiveness::kInactive, 0);
TabClosedDetector tab_closed_detector;
TabAnimation static_animation = TabAnimation::ForStaticState(
static_state, base::BindOnce(&TabClosedDetector::NotifyTabClosed,
base::Unretained(&tab_closed_detector)));
EXPECT_FALSE(tab_closed_detector.was_closed_);
static_animation.NotifyCloseCompleted();
EXPECT_TRUE(tab_closed_detector.was_closed_);
}