Skip to content
This repository was archived by the owner on Dec 23, 2021. It is now read-only.

Added unit tests and removed some unused test code #174

Merged
merged 29 commits into from
Jan 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5259563
Initial tests still a lot to do
Jan 21, 2020
fda4edc
Updated package.json script for python tests
Jan 21, 2020
c652f08
Purposely made error to test pipeline
Jan 21, 2020
d2b16ff
Corrected spelling error
Jan 21, 2020
ab18b47
commented out broken test
Jan 22, 2020
bca1b23
updated tests
Jan 23, 2020
5b9db94
updated tests
Jan 23, 2020
ffce53e
Updated imports
Jan 23, 2020
8c6e95d
updated imports
Jan 23, 2020
fc237c8
Merge branch 'dev' into users/t-vali/python-tests
vandyliu Jan 23, 2020
c452cb2
Removed comments and other accidental changes
Jan 23, 2020
97badd4
Merge branch 'users/t-vali/python-tests' of https://github.com/micros…
Jan 23, 2020
aad0cc3
removed unused import
Jan 23, 2020
bd87e99
removed unused import
vandyliu Jan 23, 2020
db53ed8
Updated tests from comments
Jan 23, 2020
f803372
added docs for testing
Jan 23, 2020
42b3d24
Updated broken test
Jan 23, 2020
fb178f5
uncommented some necessary code
Jan 23, 2020
060eb78
Merge branch 'dev' into users/t-vali/python-tests
xnkevinnguyen Jan 24, 2020
f9d2cef
fixed merge conflicts
Jan 24, 2020
08f3cf6
merge conflicts resolved
Jan 25, 2020
2872310
Updated with black formatting
Jan 25, 2020
4bc6f7f
added test
Jan 25, 2020
912d475
Merge branch 'dev' into users/t-vali/python-tests
xnkevinnguyen Jan 27, 2020
328b613
Merge branch 'dev' into users/t-vali/python-tests
Jan 27, 2020
3b4035d
Uncommented necessary code
Jan 28, 2020
44f202a
Merge branch 'dev' into users/t-vali/python-tests
vandyliu Jan 28, 2020
12e3eed
Added debugger tests
vandyliu Jan 28, 2020
f1b1157
Merge branch 'dev' into users/t-vali/python-tests
xnkevinnguyen Jan 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/developers-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@

6. Start running the extension locally by pressing F5 or going to VS Code Debug menu and select 'Start debugging'

## Testing

- To run unit tests, run the command: `npm run test` in the root level directory.
- You will need Pytest installed for the Python tests to run correctly
- To run just the python tests, run the command: `pytest src` or `python -m pytest src` in the root level directory.

## Notes on how to use it

- [Documentation to use the Extension](/docs/how-to-use.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ def button_press(data):

# Event : Sensor changed (Temperature, light, Motion)
@sio.on("sensor_changed")
def button_press(data):
def sensor_changed(data):
__update_api_state(data, CONSTANTS.EVENTS_SENSOR_CHANGED)
4 changes: 2 additions & 2 deletions src/adafruit_circuitplayground/express.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import json
import sys
import os
from playsound import playsound
import playsound
from .pixel import Pixel
from . import utils
from . import constants as CONSTANTS
Expand Down Expand Up @@ -162,7 +162,7 @@ def play_file(self, file_name):
if sys.implementation.version[0] >= 3:
if file_name.endswith(".wav"):
try:
playsound(abs_path_wav_file)
playsound.playsound(abs_path_wav_file)
except:
# TODO TASK: 29054 Verfication of a "valid" .wav file
raise EnvironmentError(CONSTANTS.NOT_SUITABLE_FILE_ERROR)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import pytest
import json # Remove
from unittest import mock
import socketio

from .. import express
from .. import debugger_communication_client


class TestDebuggerCommunicationClient(object):
@mock.patch("socketio.Client.connect")
def test_init_connection(self, mock_connect):
mock_connect.return_value = None
debugger_communication_client.init_connection()
mock_connect.assert_called_once()

def test_init_connection1(self):
socketio.Client.connect = mock.Mock()
socketio.Client.connect.return_value = None
debugger_communication_client.init_connection()
socketio.Client.connect.assert_called_once()

def test_update_state(self):
socketio.Client.emit = mock.Mock()
socketio.Client.emit.return_value = None
debugger_communication_client.update_state({})
socketio.Client.emit.assert_called_once()

@mock.patch.dict(
express.cpx._Express__state,
{"button_a": False, "button_b": False, "switch": True},
clear=True,
)
def test_button_press(self):
data = {"button_a": True, "button_b": True, "switch": True}
serialized_data = json.dumps(data)
debugger_communication_client.button_press(serialized_data)
assert data == express.cpx._Express__state

@mock.patch.dict(
express.cpx._Express__state,
{"temperature": 0, "light": 0, "motion_x": 0, "motion_y": 0, "motion_z": 0},
clear=True,
)
def test_sensor_changed(self):
data = {
"temperature": 1,
"light": 2,
"motion_x": 3,
"motion_y": 4,
"motion_z": 5,
}
serialized_data = json.dumps(data)
debugger_communication_client.sensor_changed(serialized_data)
assert data == express.cpx._Express__state

@mock.patch("builtins.print")
@mock.patch.dict(express.cpx._Express__state, {}, clear=True)
def test_update_api_state_fail(self, mocked_print):
data = []
debugger_communication_client.sensor_changed(data)
# Exception is caught and a print is stated to stderr
mocked_print.assert_called_once()
103 changes: 48 additions & 55 deletions src/adafruit_circuitplayground/test/test_express.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest
from unittest import mock

import playsound
from ..express import Express
from ..pixel import Pixel

Expand All @@ -18,105 +20,96 @@ def setup_method(self):
self.pixels = Pixel(self.__state)
self.__speaker_enabled = False

def test_acceleration(self):
mock_motion_x = 10
mock_motion_y = -10
mock_motion_z = -20
self.cpx._Express__state["motion_x"] = mock_motion_x
self.cpx._Express__state["motion_y"] = mock_motion_y
self.cpx._Express__state["motion_z"] = mock_motion_z
accel = self.cpx.acceleration
assert accel[0] == 10
assert accel[1] == -10
assert accel[2] == -20

def test_button_a(self):
self.cpx._Express__state["button_a"] = True
assert True == self.cpx.button_a
assert self.cpx.button_a

def test_button_b(self):
self.cpx._Express__state["button_b"] = True
assert True == self.cpx.button_b
assert self.cpx.button_b

def test_taps(self):
self.cpx._Express__state["detect_taps"] = 2
assert 2 == self.cpx.detect_taps

@pytest.mark.parametrize("taps, expected", [(1, 1), (2, 2), (3, 1)])
def test_taps_setter(self, taps, expected):
self.cpx.detect_taps = taps
assert expected == self.cpx.detect_taps

def test_red_led(self):
self.cpx._Express__state["red_led"] = True
assert True == self.cpx.red_led
assert self.cpx.red_led

def test_red_led_int(self):
self.cpx.red_led = 3
assert True == self.cpx.red_led
assert self.cpx.red_led

def test_red_led_string(self):
self.cpx.red_led = "foo"
assert True == self.cpx.red_led
assert self.cpx.red_led

def test_switch(self):
self.cpx._Express__state["switch"] = True
assert True == self.cpx.switch

def test_set_item_tuple(self):
self.cpx.pixels[0] = (255, 255, 255)
assert (255, 255, 255) == self.cpx._Express__state["pixels"][0]
assert self.cpx.switch

def test_set_item_list(self):
self.cpx.pixels[0] = [255, 255, 255]
assert (255, 255, 255) == self.cpx._Express__state["pixels"][0]
def test_temperature(self):
self.cpx._Express__state["temperature"] = 31
assert 31 == self.cpx.temperature

def test_set_item_hex(self):
self.cpx.pixels[0] = 0xFFFFFF
assert (255, 255, 255) == self.cpx._Express__state["pixels"][0]

def test_set_item_invalid(self):
with pytest.raises(ValueError):
self.cpx.pixels[0] = "hello"
def test_light(self):
self.cpx._Express__state["light"] = 255
assert 255 == self.cpx.light

def test_shake(self):
self.cpx._Express__state["shake"] = True
assert True == self.cpx.shake()
assert self.cpx.shake()

def test_touch_A1(self):
self.cpx._Express__state["touch"][0] = True
assert True == self.cpx.touch_A1
assert self.cpx.touch_A1

def test_touch_A2(self):
self.cpx._Express__state["touch"][1] = True
assert True == self.cpx.touch_A2
assert self.cpx.touch_A2

def test_touch_A3(self):
self.cpx._Express__state["touch"][2] = True
assert True == self.cpx.touch_A3
assert self.cpx.touch_A3

def test_touch_A4(self):
self.cpx._Express__state["touch"][3] = True
assert True == self.cpx.touch_A4
assert self.cpx.touch_A4

def test_touch_A5(self):
self.cpx._Express__state["touch"][4] = True
assert True == self.cpx.touch_A5
assert self.cpx.touch_A5

def test_touch_A6(self):
self.cpx._Express__state["touch"][5] = True
assert True == self.cpx.touch_A6
assert self.cpx.touch_A6

def test_touch_A7(self):
self.cpx._Express__state["touch"][6] = True
assert True == self.cpx.touch_A7
assert self.cpx.touch_A7

def test_play_file_mp4(self):
def test_play_file_mp4_wrong_type(self):
with pytest.raises(TypeError):
self.cpx.play_file("sample.mp4")

def test_fill(self):
self.cpx.pixels.fill((0, 255, 0))
expected_pixels = [(0, 255, 0)] * 10
assert expected_pixels == self.cpx._Express__state["pixels"]

def test_extract_pixel_value_list(self):
assert (0, 255, 0) == self.cpx.pixels._Pixel__extract_pixel_value((0, 255, 0))

def test_extract_pixel_value_list1(self):
assert (123, 123, 123) == self.cpx.pixels._Pixel__extract_pixel_value(
[123, 123, 123]
)

def test_extract_pixel_value_int(self):
assert (0, 0, 255) == self.cpx.pixels._Pixel__extract_pixel_value(255)

def test_extract_pixel_value_tuple(self):
assert (0, 255, 0) == self.cpx.pixels._Pixel__extract_pixel_value((0, 255, 0))

def test_extract_pixel_value_invalid_length(self):
with pytest.raises(ValueError):
self.cpx.pixels._Pixel__extract_pixel_value((1, 2, 3, 4))

def test_extract_pixel_value_invalid_tuple_value(self):
with pytest.raises(ValueError):
self.cpx.pixels._Pixel__extract_pixel_value((0, 222, "hello"))
def test_play_file_mp4(self):
playsound.playsound = mock.Mock()
self.cpx.play_file("sample.wav")
playsound.playsound.assert_called_once()
120 changes: 120 additions & 0 deletions src/adafruit_circuitplayground/test/test_pixel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import pytest

from ..pixel import Pixel


class TestPixel(object):
def setup_method(self):
self.pixel = Pixel(
{
"brightness": 1.0,
"button_a": False,
"button_b": False,
"pixels": [(255, 0, 0), (0, 255, 0), (0, 0, 255)],
"red_led": False,
"switch": False,
}
)

@pytest.mark.parametrize("debug_mode", [True, False])
def test_set_debug_mode(self, debug_mode):
self.pixel._Pixel__set_debug_mode(debug_mode)
assert debug_mode == self.pixel._Pixel__debug_mode

def test_get_item_out_of_bounds(self):
with pytest.raises(IndexError):
p = self.pixel[3]

def test_get_item(self):
assert (0, 0, 255) == self.pixel[2]

def test_get_item_splice(self):
assert [(255, 0, 0), (0, 255, 0)] == self.pixel[0:2]

def test_set_item(self):
self.pixel[1] = (50, 50, 50)
assert (50, 50, 50) == self.pixel[1]

def test_set_item_splice(self):
self.pixel[0:1] = [(100, 100, 100), (0, 0, 100)]
assert (100, 100, 100) == self.pixel[0]
assert (0, 0, 100) == self.pixel[1]

def test_set_item_out_of_bounds(self):
with pytest.raises(IndexError):
self.pixel[3] = (0, 0, 0)

def test_set_item_invalid(self):
with pytest.raises(ValueError):
self.pixel[0] = "hello"

def test_len(self):
assert 3 == len(self.pixel)

@pytest.mark.parametrize("index, expected", [(0, True), (3, False)])
def test_valid_index(self, index, expected):
assert self.pixel._Pixel__valid_index(index) == expected

def test_fill(self):
self.pixel.fill((123, 123, 123))
assert all(p == (123, 123, 123) for p in self.pixel._Pixel__state["pixels"])

@pytest.mark.parametrize(
"val, expected",
[([3, 4, 5], (3, 4, 5)), (432, (0, 1, 176)), ((1, 2, 3), (1, 2, 3))],
)
def test_extract_pixel_values_not_slice(self, val, expected):
assert expected == self.pixel._Pixel__extract_pixel_value(val)

@pytest.mark.parametrize(
"val, expected",
[
([[3, 4, 5], [6, 7, 8]], [(3, 4, 5), (6, 7, 8)]),
([444555, 666777], [(6, 200, 139), (10, 44, 153)]),
([(10, 10, 10), (20, 20, 20)], [(10, 10, 10), (20, 20, 20)]),
],
)
def test_extract_pixel_values_slice(self, val, expected):
assert expected == self.pixel._Pixel__extract_pixel_value(val, is_slice=True)

@pytest.mark.parametrize("val", [[1, 2, 3, 4], [1, 2], 0.3])
def test_extract_pixel_values_fail(self, val):
with pytest.raises(ValueError):
self.pixel._Pixel__extract_pixel_value(val)

def test_hex_to_rgb_fail(self):
with pytest.raises(ValueError):
self.pixel._Pixel__hex_to_rgb("x")

@pytest.mark.parametrize(
"hex, expected",
[
("0xffffff", (255, 255, 255)),
("0x0", (0, 0, 0)),
("0xff0000", (255, 0, 0)),
("0xabcdef", (171, 205, 239)),
],
)
def test_hex_to_rgb(self, hex, expected):
assert expected == self.pixel._Pixel__hex_to_rgb(hex)

@pytest.mark.parametrize(
"pixValue, expected",
[(0, True), (200, True), (255, True), (-1, False), (256, False), ("1", False)],
)
def test_valid_rgb_value(self, pixValue, expected):
assert expected == self.pixel._Pixel__valid_rgb_value(pixValue)

def test_get_brightness(self):
self.pixel._Pixel__state["brightness"] = 0.4
assert 0.4 == pytest.approx(self.pixel.brightness)

@pytest.mark.parametrize("brightness", [-0.1, 1.1])
def test_set_brightness_fail(self, brightness):
with pytest.raises(ValueError):
self.pixel.brightness = brightness

@pytest.mark.parametrize("brightness", [0, 1, 0.4, 0.333])
def test_set_brightness(self, brightness):
self.pixel.brightness = brightness
assert self.pixel._Pixel__valid_brightness(brightness)
Loading