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()