Esempio n. 1
0
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
Esempio n. 2
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)
Esempio n. 3
0
def test_open_hex():
    """
    Tries to open hex files with uFlash.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mock_open = mock.mock_open()
    hex_extracted = 'RECOVERED'
    with mock.patch('builtins.open', mock_open), \
            mock.patch('mu.contrib.uflash.extract_script',
                       return_value=hex_extracted) as extract_script:
        text = mm.open_file('path_to_file.hex')
    assert text == hex_extracted
    assert extract_script.call_count == 1
    assert mock_open.call_count == 1

    mock_open.reset_mock()
    with mock.patch('builtins.open', mock_open), \
            mock.patch('mu.contrib.uflash.extract_script',
                       return_value=hex_extracted) as extract_script:
        text = mm.open_file('path_to_file.HEX')
    assert text == hex_extracted
    assert extract_script.call_count == 1
    assert mock_open.call_count == 1
Esempio n. 4
0
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()
Esempio n. 5
0
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')
Esempio n. 6
0
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)
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
def test_custom_hex_read():
    """
    Test that a custom hex file path can be read
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.get_settings_path',
                    return_value='tests/settingswithcustomhex.json'), \
            mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\
            mock.patch('mu.modes.base.BaseMode.workspace_dir',
                       return_value=TEST_ROOT):
        assert "customhextest.hex" in mm.get_hex_path()
    """
    Test that a corrupt settings file returns None for the
    runtime hex path
    """
    with mock.patch('mu.modes.microbit.get_settings_path',
                    return_value='tests/settingscorrupt.json'), \
            mock.patch('mu.modes.base.BaseMode.workspace_dir',
                       return_value=TEST_ROOT):
        assert mm.get_hex_path() is None
    """
    Test that a missing settings file returns None for the
    runtime hex path
    """
    with mock.patch('mu.modes.microbit.get_settings_path',
                    return_value='tests/settingswithmissingcustomhex.json'), \
            mock.patch('mu.modes.base.BaseMode.workspace_dir',
                       return_value=TEST_ROOT):
        assert mm.get_hex_path() is None
Esempio n. 10
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="/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)
Esempio n. 11
0
def test_custom_hex_read():
    """
    Test that a custom hex file path can be read
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.get_settings_path',
                    return_value='tests/settingswithcustomhex.json'), \
            mock.patch('mu.modes.microbit.os.path.exists', return_value=True),\
            mock.patch('mu.modes.base.BaseMode.workspace_dir',
                       return_value=TEST_ROOT):
        assert "customhextest.hex" in mm.get_hex_path()
    """
    Test that a corrupt settings file returns None for the
    runtime hex path
    """
    with mock.patch('mu.modes.microbit.get_settings_path',
                    return_value='tests/settingscorrupt.json'), \
            mock.patch('mu.modes.base.BaseMode.workspace_dir',
                       return_value=TEST_ROOT):
        assert mm.get_hex_path() is None
    """
    Test that a missing settings file returns None for the
    runtime hex path
    """
    with mock.patch('mu.modes.microbit.get_settings_path',
                    return_value='tests/settingswithmissingcustomhex.json'), \
            mock.patch('mu.modes.base.BaseMode.workspace_dir',
                       return_value=TEST_ROOT):
        assert mm.get_hex_path() is None
Esempio n. 12
0
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
Esempio n. 13
0
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
Esempio n. 14
0
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
Esempio n. 15
0
def test_open_ignore_non_hex():
    """
    Ignores any other than hex file types.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mock_open = mock.mock_open()
    with mock.patch("builtins.open", mock_open), mock.patch(
            "mu.contrib.uflash.extract_script",
            return_value="Should not be called") as extract_script:
        text, newline = mm.open_file("path_to_file.py")
    assert text is None
    assert newline is None
    assert extract_script.call_count == 0
    assert mock_open.call_count == 0

    mock_open.reset_mock()
    with mock.patch("builtins.open", mock_open), mock.patch(
            "mu.contrib.uflash.extract_script",
            return_value="Should not be called") as extract_script:
        text, newline = mm.open_file("file_no_extension")
    assert text is None
    assert newline is None
    assert extract_script.call_count == 0
    assert mock_open.call_count == 0
Esempio n. 16
0
def test_copy_main_with_python_script():
    """
    If copy_main is called and there's something in self.python_script, then
    use microfs to write it to the device's on-board filesystem, followed by
    a soft-reboot.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.python_script = 'import love'
    with mock.patch('mu.modes.microbit.microfs') as mock_microfs:
        mock_microfs.execute.return_value = ('', '')
        mm.copy_main()
        serial = mock_microfs.get_serial()
        expected = [
            "fd = open('main.py', 'wb')",
            "f = fd.write",
            "f('import love')",
            "fd.close()",
        ]
        mock_microfs.execute.assert_called_once_with(expected, serial)
        serial.write.call_count == 2
        assert serial.write.call_args_list[0][0][0] == b'import microbit\r\n'
        assert serial.write.call_args_list[1][0][0] == b'microbit.reset()\r\n'
        # The script is re-set to empty.
        assert mm.python_script == ''
Esempio n. 17
0
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)
Esempio n. 18
0
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()
Esempio n. 19
0
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
Esempio n. 20
0
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
Esempio n. 21
0
def test_api():
    """
    Ensure the right thing comes back from the API.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    api = mm.api()
    assert api == SHARED_APIS + MICROBIT_APIS
Esempio n. 22
0
def test_api():
    """
    Ensure the right thing comes back from the API.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    api = mm.api()
    assert api == SHARED_APIS + MICROBIT_APIS
Esempio n. 23
0
def test_remove_fs_no_fs():
    """
    Removing a non-existent file system raises a RuntimeError.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.fs = None
    with pytest.raises(RuntimeError):
        mm.remove_fs()
Esempio n. 24
0
def test_remove_fs_no_fs():
    """
    Removing a non-existent file system raises a RuntimeError.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.fs = None
    with pytest.raises(RuntimeError):
        mm.remove_fs()
Esempio n. 25
0
def test_api():
    """
    Ensure the right thing comes back from the API.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    api = mm.api()
    assert isinstance(api, list)
    assert api
Esempio n. 26
0
def test_copy_main_with_python_script_encounters_device_error():
    """
    If the device returns an error, then copy_main should raise an IOError.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch("mu.modes.microbit.microfs") as mock_microfs:
        mock_microfs.execute.return_value = ("", "BANG!")
        with pytest.raises(IOError):
            mm.copy_main("import love")
Esempio n. 27
0
def test_add_fs_with_repl():
    """
    If the REPL is active, you can't add the file system pane.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.repl = True
    with mock.patch('mu.modes.microbit.microfs.get_serial', return_value=True):
        mm.add_fs()
    assert view.add_filesystem.call_count == 0
Esempio n. 28
0
def test_add_fs_no_device():
    """
    If there's no device attached then ensure a helpful message is displayed.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    editor.current_device = None
    mm = MicrobitMode(editor, view)
    mm.add_fs()
    assert view.show_message.call_count == 1
Esempio n. 29
0
def test_add_fs_with_repl():
    """
    If the REPL is active, you can't add the file system pane.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.repl = True
    with mock.patch('mu.modes.microbit.microfs.get_serial', return_value=True):
        mm.add_fs()
    assert view.add_filesystem.call_count == 0
Esempio n. 30
0
def test_copy_main_no_python_script():
    """
    If copy_main is called and there's nothing in provided script, then
    don't do anything.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch("mu.modes.microbit.microfs") as mock_microfs:
        mm.copy_main("")
        assert mock_microfs.execute.call_count == 0
Esempio n. 31
0
def test_remove_fs():
    """
    Removing the file system results in the expected state.
    """
    view = mock.MagicMock()
    view.remove_repl = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.fs = True
    mm.remove_fs()
    assert view.remove_filesystem.call_count == 1
    assert mm.fs is None
Esempio n. 32
0
def test_add_fs_no_device():
    """
    If there's no device attached then ensure a helpful message is displayed.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    ex = IOError('BOOM')
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.microfs.get_serial', side_effect=ex):
        mm.add_fs()
    assert view.show_message.call_count == 1
Esempio n. 33
0
def test_toggle_files_with_plotter():
    """
    If the plotter is active, ensure a helpful message is displayed.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.plotter = True
    mm.fs = None
    mm.toggle_files(None)
    assert view.show_message.call_count == 1
Esempio n. 34
0
def test_toggle_repl():
    """
    If the file system is active, show a helpful message instead.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.MicroPythonMode.toggle_repl') as tr:
        mm.repl = None
        mm.toggle_repl(None)
        tr.assert_called_once_with(None)
Esempio n. 35
0
def test_add_fs_no_device():
    """
    If there's no device attached then ensure a helpful message is displayed.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.microfs.find_microbit',
                    return_value=False):
        mm.add_fs()
    assert view.show_message.call_count == 1
Esempio n. 36
0
def test_add_fs_no_device():
    """
    If there's no device attached then ensure a helpful message is displayed.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    ex = IOError('BOOM')
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.microfs.get_serial', side_effect=ex):
        mm.add_fs()
    assert view.show_message.call_count == 1
Esempio n. 37
0
def test_remove_fs():
    """
    Removing the file system results in the expected state.
    """
    view = mock.MagicMock()
    view.remove_repl = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.fs = True
    mm.remove_fs()
    assert view.remove_filesystem.call_count == 1
    assert mm.fs is None
Esempio n. 38
0
def test_on_data_flood():
    """
    Ensure the "Files" button is re-enabled before calling the base method.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.set_buttons = mock.MagicMock()
    with mock.patch('builtins.super') as mock_super:
        mm.on_data_flood()
        mm.set_buttons.assert_called_once_with(files=True)
        mock_super().on_data_flood.assert_called_once_with()
Esempio n. 39
0
def test_toggle_repl():
    """
    If the file system is active, show a helpful message instead.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.MicroPythonMode.toggle_repl') as tr:
        mm.repl = None
        mm.toggle_repl(None)
        tr.assert_called_once_with(None)
Esempio n. 40
0
def test_add_fs_no_repl():
    """
    It's possible to add the file system pane if the REPL is inactive.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.microfs.get_serial', return_value=True):
        mm.add_fs()
    workspace = mm.workspace_dir()
    view.add_filesystem.assert_called_once_with(home=workspace)
    assert mm.fs
Esempio n. 41
0
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')
Esempio n. 42
0
def test_flash_finished():
    """
    Ensure state is set back as expected when the flashing thread is finished.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.flash_thread = mock.MagicMock()
    mm.flash_timer = mock.MagicMock()
    mm.flash_finished()
    view.button_bar.slots['flash'].setEnabled.assert_called_once_with(True)
    editor.show_status_message.assert_called_once_with("Finished flashing.")
    assert mm.flash_thread is None
    assert mm.flash_timer is None
Esempio n. 43
0
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)
Esempio n. 44
0
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')
Esempio n. 45
0
def test_flash_force_with_attached_device_as_windows():
    """
    Ensure the expected calls are made to DeviceFlasher and a helpful status
    message is enacted as if 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_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=('bar', '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', '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/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()
Esempio n. 46
0
def test_add_fs_no_repl():
    """
    It's possible to add the file system pane if the REPL is inactive.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.FileManager') as mock_fm,\
            mock.patch('mu.modes.microbit.QThread'),\
            mock.patch('mu.modes.microbit.microfs.get_serial',
                       return_value=True):
        mm.add_fs()
        workspace = mm.workspace_dir()
        view.add_filesystem.assert_called_once_with(workspace, mock_fm())
        assert mm.fs
Esempio n. 47
0
def test_microbit_mode_no_charts():
    """
    If QCharts is not available, ensure plotter is not displayed.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    with mock.patch('mu.modes.microbit.CHARTS', False):
        actions = mm.actions()
        assert len(actions) == 3
        assert actions[0]['name'] == 'flash'
        assert actions[0]['handler'] == mm.flash
        assert actions[1]['name'] == 'files'
        assert actions[1]['handler'] == mm.toggle_files
        assert actions[2]['name'] == 'repl'
        assert actions[2]['handler'] == mm.toggle_repl
Esempio n. 48
0
def test_flash_failed():
    """
    Ensure things are cleaned up if flashing failed.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mock_timer = mock.MagicMock()
    mm.flash_timer = mock_timer
    mm.flash_thread = mock.MagicMock()
    mm.flash_failed('Boom')
    assert view.show_message.call_count == 1
    view.button_bar.slots['flash'].setEnabled.assert_called_once_with(True)
    assert mm.flash_thread is None
    assert mm.flash_timer is None
    mock_timer.stop.assert_called_once_with()
Esempio n. 49
0
def test_toggle_plotter():
    """
    Ensure the plotter is toggled on if the file system pane is absent.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)

    def side_effect(*args, **kwargs):
        mm.plotter = True

    with mock.patch('mu.modes.microbit.MicroPythonMode.toggle_plotter',
                    side_effect=side_effect) as tp:
        mm.plotter = None
        mm.toggle_plotter(None)
        tp.assert_called_once_with(None)
        view.button_bar.slots['files'].\
            setEnabled.assert_called_once_with(False)
Esempio n. 50
0
def test_toggle_repl():
    """
    Ensure the REPL is able to toggle on if there's no file system pane.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)

    def side_effect(*args, **kwargs):
        mm.repl = True

    with mock.patch('mu.modes.microbit.MicroPythonMode.toggle_repl',
                    side_effect=side_effect) as tr:
        mm.repl = None
        mm.toggle_repl(None)
        tr.assert_called_once_with(None)
        view.button_bar.slots['files'].\
            setEnabled.assert_called_once_with(False)
Esempio n. 51
0
def test_toggle_plotter_no_repl_or_plotter():
    """
    Ensure the file system button is enabled if the plotter toggles off and the
    repl isn't active.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)

    def side_effect(*args, **kwargs):
        mm.plotter = False
        mm.repl = False

    with mock.patch('mu.modes.microbit.MicroPythonMode.toggle_plotter',
                    side_effect=side_effect) as tp:
        mm.plotter = None
        mm.toggle_plotter(None)
        tp.assert_called_once_with(None)
        view.button_bar.slots['files'].\
            setEnabled.assert_called_once_with(True)
Esempio n. 52
0
def test_microbit_mode():
    """
    Sanity check for setting up the mode.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    assert mm.name == 'BBC micro:bit'
    assert mm.description is not None
    assert mm.icon == 'microbit'
    assert mm.editor == editor
    assert mm.view == view

    actions = mm.actions()
    assert len(actions) == 4
    assert actions[0]['name'] == 'flash'
    assert actions[0]['handler'] == mm.flash
    assert actions[1]['name'] == 'files'
    assert actions[1]['handler'] == mm.toggle_files
    assert actions[2]['name'] == 'repl'
    assert actions[2]['handler'] == mm.toggle_repl
    assert actions[3]['name'] == 'plotter'
    assert actions[3]['handler'] == mm.toggle_plotter
Esempio n. 53
0
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
Esempio n. 54
0
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)
Esempio n. 55
0
def test_toggle_files_on():
    """
    If the fs is off, toggle it on.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.add_fs = mock.MagicMock()
    mm.repl = None
    mm.fs = None
    mm.toggle_files(None)
    assert mm.add_fs.call_count == 1
Esempio n. 56
0
def test_toggle_files_off():
    """
    If the fs is on, toggle if off.
    """
    view = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.remove_fs = mock.MagicMock()
    mm.repl = None
    mm.fs = True
    mm.toggle_files(None)
    assert mm.remove_fs.call_count == 1
Esempio n. 57
0
def test_toggle_repl_with_fs():
    """
    If the file system is active, show a helpful message instead.
    """
    view = mock.MagicMock()
    view.show_message = mock.MagicMock()
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)
    mm.remove_repl = mock.MagicMock()
    mm.repl = None
    mm.fs = True
    mm.toggle_repl(None)
    assert view.show_message.call_count == 1
Esempio n. 58
0
def test_toggle_files_on():
    """
    If the fs is off, toggle it on.
    """
    view = mock.MagicMock()
    view.button_bar.slots = {
        'repl': mock.MagicMock(),
        'plotter': mock.MagicMock(),
    }
    editor = mock.MagicMock()
    mm = MicrobitMode(editor, view)

    def side_effect(*args, **kwargs):
        mm.fs = True

    mm.add_fs = mock.MagicMock(side_effect=side_effect)
    mm.repl = None
    mm.fs = None
    mm.toggle_files(None)
    assert mm.add_fs.call_count == 1
    view.button_bar.slots['repl'].setEnabled.assert_called_once_with(False)
    view.button_bar.slots['plotter'].setEnabled.assert_called_once_with(False)