Fix #279 once and for all (ha! ;)

This implements the proposal discussed in the re-opened #279 to add a
pin_factory argument at the device level and remove the ability to
specify a pin instance to device constructors (they now only accept a
pin specification).

Note: there's still a couple of bits to tidy up (tests on "real" Pis,
and pin_factory.release_all needs refinement) but the test suite is now
at least capable of passing on a PC.
This commit is contained in:
Dave Jones
2017-07-04 00:26:41 +01:00
parent 448feaf68f
commit c820636fcb
14 changed files with 396 additions and 403 deletions

View File

@@ -18,22 +18,21 @@ from gpiozero import *
def teardown_function(function):
Device.pin_factory.reset()
Device._reservations.clear()
def test_input_initial_values():
pin = Device.pin_factory.pin(4)
with InputDevice(pin, pull_up=True) as device:
with InputDevice(4, pull_up=True) as device:
assert pin.function == 'input'
assert pin.pull == 'up'
assert device.pull_up
with InputDevice(pin, pull_up=False) as device:
with InputDevice(4, pull_up=False) as device:
assert pin.pull == 'down'
assert not device.pull_up
def test_input_is_active_low():
pin = Device.pin_factory.pin(2)
with InputDevice(pin, pull_up=True) as device:
with InputDevice(2, pull_up=True) as device:
pin.drive_high()
assert not device.is_active
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO2, pull_up=True, is_active=False>'
@@ -43,7 +42,7 @@ def test_input_is_active_low():
def test_input_is_active_high():
pin = Device.pin_factory.pin(4)
with InputDevice(pin, pull_up=False) as device:
with InputDevice(4, pull_up=False) as device:
pin.drive_high()
assert device.is_active
assert repr(device) == '<gpiozero.InputDevice object on pin GPIO4, pull_up=False, is_active=True>'
@@ -54,12 +53,12 @@ def test_input_is_active_high():
def test_input_pulled_up():
pin = Device.pin_factory.pin(2)
with pytest.raises(PinFixedPull):
InputDevice(pin, pull_up=False)
InputDevice(2, pull_up=False)
def test_input_event_activated():
event = Event()
pin = Device.pin_factory.pin(4)
with DigitalInputDevice(pin) as device:
with DigitalInputDevice(4) as device:
device.when_activated = lambda: event.set()
assert not event.is_set()
pin.drive_high()
@@ -68,7 +67,7 @@ def test_input_event_activated():
def test_input_event_deactivated():
event = Event()
pin = Device.pin_factory.pin(4)
with DigitalInputDevice(pin) as device:
with DigitalInputDevice(4) as device:
device.when_deactivated = lambda: event.set()
assert not event.is_set()
pin.drive_high()
@@ -84,7 +83,7 @@ def test_input_partial_callback():
return a + b
bar = partial(foo, 1)
baz = partial(bar, 2)
with DigitalInputDevice(pin) as device:
with DigitalInputDevice(4) as device:
device.when_activated = baz
assert not event.is_set()
pin.drive_high()
@@ -92,20 +91,20 @@ def test_input_partial_callback():
def test_input_wait_active():
pin = Device.pin_factory.pin(4)
with DigitalInputDevice(pin) as device:
with DigitalInputDevice(4) as device:
pin.drive_high()
assert device.wait_for_active(1)
assert not device.wait_for_inactive(0)
def test_input_wait_inactive():
pin = Device.pin_factory.pin(4)
with DigitalInputDevice(pin) as device:
with DigitalInputDevice(4) as device:
assert device.wait_for_inactive(1)
assert not device.wait_for_active(0)
def test_input_smoothed_attrib():
pin = Device.pin_factory.pin(4)
with SmoothedInputDevice(pin, threshold=0.5, queue_len=5, partial=False) as device:
with SmoothedInputDevice(4, threshold=0.5, queue_len=5, partial=False) as device:
assert repr(device) == '<gpiozero.SmoothedInputDevice object on pin GPIO4, pull_up=False>'
assert device.threshold == 0.5
assert device.queue_len == 5
@@ -117,7 +116,7 @@ def test_input_smoothed_attrib():
def test_input_smoothed_values():
pin = Device.pin_factory.pin(4)
with SmoothedInputDevice(pin) as device:
with SmoothedInputDevice(4) as device:
device._queue.start()
assert not device.is_active
pin.drive_high()
@@ -127,7 +126,7 @@ def test_input_smoothed_values():
def test_input_button():
pin = Device.pin_factory.pin(2)
with Button(pin) as button:
with Button(2) as button:
assert pin.pull == 'up'
assert not button.is_pressed
pin.drive_low()
@@ -139,7 +138,7 @@ def test_input_button():
def test_input_line_sensor():
pin = Device.pin_factory.pin(4)
with LineSensor(pin) as sensor:
with LineSensor(4) as sensor:
pin.drive_low() # logic is inverted for line sensor
assert sensor.wait_for_line(1)
assert sensor.line_detected
@@ -149,7 +148,7 @@ def test_input_line_sensor():
def test_input_motion_sensor():
pin = Device.pin_factory.pin(4)
with MotionSensor(pin) as sensor:
with MotionSensor(4) as sensor:
pin.drive_high()
assert sensor.wait_for_motion(1)
assert sensor.motion_detected
@@ -161,7 +160,7 @@ def test_input_motion_sensor():
reason='timing is too random on pypy')
def test_input_light_sensor():
pin = Device.pin_factory.pin(4, pin_class=MockChargingPin)
with LightSensor(pin) as sensor:
with LightSensor(4) as sensor:
pin.charge_time = 0.1
assert sensor.wait_for_dark(1)
pin.charge_time = 0.0
@@ -173,10 +172,10 @@ def test_input_distance_sensor():
echo_pin = Device.pin_factory.pin(4)
trig_pin = Device.pin_factory.pin(5, pin_class=MockTriggerPin, echo_pin=echo_pin, echo_time=0.02)
with pytest.raises(ValueError):
DistanceSensor(echo_pin, trig_pin, max_distance=-1)
DistanceSensor(4, 5, max_distance=-1)
# normal queue len is large (because the sensor is *really* jittery) but
# we want quick tests and we've got precisely controlled pins :)
with DistanceSensor(echo_pin, trig_pin, queue_len=5, max_distance=1) as sensor:
with DistanceSensor(4, 5, queue_len=5, max_distance=1) as sensor:
assert sensor.max_distance == 1
assert sensor.trigger is trig_pin
assert sensor.echo is echo_pin