Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions test_luhn.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,47 @@ def test_calculate_check_digit(self):
def test_append_check_digit(self):
self.assertEqual(append_check_digit("7992739871"), "79927398713")

def test_generated_numbers_have_valid_checksums(self):
for payload in ("0", "7", "12", "000", "7992739871", 7992739871):
with self.subTest(payload=payload):
number = append_check_digit(payload)
self.assertTrue(is_valid(number))
self.assertEqual(checksum(number), 0)

def test_other_check_digits_are_invalid(self):
for payload in ("0", "12", "7992739871"):
number = append_check_digit(payload)

for digit in "0123456789":
if digit == number[-1]:
continue

with self.subTest(payload=payload, check_digit=digit):
self.assertFalse(is_valid(number[:-1] + digit))

def test_supported_separators_are_removed(self):
for separator in (" ", "-", ".", "/", "\\", ","):
with self.subTest(separator=separator):
self.assertTrue(is_valid("799" + separator + "27398713"))
self.assertEqual(
append_check_digit("799" + separator + "2739871"),
"79927398713",
)

self.assertTrue(is_valid(" 799-273.987/1\\3, "))
self.assertEqual(append_check_digit(" 799-273.987/1\\, "), "79927398713")
self.assertEqual(append_check_digit("000"), "0000")

def test_separator_only_input_is_rejected(self):
value = " -./\\, "
self.assertFalse(is_valid(value))

for function in (checksum, calculate_check_digit, append_check_digit):
with self.subTest(function=function.__name__), self.assertRaises(
ValueError
):
function(value)

def test_rejects_non_digit_payloads(self):
expected_message = (
"value must contain digits only, with optional spaces, hyphens, "
Expand All @@ -55,6 +96,7 @@ def test_cli_exit_status_reflects_validity(self):
for number, expected_output, expected_status in (
("79927398713", "valid", 0),
("79927398714", "invalid", 1),
("abc", "invalid", 1),
):
with self.subTest(number=number):
result = subprocess.run(
Expand All @@ -67,6 +109,19 @@ def test_cli_exit_status_reflects_validity(self):
self.assertEqual(result.stdout.strip(), expected_output)
self.assertEqual(result.returncode, expected_status)

def test_cli_requires_a_number(self):
script = Path(__file__).with_name("luhn.py")
result = subprocess.run(
[sys.executable, str(script)],
capture_output=True,
text=True,
check=False,
)

self.assertEqual(result.returncode, 2)
self.assertEqual(result.stdout, "")
self.assertIn("required", result.stderr)


if __name__ == "__main__":
unittest.main()