################################################################################


import unittest
import random
import point
from rectangle import Rectangle
from rectangle import RectangleException


################################################################################


class RectangleTest(unittest.TestCase):
    def test_init_with_exactly_Two_arguments_zero_given(self):
        with self.assertRaises(TypeError):
            Rectangle()
            
    def test_init_with_exactly_Two_arguments_one_given(self):
        with self.assertRaises(TypeError):
            Rectangle(point.Point(random.random()))

    def test_init_with_bad_points(self):
        with self.assertRaises(RectangleException):
            x_rand = random.random()
            y_rand = random.random()
            Rectangle(point.Point(x_rand + 1, y_rand + 1),
                      point.Point(x_rand, y_rand))

    def test_init_rectangle_as_a_single_point(self):
        with self.assertRaises(RectangleException):
            p = point.Point(random.random(), random.random())
            Rectangle(p, p)

    def test_get_lower_left_point(self):
        x_rand = random.random()
        y_rand = random.random()
        r = Rectangle(point.Point(x_rand, y_rand),
                      point.Point(x_rand + random.random() + 1 , y_rand + random.random() + 1))
        self.assertEquals(point.Point(x_rand, y_rand),
                          r.get_lower_left_point())

    def test_get_upper_right_point(self):
        x_rand = random.random()
        x_rand2 = random.random()
        y_rand = random.random()
        y_rand2 = random.random()
        r = Rectangle(point.Point(x_rand, y_rand),
                      point.Point(x_rand + x_rand2 + 1 , y_rand + y_rand2 + 1))
        self.assertEquals(point.Point(x_rand + x_rand2 + 1 , y_rand + y_rand2 + 1),
                          r.get_upper_right_point())
        
    def test_stringify(self):
        x, y = random.random(), random.random()
        lower_left_point = point.Point(x, y)
        upper_right_point = point.Point(x + random.random(), y + random.random())
        rectangle = Rectangle(lower_left_point, upper_right_point)
        self.assertEquals(str(rectangle), 'Rectangle(%s,%s)' % \
                          (str(lower_left_point), str(upper_right_point)))

    def test_point_in_rectangle(self):
        x, y = random.random(), random.random()
        lower_left_point = point.Point(x, y)
        upper_right_point = point.Point(x + random.random() + 1, y + random.random() + 1)
        rectangle = Rectangle(lower_left_point, upper_right_point)
        p = point.Point(x + random.random(), y + random.random())
        self.assertTrue(p in rectangle)

    def test_point_not_in_rectangle(self):
        x, y = random.random(), random.random()
        lower_left_point = point.Point(x, y)
        upper_right_point = point.Point(x + random.random(), y + random.random())
        rectangle = Rectangle(lower_left_point, upper_right_point)
        p = point.Point(x + random.random() + 1, y + random.random() + 1)
        self.assertFalse(p in rectangle)
        p = point.Point(x + random.random() + 1, y + random.random() + 1)
        self.assertFalse(p in rectangle)

    def test_rectangle_contains_another_rectangle(self):
        x, y = random.random(), random.random()
        big_rectangle = Rectangle(point.Point(x, y),
                                  point.Point(x + random.random() + 3, y + random.random() + 3))
        small_rectangle = Rectangle(point.Point(x + random.random() + 1, y + random.random() + 1),
                                    point.Point(x + random.random() + 2, y + random.random() + 2))
        self.assertTrue(big_rectangle.contains_rectangle(small_rectangle))
        self.assertFalse(small_rectangle.contains_rectangle(big_rectangle))
        
    def test_rectangle_does_not_contain_another_rectangle(self):
        x, y = random.random(), random.random()
        rectangle1 = Rectangle(point.Point(x, y),
                               point.Point(x + random.random() + 2, y + random.random() + 2))
        rectangle2 = Rectangle(point.Point(x + random.random() + 1, y + random.random() + 1),
                               point.Point(x + random.random() + 3, y + random.random() + 3))
        self.assertFalse(rectangle1.contains_rectangle(rectangle2))
        self.assertFalse(rectangle2.contains_rectangle(rectangle1))

    def test_rectangle_intersects_itself(self):
        x, y = random.random(), random.random()
        rectangle = Rectangle(point.Point(x, y),
                                  point.Point(x + random.random(), y + random.random()))
        self.assertTrue(rectangle.intersects_with_rectangle(rectangle))
        
    def test_rectangle_intersects_with_another_rectangle_inclusion_case(self):
        x, y = random.random(), random.random()
        big_rectangle = Rectangle(point.Point(x, y),
                                  point.Point(x + random.random() + 3, y + random.random() + 3))
        small_rectangle = Rectangle(point.Point(x + random.random() + 1, y + random.random() + 1),
                                    point.Point(x + random.random() + 2, y + random.random() + 2))
        self.assertTrue(big_rectangle.intersects_with_rectangle(small_rectangle))
        self.assertTrue(small_rectangle.intersects_with_rectangle(big_rectangle))

    def test_rectangle_intersects_with_another_rectangle_overlap_case(self):
        x, y = random.random(), random.random()
        rectangle1 = Rectangle(point.Point(x, y),
                               point.Point(x + random.random() + 2, y + random.random() + 2))
        rectangle2 = Rectangle(point.Point(x + random.random() + 1, y + random.random() + 1),
                               point.Point(x + random.random() + 3, y + random.random() + 3))
        self.assertTrue(rectangle1.intersects_with_rectangle(rectangle2))
        self.assertTrue(rectangle2.intersects_with_rectangle(rectangle1))

    def test_width(self):
        x_rand = random.random()
        x_rand2 = random.random()
        y_rand = random.random()
        y_rand2 = random.random()
        r = Rectangle(point.Point(x_rand, y_rand),
                      point.Point(x_rand + x_rand2 + 1 , y_rand + y_rand2 + 1))
        self.assertEquals(round(r.width(), 5), round(x_rand2 + 1, 5))

    def test_height(self):
        x_rand = random.random()
        x_rand2 = random.random()
        y_rand = random.random()
        y_rand2 = random.random()
        r = Rectangle(point.Point(x_rand, y_rand),
                      point.Point(x_rand + x_rand2 + 1 , y_rand + y_rand2 + 1))
        self.assertEquals(round(r.height(), 5), round(y_rand2 + 1, 5))
        

################################################################################

        
if __name__ == '__main__':
    unittest.TestLoader().loadTestsFromTestCase(RectangleTest)
    rectangle_suite = unittest.TestLoader().loadTestsFromTestCase(RectangleTest)
    suite  = unittest.TestSuite([rectangle_suite])
    unittest.TextTestRunner(verbosity = 2).run(suite)


################################################################################
