diff --git a/poetry.lock b/poetry.lock index 1348a20..4af7ca9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -13,6 +13,84 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "coverage" +version = "7.6.10" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, + {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165"}, + {file = "coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3"}, + {file = "coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5"}, + {file = "coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244"}, + {file = "coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3"}, + {file = "coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f"}, + {file = "coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd"}, + {file = "coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377"}, + {file = "coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8"}, + {file = "coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853"}, + {file = "coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50"}, + {file = "coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0"}, + {file = "coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852"}, + {file = "coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359"}, + {file = "coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9"}, + {file = "coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18"}, + {file = "coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e"}, + {file = "coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694"}, + {file = "coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6"}, + {file = "coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe"}, + {file = "coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098"}, + {file = "coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf"}, + {file = "coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2"}, + {file = "coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312"}, + {file = "coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d"}, + {file = "coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a"}, + {file = "coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f"}, + {file = "coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90"}, + {file = "coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d"}, + {file = "coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18"}, + {file = "coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59"}, + {file = "coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f"}, + {file = "coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + [[package]] name = "exceptiongroup" version = "1.2.2" @@ -92,6 +170,25 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "pytest-cov" +version = "6.0.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, + {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, +] + +[package.dependencies] +coverage = {version = ">=7.5", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] + [[package]] name = "tomli" version = "2.2.1" @@ -99,7 +196,7 @@ description = "A lil' TOML parser" optional = false python-versions = ">=3.8" groups = ["dev"] -markers = "python_version < \"3.11\"" +markers = "python_full_version <= \"3.11.0a6\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -138,4 +235,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = "^3.9" -content-hash = "ea1b4551763c67d900d5ddfb7d40e26860f2d08dbc76710fdcf42fb4753e6ca9" +content-hash = "6a46a243a9e9082d4cc17f3b496ca5b1f1c8840ce8a2c1a78c9dd336d684fd35" diff --git a/pyproject.toml b/pyproject.toml index 6051eb5..1e1592a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,6 +12,7 @@ python = "^3.9" [tool.poetry.group.dev.dependencies] pytest = "^8.3.4" +pytest-cov = "^6.0.0" [build-system] requires = ["poetry-core>=1.0.0"] diff --git a/src/pysorting/__init__.py b/src/pysorting/__init__.py index 7ebc68f..78270be 100644 --- a/src/pysorting/__init__.py +++ b/src/pysorting/__init__.py @@ -3,8 +3,12 @@ __version__ = version("pysorting") -from pysorting.bubblesort import bubble_sort +from pysorting.bubblesort import ( + bubble_sort, + InvalidElementTypeError, + NonUniformTypeError, +) from pysorting.quicksort import quick_sort -from pysorting.utils import find_fastest_sorting_function, sorting_time +from pysorting.utils import find_fastest_sorting_function, sorting_time, is_sorted diff --git a/src/pysorting/bubblesort.py b/src/pysorting/bubblesort.py index e5e51e3..fe544e1 100644 --- a/src/pysorting/bubblesort.py +++ b/src/pysorting/bubblesort.py @@ -4,65 +4,25 @@ """ # import numpy as np +from .utils import validate_list_elements -def bubble_sort(arr): - """ - Sorts a list of numbers in ascending order using the Bubble Sort algorithm. - - Parameters - ---------- - arr : list - A list of numeric values to be sorted. - - Returns - ------- - list - A sorted list in ascending order. - - Raises - ------ - TypeError - If the input is not a list. - ValueError - If the list contains non-numeric elements. - - Examples - -------- - >>> bubble_sort([4, 2, 7, 1, 3]) - [1, 2, 3, 4, 7] +class InvalidElementTypeError(Exception): + """Custom exception raised when elements are not strings or lists of strings.""" - >>> bubble_sort([10, -3, 0, 5, 9]) - [-3, 0, 5, 9, 10] - """ - try: - # Validate input type - # if not isinstance(arr, (list,np.ndarray)): - if not isinstance(arr, list): - raise TypeError("Input must be a list.") + def __init__( + self, message="All elements must be either a string or a list of strings." + ): + self.message = message + super().__init__(self.message) - # Validate list elements - if not all(isinstance(x, (int, float, str)) for x in arr): - raise ValueError("All elements in the list must be numeric or be a string.") - n = len(arr) - for i in range(n): - swapped = False - for j in range(0, n - i - 1): - if arr[j] > arr[j + 1]: - arr[j], arr[j + 1] = arr[j + 1], arr[j] # Swap elements - swapped = True - if not swapped: - break - print("Done sorting the array") - return arr +class NonUniformTypeError(Exception): + """Custom exception raised when elements are not strings or lists of strings.""" - except TypeError as te: - raise (f"Some or all of the values in the list are not accepted") - except ValueError as ve: - print(f"ValueError: {ve}") - except Exception as e: - print(f"An unexpected error occurred: {e}") + def __init__(self, message="Elements are not of the same type."): + self.message = message + super().__init__(self.message) def bubble_sort(arr, ascending=True): @@ -96,14 +56,17 @@ def bubble_sort(arr, ascending=True): >>> bubble_sort([10, -3, 0, 5, 9], order="descending") [10, 9, 5, 0, -3] """ + if not all(isinstance(x, (int, float, str)) for x in arr): + raise InvalidElementTypeError() + + if not validate_list_elements(arr): + raise NonUniformTypeError() try: # Validate input type - if not isinstance(arr, list): - raise TypeError("Input must be a list.") + # if not isinstance(arr, list): + # raise TypeError("Input must be a list.") - # Validate list elements - if not all(isinstance(x, (int, float, str)) for x in arr): - raise ValueError("All elements in the list must be numeric or a string.") + # # Validate list elements # Sorting logic n = len(arr) @@ -122,8 +85,6 @@ def bubble_sort(arr, ascending=True): return arr except TypeError as te: - raise TypeError(te) - except ValueError as ve: - raise ValueError(ve) + raise TypeError("Your data should all be of the same type") except Exception as e: raise Exception(f"An unexpected error occurred: {e}") diff --git a/src/pysorting/utils.py b/src/pysorting/utils.py index ea022ab..a2c4ac4 100644 --- a/src/pysorting/utils.py +++ b/src/pysorting/utils.py @@ -80,3 +80,22 @@ def is_sorted(lst, ascending=True): return all(lst[i] <= lst[i + 1] for i in range(len(lst) - 1)) else: return all(lst[i] >= lst[i + 1] for i in range(len(lst) - 1)) + + +def validate_list_elements(elements): + """ + Validates if all elements in a list are either all numerical (int or float) + or all strings. + + Parameters: + - elements (list): List of elements to validate. + + Returns: + - bool: True if the list is valid, False otherwise. + """ + if all(isinstance(e, (int, float)) for e in elements): + return True # All elements are numerical + elif all(isinstance(e, str) for e in elements): + return True # All elements are strings + else: + return False diff --git a/tests/bubblesort_test.py b/tests/bubblesort_test.py index 0ed4c48..06586bf 100644 --- a/tests/bubblesort_test.py +++ b/tests/bubblesort_test.py @@ -1,60 +1,66 @@ import pytest -from pysorting import bubble_sort +from pysorting import bubble_sort, InvalidElementTypeError, NonUniformTypeError -def test_sorted_list(text_data_sorted): +def test_sorted_list(test_data_sorted): """Test if a pre-sorted list remains unchanged.""" expected = [1, 2, 3, 4, 5, 6, 7, 8] - actual = bubble_sort(text_data_sorted) + actual = bubble_sort(test_data_sorted) assert isinstance(actual, list) assert actual == expected -def test_reverse_sorted_list(text_data1): +def test_reverse_sorted_list(test_data1): """Test if a reverse sorting works properly.""" expected = [8, 7, 6, 5, 4, 3, 2, 1] - actual = bubble_sort(text_data1, ascending=False) + actual = bubble_sort(test_data1, ascending=False) assert isinstance(actual, list) assert actual == expected -def test_unsorted_list(text_data1): +def test_unsorted_list(test_data1): """Test if an unsorted list is sorted correctly.""" expected = [1, 2, 3, 4, 5, 6, 7, 8] - actual = bubble_sort(text_data1) + actual = bubble_sort(test_data1) assert isinstance(actual, list) assert actual == expected -def test_single_element_list(text_data_single_element): +def test_single_element_list(test_data_single_element): """Test if a single-element list is handled correctly.""" expected = [5] - actual = bubble_sort(text_data_single_element, ascending=False) + actual = bubble_sort(test_data_single_element, ascending=False) assert isinstance(actual, list) assert len(actual) == 1 assert actual == expected -def test_empty_list(text_data_empty): +def test_empty_list(test_data_empty): """Test if an empty list is handled correctly.""" - actual = bubble_sort(text_data_empty) + actual = bubble_sort(test_data_empty) assert isinstance(actual, list) assert len(actual) == 0 -def test_value_error(text_data_error): +def test_type_error(test_data_error2): """Test if a TypeError is raised for non-list inputs.""" - with pytest.raises(ValueError): - bubble_sort(text_data_error) + with pytest.raises(TypeError): + bubble_sort(test_data_error2) -def test_type_error(text_data_error2): +def test_invalid_type_error(test_invalid_error): """Test if a TypeError is raised for non-list inputs.""" - with pytest.raises(TypeError): - bubble_sort(text_data_error2) + with pytest.raises(InvalidElementTypeError): + bubble_sort(test_invalid_error) + + +def test_non_uniform_error(test_nonuniform_error): + """Test if a TypeError is raised for non-list inputs.""" + with pytest.raises(NonUniformTypeError): + bubble_sort(test_nonuniform_error) diff --git a/tests/conftest.py b/tests/conftest.py index 344bc55..e0fa731 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,31 +1,42 @@ import pytest +# pytest --cov-branch --cov=src/pysorting/ @pytest.fixture -def text_data1(): +def test_data1(): return [5, 3, 8, 6, 2, 7, 4, 1] @pytest.fixture -def text_data_single_element(): +def test_data_single_element(): return [5] @pytest.fixture -def text_data_sorted(): +def test_data_sorted(): return [1, 2, 3, 4, 5, 6, 7, 8] @pytest.fixture -def text_data_empty(): +def test_data_empty(): return [] @pytest.fixture -def text_data_error(): +def test_data_error(): return [3, "apple", 7, None] @pytest.fixture -def text_data_error2(): +def test_data_error2(): return "hello" + + +@pytest.fixture +def test_invalid_error(): + return [3, "apple", 7, []] + + +@pytest.fixture +def test_nonuniform_error(): + return [3, "apple", 7] diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..0a4e2a2 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,35 @@ +from pysorting import bubble_sort +from pysorting import find_fastest_sorting_function, sorting_time, is_sorted + + +def test_sorting_time(): + data = [5, 3, 8, 6, 2, 7, 4, 1] + elapsed_time = sorting_time(bubble_sort, data) + assert elapsed_time > 0 # Ensure the time taken is positive + assert isinstance(elapsed_time, float) # Ensure the returned value is a float + + +# Test find_fastest_sorting_function +def test_find_fastest_sorting_function(): + data = [5, 3, 8, 6, 2, 7, 4, 1] + sorting_functions = [bubble_sort] + fastest_func, fastest_time = find_fastest_sorting_function(sorting_functions, data) + + assert fastest_func in sorting_functions # Ensure the fastest function is valid + assert fastest_time > 0 # Ensure the time taken is positive + assert isinstance(fastest_time, float) # Ensure the returned time is a float + + +# Test is_sorted +def test_is_sorted(): + # Ascending order + assert is_sorted([1, 2, 3, 4, 5]) == True + assert is_sorted([5, 4, 3, 2, 1]) == False + + # Descending order + assert is_sorted([5, 4, 3, 2, 1], ascending=False) == True + assert is_sorted([1, 2, 3, 4, 5], ascending=False) == False + + # Edge cases + assert is_sorted([]) == True # Empty list is sorted + assert is_sorted([42]) == True # Single-element list is sorted