From fb29c0ae53e32fb049516fcbe0f7863882ca9173 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Sat, 17 Sep 2022 00:50:54 -0700 Subject: [Core] Add getreuer's Autocorrect feature to core (#15699) Co-authored-by: Albert Y <76888457+filterpaper@users.noreply.github.com> --- tests/autocorrect/config.h | 6 + tests/autocorrect/test.mk | 8 ++ tests/autocorrect/test_autocorrect.cpp | 204 +++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 tests/autocorrect/config.h create mode 100644 tests/autocorrect/test.mk create mode 100644 tests/autocorrect/test_autocorrect.cpp (limited to 'tests') diff --git a/tests/autocorrect/config.h b/tests/autocorrect/config.h new file mode 100644 index 0000000000..b68bf0c2d5 --- /dev/null +++ b/tests/autocorrect/config.h @@ -0,0 +1,6 @@ +// Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "test_common.h" diff --git a/tests/autocorrect/test.mk b/tests/autocorrect/test.mk new file mode 100644 index 0000000000..7b97d8cce3 --- /dev/null +++ b/tests/autocorrect/test.mk @@ -0,0 +1,8 @@ +# Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) +# SPDX-License-Identifier: GPL-2.0-or-later + +# -------------------------------------------------------------------------------- +# Keep this file, even if it is empty, as a marker that this folder contains tests +# -------------------------------------------------------------------------------- + +AUTOCORRECT_ENABLE = yes diff --git a/tests/autocorrect/test_autocorrect.cpp b/tests/autocorrect/test_autocorrect.cpp new file mode 100644 index 0000000000..509c1c9ea4 --- /dev/null +++ b/tests/autocorrect/test_autocorrect.cpp @@ -0,0 +1,204 @@ +// Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "keycode.h" +#include "test_common.hpp" + +using ::testing::_; +using ::testing::AnyNumber; +using ::testing::InSequence; + +class AutoCorrect : public TestFixture { + public: + void SetUp() override { + autocorrect_enable(); + } + // Convenience function to tap `key`. + void TapKey(KeymapKey key) { + key.press(); + run_one_scan_loop(); + key.release(); + run_one_scan_loop(); + } + + // Taps in order each key in `keys`. + template + void TapKeys(Ts... keys) { + for (KeymapKey key : {keys...}) { + TapKey(key); + } + } +}; + +// Test that verifies enable/disable/toggling works +TEST_F(AutoCorrect, OnOffToggle) { + TestDriver driver; + + EXPECT_EQ(autocorrect_is_enabled(), true); + + autocorrect_disable(); + EXPECT_EQ(autocorrect_is_enabled(), false); + autocorrect_disable(); + EXPECT_EQ(autocorrect_is_enabled(), false); + + autocorrect_enable(); + EXPECT_EQ(autocorrect_is_enabled(), true); + autocorrect_enable(); + EXPECT_EQ(autocorrect_is_enabled(), true); + + autocorrect_toggle(); + EXPECT_EQ(autocorrect_is_enabled(), false); + autocorrect_toggle(); + EXPECT_EQ(autocorrect_is_enabled(), true); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +// Test that typing "fales" autocorrects to "false" +TEST_F(AutoCorrect, fales_to_false_autocorrection) { + TestDriver driver; + auto key_f = KeymapKey(0, 0, 0, KC_F); + auto key_a = KeymapKey(0, 1, 0, KC_A); + auto key_l = KeymapKey(0, 2, 0, KC_L); + auto key_e = KeymapKey(0, 3, 0, KC_E); + auto key_s = KeymapKey(0, 4, 0, KC_S); + + set_keymap({key_f, key_a, key_l, key_e, key_s}); + + // Allow any number of empty reports. + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(AnyNumber()); + { // Expect the following reports in this order. + InSequence s; + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_F))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_A))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_L))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_BACKSPACE))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_S))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))); + } + + TapKeys(key_f, key_a, key_l, key_e, key_s); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +// Test that typing "fales" doesn't autocorrect if disabled +TEST_F(AutoCorrect, fales_disabled_autocorrect) { + TestDriver driver; + auto key_f = KeymapKey(0, 0, 0, KC_F); + auto key_a = KeymapKey(0, 1, 0, KC_A); + auto key_l = KeymapKey(0, 2, 0, KC_L); + auto key_e = KeymapKey(0, 3, 0, KC_E); + auto key_s = KeymapKey(0, 4, 0, KC_S); + + set_keymap({key_f, key_a, key_l, key_e, key_s}); + + // Allow any number of empty reports. + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(AnyNumber()); + { // Expect the following reports in this order. + InSequence s; + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_F))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_A))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_L))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_S))); + } + + autocorrect_disable(); + TapKeys(key_f, key_a, key_l, key_e, key_s); + autocorrect_enable(); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +// Test that typing "falsify" doesn't autocorrect if disabled +TEST_F(AutoCorrect, falsify_should_not_autocorrect) { + TestDriver driver; + auto key_f = KeymapKey(0, 0, 0, KC_F); + auto key_a = KeymapKey(0, 1, 0, KC_A); + auto key_l = KeymapKey(0, 2, 0, KC_L); + auto key_s = KeymapKey(0, 3, 0, KC_S); + auto key_i = KeymapKey(0, 4, 0, KC_I); + auto key_y = KeymapKey(0, 5, 0, KC_Y); + + set_keymap({key_f, key_a, key_l, key_s, key_i, key_y}); + + // Allow any number of empty reports. + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(AnyNumber()); + { // Expect the following reports in this order. + InSequence s; + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_F))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_A))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_L))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_S))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_I))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_F))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_Y))); + } + + TapKeys(key_f, key_a, key_l, key_s, key_i, key_f, key_y); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +// Test that typing "ture" autocorrect to "true" +TEST_F(AutoCorrect, ture_to_true_autocorrect) { + TestDriver driver; + auto key_t_code = KeymapKey(0, 0, 0, KC_T); + auto key_r = KeymapKey(0, 1, 0, KC_R); + auto key_u = KeymapKey(0, 2, 0, KC_U); + auto key_e = KeymapKey(0, 3, 0, KC_E); + auto key_space = KeymapKey(0, 4, 0, KC_SPACE); + + set_keymap({key_t_code, key_r, key_u, key_e, key_space}); + + // Allow any number of empty reports. + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(AnyNumber()); + { // Expect the following reports in this order. + InSequence s; + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_SPACE))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_T))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_U))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_R))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_BACKSPACE))).Times(2); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_R))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_U))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))); + } + + TapKeys(key_space, key_t_code, key_u, key_r, key_e); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +// Test that typing "overture" does not autocorrect +TEST_F(AutoCorrect, overture_should_not_autocorrect) { + TestDriver driver; + auto key_t_code = KeymapKey(0, 0, 0, KC_T); + auto key_r = KeymapKey(0, 1, 0, KC_R); + auto key_u = KeymapKey(0, 2, 0, KC_U); + auto key_e = KeymapKey(0, 3, 0, KC_E); + auto key_o = KeymapKey(0, 4, 0, KC_O); + auto key_v = KeymapKey(0, 5, 0, KC_V); + + set_keymap({key_t_code, key_r, key_u, key_e, key_o, key_v}); + + // Allow any number of empty reports. + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(AnyNumber()); + { // Expect the following reports in this order. + InSequence s; + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_O))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_V))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_R))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_T))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_U))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_R))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_E))); + } + + TapKeys(key_o, key_v, key_e, key_r, key_t_code, key_u, key_r, key_e); + + testing::Mock::VerifyAndClearExpectations(&driver); +} -- cgit v1.2.3