Coverage for tests/test_mod.py: 100%
43 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-09 18:59 +0200
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-09 18:59 +0200
1"""
2Tests of :mod:`pyyc.mod` functions, to be run with :pypi:`pytest`::
4 $ pytest -v test_mod.py
6Ideally, each function and use case should be tested: standard use (as
7described in documentation), invalid use (handled with documented exceptions),
8corner cases, etc.
10* :doc:`@pytest.mark.parametrize <pytest:how-to/parametrize>` decorator allows
11 to test different inputs/outputs;
12* :doc:`capsys <pytest:how-to/capture-stdout-stderr>` captures standard
13 and error outputs (e.g. from :func:`print`);
14* :doc:`monkeypatch <pytest:how-to/monkeypatch>` overrides modules and
15 environments (e.g. :func:`input`).
17.. Note:: Some tiny parts of the code are voluntarily left untested to
18 be used as example in `coverage report`.
19"""
21import pytest
22import pyyc
25def test_version():
26 """
27 Simple test.
28 """
30 assert pyyc.mod.version == "top-level module"
33def test_addition_int_list():
34 """
35 Single test of :func:`pyyc.mod.addition` on list of int.
36 """
38 assert pyyc.mod.addition(1, 2) == 3
41def test_addition_str_list():
42 """
43 Single test of :func:`pyyc.mod.addition` on list of str.
44 """
46 assert pyyc.mod.addition("abc", "def") == "abcdef"
49@pytest.mark.parametrize(
50 "test_input, expected_output",
51 [
52 # Test on int args
53 ([1], 1),
54 ([1, 2], 3),
55 ([1, 2, 3], 6),
56 # Test on str args
57 (["abc"], "abc"),
58 (["abc", "def"], "abcdef"),
59 # Test on list args
60 ([[1, 2]], [1, 2]),
61 ([[1, 2], [3, 4]], [1, 2, 3, 4]),
62 ],
63)
64def test_addition(test_input, expected_output):
65 """
66 Test standard usage of :func:`pyyc.mod.addition`.
68 This test uses parametrization of arguments, see
69 :doc:`pytest:how-to/parametrize`.
71 .. Tip:: `addition(*args)` will unpack the arguments on-the-fly and is
72 similar to `addition(args[0], args[1], ...)`.
73 """
75 assert pyyc.mod.addition(*test_input) == expected_output
78@pytest.mark.parametrize(
79 "test_input",
80 [
81 # Both entries should raise TypeError
82 (1, "toto"),
83 ("toto", 1)
84 ],
85)
86def test_addition_TypeError(test_input):
87 """
88 Test incompatible argument case.
90 It should raise :exc:`TypeError`, as mentioned in documentation of
91 :func:`pyyc.mod.addition`.
92 """
94 with pytest.raises(TypeError):
95 pyyc.mod.addition(*test_input)
98def test_addition_empty():
99 """
100 Test no argument case.
102 It should raise :exc:`IndexError`, not documented.
103 """
105 with pytest.raises(IndexError):
106 pyyc.mod.addition()
108# The following tests are intentionally commented out to simulate untested
109# functions (and incomplete test coverage).
111# @pytest.mark.parametrize(
112# "test_input, expected_output", [([1], 1), ([1.2, 2.3], 3), ([1, 2, 3], 6)]
113# )
114# def test_addition_int(test_input, expected_output):
115# """
116# Test standard usage of :func:`pyyc.mod.addition_int`.
117# """
119# assert pyyc.mod.addition_int(*test_input) == expected_output
122# @pytest.mark.parametrize("test_input", [["1.2"], ["abc"]])
123# def test_addition_int_ValueError(test_input):
124# """
125# Test non-int argument case.
127# It should raise :exc:`ValueError`, as mentioned in documentation of
128# :func:`pyyc.mod.addition_int`.
129# """
131# with pytest.raises(ValueError):
132# pyyc.mod.addition_int(*test_input)
135def test_read_config_version():
136 """
137 Test a single value in configuration file.
138 """
140 cfg = pyyc.mod.read_config()
141 assert cfg["DEFAULT"]["version"] == "cfg-1.0"
144def test_read_config_content(capsys):
145 """
146 Test full content of configuration file.
148 This test uses stdout capture, see :doc:`pytest:how-to/capture-stdout-stderr`.
149 """
151 import sys
153 cfg = pyyc.mod.read_config()
154 captured = capsys.readouterr() # Capture standard & error outputs (not used)
155 cfg.write(sys.stdout) # Write config to stdout
156 captured = capsys.readouterr() # Capture standard & error outputs
157 assert captured.out == "[DEFAULT]\nversion = cfg-1.0\n\n"
160def test_read_config_filename():
161 """
162 Test explicit configuration filename.
163 """
165 cfg = pyyc.mod.read_config(pyyc.mod.PYYC_PATH.joinpath("default.cfg"))
166 assert cfg["DEFAULT"]["version"] == "cfg-1.0"
169def test_read_config_IOError():
170 """
171 Test non-existing or invalid configuration files.
172 """
174 with pytest.raises(IOError):
175 pyyc.mod.read_config("nonexisting.cfg") # Non-existing file
178def test_format_pkg_tree():
179 """
180 Test standard usage of :func:`pyyc.mod.format_pkg_tree`.
181 """
183 s = pyyc.mod.format_pkg_tree(pyyc, max_depth=1)
184 assert s == [
185 "pyyc",
186 " pyyc.config",
187 " pyyc.mod",
188 " pyyc.subpkgA",
189 " pyyc.subpkgB",
190 ]
193def test_greetings(capsys, monkeypatch):
194 """
195 This test uses both input monkey patching and stdout capture.
196 """
198 import builtins
200 # Create a fake 'input' function for the test
201 monkeypatch.setattr(builtins, "input", lambda _: "John")
203 pyyc.mod.greetings() # Use fake input, and print on stdout
205 captured = capsys.readouterr() # Capture standard & error outputs
206 assert captured.out == "Hello, John!\n"