""" 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 `. 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