Repository: scipy/scipy
File: scipy/stats/tests/test_correlation.py (Python)

Code before:
            res = stats.spearmanrho(y, x)
            check_nan(res)


class TestTheilslopes:
    def test_theilslopes(self):
        # Test for basic slope and intercept.
        slope, intercept, lower, upper = stats.theilslopes([0, 1, 1])
        assert_allclose(slope, 0.5)
        assert_allclose(intercept, 0.5)

        slope, intercept, lower, upper = stats.theilslopes([0, 1, 1], method='joint')
        assert_allclose(slope, 0.5)
        assert_allclose(intercept, 0.0)

        # Test of confidence intervals from example in Sen (1968).
        x = [1, 2, 3, 4, 10, 12, 18]
        y = [9, 15, 19, 20, 45, 55, 78]
        slope, intercept, lower, upper = stats.theilslopes(y, x, 0.07)
        assert_allclose(slope, 4)
        assert_allclose(intercept, 4.0)
        assert_allclose(upper, 4.38, rtol=5e-3)
        assert_allclose(lower, 3.71, rtol=5e-3)

        slope, intercept, lower, upper = stats.theilslopes(y, x, 0.07,
                                                           method='joint')
        assert_allclose(slope, 4)
        assert_allclose(intercept, 6.0)
        assert_allclose(upper, 4.38, rtol=5e-3)
        assert_allclose(lower, 3.71, rtol=5e-3)

    def test_input_validation(self):
        msg = ("method must be either 'joint' or 'separate'."
               "'joint_separate' is invalid.")
        with pytest.raises(ValueError, match=msg):
            stats.theilslopes([0, 1, 1], method='joint_separate')

    @skip_xp_invalid_arg
    def test_mask(self):
        # Test for correct masking.
        y = np.ma.array([0, 1, 100, 1], mask=[False, False, True, False])
        slope, intercept, lower, upper = stats.theilslopes(y)
        assert_allclose(slope, 0.5)
        assert_allclose(intercept, 0.5)

        slope, intercept, lower, upper = stats.theilslopes(y, method='joint')
        assert_allclose(slope, 0.5)
        assert_allclose(intercept, 0.0)

    def test_theilslopes_warnings(self):
        # Test `theilslopes` with degenerate input; see gh-15943

Review comment (suggestion):
Calculate the reference value rather than hard-coding, since it's going to be different for `theilslopes` and `siegelslopes`.

Code after:
            res = stats.spearmanrho(y, x)
            check_nan(res)


class RobustSlopesTest:
    #  'iv, mask, warnings, consistency, gh19678, mstats'
    def test_input_validation(self):
        pfun = getattr(stats, self.pfun)
        other_method = 'joint' if pfun == stats.theilslopes else 'hierarchical'
        msg = (f"method must be either '{other_method}' or 'separate'. "
               "'joint_separate' is invalid.")
        with pytest.raises(ValueError, match=msg):
            pfun([0, 1, 1], method='joint_separate')

    @skip_xp_invalid_arg
    @pytest.mark.parametrize("method", ['separate', 'other'])
    def test_mask(self, method):
        pfun = getattr(stats, self.pfun)
        if method == 'other':
            method = 'joint' if self.pfun =='theilslopes' else 'hierarchical'

        # Test for correct masking.
        mask = np.asarray([False, False, True, False])
        y = np.ma.array([0, 1, 100, 1], mask=mask)
        res = pfun(y, method=method)
        ref = pfun(y[~mask], method=method)

        assert_allclose(res.slope, ref.slope)
        assert_allclose(res.intercept, ref.intercept)

    def test_warnings(self):
        # Test `theilslopes` with degenerate input; see gh-15943
        pfun = getattr(stats, self.pfun)
        msg = "All-NaN slice.*|Mean of empty slice|invalid value encountered.*"
        with pytest.warns(RuntimeWarning, match=msg):
            res = pfun([0, 1], [0, 0])
            assert np.all(np.isnan(res))
        with warnings.catch_warnings():
            warnings.filterwarnings(
                "ignore", "invalid value encountered...", RuntimeWarning)
            res = stats.theilslopes([0, 0, 0], [0, 1, 0])
            assert_allclose(res, (0, 0, np.nan, np.nan))

    def test_namedtuple_consistency(self):
        """
        Simple test to ensure tuple backwards-compatibility of the returned object.
        """
        pfun = getattr(stats, self.pfun)

        y = [1, 2, 4]
        x = [4, 6, 8]