|
| 1 | +from pathlib import Path |
| 2 | +from typing import List |
| 3 | + |
| 4 | +import pytest |
| 5 | +from click.testing import CliRunner |
| 6 | +from mock import Mock |
| 7 | +from pytest_mock import MockerFixture |
| 8 | + |
| 9 | +# # module under test : |
| 10 | +from mpflash import cli_main |
| 11 | +from mpflash.ask_input import DownloadParams |
| 12 | +from mpflash.mpremoteboard import MPRemoteBoard |
| 13 | + |
| 14 | +# mark all tests |
| 15 | +pytestmark = pytest.mark.mpflash |
| 16 | + |
| 17 | + |
| 18 | +########################################################################################## |
| 19 | +def fakeboard(serialport="COM99"): |
| 20 | + fake = MPRemoteBoard(serialport) |
| 21 | + fake.connected = True |
| 22 | + fake.family = "micropython" |
| 23 | + fake.port = "esp32" |
| 24 | + fake.board = "ESP32_GENERIC" |
| 25 | + fake.version = "1.22.0" |
| 26 | + fake.cpu = "ESP32" |
| 27 | + return fake |
| 28 | + |
| 29 | + |
| 30 | +def fake_ask_missing_params(params: DownloadParams, action: str = "flash") -> DownloadParams: |
| 31 | + # no input during tests |
| 32 | + return params |
| 33 | + |
| 34 | + |
| 35 | +########################################################################################## |
| 36 | +# flash |
| 37 | + |
| 38 | + |
| 39 | +@pytest.mark.parametrize( |
| 40 | + "id, ex_code, args", |
| 41 | + [ |
| 42 | + ("10", 0, ["flash"]), |
| 43 | + ("20", 0, ["flash", "--version", "1.22.0"]), |
| 44 | + ("21", 0, ["flash", "--version", "stable"]), |
| 45 | + ("30", 0, ["flash", "--board", "ESP32_GENERIC"]), |
| 46 | + ("31", 0, ["flash", "--board", "?"]), |
| 47 | + ("40", 0, ["flash", "--no-bootloader"]), |
| 48 | + # faulty |
| 49 | + # ("81", -1, ["flash", "--board", "RPI_PICO", "--board", "ESP32_GENERIC"]), |
| 50 | + # ("82", -1, ["flash", "--version", "preview", "--version", "1.22.0"]), |
| 51 | + ], |
| 52 | +) |
| 53 | +@pytest.mark.parametrize("serialport", ["COM99"]) |
| 54 | +def test_mpflash_flash(id, ex_code, args: List[str], mocker: MockerFixture, serialport: str): |
| 55 | + |
| 56 | + # fake COM99 as connected board |
| 57 | + fake = fakeboard(serialport) |
| 58 | + |
| 59 | + m_mpr_connected = mocker.patch("mpflash.worklist.MPRemoteBoard", return_value=fake) |
| 60 | + m_mpr_connected = mocker.patch("mpflash.worklist.MPRemoteBoard.connected_boards", return_value=fake.serialport) |
| 61 | + |
| 62 | + m_connected_ports_boards = mocker.patch( |
| 63 | + "mpflash.cli_flash.connected_ports_boards", |
| 64 | + return_value=(["esp32"], ["ESP32_GENERIC"]), |
| 65 | + autospec=True, |
| 66 | + ) |
| 67 | + m_flash_list = mocker.patch("mpflash.cli_flash.flash_list", return_value=None, autospec=True) |
| 68 | + m_ask_missing_params = mocker.patch( |
| 69 | + "mpflash.cli_flash.ask_missing_params", |
| 70 | + Mock(side_effect=fake_ask_missing_params), |
| 71 | + ) |
| 72 | + |
| 73 | + runner = CliRunner() |
| 74 | + result = runner.invoke(cli_main.cli, args) |
| 75 | + |
| 76 | + if not "--board" in args: |
| 77 | + m_connected_ports_boards.assert_called_once() |
| 78 | + |
| 79 | + m_ask_missing_params.assert_called_once() |
| 80 | + m_mpr_connected.assert_called_once() |
| 81 | + # m_flash_list.assert_called_once() |
| 82 | + assert result.exit_code == ex_code |
| 83 | + |
| 84 | + |
| 85 | +# TODO : Add more tests scenarios for flash |
| 86 | + |
| 87 | + |
| 88 | +@pytest.mark.parametrize( |
| 89 | + "id, serialports, ports, boards", |
| 90 | + [ |
| 91 | + ("one", ["COM99"], ["esp32"], ["ESP32_GENERIC"]), |
| 92 | + ("multiple", ["COM99", "COM100"], ["esp32", "samd"], ["ESP32_GENERIC", "SEEED_WIO_TERMINAL"]), |
| 93 | + ("None", [], [], []), |
| 94 | + ("linux", ["/dev/ttyusb0"], ["rp2"], ["ARDUINO_NANO_RP2040_CONNECT"]), |
| 95 | + ], |
| 96 | +) |
| 97 | +def test_mpflash_connected_boards( |
| 98 | + id, |
| 99 | + serialports: List[str], |
| 100 | + ports: List[str], |
| 101 | + boards: List[str], |
| 102 | + mocker: MockerFixture, |
| 103 | +): |
| 104 | + # no boards specified - detect connected boards |
| 105 | + args = ["flash"] |
| 106 | + |
| 107 | + fakes = [fakeboard(port) for port in serialports] |
| 108 | + |
| 109 | + m_connected_ports_boards = mocker.patch( |
| 110 | + "mpflash.cli_flash.connected_ports_boards", |
| 111 | + return_value=(ports, boards), |
| 112 | + autospec=True, |
| 113 | + ) |
| 114 | + m_flash_list = mocker.patch("mpflash.cli_flash.flash_list", return_value=None, autospec=True) |
| 115 | + m_ask_missing_params = mocker.patch( |
| 116 | + "mpflash.cli_flash.ask_missing_params", |
| 117 | + Mock(side_effect=fake_ask_missing_params), |
| 118 | + ) |
| 119 | + |
| 120 | + m_full_auto_worklist = mocker.patch("mpflash.cli_flash.full_auto_worklist", return_value=[]) |
| 121 | + m_manual_worklist = mocker.patch("mpflash.cli_flash.manual_worklist", return_value=[]) |
| 122 | + m_single_auto_worklist = mocker.patch("mpflash.cli_flash.single_auto_worklist", return_value=[]) |
| 123 | + |
| 124 | + runner = CliRunner() |
| 125 | + result = runner.invoke(cli_main.cli, args) |
| 126 | + |
| 127 | + if serialports: |
| 128 | + m_full_auto_worklist.assert_called_once() |
| 129 | + m_manual_worklist.assert_not_called() |
| 130 | + m_single_auto_worklist.assert_not_called() |
| 131 | + |
| 132 | + m_connected_ports_boards.assert_called_once() |
| 133 | + m_ask_missing_params.assert_called_once() |
| 134 | + |
| 135 | + if serialports: |
| 136 | + assert result.exit_code == 0 |
| 137 | + else: |
| 138 | + assert result.exit_code == 1 |
0 commit comments