From 8771e92acc1e24cceccaa327576cedfdf5edd8d2 Mon Sep 17 00:00:00 2001 From: Sitt Guruvanich Date: Tue, 21 Jan 2025 16:04:36 +0700 Subject: [PATCH 1/5] chore: adopt uv as package manager --- pyproject.toml | 5 +++ uv.lock | 118 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 uv.lock diff --git a/pyproject.toml b/pyproject.toml index 4c5046d..6ffbfd6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,11 @@ Repository = "https://github.com/itsmeadarsh2008/flpc.git" [tool.maturin] features = ["pyo3/extension-module"] +[tool.uv] +dev-dependencies = [ + "pytest>=8.3.4", +] + [build-system] requires = ["maturin>=1.6,<2.0"] build-backend = "maturin" diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..fa6ae41 --- /dev/null +++ b/uv.lock @@ -0,0 +1,118 @@ +version = 1 +requires-python = ">=3.8" + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "flpc" +version = "0.2.5" +source = { editable = "." } + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [{ name = "pytest", specifier = ">=8.3.4" }] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pytest" +version = "8.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] From 4a4754dc4ce9a2910fae493d963d0c9c116029bd Mon Sep 17 00:00:00 2001 From: Sitt Guruvanich Date: Tue, 21 Jan 2025 16:06:23 +0700 Subject: [PATCH 2/5] test: define tests for re.search --- pyproject.toml | 9 ++++ tests/search.py | 139 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 tests/search.py diff --git a/pyproject.toml b/pyproject.toml index 6ffbfd6..b9f0965 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,15 @@ Repository = "https://github.com/itsmeadarsh2008/flpc.git" [tool.maturin] features = ["pyo3/extension-module"] +[tool.pytest.ini_options] +addopts = [ + "--capture=sys", # capture sysout messages + "--strict-markers", + "--tb=short", # traceback +] + +python_files = "*.py" +testpaths = [ "tests" ] [tool.uv] dev-dependencies = [ "pytest>=8.3.4", diff --git a/tests/search.py b/tests/search.py new file mode 100644 index 0000000..fb7ca79 --- /dev/null +++ b/tests/search.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +import re +from typing import Dict, Literal + +from pytest import mark + +@mark.parametrize("args", + ( + { + "description": "Test for a valid email address", + "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", + "test_string": "example@test.com", + "expected": True + }, + { + "description": "Test for an invalid email address (missing domain)", + "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", + "test_string": "example@.com", + "expected": False + }, + { + "description": "Test for a valid phone number (US format)", + "pattern": r"^\(\d{3}\) \d{3}-\d{4}$", + "test_string": "(123) 456-7890", + "expected": True + }, + { + "description": "Test for an invalid phone number (wrong format)", + "pattern": r"^\(\d{3}\) \d{3}-\d{4}$", + "test_string": "123-456-7890", + "expected": False + }, + { + "description": "Test for a valid URL", + "pattern": r"^(https?://)(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$", + "test_string": "https://www.example.com/path", + "expected": True + }, + { + "description": "Test for an invalid URL (missing scheme)", + "pattern": r"^(https?://)(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$", + "test_string": "www.example.com/path", + "expected": False + }, + { + "description": "Test for a valid IPv4 address", + "pattern": r"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + "test_string": "192.168.1.1", + "expected": True + }, + { + "description": "Test for an invalid IPv4 address (out of range)", + "pattern": r"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + "test_string": "256.100.50.25", + "expected": False + }, + { + "description": "Test for a valid date (YYYY-MM-DD)", + "pattern": r"^\d{4}-\d{2}-\d{2}$", + "test_string": "2023-12-31", + "expected": True + }, + { + "description": "Test for an invalid date (wrong format)", + "pattern": r"^\d{4}-\d{2}-\d{2}$", + "test_string": "31/12/2023", + "expected": False + }, + { + "description": "Test for a valid hexadecimal color code", + "pattern": r"^#(?:[0-9a-fA-F]{3}){1,2}$", + "test_string": "#1A2B3C", + "expected": True + }, + { + "description": "Test for an invalid hexadecimal color code (wrong format)", + "pattern": r"^#(?:[0-9a-fA-F]{3}){1,2}$", + "test_string": "#12345G", + "expected": False + }, + { + "description": 'Test for a valid password (at least 8 characters, 1 uppercase, 1 lowercase, 1 digit)', + 'pattern': r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$', + 'test_string': 'Password1', + 'expected': True + }, + { + 'description': 'Test for an invalid password (too short)', + 'pattern': r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$', + 'test_string': 'Pass1', + 'expected': False + }, + { + 'description': 'Test for a string containing only digits', + 'pattern': r'^\d+$', + 'test_string': '123456789', + 'expected': True + }, + { + 'description': 'Test for a string containing non-digits', + 'pattern': r'^\d+$', + 'test_string': '123abc456', + 'expected': False + }, + { + 'description': 'Test for a string with whitespace only', + 'pattern': r'^\s*$', + 'test_string': '', + 'expected': True + }, + { + 'description': 'Test for a string with non-whitespace characters', + 'pattern': r'^\s*$', + 'test_string': ' a ', + 'expected': False + }, + { + 'description': 'Test for matching a word boundary', + 'pattern': r'\bword\b', + 'test_string': 'This is a word in a sentence.', + 'expected': True + }, + { + 'description': 'Test for not matching a word boundary', + 'pattern': r'\bword\b', + 'test_string': 'This is a worded sentence.', + 'expected': False + }, + ) +) +def test_regex_patterns(args: Dict[Literal["description", "expected", "pattern", "test_string"], str]): + match = re.search(args["pattern"], args["test_string"]) is not None + assert match == args["expected"], f"Failed: {args['description']}" From 6238507f072b76d40694b53bc9194173f44b9a19 Mon Sep 17 00:00:00 2001 From: Sitt Guruvanich Date: Tue, 21 Jan 2025 20:28:53 +0700 Subject: [PATCH 3/5] chore: add single-space gap between sections --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index b9f0965..19fcc97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,7 @@ addopts = [ python_files = "*.py" testpaths = [ "tests" ] + [tool.uv] dev-dependencies = [ "pytest>=8.3.4", From 56e0a6a582beb86d427883173a8bc7034fad637f Mon Sep 17 00:00:00 2001 From: Sitt Guruvanich Date: Tue, 21 Jan 2025 21:33:01 +0700 Subject: [PATCH 4/5] test: productize tests between two modules --- tests/search.py | 276 +++++++++++++++++++++++++----------------------- 1 file changed, 144 insertions(+), 132 deletions(-) diff --git a/tests/search.py b/tests/search.py index fb7ca79..0b55729 100644 --- a/tests/search.py +++ b/tests/search.py @@ -1,139 +1,151 @@ #!/usr/bin/env python3 -import re + +from itertools import product +from sys import modules +from types import ModuleType from typing import Dict, Literal from pytest import mark -@mark.parametrize("args", - ( - { - "description": "Test for a valid email address", - "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", - "test_string": "example@test.com", - "expected": True - }, - { - "description": "Test for an invalid email address (missing domain)", - "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", - "test_string": "example@.com", - "expected": False - }, - { - "description": "Test for a valid phone number (US format)", - "pattern": r"^\(\d{3}\) \d{3}-\d{4}$", - "test_string": "(123) 456-7890", - "expected": True - }, - { - "description": "Test for an invalid phone number (wrong format)", - "pattern": r"^\(\d{3}\) \d{3}-\d{4}$", - "test_string": "123-456-7890", - "expected": False - }, - { - "description": "Test for a valid URL", - "pattern": r"^(https?://)(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$", - "test_string": "https://www.example.com/path", - "expected": True - }, - { - "description": "Test for an invalid URL (missing scheme)", - "pattern": r"^(https?://)(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$", - "test_string": "www.example.com/path", - "expected": False - }, - { - "description": "Test for a valid IPv4 address", - "pattern": r"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ - r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ - r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ - r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", - "test_string": "192.168.1.1", - "expected": True - }, - { - "description": "Test for an invalid IPv4 address (out of range)", - "pattern": r"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ - r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ - r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ - r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", - "test_string": "256.100.50.25", - "expected": False - }, - { - "description": "Test for a valid date (YYYY-MM-DD)", - "pattern": r"^\d{4}-\d{2}-\d{2}$", - "test_string": "2023-12-31", - "expected": True - }, - { - "description": "Test for an invalid date (wrong format)", - "pattern": r"^\d{4}-\d{2}-\d{2}$", - "test_string": "31/12/2023", - "expected": False - }, - { - "description": "Test for a valid hexadecimal color code", - "pattern": r"^#(?:[0-9a-fA-F]{3}){1,2}$", - "test_string": "#1A2B3C", - "expected": True - }, - { - "description": "Test for an invalid hexadecimal color code (wrong format)", - "pattern": r"^#(?:[0-9a-fA-F]{3}){1,2}$", - "test_string": "#12345G", - "expected": False - }, - { - "description": 'Test for a valid password (at least 8 characters, 1 uppercase, 1 lowercase, 1 digit)', - 'pattern': r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$', - 'test_string': 'Password1', - 'expected': True - }, - { - 'description': 'Test for an invalid password (too short)', - 'pattern': r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$', - 'test_string': 'Pass1', - 'expected': False - }, - { - 'description': 'Test for a string containing only digits', - 'pattern': r'^\d+$', - 'test_string': '123456789', - 'expected': True - }, - { - 'description': 'Test for a string containing non-digits', - 'pattern': r'^\d+$', - 'test_string': '123abc456', - 'expected': False - }, - { - 'description': 'Test for a string with whitespace only', - 'pattern': r'^\s*$', - 'test_string': '', - 'expected': True - }, - { - 'description': 'Test for a string with non-whitespace characters', - 'pattern': r'^\s*$', - 'test_string': ' a ', - 'expected': False - }, - { - 'description': 'Test for matching a word boundary', - 'pattern': r'\bword\b', - 'test_string': 'This is a word in a sentence.', - 'expected': True - }, - { - 'description': 'Test for not matching a word boundary', - 'pattern': r'\bword\b', - 'test_string': 'This is a worded sentence.', - 'expected': False - }, +@mark.parametrize("arguments, library", + product( + ( + { + "description": "Test for a valid email address", + "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", + "test_string": "example@test.com", + "expected": True + }, + { + "description": "Test for an invalid email address (missing domain)", + "pattern": r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", + "test_string": "example@.com", + "expected": False + }, + { + "description": "Test for a valid phone number (US format)", + "pattern": r"^\(\d{3}\) \d{3}-\d{4}$", + "test_string": "(123) 456-7890", + "expected": True + }, + { + "description": "Test for an invalid phone number (wrong format)", + "pattern": r"^\(\d{3}\) \d{3}-\d{4}$", + "test_string": "123-456-7890", + "expected": False + }, + { + "description": "Test for a valid URL", + "pattern": r"^(https?://)(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$", + "test_string": "https://www.example.com/path", + "expected": True + }, + { + "description": "Test for an invalid URL (missing scheme)", + "pattern": r"^(https?://)(www\.)?[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(/.*)?$", + "test_string": "www.example.com/path", + "expected": False + }, + { + "description": "Test for a valid IPv4 address", + "pattern": r"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + "test_string": "192.168.1.1", + "expected": True + }, + { + "description": "Test for an invalid IPv4 address (out of range)", + "pattern": r"^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\." \ + r"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", + "test_string": "256.100.50.25", + "expected": False + }, + { + "description": "Test for a valid date (YYYY-MM-DD)", + "pattern": r"^\d{4}-\d{2}-\d{2}$", + "test_string": "2023-12-31", + "expected": True + }, + { + "description": "Test for an invalid date (wrong format)", + "pattern": r"^\d{4}-\d{2}-\d{2}$", + "test_string": "31/12/2023", + "expected": False + }, + { + "description": "Test for a valid hexadecimal color code", + "pattern": r"^#(?:[0-9a-fA-F]{3}){1,2}$", + "test_string": "#1A2B3C", + "expected": True + }, + { + "description": "Test for an invalid hexadecimal color code (wrong format)", + "pattern": r"^#(?:[0-9a-fA-F]{3}){1,2}$", + "test_string": "#12345G", + "expected": False + }, + { + "description": 'Test for a valid password (at least 8 characters, 1 uppercase, 1 lowercase, 1 digit)', + 'pattern': r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$', + 'test_string': 'Password1', + 'expected': True + }, + { + 'description': 'Test for an invalid password (too short)', + 'pattern': r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$', + 'test_string': 'Pass1', + 'expected': False + }, + { + 'description': 'Test for a string containing only digits', + 'pattern': r'^\d+$', + 'test_string': '123456789', + 'expected': True + }, + { + 'description': 'Test for a string containing non-digits', + 'pattern': r'^\d+$', + 'test_string': '123abc456', + 'expected': False + }, + { + 'description': 'Test for a string with whitespace only', + 'pattern': r'^\s*$', + 'test_string': '', + 'expected': True + }, + { + 'description': 'Test for a string with non-whitespace characters', + 'pattern': r'^\s*$', + 'test_string': ' a ', + 'expected': False + }, + { + 'description': 'Test for matching a word boundary', + 'pattern': r'\bword\b', + 'test_string': 'This is a word in a sentence.', + 'expected': True + }, + { + 'description': 'Test for not matching a word boundary', + 'pattern': r'\bword\b', + 'test_string': 'This is a worded sentence.', + 'expected': False + }, + ), + ("flpc", "re"), ) ) -def test_regex_patterns(args: Dict[Literal["description", "expected", "pattern", "test_string"], str]): - match = re.search(args["pattern"], args["test_string"]) is not None - assert match == args["expected"], f"Failed: {args['description']}" +def test_regex_compile_and_search( + arguments: Dict[Literal["description", "expected", "pattern", "test_string"], str], + library: Literal["flpc", "re"] +) -> None: + __import__(library) + module: ModuleType = modules[library] + pattern: module.Pattern = module.compile(arguments["pattern"]) # type: ignore + match = module.search(pattern, arguments["test_string"]) is not None + assert match == arguments["expected"], f"Failed: {arguments['description']}" From acd53d1526d988fd1adef4de0d5c6b3cebb236d3 Mon Sep 17 00:00:00 2001 From: Sitt Guruvanich Date: Tue, 21 Jan 2025 22:49:17 +0700 Subject: [PATCH 5/5] test: adhere assert_used rule except under tests --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 19fcc97..c194d94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,9 @@ Homepage = "https://github.com/itsmeadarsh2008/flpc" Repository = "https://github.com/itsmeadarsh2008/flpc.git" "Bug Tracker" = "https://github.com/itsmeadarsh2008/flpc/issues" +[tool.bandit.assert_used] +skips = ["tests/**/*.py"] + [tool.maturin] features = ["pyo3/extension-module"]