Chromium Code Reviews| Index: ash/common/accelerators/accelerator_table_unittest.cc |
| diff --git a/ash/common/accelerators/accelerator_table_unittest.cc b/ash/common/accelerators/accelerator_table_unittest.cc |
| index e469625545a0282e11a622e8ac2eff0d9b5d65da..8a4c32dabc0e567ff5dc22d2cb0fad0f7cf18850 100644 |
| --- a/ash/common/accelerators/accelerator_table_unittest.cc |
| +++ b/ash/common/accelerators/accelerator_table_unittest.cc |
| @@ -5,13 +5,23 @@ |
| #include <set> |
| #include "ash/common/accelerators/accelerator_table.h" |
| +#include "base/macros.h" |
| +#include "base/md5.h" |
| #include "base/strings/string_util.h" |
| +#include "base/strings/stringprintf.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| namespace ash { |
| namespace { |
| +// The number of non-Search-based accelerators as of 2017-04-06. |
| +constexpr int kNonSearchAcceleratorsNum = 92; |
| +// The hash of non-Search-based accelerators as of 2017-04-06. |
| +// See HashAcceleratorData(). |
| +constexpr char kNonSearchAcceleratorsHash[] = |
| + "6c6695ca5f4d7298504e4d1e8a148902"; |
| + |
| struct Cmp { |
| bool operator()(const AcceleratorData& lhs, const AcceleratorData& rhs) { |
| if (lhs.trigger_on_press != rhs.trigger_on_press) |
| @@ -23,6 +33,30 @@ struct Cmp { |
| } |
| }; |
| +std::string AcceleratorDataToString(const AcceleratorData& accelerator) { |
| + return base::StringPrintf( |
| + "trigger_on_press=%s keycode=%d shift=%s control=%s alt=%s search=%s " |
| + "action=%d", |
|
Daniel Erat
2017/04/06 19:33:33
just using the integer value here like this is fin
|
| + accelerator.trigger_on_press ? "true" : "false", accelerator.keycode, |
| + (accelerator.modifiers & ui::EF_SHIFT_DOWN) ? "true" : "false", |
| + (accelerator.modifiers & ui::EF_CONTROL_DOWN) ? "true" : "false", |
| + (accelerator.modifiers & ui::EF_ALT_DOWN) ? "true" : "false", |
| + (accelerator.modifiers & ui::EF_COMMAND_DOWN) ? "true" : "false", |
| + accelerator.action); |
| +} |
| + |
| +std::string HashAcceleratorData( |
| + const std::vector<AcceleratorData> accelerators) { |
| + base::MD5Context context; |
| + base::MD5Init(&context); |
| + for (const AcceleratorData& accelerator : accelerators) |
| + base::MD5Update(&context, AcceleratorDataToString(accelerator)); |
| + |
| + base::MD5Digest digest; |
| + base::MD5Final(&digest, &context); |
| + return MD5DigestToBase16(digest); |
| +} |
| + |
| } // namespace |
| TEST(AcceleratorTableTest, CheckDuplicatedAccelerators) { |
| @@ -30,10 +64,7 @@ TEST(AcceleratorTableTest, CheckDuplicatedAccelerators) { |
| for (size_t i = 0; i < kAcceleratorDataLength; ++i) { |
| const AcceleratorData& entry = kAcceleratorData[i]; |
| EXPECT_TRUE(accelerators.insert(entry).second) |
| - << "Duplicated accelerator: " << entry.trigger_on_press << ", " |
| - << entry.keycode << ", " << (entry.modifiers & ui::EF_SHIFT_DOWN) |
| - << ", " << (entry.modifiers & ui::EF_CONTROL_DOWN) << ", " |
| - << (entry.modifiers & ui::EF_ALT_DOWN); |
| + << "Duplicated accelerator: " << AcceleratorDataToString(entry); |
| } |
| } |
| @@ -80,11 +111,8 @@ TEST(AcceleratorTableTest, CheckDeprecatedAccelerators) { |
| // A deprecated action can never appear twice in the list. |
| const AcceleratorData& entry = kDeprecatedAccelerators[i]; |
| EXPECT_TRUE(deprecated_actions.insert(entry).second) |
| - << "Duplicate deprecated accelerator: " << entry.trigger_on_press |
| - << ", " << entry.keycode << ", " |
| - << (entry.modifiers & ui::EF_SHIFT_DOWN) << ", " |
| - << (entry.modifiers & ui::EF_CONTROL_DOWN) << ", " |
| - << (entry.modifiers & ui::EF_ALT_DOWN); |
| + << "Duplicate deprecated accelerator: " |
| + << AcceleratorDataToString(entry); |
| } |
| std::set<AcceleratorAction> actions; |
| @@ -101,4 +129,33 @@ TEST(AcceleratorTableTest, CheckDeprecatedAccelerators) { |
| } |
| } |
| +// All new accelerators should be Search-based and approved by UX. |
| +TEST(AcceleratorTableTest, CheckSearchBasedAccelerators) { |
| + std::vector<AcceleratorData> non_search_accelerators; |
| + for (size_t i = 0; i < kAcceleratorDataLength; ++i) { |
| + const AcceleratorData& entry = kAcceleratorData[i]; |
| + if (entry.modifiers & ui::EF_COMMAND_DOWN) |
| + continue; |
| + non_search_accelerators.emplace_back(entry); |
| + } |
| + |
| + const int accelerators_number = non_search_accelerators.size(); |
| + EXPECT_LE(accelerators_number, kNonSearchAcceleratorsNum) |
| + << "All new accelerators should be Search-based and approved by UX."; |
| + |
| + std::stable_sort(non_search_accelerators.begin(), |
| + non_search_accelerators.end(), Cmp()); |
| + const std::string non_search_accelerators_hash = |
| + HashAcceleratorData(non_search_accelerators); |
| + |
| + EXPECT_EQ(non_search_accelerators_hash, kNonSearchAcceleratorsHash) |
| + << "New accelerators must use the Search key. Please talk to the UX " |
| + "team.\n" |
| + "If you are removing a non-Search-based accelerator, please update " |
| + "the date along with the following values\n" |
| + << "kNonSearchAcceleratorsNum=" << accelerators_number << " and " |
| + << "kNonSearchAcceleratorsHash=\"" << non_search_accelerators_hash |
| + << "\""; |
| +} |
| + |
| } // namespace ash |