from inspect import signature from os.path import exists from pathlib import Path import numpy as np import pytest from hypothesis import given, settings, strategies as hst from zema_emc_annotated import dataset from zema_emc_annotated.data_types import UncertainArray from zema_emc_annotated.dataset import ( ExtractionDataType, ZEMA_DATASET_HASH, ZEMA_DATASET_URL, ZEMA_QUANTITIES, ZeMASamples, ) small_positive_integers = hst.integers(min_value=1, max_value=10) def test_dataset_has_docstring() -> None: assert dataset.__doc__ is not None def test_dataset_has_enum_extraction_data() -> None: assert hasattr(dataset, "ExtractionDataType") def test_extraction_data_enum_has_docstring_with_values() -> None: assert ExtractionDataType.__doc__ is not None assert "VALUES" in ExtractionDataType.__doc__ def test_extraction_data_enum_has_docstring_with_uncertainties() -> None: assert ExtractionDataType.__doc__ is not None assert "UNCERTAINTIES" in ExtractionDataType.__doc__ def test_dataset_extraction_data_contains_key_for_uncertainties() -> None: assert "qudt:standardUncertainty" in ExtractionDataType._value2member_map_ def test_dataset_extraction_data_contains_key_for_values() -> None: assert "qudt:value" in ExtractionDataType._value2member_map_ def test_dataset_extraction_data_contains_first_values_and_then_uncertainties() -> None: ordered_extraction_data_type = tuple(datatype for datatype in ExtractionDataType) assert "value" in ordered_extraction_data_type[0].value def test_dataset_extraction_data_contains_uncertainties_at_second_position() -> None: ordered_extraction_data_type = tuple(datatype for datatype in ExtractionDataType) assert "Uncertainty" in ordered_extraction_data_type[1].value def test_dataset_all_contains_extraction_data() -> None: assert ExtractionDataType.__name__ in dataset.__all__ def test_dataset_has_constant_quantities() -> None: assert hasattr(dataset, "ZEMA_QUANTITIES") def test_dataset_constant_quantities_is_tuple() -> None: assert isinstance(ZEMA_QUANTITIES, tuple) def test_dataset_constant_quantities_contains_acceleration() -> None: assert "Acceleration" in ZEMA_QUANTITIES def test_dataset_constant_quantities_contains_active_current() -> None: assert "Active_Current" in ZEMA_QUANTITIES def test_dataset_constant_quantities_contains_force() -> None: assert "Force" in ZEMA_QUANTITIES def test_dataset_constant_quantities_contains_motor_current() -> None: assert "Motor_Current" in ZEMA_QUANTITIES def test_dataset_constant_quantities_contains_pressure() -> None: assert "Pressure" in ZEMA_QUANTITIES def test_dataset_constant_quantities_contains_sound_pressure() -> None: assert "Sound_Pressure" in ZEMA_QUANTITIES def test_dataset_constant_quantities_contains_velocity() -> None: assert "Velocity" in ZEMA_QUANTITIES def test_dataset_all_contains_constant_quantities() -> None: assert "ZEMA_QUANTITIES" in dataset.__all__ def test_dataset_has_attribute_ZEMA_DATASET_URL() -> None: assert hasattr(dataset, "ZEMA_DATASET_URL") def test_dataset_attribute_ZEMA_DATASET_URL_is_string() -> None: assert isinstance(ZEMA_DATASET_URL, str) def test_dataset_attribute_ZEMA_DATASET_URL_in_all() -> None: assert "ZEMA_DATASET_URL" in dataset.__all__ def test_dataset_has_attribute_ZEMA_DATASET_HASH() -> None: assert hasattr(dataset, "ZEMA_DATASET_HASH") def test_dataset_attribute_ZEMA_DATASET_HASH() -> None: assert isinstance(ZEMA_DATASET_HASH, str) def test_dataset_attribute_ZEMA_DATASET_HASH_in_all() -> None: assert "ZEMA_DATASET_HASH" in dataset.__all__ def test_dataset_has_attribute_zema_samples() -> None: assert hasattr(dataset, "ZeMASamples") def test_zema_samples_is_callable() -> None: assert callable(ZeMASamples) def test_dataset_all_contains_zema_samples() -> None: assert ZeMASamples.__name__ in dataset.__all__ def test_zema_samples_has_docstring() -> None: assert ZeMASamples.__doc__ is not None def test_zema_samples_has_attribute_check_and_load_cache() -> None: assert hasattr(ZeMASamples, "_check_and_load_cache") def test_dataset_check_and_load_cache_is_callable() -> None: assert callable(ZeMASamples._check_and_load_cache) def test_check_and_load_cache_has_docstring() -> None: assert ZeMASamples._check_and_load_cache.__doc__ is not None def test_check_and_load_cache_expects_parameter_normalize() -> None: assert "normalize" in signature(ZeMASamples._check_and_load_cache).parameters def test_zema_samples_has_attribute_cache_path() -> None: assert hasattr(ZeMASamples, "_cache_path") def test_dataset_cache_path_is_callable() -> None: assert callable(ZeMASamples._cache_path) def test_cache_path_expects_parameter_normalize() -> None: assert "normalize" in signature(ZeMASamples._cache_path).parameters def test_check_and_load_cache_expects_parameter_normalize_as_bool() -> None: assert ( signature(ZeMASamples._check_and_load_cache).parameters["normalize"].annotation is bool ) def test_cache_path_has_docstring() -> None: assert ZeMASamples._cache_path.__doc__ is not None def test_cache_path_actually_returns_path() -> None: assert isinstance( ZeMASamples()._cache_path( signature(ZeMASamples).parameters["normalize"].default ), Path, ) def test_zema_samples_has_attribute_store_cache() -> None: assert hasattr(ZeMASamples, "_store_cache") def test_dataset_store_cache_is_callable() -> None: assert callable(ZeMASamples._store_cache) def test_store_cache_has_docstring() -> None: assert ZeMASamples._store_cache.__doc__ is not None def test_store_cache_expects_parameter_normalize() -> None: assert "normalize" in signature(ZeMASamples._store_cache).parameters @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_store_cache_stores_pickle_file_for_random_input(size_scaler: int) -> None: zema_samples = ZeMASamples(11, size_scaler) assert exists( zema_samples._cache_path(signature(ZeMASamples).parameters["normalize"].default) ) @pytest.mark.webtest @given(small_positive_integers, small_positive_integers) @settings(deadline=None) def test_check_and_load_cache_runs_for_random_uncertain_values_and_returns( n_samples: int, size_scaler: int ) -> None: result = ZeMASamples(n_samples, size_scaler)._check_and_load_cache( signature(ZeMASamples).parameters["normalize"].default ) assert result is None or isinstance(result, UncertainArray) @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_check_and_load_cache_returns_something_for_existing_file( size_scaler: int, ) -> None: zema_samples = ZeMASamples(12, size_scaler) assert ( zema_samples._check_and_load_cache( signature(ZeMASamples).parameters["normalize"].default ) is not None ) def test_store_cache_expects_parameter_normalize_as_bool() -> None: assert ( signature(ZeMASamples._store_cache).parameters["normalize"].annotation is bool ) def test_cache_path_expects_parameter_normalize_as_bool() -> None: assert signature(ZeMASamples._cache_path).parameters["normalize"].annotation is bool def test_cache_path_expects_stats_to_return_path() -> None: assert signature(ZeMASamples._cache_path).return_annotation is Path def test_zema_samples_expects_parameter_idx_start() -> None: assert "idx_start" in signature(ZeMASamples).parameters def test_zema_samples_expects_parameter_n_samples() -> None: assert "n_samples" in signature(ZeMASamples).parameters def test_zema_samples_expects_parameter_size_scaler() -> None: assert "size_scaler" in signature(ZeMASamples).parameters def test_zema_samples_expects_parameter_normalize() -> None: assert "normalize" in signature(ZeMASamples).parameters def test_zema_samples_expects_parameter_n_samples_as_int() -> None: assert signature(ZeMASamples).parameters["n_samples"].annotation is int def test_zema_samples_expects_parameter_idx_start_as_int() -> None: assert signature(ZeMASamples).parameters["idx_start"].annotation is int def test_zema_samples_expects_parameter_normalize_as_bool() -> None: assert signature(ZeMASamples).parameters["normalize"].annotation is bool def test_dataset_zema_samples_expects_parameter_size_scaler_as_int() -> None: assert signature(ZeMASamples).parameters["size_scaler"].annotation is int def test_zema_samples_parameter_n_samples_default_is_one() -> None: assert signature(ZeMASamples).parameters["n_samples"].default == 1 def test_zema_samples_parameter_idx_start_default_is_zero() -> None: assert signature(ZeMASamples).parameters["idx_start"].default == 0 def test_zema_samples_parameter_normalize_default_is_false() -> None: assert not signature(ZeMASamples).parameters["normalize"].default def test_zema_samples_parameter_size_scaler_default_is_one() -> None: assert signature(ZeMASamples).parameters["size_scaler"].default == 1 def test_dataset_zema_samples_states_uncertain_values_are_uncertain_array() -> None: assert ZeMASamples.__annotations__["uncertain_values"] is UncertainArray @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_extract_samples_actually_returns_uncertain_array(n_samples: int) -> None: assert isinstance(ZeMASamples(n_samples).uncertain_values, UncertainArray) @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_extract_samples_actually_returns_uncertain_array_with_n_samples_values( n_samples: int, ) -> None: assert len(ZeMASamples(n_samples).values) == n_samples @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_extract_samples_actually_returns_uncertain_array_with_n_samples_uncertainties( n_samples: int, ) -> None: result_uncertainties = ZeMASamples(n_samples).uncertainties assert result_uncertainties is not None assert len(result_uncertainties) == n_samples @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_default_extract_samples_returns_values_of_eleven_sensors( n_samples: int, ) -> None: assert ZeMASamples(n_samples).values.shape[1] == 11 @pytest.mark.webtest @given(small_positive_integers, small_positive_integers) @settings(deadline=None) def test_extract_samples_returns_eleven_times_scaler_values( n_samples: int, size_scaler: int ) -> None: assert ZeMASamples(n_samples, size_scaler).values.shape[1] == 11 * size_scaler @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_default_extract_samples_returns_uncertainties_of_eleven_sensors( n_samples: int, ) -> None: result_uncertainties = ZeMASamples(n_samples).uncertainties assert result_uncertainties is not None assert result_uncertainties.shape[1] == 11 @pytest.mark.webtest @given(small_positive_integers, small_positive_integers) @settings(deadline=None) def test_extract_samples_returns_eleven_times_scaler_uncertainties( n_samples: int, size_scaler: int ) -> None: result_uncertainties = ZeMASamples(n_samples, size_scaler).uncertainties assert result_uncertainties is not None assert result_uncertainties.shape[1] == 11 * size_scaler @pytest.mark.webtest @given(small_positive_integers) @settings(deadline=None) def test_extract_samples_returns_values_and_uncertainties_which_are_not_similar( n_samples: int, ) -> None: result = ZeMASamples(n_samples) assert not np.all(result.values == result.uncertainties) @pytest.mark.webtest @given(hst.integers(min_value=1, max_value=10000)) @settings(deadline=None) def test_zema_samples_fails_for_more_than_4766_samples( n_samples_above_max: int, ) -> None: with pytest.raises( ValueError, match=r"all the input array dimensions except for the concatenation axis must " r"match exactly.*", ): ZeMASamples(4766 + n_samples_above_max) @pytest.mark.webtest def test_zema_samples_creates_pickle_files() -> None: for size_scaler in (1, 10, 100, 1000, 2000): for normalize in (True, False): assert ZeMASamples(size_scaler=size_scaler, normalize=normalize) @pytest.mark.webtest @given(small_positive_integers, small_positive_integers) @settings(deadline=None) def test_zema_samples_normalized_mean_is_smaller_or_equal( n_samples: int, size_scaler: int ) -> None: normalized_result = ZeMASamples(n_samples, size_scaler, True) not_normalized_result = ZeMASamples(n_samples, size_scaler) assert not_normalized_result.values.mean() >= normalized_result.values.mean() @pytest.mark.webtest @given(small_positive_integers, small_positive_integers) @settings(deadline=None) def test_zema_samples_normalized_std_is_smaller_or_equal( n_samples: int, size_scaler: int ) -> None: normalized_result = ZeMASamples(n_samples, size_scaler, True) not_normalized_result = ZeMASamples(n_samples, size_scaler) assert not_normalized_result.values.std() >= normalized_result.values.std() @pytest.mark.webtest @given( small_positive_integers, small_positive_integers, hst.booleans(), hst.integers(min_value=1, max_value=9), ) @settings(deadline=None) def test_zema_samples_cache_path_contains_starting_from_for_larger_than_zero_startpoint( n_samples: int, size_scaler: int, normalize: bool, idx_start: int ) -> None: zema_samples = ZeMASamples(n_samples, size_scaler, normalize, idx_start) assert "_starting_from_" in str(zema_samples._cache_path(normalize))