package org.jooby.internal; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import org.jooby.test.MockUnit; import org.jooby.test.MockUnit.Block; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.google.common.io.ByteStreams; @RunWith(PowerMockRunner.class) @PrepareForTest({BodyReferenceImpl.class, ByteStreams.class, FileOutputStream.class, Files.class, File.class, ByteArrayOutputStream.class }) public class BodyReferenceImplTest { private Block mkdir = unit -> { File dir = unit.mock(File.class); expect(dir.mkdirs()).andReturn(true); File file = unit.get(File.class); expect(file.getParentFile()).andReturn(dir); }; private Block fos = unit -> { FileOutputStream fos = unit.constructor(FileOutputStream.class) .build(unit.get(File.class)); unit.registerMock(FileOutputStream.class, fos); }; @Test public void fromBytes() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class) .expect(baos(bytes)) .expect(copy(ByteArrayOutputStream.class)) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize); }); } @Test(expected = IOException.class) public void inErr() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class) .expect(baos(bytes)) .expect(unit -> { InputStream in = unit.get(InputStream.class); expect(in.read(unit.capture(byte[].class))).andThrow(new IOException()); OutputStream out = unit.get(ByteArrayOutputStream.class); in.close(); out.close(); }) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize); }); } @Test(expected = IOException.class) public void outErr() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class) .expect(baos(bytes)) .expect(unit -> { InputStream in = unit.get(InputStream.class); in.close(); OutputStream out = unit.get(ByteArrayOutputStream.class); out.close(); expectLastCall().andThrow(new IOException()); unit.mockStatic(ByteStreams.class); expect(ByteStreams.copy(in, out)).andReturn(1L); }) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize); }); } @Test(expected = IOException.class) public void inErrOnClose() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class) .expect(baos(bytes)) .expect(unit -> { InputStream in = unit.get(InputStream.class); in.close(); expectLastCall().andThrow(new IOException()); OutputStream out = unit.get(ByteArrayOutputStream.class); out.close(); unit.mockStatic(ByteStreams.class); expect(ByteStreams.copy(in, out)).andReturn(1L); }) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize); }); } @Test public void fromFile() throws Exception { long len = 1; long bsize = -1; new MockUnit(File.class, InputStream.class) .expect(mkdir) .expect(fos) .expect(copy(FileOutputStream.class)) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize); }); } @Test public void bytesFromBytes() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class) .expect(baos(bytes)) .expect(copy(ByteArrayOutputStream.class)) .run(unit -> { byte[] rsp = new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize).bytes(); assertArrayEquals(bytes, rsp); }); } @Test public void bytesFromFile() throws Exception { long len = 1; long bsize = -1; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class, Path.class) .expect(mkdir) .expect(fos) .expect(copy(FileOutputStream.class)) .expect(unit -> { expect(unit.get(File.class).toPath()).andReturn(unit.get(Path.class)); unit.mockStatic(Files.class); expect(Files.readAllBytes(unit.get(Path.class))).andReturn(bytes); }) .run(unit -> { byte[] rsp = new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize) .bytes(); assertEquals(bytes, rsp); }); } @Test public void textFromBytes() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class) .expect(baos(bytes)) .expect(copy(ByteArrayOutputStream.class)) .run(unit -> { String rsp = new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize).text(); assertEquals("bytes", rsp); }); } @Test public void textFromFile() throws Exception { long len = 1; long bsize = -1; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class, Path.class) .expect(mkdir) .expect(fos) .expect(copy(FileOutputStream.class)) .expect(unit -> { expect(unit.get(File.class).toPath()).andReturn(unit.get(Path.class)); unit.mockStatic(Files.class); expect(Files.readAllBytes(unit.get(Path.class))).andReturn(bytes); }) .run(unit -> { String rsp = new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize) .text(); assertEquals("bytes", rsp); }); } @Test public void writeToFromFile() throws Exception { long len = 1; long bsize = -1; new MockUnit(File.class, InputStream.class, Path.class, OutputStream.class) .expect(mkdir) .expect(fos) .expect(copy(FileOutputStream.class)) .expect(unit -> { expect(unit.get(File.class).toPath()).andReturn(unit.get(Path.class)); unit.mockStatic(Files.class); expect(Files.copy(unit.get(Path.class), unit.get(OutputStream.class))).andReturn(1L); }) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize) .writeTo(unit.get(OutputStream.class)); }); } @Test public void bytesWriteTo() throws Exception { long len = 1; long bsize = 2; byte[] bytes = "bytes".getBytes(); new MockUnit(File.class, InputStream.class, OutputStream.class) .expect(baos(bytes)) .expect(copy(ByteArrayOutputStream.class)) .expect(unit -> { unit.get(OutputStream.class).write(bytes); }) .run(unit -> { new BodyReferenceImpl(len, StandardCharsets.UTF_8, unit.get(File.class), unit.get(InputStream.class), bsize) .writeTo(unit.get(OutputStream.class)); }); } private Block copy(final Class<? extends OutputStream> oclass) { return copy(oclass, true); } private Block copy(final Class<? extends OutputStream> oclass, final boolean close) { return unit -> { InputStream in = unit.get(InputStream.class); OutputStream out = unit.get(oclass); if (close) { in.close(); out.close(); } unit.mockStatic(ByteStreams.class); expect(ByteStreams.copy(in, out)).andReturn(1L); }; } private Block baos(final byte[] bytes) { return unit -> { ByteArrayOutputStream baos = unit.constructor(ByteArrayOutputStream.class) .build(); expect(baos.toByteArray()).andReturn(bytes); unit.registerMock(ByteArrayOutputStream.class, baos); }; } }