package io.github.leovr.rtipmidi;

import io.github.leovr.rtipmidi.error.AppleMidiSessionInstantiationException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.Receiver;
import javax.sound.midi.ShortMessage;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class MidiDeviceAppleMidiSessionTest {

    @Mock
    private MidiDevice midiDevice;
    @Mock
    private Receiver receiver;

    @Rule
    public ExpectedException exception = ExpectedException.none();
    private MidiDeviceAppleMidiSession session;

    @Before
    public void setUp() throws Exception {
        given(midiDevice.isOpen()).willReturn(false);
        given(midiDevice.getMaxReceivers()).willReturn(-1);
        given(midiDevice.getReceiver()).willReturn(receiver);

        session = new MidiDeviceAppleMidiSession(midiDevice);
    }

    @Test
    public void testInstatniationAlreadyOpen() throws Exception {
        exception.expect(AppleMidiSessionInstantiationException.class);

        given(midiDevice.isOpen()).willReturn(true);

        new MidiDeviceAppleMidiSession(midiDevice);

        verify(midiDevice).isOpen();
    }

    @Test
    public void testNoMaxReceivers() throws Exception {
        exception.expect(AppleMidiSessionInstantiationException.class);
        given(midiDevice.getMaxReceivers()).willReturn(0);

        new MidiDeviceAppleMidiSession(midiDevice);
        verify(midiDevice).isOpen();
        verify(midiDevice).getMaxReceivers();
    }

    @Test
    public void testOpenError() throws Exception {
        exception.expect(AppleMidiSessionInstantiationException.class);
        willThrow(new MidiUnavailableException()).given(midiDevice).open();

        new MidiDeviceAppleMidiSession(midiDevice);
        verify(midiDevice).isOpen();
        verify(midiDevice).getMaxReceivers();
        verify(midiDevice).open();
    }

    @Test
    public void testGetReceiverError() throws Exception {
        exception.expect(AppleMidiSessionInstantiationException.class);
        willThrow(new MidiUnavailableException()).given(midiDevice).getReceiver();

        new MidiDeviceAppleMidiSession(midiDevice);
        verify(midiDevice).isOpen();
        verify(midiDevice).getMaxReceivers();
        verify(midiDevice).open();
        verify(midiDevice).getReceiver();
    }

    @Test
    public void testNormalInstantiation() throws Exception {
        new MidiDeviceAppleMidiSession(midiDevice);
        verify(midiDevice).isOpen();
        verify(midiDevice).getMaxReceivers();
        verify(midiDevice).open();
        verify(midiDevice).getReceiver();
    }

    @Test
    public void testGetMicroseconds() throws Exception {
        given(midiDevice.getMicrosecondPosition()).willReturn(133L);

        assertThat(session.getCurrentTimestampIn100Microseconds()).isEqualTo(13300L);
    }

    @Test
    public void testCloseMidiDevice() throws Exception {
        session.onEndSession();

        verify(midiDevice).close();
    }

    @Test
    public void sendMidiMessage() throws Exception {
        final ShortMessage message = new ShortMessage();
        final long timestamp = 5L;
        session.onMidiMessage(message, timestamp);

        verify(receiver).send(message, timestamp);
    }
}

@@ -924,56 +924,8 @@
 e();
-%0A    private MidiDeviceAppleMidiSession session;
 %0A%0A  
@@ -1156,71 +1156,8 @@
 er);
-%0A%0A        session = new MidiDeviceAppleMidiSession(midiDevice);
 %0A   
@@ -1308,17 +1308,16 @@
 class);%0A
-%0A
         
@@ -1701,32 +1701,33 @@
 on(midiDevice);%0A
+%0A
         verify(m
@@ -2054,32 +2054,33 @@
 on(midiDevice);%0A
+%0A
         verify(m
@@ -2456,32 +2456,33 @@
 on(midiDevice);%0A
+%0A
         verify(m
@@ -2751,24 +2751,25 @@
 idiDevice);%0A
+%0A
         veri
@@ -3056,24 +3056,120 @@
 urn(133L);%0A%0A
+        final MidiDeviceAppleMidiSession session = new MidiDeviceAppleMidiSession(midiDevice);%0A%0A
         asse
@@ -3308,32 +3308,128 @@
 ows Exception %7B%0A
+        final MidiDeviceAppleMidiSession session = new MidiDeviceAppleMidiSession(midiDevice);%0A%0A
         session.
@@ -3604,24 +3604,24 @@
 tMessage();%0A
-
         fina
@@ -3642,16 +3642,112 @@
 mp = 5L;
+%0A%0A        final MidiDeviceAppleMidiSession session = new MidiDeviceAppleMidiSession(midiDevice);
 %0A       

Fix MidiDeviceAppleMidiSessionTest