import unittest
from contract import *


def person(score=.5,tid=1,q=0):
    return dict(score=score,track_id=tid,query=q,bbox=[1.,1.,40.,80.],keypoints=[[10.,20.,.3] for _ in range(17)])


class Contract(unittest.TestCase):
    def test_bbox_boundaries(self):
        for v,s in [(.5,'HIGH'),(.499999,'LOW'),(.25,'LOW'),(.249999,'BELOW')]:self.assertEqual(person_state(person(v),100,100),s)
    def test_joint_boundaries(self):
        for v,s in [(.3,'HIGH'),(.299999,'LOW'),(.05,'LOW'),(.049999,'BELOW')]:self.assertEqual(joint_state([1,2,v],100,100),s)
    def test_invalid_distinct(self):
        for p in [None,[float('nan'),0,.5],[-1,0,.5],[0,101,.8],[1,2,2]]:self.assertEqual(joint_state(p,100,100),'INVALID')
        self.assertEqual(joint_state([0,0,0],100,100),'BELOW')
    def test_edges(self):
        self.assertEqual(edge_state('HIGH','HIGH'),'HIGH');self.assertEqual(edge_state('HIGH','LOW'),'LOW')
        self.assertIsNone(edge_state('HIGH','BELOW'));self.assertIsNone(edge_state('INVALID','LOW'))
    def test_no_min_joints(self):
        p=person();p['keypoints']=[[1,2,.01]]*17
        r=dict(sample=0,width=100,height=100,persons=[p]);d=observation(r,palette([r]))[0]
        self.assertTrue(d['visible']);self.assertEqual(d['counts']['BELOW'],17)
    def test_first_three_raw_order(self):
        r=dict(sample=0,width=100,height=100,persons=[person(.3,4,0),person(.1,8,1),person(.9,3,2),person(.7,None,3),person(.99,1,4)])
        d=observation(r,palette([r]));v=[p for p in d if p['visible']]
        self.assertEqual([p['identity'] for p in v],['T4','T3','q3','T1'])
        self.assertEqual([p['detail_slot'] for p in v],[1,2,3,None])
    def test_identity_color(self):
        r=dict(sample=0,width=100,height=100,persons=[person(tid=i,q=i) for i in range(1,41)]+[person(tid=None,q=50)])
        c=palette([r]);a=observation(r,c);r['sample']=1;b=observation(r,c)
        self.assertEqual(a[0]['identity_color'],b[0]['identity_color']);self.assertNotEqual(a[-1]['identity_color'],b[-1]['identity_color'])
        self.assertEqual(len(set(c.values())),40)
    def test_raw_unchanged_and_no_rounding(self):
        import copy
        r=dict(sample=0,width=100,height=100,persons=[person(.24999999)]);old=copy.deepcopy(r)
        self.assertFalse(observation(r,palette([r]))[0]['visible']);self.assertEqual(r,old)


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