package org.codelibs.fess.suggest.concurrent;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Collections;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.codelibs.fess.suggest.exception.SuggesterException;
import org.codelibs.fess.suggest.request.suggest.SuggestResponse;
import org.junit.Test;

public class DeferredTest {
    @Test
    public void test_doneBeforeResolve() throws Exception {
        final Deferred<SuggestResponse> deferred = new Deferred<>();

        Thread th = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignore) {}
            deferred.resolve(new SuggestResponse(0, Collections.emptyList(), 0, null));
        });
        th.start();

        final CountDownLatch latch = new CountDownLatch(1);
        deferred.promise().done(response -> latch.countDown());
        assertTrue(latch.await(10, TimeUnit.SECONDS));
    }

    @Test
    public void test_doneAfterResolve() throws Exception {
        final Deferred<SuggestResponse> deferred = new Deferred<>();

        Thread th = new Thread(() -> {
            deferred.resolve(new SuggestResponse(0, Collections.emptyList(), 0, null));
        });
        th.start();

        Thread.sleep(1000);
        final CountDownLatch latch = new CountDownLatch(1);
        deferred.promise().done(response -> latch.countDown());
        assertTrue(latch.await(10, TimeUnit.SECONDS));
    }

    @Test
    public void test_getResponseBeforeResolve() throws Exception {
        final Deferred<SuggestResponse> deferred = new Deferred<>();

        Thread th = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignore) {}
            deferred.resolve(new SuggestResponse(0, Collections.emptyList(), 0, null));
        });
        th.start();

        SuggestResponse response = deferred.promise().getResponse(10, TimeUnit.SECONDS);
        assertEquals(0, response.getNum());
    }

    @Test
    public void test_getResponseAfterResolve() throws Exception {
        final Deferred<SuggestResponse> deferred = new Deferred<>();

        Thread th = new Thread(() -> {
            deferred.resolve(new SuggestResponse(0, Collections.emptyList(), 0, null));
        });
        th.start();

        Thread.sleep(1000);
        SuggestResponse response = deferred.promise().getResponse(10, TimeUnit.SECONDS);
        assertEquals(0, response.getNum());
    }

    @Test
    public void test_getResponseWithException() throws Exception {
        final Deferred<SuggestResponse> deferred = new Deferred<>();

        Thread th = new Thread(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ignore) {}
            deferred.reject(new SuggesterException("test"));
        });
        th.start();

        try {
            deferred.promise().getResponse(10, TimeUnit.SECONDS);
            fail();
        } catch (SuggesterException e) {
            assertEquals("org.codelibs.fess.suggest.exception.SuggesterException: test", e.getMessage());
        }
    }

}

@@ -1558,32 +1558,1048 @@
 CONDS));%0A    %7D%0A%0A
+    @Test%0A    public void test_doneBeforeReject() throws Exception %7B%0A        final Deferred%3CSuggestResponse%3E deferred = new Deferred%3C%3E();%0A%0A        Thread th = new Thread(() -%3E %7B%0A            try %7B%0A                Thread.sleep(1000);%0A            %7D catch (InterruptedException ignore) %7B%7D%0A            deferred.reject(new Exception());%0A        %7D);%0A        th.start();%0A%0A        final CountDownLatch latch = new CountDownLatch(1);%0A        deferred.promise().error(error -%3E latch.countDown());%0A        assertTrue(latch.await(10, TimeUnit.SECONDS));%0A    %7D%0A%0A    @Test%0A    public void test_doneAfterReject() throws Exception %7B%0A        final Deferred%3CSuggestResponse%3E deferred = new Deferred%3C%3E();%0A%0A        Thread th = new Thread(() -%3E %7B%0A            deferred.reject(new Exception());%0A        %7D);%0A        th.start();%0A%0A        Thread.sleep(1000);%0A        final CountDownLatch latch = new CountDownLatch(1);%0A        deferred.promise().error(error -%3E latch.countDown());%0A        assertTrue(latch.await(10, TimeUnit.SECONDS));%0A    %7D%0A%0A
     @Test%0A    pu

add testcase