aboutsummaryrefslogtreecommitdiff
path: root/challenge-285/ppentchev/python/tests/unit
diff options
context:
space:
mode:
authorConor Hoekstra <codereport@outlook.com>2024-09-09 16:34:38 -0400
committerConor Hoekstra <codereport@outlook.com>2024-09-09 16:34:38 -0400
commit2f3cf4f7cfa808d89e183b77f61dac80db4ab751 (patch)
tree9dcefb9d7860406bce98f0666cd99d7b608dd758 /challenge-285/ppentchev/python/tests/unit
parent156e3186ef5b8f929e3589f8469463132e0fa996 (diff)
parent148ad068f27ef5bbdcac38b14685b2273b0d02ec (diff)
downloadperlweeklychallenge-club-2f3cf4f7cfa808d89e183b77f61dac80db4ab751.tar.gz
perlweeklychallenge-club-2f3cf4f7cfa808d89e183b77f61dac80db4ab751.tar.bz2
perlweeklychallenge-club-2f3cf4f7cfa808d89e183b77f61dac80db4ab751.zip
Merge branch 'master' of https://github.com/manwar/perlweeklychallenge-club
Diffstat (limited to 'challenge-285/ppentchev/python/tests/unit')
-rw-r--r--challenge-285/ppentchev/python/tests/unit/__init__.py3
-rw-r--r--challenge-285/ppentchev/python/tests/unit/test_change.py133
-rw-r--r--challenge-285/ppentchev/python/tests/unit/test_metadata.py21
-rw-r--r--challenge-285/ppentchev/python/tests/unit/test_routes.py73
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)