def test_flash_user_specified_device_path(): """ Ensure that if a micro:bit is not automatically found by uflash then it prompts the user to locate the device and, assuming a path was given, saves the hex in the expected location. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.logic.uflash.find_microbit', return_value=None),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.get_microbit_path = mock.MagicMock(return_value='bar') view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() home = HOME_DIRECTORY view.get_microbit_path.assert_called_once_with(home) assert editor.show_status_message.call_count == 1 assert mm.user_defined_microbit_path == 'bar' mock_flasher_class.assert_called_once_with(['bar', ], b'foo', None)
def test_flash_without_device(): """ If no device is found and the user doesn't provide a path then ensure a helpful status message is enacted. """ with mock.patch('mu.logic.uflash.hexlify', return_value=''), \ mock.patch('mu.logic.uflash.embed_hex', return_value='foo'), \ mock.patch('mu.logic.uflash.find_microbit', return_value=None), \ mock.patch('mu.logic.uflash.save_hex', return_value=None) as s: view = mock.MagicMock() view.get_microbit_path = mock.MagicMock(return_value=None) view.current_tab.text = mock.MagicMock(return_value='') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() message = 'Could not find an attached BBC micro:bit.' information = ("Please ensure you leave enough time for the BBC" " micro:bit to be attached and configured correctly" " by your computer. This may take several seconds." " Alternatively, try removing and re-attaching the" " device or saving your work and restarting Mu if" " the device remains unfound.") view.show_message.assert_called_once_with(message, information) home = HOME_DIRECTORY view.get_microbit_path.assert_called_once_with(home) assert s.call_count == 0
def test_force_flash_no_serial_connection(): """ If Mu cannot establish a serial connection to the micro:bit, BUT the path to the micro:bit on the filesystem is known, then fall back to old-school flashing of hex with script appended to the end. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.contrib.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.contrib.microfs.get_serial'),\ mock.patch('mu.contrib.microfs.version', side_effect=IOError('bang')),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '' mm = MicrobitMode(editor, view) mm.find_device = mock.MagicMock(side_effect=IOError('bang')) mm.flash() mock_flasher_class.assert_called_once_with([ 'bar', ], b'foo', None) mock_flasher.finished.connect.\ assert_called_once_with(mm.flash_finished)
def test_flash_path_specified_does_not_exist(): """ Ensure that if a micro:bit is not automatically found by uflash and the user has previously specified a path to the device, then the hex is saved in the specified location. """ with mock.patch('mu.logic.uflash.hexlify', return_value=''), \ mock.patch('mu.logic.uflash.embed_hex', return_value='foo'), \ mock.patch('mu.logic.uflash.find_microbit', return_value=None),\ mock.patch('mu.logic.os.path.exists', return_value=False),\ mock.patch('mu.logic.os.makedirs', return_value=None), \ mock.patch('mu.logic.uflash.save_hex', return_value=None) as s: view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.user_defined_microbit_path = 'baz' mm.flash() message = 'Could not find an attached BBC micro:bit.' information = ("Please ensure you leave enough time for the BBC" " micro:bit to be attached and configured correctly" " by your computer. This may take several seconds." " Alternatively, try removing and re-attaching the" " device or saving your work and restarting Mu if" " the device remains unfound.") view.show_message.assert_called_once_with(message, information) assert s.call_count == 0 assert mm.user_defined_microbit_path is None
def test_flash_with_attached_device_as_windows(): """ Ensure the expected calls are made to DeviceFlasher and a helpful status message is enacted as if on Windows. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.modes.microbit.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '/foo/bar' mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() mm.flash() assert mm.flash_thread == mock_flasher assert editor.show_status_message.call_count == 1 mm.set_buttons.assert_called_once_with(flash=False) mock_flasher_class.assert_called_once_with([ 'bar', ], b'foo', '/foo/bar') mock_flasher.finished.connect.\ assert_called_once_with(mm.flash_finished) mock_flasher.on_flash_fail.connect.\ assert_called_once_with(mm.flash_failed) mock_flasher.start.assert_called_once_with()
def test_flash_user_specified_device_path(): """ Ensure that if a micro:bit is not automatically found by uflash then it prompts the user to locate the device and, assuming a path was given, saves the hex in the expected location. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.contrib.uflash.find_microbit', return_value=None),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.get_microbit_path = mock.MagicMock(return_value='bar') view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '' mm = MicrobitMode(editor, view) mm.flash() home = HOME_DIRECTORY view.get_microbit_path.assert_called_once_with(home) assert editor.show_status_message.call_count == 1 assert mm.user_defined_microbit_path == 'bar' mock_flasher_class.assert_called_once_with([ 'bar', ], b'foo', None)
def test_force_flash_no_serial_connection(): """ If Mu cannot establish a serial connection to the micro:bit, BUT the path to the micro:bit on the filesystem is known, then fall back to old-school flashing of hex with script appended to the end. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.contrib.uflash.find_microbit", return_value="/path/microbit"), mock.patch( "mu.contrib.microfs.get_serial"), mock.patch( "mu.contrib.microfs.version", side_effect=IOError("bang")), mock.patch( "mu.logic.os.path.exists", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = None mm = MicrobitMode(editor, view) mm.flash_attached = mock.MagicMock(side_effect=mm.flash_attached) mm.flash() mm.flash_attached.assert_called_once_with(b"foo", "/path/microbit") mock_flasher_class.assert_called_once_with("/path/microbit", b"foo") mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished)
def test_flash_with_attached_device_as_not_windows(): """ Ensure the expected calls are made to DeviceFlasher and a helpful status message is enacted as if not on Windows. """ mock_timer = mock.MagicMock() mock_timer_class = mock.MagicMock(return_value=mock_timer) mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.modes.microbit.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'linux'), \ mock.patch('mu.modes.microbit.QTimer', mock_timer_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() assert mm.flash_timer == mock_timer assert editor.show_status_message.call_count == 1 view.button_bar.slots['flash'].setEnabled.\ assert_called_once_with(False) mock_flasher_class.assert_called_once_with(['bar', ], b'foo', None) assert mock_flasher.finished.connect.call_count == 0 mock_timer.timeout.connect.assert_called_once_with(mm.flash_finished) mock_timer.setSingleShot.assert_called_once_with(True) mock_timer.start.assert_called_once_with(10000) mock_flasher.on_flash_fail.connect.\ assert_called_once_with(mm.flash_failed) mock_flasher.start.assert_called_once_with()
def test_flash_path_specified_does_not_exist(): """ Ensure that if a micro:bit is not automatically found by uflash and the user has previously specified a path to the device, then the hex is saved in the specified location. """ with mock.patch('mu.contrib.uflash.hexlify', return_value=''), \ mock.patch('mu.contrib.uflash.embed_hex', return_value='foo'), \ mock.patch('mu.contrib.uflash.find_microbit', return_value=None),\ mock.patch('mu.logic.os.path.exists', return_value=False),\ mock.patch('mu.logic.os.makedirs', return_value=None), \ mock.patch('mu.contrib.uflash.save_hex', return_value=None) as s: view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.user_defined_microbit_path = 'baz' mm.flash() message = 'Could not find an attached BBC micro:bit.' information = ("Please ensure you leave enough time for the BBC" " micro:bit to be attached and configured correctly" " by your computer. This may take several seconds." " Alternatively, try removing and re-attaching the" " device or saving your work and restarting Mu if" " the device remains unfound.") view.show_message.assert_called_once_with(message, information) assert s.call_count == 0 assert mm.user_defined_microbit_path is None
def test_flash_force_with_unsupported_microbit(microbit_incompatible): """ If Mu is supposed to flash the device, but the device is, in fact, not one that's supported by the version of MicroPython built into Mu, then display a warning message to the user. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.modes.microbit.uflash.find_microbit", return_value="bar"), mock.patch( "mu.modes.microbit.microfs.version", side_effect=ValueError("bang")), mock.patch( "mu.modes.microbit.os.path.isfile", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() # Empty file to force flashing. view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.microbit_runtime = "" editor.minify = False editor.current_device = microbit_incompatible mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() mm.flash() assert view.show_message.call_count == 1
def test_flash_without_device(): """ If no device is found and the user doesn't provide a path then ensure a helpful status message is enacted. """ with mock.patch('mu.contrib.uflash.hexlify', return_value=''), \ mock.patch('mu.contrib.uflash.embed_hex', return_value='foo'), \ mock.patch('mu.contrib.uflash.find_microbit', return_value=None), \ mock.patch('mu.contrib.uflash.save_hex', return_value=None) as s: view = mock.MagicMock() view.get_microbit_path = mock.MagicMock(return_value=None) view.current_tab.text = mock.MagicMock(return_value='') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() message = 'Could not find an attached BBC micro:bit.' information = ("Please ensure you leave enough time for the BBC" " micro:bit to be attached and configured correctly" " by your computer. This may take several seconds." " Alternatively, try removing and re-attaching the" " device or saving your work and restarting Mu if" " the device remains unfound.") view.show_message.assert_called_once_with(message, information) home = HOME_DIRECTORY view.get_microbit_path.assert_called_once_with(home) assert s.call_count == 0
def test_flash_minify(microbit_v1_5): view = mock.MagicMock() script = "#" + ("x" * 8193) + "\n" view.current_tab.text = mock.MagicMock(return_value=script) view.current_tab.label = "foo" view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = True editor.current_device = microbit_v1_5 mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() with mock.patch("mu.modes.microbit.DeviceFlasher"), mock.patch( "mu.contrib.uflash._MAX_SIZE", 8188), mock.patch("nudatus.mangle", return_value="") as m: mm.flash() m.assert_called_once_with(script) ex = TokenError("Bad", (1, 0)) with mock.patch("nudatus.mangle", side_effect=ex) as m, mock.patch( "mu.contrib.uflash._MAX_SIZE", 8188): mm.flash() view.show_message.assert_called_with( 'Unable to flash "foo"', "Problem minifying script\nBad [1:0]", "Warning", )
def test_flash_with_attached_device_and_custom_runtime(): """ Ensure the custom runtime is passed into the DeviceFlasher thread. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch( "mu.modes.base.BaseMode.workspace_dir", return_value=TEST_ROOT ), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class ), mock.patch( "mu.modes.microbit.sys.platform", "win32" ): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = True editor.microbit_runtime = os.path.join("tests", "customhextest.hex") mm = MicrobitMode(editor, view) mm.flash() assert editor.show_status_message.call_count == 1 assert ( os.path.join("tests", "customhextest.hex") in editor.show_status_message.call_args[0][0] ) assert mock_flasher_class.call_count == 1
def test_flash_force_with_unsupported_microbit(): """ If Mu is supposed to flash the device, but the device is, in fact, not one that's supported by the version of MicroPython built into Mu, then display a warning message to the user. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.modes.microbit.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.modes.microbit.microfs.version', side_effect=ValueError('bang')),\ mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() # Empty file to force flashing. view.current_tab.text = mock.MagicMock(return_value='') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.microbit_runtime = '' editor.minify = False mm = MicrobitMode(editor, view) mm.find_device = mock.MagicMock(return_value=('bar', '1234567890')) mm.set_buttons = mock.MagicMock() mm.flash() assert view.show_message.call_count == 1
def test_flash_existing_user_specified_device_path(): """ Ensure that if a micro:bit is not automatically found by uflash and the user has previously specified a path to the device, then the hex is saved in the specified location. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.contrib.uflash.find_microbit', return_value=None),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.get_microbit_path = mock.MagicMock(return_value='bar') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '/foo/bar' mm = MicrobitMode(editor, view) mm.user_defined_microbit_path = 'baz' mm.flash() assert view.get_microbit_path.call_count == 0 assert editor.show_status_message.call_count == 1 mock_flasher_class.assert_called_once_with([ 'baz', ], b'foo', '/foo/bar')
def test_flash_forced_with_attached_device_as_not_windows( microbit_old_firmware, ): """ Ensure the expected calls are made to DeviceFlasher and a helpful status message is enacted as if not on Windows. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": "1.0", "version": ( "micro:bit v0.0.9-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01" ), "machine": "micro:bit with nRF51822", } mock_timer = mock.MagicMock() mock_timer_class = mock.MagicMock(return_value=mock_timer) mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch( "mu.modes.microbit.uflash.find_microbit", return_value="bar" ), mock.patch( "mu.modes.microbit.microfs.version", return_value=version_info ), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True ), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class ), mock.patch( "mu.modes.microbit.sys.platform", "linux" ), mock.patch( "mu.modes.microbit.QTimer", mock_timer_class ): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = microbit_old_firmware mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() mm.copy_main = mock.MagicMock() mm.flash() assert mm.flash_timer == mock_timer assert editor.show_status_message.call_count == 1 mm.set_buttons.assert_called_once_with(flash=False) mock_flasher_class.assert_called_once_with(["bar"], b"", None) assert mock_flasher.finished.connect.call_count == 0 mock_timer.timeout.connect.assert_called_once_with(mm.flash_finished) mock_timer.setSingleShot.assert_called_once_with(True) mock_timer.start.assert_called_once_with(10000) mock_flasher.on_flash_fail.connect.assert_called_once_with( mm.flash_failed ) mock_flasher.start.assert_called_once_with() assert mm.python_script == b"foo"
def test_flash_force_with_attached_device(microbit): """ Ensure the expected calls are made to DeviceFlasher and a helpful status message is enacted. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": "1.0", "version": ("micro:bit v0.0.9-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.modes.microbit.uflash.find_microbit", return_value="/foo/microbit/"), mock.patch( "mu.modes.microbit.microfs.version", return_value=version_info), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True), mock.patch( "mu.modes.microbit.os.path.isfile", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "/foo/bar.hex" editor.current_device = microbit mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() mm.flash_and_send = mock.MagicMock(side_effect=mm.flash_and_send) mm.flash() assert mm.flash_thread == mock_flasher assert editor.show_status_message.call_count == 1 mm.set_buttons.assert_called_once_with(flash=False, repl=False, files=False, plotter=False) mm.flash_and_send.assert_called_once_with(b"foo", "/foo/microbit/", "/foo/bar.hex") mock_flasher_class.assert_called_once_with( "/foo/microbit/", python_script=None, path_to_runtime="/foo/bar.hex", ) mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished) mock_flasher.on_flash_fail.connect.assert_called_once_with( mm.flash_failed) mock_flasher.start.assert_called_once_with()
def test_flash_device_has_latest_firmware_encounters_serial_problem_unix( microbit, ): """ If copy_main encounters an IOError on unix-y, revert to old-school flashing. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": uflash.MICROPYTHON_VERSION, "version": ( "micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01" ), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) mock_timer = mock.MagicMock() mock_timer_class = mock.MagicMock(return_value=mock_timer) with mock.patch( "mu.modes.microbit.uflash.find_microbit", return_value="bar" ), mock.patch( "mu.modes.microbit.microfs.version", return_value=version_info ), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True ), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class ), mock.patch( "mu.modes.microbit.QTimer", mock_timer_class ), mock.patch( "mu.modes.microbit.sys.platform", "linux" ): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = microbit mm = MicrobitMode(editor, view) mm.flash_failed = mock.MagicMock() error = IOError("bang") mm.copy_main = mock.MagicMock(side_effect=error) mm.set_buttons = mock.MagicMock() mm.flash() mm.copy_main.assert_called_once_with() mock_flasher_class.assert_called_once_with(["bar"], b"foo", None) mock_flasher.on_flash_fail.connect.assert_called_once_with( mm.flash_failed ) mock_flasher.start.assert_called_once_with() assert mm.flash_timer == mock_timer mock_timer.timeout.connect.assert_called_once_with(mm.flash_finished) mock_timer.setSingleShot.assert_called_once_with(True) mock_timer.start.assert_called_once_with(10000)
def test_flash_forced_with_attached_device_as_not_windows(): """ Ensure the expected calls are made to DeviceFlasher and a helpful status message is enacted as if not on Windows. """ version_info = { 'sysname': 'microbit', 'nodename': 'microbit', 'release': '1.0', 'version': ("micro:bit v0.0.9-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), 'machine': 'micro:bit with nRF51822', } mock_timer = mock.MagicMock() mock_timer_class = mock.MagicMock(return_value=mock_timer) mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.modes.microbit.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.modes.microbit.microfs.find_microbit', return_value=('COM0', '12345')),\ mock.patch('mu.modes.microbit.microfs.version', return_value=version_info),\ mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'linux'), \ mock.patch('mu.modes.microbit.QTimer', mock_timer_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '' mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() mm.copy_main = mock.MagicMock() mm.flash() assert mm.flash_timer == mock_timer assert editor.show_status_message.call_count == 1 mm.set_buttons.assert_called_once_with(flash=False) mock_flasher_class.assert_called_once_with([ 'bar', ], b'', None) assert mock_flasher.finished.connect.call_count == 0 mock_timer.timeout.connect.assert_called_once_with(mm.flash_finished) mock_timer.setSingleShot.assert_called_once_with(True) mock_timer.start.assert_called_once_with(10000) mock_flasher.on_flash_fail.connect.\ assert_called_once_with(mm.flash_failed) mock_flasher.start.assert_called_once_with() assert mm.python_script == b'foo'
def test_flash_device_has_latest_firmware_encounters_serial_problem_unix(): """ If copy_main encounters an IOError on unix-y, revert to old-school flashing. """ version_info = { 'sysname': 'microbit', 'nodename': 'microbit', 'release': uflash.MICROPYTHON_VERSION, 'version': ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), 'machine': 'micro:bit with nRF51822', } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) mock_timer = mock.MagicMock() mock_timer_class = mock.MagicMock(return_value=mock_timer) with mock.patch('mu.modes.microbit.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.modes.microbit.microfs.version', return_value=version_info),\ mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.QTimer', mock_timer_class), \ mock.patch('mu.modes.microbit.sys.platform', 'linux'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '' mm = MicrobitMode(editor, view) mm.find_device = mock.MagicMock(return_value=('bar', '12345')) mm.flash_failed = mock.MagicMock() error = IOError('bang') mm.copy_main = mock.MagicMock(side_effect=error) mm.set_buttons = mock.MagicMock() mm.flash() mm.copy_main.assert_called_once_with() mock_flasher_class.assert_called_once_with([ 'bar', ], b'foo', None) mock_flasher.on_flash_fail.connect.\ assert_called_once_with(mm.flash_failed) mock_flasher.start.assert_called_once_with() assert mm.flash_timer == mock_timer mock_timer.timeout.connect.assert_called_once_with(mm.flash_finished) mock_timer.setSingleShot.assert_called_once_with(True) mock_timer.start.assert_called_once_with(10000)
def test_force_flash_user_specified_device_path(): """ Ensure that if a micro:bit is not automatically found by uflash then it prompts the user to locate the device and, assuming a path was given, saves the hex in the expected location. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": uflash.MICROPYTHON_VERSION, "version": ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.contrib.uflash.find_microbit", return_value=None), mock.patch( "mu.contrib.microfs.get_serial"), mock.patch( "mu.contrib.microfs.version", return_value=version_info), mock.patch( "mu.logic.os.path.exists", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() view.get_microbit_path = mock.MagicMock(return_value="/bar/microbit") view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = None mm = MicrobitMode(editor, view) mm.flash_start = mock.MagicMock(side_effect=mm.flash_start) mm.flash() home = HOME_DIRECTORY view.get_microbit_path.assert_called_once_with(home) mm.flash_start.assert_called_once_with(b"foo", "/bar/microbit", None, serial_fs=False) mock_flasher_class.assert_called_once_with(["/bar/microbit"], b"foo", None) mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished)
def test_flash_script_too_big(): """ If the script in the current tab is too big, abort in the expected way. """ view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='x' * 8193) view.current_tab.label = 'foo' view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() view.show_message.assert_called_once_with('Unable to flash "foo"', 'Your script is too long!', 'Warning')
def test_flash_script_too_big(): """ If the script in the current tab is too big, abort in the expected way. """ view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='x' * 8193) view.current_tab.label = 'foo' view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() view.show_message.assert_called_once_with('Unable to flash "foo"', 'Your script is too long!', 'Warning')
def test_flash_with_attached_device_has_old_firmware(microbit): """ If the device has some unknown old firmware, force flash it. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": "1.0", "version": ("v1.9.2-34-gd64154c73 on 2017-09-01"), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.modes.microbit.uflash.find_microbit", return_value="/path/microbit"), mock.patch( "mu.modes.microbit.microfs.version", return_value=version_info), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = microbit mm = MicrobitMode(editor, view) mm.copy_main = mock.MagicMock() mm.set_buttons = mock.MagicMock() mm.flash_and_send = mock.MagicMock(side_effect=mm.flash_and_send) mm.flash() assert mm.flash_thread == mock_flasher assert editor.show_status_message.call_count == 1 mm.set_buttons.assert_called_once_with(flash=False, repl=False, files=False, plotter=False) mm.flash_and_send.assert_called_once_with(b"foo", "/path/microbit") mock_flasher_class.assert_called_once_with("/path/microbit", path_to_runtime=None, python_script=None) mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished) mock_flasher.on_flash_fail.connect.assert_called_once_with( mm.flash_failed) mock_flasher.start.assert_called_once_with()
def test_flash_script_too_big(): """ If the script in the current tab is too big, abort in the expected way. """ view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='x' * 8193) view.current_tab.label = 'foo' view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = True mm = MicrobitMode(editor, view) with mock.patch('mu.modes.microbit.can_minify', True): mm.flash() view.show_message.assert_called_once_with( 'Unable to flash "foo"', 'Our minifier tried but your ' 'script is too long!', 'Warning')
def test_flash_script_too_big_no_minify(): """ If the script in the current tab is too big, abort in the expected way. """ view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="x" * 8193) view.current_tab.label = "foo" view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False mm = MicrobitMode(editor, view) with mock.patch("mu.modes.microbit.can_minify", False): mm.flash() view.show_message.assert_called_once_with( 'Unable to flash "foo"', "Your script is too long!", "Warning" )
def test_force_flash_user_specified_device_path(): """ Ensure that if a micro:bit is not automatically found by uflash then it prompts the user to locate the device and, assuming a path was given, saves the hex in the expected location. """ version_info = { 'sysname': 'microbit', 'nodename': 'microbit', 'release': uflash.MICROPYTHON_VERSION, 'version': ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), 'machine': 'micro:bit with nRF51822', } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.contrib.uflash.find_microbit', return_value=None),\ mock.patch('mu.contrib.microfs.find_microbit', return_value=(None, None)),\ mock.patch('mu.contrib.microfs.get_serial'),\ mock.patch('mu.contrib.microfs.version', return_value=version_info),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.get_microbit_path = mock.MagicMock(return_value='bar') view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '' mm = MicrobitMode(editor, view) mm.flash() home = HOME_DIRECTORY view.get_microbit_path.assert_called_once_with(home) mock_flasher_class.assert_called_once_with([ 'bar', ], b'foo', None) mock_flasher.finished.connect.\ assert_called_once_with(mm.flash_finished)
def test_flash_script_too_big(): """ If the script in the current tab is too big, abort in the expected way. """ view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="x" * 8193) view.current_tab.label = "foo" view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = True mm = MicrobitMode(editor, view) mm.flash() view.show_message.assert_called_once_with( 'Unable to flash "foo"', "Our minifier tried but your " "script is too long!", "Warning", )
def test_flash_with_attached_device_has_old_firmware(): """ If the device has some unknown old firmware, force flash it. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": "1.0", "version": ("v1.9.2-34-gd64154c73 on 2017-09-01"), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch( "mu.modes.microbit.uflash.find_microbit", return_value="bar" ), mock.patch( "mu.modes.microbit.microfs.version", return_value=version_info ), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True ), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class ), mock.patch( "mu.modes.microbit.sys.platform", "win32" ): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" mm = MicrobitMode(editor, view) mm.find_device = mock.MagicMock(return_value=("bar", "990112345")) mm.copy_main = mock.MagicMock() mm.set_buttons = mock.MagicMock() mm.flash() assert mm.flash_thread == mock_flasher assert editor.show_status_message.call_count == 1 mm.set_buttons.assert_called_once_with(flash=False) mock_flasher_class.assert_called_once_with(["bar"], b"", None) mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished ) mock_flasher.on_flash_fail.connect.assert_called_once_with( mm.flash_failed ) mock_flasher.start.assert_called_once_with()
def test_flash_with_attached_device_has_latest_firmware_encounters_problem( microbit, ): """ If copy_main encounters a non-IOError, handle in a helpful manner. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": uflash.MICROPYTHON_VERSION, "version": ( "micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01" ), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch( "mu.modes.microbit.uflash.find_microbit", return_value="bar" ), mock.patch( "mu.modes.microbit.microfs.version", return_value=version_info ), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True ), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class ), mock.patch( "mu.modes.microbit.sys.platform", "win32" ): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = microbit mm = MicrobitMode(editor, view) mm.flash_failed = mock.MagicMock() error = ValueError("bang") mm.copy_main = mock.MagicMock(side_effect=error) mm.set_buttons = mock.MagicMock() mm.flash() assert mock_flasher_class.call_count == 0 mm.copy_main.assert_called_once_with() mm.flash_failed.assert_called_once_with(error)
def test_flash_with_attached_device_and_custom_runtime(microbit_v1_5): """ Ensure the custom runtime is passed into the DeviceFlasher thread. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.modes.base.BaseMode.workspace_dir", return_value=TEST_ROOT), mock.patch( "mu.modes.microbit.uflash.find_microbit", return_value="/foo/microbit/"), mock.patch( "mu.modes.microbit.os.path.isfile", return_value=True), mock.patch( "mu.modes.microbit.os.path.exists", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value="foo") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = True editor.current_device = microbit_v1_5 editor.microbit_runtime = os.path.join("tests", "customhextest.hex") mm = MicrobitMode(editor, view) mm.flash_and_send = mock.MagicMock(side_effect=mm.flash_and_send) mm.flash() assert editor.show_status_message.call_count == 1 assert (os.path.join("tests", "customhextest.hex") in editor.show_status_message.call_args[0][0]) assert mock_flasher_class.call_count == 1 mm.flash_and_send.assert_called_once_with( b"foo", "/foo/microbit/", os.path.join("tests", "customhextest.hex"), ) mock_flasher_class.assert_called_once_with( "/foo/microbit/", python_script=None, path_to_runtime=os.path.join("tests", "customhextest.hex"), ) mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished) mock_flasher.on_flash_fail.connect.assert_called_once_with( mm.flash_failed) mock_flasher.start.assert_called_once_with()
def test_force_flash_empty_script(microbit_v1_5): """ If the script to be flashed onto the device is empty, this is a signal to force a full flash of the "vanilla" / empty MicroPython runtime onto the device. """ version_info = { "sysname": "microbit", "nodename": "microbit", "release": uflash.MICROPYTHON_V1_VERSION, "version": ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), "machine": "micro:bit with nRF51822", } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch("mu.contrib.uflash.find_microbit", return_value="/path/microbit"), mock.patch( "mu.contrib.microfs.get_serial"), mock.patch( "mu.contrib.microfs.version", return_value=version_info), mock.patch( "mu.logic.os.path.exists", return_value=True), mock.patch( "mu.modes.microbit.DeviceFlasher", mock_flasher_class): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value=" ") view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = "" editor.current_device = microbit_v1_5 mm = MicrobitMode(editor, view) mm.flash_and_send = mock.MagicMock(side_effect=mm.flash_and_send) mm.flash() mm.flash_and_send.assert_called_once_with(b" ", "/path/microbit") mock_flasher_class.assert_called_once_with("/path/microbit", path_to_runtime=None, python_script=None) mock_flasher.finished.connect.assert_called_once_with( mm.flash_finished)
def test_flash_minify_no_minify(): view = mock.MagicMock() view.current_tab.label = 'foo' view.show_message = mock.MagicMock() script = '#' + ('x' * 8193) + '\n' view.current_tab.text = mock.MagicMock(return_value=script) editor = mock.MagicMock() editor.minify = True mm = MicrobitMode(editor, view) mm.set_buttons = mock.MagicMock() with mock.patch('mu.modes.microbit.can_minify', False): with mock.patch('nudatus.mangle', return_value='') as m: mm.flash() assert m.call_count == 0 view.show_message.assert_called_once_with( 'Unable to flash "foo"', 'Your script is too long' ' and the minifier ' 'isn\'t available', 'Warning')
def test_flash_no_tab(): """ If there are no active tabs simply return. """ editor = mock.MagicMock() view = mock.MagicMock() view.current_tab = None mm = MicrobitMode(editor, view) assert mm.flash() is None
def test_flash_no_tab(): """ If there are no active tabs simply return. """ editor = mock.MagicMock() view = mock.MagicMock() view.current_tab = None mm = MicrobitMode(editor, view) assert mm.flash() is None
def test_force_flash_empty_script(): """ If the script to be flashed onto the device is empty, this is a signal to force a full flash of the "vanilla" / empty MicroPython runtime onto the device. """ version_info = { 'sysname': 'microbit', 'nodename': 'microbit', 'release': uflash.MICROPYTHON_VERSION, 'version': ("micro:bit v0.1.0-b'e10a5ff' on 2018-6-8; MicroPython " "v1.9.2-34-gd64154c73 on 2017-09-01"), 'machine': 'micro:bit with nRF51822', } mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.contrib.uflash.find_microbit', return_value='bar'),\ mock.patch('mu.contrib.microfs.find_microbit', return_value=('COM0', '12345')),\ mock.patch('mu.contrib.microfs.get_serial'),\ mock.patch('mu.contrib.microfs.version', return_value=version_info),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value=' ') view.show_message = mock.MagicMock() editor = mock.MagicMock() editor.minify = False editor.microbit_runtime = '' mm = MicrobitMode(editor, view) mm.flash() mock_flasher_class.assert_called_once_with([ 'bar', ], b'', None) mock_flasher.finished.connect.\ assert_called_once_with(mm.flash_finished)
def test_flash_with_attached_device_and_custom_runtime(): """ Ensure the custom runtime is passed into the DeviceFlasher thread. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.modes.microbit.get_settings_path', return_value='tests/settingswithcustomhex.json'), \ mock.patch('mu.modes.base.BaseMode.workspace_dir', return_value=TEST_ROOT), \ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.flash() assert editor.show_status_message.call_count == 1 assert os.path.join('tests', 'customhextest.hex') in \ editor.show_status_message.call_args[0][0] assert mock_flasher_class.call_count == 1
def test_flash_existing_user_specified_device_path(): """ Ensure that if a micro:bit is not automatically found by uflash and the user has previously specified a path to the device, then the hex is saved in the specified location. """ mock_flasher = mock.MagicMock() mock_flasher_class = mock.MagicMock(return_value=mock_flasher) with mock.patch('mu.logic.uflash.find_microbit', return_value=None),\ mock.patch('mu.logic.os.path.exists', return_value=True),\ mock.patch('mu.modes.microbit.DeviceFlasher', mock_flasher_class), \ mock.patch('mu.modes.microbit.sys.platform', 'win32'): view = mock.MagicMock() view.current_tab.text = mock.MagicMock(return_value='foo') view.get_microbit_path = mock.MagicMock(return_value='bar') view.show_message = mock.MagicMock() editor = mock.MagicMock() mm = MicrobitMode(editor, view) mm.user_defined_microbit_path = 'baz' mm.flash() assert view.get_microbit_path.call_count == 0 assert editor.show_status_message.call_count == 1 mock_flasher_class.assert_called_once_with(['baz', ], b'foo', None)