blob: b530f6e4ce760bc1a7a57106d4ce11b6b49a5170 [file] [log] [blame]
// Copyright 2017 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 "remoting/client/ui/fling_animation.h"
#include <cmath>
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/test/simple_test_tick_clock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
namespace {
const float kFlingTimeConstant = 325.f;
} // namespace
class FlingAnimationTest : public testing::Test {
public:
void SetUp() override;
void TearDown() override;
protected:
void TickAnimation(base::TimeDelta time_delta);
// Must be called after the animation ticks.
void AssertDeltaChanged();
FlingAnimation fling_animation_{
kFlingTimeConstant,
base::Bind(&FlingAnimationTest::OnDeltaChanged, base::Unretained(this))};
float received_dx_ = 0.f;
float received_dy_ = 0.f;
private:
void OnDeltaChanged(float dx, float dy);
bool change_received_ = false;
base::SimpleTestTickClock mock_clock_;
};
void FlingAnimationTest::SetUp() {
fling_animation_.SetTickClockForTest(&mock_clock_);
}
void FlingAnimationTest::TearDown() {
ASSERT_FALSE(change_received_);
}
void FlingAnimationTest::TickAnimation(base::TimeDelta time_delta) {
mock_clock_.Advance(time_delta);
fling_animation_.Tick();
}
void FlingAnimationTest::AssertDeltaChanged() {
ASSERT_TRUE(change_received_);
change_received_ = false;
}
void FlingAnimationTest::OnDeltaChanged(float dx, float dy) {
received_dx_ = dx;
received_dy_ = dy;
change_received_ = true;
}
TEST_F(FlingAnimationTest, TestNoFling) {
EXPECT_FALSE(fling_animation_.IsAnimationInProgress());
// This should not change the delta.
TickAnimation(base::TimeDelta::FromMilliseconds(100));
}
TEST_F(FlingAnimationTest, TestFlingWillEventuallyStop) {
fling_animation_.SetVelocity(1500.f, 1200.f);
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
TickAnimation(base::TimeDelta::FromMinutes(1));
EXPECT_FALSE(fling_animation_.IsAnimationInProgress());
}
TEST_F(FlingAnimationTest, TestFlingDeltaIsDecreasing) {
fling_animation_.SetVelocity(1500.f, 1200.f);
float previous_dx = std::numeric_limits<float>::infinity();
float previous_dy = std::numeric_limits<float>::infinity();
while (true) {
TickAnimation(base::TimeDelta::FromMilliseconds(16));
if (!fling_animation_.IsAnimationInProgress()) {
break;
}
AssertDeltaChanged();
float hyp =
std::sqrt(received_dx_ * received_dx_ + received_dy_ * received_dy_);
float prev_hyp =
std::sqrt(previous_dx * previous_dx + previous_dy * previous_dy);
EXPECT_LT(hyp, prev_hyp);
previous_dx = received_dx_;
previous_dy = received_dy_;
}
}
TEST_F(FlingAnimationTest, TestIgnoreLowVelocity) {
fling_animation_.SetVelocity(5.f, 5.f);
EXPECT_FALSE(fling_animation_.IsAnimationInProgress());
// This should not change the delta.
TickAnimation(base::TimeDelta::FromMilliseconds(5));
}
TEST_F(FlingAnimationTest, TestAbortAnimation) {
fling_animation_.SetVelocity(1500.f, 1200.f);
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
TickAnimation(base::TimeDelta::FromMilliseconds(16));
AssertDeltaChanged();
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
fling_animation_.Abort();
EXPECT_FALSE(fling_animation_.IsAnimationInProgress());
}
TEST_F(FlingAnimationTest, TestResetVelocity) {
fling_animation_.SetVelocity(1000.f, -1000.f);
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
TickAnimation(base::TimeDelta::FromMilliseconds(16));
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
AssertDeltaChanged();
EXPECT_GT(received_dx_, 0);
EXPECT_LT(received_dy_, 0);
fling_animation_.SetVelocity(-1000.f, 1000.f);
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
TickAnimation(base::TimeDelta::FromMilliseconds(16));
EXPECT_TRUE(fling_animation_.IsAnimationInProgress());
AssertDeltaChanged();
EXPECT_LT(received_dx_, 0);
EXPECT_GT(received_dy_, 0);
}
} // namespace remoting