class HouseActionsTestCase(unittest.TestCase):
    """Testing house actions"""
    def setUp(self):
        self.house = House(1)  # one minute timeframe
        self.house.influence = 0.2
        self.house.devices_settings = {
            'energy_src': 'grid',
            'cooling_lvl': 0.5,
            'heating_lvl': 0.5,
            'light_lvl': 0.5,
            'curtains_lvl': 0.5
        }
        self.house.battery['current'] = 0.5

        self.house_empty_battery = House(1)
        self.house_empty_battery.battery['current'] = 0.2
        self.house_empty_battery.devices_settings = {
            'energy_src': 'grid',
        }

    def test_action_sources(self):
        """Test changing between power sources"""

        self.house.action_source_battery()
        self.assertTrue(self.house.devices_settings['energy_src'], 'battery')

        self.house.action_source_grid()
        self.assertTrue(self.house.devices_settings['energy_src'], 'grid')

    def test_action_more_cooling(self):
        """Test more cooling"""

        self.house.action_more_cooling()
        self.assertEqual(self.house.devices_settings['cooling_lvl'], 0.7)

        for _ in range(3):
            self.house.action_more_cooling()
        self.assertEqual(self.house.devices_settings['cooling_lvl'], 1)

    def test_action_less_cooling(self):
        """Test less cooling"""

        self.house.action_less_cooling()
        self.assertEqual(self.house.devices_settings['cooling_lvl'], 0.3)

        for _ in range(3):
            self.house.action_less_cooling()
        self.assertEqual(self.house.devices_settings['cooling_lvl'], 0)

    def test_action_more_heating(self):
        """Test more heating"""

        self.house.action_more_heating()
        self.assertEqual(self.house.devices_settings['heating_lvl'], 0.7)

        for _ in range(3):
            self.house.action_more_heating()
        self.assertEqual(self.house.devices_settings['heating_lvl'], 1)

    def test_action_less_heating(self):
        """Test less heating"""

        self.house.action_less_heating()
        self.assertEqual(self.house.devices_settings['heating_lvl'], 0.3)

        for _ in range(3):
            self.house.action_less_heating()
        self.assertEqual(self.house.devices_settings['heating_lvl'], 0)

    def test_action_more_light(self):
        """Test more light"""

        self.house.action_more_light()
        self.assertEqual(self.house.devices_settings['light_lvl'], 0.6)

        for _ in range(4):
            self.house.action_more_light()
        self.assertEqual(self.house.devices_settings['light_lvl'], 1)

    def test_action_less_light(self):
        """Test less light"""

        self.house.action_less_light()
        self.assertEqual(self.house.devices_settings['light_lvl'], 0.4)

        for _ in range(4):
            self.house.action_less_light()
        self.assertEqual(self.house.devices_settings['light_lvl'], 0)

    def test_action_curtains_up(self):
        """Test curtains up"""

        self.house.action_curtains_up()
        self.assertEqual(self.house.devices_settings['curtains_lvl'], 0.4)

        for _ in range(6):
            self.house.action_curtains_up()
        self.assertEqual(self.house.devices_settings['curtains_lvl'], 0)

    def test_action_curtains_down(self):
        """Test curtains down"""

        self.house.action_curtains_down()
        self.assertEqual(self.house.devices_settings['curtains_lvl'], 0.6)

        for _ in range(4):
            self.house.action_curtains_down()
        self.assertEqual(self.house.devices_settings['curtains_lvl'], 1)

    def test_action_nop(self):
        """Test action nop"""

        devices_settings = dict(self.house.devices_settings)
        self.house.action_nop()
        self.assertDictEqual(devices_settings, self.house.devices_settings,
                             "Action Nop shouldn't change devices' settings")
class HouseActionPenaltiesTestCase(unittest.TestCase):
    """
    Testing the action penalty mechanism.
    """
    def setUp(self):
        self.house = House(timeframe=1)

    def test_penalty_on_curtains_use(self):
        self.house.action_curtains_down()
        self.assertGreater(self.house.action_penalty, 0,
                           "Using curtains should produce action penalty.")

        self.house.action_curtains_up()
        self.assertGreater(self.house.action_penalty, 0,
                           "Using curtains should produce action penalty.")

    def test_curtains_use_penalty_smaller_than_illegal_action_penalty(self):
        self.house.devices_settings['curtains_lvl'] = 0.5
        self.house.action_curtains_down()
        curtains_use_penalty = self.house.action_penalty

        self.house.devices_settings['curtains_lvl'] = 1
        self.house.action_curtains_down()
        illegal_action_penalty = self.house.action_penalty

        self.assertGreater(
            illegal_action_penalty, curtains_use_penalty,
            "Penalty for illegal action should be bigger than"
            "penalty for curtains use")

    def test_penalty_on_illegal_cooling_action(self):
        """Illegal action is defined as increasing the maximum level or
        decreasing the minimum level"""

        self.house.devices_settings['cooling_lvl'] = 0
        self.house.action_less_cooling()
        self.assertGreater(
            self.house.action_penalty, 0,
            "Decreasing the minimum cooling level "
            "should produce action penalty.")

        self.house.devices_settings['cooling_lvl'] = 1
        self.house.action_more_cooling()
        self.assertGreater(
            self.house.action_penalty, 0,
            "Increasing the maximum cooling level "
            "should produce action penalty.")

    def test_penalty_on_illegal_heating_action(self):
        """Illegal action is defined as increasing the maximum level or
        decreasing the minimum level"""

        self.house.devices_settings['heating_lvl'] = 0
        self.house.action_less_heating()
        self.assertGreater(
            self.house.action_penalty, 0,
            "Decreasing the minimum heating level "
            "should produce action penalty.")

        self.house.devices_settings['heating_lvl'] = 1
        self.house.action_more_heating()
        self.assertGreater(
            self.house.action_penalty, 0,
            "Increasing the maximum heating level "
            "should produce action penalty.")

    def test_penalty_on_illegal_light_action(self):
        """Illegal action is defined as increasing the maximum level or
        decreasing the minimum level"""

        self.house.devices_settings['light_lvl'] = 0
        self.house.action_less_light()
        self.assertGreater(
            self.house.action_penalty, 0, "Decreasing the minimum light level "
            "should produce action penalty.")

        self.house.devices_settings['light_lvl'] = 1
        self.house.action_more_light()
        self.assertGreater(
            self.house.action_penalty, 0, "Increasing the maximum light level "
            "should produce action penalty.")

    def test_penalty_on_illegal_curtains_action(self):
        """Illegal action is defined as increasing the maximum level or
        decreasing the minimum level"""

        self.house.devices_settings['curtains_lvl'] = 0
        self.house.action_curtains_up()
        self.assertGreater(
            self.house.action_penalty, 0,
            "Decreasing the minimum curtains level "
            "should produce action penalty.")

        self.house.devices_settings['curtains_lvl'] = 1
        self.house.action_curtains_down()
        self.assertGreater(
            self.house.action_penalty, 0,
            "Increasing the maximum curtains level "
            "should produce action penalty.")