test_one_shot_keys.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. /* Copyright 2021 Stefan Kerkmann
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "action_util.h"
  17. #include "keyboard_report_util.hpp"
  18. #include "test_common.hpp"
  19. using testing::_;
  20. using testing::InSequence;
  21. class OneShot : public TestFixture {};
  22. class OneShotParametrizedTestFixture : public ::testing::WithParamInterface<std::pair<KeymapKey, KeymapKey>>, public OneShot {};
  23. TEST_F(OneShot, OSMWithoutAdditionalKeypressDoesNothing) {
  24. TestDriver driver;
  25. auto osm_key = KeymapKey(0, 0, 0, OSM(MOD_LSFT), KC_LSFT);
  26. set_keymap({osm_key});
  27. /* Press and release OSM key*/
  28. EXPECT_NO_REPORT(driver);
  29. tap_key(osm_key);
  30. VERIFY_AND_CLEAR(driver);
  31. /* OSM are added when an actual report is send */
  32. EXPECT_REPORT(driver, (osm_key.report_code));
  33. send_keyboard_report();
  34. VERIFY_AND_CLEAR(driver);
  35. /* Make unit-test pass */
  36. clear_oneshot_mods();
  37. }
  38. #if defined(ONESHOT_TIMEOUT)
  39. TEST_P(OneShotParametrizedTestFixture, OSMExpiredDoesNothing) {
  40. TestDriver driver;
  41. KeymapKey osm_key = GetParam().first;
  42. KeymapKey regular_key = GetParam().second;
  43. set_keymap({osm_key, regular_key});
  44. /* Press and release OSM */
  45. EXPECT_NO_REPORT(driver);
  46. osm_key.press();
  47. run_one_scan_loop();
  48. osm_key.release();
  49. idle_for(ONESHOT_TIMEOUT);
  50. VERIFY_AND_CLEAR(driver);
  51. /* Press regular key */
  52. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  53. regular_key.press();
  54. run_one_scan_loop();
  55. VERIFY_AND_CLEAR(driver);
  56. /* Release regular key */
  57. EXPECT_EMPTY_REPORT(driver);
  58. regular_key.release();
  59. run_one_scan_loop();
  60. VERIFY_AND_CLEAR(driver);
  61. }
  62. #endif
  63. TEST_P(OneShotParametrizedTestFixture, OSMWithAdditionalKeypress) {
  64. TestDriver driver;
  65. KeymapKey osm_key = GetParam().first;
  66. KeymapKey regular_key = GetParam().second;
  67. set_keymap({osm_key, regular_key});
  68. /* Press and release OSM */
  69. EXPECT_NO_REPORT(driver);
  70. tap_key(osm_key);
  71. VERIFY_AND_CLEAR(driver);
  72. /* Press regular key */
  73. EXPECT_REPORT(driver, (osm_key.report_code, regular_key.report_code)).Times(1);
  74. regular_key.press();
  75. run_one_scan_loop();
  76. VERIFY_AND_CLEAR(driver);
  77. /* Release regular key */
  78. EXPECT_EMPTY_REPORT(driver);
  79. regular_key.release();
  80. run_one_scan_loop();
  81. VERIFY_AND_CLEAR(driver);
  82. }
  83. TEST_P(OneShotParametrizedTestFixture, OSMAsRegularModifierWithAdditionalKeypress) {
  84. TestDriver driver;
  85. testing::InSequence s;
  86. KeymapKey osm_key = GetParam().first;
  87. KeymapKey regular_key = GetParam().second;
  88. set_keymap({osm_key, regular_key});
  89. /* Press OSM */
  90. EXPECT_NO_REPORT(driver);
  91. osm_key.press();
  92. run_one_scan_loop();
  93. VERIFY_AND_CLEAR(driver);
  94. /* Press regular key */
  95. EXPECT_NO_REPORT(driver);
  96. regular_key.press();
  97. run_one_scan_loop();
  98. VERIFY_AND_CLEAR(driver);
  99. /* Release regular key */
  100. EXPECT_NO_REPORT(driver);
  101. regular_key.release();
  102. run_one_scan_loop();
  103. VERIFY_AND_CLEAR(driver);
  104. /* Release OSM */
  105. EXPECT_REPORT(driver, (regular_key.report_code, osm_key.report_code)).Times(1);
  106. EXPECT_EMPTY_REPORT(driver);
  107. osm_key.release();
  108. run_one_scan_loop();
  109. VERIFY_AND_CLEAR(driver);
  110. }
  111. // clang-format off
  112. INSTANTIATE_TEST_CASE_P(
  113. OneShotModifierTests,
  114. OneShotParametrizedTestFixture,
  115. ::testing::Values(
  116. /* first is osm key, second is regular key. */
  117. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT}, KeymapKey{0, 1, 1, KC_A}),
  118. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LCTL), KC_LCTL}, KeymapKey{0, 1, 1, KC_A}),
  119. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LALT), KC_LALT}, KeymapKey{0, 1, 1, KC_A}),
  120. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LGUI), KC_LGUI}, KeymapKey{0, 1, 1, KC_A}),
  121. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RCTL), KC_RCTL}, KeymapKey{0, 1, 1, KC_A}),
  122. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RSFT), KC_RSFT}, KeymapKey{0, 1, 1, KC_A}),
  123. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RALT), KC_RALT}, KeymapKey{0, 1, 1, KC_A}),
  124. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RGUI), KC_RGUI}, KeymapKey{0, 1, 1, KC_A})
  125. ));
  126. // clang-format on
  127. TEST_F(OneShot, OSMChainingTwoOSMs) {
  128. TestDriver driver;
  129. InSequence s;
  130. KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
  131. KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
  132. KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A};
  133. set_keymap({osm_key1, osm_key2, regular_key});
  134. /* Press and release OSM1 */
  135. EXPECT_NO_REPORT(driver);
  136. tap_key(osm_key1);
  137. VERIFY_AND_CLEAR(driver);
  138. /* Press and relesea OSM2 */
  139. EXPECT_NO_REPORT(driver);
  140. tap_key(osm_key2);
  141. VERIFY_AND_CLEAR(driver);
  142. /* Press regular key */
  143. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
  144. regular_key.press();
  145. run_one_scan_loop();
  146. VERIFY_AND_CLEAR(driver);
  147. /* Release regular key */
  148. EXPECT_EMPTY_REPORT(driver);
  149. regular_key.release();
  150. run_one_scan_loop();
  151. VERIFY_AND_CLEAR(driver);
  152. }
  153. TEST_F(OneShot, OSMDoubleTapNotLockingOSMs) {
  154. TestDriver driver;
  155. InSequence s;
  156. KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
  157. KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
  158. KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A};
  159. set_keymap({osm_key1, osm_key2, regular_key});
  160. /* Press and release OSM1 */
  161. EXPECT_NO_REPORT(driver);
  162. tap_key(osm_key1);
  163. VERIFY_AND_CLEAR(driver);
  164. /* Press and release OSM2 twice */
  165. EXPECT_NO_REPORT(driver);
  166. tap_key(osm_key2);
  167. tap_key(osm_key2);
  168. VERIFY_AND_CLEAR(driver);
  169. /* Press regular key */
  170. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
  171. regular_key.press();
  172. run_one_scan_loop();
  173. VERIFY_AND_CLEAR(driver);
  174. /* Release regular key */
  175. EXPECT_EMPTY_REPORT(driver);
  176. regular_key.release();
  177. run_one_scan_loop();
  178. VERIFY_AND_CLEAR(driver);
  179. /* Press regular key */
  180. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  181. regular_key.press();
  182. run_one_scan_loop();
  183. VERIFY_AND_CLEAR(driver);
  184. /* Release regular key */
  185. EXPECT_EMPTY_REPORT(driver);
  186. regular_key.release();
  187. run_one_scan_loop();
  188. VERIFY_AND_CLEAR(driver);
  189. }
  190. TEST_F(OneShot, OSMHoldNotLockingOSMs) {
  191. TestDriver driver;
  192. InSequence s;
  193. KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
  194. KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
  195. KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A};
  196. set_keymap({osm_key1, osm_key2, regular_key});
  197. /* Press and release OSM1 */
  198. EXPECT_NO_REPORT(driver);
  199. tap_key(osm_key1);
  200. VERIFY_AND_CLEAR(driver);
  201. /* Press and hold OSM2 */
  202. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code)).Times(1);
  203. osm_key2.press();
  204. run_one_scan_loop();
  205. idle_for(TAPPING_TERM);
  206. VERIFY_AND_CLEAR(driver);
  207. /* Press and release regular key */
  208. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
  209. EXPECT_REPORT(driver, (osm_key2.report_code)).Times(1);
  210. tap_key(regular_key);
  211. VERIFY_AND_CLEAR(driver);
  212. /* Release OSM2 */
  213. EXPECT_EMPTY_REPORT(driver);
  214. osm_key2.release();
  215. run_one_scan_loop();
  216. VERIFY_AND_CLEAR(driver);
  217. /* Press regular key */
  218. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  219. regular_key.press();
  220. run_one_scan_loop();
  221. VERIFY_AND_CLEAR(driver);
  222. /* Release regular key */
  223. EXPECT_EMPTY_REPORT(driver);
  224. regular_key.release();
  225. run_one_scan_loop();
  226. VERIFY_AND_CLEAR(driver);
  227. }
  228. TEST_F(OneShot, OSLWithAdditionalKeypress) {
  229. TestDriver driver;
  230. InSequence s;
  231. KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
  232. KeymapKey regular_key = KeymapKey{1, 1, 0, KC_A};
  233. set_keymap({osl_key, regular_key});
  234. /* Press OSL key */
  235. EXPECT_NO_REPORT(driver);
  236. osl_key.press();
  237. run_one_scan_loop();
  238. VERIFY_AND_CLEAR(driver);
  239. /* Release OSL key */
  240. EXPECT_NO_REPORT(driver);
  241. osl_key.release();
  242. run_one_scan_loop();
  243. VERIFY_AND_CLEAR(driver);
  244. /* Press regular key */
  245. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  246. EXPECT_EMPTY_REPORT(driver);
  247. regular_key.press();
  248. run_one_scan_loop();
  249. VERIFY_AND_CLEAR(driver);
  250. /* Release regular key */
  251. EXPECT_NO_REPORT(driver);
  252. regular_key.release();
  253. run_one_scan_loop();
  254. VERIFY_AND_CLEAR(driver);
  255. }
  256. TEST_F(OneShot, OSLWithOsmAndAdditionalKeypress) {
  257. TestDriver driver;
  258. InSequence s;
  259. KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
  260. KeymapKey osm_key = KeymapKey{1, 1, 0, OSM(MOD_LSFT), KC_LSFT};
  261. KeymapKey regular_key = KeymapKey{1, 1, 1, KC_A};
  262. set_keymap({osl_key, osm_key, regular_key});
  263. /* Press OSL key */
  264. EXPECT_NO_REPORT(driver);
  265. osl_key.press();
  266. run_one_scan_loop();
  267. VERIFY_AND_CLEAR(driver);
  268. /* Release OSL key */
  269. EXPECT_NO_REPORT(driver);
  270. osl_key.release();
  271. run_one_scan_loop();
  272. EXPECT_TRUE(layer_state_is(1));
  273. VERIFY_AND_CLEAR(driver);
  274. /* Press and release OSM */
  275. EXPECT_NO_REPORT(driver);
  276. tap_key(osm_key);
  277. EXPECT_TRUE(layer_state_is(1));
  278. VERIFY_AND_CLEAR(driver);
  279. /* Press regular key */
  280. EXPECT_REPORT(driver, (osm_key.report_code, regular_key.report_code)).Times(1);
  281. EXPECT_EMPTY_REPORT(driver);
  282. regular_key.press();
  283. run_one_scan_loop();
  284. EXPECT_FALSE(layer_state_is(1));
  285. VERIFY_AND_CLEAR(driver);
  286. /* Release regular key */
  287. EXPECT_NO_REPORT(driver);
  288. regular_key.release();
  289. run_one_scan_loop();
  290. VERIFY_AND_CLEAR(driver);
  291. }