pytest-csv-params/tests/test_docs_example.py

98 lines
3.8 KiB
Python

"""
Example Code for a test case for the documentation site
=======================================================
**Module:** ``tests.test_docs_example``
This is the test code for the documentation site's :doc:`User guide </pages/guide>`. It contains everything that's
needed to follow the example -- and makes sure the code example is working.
"""
from functools import reduce
from os.path import dirname, join
from typing import List, Tuple, Union
import pytest
from pytest_csv_params.decorator import csv_params
def get_smallest_possible_container(
number_of_items: int,
dimensions_of_item: Tuple[int, int, int],
available_container_sizes: Union[List[int], Tuple[int, ...]] = (1000, 2500, 7500),
) -> int:
"""
This is the method to be tested. It searches for the smallest possible container after calculating the volume of the
things to be loaded into the container. A container can only contain items of one product, so it is enough to know
about the size of a single product, and how many of them need to be stored in a container.
The method raises a :class:`ValueError` when the items do not fit any container.
:param number_of_items: Number of items to be packed
:param dimensions_of_item: Edge lengths of a single item
:param available_container_sizes: What container sizes are available? This parameter has a default value
``(1000, 2500, 7500)``.
:raises ValueError: When no matching container can be found
"""
volume = reduce(lambda x, y: x * y, [*dimensions_of_item, number_of_items])
possible_containers = list(filter(lambda s: s >= volume, available_container_sizes))
if len(possible_containers) == 0:
raise ValueError("No container available") from None
return min(possible_containers)
def get_dimensions(dimensions_str: str) -> Tuple[int, int, int]:
"""
Read the dimensions from a string. A helper method to build the dimensions tuple.
:param dimensions_str: The dimensions from the CSV file
:raises ValueError: When the dimensions cannot be converted
:returns: The dimensions as int tuple
"""
dimensions_tuple = tuple(map(lambda x: int(x.strip()), dimensions_str.split("x")))
if len(dimensions_tuple) != 3:
raise ValueError("Dimensions invalid") from None
return dimensions_tuple # type: ignore
@csv_params(
data_file=join(dirname(__file__), "assets", "doc-example.csv"),
id_col="Test-ID",
header_renames={
"Number of items": "number_of_items",
"Dimensions of item": "dimensions_of_item",
"Expected Container Size": "expected_container_size",
"Expect Exception?": "expect_exception",
"Expected Message": "expected_message",
},
data_casts={
"number_of_items": int,
"dimensions_of_item": get_dimensions,
"expected_container_size": int,
"expect_exception": lambda x: x == "Y",
},
)
def test_get_smallest_possible_container(
number_of_items: int,
dimensions_of_item: Tuple[int, int, int],
expected_container_size: int,
expect_exception: bool,
expected_message: str,
) -> None:
"""
This is the test method for the documentation.
:param number_of_items: The number of items
:param dimensions_of_item: The dimensions of a single item
:param expected_container_size: Expected container size
:param expect_exception: Expect a :class:`ValueError`
:param expected_message: Message of the exception
"""
if expect_exception:
with pytest.raises(ValueError) as expected_exception:
get_smallest_possible_container(number_of_items, dimensions_of_item)
assert expected_exception.value.args[0] == expected_message
else:
container_size = get_smallest_possible_container(number_of_items, dimensions_of_item)
assert container_size == expected_container_size