Skip to content

Commit

Permalink
Check (& test) for None input(s)
Browse files Browse the repository at this point in the history
  • Loading branch information
JorisVincent committed Sep 22, 2022
1 parent 900f840 commit cf8f0ed
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 16 deletions.
12 changes: 9 additions & 3 deletions stimuli/utils/resolution.py
Expand Up @@ -132,7 +132,9 @@ def validate_shape(shape):

# Check if sequence
try:
len(shape)
if len(shape) < 1:
# Empty sequence
raise ValueError(f"shape must be of at least length 1: {shape}")
except TypeError: # not a sequence; make it one
shape = (shape, shape)

Expand Down Expand Up @@ -171,7 +173,9 @@ def validate_ppd(ppd):

# Check if sequence
try:
len(ppd)
if len(ppd) < 1:
# Empty sequence
raise ValueError(f"ppd must be of at least length 1: {ppd}")
except TypeError: # not a sequence; make it one
ppd = (ppd, ppd)

Expand Down Expand Up @@ -212,7 +216,9 @@ def validate_visual_size(visual_size):

# Check if sequence
try:
len(visual_size)
if len(visual_size) < 1:
# Empty sequence
raise ValueError(f"visual_size must be of at least length 1: {visual_size}")
except TypeError: # not a sequence; make it one
visual_size = (visual_size, visual_size)

Expand Down
@@ -1,4 +1,27 @@
import numpy as np
"""Tests whether validation of resolution components works as expected
Seperately tests each of three components: visual size, shape, ppd.
For each component, the validation routine has two expected major behaviors:
- if input is valid, return canonical format (2-(named)tuple)
- casts values to correct type (float or int)
- expands 1D to 2D, i.e., if 1 value is provided, uses it for both dimensions
- if input is not valid, raise specific exceptions:
- ValueError if input cannot be cast
- ValueError if values are not in accepted ranges, i.e., not positive
- TypeError if input is not a 1-Sequence or 2-Sequence
The tests do this through parameterization:
pytest runs each test for each of the specified parameter sets.
For the valid-input tests, each parameter set specifies the (valid) input,
and value (in canonical form) that should be returned.
If the actual returned value matches this expected return value, the test passes.
For the invalid-input tests, each parameter set specifies the (invalid) input,
and the Exception that should be raised.
If the function under testing raises this specified exception, the test passes.
"""

import pytest
from stimuli.utils import resolution

Expand All @@ -21,23 +44,24 @@
((None, None), (None, None)),
],
)
def test_validate_visual_size(visual_size, expected):
def test_valid_visual_size(visual_size, expected):
out = resolution.validate_visual_size(visual_size)
assert out.width == expected[1] and out.height == expected[0]


@pytest.mark.parametrize(
"visual_size, exception",
[
((), ValueError),
("bla", ValueError),
((32, 32, 32), TypeError),
({32, 32}, TypeError),
((-32, 16), ValueError),
((16, 0), ValueError),
],
)
def test_raises_visual_size(visual_size, exception):
with pytest.raises(exception) as e_info:
def test_invalid_visual_size(visual_size, exception):
with pytest.raises(exception):
resolution.validate_visual_size(visual_size)


Expand All @@ -54,26 +78,29 @@ def test_raises_visual_size(visual_size, exception):
("32", (32, 32)),
((16, "32"), (16, 32)),
(("16", "32"), (16, 32)),
# Add None cases
((16.1, None), (16, None)),
((None, "32"), (None, 32)),
((None, None), (None, None)),
],
)
def test_validate_shape(shape, expected):
def test_valid_shape(shape, expected):
out = resolution.validate_shape(shape)
assert out.width == expected[1] and out.height == expected[0]


@pytest.mark.parametrize(
"shape, exception",
[
((), ValueError),
("bla", ValueError),
((32, 32, 32), TypeError),
({32, 32}, TypeError),
((-32, 16), ValueError),
((16, 0), ValueError),
],
)
def test_raises_shape(shape, exception):
with pytest.raises(exception) as e_info:
def test_invalid_shape(shape, exception):
with pytest.raises(exception):
resolution.validate_shape(shape)


Expand All @@ -85,29 +112,32 @@ def test_raises_shape(shape, exception):
[
((32, 32), (32, 32)),
((16, 32), (16, 32)),
((22.5, 48.1), (22, 48)),
((22.5, 48.1), (22.5, 48.1)),
((16), (16, 16)),
("32", (32, 32)),
((16, "32"), (16, 32)),
(("16", "32"), (16, 32)),
# Add None cases
((16.1, None), (16.1, None)),
((None, "32"), (None, 32)),
((None, None), (None, None)),
],
)
def test_validate_ppd(ppd, expected):
def test_valid_ppd(ppd, expected):
out = resolution.validate_ppd(ppd)
assert out.horizontal == expected[1] and out.vertical == expected[0]


@pytest.mark.parametrize(
"ppd, exception",
[
((), ValueError),
("bla", ValueError),
((32, 32, 32), TypeError),
({32, 32}, TypeError),
((-32, 16), ValueError),
((16, 0), ValueError),
],
)
def test_raises_ppd(ppd, exception):
with pytest.raises(exception) as e_info:
def test_invalid_ppd(ppd, exception):
with pytest.raises(exception):
resolution.validate_ppd(ppd)

0 comments on commit cf8f0ed

Please sign in to comment.