| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/common/extensions/extension_commands.h" |
| 6 |
| 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/string_number_conversions.h" |
| 9 #include "base/values.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" |
| 11 |
| 12 class ExtensionCommandsTest : public testing::Test { |
| 13 }; |
| 14 |
| 15 TEST(ExtensionCommandsTest, ExtensionCommandParsing) { |
| 16 const ui::Accelerator None = ui::Accelerator(); |
| 17 const ui::Accelerator ShiftF = |
| 18 ui::Accelerator(ui::VKEY_F, true, false, false); |
| 19 const ui::Accelerator CtrlF = |
| 20 ui::Accelerator(ui::VKEY_F, false, true, false); |
| 21 const ui::Accelerator AltF = |
| 22 ui::Accelerator(ui::VKEY_F, false, false, true); |
| 23 const ui::Accelerator CtrlShiftF = |
| 24 ui::Accelerator(ui::VKEY_F, true, true, false); |
| 25 const ui::Accelerator AltShiftF = |
| 26 ui::Accelerator(ui::VKEY_F, true, false, true); |
| 27 |
| 28 const struct { |
| 29 bool expected_result; |
| 30 ui::Accelerator accelerator; |
| 31 const char* command_name; |
| 32 const char* key; |
| 33 const char* description; |
| 34 } kTests[] = { |
| 35 // Negative test (one or more missing required fields). We don't need to |
| 36 // test |command_name| being blank as it is used as a key in the manifest, |
| 37 // so it can't be blank (and we CHECK() when it is). |
| 38 { false, None, "command", "", "" }, |
| 39 { false, None, "command", "Ctrl+f", "" }, |
| 40 { false, None, "command", "", "description" }, |
| 41 // Ctrl+Alt is not permitted, see MSDN link in comments in Parse function. |
| 42 { false, None, "command", "Ctrl+Alt+F", "description" }, |
| 43 // Unsupported shortcuts/too many, or missing modifier. |
| 44 { false, None, "command", "A", "description" }, |
| 45 { false, None, "command", "F10", "description" }, |
| 46 { false, None, "command", "Ctrl+1", "description" }, |
| 47 { false, None, "command", "Ctrl+F+G", "description" }, |
| 48 { false, None, "command", "Ctrl+Alt+Shift+G", "description" }, |
| 49 // Basic tests. |
| 50 { true, CtrlF, "command", "Ctrl+F", "description" }, |
| 51 { true, ShiftF, "command", "Shift+F", "description" }, |
| 52 { true, AltF, "command", "Alt+F", "description" }, |
| 53 { true, CtrlShiftF, "command", "Ctrl+Shift+F", "description" }, |
| 54 { true, AltShiftF, "command", "Alt+Shift+F", "description" }, |
| 55 // Order tests. |
| 56 { true, CtrlF, "command", "F+Ctrl", "description" }, |
| 57 { true, ShiftF, "command", "F+Shift", "description" }, |
| 58 { true, AltF, "command", "F+Alt", "description" }, |
| 59 { true, CtrlShiftF, "command", "F+Ctrl+Shift", "description" }, |
| 60 { true, CtrlShiftF, "command", "F+Shift+Ctrl", "description" }, |
| 61 { true, AltShiftF, "command", "F+Alt+Shift", "description" }, |
| 62 { true, AltShiftF, "command", "F+Shift+Alt", "description" }, |
| 63 // Case insensitivity is not OK. |
| 64 { false, CtrlF, "command", "Ctrl+f", "description" }, |
| 65 { false, CtrlF, "command", "cTrL+F", "description" }, |
| 66 // Skipping description is OK for browser- and pageActions. |
| 67 { true, CtrlF, "_execute_browser_action", "Ctrl+F", "" }, |
| 68 { true, CtrlF, "_execute_page_action", "Ctrl+F", "" }, |
| 69 }; |
| 70 |
| 71 // TODO(finnur): test Command/Options on Mac when implemented. |
| 72 |
| 73 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTests); ++i) { |
| 74 // First parse the command as a simple string. |
| 75 scoped_ptr<DictionaryValue> input(new DictionaryValue); |
| 76 input->SetString("suggested_key", kTests[i].key); |
| 77 input->SetString("description", kTests[i].description); |
| 78 |
| 79 SCOPED_TRACE(std::string("Command name: |") + kTests[i].command_name + |
| 80 "| key: |" + kTests[i].key + |
| 81 "| description: |" + kTests[i].description + |
| 82 "| index: " + base::IntToString(i)); |
| 83 |
| 84 extensions::Command command; |
| 85 string16 error; |
| 86 bool result = |
| 87 command.Parse(input.get(), kTests[i].command_name, i, &error); |
| 88 |
| 89 EXPECT_EQ(kTests[i].expected_result, result); |
| 90 if (result) { |
| 91 EXPECT_STREQ(kTests[i].description, command.description().c_str()); |
| 92 EXPECT_STREQ(kTests[i].command_name, command.command_name().c_str()); |
| 93 EXPECT_EQ(kTests[i].accelerator, command.accelerator()); |
| 94 } |
| 95 |
| 96 // Now parse the command as a dictionary of multiple values. |
| 97 input.reset(new DictionaryValue); |
| 98 DictionaryValue* key_dict = new DictionaryValue(); |
| 99 key_dict->SetString("default", kTests[i].key); |
| 100 key_dict->SetString("windows", kTests[i].key); |
| 101 key_dict->SetString("mac", kTests[i].key); |
| 102 input->Set("suggested_key", key_dict); |
| 103 input->SetString("description", kTests[i].description); |
| 104 |
| 105 result = command.Parse(input.get(), kTests[i].command_name, i, &error); |
| 106 |
| 107 EXPECT_EQ(kTests[i].expected_result, result); |
| 108 if (result) { |
| 109 EXPECT_STREQ(kTests[i].description, command.description().c_str()); |
| 110 EXPECT_STREQ(kTests[i].command_name, command.command_name().c_str()); |
| 111 EXPECT_EQ(kTests[i].accelerator, command.accelerator()); |
| 112 } |
| 113 } |
| 114 } |
| 115 |
| 116 TEST(ExtensionCommandsTest, ExtensionCommandParsingFallback) { |
| 117 std::string description = "desc"; |
| 118 std::string command_name = "foo"; |
| 119 |
| 120 // Test that platform specific keys are honored on each platform, despite |
| 121 // fallback being given. |
| 122 scoped_ptr<DictionaryValue> input(new DictionaryValue); |
| 123 DictionaryValue* key_dict = new DictionaryValue(); |
| 124 key_dict->SetString("default", "Ctrl+Shift+D"); |
| 125 key_dict->SetString("windows", "Ctrl+Shift+W"); |
| 126 key_dict->SetString("mac", "Ctrl+Shift+M"); |
| 127 key_dict->SetString("linux", "Ctrl+Shift+L"); |
| 128 key_dict->SetString("chromeos", "Ctrl+Shift+C"); |
| 129 input->Set("suggested_key", key_dict); |
| 130 input->SetString("description", description); |
| 131 |
| 132 extensions::Command command; |
| 133 string16 error; |
| 134 EXPECT_TRUE(command.Parse(input.get(), command_name, 0, &error)); |
| 135 EXPECT_STREQ(description.c_str(), command.description().c_str()); |
| 136 EXPECT_STREQ(command_name.c_str(), command.command_name().c_str()); |
| 137 |
| 138 #if defined(OS_WIN) |
| 139 ui::Accelerator accelerator(ui::VKEY_W, true, true, false); |
| 140 #elif defined(OS_MACOSX) |
| 141 ui::Accelerator accelerator(ui::VKEY_M, true, true, false); |
| 142 #elif defined(OS_CHROMEOS) |
| 143 ui::Accelerator accelerator(ui::VKEY_C, true, true, false); |
| 144 #elif defined(OS_LINUX) |
| 145 ui::Accelerator accelerator(ui::VKEY_L, true, true, false); |
| 146 #else |
| 147 ui::Accelerator accelerator(ui::VKEY_D, true, true, false); |
| 148 #endif |
| 149 EXPECT_EQ(accelerator, command.accelerator()); |
| 150 |
| 151 // Misspell a platform. |
| 152 key_dict->SetString("windosw", "Ctrl+M"); |
| 153 EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error)); |
| 154 EXPECT_TRUE(key_dict->Remove("windosw", NULL)); |
| 155 |
| 156 // Now remove platform specific keys (leaving just "default") and make sure |
| 157 // every platform falls back to the default. |
| 158 EXPECT_TRUE(key_dict->Remove("windows", NULL)); |
| 159 EXPECT_TRUE(key_dict->Remove("mac", NULL)); |
| 160 EXPECT_TRUE(key_dict->Remove("linux", NULL)); |
| 161 EXPECT_TRUE(key_dict->Remove("chromeos", NULL)); |
| 162 EXPECT_TRUE(command.Parse(input.get(), command_name, 0, &error)); |
| 163 EXPECT_EQ(ui::VKEY_D, command.accelerator().key_code()); |
| 164 |
| 165 // Now remove "default", leaving no option but failure. Or, in the words of |
| 166 // the immortal Adam Savage: "Failure is always an option". |
| 167 EXPECT_TRUE(key_dict->Remove("default", NULL)); |
| 168 EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error)); |
| 169 |
| 170 // Now add only a valid platform that we are not running on to make sure devs |
| 171 // are notified of errors on other platforms. |
| 172 #if defined(OS_WIN) |
| 173 key_dict->SetString("mac", "Ctrl+Shift+M"); |
| 174 #else |
| 175 key_dict->SetString("windows", "Ctrl+Shift+W"); |
| 176 #endif |
| 177 EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error)); |
| 178 |
| 179 // Make sure Mac specific keys are not processed on other platforms. |
| 180 #if !defined(OS_MACOSX) |
| 181 key_dict->SetString("windows", "Command+Shift+M"); |
| 182 EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error)); |
| 183 key_dict->SetString("windows", "Options+Shift+M"); |
| 184 EXPECT_FALSE(command.Parse(input.get(), command_name, 0, &error)); |
| 185 #endif |
| 186 } |
| OLD | NEW |