import unittest
import io
import re
from unittest import mock
import math
import copy
import inspect
import student_X as main #Replace student_X with your filename 
    
    
    
 

class PointBasicsTests(unittest.TestCase):

    def test_default_case(self):
        #test the docstrings
        incorrect = ""
        try:
            doc = main.Point.__doc__
            doc = doc.strip()
        except:
            doc = ""
        test = doc != incorrect
        message = "No docstring for the Point class."
        self.assertTrue(test, message)

        try:
            doc = main.Point.__init__.__doc__
            doc = doc.strip()
        except:
            doc = ""
        test = doc != incorrect
        message = "No docstring for Point.__init__."
        self.assertTrue(test, message)

        try:
            doc = main.Point.__str__.__doc__
            doc = doc.strip()
        except:
            doc = ""
        test = doc != incorrect
        message = "No docstring for Point.__str__."
        self.assertTrue(test, message)
        
        
        function = point_to_string

        a = main.Point(5, 2)

        inputs = (a)
        tested_inputs = inputs #change this if you need to test specific inputs

        #expected answers
        correct_inputs = inputs
        correct_result = "(5, 2)"
        correct_printed = ""

        #run the test
        with mock.patch('sys.stdout', new=io.StringIO()) as fake_stdout:
            if isinstance(inputs, tuple):
                result = function(*inputs)
            else:
                result = function(inputs)
        printed_output = fake_stdout.getvalue().strip()

        
        test = "," in result
        message = "I think you're missing the comma between the numbers."
        self.assertTrue(test, message)
        test = ", " in result
        message = "I think you're missing the space after the comma."
        self.assertTrue(test, message)
        test = correct_printed == printed_output
        message = "Shouldn't print anything out."
        self.assertTrue(test, message)
        test = result == correct_result
        message = "Doesn't work on a Point with two positive fields."
        self.assertTrue(test, message)
        test = tested_inputs == correct_inputs
        message = "Modifies the inputs."
        self.assertTrue(test, message)

        

        a = main.Point(-10, 8)

        inputs = (a)
        tested_inputs = inputs #change this if you need to test specific inputs

        #expected answers
        correct_inputs = inputs
        correct_result = "(-10, 8)"
        correct_printed = ""

        #run the test
        with mock.patch('sys.stdout', new=io.StringIO()) as fake_stdout:
            if isinstance(inputs, tuple):
                result = function(*inputs)
            else:
                result = function(inputs)
        printed_output = fake_stdout.getvalue().strip()

        
        test = correct_printed == printed_output
        message = "Shouldn't print anything out."
        self.assertTrue(test, message)
        test = result == correct_result
        message = "Doesn't work on my hidden Point."
        self.assertTrue(test, message)
        test = tested_inputs == correct_inputs
        message = "Modifies the inputs."
        self.assertTrue(test, message)



def point_to_string(p):
    return "(" + str(p.x) + ", " + str(p.y) + ")"
        
        
if __name__ == "__main__":
    tests = PointBasicsTests()
    tests.test_default_case()