import unittest
import sys
from karpathos.gedcom import GEDCOMParser
from karpathos.interface_tests import InterfaceTests
from karpathos.interface import KarpathosError
from StringIO import StringIO

class SimpleTest (unittest.TestCase, InterfaceTests):

    """ Simple tests of our ability to parse a short GEDCOM file involving
    three individuals and one family and to output it back out again """
    
    sample_file = """0 @p1@ INDI
1 NAME Irene Karanikola /(beba)/
1 SEX F
1 FAMS @f0@
0 @p2@ INDI
1 NAME Agapitos /Matsakis/
1 SEX M
1 FAMS @f0@
0 @p3@ INDI
1 NAME Anastasia /Agapitou/
1 SEX F
1 FAMC @f0@
0 @p4@ INDI
1 NAME Eleni /Boopi/
1 SEX F
1 NOTE 4 grandchildren
1 FAMC @f0@
0 @f0@ FAM
1 HUSB @p1@
1 WIFE @p2@
1 NCHI 2
1 CHIL @p3@
1 CHIL @p4@
"""

    def create_database (self):
        parser = GEDCOMParser ()
        return parser.parse (self.sample_file.split('\n'))

    def setUp (self):
        self.database = self.create_database ()
        return

    def testIndividualCount (self):
        self.failUnless (len (self.database.individuals) == 4,
                         'Invalid number of individuals')
        return

    def testFamilyCount (self):
        self.failUnless (len (self.database.families) == 1,
                         'Invalid number of families')
        return

    def testLastNames (self):
        def getind (tag):
            return self.database.get_individual (tag)
        self.failUnless (getind('p2').name.last_name == "Matsakis",
                         'Invalid last name for p2')
        self.failUnless (getind('p3').name.last_name == "Agapitou",
                         'Invalid last name for p3')
        self.failUnless (getind('p4').name.last_name == "Boopi",
                         'Invalid last name for p4')
        return

    def testBadId (self):
        self.assertRaises (KarpathosError,
                           self.database.get_individual,
                           'blah')
        return

    def testDatabaseIds (self):

        """ Tests that each individual and family has a database_id which
        they can be fetched with """

        for ind in self.database.individuals:
            id = ind.database_id
            ind2 = self.database.get_individual (id)
            self.assertEquals (ind, ind2)
            pass

        for fam in self.database.families:
            id = fam.database_id
            fam2 = self.database.get_family (id)
            self.assertEquals (fam, fam2)
            pass

        return

    def testFamilyStructure (self):
        
        """ Tests that the @p3@ and @p4@ are children of @p1@ and @p2@ """

        kid1 = self.database.get_individual ('p3')
        kid2 = self.database.get_individual ('p4')

        # kid1 and kid2 have no children, and 1 set of parents
        self.assertEqual (len(kid1.families), 0)
        self.assertEqual (len(kid2.families), 0)
        self.assertEqual (len(kid1.lineage), 1)
        self.assertEqual (len(kid2.lineage), 1)

        # kid1 and kid2 are in the same family
        self.assertEqual (kid1.lineage[0], kid2.lineage[0])

        family = kid1.lineage[0]

        self.assertEqual (len (family.children), 2)
        self.failUnless (kid1 in family.children, 'p3 not in children')
        self.failUnless (kid1 in family.children, 'p4 not in children')

        par1 = self.database.get_individual ('p1')
        par2 = self.database.get_individual ('p2')

        self.assertEqual (len (family.parents), 2)
        self.failUnless (par1 in family.parents, 'p1 not in parents')
        self.failUnless (par2 in family.parents, 'p2 not in parents')

        return

    def testOutput (self):
        out = StringIO ()
        self.database.output (out)
        out = out.getvalue()
        self.failUnless (out == self.sample_file, "output not identical")
        return

    pass

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