def setUp(self):
     self.test_func = VulnerabilityFunction(
         self.IMLS_GOOD, self.LOSS_RATIOS_GOOD, self.COVS_GOOD, "LN", "RC")
     self.test_func.seed(seed=3)
class VulnerabilityFunctionTestCase(unittest.TestCase):
    """
    Test for :py:class:`risklib.vulnerability_function.VulnerabilityFunction`.
    """
    IMLS_GOOD = [0.005, 0.007, 0.0098, 0.0137, 0.0192, 0.0269]
    IMLS_BAD = [-0.1, 0.007, 0.0098, 0.0137, 0.0192, 0.0269]
    IMLS_DUPE = [0.005, 0.005, 0.0098, 0.0137, 0.0192, 0.0269]
    IMLS_BAD_ORDER = [0.005, 0.0098, 0.007, 0.0137, 0.0192, 0.0269]

    LOSS_RATIOS_GOOD = [0.1, 0.3, 0.0, 0.5, 1.0, 0.6]
    LOSS_RATIOS_BAD = [0.1, 0.3, 0.0, 1.1, -0.1, 0.6]
    LOSS_RATIOS_TOO_SHORT = [0.1, 0.3, 0.0, 0.5, 1.0]
    LOSS_RATIOS_TOO_LONG = [0.1, 0.3, 0.0, 0.5, 1.0, 0.6, 0.5]

    COVS_GOOD = [0.3, 0.1, 0.3, 0.0, 0.3, 10]
    COVS_BAD = [-0.1, 0.1, 0.3, 0.0, 0.3, 10]
    COVS_TOO_SHORT = [0.3, 0.1, 0.3, 0.0, 0.3]
    COVS_TOO_LONG = [0.3, 0.1, 0.3, 0.0, 0.3, 10, 11]

    def setUp(self):
        self.test_func = VulnerabilityFunction(
            self.IMLS_GOOD, self.LOSS_RATIOS_GOOD, self.COVS_GOOD, "LN", "RC")
        self.test_func.seed(seed=3)

    def test_vuln_func_constructor_raises_on_bad_imls(self):
        # This test attempts to invoke AssertionErrors by passing 3 different
        # sets of bad IMLs to the constructor:
        #     - IML list containing out-of-range value(s)
        #     - IML list containing duplicates
        #     - IML list ordered improperly
        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_BAD, self.LOSS_RATIOS_GOOD, self.COVS_GOOD, "LN", "RC")

        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_DUPE, self.LOSS_RATIOS_GOOD, self.COVS_GOOD, "LN", "RC")

        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_BAD_ORDER, self.LOSS_RATIOS_GOOD,
            self.COVS_GOOD, "LN", "RC")

    def test_vuln_func_constructor_raises_on_bad_cov(self):
        # This test attempts to invoke AssertionErrors by passing 3 different
        # sets of bad CoV values to the constructor:
        #     - CoV list containing out-range-values
        #     - CoV list which is shorter than the IML list
        #     - CoV list which is longer than the IML list
        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_GOOD, self.LOSS_RATIOS_GOOD, self.COVS_BAD, "LN", "RC")

        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_GOOD, self.LOSS_RATIOS_GOOD,
            self.COVS_TOO_SHORT, "LN", "RC")

        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_GOOD, self.LOSS_RATIOS_GOOD,
            self.COVS_TOO_LONG, "LN", "RC")

    def test_vuln_func_constructor_raises_on_bad_loss_ratios(self):
        # This test attempts to invoke AssertionErrors by passing 3 different
        # sets of bad loss ratio values to the constructor:
        #     - loss ratio list containing out-range-values
        #     - loss ratio list which is shorter than the IML list
        #     - loss ratio list which is longer than the IML list
        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_GOOD, self.LOSS_RATIOS_BAD, self.COVS_GOOD, "LN", "RC")

        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_GOOD, self.LOSS_RATIOS_TOO_SHORT,
            self.COVS_GOOD, "LN", "RC")

        self.assertRaises(
            AssertionError, VulnerabilityFunction,
            self.IMLS_GOOD, self.LOSS_RATIOS_TOO_LONG, self.COVS_GOOD,
            "LN", "RC")

    def test_loss_ratio_interp_many_values(self):
        expected_lrs = numpy.array([0.07170362, 0.1754156, 0.09802228])
        test_input = [0.005, 0.006, 0.0269]

        numpy.testing.assert_allclose(expected_lrs, self.test_func(test_input))

    def test_loss_ratio_interp_many_values_clipped(self):
        # Given a list of IML values (abscissae), test for proper interpolation
        # of loss ratios (ordinates).
        # This test also ensures that input IML values are 'clipped' to the IML
        # range defined for the vulnerability function.
        expected_lrs = numpy.array([0.0, 0.16131791, 0.01780234])
        test_input = [0.00049, 0.006, 2.7]

        numpy.testing.assert_allclose(expected_lrs, self.test_func(test_input))

    def test_cov_interp_many_values(self):
        expected_covs = numpy.array([0.3, 0.2, 10])
        test_input = [0.005, 0.006, 0.0269]

        numpy.testing.assert_allclose(
            expected_covs, self.test_func._cov_for(test_input))

    def test_cov_interp_many_values_clipped(self):
        # Given a list of IML values (abscissae), test for proper interpolation
        # of CoVs.
        # This test also ensures that input IML values are 'clipped' to the IML
        # range defined for the vulnerability function.
        expected_covs = numpy.array([0.3, 0.2, 10])
        test_input = [0.0049, 0.006, 0.027]

        numpy.testing.assert_allclose(
            expected_covs, self.test_func._cov_for(test_input))