test_one_shot_keys.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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. osm_key.press();
  30. run_one_scan_loop();
  31. osm_key.release();
  32. run_one_scan_loop();
  33. VERIFY_AND_CLEAR(driver);
  34. /* OSM are added when an actual report is send */
  35. EXPECT_REPORT(driver, (osm_key.report_code));
  36. send_keyboard_report();
  37. VERIFY_AND_CLEAR(driver);
  38. /* Make unit-test pass */
  39. clear_oneshot_mods();
  40. }
  41. #if defined(ONESHOT_TIMEOUT)
  42. TEST_P(OneShotParametrizedTestFixture, OSMExpiredDoesNothing) {
  43. TestDriver driver;
  44. KeymapKey osm_key = GetParam().first;
  45. KeymapKey regular_key = GetParam().second;
  46. set_keymap({osm_key, regular_key});
  47. /* Press and release OSM */
  48. EXPECT_NO_REPORT(driver);
  49. osm_key.press();
  50. run_one_scan_loop();
  51. osm_key.release();
  52. idle_for(ONESHOT_TIMEOUT);
  53. VERIFY_AND_CLEAR(driver);
  54. /* Press regular key */
  55. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  56. regular_key.press();
  57. run_one_scan_loop();
  58. VERIFY_AND_CLEAR(driver);
  59. /* Release regular key */
  60. EXPECT_EMPTY_REPORT(driver);
  61. regular_key.release();
  62. run_one_scan_loop();
  63. VERIFY_AND_CLEAR(driver);
  64. }
  65. #endif
  66. TEST_P(OneShotParametrizedTestFixture, OSMWithAdditionalKeypress) {
  67. TestDriver driver;
  68. KeymapKey osm_key = GetParam().first;
  69. KeymapKey regular_key = GetParam().second;
  70. set_keymap({osm_key, regular_key});
  71. /* Press and release OSM */
  72. EXPECT_NO_REPORT(driver);
  73. osm_key.press();
  74. run_one_scan_loop();
  75. osm_key.release();
  76. run_one_scan_loop();
  77. VERIFY_AND_CLEAR(driver);
  78. /* Press regular key */
  79. EXPECT_REPORT(driver, (osm_key.report_code, regular_key.report_code)).Times(1);
  80. regular_key.press();
  81. run_one_scan_loop();
  82. VERIFY_AND_CLEAR(driver);
  83. /* Release regular key */
  84. EXPECT_EMPTY_REPORT(driver);
  85. regular_key.release();
  86. run_one_scan_loop();
  87. VERIFY_AND_CLEAR(driver);
  88. }
  89. TEST_P(OneShotParametrizedTestFixture, OSMAsRegularModifierWithAdditionalKeypress) {
  90. TestDriver driver;
  91. testing::InSequence s;
  92. KeymapKey osm_key = GetParam().first;
  93. KeymapKey regular_key = GetParam().second;
  94. set_keymap({osm_key, regular_key});
  95. /* Press OSM */
  96. EXPECT_NO_REPORT(driver);
  97. osm_key.press();
  98. run_one_scan_loop();
  99. VERIFY_AND_CLEAR(driver);
  100. /* Press regular key */
  101. EXPECT_NO_REPORT(driver);
  102. regular_key.press();
  103. run_one_scan_loop();
  104. VERIFY_AND_CLEAR(driver);
  105. /* Release regular key */
  106. EXPECT_NO_REPORT(driver);
  107. regular_key.release();
  108. run_one_scan_loop();
  109. VERIFY_AND_CLEAR(driver);
  110. /* Release OSM */
  111. EXPECT_REPORT(driver, (regular_key.report_code, osm_key.report_code)).Times(1);
  112. EXPECT_EMPTY_REPORT(driver);
  113. osm_key.release();
  114. run_one_scan_loop();
  115. VERIFY_AND_CLEAR(driver);
  116. }
  117. // clang-format off
  118. INSTANTIATE_TEST_CASE_P(
  119. OneShotModifierTests,
  120. OneShotParametrizedTestFixture,
  121. ::testing::Values(
  122. /* first is osm key, second is regular key. */
  123. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT}, KeymapKey{0, 1, 1, KC_A}),
  124. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LCTL), KC_LCTL}, KeymapKey{0, 1, 1, KC_A}),
  125. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LALT), KC_LALT}, KeymapKey{0, 1, 1, KC_A}),
  126. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LGUI), KC_LGUI}, KeymapKey{0, 1, 1, KC_A}),
  127. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RCTL), KC_RCTL}, KeymapKey{0, 1, 1, KC_A}),
  128. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RSFT), KC_RSFT}, KeymapKey{0, 1, 1, KC_A}),
  129. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RALT), KC_RALT}, KeymapKey{0, 1, 1, KC_A}),
  130. std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RGUI), KC_RGUI}, KeymapKey{0, 1, 1, KC_A})
  131. ));
  132. // clang-format on
  133. TEST_F(OneShot, OSMChainingTwoOSMs) {
  134. TestDriver driver;
  135. InSequence s;
  136. KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
  137. KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
  138. KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A};
  139. set_keymap({osm_key1, osm_key2, regular_key});
  140. /* Press and release OSM1 */
  141. EXPECT_NO_REPORT(driver);
  142. osm_key1.press();
  143. run_one_scan_loop();
  144. osm_key1.release();
  145. run_one_scan_loop();
  146. VERIFY_AND_CLEAR(driver);
  147. /* Press and relesea OSM2 */
  148. EXPECT_NO_REPORT(driver);
  149. osm_key2.press();
  150. run_one_scan_loop();
  151. osm_key2.release();
  152. run_one_scan_loop();
  153. VERIFY_AND_CLEAR(driver);
  154. /* Press regular key */
  155. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
  156. regular_key.press();
  157. run_one_scan_loop();
  158. VERIFY_AND_CLEAR(driver);
  159. /* Release regular key */
  160. EXPECT_EMPTY_REPORT(driver);
  161. regular_key.release();
  162. run_one_scan_loop();
  163. VERIFY_AND_CLEAR(driver);
  164. }
  165. TEST_F(OneShot, OSMDoubleTapNotLockingOSMs) {
  166. TestDriver driver;
  167. InSequence s;
  168. KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
  169. KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
  170. KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A};
  171. set_keymap({osm_key1, osm_key2, regular_key});
  172. /* Press and release OSM1 */
  173. EXPECT_NO_REPORT(driver);
  174. osm_key1.press();
  175. run_one_scan_loop();
  176. osm_key1.release();
  177. run_one_scan_loop();
  178. VERIFY_AND_CLEAR(driver);
  179. /* Press and release OSM2 twice */
  180. EXPECT_NO_REPORT(driver);
  181. osm_key2.press();
  182. run_one_scan_loop();
  183. osm_key2.release();
  184. run_one_scan_loop();
  185. osm_key2.press();
  186. run_one_scan_loop();
  187. osm_key2.release();
  188. run_one_scan_loop();
  189. VERIFY_AND_CLEAR(driver);
  190. /* Press regular key */
  191. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
  192. regular_key.press();
  193. run_one_scan_loop();
  194. VERIFY_AND_CLEAR(driver);
  195. /* Release regular key */
  196. EXPECT_EMPTY_REPORT(driver);
  197. regular_key.release();
  198. run_one_scan_loop();
  199. VERIFY_AND_CLEAR(driver);
  200. /* Press regular key */
  201. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  202. regular_key.press();
  203. run_one_scan_loop();
  204. VERIFY_AND_CLEAR(driver);
  205. /* Release regular key */
  206. EXPECT_EMPTY_REPORT(driver);
  207. regular_key.release();
  208. run_one_scan_loop();
  209. VERIFY_AND_CLEAR(driver);
  210. }
  211. TEST_F(OneShot, OSMHoldNotLockingOSMs) {
  212. TestDriver driver;
  213. InSequence s;
  214. KeymapKey osm_key1 = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
  215. KeymapKey osm_key2 = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
  216. KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A};
  217. set_keymap({osm_key1, osm_key2, regular_key});
  218. /* Press and release OSM1 */
  219. EXPECT_NO_REPORT(driver);
  220. osm_key1.press();
  221. run_one_scan_loop();
  222. osm_key1.release();
  223. run_one_scan_loop();
  224. VERIFY_AND_CLEAR(driver);
  225. /* Press and hold OSM2 */
  226. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code)).Times(1);
  227. osm_key2.press();
  228. run_one_scan_loop();
  229. idle_for(TAPPING_TERM);
  230. VERIFY_AND_CLEAR(driver);
  231. /* Press and release regular key */
  232. EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
  233. EXPECT_REPORT(driver, (osm_key2.report_code)).Times(1);
  234. regular_key.press();
  235. run_one_scan_loop();
  236. regular_key.release();
  237. run_one_scan_loop();
  238. VERIFY_AND_CLEAR(driver);
  239. /* Release OSM2 */
  240. EXPECT_EMPTY_REPORT(driver);
  241. osm_key2.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. regular_key.press();
  247. run_one_scan_loop();
  248. VERIFY_AND_CLEAR(driver);
  249. /* Release regular key */
  250. EXPECT_EMPTY_REPORT(driver);
  251. regular_key.release();
  252. run_one_scan_loop();
  253. VERIFY_AND_CLEAR(driver);
  254. }
  255. TEST_F(OneShot, OSLWithAdditionalKeypress) {
  256. TestDriver driver;
  257. InSequence s;
  258. KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
  259. KeymapKey regular_key = KeymapKey{1, 1, 0, KC_A};
  260. set_keymap({osl_key, regular_key});
  261. /* Press OSL key */
  262. EXPECT_NO_REPORT(driver);
  263. osl_key.press();
  264. run_one_scan_loop();
  265. VERIFY_AND_CLEAR(driver);
  266. /* Release OSL key */
  267. EXPECT_NO_REPORT(driver);
  268. osl_key.release();
  269. run_one_scan_loop();
  270. VERIFY_AND_CLEAR(driver);
  271. /* Press regular key */
  272. EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
  273. EXPECT_EMPTY_REPORT(driver);
  274. regular_key.press();
  275. run_one_scan_loop();
  276. VERIFY_AND_CLEAR(driver);
  277. /* Release regular key */
  278. EXPECT_NO_REPORT(driver);
  279. regular_key.release();
  280. run_one_scan_loop();
  281. VERIFY_AND_CLEAR(driver);
  282. }
  283. TEST_F(OneShot, OSLWithOsmAndAdditionalKeypress) {
  284. TestDriver driver;
  285. InSequence s;
  286. KeymapKey osl_key = KeymapKey{0, 0, 0, OSL(1)};
  287. KeymapKey osm_key = KeymapKey{1, 1, 0, OSM(MOD_LSFT), KC_LSFT};
  288. KeymapKey regular_key = KeymapKey{1, 1, 1, KC_A};
  289. set_keymap({osl_key, osm_key, regular_key});
  290. /* Press OSL key */
  291. EXPECT_NO_REPORT(driver);
  292. osl_key.press();
  293. run_one_scan_loop();
  294. VERIFY_AND_CLEAR(driver);
  295. /* Release OSL key */
  296. EXPECT_NO_REPORT(driver);
  297. osl_key.release();
  298. run_one_scan_loop();
  299. EXPECT_TRUE(layer_state_is(1));
  300. VERIFY_AND_CLEAR(driver);
  301. /* Press and release OSM */
  302. EXPECT_NO_REPORT(driver);
  303. osm_key.press();
  304. run_one_scan_loop();
  305. osm_key.release();
  306. run_one_scan_loop();
  307. EXPECT_TRUE(layer_state_is(1));
  308. VERIFY_AND_CLEAR(driver);
  309. /* Press regular key */
  310. EXPECT_REPORT(driver, (osm_key.report_code, regular_key.report_code)).Times(1);
  311. EXPECT_EMPTY_REPORT(driver);
  312. regular_key.press();
  313. run_one_scan_loop();
  314. EXPECT_FALSE(layer_state_is(1));
  315. VERIFY_AND_CLEAR(driver);
  316. /* Release regular key */
  317. EXPECT_NO_REPORT(driver);
  318. regular_key.release();
  319. run_one_scan_loop();
  320. VERIFY_AND_CLEAR(driver);
  321. }