#include "ash/system/progress_indicator/progress_indicator.h"
#include "ash/system/progress_indicator/progress_indicator_animation_registry.h"
#include "ash/test/ash_test_base.h"
#include "base/test/bind.h"
#include "base/test/repeating_test_future.h"
namespace ash {
namespace {
class TestProgressIndicator : public ProgressIndicator {
public:
TestProgressIndicator()
: ProgressIndicator(
nullptr,
ProgressIndicatorAnimationRegistry::AsAnimationKey(this)) {}
void SetProgress(const std::optional<float>& progress) {
progress_ = progress;
static_cast<ui::LayerDelegate*>(this)->UpdateVisualState();
}
private:
std::optional<float> CalculateProgress() const override { return progress_; }
std::optional<float> progress_;
};
}
using ProgressIndicatorTest = AshTestBase;
TEST_F(ProgressIndicatorTest, CreateDefaultInstance) {
std::optional<float> progress = ProgressIndicator::kProgressComplete;
auto progress_indicator = ProgressIndicator::CreateDefaultInstance(
base::BindLambdaForTesting([&]() { return progress; }));
auto* layer_delegate =
static_cast<ui::LayerDelegate*>(progress_indicator.get());
auto key = progress_indicator->animation_key();
auto* registry = progress_indicator->animation_registry();
EXPECT_EQ(progress_indicator->progress(), progress);
EXPECT_FALSE(registry->GetProgressIconAnimationForKey(key));
EXPECT_FALSE(registry->GetProgressRingAnimationForKey(key));
progress = 0.f;
layer_delegate->UpdateVisualState();
EXPECT_EQ(progress_indicator->progress(), progress);
ASSERT_TRUE(registry->GetProgressIconAnimationForKey(key));
EXPECT_TRUE(registry->GetProgressIconAnimationForKey(key)->HasAnimated());
EXPECT_FALSE(registry->GetProgressRingAnimationForKey(key));
progress = 0.5f;
layer_delegate->UpdateVisualState();
EXPECT_EQ(progress_indicator->progress(), progress);
ASSERT_TRUE(registry->GetProgressIconAnimationForKey(key));
EXPECT_TRUE(registry->GetProgressIconAnimationForKey(key)->HasAnimated());
EXPECT_FALSE(registry->GetProgressRingAnimationForKey(key));
progress = std::nullopt;
layer_delegate->UpdateVisualState();
EXPECT_EQ(progress_indicator->progress(), progress);
ASSERT_TRUE(registry->GetProgressIconAnimationForKey(key));
EXPECT_TRUE(registry->GetProgressIconAnimationForKey(key)->HasAnimated());
ASSERT_TRUE(registry->GetProgressRingAnimationForKey(key));
EXPECT_EQ(registry->GetProgressRingAnimationForKey(key)->type(),
ProgressRingAnimation::Type::kIndeterminate);
progress = 0.75f;
layer_delegate->UpdateVisualState();
EXPECT_EQ(progress_indicator->progress(), progress);
ASSERT_TRUE(registry->GetProgressIconAnimationForKey(key));
EXPECT_TRUE(registry->GetProgressIconAnimationForKey(key)->HasAnimated());
EXPECT_FALSE(registry->GetProgressRingAnimationForKey(key));
progress = ProgressIndicator::kProgressComplete;
layer_delegate->UpdateVisualState();
EXPECT_EQ(progress_indicator->progress(), progress);
EXPECT_FALSE(registry->GetProgressIconAnimationForKey(key));
ASSERT_TRUE(registry->GetProgressRingAnimationForKey(key));
EXPECT_EQ(registry->GetProgressRingAnimationForKey(key)->type(),
ProgressRingAnimation::Type::kPulse);
base::test::RepeatingTestFuture<ProgressRingAnimation*> future;
auto subscription = registry->AddProgressRingAnimationChangedCallbackForKey(
key, future.GetCallback());
EXPECT_EQ(future.Take(), nullptr);
}
TEST_F(ProgressIndicatorTest, AddProgressChangedCallback) {
TestProgressIndicator progress_indicator;
progress_indicator.SetProgress(0.5f);
int callback_call_count = 0;
auto subscription = progress_indicator.AddProgressChangedCallback(
base::BindLambdaForTesting([&]() { ++callback_call_count; }));
progress_indicator.SetProgress(0.75f);
EXPECT_EQ(callback_call_count, 1);
progress_indicator.SetProgress(0.75f);
EXPECT_EQ(callback_call_count, 1);
subscription = base::CallbackListSubscription();
progress_indicator.SetProgress(1.f);
EXPECT_EQ(callback_call_count, 1);
}
}