| // Copyright 2022 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 <AppKit/AppKit.h> |
| |
| #include "ui/base/cocoa/defaults_utils.h" |
| #import "ui/base/test/cocoa_helper.h" |
| |
| namespace ui { |
| namespace cocoa { |
| namespace { |
| |
| const int k750MS = 750; |
| const int k250MS = 250; |
| const int kTwoHoursInMS = 2 * 60 * 1000; |
| const base::TimeDelta kInfiniteBlinkTime = base::Milliseconds(0); |
| |
| NSString* const kInsertionPointBlinkPeriod = @"NSTextInsertionPointBlinkPeriod"; |
| NSString* const kInsertionPointBlinkPeriodOn = |
| @"NSTextInsertionPointBlinkPeriodOn"; |
| NSString* const kInsertionPointBlinkPeriodOff = |
| @"NSTextInsertionPointBlinkPeriodOff"; |
| NSArray<NSString*>* blink_period_keys = @[ |
| kInsertionPointBlinkPeriod, kInsertionPointBlinkPeriodOn, |
| kInsertionPointBlinkPeriodOff |
| ]; |
| |
| class DefaultsUtilsTest : public CocoaTest { |
| public: |
| void SetUp() override { |
| CocoaTest::SetUp(); |
| |
| // Capture the (static) flag's value after the first time the function gets |
| // called. |
| if (!refresh_flag_initial_value_) { |
| refresh_flag_initial_value_ = BlinkPeriodRefreshFlagForTesting(); |
| } |
| |
| // Preserve the environment before clearing it out (in case we're running on |
| // a personal machine). |
| int i = 0; |
| for (NSString* next_key in blink_period_keys) { |
| orig_blink_period_values_[i++] = |
| [[NSUserDefaults standardUserDefaults] integerForKey:next_key]; |
| [[NSUserDefaults standardUserDefaults] removeObjectForKey:next_key]; |
| } |
| |
| // Make sure the test's blink period changes get picked up. |
| BlinkPeriodRefreshFlagForTesting() = true; |
| } |
| |
| bool BlinkPeriodRefreshFlagInitialValue() { |
| return *refresh_flag_initial_value_; |
| } |
| |
| bool WillRefreshBlinkPeriod() { return BlinkPeriodRefreshFlagForTesting(); } |
| |
| void RefreshBlinkPeriod() { BlinkPeriodRefreshFlagForTesting() = true; } |
| |
| // Sets the blink period to `milliseconds`. Removes all values from defaults. |
| void SetBlinkPeriod(const int milliseconds) { |
| NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
| |
| [defaults removeObjectForKey:kInsertionPointBlinkPeriodOn]; |
| [defaults removeObjectForKey:kInsertionPointBlinkPeriodOff]; |
| |
| [defaults setInteger:milliseconds forKey:kInsertionPointBlinkPeriod]; |
| RefreshBlinkPeriod(); |
| EXPECT_EQ(base::Milliseconds(milliseconds), |
| *TextInsertionCaretBlinkPeriodFromDefaults()); |
| |
| [defaults removeObjectForKey:kInsertionPointBlinkPeriod]; |
| } |
| |
| void TearDown() override { |
| int i = 0; |
| for (NSString* next_key in blink_period_keys) { |
| if (orig_blink_period_values_[i]) { |
| [[NSUserDefaults standardUserDefaults] |
| setInteger:orig_blink_period_values_[i] |
| forKey:next_key]; |
| } else { |
| [[NSUserDefaults standardUserDefaults] removeObjectForKey:next_key]; |
| } |
| i++; |
| } |
| |
| CocoaTest::TearDown(); |
| } |
| |
| private: |
| absl::optional<bool> refresh_flag_initial_value_; |
| NSInteger orig_blink_period_values_[3]; |
| }; |
| |
| // Tests that the flag which tells |
| // TextInsertionCaretBlinkPeriodFromDefaults() to refresh the blink period is |
| // set to true the first time BlinkPeriodRefreshFlagForTesting() gets called. |
| TEST_F(DefaultsUtilsTest, RefreshFlagTrueAfterFirstCall) { |
| EXPECT_TRUE(BlinkPeriodRefreshFlagInitialValue()); |
| } |
| |
| // Tests that the flag which tells |
| // TextInsertionCaretBlinkPeriodFromDefaults() to refresh the blink period is |
| // set to true whenever the app becomes active. |
| TEST_F(DefaultsUtilsTest, RefreshFlagResetsOnAppActivate) { |
| // Confirm that after retrieving the blink period we aren't set to refresh. |
| TextInsertionCaretBlinkPeriodFromDefaults(); |
| EXPECT_FALSE(WillRefreshBlinkPeriod()); |
| |
| // Simulate the app becoming active, as if the user switched away and back. |
| [[NSNotificationCenter defaultCenter] |
| postNotificationName:NSApplicationWillBecomeActiveNotification |
| object:nil]; |
| |
| EXPECT_TRUE(WillRefreshBlinkPeriod()); |
| |
| TextInsertionCaretBlinkPeriodFromDefaults(); |
| EXPECT_FALSE(WillRefreshBlinkPeriod()); |
| } |
| |
| // Tests that we don't return a blink period if there's nothing set in defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodNoDefaults) { |
| EXPECT_FALSE(TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning the blink period from defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromDefaults) { |
| [[NSUserDefaults standardUserDefaults] setInteger:k750MS |
| forKey:kInsertionPointBlinkPeriod]; |
| |
| EXPECT_EQ(base::Milliseconds(k750MS), |
| *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning the blink period when a double is stored in defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromDefaultsDouble) { |
| const double k750WithFractionalMS = 750.6; |
| [[NSUserDefaults standardUserDefaults] setDouble:k750WithFractionalMS |
| forKey:kInsertionPointBlinkPeriod]; |
| |
| EXPECT_EQ(base::Milliseconds(k750MS), |
| *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning the blink period derived from just the on time setting in |
| // defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromOnTime) { |
| [[NSUserDefaults standardUserDefaults] |
| setInteger:k750MS |
| forKey:kInsertionPointBlinkPeriodOn]; |
| |
| EXPECT_EQ(base::Milliseconds((k750MS + 0) / 2), |
| *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning the blink period derived from just the off time setting in |
| // defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromOffTime) { |
| [[NSUserDefaults standardUserDefaults] |
| setInteger:k250MS |
| forKey:kInsertionPointBlinkPeriodOff]; |
| |
| EXPECT_EQ(base::Milliseconds((0 + k250MS) / 2), |
| *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning the blink period derived from just the on and off times in |
| // defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromOnOffTime) { |
| [[NSUserDefaults standardUserDefaults] |
| setInteger:k750MS |
| forKey:kInsertionPointBlinkPeriodOn]; |
| [[NSUserDefaults standardUserDefaults] |
| setInteger:k250MS |
| forKey:kInsertionPointBlinkPeriodOff]; |
| |
| EXPECT_EQ(base::Milliseconds((k750MS + k250MS) / 2), |
| *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning "infinite" blink period for a long time in defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromLongTime) { |
| [[NSUserDefaults standardUserDefaults] setInteger:kTwoHoursInMS |
| forKey:kInsertionPointBlinkPeriod]; |
| |
| EXPECT_EQ(kInfiniteBlinkTime, *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests returning "infinite" blink period for a long on time in defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodFromLongOnTime) { |
| [[NSUserDefaults standardUserDefaults] |
| setInteger:kTwoHoursInMS |
| forKey:kInsertionPointBlinkPeriodOn]; |
| |
| EXPECT_EQ(kInfiniteBlinkTime, *TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| // Tests handling of bad blink period times from defaults. |
| TEST_F(DefaultsUtilsTest, InsertionPointBlinkPeriodNegativeTimes) { |
| const int kNegativeMS = -500; |
| NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; |
| |
| // By setting the blink period we cause |
| // TextInsertionCaretBlinkPeriodFromDefaults() to evaluate to true so |
| // we're sure that setting a negative value causes it to evaluate to false. |
| SetBlinkPeriod(k250MS); |
| |
| [defaults setInteger:kNegativeMS forKey:kInsertionPointBlinkPeriod]; |
| RefreshBlinkPeriod(); |
| EXPECT_FALSE(TextInsertionCaretBlinkPeriodFromDefaults()); |
| |
| SetBlinkPeriod(k250MS); |
| |
| [defaults setInteger:kNegativeMS forKey:kInsertionPointBlinkPeriodOn]; |
| RefreshBlinkPeriod(); |
| EXPECT_FALSE(TextInsertionCaretBlinkPeriodFromDefaults()); |
| |
| SetBlinkPeriod(k250MS); |
| |
| [defaults setInteger:k750MS forKey:kInsertionPointBlinkPeriodOn]; |
| [defaults setInteger:kNegativeMS forKey:kInsertionPointBlinkPeriodOff]; |
| RefreshBlinkPeriod(); |
| EXPECT_FALSE(TextInsertionCaretBlinkPeriodFromDefaults()); |
| } |
| |
| } // namespace |
| } // namespace cocoa |
| } // namespace ui |