diff --git a/src/safeds/data/tabular/containers/_table.py b/src/safeds/data/tabular/containers/_table.py index cf553eb33..99709faea 100644 --- a/src/safeds/data/tabular/containers/_table.py +++ b/src/safeds/data/tabular/containers/_table.py @@ -25,6 +25,7 @@ NonNumericColumnError, SchemaMismatchError, UnknownColumnNameError, + WrongFileExtensionError, ) from ._column import Column @@ -92,9 +93,12 @@ def from_csv_file(path: str | Path) -> Table: ------ FileNotFoundError If the specified file does not exist. - ValueError - If the file could not be read. + WrongFileExtensionError + If the file is not a csv file. """ + path = Path(path) + if path.suffix != ".csv": + raise WrongFileExtensionError(path, ".csv") try: return Table._from_pandas_dataframe(pd.read_csv(path)) except FileNotFoundError as exception: @@ -105,6 +109,8 @@ def from_excel_file(path: str | Path) -> Table: """ Read data from an Excel file into a table. + Valid file extensions are `.xls`, '.xlsx', `.xlsm`, `.xlsb`, `.odf`, `.ods` and `.odt`. + Parameters ---------- path : str | Path @@ -119,9 +125,13 @@ def from_excel_file(path: str | Path) -> Table: ------ FileNotFoundError If the specified file does not exist. - ValueError - If the file could not be read. + WrongFileExtensionError + If the file is not an Excel file. """ + path = Path(path) + excel_extensions = [".xls", ".xlsx", ".xlsm", ".xlsb", ".odf", ".ods", ".odt"] + if path.suffix not in excel_extensions: + raise WrongFileExtensionError(path, excel_extensions) try: return Table._from_pandas_dataframe( pd.read_excel(path, engine="openpyxl", usecols=lambda colname: "Unnamed" not in colname), @@ -148,9 +158,12 @@ def from_json_file(path: str | Path) -> Table: ------ FileNotFoundError If the specified file does not exist. - ValueError - If the file could not be read. + WrongFileExtensionError + If the file is not a JSON file. """ + path = Path(path) + if path.suffix != ".json": + raise WrongFileExtensionError(path, ".json") try: return Table._from_pandas_dataframe(pd.read_json(path)) except FileNotFoundError as exception: @@ -197,14 +210,20 @@ def from_columns(columns: list[Column]) -> Table: ------ ColumnLengthMismatchError If any of the column sizes does not match with the others. + DuplicateColumnNameError + If multiple columns have the same name. """ dataframe: DataFrame = pd.DataFrame() + column_names = [] for column in columns: if column._data.size != columns[0]._data.size: raise ColumnLengthMismatchError( "\n".join(f"{column.name}: {column._data.size}" for column in columns), ) + if column.name in column_names: + raise DuplicateColumnNameError(column.name) + column_names.append(column.name) dataframe[column.name] = column._data return Table._from_pandas_dataframe(dataframe) @@ -328,6 +347,8 @@ def __eq__(self, other: Any) -> bool: return NotImplemented if self is other: return True + if self.number_of_rows == 0 and other.number_of_rows == 0: + return self.column_names == other.column_names table1 = self.sort_columns() table2 = other.sort_columns() return table1._schema == table2._schema and table1._data.equals(table2._data) @@ -463,7 +484,7 @@ def get_column_type(self, column_name: str) -> ColumnType: Raises ------ - ColumnNameError + UnknownColumnNameError If the specified target column name does not exist. """ return self._schema.get_column_type(column_name) @@ -627,6 +648,10 @@ def add_row(self, row: Row) -> Table: table : Table A new table with the added row at the end. + Raises + ------ + SchemaMismatchError + If the schema of the row does not match the table schema. """ if self._schema != row.schema: raise SchemaMismatchError @@ -650,6 +675,11 @@ def add_rows(self, rows: list[Row] | Table) -> Table: ------- result : Table A new table which combines the original table and the given rows. + + Raises + ------ + SchemaMismatchError + If the schema of on of the row does not match the table schema. """ if isinstance(rows, Table): rows = rows.to_rows() @@ -705,7 +735,7 @@ def keep_only_columns(self, column_names: list[str]) -> Table: Raises ------ - ColumnNameError + UnknownColumnNameError If any of the given columns does not exist. """ invalid_columns = [] @@ -737,7 +767,7 @@ def remove_columns(self, column_names: list[str]) -> Table: Raises ------ - ColumnNameError + UnknownColumnNameError If any of the given columns does not exist. """ invalid_columns = [] @@ -851,7 +881,7 @@ def rename_column(self, old_name: str, new_name: str) -> Table: Raises ------ - ColumnNameError + UnknownColumnNameError If the specified old target column name does not exist. DuplicateColumnNameError If the specified new target column name already exists. @@ -960,7 +990,7 @@ def slice_rows( Raises ------ - ValueError + IndexOutOfBoundsError If the index is out of bounds. """ if start is None: @@ -969,8 +999,10 @@ def slice_rows( if end is None: end = self.number_of_rows - if start < 0 or end < 0 or start >= self.number_of_rows or end > self.number_of_rows or end < start: - raise ValueError("The given index is out of bounds") + if end < start: + raise IndexOutOfBoundsError(slice(start, end)) + if start < 0 or end < 0 or start > self.number_of_rows or end > self.number_of_rows: + raise IndexOutOfBoundsError(start if start < 0 or start > self.number_of_rows else end) new_df = self._data.iloc[start:end:step] new_df.columns = self._schema.column_names @@ -1053,10 +1085,13 @@ def split(self, percentage_in_first: float) -> tuple[Table, Table]: A tuple containing the two resulting tables. The first table has the specified size, the second table contains the rest of the data. - + Raises + ------ + ValueError: + if the 'percentage_in_first' is not between 0 and 1 """ - if percentage_in_first <= 0 or percentage_in_first >= 1: - raise ValueError("the given percentage is not in range") + if percentage_in_first < 0 or percentage_in_first > 1: + raise ValueError("The given percentage is not between 0 and 1") return ( self.slice_rows(0, round(percentage_in_first * self.number_of_rows)), self.slice_rows(round(percentage_in_first * self.number_of_rows)), @@ -1079,6 +1114,13 @@ def tag_columns(self, target_name: str, feature_names: list[str] | None = None) ------- tagged_table : TaggedTable A new tagged table with the given target and feature names. + + Raises + ------ + ValueError + If the target column is also a feature column. + ValueError + If no feature columns are specified. """ from ._tagged_table import TaggedTable @@ -1241,10 +1283,11 @@ def plot_lineplot(self, x_column_name: str, y_column_name: str) -> Image: UnknownColumnNameError If either of the columns do not exist. """ - if not self.has_column(x_column_name): - raise UnknownColumnNameError([x_column_name]) - if not self.has_column(y_column_name): - raise UnknownColumnNameError([y_column_name]) + if not self.has_column(x_column_name) or not self.has_column(y_column_name): + raise UnknownColumnNameError( + ([x_column_name] if not self.has_column(x_column_name) else []) + + ([y_column_name] if not self.has_column(y_column_name) else []), + ) fig = plt.figure() ax = sns.lineplot( @@ -1288,10 +1331,11 @@ def plot_scatterplot(self, x_column_name: str, y_column_name: str) -> Image: UnknownColumnNameError If either of the columns do not exist. """ - if not self.has_column(x_column_name): - raise UnknownColumnNameError([x_column_name]) - if not self.has_column(y_column_name): - raise UnknownColumnNameError([y_column_name]) + if not self.has_column(x_column_name) or not self.has_column(y_column_name): + raise UnknownColumnNameError( + ([x_column_name] if not self.has_column(x_column_name) else []) + + ([y_column_name] if not self.has_column(y_column_name) else []), + ) fig = plt.figure() ax = sns.scatterplot( @@ -1399,8 +1443,16 @@ def to_csv_file(self, path: str | Path) -> None: ---------- path : str | Path The path to the output file. + + Raises + ------ + WrongFileExtensionError + If the file is not a csv file. """ - Path(path).parent.mkdir(parents=True, exist_ok=True) + path = Path(path) + if path.suffix != ".csv": + raise WrongFileExtensionError(path, ".csv") + path.parent.mkdir(parents=True, exist_ok=True) data_to_csv = self._data.copy() data_to_csv.columns = self._schema.column_names data_to_csv.to_csv(path, index=False) @@ -1409,6 +1461,7 @@ def to_excel_file(self, path: str | Path) -> None: """ Write the data from the table into an Excel file. + Valid file extensions are `.xls`, '.xlsx', `.xlsm`, `.xlsb`, `.odf`, `.ods` and `.odt`. If the file and/or the directories do not exist, they will be created. If the file already exists, it will be overwritten. @@ -1416,12 +1469,22 @@ def to_excel_file(self, path: str | Path) -> None: ---------- path : str | Path The path to the output file. + + Raises + ------ + WrongFileExtensionError + If the file is not an Excel file. """ + path = Path(path) + excel_extensions = [".xls", ".xlsx", ".xlsm", ".xlsb", ".odf", ".ods", ".odt"] + if path.suffix not in excel_extensions: + raise WrongFileExtensionError(path, excel_extensions) + # Create Excel metadata in the file tmp_table_file = openpyxl.Workbook() tmp_table_file.save(path) - Path(path).parent.mkdir(parents=True, exist_ok=True) + path.parent.mkdir(parents=True, exist_ok=True) data_to_excel = self._data.copy() data_to_excel.columns = self._schema.column_names data_to_excel.to_excel(path) @@ -1437,8 +1500,16 @@ def to_json_file(self, path: str | Path) -> None: ---------- path : str | Path The path to the output file. + + Raises + ------ + WrongFileExtensionError + If the file is not a JSON file. """ - Path(path).parent.mkdir(parents=True, exist_ok=True) + path = Path(path) + if path.suffix != ".json": + raise WrongFileExtensionError(path, ".json") + path.parent.mkdir(parents=True, exist_ok=True) data_to_json = self._data.copy() data_to_json.columns = self._schema.column_names data_to_json.to_json(path) diff --git a/src/safeds/data/tabular/typing/_schema.py b/src/safeds/data/tabular/typing/_schema.py index 13c0f521a..a75a87241 100644 --- a/src/safeds/data/tabular/typing/_schema.py +++ b/src/safeds/data/tabular/typing/_schema.py @@ -184,7 +184,7 @@ def get_column_type(self, column_name: str) -> ColumnType: Raises ------ - ColumnNameError + UnknownColumnNameError If the specified column name does not exist. Examples diff --git a/src/safeds/exceptions/__init__.py b/src/safeds/exceptions/__init__.py index d65119021..48af59135 100644 --- a/src/safeds/exceptions/__init__.py +++ b/src/safeds/exceptions/__init__.py @@ -10,6 +10,7 @@ TransformerNotFittedError, UnknownColumnNameError, ValueNotPresentWhenFittedError, + WrongFileExtensionError, ) from safeds.exceptions._ml import ( DatasetContainsTargetError, @@ -31,6 +32,7 @@ "TransformerNotFittedError", "UnknownColumnNameError", "ValueNotPresentWhenFittedError", + "WrongFileExtensionError", # ML exceptions "DatasetContainsTargetError", "DatasetMissesFeaturesError", diff --git a/src/safeds/exceptions/_data.py b/src/safeds/exceptions/_data.py index 8a551784b..26e402c1c 100644 --- a/src/safeds/exceptions/_data.py +++ b/src/safeds/exceptions/_data.py @@ -1,5 +1,10 @@ from __future__ import annotations +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from pathlib import Path + class UnknownColumnNameError(KeyError): """ @@ -47,7 +52,10 @@ class IndexOutOfBoundsError(IndexError): """ def __init__(self, index: int | slice): - super().__init__(f"There is no element at index '{index}'.") + if isinstance(index, int): + super().__init__(f"There is no element at index '{index}'.") + else: + super().__init__(f"There is no element in the range [{index.start}, {index.stop}]") class ColumnSizeError(Exception): @@ -92,3 +100,15 @@ class ValueNotPresentWhenFittedError(Exception): def __init__(self, value: str, column: str) -> None: super().__init__(f"Value not present in the table the transformer was fitted on: \n{value} in column {column}.") + + +class WrongFileExtensionError(Exception): + """Exception raised when the file has the wrong file extension.""" + + def __init__(self, file: str | Path, file_extension: str | list[str]) -> None: + super().__init__( + ( + f"The file {file} has a wrong file extension. Please provide a file with the following extension(s):" + f" {file_extension}" + ), + ) diff --git a/tests/safeds/data/tabular/containers/_table/test_add_column.py b/tests/safeds/data/tabular/containers/_table/test_add_column.py index 111be80c6..26958e6a6 100644 --- a/tests/safeds/data/tabular/containers/_table/test_add_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_add_column.py @@ -26,11 +26,11 @@ def test_should_add_column(table1: Table, column: Column, expected: Table) -> No def test_should_raise_error_if_column_name_exists() -> None: table1 = Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}) - with pytest.raises(DuplicateColumnNameError): + with pytest.raises(DuplicateColumnNameError, match=r"Column 'col1' already exists."): table1.add_column(Column("col1", ["a", "b", "c"])) def test_should_raise_error_if_column_size_invalid() -> None: table1 = Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}) - with pytest.raises(ColumnSizeError): + with pytest.raises(ColumnSizeError, match=r"Expected a column of size 3 but got column of size 4."): table1.add_column(Column("col3", ["a", "b", "c", "d"])) diff --git a/tests/safeds/data/tabular/containers/_table/test_add_columns.py b/tests/safeds/data/tabular/containers/_table/test_add_columns.py index 6647e6492..cc4d14fbb 100644 --- a/tests/safeds/data/tabular/containers/_table/test_add_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_add_columns.py @@ -36,30 +36,40 @@ def test_should_add_columns_from_table(table1: Table, table2: Table, expected: T @pytest.mark.parametrize( - ("table", "columns"), + ("table", "columns", "error_message_regex"), [ ( Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), [Column("col3", ["a", "b", "c", "d"]), Column("col4", ["e", "f", "g", "h"])], + r"Expected a column of size 3 but got column of size 4.", ), ], ids=["Two Columns with too many values"], ) -def test_should_raise_error_if_column_size_invalid(table: Table, columns: list[Column] | Table) -> None: - with pytest.raises(ColumnSizeError): +def test_should_raise_error_if_column_size_invalid( + table: Table, + columns: list[Column] | Table, + error_message_regex: str, +) -> None: + with pytest.raises(ColumnSizeError, match=error_message_regex): table.add_columns(columns) @pytest.mark.parametrize( - ("table", "columns"), + ("table", "columns", "error_message_regex"), [ ( Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), [Column("col2", ["a", "b", "c"]), Column("col3", [2, 3, 4])], + r"Column 'col2' already exists.", ), ], ids=["Column already exists"], ) -def test_should_raise_error_if_column_name_in_result_column(table: Table, columns: list[Column] | Table) -> None: - with pytest.raises(DuplicateColumnNameError): +def test_should_raise_error_if_column_name_in_result_column( + table: Table, + columns: list[Column] | Table, + error_message_regex: str, +) -> None: + with pytest.raises(DuplicateColumnNameError, match=error_message_regex): table.add_columns(columns) diff --git a/tests/safeds/data/tabular/containers/_table/test_add_row.py b/tests/safeds/data/tabular/containers/_table/test_add_row.py index a0a222995..e75e96ebb 100644 --- a/tests/safeds/data/tabular/containers/_table/test_add_row.py +++ b/tests/safeds/data/tabular/containers/_table/test_add_row.py @@ -21,5 +21,5 @@ def test_should_add_row(table: Table, row: Row) -> None: def test_should_raise_error_if_row_schema_invalid() -> None: table1 = Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}) row = Row({"col1": 5, "col2": "Hallo"}) - with raises(SchemaMismatchError): + with raises(SchemaMismatchError, match=r"Failed because at least two schemas didn't match."): table1.add_row(row) diff --git a/tests/safeds/data/tabular/containers/_table/test_add_rows.py b/tests/safeds/data/tabular/containers/_table/test_add_rows.py index 01e918b03..88d427784 100644 --- a/tests/safeds/data/tabular/containers/_table/test_add_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_add_rows.py @@ -38,5 +38,5 @@ def test_should_add_rows_from_table(table1: Table, table2: Table, expected: Tabl def test_should_raise_error_if_row_schema_invalid() -> None: table1 = Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}) row = [Row({"col1": 2, "col2": 4}), Row({"col1": 5, "col2": "Hallo"})] - with pytest.raises(SchemaMismatchError): + with pytest.raises(SchemaMismatchError, match=r"Failed because at least two schemas didn't match."): table1.add_rows(row) diff --git a/tests/safeds/data/tabular/containers/_table/test_dataframe.py b/tests/safeds/data/tabular/containers/_table/test_dataframe.py index 3eabb3237..32b06995e 100644 --- a/tests/safeds/data/tabular/containers/_table/test_dataframe.py +++ b/tests/safeds/data/tabular/containers/_table/test_dataframe.py @@ -23,5 +23,8 @@ def test_should_restore_table_from_exchange_object(table: Table) -> None: def test_should_raise_error_if_allow_copy_is_false() -> None: table = Table() - with pytest.raises(NotImplementedError, match="`allow_copy` must be True"): + with pytest.raises( + NotImplementedError, + match=r"For the moment we need to copy the data, so `allow_copy` must be True.", + ): table.__dataframe__(allow_copy=False) diff --git a/tests/safeds/data/tabular/containers/_table/test_filter_rows.py b/tests/safeds/data/tabular/containers/_table/test_filter_rows.py index 2a777f2b3..5d4d40803 100644 --- a/tests/safeds/data/tabular/containers/_table/test_filter_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_filter_rows.py @@ -30,5 +30,5 @@ def test_should_filter_rows(table1: Table, filter_column: str, filter_value: Col # noinspection PyTypeChecker def test_should_raise_error_if_column_type_invalid() -> None: table = Table({"col1": [1, 2, 3], "col2": [1, 1, 4]}) - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=r"'Series' object is not callable"): table.filter_rows(table.get_column("col1")._data > table.get_column("col2")._data) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_columns.py b/tests/safeds/data/tabular/containers/_table/test_from_columns.py index d56bd54af..a0f1ea66b 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_columns.py @@ -1,6 +1,6 @@ import pytest from safeds.data.tabular.containers import Column, Table -from safeds.exceptions import ColumnLengthMismatchError +from safeds.exceptions import ColumnLengthMismatchError, DuplicateColumnNameError @pytest.mark.parametrize( @@ -27,5 +27,13 @@ def test_should_create_table_from_list_of_columns(columns: list[Column], expecte def test_should_raise_error_if_column_length_mismatch() -> None: - with pytest.raises(ColumnLengthMismatchError): + with pytest.raises( + ColumnLengthMismatchError, + match=r"The length of at least one column differs: \ncol1: 3\ncol2: 4", + ): Table.from_columns([Column("col1", [5, 2, 3]), Column("col2", [5, 3, 4, 1])]) + + +def test_should_raise_error_if_duplicate_column_name() -> None: + with pytest.raises(DuplicateColumnNameError, match=r"Column 'col1' already exists."): + Table.from_columns([Column("col1", [5, 2, 3]), Column("col1", [5, 3, 4])]) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py b/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py index d437631b0..e8878e969 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_csv_file.py @@ -2,6 +2,7 @@ import pytest from safeds.data.tabular.containers import Table +from safeds.exceptions import WrongFileExtensionError from tests.helpers import resolve_resource_path @@ -14,10 +15,38 @@ def test_should_create_table_from_csv_file(path: str | Path) -> None: @pytest.mark.parametrize( - "path", - ["test_table_from_csv_file_invalid.csv", Path("test_table_from_csv_file_invalid.csv")], + ("path", "expected_error_message"), + [ + ("test_table_from_csv_file_invalid.csv", r"test_table_from_csv_file_invalid.csv\" does not exist"), + (Path("test_table_from_csv_file_invalid.csv"), r"test_table_from_csv_file_invalid.csv\" does not exist"), + ], ids=["by String", "by path"], ) -def test_should_raise_error_if_file_not_found(path: str | Path) -> None: - with pytest.raises(FileNotFoundError): +def test_should_raise_error_if_file_not_found(path: str | Path, expected_error_message: str) -> None: + with pytest.raises(FileNotFoundError, match=expected_error_message): + Table.from_csv_file(resolve_resource_path(path)) + + +@pytest.mark.parametrize( + ("path", "expected_error_message"), + [ + ( + "invalid_file_extension.file_extension", + ( + r"invalid_file_extension.file_extension has a wrong file extension. Please provide a file with the" + r" following extension\(s\): .csv" + ), + ), + ( + Path("invalid_file_extension.file_extension"), + ( + r"invalid_file_extension.file_extension has a wrong file extension. Please provide a file with the" + r" following extension\(s\): .csv" + ), + ), + ], + ids=["by String", "by path"], +) +def test_should_raise_error_if_wrong_file_extension(path: str | Path, expected_error_message: str) -> None: + with pytest.raises(WrongFileExtensionError, match=expected_error_message): Table.from_csv_file(resolve_resource_path(path)) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_dict.py b/tests/safeds/data/tabular/containers/_table/test_from_dict.py index 724b4ad68..fc894e3ea 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_dict.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_dict.py @@ -32,5 +32,5 @@ def test_should_create_table_from_dict(data: dict[str, list[Any]], expected: Tab def test_should_raise_error_if_columns_have_different_lengths() -> None: - with pytest.raises(ColumnLengthMismatchError): + with pytest.raises(ColumnLengthMismatchError, match=r"The length of at least one column differs: \na: 2\nb: 1"): Table.from_dict({"a": [1, 2], "b": [3]}) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_excel_file.py b/tests/safeds/data/tabular/containers/_table/test_from_excel_file.py index d44c60c9d..f9c0b72f9 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_excel_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_excel_file.py @@ -2,6 +2,7 @@ import pytest from safeds.data.tabular.containers import Table +from safeds.exceptions import WrongFileExtensionError from tests.helpers import resolve_resource_path @@ -36,5 +37,30 @@ def test_should_create_table_from_excel_file(path: str | Path, expected: Table) def test_should_raise_if_file_not_found() -> None: - with pytest.raises(FileNotFoundError): + with pytest.raises(FileNotFoundError, match=r"test_table_from_excel_file_invalid.xls\" does not exist"): Table.from_excel_file(resolve_resource_path("test_table_from_excel_file_invalid.xls")) + + +@pytest.mark.parametrize( + ("path", "expected_error_message"), + [ + ( + "invalid_file_extension.file_extension", + ( + r"invalid_file_extension.file_extension has a wrong file extension. Please provide a file with the" + r" following extension\(s\): \['.xls', '.xlsx', '.xlsm', '.xlsb', '.odf', '.ods', '.odt'\]" + ), + ), + ( + Path("invalid_file_extension.file_extension"), + ( + r"invalid_file_extension.file_extension has a wrong file extension. Please provide a file with the" + r" following extension\(s\): \['.xls', '.xlsx', '.xlsm', '.xlsb', '.odf', '.ods', '.odt'\]" + ), + ), + ], + ids=["by String", "by path"], +) +def test_should_raise_error_if_wrong_file_extension(path: str | Path, expected_error_message: str) -> None: + with pytest.raises(WrongFileExtensionError, match=expected_error_message): + Table.from_excel_file(resolve_resource_path(path)) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_json_file.py b/tests/safeds/data/tabular/containers/_table/test_from_json_file.py index 34c591954..f2c53fd7f 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_json_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_json_file.py @@ -2,6 +2,7 @@ import pytest from safeds.data.tabular.containers import Table +from safeds.exceptions import WrongFileExtensionError from tests.helpers import resolve_resource_path @@ -14,10 +15,38 @@ def test_should_create_table_from_json_file(path: str | Path) -> None: @pytest.mark.parametrize( - "path", - ["test_table_from_json_file_invalid.json", Path("test_table_from_json_file_invalid.json")], + ("path", "expected_error_message"), + [ + ("test_table_from_json_file_invalid.json", r"test_table_from_json_file_invalid.json\" does not exist"), + (Path("test_table_from_json_file_invalid.json"), r"test_table_from_json_file_invalid.json\" does not exist"), + ], ids=["by string", "by path"], ) -def test_should_raise_error_if_file_not_found(path: str | Path) -> None: - with pytest.raises(FileNotFoundError): +def test_should_raise_error_if_file_not_found(path: str | Path, expected_error_message: str) -> None: + with pytest.raises(FileNotFoundError, match=expected_error_message): + Table.from_json_file(resolve_resource_path(path)) + + +@pytest.mark.parametrize( + ("path", "expected_error_message"), + [ + ( + "invalid_file_extension.file_extension", + ( + r"invalid_file_extension.file_extension has a wrong file extension. Please provide a file with the" + r" following extension\(s\): .json" + ), + ), + ( + Path("invalid_file_extension.file_extension"), + ( + r"invalid_file_extension.file_extension has a wrong file extension. Please provide a file with the" + r" following extension\(s\): .json" + ), + ), + ], + ids=["by String", "by path"], +) +def test_should_raise_error_if_wrong_file_extension(path: str | Path, expected_error_message: str) -> None: + with pytest.raises(WrongFileExtensionError, match=expected_error_message): Table.from_json_file(resolve_resource_path(path)) diff --git a/tests/safeds/data/tabular/containers/_table/test_from_rows.py b/tests/safeds/data/tabular/containers/_table/test_from_rows.py index 0ae2d7d31..56c8a296a 100644 --- a/tests/safeds/data/tabular/containers/_table/test_from_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_from_rows.py @@ -33,5 +33,5 @@ def test_should_create_table_from_rows(rows: list[Row], expected: Table) -> None def test_should_raise_error_if_mismatching_schema() -> None: rows = [Row({"A": 1, "B": 2}), Row({"A": 2, "B": "a"})] - with pytest.raises(SchemaMismatchError): + with pytest.raises(SchemaMismatchError, match=r"Failed because at least two schemas didn't match."): Table.from_rows(rows) diff --git a/tests/safeds/data/tabular/containers/_table/test_get_column.py b/tests/safeds/data/tabular/containers/_table/test_get_column.py index 7dccc4adc..f5eccad42 100644 --- a/tests/safeds/data/tabular/containers/_table/test_get_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_get_column.py @@ -16,5 +16,5 @@ def test_should_get_column(table1: Table, expected: Column) -> None: def test_should_raise_error_if_column_name_unknown() -> None: table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=r"Could not find column\(s\) 'col3'"): table.get_column("col3") diff --git a/tests/safeds/data/tabular/containers/_table/test_get_row.py b/tests/safeds/data/tabular/containers/_table/test_get_row.py index 2c5087785..2e1f85fa8 100644 --- a/tests/safeds/data/tabular/containers/_table/test_get_row.py +++ b/tests/safeds/data/tabular/containers/_table/test_get_row.py @@ -15,11 +15,11 @@ def test_should_get_row(table1: Table, expected: Row) -> None: @pytest.mark.parametrize( - "index", - [-1, 5], + ("index", "expected_error_message"), + [(-1, r"There is no element at index '-1'."), (5, r"There is no element at index '5'.")], ids=["<0", "too high"], ) -def test_should_raise_error_if_index_out_of_bounds(index: int) -> None: +def test_should_raise_error_if_index_out_of_bounds(index: int, expected_error_message: str) -> None: table = Table({"A": [1], "B": [2]}) - with pytest.raises(IndexOutOfBoundsError): + with pytest.raises(IndexOutOfBoundsError, match=expected_error_message): table.get_row(index) diff --git a/tests/safeds/data/tabular/containers/_table/test_init.py b/tests/safeds/data/tabular/containers/_table/test_init.py index aa5265869..0f7895715 100644 --- a/tests/safeds/data/tabular/containers/_table/test_init.py +++ b/tests/safeds/data/tabular/containers/_table/test_init.py @@ -22,5 +22,5 @@ def test_should_infer_the_schema(table: Table, expected: Schema) -> None: def test_should_raise_error_if_columns_have_different_lengths() -> None: - with pytest.raises(ColumnLengthMismatchError): + with pytest.raises(ColumnLengthMismatchError, match=r"The length of at least one column differs: \na: 2\nb: 1"): Table({"a": [1, 2], "b": [3]}) diff --git a/tests/safeds/data/tabular/containers/_table/test_inverse_transform_table.py b/tests/safeds/data/tabular/containers/_table/test_inverse_transform_table.py index bb0e151ad..cdcc98153 100644 --- a/tests/safeds/data/tabular/containers/_table/test_inverse_transform_table.py +++ b/tests/safeds/data/tabular/containers/_table/test_inverse_transform_table.py @@ -115,5 +115,5 @@ def test_should_raise_error_if_not_fitted() -> None: transformer = OneHotEncoder() - with pytest.raises(TransformerNotFittedError): + with pytest.raises(TransformerNotFittedError, match=r"The transformer has not been fitted yet."): table.inverse_transform_table(transformer) diff --git a/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py b/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py index a4a1ff723..a38cd6598 100644 --- a/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_keep_only_columns.py @@ -42,5 +42,5 @@ def test_should_keep_only_listed_columns(table: Table, column_names: list[str], def test_should_raise_error_if_column_name_unknown() -> None: table = Table({"A": [1], "B": [2]}) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=r"Could not find column\(s\) 'C'"): table.keep_only_columns(["C"]) diff --git a/tests/safeds/data/tabular/containers/_table/test_plot_boxplots.py b/tests/safeds/data/tabular/containers/_table/test_plot_boxplots.py index 6a8a31665..2e9887db5 100644 --- a/tests/safeds/data/tabular/containers/_table/test_plot_boxplots.py +++ b/tests/safeds/data/tabular/containers/_table/test_plot_boxplots.py @@ -32,5 +32,11 @@ def test_should_match_snapshot(table: Table, path: str) -> None: def test_should_raise_if_column_contains_non_numerical_values() -> None: table = Table.from_dict({"A": ["1", "2", "3.5"], "B": ["0.2", "4", "77"]}) - with pytest.raises(NonNumericColumnError): + with pytest.raises( + NonNumericColumnError, + match=( + r"Tried to do a numerical operation on one or multiple non numerical Columns: \nThis table contains only" + r" non-numerical columns." + ), + ): table.plot_boxplots() diff --git a/tests/safeds/data/tabular/containers/_table/test_plot_lineplot.py b/tests/safeds/data/tabular/containers/_table/test_plot_lineplot.py index 480d5b147..1eb5d101a 100644 --- a/tests/safeds/data/tabular/containers/_table/test_plot_lineplot.py +++ b/tests/safeds/data/tabular/containers/_table/test_plot_lineplot.py @@ -17,11 +17,15 @@ def test_should_match_snapshot() -> None: @pytest.mark.parametrize( - ("x", "y"), - [("C", "A"), ("A", "C")], - ids=["x column", "y column"], + ("x", "y", "error_message"), + [ + ("C", "A", r"Could not find column\(s\) 'C'"), + ("A", "C", r"Could not find column\(s\) 'C'"), + ("C", "D", r"Could not find column\(s\) 'C, D'"), + ], + ids=["x column", "y column", "x and y column"], ) -def test_should_raise_if_column_does_not_exist(x: str, y: str) -> None: +def test_should_raise_if_column_does_not_exist(x: str, y: str, error_message: str) -> None: table = Table({"A": [1, 2, 3], "B": [2, 4, 7]}) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=error_message): table.plot_lineplot(x, y) diff --git a/tests/safeds/data/tabular/containers/_table/test_plot_scatterplot.py b/tests/safeds/data/tabular/containers/_table/test_plot_scatterplot.py index f23353517..1158c0eab 100644 --- a/tests/safeds/data/tabular/containers/_table/test_plot_scatterplot.py +++ b/tests/safeds/data/tabular/containers/_table/test_plot_scatterplot.py @@ -17,13 +17,14 @@ def test_should_match_snapshot() -> None: @pytest.mark.parametrize( - ("table", "col1", "col2"), + ("table", "col1", "col2", "error_message"), [ - (Table({"A": [1, 2, 3], "B": [2, 4, 7]}), "C", "A"), - (Table({"A": [1, 2, 3], "B": [2, 4, 7]}), "B", "C"), + (Table({"A": [1, 2, 3], "B": [2, 4, 7]}), "C", "A", r"Could not find column\(s\) 'C'"), + (Table({"A": [1, 2, 3], "B": [2, 4, 7]}), "B", "C", r"Could not find column\(s\) 'C'"), + (Table({"A": [1, 2, 3], "B": [2, 4, 7]}), "C", "D", r"Could not find column\(s\) 'C, D'"), ], - ids=["First argument doesn't exist", "Second argument doesn't exist"], + ids=["First argument doesn't exist", "Second argument doesn't exist", "Both arguments do not exist"], ) -def test_should_raise_if_column_does_not_exist(table: Table, col1: str, col2: str) -> None: - with pytest.raises(UnknownColumnNameError): +def test_should_raise_if_column_does_not_exist(table: Table, col1: str, col2: str, error_message: str) -> None: + with pytest.raises(UnknownColumnNameError, match=error_message): table.plot_scatterplot(col1, col2) diff --git a/tests/safeds/data/tabular/containers/_table/test_remove_columns.py b/tests/safeds/data/tabular/containers/_table/test_remove_columns.py index f0a47fc18..2ed71334b 100644 --- a/tests/safeds/data/tabular/containers/_table/test_remove_columns.py +++ b/tests/safeds/data/tabular/containers/_table/test_remove_columns.py @@ -4,19 +4,20 @@ @pytest.mark.parametrize( - ("table1", "expected"), + ("table1", "expected", "columns"), [ - (Table({"col1": [1, 2, 1], "col2": ["a", "b", "c"]}), Table({"col1": [1, 2, 1]})), - (Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), Table({"col1": [1, 2, 1]})), + (Table({"col1": [1, 2, 1], "col2": ["a", "b", "c"]}), Table({"col1": [1, 2, 1]}), ["col2"]), + (Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), Table({}), ["col1", "col2"]), + (Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), []), ], - ids=["String", "Integer"], + ids=["one column", "multiple columns", "no columns"], ) -def test_should_remove_table_columns(table1: Table, expected: Table) -> None: - table1 = table1.remove_columns(["col2"]) +def test_should_remove_table_columns(table1: Table, expected: Table, columns: list[str]) -> None: + table1 = table1.remove_columns(columns) assert table1 == expected def test_should_raise_if_column_not_found() -> None: table = Table({"A": [1], "B": [2]}) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=r"Could not find column\(s\) 'C'"): table.remove_columns(["C"]) diff --git a/tests/safeds/data/tabular/containers/_table/test_rename.py b/tests/safeds/data/tabular/containers/_table/test_rename.py index 97b9fc376..edb7d6d8c 100644 --- a/tests/safeds/data/tabular/containers/_table/test_rename.py +++ b/tests/safeds/data/tabular/containers/_table/test_rename.py @@ -18,11 +18,11 @@ def test_should_rename_column(name_from: str, name_to: str, column_one: str, col def test_should_raise_if_old_column_does_not_exist() -> None: table: Table = Table({"A": [1], "B": [2]}) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=r"Could not find column\(s\) 'C'"): table.rename_column("C", "D") def test_should_raise_if_new_column_exists_already() -> None: table: Table = Table({"A": [1], "B": [2]}) - with pytest.raises(DuplicateColumnNameError): + with pytest.raises(DuplicateColumnNameError, match=r"Column 'B' already exists."): table.rename_column("A", "B") diff --git a/tests/safeds/data/tabular/containers/_table/test_replace_column.py b/tests/safeds/data/tabular/containers/_table/test_replace_column.py index aeecb77e9..6dfead5dd 100644 --- a/tests/safeds/data/tabular/containers/_table/test_replace_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_replace_column.py @@ -54,11 +54,11 @@ def test_should_replace_column(table: Table, column_name: str, column: Column, e @pytest.mark.parametrize( - ("old_column_name", "column_values", "column_name", "error"), + ("old_column_name", "column_values", "column_name", "error", "error_message"), [ - ("D", ["d", "e", "f"], "C", UnknownColumnNameError), - ("C", ["d", "e", "f"], "B", DuplicateColumnNameError), - ("C", ["d", "e"], "D", ColumnSizeError), + ("D", ["d", "e", "f"], "C", UnknownColumnNameError, r"Could not find column\(s\) 'D'"), + ("C", ["d", "e", "f"], "B", DuplicateColumnNameError, r"Column 'B' already exists."), + ("C", ["d", "e"], "D", ColumnSizeError, r"Expected a column of size 3 but got column of size 2."), ], ids=["UnknownColumnNameError", "DuplicateColumnNameError", "ColumnSizeError"], ) @@ -67,6 +67,7 @@ def test_should_raise_error( column_values: list[str], column_name: str, error: type[Exception], + error_message: str, ) -> None: input_table: Table = Table( { @@ -77,5 +78,5 @@ def test_should_raise_error( ) column = Column(column_name, column_values) - with pytest.raises(error): + with pytest.raises(error, match=error_message): input_table.replace_column(old_column_name, column) diff --git a/tests/safeds/data/tabular/containers/_table/test_slice_rows.py b/tests/safeds/data/tabular/containers/_table/test_slice_rows.py index aabbc32af..888143d21 100644 --- a/tests/safeds/data/tabular/containers/_table/test_slice_rows.py +++ b/tests/safeds/data/tabular/containers/_table/test_slice_rows.py @@ -1,5 +1,7 @@ import pytest +from _pytest.python_api import raises from safeds.data.tabular.containers import Table +from safeds.exceptions import IndexOutOfBoundsError @pytest.mark.parametrize( @@ -23,17 +25,17 @@ def test_should_slice_rows(table: Table, test_table: Table, second_test_table: T @pytest.mark.parametrize( - ("start", "end", "step"), + ("start", "end", "step", "error_message"), [ - (3, 2, 1), - (4, 0, 1), - (0, 4, 1), - (-4, 0, 1), - (0, -4, 1), + (3, 2, 1, r"There is no element in the range \[3, 2\]"), + (4, 0, 1, r"There is no element in the range \[4, 0\]"), + (0, 4, 1, r"There is no element at index '4'"), + (-4, 0, 1, r"There is no element at index '-4'"), + (0, -4, 1, r"There is no element in the range \[0, -4\]"), ], ) -def test_should_raise_if_index_out_of_bounds(start: int, end: int, step: int) -> None: +def test_should_raise_if_index_out_of_bounds(start: int, end: int, step: int, error_message: str) -> None: table = Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}) - with pytest.raises(ValueError, match="The given index is out of bounds"): + with raises(IndexOutOfBoundsError, match=error_message): table.slice_rows(start, end, step) diff --git a/tests/safeds/data/tabular/containers/_table/test_split.py b/tests/safeds/data/tabular/containers/_table/test_split.py index 4c510299f..591a5c824 100644 --- a/tests/safeds/data/tabular/containers/_table/test_split.py +++ b/tests/safeds/data/tabular/containers/_table/test_split.py @@ -1,20 +1,40 @@ +import pandas as pd import pytest from safeds.data.tabular.containers import Table +from safeds.data.tabular.typing import Integer, Schema @pytest.mark.parametrize( - ("table", "result_train_table", "result_test_table"), + ("table", "result_train_table", "result_test_table", "percentage_in_first"), [ ( Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), Table({"col1": [1, 2], "col2": [1, 2]}), Table({"col1": [1], "col2": [4]}), + 2 / 3, + ), + ( + Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), + Table._from_pandas_dataframe(pd.DataFrame(), Schema({"col1": Integer(), "col2": Integer()})), + Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), + 0, + ), + ( + Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), + Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}), + Table._from_pandas_dataframe(pd.DataFrame(), Schema({"col1": Integer(), "col2": Integer()})), + 1, ), ], - ids=["Table with three rows"], + ids=["2/3%", "0%", "100%"], ) -def test_should_split_table(table: Table, result_test_table: Table, result_train_table: Table) -> None: - train_table, test_table = table.split(2 / 3) +def test_should_split_table( + table: Table, + result_test_table: Table, + result_train_table: Table, + percentage_in_first: int, +) -> None: + train_table, test_table = table.split(percentage_in_first) assert result_test_table == test_table assert result_train_table == train_table @@ -22,15 +42,13 @@ def test_should_split_table(table: Table, result_test_table: Table, result_train @pytest.mark.parametrize( "percentage_in_first", [ - 0.0, - 1.0, -1.0, 2.0, ], - ids=["0.0%", "1.0%", "-1.0%", "2.0%"], + ids=["-100%", "200%"], ) def test_should_raise_if_value_not_in_range(percentage_in_first: float) -> None: table = Table({"col1": [1, 2, 1], "col2": [1, 2, 4]}) - with pytest.raises(ValueError, match="the given percentage is not in range"): + with pytest.raises(ValueError, match=r"The given percentage is not between 0 and 1"): table.split(percentage_in_first) diff --git a/tests/safeds/data/tabular/containers/_table/test_to_csv_file.py b/tests/safeds/data/tabular/containers/_table/test_to_csv_file.py index 60bea9acb..cc2287d70 100644 --- a/tests/safeds/data/tabular/containers/_table/test_to_csv_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_to_csv_file.py @@ -1,12 +1,14 @@ from pathlib import Path from tempfile import NamedTemporaryFile +import pytest from safeds.data.tabular.containers import Table +from safeds.exceptions import WrongFileExtensionError def test_should_create_csv_file_from_table_by_str() -> None: table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) - with NamedTemporaryFile() as tmp_table_file: + with NamedTemporaryFile(suffix=".csv") as tmp_table_file: tmp_table_file.close() with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file: table.to_csv_file(tmp_file.name) @@ -17,10 +19,24 @@ def test_should_create_csv_file_from_table_by_str() -> None: def test_should_create_csv_file_from_table_by_path() -> None: table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) - with NamedTemporaryFile() as tmp_table_file: + with NamedTemporaryFile(suffix=".csv") as tmp_table_file: tmp_table_file.close() with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file: table.to_csv_file(Path(tmp_file.name)) with Path(tmp_table_file.name).open("r", encoding="utf-8") as tmp_file: table_r = Table.from_csv_file(Path(tmp_file.name)) assert table == table_r + + +def test_should_raise_error_if_wrong_file_extension() -> None: + table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) + with NamedTemporaryFile(suffix=".invalid_file_extension") as tmp_table_file: + tmp_table_file.close() + with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file, pytest.raises( + WrongFileExtensionError, + match=( + r".invalid_file_extension has a wrong file extension. Please provide a file with the following" + r" extension\(s\): .csv" + ), + ): + table.to_csv_file(Path(tmp_file.name)) diff --git a/tests/safeds/data/tabular/containers/_table/test_to_excel_file.py b/tests/safeds/data/tabular/containers/_table/test_to_excel_file.py index 96c2803ad..98a00ac62 100644 --- a/tests/safeds/data/tabular/containers/_table/test_to_excel_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_to_excel_file.py @@ -1,7 +1,9 @@ from pathlib import Path from tempfile import NamedTemporaryFile +import pytest from safeds.data.tabular.containers import Table +from safeds.exceptions import WrongFileExtensionError def test_should_create_csv_file_from_table_by_str() -> None: @@ -24,3 +26,17 @@ def test_should_create_csv_file_from_table_by_path() -> None: with Path(tmp_table_file.name).open("r", encoding="utf-8") as tmp_file: table_r = Table.from_excel_file(Path(tmp_file.name)) assert table == table_r + + +def test_should_raise_error_if_wrong_file_extension() -> None: + table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) + with NamedTemporaryFile(suffix=".invalid_file_extension") as tmp_table_file: + tmp_table_file.close() + with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file, pytest.raises( + WrongFileExtensionError, + match=( + r".invalid_file_extension has a wrong file extension. Please provide a file with the following" + r" extension\(s\): \['.xls', '.xlsx', '.xlsm', '.xlsb', '.odf', '.ods', '.odt'\]" + ), + ): + table.to_excel_file(Path(tmp_file.name)) diff --git a/tests/safeds/data/tabular/containers/_table/test_to_json_file.py b/tests/safeds/data/tabular/containers/_table/test_to_json_file.py index 961b4f2a0..10b29ce04 100644 --- a/tests/safeds/data/tabular/containers/_table/test_to_json_file.py +++ b/tests/safeds/data/tabular/containers/_table/test_to_json_file.py @@ -1,12 +1,14 @@ from pathlib import Path from tempfile import NamedTemporaryFile +import pytest from safeds.data.tabular.containers import Table +from safeds.exceptions import WrongFileExtensionError def test_should_create_json_file_from_table_by_str() -> None: table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) - with NamedTemporaryFile() as tmp_table_file: + with NamedTemporaryFile(suffix=".json") as tmp_table_file: tmp_table_file.close() with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file: table.to_json_file(tmp_file.name) @@ -17,10 +19,24 @@ def test_should_create_json_file_from_table_by_str() -> None: def test_should_create_json_file_from_table_by_path() -> None: table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) - with NamedTemporaryFile() as tmp_table_file: + with NamedTemporaryFile(suffix=".json") as tmp_table_file: tmp_table_file.close() with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file: table.to_json_file(Path(tmp_file.name)) with Path(tmp_table_file.name).open("r", encoding="utf-8") as tmp_file: table_r = Table.from_json_file(Path(tmp_file.name)) assert table == table_r + + +def test_should_raise_error_if_wrong_file_extension() -> None: + table = Table({"col1": ["col1_1"], "col2": ["col2_1"]}) + with NamedTemporaryFile(suffix=".invalid_file_extension") as tmp_table_file: + tmp_table_file.close() + with Path(tmp_table_file.name).open("w", encoding="utf-8") as tmp_file, pytest.raises( + WrongFileExtensionError, + match=( + r".invalid_file_extension has a wrong file extension. Please provide a file with the following" + r" extension\(s\): .json" + ), + ): + table.to_json_file(Path(tmp_file.name)) diff --git a/tests/safeds/data/tabular/containers/_table/test_transform_column.py b/tests/safeds/data/tabular/containers/_table/test_transform_column.py index 0707dcae2..6219d9a6b 100644 --- a/tests/safeds/data/tabular/containers/_table/test_transform_column.py +++ b/tests/safeds/data/tabular/containers/_table/test_transform_column.py @@ -28,5 +28,5 @@ def test_should_raise_if_column_not_found() -> None: }, ) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=r"Could not find column\(s\) 'D'"): input_table.transform_column("D", lambda row: row.get_value("A") * 2) diff --git a/tests/safeds/data/tabular/containers/_table/test_transform_table.py b/tests/safeds/data/tabular/containers/_table/test_transform_table.py index 7d93e4b3d..ebd5687d3 100644 --- a/tests/safeds/data/tabular/containers/_table/test_transform_table.py +++ b/tests/safeds/data/tabular/containers/_table/test_transform_table.py @@ -98,7 +98,7 @@ def test_should_raise_if_column_not_found() -> None: }, ) - with pytest.raises(UnknownColumnNameError): + with pytest.raises(UnknownColumnNameError, match=r"Could not find column\(s\) 'col1'"): table_to_transform.transform_table(transformer) @@ -111,5 +111,5 @@ def test_should_raise_if_not_fitted() -> None: transformer = OneHotEncoder() - with pytest.raises(TransformerNotFittedError): + with pytest.raises(TransformerNotFittedError, match=r"The transformer has not been fitted yet."): table.transform_table(transformer)