diff options
author | Cody Hiar <codyfh@gmail.com> | 2018-05-27 15:29:21 -0600 |
---|---|---|
committer | Cody Hiar <codyfh@gmail.com> | 2018-05-27 15:29:21 -0600 |
commit | ceec171c42bd79f1762b971569e20ead656f4fd0 (patch) | |
tree | 1880be0b1cef9786be5bc818cbd50095cd797a6d /lib/Adafruit_Python_GPIO/tests | |
parent | 611a8b7be4331e4f8416c4d10a0be47a109b47e4 (diff) |
Moving libs into separate own directory
Diffstat (limited to 'lib/Adafruit_Python_GPIO/tests')
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/MockGPIO.py | 40 | ||||
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/__init__.py | 0 | ||||
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/test_GPIO.py | 228 | ||||
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/test_I2C.py | 181 | ||||
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/test_PWM.py | 103 | ||||
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/test_Platform.py | 70 | ||||
-rw-r--r-- | lib/Adafruit_Python_GPIO/tests/test_SPI.py | 192 |
7 files changed, 814 insertions, 0 deletions
diff --git a/lib/Adafruit_Python_GPIO/tests/MockGPIO.py b/lib/Adafruit_Python_GPIO/tests/MockGPIO.py new file mode 100644 index 0000000..d3dce13 --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/MockGPIO.py @@ -0,0 +1,40 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import Adafruit_GPIO as GPIO + + +class MockGPIO(GPIO.BaseGPIO): + def __init__(self): + self.pin_mode = {} + self.pin_written = {} + self.pin_read = {} + + def setup(self, pin, mode): + self.pin_mode[pin] = mode + + def output(self, pin, bit): + self.pin_written.setdefault(pin, []).append(1 if bit else 0) + + def input(self, pin): + if pin not in self.pin_read: + raise RuntimeError('No mock GPIO data to read for pin {0}'.format(pin)) + return self.pin_read[pin].pop(0) == 1 diff --git a/lib/Adafruit_Python_GPIO/tests/__init__.py b/lib/Adafruit_Python_GPIO/tests/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/__init__.py diff --git a/lib/Adafruit_Python_GPIO/tests/test_GPIO.py b/lib/Adafruit_Python_GPIO/tests/test_GPIO.py new file mode 100644 index 0000000..24c51a6 --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/test_GPIO.py @@ -0,0 +1,228 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import unittest + +from mock import Mock, patch + +import Adafruit_GPIO as GPIO +import Adafruit_GPIO.SPI as SPI +import Adafruit_GPIO.Platform as Platform + +from MockGPIO import MockGPIO + + +class TestBaseGPIO(unittest.TestCase): + def test_set_high_and_set_low(self): + gpio = MockGPIO() + gpio.set_high(1) + gpio.set_low(1) + self.assertDictEqual(gpio.pin_written, {1: [1, 0]}) + + def test_is_high_and_is_low(self): + gpio = MockGPIO() + gpio.pin_read[1] = [0, 0, 1, 1] + self.assertTrue(gpio.is_low(1)) + self.assertFalse(gpio.is_high(1)) + self.assertFalse(gpio.is_low(1)) + self.assertTrue(gpio.is_high(1)) + + def test_output_pins(self): + gpio = MockGPIO() + gpio.output_pins({0: True, 1: False, 7: True}) + self.assertDictEqual(gpio.pin_written, {0: [1], 1: [0], 7: [1]}) + + +class TestRPiGPIOAdapter(unittest.TestCase): + def test_setup(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.setup(1, GPIO.OUT) + rpi_gpio.setup.assert_called_with(1, rpi_gpio.OUT, pull_up_down=rpi_gpio.PUD_OFF) + adapter.setup(1, GPIO.IN) + rpi_gpio.setup.assert_called_with(1, rpi_gpio.IN, pull_up_down=rpi_gpio.PUD_OFF) + adapter.setup(1, GPIO.IN, GPIO.PUD_DOWN) + rpi_gpio.setup.assert_called_with(1, rpi_gpio.IN, pull_up_down=rpi_gpio.PUD_DOWN) + adapter.setup(1, GPIO.IN, GPIO.PUD_UP) + rpi_gpio.setup.assert_called_with(1, rpi_gpio.IN, pull_up_down=rpi_gpio.PUD_UP) + + def test_output(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.output(1, True) + rpi_gpio.output.assert_called_with(1, True) + adapter.output(1, False) + rpi_gpio.output.assert_called_with(1, False) + + def test_input(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + rpi_gpio.input = Mock(return_value=True) + val = adapter.input(1) + self.assertTrue(val) + rpi_gpio.input.assert_called_with(1) + + def test_setmode(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio, mode=rpi_gpio.BCM) + rpi_gpio.setmode.assert_called_with(rpi_gpio.BCM) + adapter = GPIO.RPiGPIOAdapter(rpi_gpio, mode=rpi_gpio.BOARD) + rpi_gpio.setmode.assert_called_with(rpi_gpio.BOARD) + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + rpi_gpio.setmode.assert_called_with(rpi_gpio.BCM) + + def test_add_event_detect(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.add_event_detect(1, GPIO.RISING) + rpi_gpio.add_event_detect.assert_called_with(1, rpi_gpio.RISING) + + def test_remove_event_detect(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.remove_event_detect(1) + rpi_gpio.remove_event_detect.assert_called_with(1) + + def test_add_event_callback(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.add_event_callback(1, callback=self.test_add_event_callback) + rpi_gpio.add_event_callback.assert_called_with(1, self.test_add_event_callback) + + def test_event_detected(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.event_detected(1) + rpi_gpio.event_detected.assert_called_with(1) + + def test_wait_for_edge(self): + rpi_gpio = Mock() + adapter = GPIO.RPiGPIOAdapter(rpi_gpio) + adapter.wait_for_edge(1, GPIO.FALLING) + rpi_gpio.wait_for_edge.assert_called_with(1, rpi_gpio.FALLING) + + def test_cleanup(self): + rpi_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(rpi_gpio) + adapter.cleanup() + rpi_gpio.cleanup.assert_called() + + def test_cleanup_pin(self): + rpi_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(rpi_gpio) + adapter.cleanup(1) + rpi_gpio.cleanup.assert_called_with(1) + + +class TestAdafruitBBIOAdapter(unittest.TestCase): + def test_setup(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.setup(1, GPIO.OUT) + bbio_gpio.setup.assert_called_with(1, bbio_gpio.OUT, pull_up_down=bbio_gpio.PUD_OFF) + adapter.setup(1, GPIO.IN) + bbio_gpio.setup.assert_called_with(1, bbio_gpio.IN, pull_up_down=bbio_gpio.PUD_OFF) + adapter.setup(1, GPIO.IN, GPIO.PUD_DOWN) + bbio_gpio.setup.assert_called_with(1, bbio_gpio.IN, pull_up_down=bbio_gpio.PUD_DOWN) + adapter.setup(1, GPIO.IN, GPIO.PUD_UP) + bbio_gpio.setup.assert_called_with(1, bbio_gpio.IN, pull_up_down=bbio_gpio.PUD_UP) + + def test_output(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.output(1, True) + bbio_gpio.output.assert_called_with(1, True) + adapter.output(1, False) + bbio_gpio.output.assert_called_with(1, False) + + def test_input(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + bbio_gpio.input = Mock(return_value=True) + val = adapter.input(1) + self.assertTrue(val) + bbio_gpio.input.assert_called_with(1) + + def test_add_event_detect(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.add_event_detect(1, GPIO.RISING) + bbio_gpio.add_event_detect.assert_called_with(1, bbio_gpio.RISING) + + def test_add_event_detect(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.add_event_detect(1, GPIO.RISING) + bbio_gpio.add_event_detect.assert_called_with(1, bbio_gpio.RISING) + + def test_remove_event_detect(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.remove_event_detect(1) + bbio_gpio.remove_event_detect.assert_called_with(1) + + def test_add_event_callback(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.add_event_callback(1, callback=self.test_add_event_callback) + bbio_gpio.add_event_callback.assert_called_with(1, self.test_add_event_callback) + + def test_event_detected(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.event_detected(1) + bbio_gpio.event_detected.assert_called_with(1) + + def test_wait_for_edge(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.wait_for_edge(1, GPIO.FALLING) + bbio_gpio.wait_for_edge.assert_called_with(1, bbio_gpio.FALLING) + + def test_cleanup(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.cleanup() + bbio_gpio.cleanup.assert_called() + + def test_cleanup_pin(self): + bbio_gpio = Mock() + adapter = GPIO.AdafruitBBIOAdapter(bbio_gpio) + adapter.cleanup(1) + bbio_gpio.cleanup.assert_called_with(1) + + +class TestGetPlatformGPIO(unittest.TestCase): + @patch.dict('sys.modules', {'RPi': Mock(), 'RPi.GPIO': Mock()}) + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.RASPBERRY_PI)) + def test_raspberrypi(self): + gpio = GPIO.get_platform_gpio() + self.assertIsInstance(gpio, GPIO.RPiGPIOAdapter) + + @patch.dict('sys.modules', {'Adafruit_BBIO': Mock(), 'Adafruit_BBIO.GPIO': Mock()}) + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.BEAGLEBONE_BLACK)) + def test_beagleboneblack(self): + gpio = GPIO.get_platform_gpio() + self.assertIsInstance(gpio, GPIO.AdafruitBBIOAdapter) + + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.UNKNOWN)) + def test_unknown(self): + self.assertRaises(RuntimeError, GPIO.get_platform_gpio) diff --git a/lib/Adafruit_Python_GPIO/tests/test_I2C.py b/lib/Adafruit_Python_GPIO/tests/test_I2C.py new file mode 100644 index 0000000..01d0393 --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/test_I2C.py @@ -0,0 +1,181 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import logging +import unittest + +from mock import Mock, patch + +import Adafruit_GPIO.Platform as Platform + + +# Enable debug logging to stdout during tests. +logging.basicConfig() +logging.getLogger().setLevel(logging.DEBUG) + + +class MockSMBus(object): + # Mock the smbus.SMBus class to record all data written to specific + # addresses and registers in the _written member. + def __init__(self): + # _written will store a dictionary of address to register dictionary. + # Each register dictionary will store a mapping of register value to + # an array of all written values (in sequential write order). + self._written = {} + self._read = {} + + def _write_register(self, address, register, value): + self._written.setdefault(address, {}).setdefault(register, []).append(value) + + def _read_register(self, address, register): + return self._read.get(address).get(register).pop(0) + + def write_byte_data(self, address, register, value): + self._write_register(address, register, value) + + def write_word_data(self, address, register, value): + self._write_register(address, register, value >> 8 & 0xFF) + self._write_register(address, register+1, value & 0xFF) + + def write_i2c_block_data(self, address, register, values): + for i, value in enumerate(values): + self._write_register(address, register+i, value & 0xFF) + + def read_byte_data(self, address, register): + return self._read_register(address, register) + + def read_word_data(self, address, register): + high = self._read_register(address, register) + low = self._read_register(address, register+1) + return (high << 8) | low + + def read_i2c_block_data(self, address, length): + return [self._read_register(address+i) for i in range(length)] + + +def create_device(address, busnum): + # Mock the smbus module and inject it into the global namespace so the + # Adafruit_GPIO.I2C module can be imported. Also inject a mock SMBus + # instance to be returned by smbus.SMBus function calls. + smbus = Mock() + mockbus = MockSMBus() + smbus.SMBus.return_value = mockbus + with patch.dict('sys.modules', {'smbus': smbus}): + import Adafruit_GPIO.I2C as I2C + return (I2C.Device(address, busnum), smbus, mockbus) + +def safe_import_i2c(): + # Mock the smbus module and inject it into the global namespace so the + # Adafruit_GPIO.I2C module can be imported. The imported I2C module is + # returned so global functions can be called on it. + with patch.dict('sys.modules', {'smbus': Mock() }): + import Adafruit_GPIO.I2C as I2C + return I2C + + +class TestI2CDevice(unittest.TestCase): + + def test_address_and_bus_set_correctly(self): + device, smbus, mockbus = create_device(0x1F, 1) + self.assertEqual(device._bus, mockbus) + smbus.SMBus.assert_called_with(1) + self.assertEqual(device._address, 0x1F) + + def test_write8(self): + device, smbus, mockbus = create_device(0x1F, 1) + device.write8(0xFE, 0xED) + self.assertDictEqual(mockbus._written, { 0x1F: { 0xFE: [0xED] }}) + + def test_write8_truncates_to_8bits(self): + device, smbus, mockbus = create_device(0x1F, 1) + device.write8(0xFE, 0xBEEFED) + self.assertDictEqual(mockbus._written, { 0x1F: { 0xFE: [0xED] }}) + + def test_write16(self): + device, smbus, mockbus = create_device(0x1F, 1) + device.write16(0xFE, 0xBEEF) + self.assertDictEqual(mockbus._written, { 0x1F: { 0xFE: [0xBE], + 0xFF: [0xEF] }}) + + def test_write16_truncates_to_8bits(self): + device, smbus, mockbus = create_device(0x1F, 1) + device.write16(0xFE, 0xFEEDBEEF) + self.assertDictEqual(mockbus._written, { 0x1F: { 0xFE: [0xBE], + 0xFF: [0xEF] }}) + + def test_writeList(self): + device, smbus, mockbus = create_device(0x1F, 1) + device.writeList(0x00, [0xFE, 0xED, 0xBE, 0xEF]) + self.assertDictEqual(mockbus._written, { 0x1F: { 0x00: [0xFE], + 0x01: [0xED], + 0x02: [0xBE], + 0x03: [0xEF] }}) + + def test_readU8(self): + device, smbus, mockbus = create_device(0x1F, 1) + mockbus._read[0x1F] = { 0xFE: [0xED] } + value = device.readU8(0xFE) + self.assertEqual(value, 0xED) + + def test_readS8(self): + device, smbus, mockbus = create_device(0x1F, 1) + mockbus._read[0x1F] = { 0xFE: [0xED] } + value = device.readS8(0xFE) + self.assertEqual(value, -19) + + def test_readU16(self): + device, smbus, mockbus = create_device(0x1F, 1) + mockbus._read[0x1F] = { 0xFE: [0xED], 0xFF: [0x01] } + value = device.readU16(0xFE) + self.assertEqual(value, 0xED01) + + def test_readS16(self): + device, smbus, mockbus = create_device(0x1F, 1) + mockbus._read[0x1F] = { 0xFE: [0xED], 0xFF: [0x01] } + value = device.readS16(0xFE) + self.assertEqual(value, -4863) + + +class TestGetDefaultBus(unittest.TestCase): + @patch('Adafruit_GPIO.Platform.pi_revision', Mock(return_value=1)) + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.RASPBERRY_PI)) + def test_raspberry_pi_rev1(self): + I2C = safe_import_i2c() + bus = I2C.get_default_bus() + self.assertEqual(bus, 0) + + @patch('Adafruit_GPIO.Platform.pi_revision', Mock(return_value=2)) + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.RASPBERRY_PI)) + def test_raspberry_pi_rev2(self): + I2C = safe_import_i2c() + bus = I2C.get_default_bus() + self.assertEqual(bus, 1) + + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.BEAGLEBONE_BLACK)) + def test_beaglebone_black(self): + I2C = safe_import_i2c() + bus = I2C.get_default_bus() + self.assertEqual(bus, 1) + + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.UNKNOWN)) + def test_unknown(self): + I2C = safe_import_i2c() + self.assertRaises(RuntimeError, I2C.get_default_bus) diff --git a/lib/Adafruit_Python_GPIO/tests/test_PWM.py b/lib/Adafruit_Python_GPIO/tests/test_PWM.py new file mode 100644 index 0000000..d80bd1f --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/test_PWM.py @@ -0,0 +1,103 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import unittest + +from mock import Mock, patch + +import Adafruit_GPIO.PWM as PWM +import Adafruit_GPIO.Platform as Platform + + +class TestRPi_PWM_Adapter(unittest.TestCase): + def test_setup(self): + rpi_gpio = Mock() + pwm = PWM.RPi_PWM_Adapter(rpi_gpio) + pwm.start(1, 50) + rpi_gpio.PWM.assert_called_with(1, 2000) + + def test_set_duty_cycle_valid(self): + rpi_gpio = Mock() + pwm = PWM.RPi_PWM_Adapter(rpi_gpio) + pwm.start(1, 50) + pwm.set_duty_cycle(1, 75) + # Implicit verification that no assertion or other error thrown. + + def test_set_duty_cycle_invalid(self): + rpi_gpio = Mock() + pwm = PWM.RPi_PWM_Adapter(rpi_gpio) + pwm.start(1, 50) + self.assertRaises(ValueError, pwm.set_duty_cycle, 1, 150) + self.assertRaises(ValueError, pwm.set_duty_cycle, 1, -10) + + def test_set_frequency(self): + rpi_gpio = Mock() + pwm = PWM.RPi_PWM_Adapter(rpi_gpio) + pwm.start(1, 50) + pwm.set_frequency(1, 1000) + # Implicit verification that no assertion or other error thrown. + + +class TestBBIO_PWM_Adapter(unittest.TestCase): + def test_setup(self): + bbio_pwm = Mock() + pwm = PWM.BBIO_PWM_Adapter(bbio_pwm) + pwm.start('P9_16', 50) + bbio_pwm.start.assert_called_with('P9_16', 50, 2000) + + def test_set_duty_cycle_valid(self): + bbio_pwm = Mock() + pwm = PWM.BBIO_PWM_Adapter(bbio_pwm) + pwm.start('P9_16', 50) + pwm.set_duty_cycle('P9_16', 75) + bbio_pwm.set_duty_cycle.assert_called_with('P9_16', 75) + + def test_set_duty_cycle_invalid(self): + bbio_pwm = Mock() + pwm = PWM.BBIO_PWM_Adapter(bbio_pwm) + pwm.start('P9_16', 50) + self.assertRaises(ValueError, pwm.set_duty_cycle, 'P9_16', 150) + self.assertRaises(ValueError, pwm.set_duty_cycle, 'P9_16', -10) + + def test_set_frequency(self): + bbio_pwm = Mock() + pwm = PWM.BBIO_PWM_Adapter(bbio_pwm) + pwm.start('P9_16', 50) + pwm.set_frequency('P9_16', 1000) + bbio_pwm.set_frequency.assert_called_with('P9_16', 1000) + + +class TestGetPlatformPWM(unittest.TestCase): + @patch.dict('sys.modules', {'RPi': Mock(), 'RPi.GPIO': Mock()}) + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.RASPBERRY_PI)) + def test_raspberrypi(self): + pwm = PWM.get_platform_pwm() + self.assertIsInstance(pwm, PWM.RPi_PWM_Adapter) + + @patch.dict('sys.modules', {'Adafruit_BBIO': Mock(), 'Adafruit_BBIO.PWM': Mock()}) + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.BEAGLEBONE_BLACK)) + def test_beagleboneblack(self): + pwm = PWM.get_platform_pwm() + self.assertIsInstance(pwm, PWM.BBIO_PWM_Adapter) + + @patch('Adafruit_GPIO.Platform.platform_detect', Mock(return_value=Platform.UNKNOWN)) + def test_otherplatform(self): + self.assertRaises(RuntimeError, PWM.get_platform_pwm) diff --git a/lib/Adafruit_Python_GPIO/tests/test_Platform.py b/lib/Adafruit_Python_GPIO/tests/test_Platform.py new file mode 100644 index 0000000..42da8e3 --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/test_Platform.py @@ -0,0 +1,70 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +import unittest + +from mock import Mock, patch + +import Adafruit_GPIO.Platform as Platform + + +class TestPlatformDetect(unittest.TestCase): + @patch('platform.platform', Mock(return_value='Linux-3.8.13-bone47-armv7l-with-debian-7.4')) + def test_beaglebone_black(self): + result = Platform.platform_detect() + self.assertEquals(result, Platform.BEAGLEBONE_BLACK) + + @patch('platform.platform', Mock(return_value='Darwin-13.2.0-x86_64-i386-64bit')) + def test_unknown(self): + result = Platform.platform_detect() + self.assertEquals(result, Platform.UNKNOWN) + + +class TestPiRevision(unittest.TestCase): + def test_revision_1(self): + with patch('__builtin__.open') as mock_open: + handle = mock_open.return_value.__enter__.return_value + handle.__iter__.return_value = iter(['Revision : 0000']) + rev = Platform.pi_revision() + self.assertEquals(rev, 1) + with patch('__builtin__.open') as mock_open: + handle = mock_open.return_value.__enter__.return_value + handle.__iter__.return_value = iter(['Revision : 0002']) + rev = Platform.pi_revision() + self.assertEquals(rev, 1) + with patch('__builtin__.open') as mock_open: + handle = mock_open.return_value.__enter__.return_value + handle.__iter__.return_value = iter(['Revision : 0003']) + rev = Platform.pi_revision() + self.assertEquals(rev, 1) + + def test_revision_2(self): + with patch('__builtin__.open') as mock_open: + handle = mock_open.return_value.__enter__.return_value + handle.__iter__.return_value = iter(['Revision : 000e']) + rev = Platform.pi_revision() + self.assertEquals(rev, 2) + + def test_unknown_revision(self): + with patch('__builtin__.open') as mock_open: + handle = mock_open.return_value.__enter__.return_value + handle.__iter__.return_value = iter(['foobar']) + self.assertRaises(RuntimeError, Platform.pi_revision) + diff --git a/lib/Adafruit_Python_GPIO/tests/test_SPI.py b/lib/Adafruit_Python_GPIO/tests/test_SPI.py new file mode 100644 index 0000000..123eec1 --- /dev/null +++ b/lib/Adafruit_Python_GPIO/tests/test_SPI.py @@ -0,0 +1,192 @@ +# Copyright (c) 2014 Adafruit Industries +# Author: Tony DiCola +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +import unittest + +import Adafruit_GPIO as GPIO +import Adafruit_GPIO.SPI as SPI + +from MockGPIO import MockGPIO + + +class TestBitBangSPI(unittest.TestCase): + def test_pin_modes_set_correctly(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + self.assertDictEqual(gpio.pin_mode, { 1: GPIO.OUT, + 2: GPIO.OUT, + 3: GPIO.IN, + 4: GPIO.OUT }) + + def test_ss_set_high_after_initialization(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + self.assertListEqual(gpio.pin_written[4], [1]) + + def test_mode_0_write(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + device.write([0x1F]) + # Verify clock + self.assertListEqual(gpio.pin_written[1], [0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0]) + # Verify MOSI + self.assertListEqual(gpio.pin_written[2], [0, 0, 0, 1, 1, 1, 1, 1]) + # Verify MISO + self.assertNotIn(3, gpio.pin_written) + # Verify SS + self.assertListEqual(gpio.pin_written[4], [1, 0, 1]) + + def test_write_assert_deassert_ss_false(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + device.write([0x1F], assert_ss=False, deassert_ss=False) + self.assertListEqual(gpio.pin_written[4], [1]) + + def test_write_lsbfirst(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + device.set_bit_order(SPI.LSBFIRST) + device.write([0x1F]) + self.assertListEqual(gpio.pin_written[2], [1, 1, 1, 1, 1, 0, 0, 0]) + + def test_invalid_mode_fails(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + self.assertRaises(ValueError, device.set_mode, -1) + self.assertRaises(ValueError, device.set_mode, 4) + + def test_invalid_bit_order_fails(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + self.assertRaises(ValueError, device.set_bit_order, -1) + self.assertRaises(ValueError, device.set_bit_order, 2) + + def test_mode_0_read(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + gpio.pin_read[3] = [0, 0, 0, 1, 1, 1, 1, 1] + result = device.read(1) + # Verify clock + self.assertListEqual(gpio.pin_written[1], [0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0]) + # Verify MOSI + self.assertNotIn(2, gpio.pin_written) + # Verify MISO + self.assertNotIn(3, gpio.pin_written) + # Verify SS + self.assertListEqual(gpio.pin_written[4], [1, 0, 1]) + # Verify result + self.assertEqual(result, bytearray([0x1F])) + + def test_read_assert_deassert_ss_false(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + gpio.pin_read[3] = [0, 0, 0, 1, 1, 1, 1, 1] + result = device.read(1, assert_ss=False, deassert_ss=False) + self.assertListEqual(gpio.pin_written[4], [1]) + + def test_read_multiple_bytes(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + gpio.pin_read[3] = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1] + result = device.read(3) + # Verify clock + self.assertListEqual(gpio.pin_written[1], [0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0]) + # Verify MOSI + self.assertNotIn(2, gpio.pin_written) + # Verify MISO + self.assertNotIn(3, gpio.pin_written) + # Verify SS + self.assertListEqual(gpio.pin_written[4], [1, 0, 1]) + # Verify result + self.assertEqual(result, bytearray([0x1F, 0xF8, 0x1F])) + + def test_write_multiple_bytes(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + device.write([0x1F, 0xF8, 0x1F]) + # Verify clock + self.assertListEqual(gpio.pin_written[1], [0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0]) + # Verify MOSI + self.assertListEqual(gpio.pin_written[2], [0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1]) + # Verify MISO + self.assertNotIn(3, gpio.pin_written) + # Verify SS + self.assertListEqual(gpio.pin_written[4], [1, 0, 1]) + + def test_mode_0_transfer(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + gpio.pin_read[3] = [0, 0, 0, 1, 1, 1, 1, 1] + result = device.transfer([0xF8]) + # Verify clock + self.assertListEqual(gpio.pin_written[1], [0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0]) + # Verify MOSI + self.assertListEqual(gpio.pin_written[2], [1, 1, 1, 1, 1, 0, 0, 0]) + # Verify MISO + self.assertNotIn(3, gpio.pin_written) + # Verify SS + self.assertListEqual(gpio.pin_written[4], [1, 0, 1]) + # Verify result + self.assertEqual(result, bytearray([0x1F])) + + def test_transfer_multiple_bytes(self): + gpio = MockGPIO() + device = SPI.BitBang(gpio, 1, 2, 3, 4) + gpio.pin_read[3] = [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1] + result = device.transfer([0xF8, 0x1F, 0xF8]) + # Verify clock + self.assertListEqual(gpio.pin_written[1], [0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0]) + # Verify MOSI + self.assertListEqual(gpio.pin_written[2], [1, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 0]) + # Verify MISO + self.assertNotIn(3, gpio.pin_written) + # Verify SS + self.assertListEqual(gpio.pin_written[4], [1, 0, 1]) + # Verify result + self.assertEqual(result, bytearray([0x1F, 0xF8, 0x1F])) + + #TODO: Test mode 1, 2, 3 + + #TODO: Test null MOSI, MISO, SS |