Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 25 additions & 0 deletions .github/workflows/unit_tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Run unit tests

on:
pull_request:
branches:
- '**'

jobs:
pytest:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Python Setup
uses: actions/setup-python@v6
with:
python-version: 3.13
cache: 'pip'
cache-dependency-path: ./setup.cfg

- name: Install libraries
run: make python-install-development

- name: Run pytest
run: pytest
2 changes: 1 addition & 1 deletion src/python/app/io/bmp.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class BMPReader(IFormatReader): # pylint: disable=too-few-public-methods

@override
def read_format(self, file: BinaryIO) -> Image:
header = BitmapFileHeader.from_bytes(data=file.read(BitmapFileHeader.HEADER_LENGTH))
# header = BitmapFileHeader.from_bytes(data=file.read(BitmapFileHeader.HEADER_LENGTH))

dib_header_size = file.read(4)
dib_header_size, = struct.unpack('I', dib_header_size)
Expand Down
8 changes: 5 additions & 3 deletions src/python/app/operation/flip.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,11 @@ def parser(cls, parser: ArgumentParser) -> None:
@override
def __call__(self, args: Namespace, input_image: Image) -> Image:
if args.horizontal:
return Image(np.flip(input_image.data, axis=1))
input_image = Image(np.flip(input_image.data, axis=1))

if args.vertical:
return Image(np.flip(input_image.data, axis=0))
input_image = Image(np.flip(input_image.data, axis=0))

assert False, 'unreachable'
if not args.horizontal and not args.vertical:
assert False, 'unreachable'
return input_image
7 changes: 4 additions & 3 deletions src/python/app/operation/grayscale.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ def __call__(self, args: Namespace, input_image: Image) -> Image:
if input_image.data.shape[-1] == 1:
return input_image

result_image = 0.2126 * input_image.data[:, :, 0] \
+ 0.7152 * input_image.data[:, :, 1] \
+ 0.0722 * input_image.data[:, :, 2]
result_image = \
0.2126 * input_image.data[:, :, 0] \
+ 0.7152 * input_image.data[:, :, 1] \
+ 0.0722 * input_image.data[:, :, 2]

return Image(data=np.repeat(a=np.expand_dims(a=np.clip(a=result_image,
a_min=0.,
Expand Down
23 changes: 23 additions & 0 deletions tests/cpp/test_fast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest
import numpy as np

from app.fast import system # type: ignore
from app.fast import numpy_add # type: ignore


def test_system():
assert 0 == system('ls -la')
assert 0 != system('false')


numpy_add_values = [
(np.array([2, 1, 4], dtype=np.double), np.sum([2, 1, 4])),
(np.array([3, 1, 2], dtype=np.double), np.sum([3, 1, 2])),
(np.array([10, 24, 11], dtype=np.double), np.sum([10, 24, 11])),
(np.array([99, 1, 22], dtype=np.double), np.sum([99, 1, 22]))
]


@pytest.mark.parametrize("array1,expected_result", numpy_add_values)
def test_numpy_add(array1, expected_result):
assert numpy_add(array1) == expected_result
83 changes: 83 additions & 0 deletions tests/python/test_operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from argparse import Namespace
import numpy as np

from app.image.image import Image
from app.operation.bgr2rgb import BGR2RGB
from app.operation.flip import Flip
from app.operation.grayscale import Grayscale
from app.operation.rotate90 import Rotate90


def test_bgr2rgb():
input_image = Image(np.array([
[[10, 20, 30], [15, 25, 35], [16, 26, 36]],
[[20, 30, 40], [21, 31, 41], [22, 32, 42]],
[[30, 40, 50], [31, 41, 51], [32, 42, 52]]
]))

expected_image = Image(np.array([
[[30, 20, 10], [35, 25, 15], [36, 26, 16]],
[[40, 30, 20], [41, 31, 21], [42, 32, 22]],
[[50, 40, 30], [51, 41, 31], [52, 42, 32]]
]))

output_image = BGR2RGB()(args=None, input_image=input_image)

assert (output_image.data == expected_image.data).all()


def test_flip():
input_image = Image(np.array([
[[10, 20, 30], [15, 25, 35], [16, 26, 36]],
[[20, 30, 40], [21, 31, 41], [22, 32, 42]],
[[30, 40, 50], [31, 41, 51], [32, 42, 52]]
]))

expected_image = Image(np.array([
[[32, 42, 52], [31, 41, 51], [30, 40, 50]],
[[22, 32, 42], [21, 31, 41], [20, 30, 40]],
[[16, 26, 36], [15, 25, 35], [10, 20, 30]],
]))

output_image = Flip()(args=Namespace(horizontal=True, vertical=True), input_image=input_image)

assert (expected_image.data == output_image.data).all()


def test_grayscale():
# Try for already grayscale image
input_image = Image(np.array([
[[5], [123], [123]],
[[12], [12], [12]],
[[12], [12], [12]]
]))
expected_output = input_image

output_image = Grayscale()(args=None, input_image=input_image)

assert (expected_output.data == output_image.data).all()

# Try for coloured image
input_image = Image(np.array([
[[15, 10, 12], [120, 33, 20]],
[[30, 0, 2], [10, 45, 22]]
]))

output_image = Grayscale()(args=None, input_image=input_image)

assert output_image.data.shape[-1] == 3
for row in output_image.data:
for pixel in row:
assert np.all(pixel == pixel[0])


def test_rotate90():
input_image = Image(np.array([
[[15, 10, 12], [120, 33, 20]],
[[30, 0, 2], [10, 45, 22]]
]))

for rotation in range(-5, 5):
expected_output = np.rot90(input_image.data, rotation)
output_image = Rotate90()(args=Namespace(rotations=rotation), input_image=input_image)
assert (expected_output == output_image.data).all()
Loading