/ tests / tests.py
tests.py
  1  """
  2  How to use this test file:
  3  
  4  Copy adafruit_debouncer's dependencies to lib/ on your circuitpython device.
  5  Copy adafruit_debouncer.py to / on the device
  6  Copy this tests.py file to /main.py on the device
  7  Connect to the serial terminal (e.g. sudo screen /dev/ttyACM0 115200)
  8  Press Ctrl-D, if needed to start the tests running
  9  """
 10  import sys
 11  import time
 12  import adafruit_debouncer
 13  
 14  
 15  def _true():
 16      return True
 17  
 18  
 19  def _false():
 20      return False
 21  
 22  
 23  def assertEqual(a, b):
 24      assert a == b, "Want %r, got %r" % (a, b)
 25  
 26  
 27  def test_back_and_forth():
 28      # Start false
 29      db = adafruit_debouncer.Debouncer(_false)
 30      assertEqual(db.value, False)
 31  
 32      # Set the raw state to true, update, and make sure the debounced
 33      # state has not changed yet:
 34      db.function = _true
 35      db.update()
 36      assertEqual(db.value, False)
 37      assert not db.last_duration, "There was no previous interval??"
 38  
 39      # Sleep longer than the debounce interval, so state can change:
 40      time.sleep(0.02)
 41      db.update()
 42      assert db.last_duration  # is actually duration between powerup and now
 43      assertEqual(db.value, True)
 44      assertEqual(db.rose, True)
 45      assertEqual(db.fell, False)
 46      # Duration since last change has only been long enough to run these
 47      # asserts, which should be well under 1/10 second
 48      assert db.current_duration < 0.1, "Unit error? %d" % db.current_duration
 49  
 50      # Set raw state back to false, make sure it's not instantly reflected,
 51      # then wait and make sure it IS reflected after the interval has passed.
 52      db.function = _false
 53      db.update()
 54      assertEqual(db.value, True)
 55      assertEqual(db.fell, False)
 56      assertEqual(db.rose, False)
 57      time.sleep(0.02)
 58      assert 0.019 < db.current_duration <= 1, (
 59          "Unit error? sleep .02 -> duration %d" % db.current_duration
 60      )
 61      db.update()
 62      assertEqual(db.value, False)
 63      assertEqual(db.rose, False)
 64      assertEqual(db.fell, True)
 65  
 66      assert 0 < db.current_duration <= 0.1, (
 67          "Unit error? time to run asserts %d" % db.current_duration
 68      )
 69      assert 0 < db.last_duration < 0.1, (
 70          "Unit error? Last dur should be ~.02, is %d" % db.last_duration
 71      )
 72  
 73  
 74  def test_interval_is_the_same():
 75      db = adafruit_debouncer.Debouncer(_false, interval=0.25)
 76      assertEqual(db.value, False)
 77      db.update()
 78      db.function = _true
 79      db.update()
 80  
 81      time.sleep(0.1)  # longer than default interval
 82      db.update()
 83      assertEqual(db.value, False)
 84  
 85      time.sleep(0.2)  # 0.1 + 0.2 > 0.25
 86      db.update()
 87      assertEqual(db.value, True)
 88      assertEqual(db.rose, True)
 89      assertEqual(db.interval, 0.25)
 90  
 91  
 92  def test_setting_interval():
 93      # Check that setting the interval does change the time the debouncer waits
 94      db = adafruit_debouncer.Debouncer(_false, interval=0.01)
 95      db.update()
 96  
 97      # set the interval to a longer time, sleep for a time between
 98      # the two interval settings, and assert that the value hasn't changed.
 99  
100      db.function = _true
101      db.interval = 0.2
102      db.update()
103      assert db.interval - 0.2 < 0.00001, "interval is not consistent"
104      time.sleep(0.11)
105      db.update()
106  
107      assertEqual(db.value, False)
108      assertEqual(db.rose, False)
109      assertEqual(db.fell, False)
110  
111      # and then once the whole time has passed make sure it did change
112      time.sleep(0.11)
113      db.update()
114      assertEqual(db.value, True)
115      assertEqual(db.rose, True)
116      assertEqual(db.fell, False)
117  
118  
119  def run():
120      passes = 0
121      fails = 0
122      for name, test in locals().items():
123          if name.startswith("test_") and callable(test):
124              try:
125                  print()
126                  print(name)
127                  test()
128                  print("PASS")
129                  passes += 1
130              except Exception as e:
131                  sys.print_exception(e)
132                  print("FAIL")
133                  fails += 1
134  
135      print(passes, "passed,", fails, "failed")
136      if passes and not fails:
137          print(
138              r"""
139   ________
140  < YATTA! >
141   --------
142          \   ^__^
143           \  (oo)\_______
144              (__)\       )\/\
145                  ||----w |
146                  ||     ||"""
147          )
148  
149  
150  if __name__ == "__main__":
151      run()