mirror of
https://github.com/jaksatomovic/esp32-clickwheel.git
synced 2025-07-04 11:07:12 -04:00
499 lines
13 KiB
C++
499 lines
13 KiB
C++
#line 2 "Button2Test.ino"
|
|
/////////////////////////////////////////////////////////////////
|
|
/*
|
|
Unit tests for Button2 library.
|
|
Arduino Library to simplify working with buttons.
|
|
|
|
Created by Lennart Hennigs
|
|
Tested on Wemos D1 Mini, M5Stack ESP32, Arduino UNO
|
|
*/
|
|
/////////////////////////////////////////////////////////////////
|
|
/*
|
|
To add:
|
|
- check retriggerable long-clicks (setLongClickDetectedRetriggerable getLongClickCount())
|
|
- check loop functions (read(), wait(), waitForClick(), waitForDouble(), waitForTriple())
|
|
- check custom handler
|
|
*/
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
#include "AUnitVerbose.h"
|
|
// #include "AUnit.h"
|
|
#include "Button2.h"
|
|
|
|
using namespace aunit;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
#define SERIAL_SPEED 115200
|
|
|
|
#define VERBOSE_CHANGED false
|
|
#define VERBOSE_PRESS_RELEASE false
|
|
#define VERBOSE_MAIN_EVENTS false // clicks, long presses
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
#define BUTTON_PIN 37
|
|
#define BUTTON_MODE INPUT_PULLUP
|
|
#define BUTTON_ACTIVE LOW
|
|
|
|
#define DEBOUNCE_MS BTN_DEBOUNCE_MS + 5
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
MockHardware hw;
|
|
Button2 button;
|
|
|
|
bool pressed = false;
|
|
bool released = false;
|
|
bool tap = false;
|
|
bool longclick = false;
|
|
bool long_detected = false;
|
|
int long_detected_count = 0;
|
|
bool changed = false;
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void setup_test_runner() {
|
|
TestRunner::setVerbosity(Verbosity::kDefault);
|
|
// TestRunner::setVerbosity(Verbosity::kAssertionFailed);
|
|
// TestRunner::setVerbosityVerbosity::kAll);
|
|
|
|
TestRunner::list();
|
|
/*
|
|
TestRunner::exclude("*");
|
|
// TestRunner::include("basics_*");
|
|
// TestRunner::include("defaults_*");
|
|
// TestRunner::include("settings_*");
|
|
// TestRunner::include("clicks_*");
|
|
// TestRunner::include("other_*");
|
|
*/
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// helper functions
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
// pressing the button
|
|
void press() {
|
|
hw.digitalWrite(BUTTON_PIN, BUTTON_ACTIVE);
|
|
button.loop();
|
|
}
|
|
|
|
// letting it go
|
|
void release() {
|
|
hw.digitalWrite(BUTTON_PIN, !BUTTON_ACTIVE);
|
|
button.loop();
|
|
}
|
|
|
|
// emulate a button click
|
|
void click(unsigned long duration) {
|
|
press();
|
|
delay(duration);
|
|
button.loop();
|
|
release();
|
|
}
|
|
|
|
// resets all handler vars
|
|
void resetHandlerVars() {
|
|
pressed = false;
|
|
released = false;
|
|
tap = false;
|
|
longclick = false;
|
|
long_detected = false;
|
|
changed = false;
|
|
long_detected_count = 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BASICS
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(basics, loop) {
|
|
resetHandlerVars();
|
|
button.resetPressedState();
|
|
// press the button down
|
|
hw.digitalWrite(BUTTON_PIN, BUTTON_ACTIVE);
|
|
button.loop();
|
|
// wait a while
|
|
delay(DEBOUNCE_MS);
|
|
// is there an update without the loop?
|
|
assertFalse(pressed);
|
|
// there should be one now
|
|
button.loop();
|
|
assertTrue(pressed);
|
|
|
|
// release the button
|
|
hw.digitalWrite(BUTTON_PIN, !BUTTON_ACTIVE);
|
|
// wait a while
|
|
delay(DEBOUNCE_MS);
|
|
// is there an update without the loop?
|
|
assertFalse(released);
|
|
// there should be one now
|
|
button.loop();
|
|
assertTrue(released);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(basics, equal_operator) {
|
|
Button2 b;
|
|
assertTrue(button == button);
|
|
assertTrue(b == b);
|
|
assertFalse(button == b);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// BASICS
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, changed_handler) {
|
|
button.resetPressedState();
|
|
changed = false;
|
|
|
|
press();
|
|
// wait a bit
|
|
delay(DEBOUNCE_MS);
|
|
button.loop();
|
|
// test
|
|
assertTrue(changed);
|
|
changed = false;
|
|
// let go
|
|
release();
|
|
// test
|
|
assertTrue(changed);
|
|
// clean up
|
|
changed = false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, is_not_pressed) {
|
|
release();
|
|
button.resetPressedState();
|
|
// run the tests
|
|
assertFalse(button.isPressed());
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, is_pressed) {
|
|
release();
|
|
button.resetPressedState();
|
|
press();
|
|
// wait a bit
|
|
delay(DEBOUNCE_MS);
|
|
button.loop();
|
|
// test
|
|
assertTrue(button.isPressed());
|
|
assertTrue(pressed);
|
|
release();
|
|
// clean up
|
|
pressed = false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, is_pressed_raw) {
|
|
button.resetPressedState();
|
|
press();
|
|
// wait a bit
|
|
delay(BTN_DEBOUNCE_MS);
|
|
button.loop();
|
|
// test
|
|
assertTrue(button.isPressedRaw());
|
|
release();
|
|
// clean up
|
|
assertFalse(button.isPressedRaw());
|
|
pressed = false;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, not_a_click) {
|
|
resetHandlerVars();
|
|
button.resetPressedState();
|
|
// click, but too short
|
|
click(BTN_DEBOUNCE_MS - 10);
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
// run the tests
|
|
assertFalse(button.wasPressed());
|
|
assertFalse(tap);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, single_click) {
|
|
resetHandlerVars();
|
|
button.resetPressedState();
|
|
// click
|
|
int time = DEBOUNCE_MS;
|
|
click(time);
|
|
// wait out the double click time
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
int pressedFor = button.wasPressedFor();
|
|
// run the tests
|
|
assertTrue(button.wasPressed());
|
|
assertNear(time, pressedFor, 10);
|
|
assertEqual(button.getType(), single_click);
|
|
assertEqual(button.getNumberOfClicks(), 1);
|
|
assertTrue(tap);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, long_click) {
|
|
resetHandlerVars();
|
|
button.resetPressedState();
|
|
// long click
|
|
int time = BTN_LONGCLICK_MS + 10;
|
|
click(time);
|
|
// wait out the double click time
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
int pressedFor = button.wasPressedFor();
|
|
// run the tests
|
|
assertTrue(button.wasPressed());
|
|
assertNear(time, pressedFor, 10);
|
|
assertEqual(button.getType(), long_click);
|
|
assertEqual(button.getNumberOfClicks(), 1);
|
|
assertTrue(long_detected);
|
|
assertTrue(longclick);
|
|
assertTrue(tap);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, double_click) {
|
|
button.resetPressedState();
|
|
// 2x click
|
|
int time = DEBOUNCE_MS;
|
|
click(time);
|
|
click(time);
|
|
// wait out the double click time
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
// run the tests
|
|
assertTrue(button.wasPressed());
|
|
assertEqual(button.getType(), double_click);
|
|
assertEqual(button.getNumberOfClicks(), 2);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, triple_click) {
|
|
button.resetPressedState();
|
|
// 3x click
|
|
int time = DEBOUNCE_MS;
|
|
click(time);
|
|
click(time);
|
|
click(time);
|
|
// wait out the double click time
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
// run the tests
|
|
assertTrue(button.wasPressed());
|
|
assertEqual(button.getType(), triple_click);
|
|
assertEqual(button.getNumberOfClicks(), 3);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(clicks, more_than_3_click) {
|
|
button.resetPressedState();
|
|
// 4x click
|
|
int time = DEBOUNCE_MS;
|
|
click(time);
|
|
click(time);
|
|
click(time);
|
|
click(time);
|
|
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
// run the tests
|
|
assertTrue(button.wasPressed());
|
|
assertEqual(button.getType(), triple_click);
|
|
assertEqual(button.getNumberOfClicks(), 4);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test (clicks, reset) {
|
|
button.resetPressedState();
|
|
// single click
|
|
int time = DEBOUNCE_MS;
|
|
click(time);
|
|
// wait out the double click time
|
|
delay(BTN_DOUBLECLICK_MS);
|
|
button.loop();
|
|
// run the tests
|
|
assertTrue(button.wasPressed());
|
|
assertEqual(button.getNumberOfClicks(), 1);
|
|
// now reset the "click memory"
|
|
button.resetPressedState();
|
|
assertFalse(button.wasPressed());
|
|
assertEqual(button.getNumberOfClicks(), 0);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// DEFAULTS
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(defaults, doubleclick_time) {
|
|
assertEqual(button.getDoubleClickTime(), BTN_DOUBLECLICK_MS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(defaults, debounce_time) {
|
|
assertEqual(button.getDebounceTime(), BTN_DEBOUNCE_MS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(defaults, longclick_time) {
|
|
assertEqual(button.getLongClickTime(), BTN_LONGCLICK_MS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(defaults, id) {
|
|
assertTrue(button.getID() == 0);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(defaults, pin) {
|
|
assertTrue(button.getPin() == BUTTON_PIN);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// SETTING
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(settings, id) {
|
|
int id = 10;
|
|
button.setID(id);
|
|
// run the tests
|
|
assertTrue(button.getID() == id);
|
|
// clean up
|
|
button.setID(0);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(settings, additional_ids) {
|
|
Button2 b;
|
|
assertNotEqual(b.getID(), button.getID());
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(settings, doubleclick_time) {
|
|
unsigned int dc_time = BTN_DOUBLECLICK_MS + 1;
|
|
button.setDoubleClickTime(dc_time);
|
|
// run the tests
|
|
assertEqual(button.getDoubleClickTime(), dc_time);
|
|
// clean up
|
|
button.setDoubleClickTime(BTN_DOUBLECLICK_MS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(settings, longclick_time) {
|
|
unsigned int lc_time = BTN_LONGCLICK_MS + 1;
|
|
button.setLongClickTime(lc_time);
|
|
// run the tests
|
|
assertEqual(button.getLongClickTime(), lc_time);
|
|
// clean up
|
|
button.setLongClickTime(BTN_LONGCLICK_MS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(settings, debounce_time) {
|
|
unsigned int debounce_time = BTN_DEBOUNCE_MS + 1;
|
|
button.setDebounceTime(debounce_time);
|
|
// run the tests
|
|
assertEqual(button.getDebounceTime(), debounce_time);
|
|
// clean up
|
|
button.setDebounceTime(BTN_DEBOUNCE_MS);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// OTHER
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
test(other, to_string) {
|
|
assertStringCaseEqual(button.clickToString(clickType::single_click), String("single click"));
|
|
assertStringCaseEqual(button.clickToString(clickType::double_click), String("double click"));
|
|
assertStringCaseEqual(button.clickToString(clickType::triple_click), String("triple click"));
|
|
assertStringCaseEqual(button.clickToString(clickType::long_click), String("long click"));
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
// ignore unused params in the lamda functions
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void setup() {
|
|
setup_test_runner();
|
|
|
|
// setup serial
|
|
delay(1000);
|
|
Serial.begin(SERIAL_SPEED);
|
|
while(!Serial) {}
|
|
Serial.println(F("\n\nButton2 Unit Tests"));
|
|
// set up button
|
|
button.begin(BUTTON_PIN, BUTTON_MODE, BUTTON_ACTIVE == LOW, &hw);
|
|
|
|
button.setPressedHandler([](Button2& b) {
|
|
if (VERBOSE_PRESS_RELEASE) Serial.println(F("-- PRESSED"));
|
|
released = false;
|
|
pressed = true;
|
|
});
|
|
button.setReleasedHandler([](Button2& b) {
|
|
if (VERBOSE_PRESS_RELEASE) Serial.println(F("-- RELEASED"));
|
|
released = true;
|
|
pressed = false;
|
|
tap = true;
|
|
});
|
|
button.setChangedHandler([](Button2& b) {
|
|
if (VERBOSE_CHANGED) Serial.println(F("-- CHANGED"));
|
|
changed = true;
|
|
});
|
|
button.setClickHandler([](Button2& b) {
|
|
if (VERBOSE_MAIN_EVENTS) Serial.println(F(" -- CLICK"));
|
|
});
|
|
button.setLongClickHandler([](Button2& b) {
|
|
if (VERBOSE_MAIN_EVENTS) Serial.println(F(" -- LONG"));
|
|
longclick = true;
|
|
});
|
|
button.setLongClickDetectedHandler([](Button2& b) {
|
|
if (VERBOSE_MAIN_EVENTS) Serial.println(" -- LONG DETECTED");
|
|
long_detected = true;
|
|
long_detected_count = long_detected_count + 1;
|
|
});
|
|
button.setDoubleClickHandler([](Button2& b) {
|
|
if (VERBOSE_MAIN_EVENTS) Serial.println(" -- DOUBLE");
|
|
});
|
|
button.setTripleClickHandler([](Button2& b) {
|
|
if (VERBOSE_MAIN_EVENTS) Serial.println(" -- TRIPLE ");
|
|
});
|
|
}
|
|
#pragma GCC diagnostic push
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
|
|
void loop() {
|
|
button.loop();
|
|
aunit::TestRunner::run();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|