diff options
Diffstat (limited to 'challenge-285/ppentchev/python/tests')
4 files changed, 230 insertions, 0 deletions
diff --git a/challenge-285/ppentchev/python/tests/unit/__init__.py b/challenge-285/ppentchev/python/tests/unit/__init__.py new file mode 100644 index 0000000000..2fcf8ce229 --- /dev/null +++ b/challenge-285/ppentchev/python/tests/unit/__init__.py @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net> +# SPDX-License-Identifier: BSD-2-Clause +"""Unit tests for the Perl weekly challenge 285 solutions.""" diff --git a/challenge-285/ppentchev/python/tests/unit/test_change.py b/challenge-285/ppentchev/python/tests/unit/test_change.py new file mode 100644 index 0000000000..e93bbe0286 --- /dev/null +++ b/challenge-285/ppentchev/python/tests/unit/test_change.py @@ -0,0 +1,133 @@ +# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net> +# SPDX-License-Identifier: BSD-2-Clause +"""Test the second task in Perl weekly challenge 285, "Making Change".""" + +from __future__ import annotations + +import dataclasses + +import pytest + +from perl_weekly_285 import change + + +@dataclasses.dataclass(frozen=True) +class BreakDownWaysCase: + """A test case for the "No Connection" task.""" + + amount: int + """The amount to break down.""" + + highest: change.Coin + """The highest coin to use for this amount.""" + + expected: list[tuple[int, change.Coin]] + """The ways to break this amount down into smaller chunks.""" + + +@pytest.mark.parametrize( + "tcase", + [ + BreakDownWaysCase(amount=1, highest=change.Coin.HALF_DOLLAR, expected=[]), + BreakDownWaysCase(amount=2, highest=change.Coin.HALF_DOLLAR, expected=[]), + BreakDownWaysCase( + amount=6, + highest=change.Coin.HALF_DOLLAR, + expected=[(1, change.Coin.PENNY)], + ), + BreakDownWaysCase(amount=6, highest=change.Coin.NICKEL, expected=[(1, change.Coin.PENNY)]), + BreakDownWaysCase(amount=6, highest=change.Coin.PENNY, expected=[]), + BreakDownWaysCase( + amount=7, + highest=change.Coin.HALF_DOLLAR, + expected=[(2, change.Coin.PENNY)], + ), + BreakDownWaysCase(amount=7, highest=change.Coin.NICKEL, expected=[(2, change.Coin.PENNY)]), + BreakDownWaysCase(amount=7, highest=change.Coin.PENNY, expected=[]), + BreakDownWaysCase( + amount=10, + highest=change.Coin.HALF_DOLLAR, + expected=[(0, change.Coin.NICKEL), (5, change.Coin.PENNY), (0, change.Coin.PENNY)], + ), + BreakDownWaysCase( + amount=10, + highest=change.Coin.DIME, + expected=[(0, change.Coin.NICKEL), (5, change.Coin.PENNY), (0, change.Coin.PENNY)], + ), + BreakDownWaysCase( + amount=10, + highest=change.Coin.NICKEL, + expected=[(5, change.Coin.PENNY), (0, change.Coin.PENNY)], + ), + BreakDownWaysCase(amount=10, highest=change.Coin.PENNY, expected=[]), + BreakDownWaysCase( + amount=12, + highest=change.Coin.HALF_DOLLAR, + expected=[(2, change.Coin.NICKEL), (7, change.Coin.PENNY), (2, change.Coin.PENNY)], + ), + BreakDownWaysCase( + amount=12, + highest=change.Coin.DIME, + expected=[(2, change.Coin.NICKEL), (7, change.Coin.PENNY), (2, change.Coin.PENNY)], + ), + BreakDownWaysCase( + amount=12, + highest=change.Coin.NICKEL, + expected=[(7, change.Coin.PENNY), (2, change.Coin.PENNY)], + ), + BreakDownWaysCase(amount=12, highest=change.Coin.PENNY, expected=[]), + BreakDownWaysCase( + amount=15, + highest=change.Coin.HALF_DOLLAR, + expected=[ + (5, change.Coin.NICKEL), + (10, change.Coin.PENNY), + (5, change.Coin.PENNY), + (0, change.Coin.PENNY), + ], + ), + BreakDownWaysCase( + amount=15, + highest=change.Coin.DIME, + expected=[ + (5, change.Coin.NICKEL), + (10, change.Coin.PENNY), + (5, change.Coin.PENNY), + (0, change.Coin.PENNY), + ], + ), + BreakDownWaysCase( + amount=15, + highest=change.Coin.NICKEL, + expected=[(10, change.Coin.PENNY), (5, change.Coin.PENNY), (0, change.Coin.PENNY)], + ), + BreakDownWaysCase(amount=15, highest=change.Coin.PENNY, expected=[]), + ], +) +def test_break_down_ways(*, tcase: BreakDownWaysCase) -> None: + """Make sure we can find the leaf destination.""" + assert change.break_down_ways(tcase.amount, tcase.highest) == tcase.expected + + +@dataclasses.dataclass(frozen=True) +class MakeChangeCase: + """A test case for the actual "how many ways can we break this down" function.""" + + amount: int + """The amount to break down.""" + + expected: int + """The expected number of ways.""" + + +@pytest.mark.parametrize( + "tcase", + [ + MakeChangeCase(amount=9, expected=2), + MakeChangeCase(amount=15, expected=6), + MakeChangeCase(amount=100, expected=292), + ], +) +def test_make_change(tcase: MakeChangeCase) -> None: + """Make sure we can count the ways.""" + assert change.solve_making_change(tcase.amount) == tcase.expected diff --git a/challenge-285/ppentchev/python/tests/unit/test_metadata.py b/challenge-285/ppentchev/python/tests/unit/test_metadata.py new file mode 100644 index 0000000000..e957790fba --- /dev/null +++ b/challenge-285/ppentchev/python/tests/unit/test_metadata.py @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net> +# SPDX-License-Identifier: BSD-2-Clause +"""Basic test for file importing.""" + +from __future__ import annotations + +import typing + +from packaging import version as pkg_version + +from perl_weekly_285 import defs + + +if typing.TYPE_CHECKING: + from typing import Final + + +def test_version() -> None: + """Make sure the `VERSION` variable has a sane value.""" + version: Final = pkg_version.Version(defs.VERSION) + assert version > pkg_version.Version("0") diff --git a/challenge-285/ppentchev/python/tests/unit/test_routes.py b/challenge-285/ppentchev/python/tests/unit/test_routes.py new file mode 100644 index 0000000000..743e0d20d2 --- /dev/null +++ b/challenge-285/ppentchev/python/tests/unit/test_routes.py @@ -0,0 +1,73 @@ +# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net> +# SPDX-License-Identifier: BSD-2-Clause +"""Test the first task in Perl weekly challenge 285, "No Connection".""" + +from __future__ import annotations + +import dataclasses + +import pytest + +from perl_weekly_285 import defs +from perl_weekly_285 import routes + + +@dataclasses.dataclass(frozen=True) +class RoutesCase: + """A test case for the "No Connection" task.""" + + routes: list[tuple[str, str]] + """The routes to examine.""" + + expected: str + """The leaf destination we expect to find.""" + + +@pytest.mark.parametrize( + "tcase", + [ + RoutesCase( + routes=[ + ("me", "you"), + ], + expected="you", + ), + RoutesCase( + routes=[ + ("here", "there"), + ("here", "everywhere"), + ("there", "everywhere"), + ], + expected="everywhere", + ), + RoutesCase( + routes=[("B", "C"), ("D", "B"), ("C", "A")], + expected="A", + ), + ], +) +def test_connection(*, tcase: RoutesCase) -> None: + """Make sure we can find the leaf destination.""" + assert routes.solve_no_connection(tcase.routes) == tcase.expected + + +@pytest.mark.parametrize( + "tcase", + [ + RoutesCase( + routes=[ + ("here", "there"), + ("here", "everywhere"), + ], + expected="not really", + ), + RoutesCase( + routes=[("me", "you"), ("you", "me")], + expected="not really", + ), + ], +) +def test_no_connection(*, tcase: RoutesCase) -> None: + """Make sure we cannot find any leaf destination.""" + with pytest.raises(defs.NoSolutionError): + routes.solve_no_connection(tcase.routes) |
