Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: improve structure of table tests #256

Merged
merged 112 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 99 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
d5f806c
add column and add columns
robmeth Apr 28, 2023
d69726f
filter_rows, from_columns and addition to add_columns
robmeth Apr 28, 2023
d27a08c
test_add_row.py, test_add_rows.py and test_add_column.py modified
daniaHu Apr 28, 2023
85ed64f
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu Apr 28, 2023
91253eb
from_csv_file, from_dict, from_json_file, from_rows
robmeth Apr 28, 2023
be14509
from_json_file, from_rows
robmeth Apr 28, 2023
5602e20
added parametrization in test_column_names.py and test_dataframe.py
jxnior01 Apr 28, 2023
783ff47
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 Apr 28, 2023
c05ccf6
test_get_row.py and test_get_column.py modified
daniaHu Apr 28, 2023
f0ee53f
has_column, to_rows, transform_column, transform_table
robmeth Apr 28, 2023
f27afbd
added parametrization in test_number_of_columns.py, test_number_of_ro…
jxnior01 Apr 28, 2023
ab6312a
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 Apr 28, 2023
b1cc11d
test_rename.py modified
daniaHu Apr 28, 2023
a147937
test_replace_column.py modified
daniaHu Apr 28, 2023
d8c281a
test_repr_html.py modified
daniaHu Apr 28, 2023
48dc656
test_shuffle_rows.py modified
daniaHu Apr 28, 2023
e277fe6
to_columns, to_csv_file, to_json_file
robmeth Apr 28, 2023
61b5c78
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth Apr 28, 2023
6855d11
added parametrization in test_remove_columns_with_missing_values.py
jxnior01 Apr 28, 2023
b715c4c
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 Apr 28, 2023
78c1809
test_to_html.py needed no changes
daniaHu May 5, 2023
2389ef7
test_to_dict.py needed no changes
daniaHu May 5, 2023
f40acf4
from_columns, get_row
robmeth May 5, 2023
88b336e
added parametrization in test_remove_columns_with_non_numerical_value…
jxnior01 May 5, 2023
09e94b2
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 May 5, 2023
0446578
test_table_add_column.py modified
daniaHu May 5, 2023
3a3dd68
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
7bfa0c5
plot_correlation_heatmap, plot_lineplot
robmeth May 5, 2023
9bb9d28
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth May 5, 2023
c1e0590
added parametrization in test_remove_duplicate_rows.py and removed un…
jxnior01 May 5, 2023
1dde7bd
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 May 5, 2023
619c406
test_summary.py modified
daniaHu May 5, 2023
9bcb794
test_summary.py modified
daniaHu May 5, 2023
79650ce
test_summary.py ids added
daniaHu May 5, 2023
775eadc
added parametrization in test_remove_rows_with_missing_values.py
jxnior01 May 5, 2023
741eba0
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 May 5, 2023
f8cc6d6
test_split.py modified
daniaHu May 5, 2023
3ccd325
keep_only_columns, plow_scatterplot,
robmeth May 5, 2023
9af080f
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth May 5, 2023
bf8cb00
test_add_column.py function names lowercase
daniaHu May 5, 2023
84579bb
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
ebc51c7
test_add_column.py functions names modified
daniaHu May 5, 2023
edcddc4
test_add_column.py functions names modified
daniaHu May 5, 2023
4706699
test_add_row.py function name modified
daniaHu May 5, 2023
6609ea1
test_column_names.py reformated
daniaHu May 5, 2023
566aebc
test_column_names.py reformated
daniaHu May 5, 2023
9d58780
test_dataframe.py function name modified
daniaHu May 5, 2023
3cbcef6
test_filter_rows.py function name modified
daniaHu May 5, 2023
3c31536
test_from_columns.py function name modified
daniaHu May 5, 2023
adfb01d
test_from_csv_file.py function name modified
daniaHu May 5, 2023
5971bb1
test_from_dict.py function name changed
daniaHu May 5, 2023
690a347
test_from_json_file.py function name modified
daniaHu May 5, 2023
b6b09b6
slice_rows, sort_columns, split, transform_column, transform_table
robmeth May 5, 2023
41f05f3
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth May 5, 2023
84fe45a
test_from_rows.py function name and test_should_create_table_from_row…
daniaHu May 5, 2023
1fb7611
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
c838bac
test_from_rows.py function name and test_should_create_table_from_row…
daniaHu May 5, 2023
83531f4
test_get_column.py function name modified
daniaHu May 5, 2023
9df3486
test_get_row.py function name modified
daniaHu May 5, 2023
5f4ffca
test_has_column.py imports organized
daniaHu May 5, 2023
d59df42
test_inverse_transform_table.py function name modified and file refor…
daniaHu May 5, 2023
601a9e8
test_keep_only_columns.py added ids and function name modified
daniaHu May 5, 2023
17990e9
test_plot_lineplot.py function name modified
daniaHu May 5, 2023
38cfa04
test_plot_scatterplot.py function name modified
daniaHu May 5, 2023
de53866
test_plot_correlation_heatmap.py imports organised
daniaHu May 5, 2023
99e530a
added ids in test_remove_columns_with_non_numerical_values.py
jxnior01 May 5, 2023
7ed1038
added parametrization tests in test_remove_rows_with_outliers.py
jxnior01 May 5, 2023
929d1f0
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 May 5, 2023
3c7db2d
test_add_column.py modified, removed argument columnType
daniaHu May 5, 2023
8c33023
fix poetry.lock
robmeth May 5, 2023
eb3ad19
copied pyproject.toml from main
daniaHu May 5, 2023
9d6b063
Merge branch 'main' into 98-improve-structure-of-table-tests
robmeth May 5, 2023
111022d
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth May 5, 2023
e4aa1b4
test_remove_columns.py function name modified
daniaHu May 5, 2023
c7e02d5
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
1b90d0d
for linter to be happy
robmeth May 5, 2023
aee7deb
to_rows
robmeth May 5, 2023
f6abcff
to_rows
robmeth May 5, 2023
0a68ab3
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
11554e0
style: apply automated linter fixes
megalinter-bot May 5, 2023
b16b28c
style: apply automated linter fixes
megalinter-bot May 5, 2023
bc1105b
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
25df46d
test_add_columns.py, test_should_raise_error_if_column_size_invalid a…
daniaHu May 5, 2023
805e6d0
coverage: add_rows, filter_rows, from_rows
robmeth May 5, 2023
92b0681
added test function to raise DuplicateColumnNameError exception
jxnior01 May 5, 2023
8586686
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 May 5, 2023
2afc034
formatin
robmeth May 5, 2023
be4db2a
added test function to raise DuplicateColumnNameError exception
jxnior01 May 5, 2023
57fc333
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
jxnior01 May 5, 2023
4f20537
test_plot_scatterplot.py, included both parameters from plot_scatterp…
daniaHu May 5, 2023
ffe5f8a
Merge remote-tracking branch 'origin/98-improve-structure-of-table-te…
daniaHu May 5, 2023
0533f29
coverage: plot_lineplot
robmeth May 5, 2023
686a18d
test_add_columns.py, test_should_raise_error_if_column_name_in_result…
daniaHu May 5, 2023
a7c9e0e
test_add_columns.py, test_should_raise_error_if_column_name_in_result…
daniaHu May 5, 2023
2b9d3b4
coverage: add_row
robmeth May 5, 2023
b3479a3
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth May 5, 2023
9ab4cab
Merge branch 'main' into 98-improve-structure-of-table-tests
lars-reimann May 5, 2023
dd7b3ef
test_add_columns.py, added type annotation to functions
daniaHu May 5, 2023
e006e2e
coverage: add_row, __eq__
robmeth May 5, 2023
a128798
test_plot_scatterplot.py, added type annotation to functions
daniaHu May 5, 2023
c967f6a
style: apply automated linter fixes
megalinter-bot May 5, 2023
8ec0b44
coverage: __eq__
robmeth May 5, 2023
a522381
Merge branch '98-improve-structure-of-table-tests' of https://github.…
robmeth May 5, 2023
a7d9bb3
coverage: __eq__
robmeth May 5, 2023
8e516f4
style: apply automated linter fixes
megalinter-bot May 5, 2023
a54c022
test_eq.py and test_str.py added
daniaHu May 5, 2023
5cdce75
test_str.py more test cases added
daniaHu May 5, 2023
840375e
style: apply automated linter fixes
megalinter-bot May 5, 2023
bab55aa
Merge branch 'main' into 98-improve-structure-of-table-tests
lars-reimann May 5, 2023
51cdad9
test: specify entire lists
lars-reimann May 5, 2023
3454abd
test: fix some warnings
lars-reimann May 5, 2023
edf937f
test: remove unneeded classes
lars-reimann May 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions tests/safeds/data/tabular/containers/_table/test_add_column.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
import pytest
from safeds.data.tabular.containers import Column, Table
from safeds.data.tabular.exceptions import ColumnSizeError, DuplicateColumnNameError
from safeds.data.tabular.typing import ColumnType, Integer, String


@pytest.mark.parametrize(
("column", "col_type"),
("table1", "column", "expected"),
[
(Column("col3", ["a", "b", "c"]), String()),
(Column("col3", [0, -1, -2]), Integer()),
(
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
Column("col3", ["a", "b", "c"]),
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4], "col3": ["a", "b", "c"]}),
),
(
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
Column("col3", [0, -1, -2]),
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4], "col3": [0, -1, -2]}),
),
],
ids=["String", "Integer"],
)
def test_add_column_valid(column: Column, col_type: ColumnType) -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
def test_should_add_column(table1: Table, column: Column, expected: Table) -> None:
table1 = table1.add_column(column)
assert table1.number_of_columns == 3
assert table1.get_column("col3") == column
assert isinstance(table1.schema.get_column_type("col1"), Integer)
assert isinstance(table1.schema.get_column_type("col2"), Integer)
assert isinstance(table1.schema.get_column_type("col3"), type(col_type))
assert table1 == expected


def test_add_column_invalid_duplicate_column_name_error() -> None:
def test_should_raise_error_if_column_name_exists() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
with pytest.raises(DuplicateColumnNameError):
table1 = table1.add_column(Column("col1", ["a", "b", "c"]))


def test_add_column_invalid_column_size_error() -> None:
def test_should_raise_error_if_column_size_invalid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
with pytest.raises(ColumnSizeError):
table1 = table1.add_column(Column("col3", ["a", "b", "c", "d"]))
89 changes: 60 additions & 29 deletions tests/safeds/data/tabular/containers/_table/test_add_columns.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,62 @@
import pytest
from safeds.data.tabular.containers import Column, Table
from safeds.data.tabular.typing import Integer, String


def test_add_columns_valid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
col3 = Column("col3", [0, -1, -2])
col4 = Column("col4", ["a", "b", "c"])
table1 = table1.add_columns([col3, col4])
assert table1.number_of_columns == 4
assert table1.get_column("col3") == col3
assert table1.get_column("col4") == col4
assert isinstance(table1.schema.get_column_type("col1"), Integer)
assert isinstance(table1.schema.get_column_type("col2"), Integer)
assert isinstance(table1.schema.get_column_type("col3"), Integer)
assert isinstance(table1.schema.get_column_type("col4"), String)


def test_add_columns_table_valid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
col3 = Column("col3", [0, -1, -2])
col4 = Column("col4", ["a", "b", "c"])
table2 = Table.from_columns([col3, col4])
from safeds.data.tabular.exceptions import ColumnSizeError, DuplicateColumnNameError


@pytest.mark.parametrize(
("table1", "column1", "column2", "expected"),
[
(
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
Column("col3", [0, -1, -2]),
Column("col4", ["a", "b", "c"]),
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4], "col3": [0, -1, -2], "col4": ["a", "b", "c"]}),
),
],
ids=["add 2 columns"],
)
def test_should_add_columns(table1: Table, column1: Column, column2: Column, expected: Table) -> None:
table1 = table1.add_columns([column1, column2])
assert table1 == expected


@pytest.mark.parametrize(
("table1", "table2", "expected"),
[
(
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
Table.from_dict({"col3": [0, -1, -2], "col4": ["a", "b", "c"]}),
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4], "col3": [0, -1, -2], "col4": ["a", "b", "c"]}),
),
],
ids=["add a table with 2 columns"],
)
def test_should_add_columns_from_table(table1: Table, table2: Table, expected: Table) -> None:
table1 = table1.add_columns(table2)
assert table1.number_of_columns == 4
assert table1.get_column("col3") == col3
assert table1.get_column("col4") == col4
assert isinstance(table1.schema.get_column_type("col1"), Integer)
assert isinstance(table1.schema.get_column_type("col2"), Integer)
assert isinstance(table1.schema.get_column_type("col3"), Integer)
assert isinstance(table1.schema.get_column_type("col4"), String)
assert table1 == expected


@pytest.mark.parametrize(
("table", "columns"),
[
(Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
[Column("col3", ["a", "b", "c", "d"]), Column("col4", ["e", "f", "g", "h"])]),
],
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):
table = table.add_columns(columns)


@pytest.mark.parametrize(
("table", "columns"),
[
(Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
[Column("col2", ["a", "b", "c"]), Column("col3", [2, 3, 4])]),
],
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):
table = table.add_columns(columns)
22 changes: 14 additions & 8 deletions tests/safeds/data/tabular/containers/_table/test_add_row.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import pytest
from _pytest.python_api import raises
from safeds.data.tabular.containers import Row, Table
from safeds.data.tabular.exceptions import SchemaMismatchError


def test_add_row_valid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
row = Row({"col1": 5, "col2": 6})
table1 = table1.add_row(row)
assert table1.number_of_rows == 4
assert table1.get_row(3) == row
assert table1.schema == row._schema
@pytest.mark.parametrize(
("table", "row"),
[
(Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}), Row({"col1": 5, "col2": 6})),
],
ids=["added row"],
)
def test_should_add_row(table: Table, row: Row) -> None:
table = table.add_row(row)
assert table.number_of_rows == 4
assert table.get_row(3) == row
assert table.schema == row._schema


def test_add_row_invalid() -> None:
def test_should_raise_error_if_row_schema_invalid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
row = Row({"col1": 5, "col2": "Hallo"})
with raises(SchemaMismatchError):
Expand Down
88 changes: 38 additions & 50 deletions tests/safeds/data/tabular/containers/_table/test_add_rows.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,47 @@
import pandas as pd
import pytest
from safeds.data.tabular.containers import Row, Table
from safeds.data.tabular.exceptions import SchemaMismatchError


def test_add_rows_valid() -> None:
table1 = Table.from_dict({"col1": ["a", "b", "c"], "col2": [1, 2, 4]})
row1 = Row._from_pandas_dataframe(
pd.DataFrame(
{
"col1": ["d"],
"col2": [6],
},
),
table1.schema,
)
row2 = Row._from_pandas_dataframe(
pd.DataFrame(
{
"col1": ["e"],
"col2": [8],
},

@pytest.mark.parametrize(
("table1", "row1", "row2", "table2"),
[
(
Table.from_dict({"col1": ["a", "b", "c"], "col2": [1, 2, 4]}),
Row({"col1": "d", "col2": 6}),
Row({"col1": "e", "col2": 8}),
Table.from_dict({"col1": ["a", "b", "c", "d", "e"], "col2": [1, 2, 4, 6, 8]}),
),
table1.schema,
)
],
ids=["Rows with string and integer values"],
)
def test_should_add_rows(table1: Table, row1: Row, row2: Row, table2: Table) -> None:
table1 = table1.add_rows([row1, row2])
assert table1.number_of_rows == 5
assert table1.get_row(3) == row1
assert table1.get_row(4) == row2
assert table1.schema == row1._schema
assert table1.schema == row2._schema
assert table1 == table2


def test_add_rows_table_valid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
row1 = Row._from_pandas_dataframe(
pd.DataFrame(
{
"col1": [5],
"col2": [6],
},
),
table1.schema,
)
row2 = Row._from_pandas_dataframe(
pd.DataFrame(
{
"col1": [7],
"col2": [8],
},
@pytest.mark.parametrize(
("table1", "table2", "expected"),
[
(
Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]}),
Table.from_dict({"col1": [5, 7], "col2": [6, 8]}),
Table.from_dict({"col1": [1, 2, 1, 5, 7], "col2": [1, 2, 4, 6, 8]}),
),
table1.schema,
)
table2 = Table.from_rows([row1, row2])
],
ids=["Rows from table"],
)
def test_should_add_rows_from_table(table1: Table, table2: Table, expected: Table) -> None:
table1 = table1.add_rows(table2)
assert table1.number_of_rows == 5
assert table1.get_row(3) == row1
assert table1.get_row(4) == row2
assert table1.schema == row1._schema
assert table1.schema == row2._schema
assert table1 == expected


def test_should_raise_error_if_row_schema_invalid() -> None:
table1 = Table.from_dict({"col1": [1, 2, 1], "col2": [1, 2, 4]})
row = [
Row({"col1": 2, "col2": 4}),
Row({"col1": 5, "col2": "Hallo"})
]
with pytest.raises(SchemaMismatchError):
table1 = table1.add_rows(row)
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import pytest
from safeds.data.tabular.containers import Table


def test_column_names() -> None:
table = Table.from_dict({"col1": [1], "col2": [1]})
assert table.column_names == ["col1", "col2"]


def test_get_column_names_empty() -> None:
table = Table([])
assert table.column_names == []
@pytest.mark.parametrize(
("table", "expected"),
[
((Table.from_dict({"col1": [1], "col2": [1]}), ["col1", "col2"])),
(Table([]), []),
],
ids=["Integer", "empty"],
)
def test_should_compare_column_names(table: Table, expected: list) -> None:
assert table.column_names == expected
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
"non-empty",
],
)
def test_can_restore_table_from_exchange_object(table: Table) -> None:
def test_should_restore_table_from_exchange_object(table: Table) -> None:
exchange_object = table.__dataframe__()
restored = Table(from_dataframe(exchange_object))

assert restored == table


def test_should_raise_if_allow_copy_is_false() -> None:
def test_should_raise_error_if_allow_copy_is_false() -> None:
table = Table.from_dict({})
with pytest.raises(NotImplementedError, match="`allow_copy` must be True"):
table.__dataframe__(allow_copy=False)
55 changes: 55 additions & 0 deletions tests/safeds/data/tabular/containers/_table/test_eq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from typing import Any

import pytest
from safeds.data.tabular.containers import Column, Row


@pytest.mark.parametrize(
("row1", "row2", "expected"),
[
(Row({}), Row({}), True),
lars-reimann marked this conversation as resolved.
Show resolved Hide resolved
(Row({"A": 1}), Row({"A": 1}), True),
(Row({"A": 1}), Row({"A": 2}), False),
(Row({"A": 1, "B": 2, "C": 3}), Row({"A": 2, "B": 4, "C": 3}), False),
(Row({"A": 1, "B": 2, "C": 3}), Row({"A": "1", "B": "2", "C": "3"}), False),
],
ids=[
"empty Row",
"equal Row",
"different names",
"different values",
"different types",
],
)
def test_should_return_whether_two_columns_are_equal(row1: Row, row2: Row, expected: bool) -> None:
assert (row1.__eq__(row2)) == expected


@pytest.mark.parametrize(
"row",
[
Row({}),
Row({"A": 1, "B": 2, "C": 3}),
],
ids=[
"empty",
"non-empty",
],
)
def test_should_return_true_if_objects_are_identical(row: Row) -> None:
assert (row.__eq__(row)) is True


@pytest.mark.parametrize(
("row", "other"),
[
(Row({}), None),
(Row({"A": 1}), Column("col1")),
],
ids=[
"Row vs. None",
"Row vs. Column",
],
)
def test_should_return_not_implemented_if_other_is_not_column(row: Row, other: Any) -> None:
assert (row.__eq__(other)) is NotImplemented
Loading