Add debouncer to y2018 superstructure
Change-Id: Id53ded166c5fc918357ec37d3e79fdc57ba71e1b
diff --git a/y2018/control_loops/superstructure/debouncer_test.cc b/y2018/control_loops/superstructure/debouncer_test.cc
new file mode 100644
index 0000000..2f56d56
--- /dev/null
+++ b/y2018/control_loops/superstructure/debouncer_test.cc
@@ -0,0 +1,59 @@
+#include "y2018/control_loops/superstructure/debouncer.h"
+
+#include "gtest/gtest.h"
+
+namespace y2018 {
+namespace control_loops {
+namespace superstructure {
+namespace testing {
+
+// Tests that the debouncer behaves as it should. This tests the following:
+// - The debouncer changes its internal state after the desired number of
+// repeated inputs.
+// - The debouncer doesn't change its internal state before the desired number
+// of repeated inputs.
+TEST(DebouncerTest, Debouncer) {
+ Debouncer bouncer(false, 2);
+
+ bouncer.Update(true);
+ bouncer.Update(true);
+ EXPECT_EQ(true, bouncer.current_state());
+
+ bouncer.Update(false);
+
+ // Only one false, state shouldn't have changed.
+ EXPECT_EQ(true, bouncer.current_state());
+
+ bouncer.Update(false);
+ // Now there are two falses in a row, the state should've changed.
+ EXPECT_EQ(false, bouncer.current_state());
+}
+
+// Test that the debouncer will hold its state through a short-lived state
+// change.
+TEST(DebouncerTest, DebouncerLongSequence) {
+ Debouncer bouncer(false, 2);
+
+ bouncer.Update(true);
+
+ // Only one true, should still read false.
+ EXPECT_EQ(false, bouncer.current_state());
+
+ bouncer.Update(true);
+
+ // Two trues, should now read true.
+ EXPECT_EQ(true, bouncer.current_state());
+
+ bouncer.Update(false);
+
+ // Only one false, should still read true.
+ EXPECT_EQ(true, bouncer.current_state());
+
+ bouncer.Update(true);
+
+ EXPECT_EQ(true, bouncer.current_state());
+}
+} // namespace testing
+} // namespace superstructure
+} // namespace control_loops
+} // namespace y2018