package org.westmalle.wayland.protocol;

import org.freedesktop.wayland.server.Client;
import org.freedesktop.wayland.server.Resource;
import org.freedesktop.wayland.server.jna.WaylandServerLibrary;
import org.freedesktop.wayland.server.jna.WaylandServerLibraryMapping;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.Optional;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest(WaylandServerLibrary.class)
public class ProtocolObjectTest {

    @Mock
    private WaylandServerLibraryMapping waylandServerLibraryMapping;

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(WaylandServerLibrary.class);
        when(WaylandServerLibrary.INSTANCE()).thenReturn(this.waylandServerLibraryMapping);
    }

    @Test
    public void testGetResourceSingleResource() throws Exception {
        //given
        final Client client = mock(Client.class);
        //when
        final ProtocolObject<Resource<?>> protocolObject = new ProtocolObjectDummy();
        final Resource<?> resource = protocolObject.add(client,
                                                        1,
                                                        1);
        //then
        assertThat(protocolObject.getResource()).isEqualTo(Optional.of(resource));
    }

    @Test
    public void testGetResourceNoResource() throws Exception {
        //given
        //when
        //then
        final ProtocolObject<Resource<?>> protocolObject = new ProtocolObjectDummy();
        assertThat(protocolObject.getResource()).isEqualTo(Optional.empty());
    }

    @Test(expected = IllegalStateException.class)
    public void testGetResourceMultipleResourceResource() throws Exception {
        //given
        final Client                      client         = mock(Client.class);
        final ProtocolObject<Resource<?>> protocolObject = new ProtocolObjectDummy();
        protocolObject.add(client,
                           1,
                           1);
        protocolObject.add(client,
                           1,
                           2);
        //when
        protocolObject.getResource();
        //then
    }

    @Test
    public void testAddNone() throws Exception {
        //given
        final ProtocolObject<Resource<?>> protocolObject = new ProtocolObjectDummy();
        //when
        //then
        assertThat((Iterable) protocolObject.getResources()).isEmpty();
    }

    @Test
    public void testAddSingle() throws Exception {
        //given
        final Client                      client         = mock(Client.class);
        final ProtocolObject<Resource<?>> protocolObject = new ProtocolObjectDummy();
        //when
        final Resource<?> resource = protocolObject.add(client,
                                                        1,
                                                        1);
        //then
        assertThat((Iterable) protocolObject.getResources()).contains(resource);
        assertThat((Iterable) protocolObject.getResources()).hasSize(1);
    }

    @Test
    public void testAddMultiple() throws Exception {
        //given
        final Client                      client         = mock(Client.class);
        final ProtocolObject<Resource<?>> protocolObject = new ProtocolObjectDummy();
        //when
        final Resource<?> resource0 = protocolObject.add(client,
                                                         1,
                                                         1);
        final Resource<?> resource1 = protocolObject.add(client,
                                                         1,
                                                         2);
        final Resource<?> resource2 = protocolObject.add(client,
                                                         1,
                                                         3);
        //then
        assertThat((Iterable) protocolObject.getResources()).contains(resource0);
        assertThat((Iterable) protocolObject.getResources()).contains(resource1);
        assertThat((Iterable) protocolObject.getResources()).contains(resource2);
        assertThat((Iterable) protocolObject.getResources()).hasSize(3);
    }
}
@@ -80,16 +80,64 @@
 Client;%0A
+import org.freedesktop.wayland.server.Listener;%0A
 import o
@@ -392,16 +392,51 @@
 unWith;%0A
+import org.mockito.ArgumentCaptor;%0A
 import o
@@ -741,52 +741,9 @@
 ito.
-mock;%0Aimport static org.mockito.Mockito.when
+*
 ;%0A%0A@
@@ -4586,10 +4586,871 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void testDestroyed() %7B%0A        //given%0A        final Client                      client         = mock(Client.class);%0A        final ProtocolObject%3CResource%3C?%3E%3E protocolObject = new ProtocolObjectDummy();%0A        //when%0A        final Resource%3C?%3E resource = protocolObject.add(client,%0A                                                        1,%0A                                                        1);%0A        //then%0A        final ArgumentCaptor%3CListener%3E listenerArgumentCaptor = ArgumentCaptor.forClass(Listener.class);%0A        verify(resource).addDestroyListener(listenerArgumentCaptor.capture());%0A%0A        //and when%0A        final Listener listener = listenerArgumentCaptor.getValue();%0A        listener.handle();%0A%0A        //then%0A        assertThat((Iterable%3CResource%3C?%3E%3E) protocolObject.getResources()).doesNotContain(resource);%0A    %7D
 %0A%7D

add test for bug where resource was not properly cleaned up