Skip to content

Commit

Permalink
fix: capture UserWarning in tests that trigger it
Browse files Browse the repository at this point in the history
The smoothing work generated a large number of UserWarning messages from
tests that were not captured and therefore appeared as noise in the
pytest output.

Capture all of these and inspect them in each test to make sure the
right one is being triggered.

Correct several tests that were improperly emitting warnings or were
emitting the wrong warning for the test case.

Remove unnecessary fixtures for smoothing-failure cases because those
can simply be checked against the unsmoothed output.
  • Loading branch information
scanny committed Nov 6, 2020
1 parent b0c4a05 commit 85edbe2
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 282 deletions.
23 changes: 12 additions & 11 deletions src/cr/cube/cubepart.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,18 @@ def dimension_types(self):
return tuple(d.dimension_type for d in self._dimensions)

def evaluate(self, measure_expr):
"""Return 1D/2D ndarray, values evaluated given the function specification
The `function_spec` contains the function to apply and its parameters, e.g.:
```
{
"function": "one_sided_moving_avg",
"kwargs": {"base_measure": "means", "window": 3},
}
```
This `function_spec` object would apply the function `one_sided_moving_avg` to
the `base_measure` means, using 3 as window.
"""Return 1D/2D ndarray result of evaluating `measure_expr`.
`measure_expr` contains the function to apply and its parameters, like::
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 3
}
This expression specifies application of the `one_sided_moving_avg` function to
the `col_percent` base-measure, with a sliding window of 3 periods.
"""
function = measure_expr.get("function", None)
if function != "one_sided_moving_avg":
Expand Down
11 changes: 5 additions & 6 deletions src/cr/cube/noa/smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def _base_measure(self):

@lazyproperty
def _base_values(self):
""" ndarray, base measure values of the current partition
"""ndarray base-measure values from the partition.
The `base_measure` is expressed in the kwargs of the function_spec and used
to get the values for the partition.
Expand All @@ -96,18 +96,17 @@ def _can_smooth(self):
# --- and it must be at least 2.
if self._window > self._base_values.shape[-1] or self._window < 2:
warnings.warn(
"No smoothing performed. Window (value: {}) parameter is not "
"valid: window must be less than equal to the total period "
"(value: {}) and positive".format(
self._window, self._base_values.shape[-1]
"No smoothing performed. Smoothing window must be between 2 and the "
"number of periods ({}), got {}".format(
self._base_values.shape[-1], self._window
),
UserWarning,
)
return False
# --- no smoothing when column dimension is not a categorical date ---
if not self._is_cat_date:
warnings.warn(
"No smoothing performed. Column dimension must be a categorical date"
"No smoothing performed. Column dimension must be a categorical date."
)
return False
return True
Expand Down
24 changes: 0 additions & 24 deletions tests/expectations/cat-date-x-cat-unsmoothed-col-pct.py

This file was deleted.

7 changes: 0 additions & 7 deletions tests/expectations/cat-x-cat-date-smoothed-col-idx-w1.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/expectations/cat-x-cat-unsmoothed-col-pct.py

This file was deleted.

1 change: 0 additions & 1 deletion tests/expectations/cat-x-mr-unsmoothed-col-pct.py

This file was deleted.

123 changes: 0 additions & 123 deletions tests/expectations/mr-x-ca-cat-x-ca-subvar-unsmoothed-col-pct.py

This file was deleted.

6 changes: 0 additions & 6 deletions tests/expectations/mr-x-mr-unsmoothed-col-pct.py

This file was deleted.

6 changes: 5 additions & 1 deletion tests/integration/test_pairwise_significance.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,11 @@ def test_cat_x_cat_wgtd_pairwise_t_tests(self):
actual.p_vals, load_python_expression("cat-x-cat-wgtd-pw-pvals")
)
np.testing.assert_array_equal(
pairwise_indices, load_python_expression("cat-x-cat-wgtd-pw-indices")
pairwise_indices,
np.array(
load_python_expression("cat-x-cat-wgtd-pw-indices"),
dtype=tuple,
),
)

def test_cat_x_cat_wgtd_scale_means_pariwise_t_tests(self):
Expand Down
97 changes: 63 additions & 34 deletions tests/integration/test_smoothing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@


class DescribeSliceSmoothing(object):
"""Integration-test suite for _Slice.evaluate() method."""

@pytest.mark.parametrize(
"fixture, window, expectation",
(
(CR.CAT_X_CAT_DATE, 1, "cat-x-cat-date-smoothed-col-idx-w1"),
(CR.CAT_X_CAT_DATE_WGTD, 4, "cat-x-cat-date-wgtd-smoothed-col-idx-w4"),
(CR.CAT_X_MR_X_CAT_DATE, 3, "cat-x-mr-x-cat-date-smoothed-col-idx-w3"),
(
Expand Down Expand Up @@ -48,7 +49,6 @@ def it_provides_smoothed_col_index_for_compatible_cubes(
@pytest.mark.parametrize(
"fixture, window, expectation",
(
(CR.CAT_X_CAT_DATE, 1, "cat-x-cat-date-smoothed-col-pct-w1"),
(CR.CAT_X_CAT_DATE_WGTD, 4, "cat-x-cat-date-wgtd-smoothed-col-pct-w4"),
(CR.CAT_X_MR_X_CAT_DATE, 3, "cat-x-mr-x-cat-date-smoothed-col-pct-w3"),
(
Expand Down Expand Up @@ -107,45 +107,65 @@ def it_provides_smoothed_scale_means_for_compatible_cubes(
)

@pytest.mark.parametrize(
"fixture, expectation",
"fixture",
(
(CR.CAT_X_MR, "cat-x-mr-unsmoothed-col-pct"),
(CR.MR_X_MR, "mr-x-mr-unsmoothed-col-pct"),
(CR.MR_X_CA_CAT_X_CA_SUBVAR, "mr-x-ca-cat-x-ca-subvar-unsmoothed-col-pct"),
(CR.CAT_X_CAT, "cat-x-cat-unsmoothed-col-pct"),
(CR.CAT_DATE_X_CAT, "cat-date-x-cat-unsmoothed-col-pct"),
CR.CAT_X_MR,
CR.MR_X_MR,
CR.MR_X_CA_CAT_X_CA_SUBVAR,
CR.CAT_DATE_X_CAT,
),
)
def it_does_not_smooth_col_pct_for_incompatible_cubes(self, fixture, expectation):
cube = Cube(fixture)
slice_ = cube.partitions[0]
col_percent = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 3,
}
)
np.testing.assert_array_almost_equal(
col_percent, load_python_expression(expectation)
def it_warns_and_does_not_smooth_when_dimension_is_not_smoothable(self, fixture):
slice_ = Cube(fixture).partitions[0]
base_values = slice_.column_percentages
expected_warning_regex = (
r"No smoothing performed. Column dimension must be a categorical date."
)

def it_doesnt_smooth_counts_when_window_is_not_valid(self):
slice_ = Cube(CR.CAT_X_CAT_DATE).partitions[0]
col_percent = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 1,
}
with pytest.warns(UserWarning, match=expected_warning_regex):
smoothed_values = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "col_percent",
"window": 3,
}
)

np.testing.assert_array_almost_equal(smoothed_values, base_values)

@pytest.mark.parametrize(
"fixture, base_measure, prop_name, periods, window",
(
(CR.CAT_X_CAT_DATE, "col_percent", "column_percentages", 4, 1),
(CR.CAT_X_CAT_DATE, "col_index", "column_index", 4, 1),
(CR.CAT_X_CAT, "col_percent", "column_percentages", 2, 3),
),
)
def it_warns_and_does_not_smooth_when_window_is_invalid(
self, fixture, base_measure, prop_name, periods, window
):
slice_ = Cube(fixture).partitions[0]
base_values = getattr(slice_, prop_name)
expected_warning_regex = (
r"No smoothing performed. Smoothing window must be between 2 and the "
r"number of periods \(%d\), got %d" % (periods, window)
)
slice2_ = Cube(CR.CAT_X_CAT_DATE).partitions[0]
col_percent2 = slice2_.column_percentages

np.testing.assert_array_almost_equal(col_percent, col_percent2)
with pytest.warns(UserWarning, match=expected_warning_regex):
smoothed_values = slice_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": base_measure,
"window": window,
}
)

np.testing.assert_array_almost_equal(smoothed_values, base_values)


class DescribeStrandMeansSmoothing(object):
"""Integration-test suite for _Strand.evaluate() method."""

def it_provides_smoothed_means_cat_date(self):
strand_ = Cube(CR.CAT_DATE_MEAN).partitions[0]
means = strand_.evaluate(
Expand All @@ -155,11 +175,20 @@ def it_provides_smoothed_means_cat_date(self):
means, [np.nan, np.nan, 2.65670765025029, 2.5774816240050358]
)

def it_doesnt_smoot_means_mr_mean_filt_wgtd(self):
def it_does_not_smooth_means_mr_mean_filt_wgtd(self):
strand_ = Cube(CR.MR_MEAN_FILT_WGTD).partitions[0]
means = strand_.evaluate(
{"function": "one_sided_moving_avg", "base_measure": "mean", "window": 3}
expected_warning_regex = (
r"No smoothing performed. Column dimension must be a categorical date."
)

with pytest.warns(UserWarning, match=expected_warning_regex):
means = strand_.evaluate(
{
"function": "one_sided_moving_avg",
"base_measure": "mean",
"window": 3,
}
)
np.testing.assert_array_almost_equal(
means, [3.724051, 2.578429, 2.218593, 1.865335]
)

0 comments on commit 85edbe2

Please sign in to comment.