File: test_adafruit.py

package info (click to toggle)
mu-editor 1.0.3%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 9,440 kB
  • sloc: python: 16,321; makefile: 129; xml: 29; sh: 7
file content (168 lines) | stat: -rw-r--r-- 6,038 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# -*- coding: utf-8 -*-
"""
Tests for the Adafruit mode.
"""
import pytest
import ctypes
from mu.modes.adafruit import AdafruitMode
from mu.modes.api import ADAFRUIT_APIS, SHARED_APIS
from unittest import mock


def test_adafruit_mode():
    """
    Sanity check for setting up the mode.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    assert am.name == 'Adafruit CircuitPython'
    assert am.description is not None
    assert am.icon == 'adafruit'
    assert am.editor == editor
    assert am.view == view

    actions = am.actions()
    assert len(actions) == 2
    assert actions[0]['name'] == 'serial'
    assert actions[0]['handler'] == am.toggle_repl
    assert actions[1]['name'] == 'plotter'
    assert actions[1]['handler'] == am.toggle_plotter
    assert 'code' not in am.module_names


def test_adafruit_mode_no_charts():
    """
    If QCharts is not available, ensure the plotter feature is not available.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with mock.patch('mu.modes.adafruit.CHARTS', False):
        actions = am.actions()
        assert len(actions) == 1
        assert actions[0]['name'] == 'serial'
        assert actions[0]['handler'] == am.toggle_repl


def test_workspace_dir_posix_exists():
    """
    Simulate being on os.name == 'posix' and a call to "mount" returns a
    record indicating a connected device.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with open('tests/modes/mount_exists.txt', 'rb') as fixture_file:
        fixture = fixture_file.read()
        with mock.patch('os.name', 'posix'):
            with mock.patch('mu.modes.adafruit.check_output',
                            return_value=fixture):
                assert am.workspace_dir() == '/media/ntoll/CIRCUITPY'


def test_workspace_dir_posix_no_mount_command():
    """
    When the user doesn't have administrative privileges on OSX then the mount
    command isn't on their path. In which case, check Mu uses the more
    explicit /sbin/mount instead.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with open('tests/modes/mount_exists.txt', 'rb') as fixture_file:
        fixture = fixture_file.read()
    mock_check = mock.MagicMock(side_effect=[FileNotFoundError, fixture])
    with mock.patch('os.name', 'posix'), \
            mock.patch('mu.modes.adafruit.check_output', mock_check):
        assert am.workspace_dir() == '/media/ntoll/CIRCUITPY'
        assert mock_check.call_count == 2
        assert mock_check.call_args_list[0][0][0] == 'mount'
        assert mock_check.call_args_list[1][0][0] == '/sbin/mount'


def test_workspace_dir_posix_missing():
    """
    Simulate being on os.name == 'posix' and a call to "mount" returns a
    no records associated with a micro:bit device.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with open('tests/modes/mount_missing.txt', 'rb') as fixture_file:
        fixture = fixture_file.read()
        with mock.patch('os.name', 'posix'):
            with mock.patch('mu.modes.adafruit.check_output',
                            return_value=fixture),\
                    mock.patch('mu.modes.adafruit.'
                               'MicroPythonMode.workspace_dir') as mpm:
                mpm.return_value = 'foo'
                assert am.workspace_dir() == 'foo'


def test_workspace_dir_nt_exists():
    """
    Simulate being on os.name == 'nt' and a disk with a volume name 'CIRCUITPY'
    exists indicating a connected device.
    """
    mock_windll = mock.MagicMock()
    mock_windll.kernel32 = mock.MagicMock()
    mock_windll.kernel32.GetVolumeInformationW = mock.MagicMock()
    mock_windll.kernel32.GetVolumeInformationW.return_value = None
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with mock.patch('os.name', 'nt'):
        with mock.patch('os.path.exists', return_value=True):
            return_value = ctypes.create_unicode_buffer('CIRCUITPY')
            with mock.patch('ctypes.create_unicode_buffer',
                            return_value=return_value):
                ctypes.windll = mock_windll
                assert am.workspace_dir() == 'A:\\'


def test_workspace_dir_nt_missing():
    """
    Simulate being on os.name == 'nt' and a disk with a volume name 'CIRCUITPY'
    does not exist for a device.
    """
    mock_windll = mock.MagicMock()
    mock_windll.kernel32 = mock.MagicMock()
    mock_windll.kernel32.GetVolumeInformationW = mock.MagicMock()
    mock_windll.kernel32.GetVolumeInformationW.return_value = None
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with mock.patch('os.name', 'nt'):
        with mock.patch('os.path.exists', return_value=True):
            return_value = ctypes.create_unicode_buffer(1024)
            with mock.patch('ctypes.create_unicode_buffer',
                            return_value=return_value), \
                    mock.patch('mu.modes.adafruit.'
                               'MicroPythonMode.workspace_dir') as mpm:
                mpm.return_value = 'foo'
                ctypes.windll = mock_windll
                assert am.workspace_dir() == 'foo'


def test_workspace_dir_unknown_os():
    """
    Raises a NotImplementedError if the host OS is not supported.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    with mock.patch('os.name', 'foo'):
        with pytest.raises(NotImplementedError) as ex:
            am.workspace_dir()
    assert ex.value.args[0] == 'OS "foo" not supported.'


def test_api():
    """
    Ensure the correct API definitions are returned.
    """
    editor = mock.MagicMock()
    view = mock.MagicMock()
    am = AdafruitMode(editor, view)
    assert am.api() == SHARED_APIS + ADAFRUIT_APIS