package net.yeputons.spbau.spring2016.torrent.protocol;

import org.junit.Test;

import java.io.*;

import static org.junit.Assert.*;

public abstract class RequestTest<T> {
    protected abstract Request<T> getRequest();
    protected abstract T getAnswer();
    protected abstract byte[] getSerializedRequest();
    protected abstract byte[] getSerializedAnswer();

    @Test
    public void testAnswerTo() throws IOException {
        Request<T> r = getRequest();
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            try (DataOutputStream dataOut = new DataOutputStream(out)) {
                r.answerTo(dataOut, getAnswer());
            }
            assertArrayEquals(getSerializedAnswer(), out.toByteArray());
        }
    }

    @Test
    public void testReadFrom() throws IOException {
        try (ByteArrayInputStream in = new ByteArrayInputStream(getSerializedRequest())) {
            Request<T> request = getRequest();
            if (request instanceof ServerRequest) {
                assertEquals(request, ServerRequest.readRequest(new DataInputStream(in)));
            } else  if (request instanceof ClientRequest) {
                assertEquals(request, ClientRequest.readRequest(new DataInputStream(in)));
            } else {
                throw new AssertionError("request is neither ServerRequest nor ClientRequest");
            }
        }
    }

    @Test
    public void testMakeRequest() throws IOException {
        try (ByteArrayInputStream in = new ByteArrayInputStream(getSerializedAnswer());
             ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            try (DataOutputStream dataOut = new DataOutputStream(out)) {
                assertEquals(getAnswer(), getRequest().makeRequest(new DataInputStream(in), dataOut));
            }
            assertArrayEquals(getSerializedRequest(), out.toByteArray());
        }
    }
}

@@ -924,28 +924,169 @@
         
-Request%3CT%3E r
+assertEquals(getRequest(), readRequest(in));%0A        %7D%0A    %7D%0A%0A    @Test%0A    public void testReadFromEof() throws IOException %7B%0A        byte%5B%5D serializedR
 equest =
@@ -1085,24 +1085,34 @@
 equest = get
+Serialized
 Request();%0A 
@@ -1122,51 +1122,415 @@
     
-    if (request instanceof ServerRequest) %7B
+if (serializedRequest.length %3E 1) %7B%0A            try (ByteArrayInputStream in = new ByteArrayInputStream(%0A                    serializedRequest, 0, serializedRequest.length - 1)) %7B%0A                readRequest(in);%0A                throw new AssertionError(%22Expected EOFException to be thrown%22);%0A            %7D catch (EOFException e) %7B%0A                assertFalse(e instanceof NoRequestException);%0A            %7D
 %0A   
@@ -1538,37 +1538,194 @@
     
+%7D%0A
     
+%7D%0A%0A
     
-assertEquals(request,
+private Object readRequest(InputStream in) throws IOException %7B%0A        Request%3CT%3E request = getRequest();%0A        if (request instanceof ServerRequest) %7B%0A            return
  Ser
@@ -1763,39 +1763,34 @@
 InputStream(in))
-)
 ;%0A
-    
         %7D else  
@@ -1845,33 +1845,14 @@
     
-    assertEquals(request,
+return
  Cli
@@ -1898,23 +1898,18 @@
 eam(in))
-)
 ;%0A
-    
         
@@ -1917,20 +1917,16 @@
  else %7B%0A
-    
         
@@ -2009,30 +2009,16 @@
 uest%22);%0A
-            %7D%0A
         

make it test that EOFException (not NoRequestException) is thrown when request cannot be read to the end