Skip to content

Commit

Permalink
Merge pull request #330 from lvgig/229-bring-ordinalencodertransforme…
Browse files Browse the repository at this point in the history
…r-in-line-with-new-testing-setup

refactored OrdinalEncoderTransformer tests
  • Loading branch information
limlam96 authored Oct 15, 2024
2 parents 83eeb1f + 41a312b commit 3247eba
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 152 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Changed
- Refactored DatetimeSinusoidCalculator tests in new format. `#310 <https://github.com/lvgig/tubular/issues/310>`_
- fixed a bug in CappingTransformer which was preventing use of .get_params method `#311 <https://github.com/lvgig/tubular/issues/311>`_
- Refactored ToDatetimeTransformer tests in new format `#300 <https://github.com/lvgig/tubular/issues/300>`_
- Refactored OrdinalEncoderTransformer tests in new format `#330 <https://github.com/lvgig/tubular/issues/330>`_


1.3.1 (2024-07-18)
Expand Down
181 changes: 29 additions & 152 deletions tests/nominal/test_OrdinalEncoderTransformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
import test_aide as ta

import tests.test_data as d
import tubular
from tests.base_tests import (
ColumnStrListInitTests,
GenericFitTests,
GenericTransformTests,
OtherBaseBehaviourTests,
WeightColumnFitMixinTests,
WeightColumnInitMixinTests,
)
from tubular.nominal import OrdinalEncoderTransformer


Expand Down Expand Up @@ -31,84 +38,20 @@ def create_OrdinalEncoderTransformer_test_df():
return df


class TestInit:
class TestInit(ColumnStrListInitTests, WeightColumnInitMixinTests):
"""Tests for OrdinalEncoderTransformer.init()."""

def test_weights_column_not_str_error(self):
"""Test that an exception is raised if weights_column is not a str."""
with pytest.raises(
TypeError,
match="weights_column should be str or None",
):
OrdinalEncoderTransformer(weights_column=1)
@classmethod
def setup_class(cls):
cls.transformer_name = "OrdinalEncoderTransformer"


class TestFit:
class TestFit(GenericFitTests, WeightColumnFitMixinTests):
"""Tests for OrdinalEncoderTransformer.fit()."""

def test_super_fit_called(self, mocker):
"""Test that fit calls BaseNominalTransformer.fit."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns="b")

spy = mocker.spy(tubular.nominal.BaseNominalTransformer, "fit")

x.fit(df, df["a"])

assert spy.call_count == 1, "unexpected number of calls to BaseTransformer.fit"

call_args = spy.call_args_list[0]
call_pos_args = call_args[0]
call_kwargs = call_args[1]

expected_kwargs = {}

assert (
call_kwargs == expected_kwargs
), "unexpected kwargs in BaseTransformer.fit call"

expected_pos_args = (
x,
create_OrdinalEncoderTransformer_test_df(),
create_OrdinalEncoderTransformer_test_df()["a"],
)

assert len(expected_pos_args) == len(
call_pos_args,
), "unexpected # positional args in BaseTransformer.fit call"

ta.equality.assert_equal_dispatch(
expected_pos_args,
call_pos_args,
"unexpected positional args in BaseTransformer.fit call",
)

def test_fit_returns_self(self):
"""Test fit returns self?."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns="b")

x_fitted = x.fit(df, df["a"])

assert (
x_fitted is x
), "Returned value from create_OrdinalEncoderTransformer_test_df.fit not as expected."

def test_fit_not_changing_data(self):
"""Test fit does not change X."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns="b")

x.fit(df, df["a"])

ta.equality.assert_equal_dispatch(
expected=create_OrdinalEncoderTransformer_test_df(),
actual=df,
msg="Check X not changing during fit",
)
@classmethod
def setup_class(cls):
cls.transformer_name = "OrdinalEncoderTransformer"

def test_learnt_values(self):
"""Test that the ordinal encoder values learnt during fit are expected."""
Expand Down Expand Up @@ -150,18 +93,6 @@ def test_learnt_values_weight(self):
msg="mappings attribute",
)

def test_weights_column_missing_error(self):
"""Test that an exception is raised if weights_column is specified but not present in data for fit."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(weights_column="z", columns=["b", "d", "f"])

with pytest.raises(
ValueError,
match=r"weight col \(z\) is not present in columns of data",
):
x.fit(df, df["a"])

def test_response_column_nulls_error(self):
"""Test that an exception is raised if nulls are present in response_column."""
df = d.create_df_4()
Expand All @@ -175,9 +106,13 @@ def test_response_column_nulls_error(self):
x.fit(df, df["a"])


class TestTransform:
class TestTransform(GenericTransformTests):
"""Tests for OrdinalEncoderTransformer.transform()."""

@classmethod
def setup_class(cls):
cls.transformer_name = "OrdinalEncoderTransformer"

def expected_df_1():
"""Expected output for ."""
df = pd.DataFrame(
Expand All @@ -195,60 +130,6 @@ def expected_df_1():

return df

def test_check_is_fitted_called(self, mocker):
"""Test that BaseTransformer check_mappable_rows called."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns="b")

x.fit(df, df["a"])

expected_call_args = {0: {"args": (df,), "kwargs": {}}}

with ta.functions.assert_function_call(
mocker,
tubular.nominal.BaseNominalTransformer,
"check_mappable_rows",
expected_call_args,
):
x.transform(df)

def test_not_dataframe_error_raised(self):
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns="b")
x.fit(df, df["a"])

with pytest.raises(
TypeError,
match=f"{x.classname()}: X should be a pd.DataFrame",
):
x.transform(X=[1, 2, 3, 4, 5, 6])

def test_super_transform_called(self, mocker):
"""Test that BaseMappingTransformMixin.transform called."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns="b")

x.fit(df, df["a"])

expected_call_args = {
0: {
"args": (x, create_OrdinalEncoderTransformer_test_df()),
"kwargs": {},
},
}

with ta.functions.assert_function_call(
mocker,
tubular.mapping.BaseMappingTransformMixin,
"transform",
expected_call_args,
return_value=create_OrdinalEncoderTransformer_test_df(),
):
x.transform(df)

def test_learnt_values_not_modified(self):
"""Test that the mappings from fit are not changed in transform."""
df = create_OrdinalEncoderTransformer_test_df()
Expand Down Expand Up @@ -295,18 +176,14 @@ def test_expected_output(self, df, expected):
msg_tag="Unexpected values in OrdinalEncoderTransformer.transform",
)

def test_nulls_introduced_in_transform_error(self):
"""Test that transform will raise an error if nulls are introduced."""
df = create_OrdinalEncoderTransformer_test_df()

x = OrdinalEncoderTransformer(columns=["b", "d", "f"])

x.fit(df, df["a"])
class TestOtherBaseBehaviour(OtherBaseBehaviourTests):
"""
Class to run tests for OrdinalEncoderTransformer outside the three standard methods.
df["b"] = "z"
May need to overwite specific tests in this class if the tested transformer modifies this behaviour.
"""

with pytest.raises(
ValueError,
match="OrdinalEncoderTransformer: nulls would be introduced into column b from levels not present in mapping",
):
x.transform(df)
@classmethod
def setup_class(cls):
cls.transformer_name = "OrdinalEncoderTransformer"

0 comments on commit 3247eba

Please sign in to comment.