import unittest
from receiver import Receiver
class FakeOutputs:
    enabled=False
    def __init__(self):self.frames=[]
    def write(self,*frame):self.frames.append(frame)
class Tests(unittest.TestCase):
    def setUp(self):
        self.now=100.;self.out=FakeOutputs();self.r=Receiver(self.out,lambda:self.now);self.s=self.r.pair()['session'];self.seq=0
    def frame(self,**kw):
        self.seq+=1;f=dict(session=self.s,seq=self.seq,profile='car',armed=True,deadman=False,throttle=0,yaw=0,pitch=0,roll=0);f.update(kw);return f
    def test_neutral_arm_and_drive(self):
        self.r.command(self.frame());self.r.command(self.frame(deadman=True,throttle=.2,roll=.1));self.assertEqual(self.out.frames[-1],(True,.2,.1))
    def test_deadman_release(self):
        self.r.command(self.frame());self.r.command(self.frame(throttle=.5));self.assertEqual(self.out.frames[-1],(False,0,0))
    def test_watchdog_and_neutral_rearm(self):
        self.r.command(self.frame());self.r.command(self.frame(deadman=True,throttle=.5));self.now+=.501;self.r.tick();self.assertFalse(self.r.armed);self.assertEqual(self.out.frames[-1],(False,0,0))
        with self.assertRaises(ValueError):self.r.command(self.frame(deadman=True,throttle=.5))
    def test_reject_aircraft(self):
        for p in ['plane','drone','fpv','heli','tricopter']:
            with self.assertRaises(ValueError):self.r.command(self.frame(profile=p))
            self.assertFalse(self.r.armed)
    def test_invalid_and_nonfinite(self):
        for value in [float('nan'),float('inf'),-0.1,2,'1',True]:
            with self.assertRaises(ValueError):self.r.command(self.frame(throttle=value))
    def test_replay(self):
        f=self.frame();self.r.command(f)
        with self.assertRaises(ValueError):self.r.command(f)
    def test_wrong_session(self):
        with self.assertRaises(ValueError):self.r.command(self.frame(session='wrong'))
    def test_pairing_busy_and_old_session(self):
        with self.assertRaises(ValueError):self.r.pair()
        self.now+=1.1;self.r.pair()
        with self.assertRaises(ValueError):self.r.command(self.frame())
    def test_no_non_neutral_initial_arm(self):
        with self.assertRaises(ValueError):self.r.command(self.frame(deadman=True,roll=.2))
if __name__=='__main__':unittest.main()
