"""Unit testing module for Type guess"""
import unittest

from os.path import abspath, dirname, join
from io import StringIO

import pandas as pd
import numpy as np


PREPROCESS_DIR = dirname(dirname(dirname(abspath(__file__))))
INPUT_DIR = join(PREPROCESS_DIR, 'input')

from raven_preprocess.msg_util import msg, msgt, dashes
from raven_preprocess.type_guess_util import TypeGuessUtil
import raven_preprocess.col_info_constants as col_const



class TestTypeGuess(unittest.TestCase):
    """Unit testing class for type_guess_util"""
    col_info = {}

    def test_10_is_logical(self, col_info=col_info):
        """(10) Test the is_logical with logical Series"""
        msgt(self.test_10_is_logical.__doc__)

        msg('Test a logical series')
        series = pd.Series([True, False, True, True])
        self.assertTrue(TypeGuessUtil.is_logical(series))

        msg('Test a logical series that includes Nan and None')
        series = pd.Series([True, False, True, True, np.nan, None])
        self.assertTrue(TypeGuessUtil.is_logical(series))

    def test_20_is_logical_empty_string(self,col_info = col_info):
        """(20) Test series with empty string, expect not logical"""
        msgt(self.test_20_is_logical_empty_string.__doc__)

        series = pd.Series([True, False, True, True, ""])

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

    def test_30_is_logical_empty_list(self,col_info = col_info):
        """(30) Test empty series, expect not logical"""
        msgt(self.test_30_is_logical_empty_list.__doc__)

        series = pd.Series([])

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

    def test_40_series_with_string_booleans(self,col_info = col_info):
        """(40) Test series with 'TRUE', 'FALSE'"""
        msgt(self.test_40_series_with_string_booleans.__doc__)

        test_data = StringIO(('col1\n'
                              'TRUE\n'
                              'FALSE\n'
                              'TRUE\n'
                              'FALSE'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series))

        test_data = StringIO(('col1\n'
                              'TRUE\n'
                              '\n'
                              'FALSE\n'
                              'TRUE\n'
                              'FALSE'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series))

    def test_50_series_with_string_not_boolean(self,col_info = col_info):
        """(50) Test series with string 'Red', 'Blue'"""
        msgt(self.test_50_series_with_string_not_boolean.__doc__)

        test_data = StringIO(('col1\n'
                              'Red\n'
                              'Blue\n'
                              'Green\n'
                              'Purple'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

        test_data = StringIO(('col1\n'
                              'Red\n'
                              '\n'
                              'Blue\n'
                              'Green\n'
                              'Purple'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

    """ Test cases for is_not_numeric function"""

    def test_60_is_not_numeric(self,col_info = col_info):
        """(60) Test series with int eg: 2, 4, 8'"""
        msgt(self.test_60_is_not_numeric.__doc__)
        msg('Test a int series')
        series = pd.Series([2, 6, 7, 3, 2, 65])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series))

    def test_70_is_not_numeric(self,col_info = col_info):
        """(70) Test series with float eg: 2, 4, 8'"""
        msgt(self.test_70_is_not_numeric.__doc__)
        msg('Test a float series')
        series = pd.Series([2.5, 3.4, 7.00008, 3.2, 2.12, 65.57659])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series))

    def test_80_is_not_numeric_nan_values(self,col_info = col_info):
        """(80) Test series with nan eg: 2, 4, 8, NAN'"""
        msgt(self.test_80_is_not_numeric_nan_values.__doc__)
        msg('Test a numeric series with NAN')
        series = pd.Series([2.5, 3.4, 7.00008, np.nan, 2.12, 65.57659])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series))

    def test_90_is_not_numeric_all_nan_values(self,col_info = col_info):
        """(90) Test series with nan eg: NAN,NAN, NAN'"""
        msgt(self.test_90_is_not_numeric_all_nan_values.__doc__)
        msg('Test a numeric series with all NAN')
        msg('Should be sent as a character i.e return True')
        series = pd.Series([np.nan, np.nan, np.nan])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series) is False)

    def test_100_is_not_numeric_empty_strings(self,col_info = col_info):
        """(100) Test series with nan eg: 2,3.0,"",5'"""
        msgt(self.test_100_is_not_numeric_empty_strings.__doc__)
        msg('Test a numeric series with empty strings')
        msg('Should be sent as a character i.e return True')

        series = pd.Series([3, 4.9, "", 23])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series) is False)

    def test_110_is_not_numeric_all_characters(self,col_info = col_info):
        """(110) Test series with string eg: 'price','Red'"""
        msgt(self.test_110_is_not_numeric_all_characters.__doc__)
        msg('Test a numeric series with strings')
        msg('Should be sent as a character i.e return True')

        series = pd.Series(['Red', 'Blue'])
        self.assertTrue(TypeGuessUtil.is_not_numeric(series))

    def test_120_is_not_numeric_boolean(self,col_info = col_info):
        """(120) Test the is_not_numeric with logical Series"""
        msgt(self.test_120_is_not_numeric_boolean.__doc__)

        msg('Test with a logical series')
        series = pd.Series([True, False, True, True])
        self.assertTrue(TypeGuessUtil.is_not_numeric(series))

    def test_130_is_not_numeric_boolean_nan(self,col_info = col_info):
        """(130) Test the is_not_numeric with nan"""
        msgt(self.test_130_is_not_numeric_boolean_nan.__doc__)

        msg('Test with a logical series with nan')
        series = pd.Series([True, False, np.nan, True, True, np.nan, False])
        self.assertTrue(TypeGuessUtil.is_not_numeric(series))

    def test_140_is_logical_all_nan(self,col_info = col_info):
        """(140) Test the is_logical with nan"""
        msgt(self.test_140_is_logical_all_nan.__doc__)

        msg('Test a logical series with nan')
        series = pd.Series([np.nan, np.nan, np.nan])
        self.assertFalse(TypeGuessUtil.is_logical(series))

    def test_150_nature_check_condition_1(self,col_info = col_info):
        """(150) Test the nature check condition 1 : if series(continuous) is between 0 and 1"""
        msgt(self.test_150_nature_check_condition_1.__doc__)
        msg('Test a (0,1) series')
        series = pd.Series([0.2, 0.6, 0.7, 0.3, 0.3, 1])
        self.assertEqual(TypeGuessUtil.check_nature(series, True),
                         col_const.NATURE_PERCENT)

    def test_160_nature_check_condition_2(self,col_info = col_info):
        """(160) check condition 2 : if series(continuous) is between 0 and 100 and min < 15 and max > 85"""
        msgt(self.test_160_nature_check_condition_2.__doc__)
        msg('Test a int (0,100) series')
        series = pd.Series([1, 23, 12, 34, 99])
        self.assertEqual(TypeGuessUtil.check_nature(series, True),
                         col_const.NATURE_PERCENT)

    def test_170_nature_check_condition_3(self,col_info = col_info):
        """(170) check condition 3 : if series(continuous) is between not  0 and 100 and min !< 15 and max !> 85"""
        msgt(self.test_170_nature_check_condition_3.__doc__)
        msg('Test a int any series')
        series = pd.Series([0.1, 223, 12, 34, 99])
        self.assertEqual(TypeGuessUtil.check_nature(series, True),
                         col_const.NATURE_RATIO)

    def test_180_nature_check_condition_4(self,col_info = col_info):
        """(180) check condition 4 : if series(continuous) is between not  0 and 100 and min !< 15 and max !> 85"""
        msgt(self.test_180_nature_check_condition_4.__doc__)
        msg('Test a int discreet series')
        series = pd.Series([0.1, 223, 12, 34, 99, None])
        self.assertEqual(TypeGuessUtil.check_nature(series, False),
                         col_const.NATURE_ORDINAL)


    # The code below is not needed as the test case for valid and invalid is in test_summary_stats.py
    # def setUp(self,col_info = col_info):
    #     """Load up the test file"""
    #     self.df_01 = pd.read_csv(join(INPUT_DIR, 'test_file_01.csv'))
    #     type_guess_obj = TypeGuessUtil(self.df_01,col_info = col_info)
    #     self.variable_info_01 = type_guess_obj.get_variable_dict()
    #
    # def test_190_valid_check(self,col_info = col_info):
    #     """(190) Test the data for numeric series"""
    #     msgt(self.test_190_valid_check.__doc__)
    #
    #     # Pull the ColumnInfo for Ranking
    #     col_info = self.variable_info_01.get('UN')
    #
    #     # Calculate the stats
    #     TypeGuessUtil(self.df_01,col_info = col_info)
    #     dashes()
    #     # Check valid and invalid data
    #     msg('Check valid and invalid ')
    #     self.assertEqual(col_info.valid, 8)
    #     self.assertEqual(col_info.invalid, 4)

if __name__ == '__main__':
    unittest.main()

"""Unit testing module for Type guess"""
import unittest

from os.path import abspath, dirname, join
from io import StringIO

import pandas as pd
import numpy as np


PREPROCESS_DIR = dirname(dirname(dirname(abspath(__file__))))
INPUT_DIR = join(PREPROCESS_DIR, 'input')

from raven_preprocess.msg_util import msg, msgt, dashes
from raven_preprocess.type_guess_util import TypeGuessUtil
import raven_preprocess.col_info_constants as col_const



class TestTypeGuess(unittest.TestCase):
    """Unit testing class for type_guess_util"""
    col_info = {}

    def test_10_is_logical(self, col_info=col_info):
        """(10) Test the is_logical with logical Series"""
        msgt(self.test_10_is_logical.__doc__)

        msg('Test a logical series')
        series = pd.Series([True, False, True, True])
        self.assertTrue(TypeGuessUtil.is_logical(series))

        msg('Test a logical series that includes Nan and None')
        series = pd.Series([True, False, True, True, np.nan, None])
        self.assertTrue(TypeGuessUtil.is_logical(series))

    def test_20_is_logical_empty_string(self,col_info = col_info):
        """(20) Test series with empty string, expect not logical"""
        msgt(self.test_20_is_logical_empty_string.__doc__)

        series = pd.Series([True, False, True, True, ""])

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

    def test_30_is_logical_empty_list(self,col_info = col_info):
        """(30) Test empty series, expect not logical"""
        msgt(self.test_30_is_logical_empty_list.__doc__)

        series = pd.Series([])

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

    def test_40_series_with_string_booleans(self,col_info = col_info):
        """(40) Test series with 'TRUE', 'FALSE'"""
        msgt(self.test_40_series_with_string_booleans.__doc__)

        test_data = StringIO(('col1\n'
                              'TRUE\n'
                              'FALSE\n'
                              'TRUE\n'
                              'FALSE'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series))

        test_data = StringIO(('col1\n'
                              'TRUE\n'
                              '\n'
                              'FALSE\n'
                              'TRUE\n'
                              'FALSE'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series))

    def test_50_series_with_string_not_boolean(self,col_info = col_info):
        """(50) Test series with string 'Red', 'Blue'"""
        msgt(self.test_50_series_with_string_not_boolean.__doc__)

        test_data = StringIO(('col1\n'
                              'Red\n'
                              'Blue\n'
                              'Green\n'
                              'Purple'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

        test_data = StringIO(('col1\n'
                              'Red\n'
                              '\n'
                              'Blue\n'
                              'Green\n'
                              'Purple'))

        data_frame = pd.read_csv(test_data)
        series = data_frame['col1']

        self.assertTrue(TypeGuessUtil.is_logical(series) is False)

    """ Test cases for is_not_numeric function"""

    def test_60_is_not_numeric(self,col_info = col_info):
        """(60) Test series with int eg: 2, 4, 8'"""
        msgt(self.test_60_is_not_numeric.__doc__)
        msg('Test a int series')
        series = pd.Series([2, 6, 7, 3, 2, 65])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series))

    def test_70_is_not_numeric(self,col_info = col_info):
        """(70) Test series with float eg: 2, 4, 8'"""
        msgt(self.test_70_is_not_numeric.__doc__)
        msg('Test a float series')
        series = pd.Series([2.5, 3.4, 7.00008, 3.2, 2.12, 65.57659])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series))

    def test_80_is_not_numeric_nan_values(self,col_info = col_info):
        """(80) Test series with nan eg: 2, 4, 8, NAN'"""
        msgt(self.test_80_is_not_numeric_nan_values.__doc__)
        msg('Test a numeric series with NAN')
        series = pd.Series([2.5, 3.4, 7.00008, np.nan, 2.12, 65.57659])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series))

    def test_90_is_not_numeric_all_nan_values(self,col_info = col_info):
        """(90) Test series with nan eg: NAN,NAN, NAN'"""
        msgt(self.test_90_is_not_numeric_all_nan_values.__doc__)
        msg('Test a numeric series with all NAN')
        msg('Should be sent as a character i.e return True')
        series = pd.Series([np.nan, np.nan, np.nan])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series) is False)

    def test_100_is_not_numeric_empty_strings(self,col_info = col_info):
        """(100) Test series with nan eg: 2,3.0,"",5'"""
        msgt(self.test_100_is_not_numeric_empty_strings.__doc__)
        msg('Test a numeric series with empty strings')
        msg('Should be sent as a character i.e return True')

        series = pd.Series([3, 4.9, "", 23])
        self.assertFalse(TypeGuessUtil.is_not_numeric(series) is False)

    def test_110_is_not_numeric_all_characters(self,col_info = col_info):
        """(110) Test series with string eg: 'price','Red'"""
        msgt(self.test_110_is_not_numeric_all_characters.__doc__)
        msg('Test a numeric series with strings')
        msg('Should be sent as a character i.e return True')

        series = pd.Series(['Red', 'Blue'])
        self.assertTrue(TypeGuessUtil.is_not_numeric(series))

    def test_120_is_not_numeric_boolean(self,col_info = col_info):
        """(120) Test the is_not_numeric with logical Series"""
        msgt(self.test_120_is_not_numeric_boolean.__doc__)

        msg('Test with a logical series')
        series = pd.Series([True, False, True, True])
        self.assertTrue(TypeGuessUtil.is_not_numeric(series))

    def test_130_is_not_numeric_boolean_nan(self,col_info = col_info):
        """(130) Test the is_not_numeric with nan"""
        msgt(self.test_130_is_not_numeric_boolean_nan.__doc__)

        msg('Test with a logical series with nan')
        series = pd.Series([True, False, np.nan, True, True, np.nan, False])
        self.assertTrue(TypeGuessUtil.is_not_numeric(series))

    def test_140_is_logical_all_nan(self,col_info = col_info):
        """(140) Test the is_logical with nan"""
        msgt(self.test_140_is_logical_all_nan.__doc__)

        msg('Test a logical series with nan')
        series = pd.Series([np.nan, np.nan, np.nan])
        self.assertFalse(TypeGuessUtil.is_logical(series))

    def test_150_nature_check_condition_1(self,col_info = col_info):
        """(150) Test the nature check condition 1 : if series(continuous) is between 0 and 1"""
        msgt(self.test_150_nature_check_condition_1.__doc__)
        msg('Test a (0,1) series')
        series = pd.Series([0.2, 0.6, 0.7, 0.3, 0.3, 1])
        self.assertEqual(TypeGuessUtil.check_nature(series, True),
                         col_const.NATURE_PERCENT)

    def test_160_nature_check_condition_2(self,col_info = col_info):
        """(160) check condition 2 : if series(continuous) is between 0 and 100 and min < 15 and max > 85"""
        msgt(self.test_160_nature_check_condition_2.__doc__)
        msg('Test a int (0,100) series')
        series = pd.Series([1, 23, 12, 34, 99])
        self.assertEqual(TypeGuessUtil.check_nature(series, True),
                         col_const.NATURE_PERCENT)

    def test_170_nature_check_condition_3(self,col_info = col_info):
        """(170) check condition 3 : if series(continuous) is between not  0 and 100 and min !< 15 and max !> 85"""
        msgt(self.test_170_nature_check_condition_3.__doc__)
        msg('Test a int any series')
        series = pd.Series([0.1, 223, 12, 34, 99])
        self.assertEqual(TypeGuessUtil.check_nature(series, True),
                         col_const.NATURE_RATIO)

    def test_180_nature_check_condition_4(self,col_info = col_info):
        """(180) check condition 4 : if series(continuous) is between not  0 and 100 and min !< 15 and max !> 85"""
        msgt(self.test_180_nature_check_condition_4.__doc__)
        msg('Test a int discreet series')
        series = pd.Series([0.1, 223, 12, 34, 99, None])
        self.assertEqual(TypeGuessUtil.check_nature(series, False),
                         col_const.NATURE_ORDINAL)


    # The code below is not needed as the test case for valid and invalid is in test_summary_stats.py
    # def setUp(self,col_info = col_info):
    #     """Load up the test file"""
    #     self.df_01 = pd.read_csv(join(INPUT_DIR, 'test_file_01.csv'))
    #     type_guess_obj = TypeGuessUtil(self.df_01,col_info = col_info)
    #     self.variable_info_01 = type_guess_obj.get_variable_dict()
    #
    # def test_190_valid_check(self,col_info = col_info):
    #     """(190) Test the data for numeric series"""
    #     msgt(self.test_190_valid_check.__doc__)
    #
    #     # Pull the ColumnInfo for Ranking
    #     col_info = self.variable_info_01.get('UN')
    #
    #     # Calculate the stats
    #     TypeGuessUtil(self.df_01,col_info = col_info)
    #     dashes()
    #     # Check valid and invalid data
    #     msg('Check valid and invalid ')
    #     self.assertEqual(col_info.valid, 8)
    #     self.assertEqual(col_info.invalid, 4)

if __name__ == '__main__':
    unittest.main()

Unit testing module for Type guess Unit testing class for type_guess_util (10) Test the is_logical with logical Series (20) Test series with empty string, expect not logical (30) Test empty series, expect not logical (40) Test series with 'TRUE', 'FALSE' (50) Test series with string 'Red', 'Blue' Test cases for is_not_numeric function (60) Test series with int eg: 2, 4, 8' (70) Test series with float eg: 2, 4, 8' (80) Test series with nan eg: 2, 4, 8, NAN' (90) Test series with nan eg: NAN,NAN, NAN' (100) Test series with nan eg: 2,3.0,"",5' (110) Test series with string eg: 'price','Red' (120) Test the is_not_numeric with logical Series (130) Test the is_not_numeric with nan (140) Test the is_logical with nan (150) Test the nature check condition 1 : if series(continuous) is between 0 and 1 (160) check condition 2 : if series(continuous) is between 0 and 100 and min < 15 and max > 85 (170) check condition 3 : if series(continuous) is between not  0 and 100 and min !< 15 and max !> 85 (180) check condition 4 : if series(continuous) is between not  0 and 100 and min !< 15 and max !> 85 # The code below is not needed as the test case for valid and invalid is in test_summary_stats.py # def setUp(self,col_info = col_info): #     """Load up the test file""" #     self.df_01 = pd.read_csv(join(INPUT_DIR, 'test_file_01.csv')) #     type_guess_obj = TypeGuessUtil(self.df_01,col_info = col_info) #     self.variable_info_01 = type_guess_obj.get_variable_dict() # # def test_190_valid_check(self,col_info = col_info): #     """(190) Test the data for numeric series""" #     msgt(self.test_190_valid_check.__doc__) # #     # Pull the ColumnInfo for Ranking #     col_info = self.variable_info_01.get('UN') # #     # Calculate the stats #     TypeGuessUtil(self.df_01,col_info = col_info) #     dashes() #     # Check valid and invalid data #     msg('Check valid and invalid ') #     self.assertEqual(col_info.valid, 8) #     self.assertEqual(col_info.invalid, 4)