def test_REPLConnection_open_DTR_unset(): """ If data terminal ready (DTR) is unset (as can be the case on some Windows / Qt combinations) then fall back to PySerial to correct. See issues #281 and #302 for details. """ # Mock QtSerialPort object mock_qt_serial = mock.MagicMock() mock_qt_serial.isDataTerminalReady.return_value = False mock_qtserial_class = mock.MagicMock(return_value=mock_qt_serial) # Mock PySerial object mock_Serial = mock.MagicMock() mock_pyserial_class = mock.MagicMock(return_value=mock_Serial) with mock.patch("mu.modes.base.QSerialPort", mock_qtserial_class): with mock.patch("mu.modes.base.Serial", mock_pyserial_class): conn = REPLConnection("COM0") conn.open() # Check that Qt serial is opened twice mock_qt_serial.close.assert_called_once_with() assert mock_qt_serial.open.call_count == 2 # Check that DTR is set true with PySerial assert mock_Serial.dtr is True mock_Serial.close.assert_called_once_with()
def test_REPLConnection_send_commands(): """ Ensure the list of commands is correctly encoded and bound by control commands to put the board into and out of raw mode. """ mock_serial_class = mock.MagicMock() with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0") conn.execute = mock.MagicMock() commands = ["import os", "print(os.listdir())"] conn.send_commands(commands) expected = [ b"\x03", # Keyboard interrupt b"\x03", # Keyboard interrupt b"\x01", # Put the board into raw mode. b"\x04", # Soft-reboot b"\x03", # Keyboard interrupt b"\x03", # Keyboard interrupt b'print("\\n");', # Ensure a newline at the start of output. b"import os\r", # The commands to run. b"print(os.listdir())\r", b"\r", # Ensure newline after commands. b"\x04", # Evaluate the commands. b"\x02", # Leave raw mode. ] conn.execute.assert_called_once_with(expected)
def test_REPLConnection_open_unable_to_connect(): """ If serial.open fails raise an IOError. """ mock_serial = mock.MagicMock() mock_serial.setPortName = mock.MagicMock(return_value=None) mock_serial.setBaudRate = mock.MagicMock(return_value=None) mock_serial.open = mock.MagicMock(return_value=False) mock_serial_class = mock.MagicMock(return_value=mock_serial) with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): with pytest.raises(IOError): conn = REPLConnection("COM0") conn.open()
def test_REPLConnection_on_serial_read(): """ When data is received the data_received signal should emit it. """ mock_serial = mock.MagicMock() mock_serial.readAll.return_value = b"Hello" mock_serial_class = mock.MagicMock(return_value=mock_serial) with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0") conn.data_received = mock.MagicMock() conn._on_serial_read() conn.data_received.emit.assert_called_once_with(b"Hello")
def test_REPLConnection_execute(): """ Ensure the first command is sent via serial to the connected device, and further commands are scheduled for the future. """ mock_serial_class = mock.MagicMock() with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0") conn.write = mock.MagicMock() # Mocks QTimer, so only first command will be sent commands = [b"A", b"B"] with mock.patch("mu.modes.base.QTimer") as mock_timer: conn.execute(commands) conn.write.assert_called_once_with(b"A") assert mock_timer.singleShot.call_count == 1
def test_REPLConnection_open(): """ Ensure the serial port is opened in the expected manner. """ mock_serial = mock.MagicMock() mock_serial.setPortName = mock.MagicMock(return_value=None) mock_serial.setBaudRate = mock.MagicMock(return_value=None) mock_serial.open = mock.MagicMock(return_value=True) mock_serial.readyRead = mock.MagicMock() mock_serial.readyRead.connect = mock.MagicMock(return_value=None) mock_serial_class = mock.MagicMock(return_value=mock_serial) with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0", baudrate=9600) conn.open() mock_serial.setPortName.assert_called_once_with("COM0") mock_serial.setBaudRate.assert_called_once_with(9600) mock_serial.open.assert_called_once_with(QIODevice.ReadWrite) mock_serial.readyRead.connect.assert_called_once_with(conn._on_serial_read)
def test_REPLConnection_init_default_args(): """ Ensure the MicroPython REPLConnection object is instantiated as expected. """ mock_serial_class = mock.MagicMock() with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0", baudrate=9600) assert conn.port == "COM0" assert conn.baudrate == 9600
def test_REPLConnection_write(): mock_serial = mock.MagicMock() mock_serial_class = mock.MagicMock(return_value=mock_serial) with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0") conn.open() conn.write(b"Hello") mock_serial.write.assert_called_once_with(b"Hello")
def test_REPLConnection_send_interrupt(): mock_serial = mock.MagicMock() mock_serial_class = mock.MagicMock(return_value=mock_serial) with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0") conn.open() conn.send_interrupt() mock_serial.write.assert_any_call(b"\x02") # CTRL-B mock_serial.write.assert_any_call(b"\x03") # CTRL-C
def test_REPLConnection_close(): """ Ensure the serial link is closed / cleaned up as expected. """ mock_serial = mock.MagicMock() mock_serial_class = mock.MagicMock(return_value=mock_serial) with mock.patch("mu.modes.base.QSerialPort", mock_serial_class): conn = REPLConnection("COM0") conn.open() conn.close() mock_serial.close.assert_called_once_with() assert conn.serial is None assert conn.port is None assert conn.baudrate is None