Skip to content

Commit

Permalink
common classes covered by updated tests
Browse files Browse the repository at this point in the history
minor tweaks based on failed tests

Signed-off-by: apetrynet <[email protected]>
  • Loading branch information
apetrynet committed Jul 17, 2024
1 parent 9f78729 commit 9959752
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 79 deletions.
17 changes: 15 additions & 2 deletions src/pyfdl/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@ def add(self, item: Any):
self._data[item_id] = item

else:
raise FDLError(f"Item must have a valid identifier (\"{self._cls.id_attribute}\"), not None or empty string")
raise FDLError(
f"Item must have a valid identifier (\"{self._cls.id_attribute}\"), not None or empty string"
)

def get(self, item_id: str) -> Union[Any, None]:
"""Get an item in the collection
Expand Down Expand Up @@ -278,6 +280,9 @@ def _get_item_id(self, item: Any) -> str:
"""
return getattr(item, self._cls.id_attribute)

def __bool__(self):
return bool(self._data)

def __len__(self):
return len(self._data)

Expand Down Expand Up @@ -352,6 +357,7 @@ def copy(self) -> 'Dimensions':
return Dimensions(width=self.width, height=self.height, dtype=self.dtype)

def to_dict(self) -> dict:
# TODO: do we round before casting to int?
return {'width': self.dtype(self.width), 'height': self.dtype(self.height)}

def __iter__(self):
Expand Down Expand Up @@ -421,6 +427,7 @@ def __init__(self, even: str = None, mode: str = None):
super().__init__()
self.even = even
self.mode = mode
self.rounding_strategy = None

@property
def even(self):
Expand Down Expand Up @@ -484,7 +491,13 @@ def round_dimensions(
width = mode_map[self.mode](width / adjust) * adjust
height = mode_map[self.mode](height / adjust) * adjust

return type(dimensions)(width=width, height=height)
return Dimensions(width=width, height=height, dtype=dimensions.dtype)

def __eq__(self, other):
if isinstance(other, dict):
return self.even == other.get('even') and self.mode == other.get('mode')

return self.even == other.even and self.mode == other.mode

def __repr__(self):
return f'{self.__class__.__name__}(even="{self.even}", mode="{self.mode}")'
9 changes: 4 additions & 5 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import pyfdl


@pytest.fixture
@pytest.fixture(scope="function")
def base_subclass():
class BaseSubclass(pyfdl.Base):
# Holds a list of known attributes
Expand Down Expand Up @@ -39,8 +39,7 @@ def __init__(
self.round = round_

# Make sure we have a rounding strategy
if pyfdl.Base.rounding_strategy is None:
pyfdl.Base.set_rounding_strategy()
self.set_rounding_strategy(pyfdl.DEFAULT_ROUNDING_STRATEGY)

return BaseSubclass

Expand Down Expand Up @@ -223,7 +222,7 @@ def sample_context() -> dict:
return ctx


@pytest.fixture()
@pytest.fixture
def sample_canvas_template() -> dict:
canvas_template = {
"label": "VFX Pull",
Expand All @@ -240,7 +239,7 @@ def sample_canvas_template() -> dict:
return canvas_template


@pytest.fixture()
@pytest.fixture
def sample_canvas_template_kwargs() -> dict:
canvas_template = {
"label": "VFX Pull",
Expand Down
182 changes: 110 additions & 72 deletions tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,111 +72,149 @@ def test_base_set_rounding_strategy(base_subclass, sample_rounding_strategy_obj)
obj.set_rounding_strategy(rules=override)
assert obj.rounding_strategy.to_dict() == override

# Reset to default to not mess up other tests
obj.set_rounding_strategy(pyfdl.DEFAULT_ROUNDING_STRATEGY)


def test_base_generate_uuid(base_subclass):
assert isinstance(base_subclass.generate_uuid(), str)


def test_dimensions_point_from_dict(sample_point):
point1 = pyfdl.Point.from_dict(sample_point)
assert isinstance(point1, pyfdl.Point)
assert point1.check_required() == []
assert point1.to_dict() == sample_point
def test_typed_collection_ids(sample_framing_intent_obj):
collection = pyfdl.TypedCollection(pyfdl.FramingIntent)
assert collection.ids == []

collection.add(sample_framing_intent_obj)
assert collection.ids == [sample_framing_intent_obj.id]

def test_dimensions_point_from_kwargs(sample_point):
point2 = pyfdl.Point(**sample_point)
assert isinstance(point2, pyfdl.Point)
assert point2.check_required() == []
assert point2.to_dict() == sample_point

point3 = pyfdl.Point(x=16, y=9)
assert isinstance(point3, pyfdl.Point)
assert point3.check_required() == []
assert point3.x == 16
assert point3.y == 9
def test_typed_collection_add(sample_framing_intent_obj):
collection = pyfdl.TypedCollection(pyfdl.FramingIntent)
framing_intent = sample_framing_intent_obj
collection.add(framing_intent)
assert len(collection) == 1

with pytest.raises(TypeError) as err:
pyfdl.Point()
# Add something of wrong type
with pytest.raises(TypeError):
collection.add(pyfdl.Point(x=10, y=10))

assert "missing 2 required positional arguments: 'x' and 'y'" in str(err.value)
# Add duplicate "id"
with pytest.raises(pyfdl.FDLError) as err:
collection.add(framing_intent)

assert "already exists." in str(err)

def test_rounding_strategy_validation():
rs = pyfdl.RoundStrategy()
# Add something with "id_attribute" not set
framing_intent_1 = pyfdl.FramingIntent()
with pytest.raises(pyfdl.FDLError) as err:
rs.even = 'wrong'
collection.add(framing_intent_1)

assert '"wrong" is not a valid option for "even".' in str(err.value)
assert "Item must have a valid identifier" in str(err)

with pytest.raises(pyfdl.FDLError) as err:
rs.mode = 'wrong'

assert '"wrong" is not a valid option for "mode".' in str(err.value)
def test_typed_collection_get(sample_framing_intent_obj):
collection = pyfdl.TypedCollection(pyfdl.FramingIntent)
framing_intent = sample_framing_intent_obj
collection.add(framing_intent)
assert collection.get(framing_intent.id) == framing_intent
assert collection.get("not_present") is None


def test_rounding_strategy_default_values():
rs = pyfdl.RoundStrategy()
assert rs.check_required() == ['even', 'mode']
def test_typed_collection_remove(sample_framing_intent_obj):
collection = pyfdl.TypedCollection(pyfdl.FramingIntent)
framing_intent = sample_framing_intent_obj
collection.add(framing_intent)
assert len(collection) == 1
collection.remove(framing_intent.id)
assert len(collection) == 0
assert bool(collection) is False

rs.apply_defaults()
assert rs.even == 'even'
assert rs.mode == 'up'
assert rs.check_required() == []

def test_typed_collection_to_list(sample_framing_intent_obj):
collection = pyfdl.TypedCollection(pyfdl.FramingIntent)
framing_intent = sample_framing_intent_obj
collection.add(framing_intent)

def test_rounding_strategy_from_dict(sample_rounding_strategy):
rs = pyfdl.RoundStrategy.from_dict(sample_rounding_strategy)
assert isinstance(rs, pyfdl.RoundStrategy)
assert rs.even == "even"
assert rs.mode == "up"
assert collection.to_list() == [framing_intent.to_dict()]


def test_typed_collection(sample_framing_intent, sample_framing_intent_kwargs):
td = pyfdl.TypedCollection(pyfdl.FramingIntent)
fi = pyfdl.FramingIntent.from_dict(sample_framing_intent)
td.add(fi)
def test_typed_collection_contents(sample_framing_intent_obj):
collection = pyfdl.TypedCollection(pyfdl.FramingIntent)
framing_intent = sample_framing_intent_obj
collection.add(framing_intent)
assert framing_intent in collection
assert framing_intent.id in collection
assert [_fi for _fi in collection] == [framing_intent]

assert td.to_list() == [fi.to_dict()]
assert td.ids == [f"{fi.id}"]

assert fi in td
assert fi.id in td
assert td.get(fi.id) == fi
assert [_fi for _fi in td] == [fi]
def test_dimensions_to_dict():
dim_1 = pyfdl.Dimensions(width=1.1, height=2.2, dtype=int)
assert dim_1.to_dict() == {"width": 1, "height": 2}

td.remove(fi.id)
assert len(td) == 0
assert bool(td) is False
dim_2 = pyfdl.Dimensions(width=1.1, height=2.2, dtype=float)
assert dim_2.to_dict() == {"width": 1.1, "height": 2.2}

with pytest.raises(TypeError) as err:
td.add(pyfdl.Point(x=10, y=10))

assert "This container does not accept items of type:" in str(err.value)
def test_dimensions_scale_by():
dim_1 = pyfdl.Dimensions(width=1.1, height=2.2, dtype=int)
dim_1.scale_by(2)
assert (dim_1.width, dim_1.height) == (2, 4)

# Test missing id
fi1 = pyfdl.FramingIntent()
with pytest.raises(pyfdl.FDLError) as err:
td.add(fi1)
dim_2 = pyfdl.Dimensions(width=1.1, height=2.2, dtype=float)
dim_2.scale_by(2)
assert (dim_2.width, dim_2.height) == (2.2, 4.4)

assert f"Item must have a valid identifier (\"id\")" in str(err.value)
# Check if scaling follows rounding rules
dim_3 = pyfdl.Dimensions(width=1.1, height=2.2, dtype=int)
dim_3.rounding_strategy = pyfdl.RoundStrategy(**{"even": "whole", "mode": "up"})
dim_3.scale_by(2)
assert (dim_3.width, dim_3.height) == (3, 5)

# Test duplicate id's
td.add(fi)
kwargs = sample_framing_intent_kwargs.copy()
kwargs['label'] = 'somethingelse'
fi2 = pyfdl.FramingIntent(**kwargs)
with pytest.raises(pyfdl.FDLError) as err:
td.add(fi2)

assert f"FramingIntent.id (\"{fi.id}\") already exists." in str(err.value)
def test_dimensions_copy():
dim_1 = pyfdl.Dimensions(width=1.1, height=2.2, dtype=int)
dim_2 = dim_1.copy()
assert dim_1 == dim_2
assert dim_1.dtype == dim_2.dtype

# Test object with alternative id_attribute
td1 = pyfdl.TypedCollection(pyfdl.Context)
ctx1 = pyfdl.Context(label='context1')
td1.add(ctx1)

def test_rounding_strategy_validation():
rs = pyfdl.RoundStrategy()
with pytest.raises(pyfdl.FDLError) as err:
td1.add(ctx1)
rs.even = 'wrong'

assert '"wrong" is not a valid option for "even".' in str(err.value)

with pytest.raises(pyfdl.FDLError) as err:
rs.mode = 'wrong'

assert '"wrong" is not a valid option for "mode".' in str(err.value)


assert f"Context.label (\"{ctx1.label}\") already exists." in str(err)
@pytest.mark.parametrize(
'rules,dimensions,dtype,expected',
[
({"even": "even", "mode": "up"}, {"width": 19, "height": 79}, int, (20, 80)),
({"even": "even", "mode": "up"}, {"width": 19, "height": 79}, float, (20, 80)),
({"even": "even", "mode": "down"}, {"width": 19, "height": 79}, int, (18, 78)),
({"even": "even", "mode": "down"}, {"width": 19, "height": 79}, float, (18, 78)),
({"even": "even", "mode": "round"}, {"width": 19, "height": 79}, int, (20, 80)),
({"even": "even", "mode": "round"}, {"width": 19, "height": 79}, float, (20, 80)),
({"even": "even", "mode": "round"}, {"width": 19.456, "height": 79.456}, int, (20, 80)),
({"even": "even", "mode": "round"}, {"width": 19.456, "height": 79.456}, float, (20, 80)),
({"even": "whole", "mode": "up"}, {"width": 19.5, "height": 79.5}, int, (20, 80)),
({"even": "whole", "mode": "up"}, {"width": 19.5, "height": 79.5}, float, (20, 80)),
({"even": "whole", "mode": "down"}, {"width": 19.5, "height": 79.5}, int, (19, 79)),
({"even": "whole", "mode": "down"}, {"width": 19.5, "height": 79.5}, float, (19, 79)),
({"even": "whole", "mode": "round"}, {"width": 19.5, "height": 79.5}, int, (20, 80)),
({"even": "whole", "mode": "round"}, {"width": 19.5, "height": 79.5}, float, (20, 80)),
({"even": "whole", "mode": "round"}, {"width": 19.456, "height": 79.456}, int, (19, 79)),
({"even": "whole", "mode": "round"}, {"width": 19.456, "height": 79.456}, float, (19, 79))
]
)
def test_rounding_strategy_rounding(rules, dimensions, dtype, expected):
rnd = pyfdl.RoundStrategy.from_dict(rules)
dim = pyfdl.Dimensions(**dimensions, dtype=dtype)
result = rnd.round_dimensions(dim)

assert (result.width, result.height) == expected

0 comments on commit 9959752

Please sign in to comment.