unified_retro_keyboard/firmware/asdf/test/test_asdf_repeat.c

449 lines
13 KiB
C

#include <stdio.h>
#include <stdint.h>
#include "unity.h"
#include "asdf_repeat.h"
#define REPEAT_TIMED_OUT 10000
#define NUM_REPETITIONS 10
uint32_t count_repeat_ticks(uint32_t timeout)
{
uint32_t count = 0;
uint32_t test;
do {
test = asdf_repeat();
count++;
} while (!test && count < timeout);
return count;
}
void setUp(void)
{
asdf_repeat_init();
}
void tearDown(void) {}
// On initialization, autorepeat should be enabled by default.
void test_asdf_repeat_init_resets_to_autorepeat_default(void)
{
uint32_t delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
// If autorepeat is turned off, then holding down a simulated key should not
// cause a repeat event.
void test_asdf_repeat_no_repeat_if_auto_turned_off(void)
{
uint32_t delay;
asdf_repeat_auto_off();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(REPEAT_TIMED_OUT, delay);
}
// If autorepeat is turned on, then holding down a simulated key should cause a
// repeat event after the autorepeat interval.
void test_asdf_repeat_autorepeat_if_auto_turned_on(void)
{
uint32_t delay;
asdf_repeat_auto_off();
asdf_repeat_auto_on();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
// After the autorepeat interval, subsequent repeat events should occur at the
// regular repeat interval.
void test_asf_repeat_autorepeat_fast_repeat_after_delay(void)
{
uint32_t delay;
// wait out the autorepeat delay
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
// now verify the next repeat interval is short:
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// If autorepeat is turned on, then holding down a key should cause a repeat
// event at the autorepeat interval. This should be true if autorepeat was
// previously off, or if it was already on, so test both cases here.
void test_asdf_repeat_auto_repeat_if_auto_turned_on(void)
{
uint32_t delay;
asdf_repeat_auto_on();
asdf_repeat_auto_on();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
asdf_repeat_auto_off();
asdf_repeat_auto_on();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
// When in autorepeat mode, calling asdf_repeat_reset_count() should reset the
// repeat timer to the autorepeat interval.
void test_asdf_repeat_reset_count_works_in_autorepeat_mode(void)
{
uint32_t delay;
// wait 1/2 of autorepeat time and release a key
delay = count_repeat_ticks(ASDF_AUTOREPEAT_TIME_MS / 2);
TEST_ASSERT_EQUAL_INT((ASDF_AUTOREPEAT_TIME_MS / 2), delay);
asdf_repeat_reset_count();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
// When in repeat mode (repeat key held down), calling asdf_repeat_reset_count()
// should reset the repeat timer to the repeat interval.
void test_asdf_repeat_reset_count_works_in_repeat_mode(void)
{
uint32_t delay;
// wait 1/2 of autorepeat time and release a key
asdf_repeat_activate();
delay = count_repeat_ticks(ASDF_REPEAT_TIME_MS / 2);
TEST_ASSERT_EQUAL_INT((ASDF_REPEAT_TIME_MS / 2), delay);
asdf_repeat_reset_count();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// When Autoreat is enabled, activating repeat mode (pressing the repeat key)
// should cause repeat events to occur at the fast repeat rate, skipping the
// autorepeat interval.
void test_asdf_repeat_activate_with_auto_on(void)
{
uint32_t delay;
asdf_repeat_auto_on();
asdf_repeat_activate();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// When Autoreat is off, activating repeat mode (pressing the repeat key)
// should cause repeat events to occur at the fast repeat rate
void test_asdf_repeat_activate_with_auto_off(void)
{
uint32_t delay;
asdf_repeat_auto_off();
asdf_repeat_activate();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// If autorepeat is disabled, then activating and deactivating repeat mode
// (pressing and releasing the repeat key) should return to the autorepeat
// disabled mode.
void test_asdf_repeat_deactivate_returns_to_baseline_no_repeat(void)
{
uint32_t delay;
asdf_repeat_auto_off();
// simulate a brief REPEAT key press (3 repeat cycles)
asdf_repeat_activate();
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
asdf_repeat_deactivate();
// now that repeat is deactivated, we should time out before hitting a repeat
// event:
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(REPEAT_TIMED_OUT, delay);
}
// If autorepeat is enabled, then activating and deactivating repeat mode
// (pressing and releasing the repeat key) should return to the autorepeat
// enabled mode.
void test_asdf_repeat_deactivate_returns_to_baseline_autorepeat(void)
{
uint32_t delay;
// simulate a brief REPEAT key press (1/2 autorepeat time)
asdf_repeat_activate();
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
asdf_repeat_deactivate();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
// When Autoreat is enabled, and the autorepeat timer is activated by holding
// down a key, then activating repeat (pressing the repeat key) should skip the
// rest of the autorepeat interval, and cause repeat events to occur at the fast
// repeat rate.
void test_asdf_repeat_repeat_key_circumvents_initial_autorepeat_delay(void)
{
uint32_t delay;
// simulate a brief keypress (1/2 autorepeat time)
delay = count_repeat_ticks(ASDF_AUTOREPEAT_TIME_MS / 2);
TEST_ASSERT_EQUAL_INT((ASDF_AUTOREPEAT_TIME_MS / 2), delay);
// simulate pressing the REPEAT key in the middle of an autorepeat interval
asdf_repeat_activate();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// If autorepeat is on, and a key is being held down to start the autorepeat
// interval, then turning off autorepeat mode should prevent the key from
// repeating.
void test_asdf_repeat_turning_off_auto_cancels_autorepeat_delay_in_progress(void)
{
uint32_t delay;
asdf_repeat_auto_on();
// simulate a brief keypress (1/2 autorepeat time)
delay = count_repeat_ticks(ASDF_AUTOREPEAT_TIME_MS / 2);
TEST_ASSERT_EQUAL_INT((ASDF_AUTOREPEAT_TIME_MS / 2), delay);
asdf_repeat_auto_off();
// simulate continued holding down key
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(REPEAT_TIMED_OUT, delay);
}
// If a key is autorepeating (held down until it repeats, without the repeat key
// being held down), then turning off autorepeat mode should stop the key from
// repeating.
void test_asdf_repeat_turning_off_auto_cancels_autorepeating_keypress(void)
{
uint32_t delay;
asdf_repeat_auto_on();
// simulate an autorepeating key. Wait out entire autorepeat delay.
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
// wait NUM_REPETITIONS repeat cycles:
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
asdf_repeat_auto_off();
for (delay = 0; !asdf_repeat() && (delay < REPEAT_TIMED_OUT); delay++) {
}
TEST_ASSERT_EQUAL_INT(REPEAT_TIMED_OUT, delay);
}
// If you press the REPEAT key while a key is already autorepeating (i.e., after
// the autorepeat delay interval), then the repeat timing shall not be affected.
void test_asdf_repeat_activate_while_autorepeating_wont_affect_timing(void)
{
uint32_t delay;
asdf_repeat_auto_on();
// simulate an autorepeating key. Wait out entire autorepeat delay.
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
// wait 1/2 fast repeat cycle:
// simulate an autorepeating key. Wait out entire autorepeat delay.
delay = count_repeat_ticks(ASDF_REPEAT_TIME_MS / 2);
TEST_ASSERT_EQUAL_INT((ASDF_REPEAT_TIME_MS / 2), delay);
// turn on repeat mode (press REPEAT key)
asdf_repeat_activate();
// now verify the repeat interval was not affected. Finish the current repeat
// interval
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// If in autorepeat mode and the repeat key is released while a key is
// repeating, the next repeat event should occur after a new autorepeat delay
// interval.
void test_asdf_repeat_deactivate_while_repeating_resets_autorepeat_counter(void)
{
uint32_t delay;
asdf_repeat_auto_on();
asdf_repeat_activate();
// wait NUM_REPETITIONS repeat cycles:
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
// releast REPEAT key:
asdf_repeat_deactivate();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
// should have waited entire autorepeat delay interval
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
// If autorepeat is disabled and the repeat key is released while a key is
// repeating, then the key should stop repeating.
void test_asdf_repeat_deactivate_while_repeating_stops_repeating(void)
{
uint32_t delay;
asdf_repeat_auto_off();
asdf_repeat_activate();
// wait NUM_REPETITIONS repeat cycles:
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
// releast REPEAT key:
asdf_repeat_deactivate();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
// should have waited entire autorepeat delay interval
TEST_ASSERT_EQUAL_INT(REPEAT_TIMED_OUT, delay);
}
// pressing a new value key when REPEAT is active should start repeating right
// away.
void test_asdf_repeat_new_key_while_repeat_active_keeps_repeating(void)
{
uint32_t delay;
asdf_repeat_activate();
// wait NUM_REPETITIONS repeat cycles:
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
// simulate half a repeat interval
delay = count_repeat_ticks(ASDF_REPEAT_TIME_MS / 2);
// simulate a new key press:
asdf_repeat_reset_count();
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
// should have waited the key repeat interval
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS, delay);
}
// pressing a new value key when autorepeating should start new autorepeat
// delay.
void test_asdf_repeat_new_key_while_autorepeating_starts_new_autorepeat(void)
{
uint32_t delay;
asdf_repeat_auto_on();
// simulate an autorepeating key. Wait out entire autorepeat delay.
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
// wait NUM_REPETITIONS repeat cycles:
delay = 0;
for (uint32_t i = 0; i < NUM_REPETITIONS; i++) {
delay += count_repeat_ticks(REPEAT_TIMED_OUT);
}
TEST_ASSERT_EQUAL_INT(ASDF_REPEAT_TIME_MS * NUM_REPETITIONS, delay);
// simulate new keypress:
asdf_repeat_reset_count();
// now measure interval until next repeat event.
delay = count_repeat_ticks(REPEAT_TIMED_OUT);
TEST_ASSERT_EQUAL_INT(ASDF_AUTOREPEAT_TIME_MS, delay);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_asdf_repeat_init_resets_to_autorepeat_default);
RUN_TEST(test_asdf_repeat_no_repeat_if_auto_turned_off);
RUN_TEST(test_asdf_repeat_auto_repeat_if_auto_turned_on);
RUN_TEST(test_asf_repeat_autorepeat_fast_repeat_after_delay);
RUN_TEST(test_asdf_repeat_reset_count_works_in_autorepeat_mode);
RUN_TEST(test_asdf_repeat_reset_count_works_in_repeat_mode);
RUN_TEST(test_asdf_repeat_activate_with_auto_on);
RUN_TEST(test_asdf_repeat_activate_with_auto_off);
RUN_TEST(test_asdf_repeat_deactivate_returns_to_baseline_autorepeat);
RUN_TEST(test_asdf_repeat_deactivate_returns_to_baseline_no_repeat);
RUN_TEST(test_asdf_repeat_repeat_key_circumvents_initial_autorepeat_delay);
RUN_TEST(test_asdf_repeat_activate_while_autorepeating_wont_affect_timing);
RUN_TEST(test_asdf_repeat_turning_off_auto_cancels_autorepeating_keypress);
RUN_TEST(test_asdf_repeat_turning_off_auto_cancels_autorepeat_delay_in_progress);
RUN_TEST(test_asdf_repeat_deactivate_while_repeating_resets_autorepeat_counter);
RUN_TEST(test_asdf_repeat_deactivate_while_repeating_stops_repeating);
RUN_TEST(test_asdf_repeat_new_key_while_repeat_active_keeps_repeating);
RUN_TEST(test_asdf_repeat_new_key_while_autorepeating_starts_new_autorepeat);
return UNITY_END();
}