123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- // Copyright 2021 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 "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 {
- // TestProgressIndicator -------------------------------------------------------
- class TestProgressIndicator : public ProgressIndicator {
- public:
- TestProgressIndicator()
- : ProgressIndicator(/*animation_registry=*/nullptr,
- /*animation_key=*/this) {}
- void SetProgress(const absl::optional<float>& progress) {
- progress_ = progress;
- static_cast<ui::LayerDelegate*>(this)->UpdateVisualState();
- }
- private:
- // ProgressIndicator:
- absl::optional<float> CalculateProgress() const override { return progress_; }
- absl::optional<float> progress_;
- };
- } // namespace
- // ProgressIndicatorTest -------------------------------------------------------
- using ProgressIndicatorTest = AshTestBase;
- // Verifies that `ProgressIndicator::CreateDefaultInstance()` works as intended.
- // It should delegate progress calculation to a constructor provided callback
- // and manage progress animations as needed.
- TEST_F(ProgressIndicatorTest, CreateDefaultInstance) {
- absl::optional<float> progress;
- // Create a default instance of `ProgressIndicator` that paints `progress`
- // whenever visual state is updated.
- auto progress_indicator = ProgressIndicator::CreateDefaultInstance(
- base::BindLambdaForTesting([&]() { return progress; }));
- // Cache `layer_delegate` associate with `progress_indicator` to manually
- // trigger update of visual state.
- auto* layer_delegate =
- static_cast<ui::LayerDelegate*>(progress_indicator.get());
- // Cache animation `key` and `registry` associated with `progress_indicator`.
- auto* key = progress_indicator.get();
- auto* registry = progress_indicator->animation_registry();
- // Verify initial progress and animation states.
- EXPECT_EQ(progress_indicator->progress(), progress);
- EXPECT_FALSE(registry->GetProgressIconAnimationForKey(key));
- EXPECT_FALSE(registry->GetProgressRingAnimationForKey(key));
- // Update `progress` to 0%. Verify progress and animation states.
- 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));
- // Update `progress` to 50%. Verify progress and animation states.
- 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));
- // Update `progress` to indeterminate. Verify progress and animation states.
- progress = absl::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);
- // Update `progress` to 75%. Verify progress and animation states.
- 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));
- // Update `progress` to 100%. Verify progress an animation states.
- 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);
- // The pulse animation that runs on progress completion should be removed
- // automatically on animation completion.
- base::test::RepeatingTestFuture<ProgressRingAnimation*> future;
- auto subscription = registry->AddProgressRingAnimationChangedCallbackForKey(
- key, future.GetCallback());
- EXPECT_EQ(future.Take(), nullptr);
- }
- // Verifies that `ProgressIndicator::AddProgressChangedCallback()` works as
- // intended.
- TEST_F(ProgressIndicatorTest, AddProgressChangedCallback) {
- // Create a test `progress_indicator`.
- TestProgressIndicator progress_indicator;
- progress_indicator.SetProgress(0.5f);
- // Add a callback to be notified of progress changed events. The callback
- // should be invoked on progress changes so long as the returned subscription
- // continues to exist.
- int callback_call_count = 0;
- auto subscription =
- std::make_unique<base::RepeatingClosureList::Subscription>(
- progress_indicator.AddProgressChangedCallback(
- base::BindLambdaForTesting([&]() { ++callback_call_count; })));
- // Change the underlying progress.
- progress_indicator.SetProgress(0.75f);
- EXPECT_EQ(callback_call_count, 1);
- // Attempt to change the underlying progress to the same value.
- progress_indicator.SetProgress(0.75f);
- EXPECT_EQ(callback_call_count, 1);
- // Reset the subscription and change the underlying progress.
- subscription.reset();
- progress_indicator.SetProgress(1.f);
- EXPECT_EQ(callback_call_count, 1);
- }
- } // namespace ash
|