def test__transform_constraints_is_condition_false_returns_data(self): """Test that method returns data unchanged when necessary. The ``_transform_constraints`` method is expected to return data unchanged when the constraint transform raises a ``MissingConstraintColumnError`` and the ``is_condition`` flag is False. Input: - Table data Output: - Table with dropped columns """ # Setup data = pd.DataFrame({ 'item 0': [0, 1, 2], 'item 1': [3, 4, 5] }, index=[0, 1, 2]) constraint_mock = Mock() constraint_mock.transform.side_effect = MissingConstraintColumnError(missing_columns=[]) constraint_mock.constraint_columns = ['item 0'] table_instance = Table() table_instance._constraints = [constraint_mock] table_instance._constraints_to_reverse = [constraint_mock] # Run result = table_instance._transform_constraints(data, False) # Assert expected_result = pd.DataFrame({ 'item 0': [0, 1, 2], 'item 1': [3, 4, 5] }, index=[0, 1, 2]) assert result.equals(expected_result) assert table_instance._constraints_to_reverse == []
def test_fit_constraint_transform_errors(self): """Test the ``fit`` method when constraints error on transform. The ``fit`` method should loop through all the constraints and try to fit them. Then it should loop through again and try to transform. If any errors are raised, they should be caught and surfaced together. Setup: - Set the ``_constraints`` to be a list of mocked constraints. - Set constraint mocks to raise Exceptions when calling transform. Input: - A ``pandas.DataFrame``. Side effect: - A ``MultipleConstraintsErrors`` error should be raised. """ # Setup data = pd.DataFrame({'a': [1, 2, 3]}) instance = Table() constraint1 = Mock() constraint2 = Mock() constraint1.transform.side_effect = Exception('error 1') constraint2.transform.side_effect = Exception('error 2') instance._constraints = [constraint1, constraint2] # Run / Assert error_message = re.escape('\nerror 1\n\nerror 2') with pytest.raises(MultipleConstraintsErrors, match=error_message): instance.fit(data) constraint1.fit.assert_called_once_with(data) constraint2.fit.assert_called_once_with(data)
def test_fit_constraint_transform_missing_columns_error(self, warnings_mock): """Test the ``fit`` method when transform raises a errors. The ``fit`` method should loop through all the constraints and try to fit them. Then it should loop through again and try to transform. If a ``MissingConstraintColumnError`` or ``FunctionError`` is raised, a warning should be raised and reject sampling should be used. Setup: - Set the ``_constraints`` to be a list of mocked constraints. - Set constraint mocks to raise ``MissingConstraintColumnError`` and ``FunctionError`` when calling transform. - Mock warnings module. Input: - A ``pandas.DataFrame``. Side effect: - ``MissingConstraintColumnError`` and ``FunctionError`` warning messages. """ # Setup data = pd.DataFrame({'a': [1, 2, 3]}) instance = Table() constraint1 = Mock() constraint2 = Mock() constraint3 = Mock() constraint1.transform.return_value = data constraint2.transform.side_effect = MissingConstraintColumnError(['column']) constraint3.transform.side_effect = FunctionError() instance._constraints = [constraint1, constraint2, constraint3] # Run instance.fit(data) # Assert constraint1.fit.assert_called_once_with(data) constraint2.fit.assert_called_once_with(data) constraint3.fit.assert_called_once_with(data) assert warnings_mock.warn.call_count == 2 warning_message1 = ( "Mock cannot be transformed because columns: ['column'] were not found. Using the " 'reject sampling approach instead.' ) warning_message2 = 'Error transforming Mock. Using the reject sampling approach instead.' warnings_mock.warn.assert_has_calls([call(warning_message1), call(warning_message2)])
def test__transform_constraints(self): """Test that method correctly transforms data based on constraints The ``_transform_constraints`` method is expected to loop through constraints and call each constraint's ``transform`` method on the data. Input: - Table data Output: - Transformed data """ # Setup data = pd.DataFrame({ 'item 0': [0, 1, 2], 'item 1': [3, 4, 5] }, index=[0, 1, 2]) transformed_data = pd.DataFrame({ 'item 0': [0, 0.5, 1], 'item 1': [6, 8, 10] }, index=[0, 1, 2]) first_constraint_mock = Mock() second_constraint_mock = Mock() first_constraint_mock.transform.return_value = transformed_data second_constraint_mock.return_value = transformed_data table_instance = Table() table_instance._constraints = [first_constraint_mock, second_constraint_mock] # Run result = table_instance._transform_constraints(data) # Assert assert result.equals(transformed_data) first_constraint_mock.transform.assert_called_once_with(data) second_constraint_mock.transform.assert_called_once_with(transformed_data) assert table_instance._constraints_to_reverse == [ first_constraint_mock, second_constraint_mock ]
def test_fit_fits_and_transforms_constraints(self): """Test the ``fit`` method. The ``fit`` method should loop through all the constraints, fit them, and then call ``transform`` for all of them. Setup: - Set the ``_constraints`` to be a list of mocked constraints. Input: - A ``pandas.DataFrame``. Output: - Same ``pandas.DataFrame``. Side effect: - Each constraint should be fit and transform the data. """ # Setup data = pd.DataFrame({'a': [1, 2, 3]}) transformed_data = pd.DataFrame({'a': [4, 5, 6]}) instance = Table() constraint1 = Mock() constraint2 = Mock() constraint1.transform.return_value = transformed_data constraint2.transform.return_value = data instance._constraints = [constraint1, constraint2] # Run instance.fit(data) # Assert constraint1.fit.assert_called_once_with(data) constraint2.fit.assert_called_once_with(data) constraint1.transform.assert_called_once_with(data) constraint2.transform.assert_called_once_with(transformed_data)