package io.reactivex.netty.util;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.ReferenceCountUtil;
import io.reactivex.netty.util.CollectBytes.TooMuchDataException;
import org.junit.Assert;
import org.junit.Test;
import rx.Observable;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.observers.TestSubscriber;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CollectBytesTest {
@Test
public void testCollectOverEmptyObservable() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
Observable.<ByteBuf>empty()
.compose(CollectBytes.all())
.subscribe(t);
t.assertNoErrors();
t.assertCompleted();
t.assertValue(Unpooled.buffer());
}
@Test
public void testCollectSingleEvent() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
Observable.just(getByteBuf("test"))
.compose(CollectBytes.all())
.subscribe(t);
t.assertNoErrors();
t.assertCompleted();
t.assertValues(getByteBuf("test"));
}
@Test
public void testCollectManyEvents() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
Observable.just(
getByteBuf("t"),
getByteBuf("e"),
getByteBuf("s"),
getByteBuf("t")
)
.compose(CollectBytes.all())
.subscribe(t);
t.assertNoErrors();
t.assertCompleted();
t.assertValues(getByteBuf("test"));
}
@Test
public void testWithLimitEqualToBytes() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
Observable.just(
getByteBuf("t"),
getByteBuf("e"),
getByteBuf("s"),
getByteBuf("t")
)
.compose(CollectBytes.upTo(4))
.subscribe(t);
t.assertNoErrors();
t.assertCompleted();
t.assertValues(getByteBuf("test"));
}
@Test
public void testWithLimitGreaterThanBytes() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
Observable.just(
getByteBuf("t"),
getByteBuf("e"),
getByteBuf("s"),
getByteBuf("t")
)
.compose(CollectBytes.upTo(5))
.subscribe(t);
t.assertNoErrors();
t.assertCompleted();
t.assertValues(getByteBuf("test"));
}
@Test
public void testCollectWithLimitSmallerThanBytes() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
Observable.just(
getByteBuf("t"),
getByteBuf("e"),
getByteBuf("s"),
getByteBuf("t")
)
.compose(CollectBytes.upTo(2))
.subscribe(t);
t.assertError(TooMuchDataException.class);
t.assertNotCompleted();
t.assertNoValues();
}
@Test
public void testReturnSingleEventWithMoreBytesThanMax() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
toByteBufObservable("test")
.compose(CollectBytes.upTo(0))
.subscribe(t);
t.assertError(TooMuchDataException.class);
t.assertNotCompleted();
t.assertNoValues();
}
@Test
public void testReturnMultipleEvents() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
toByteBufObservable("1", "2")
.compose(CollectBytes.upTo(5))
.subscribe(t);
t.assertNoErrors();
t.assertCompleted();
t.assertValues(getByteBufs("12"));
}
@Test
public void testReturnEventsOnLimitBoundary() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
toByteBufObservable("12", "34", "56")
.compose(CollectBytes.upTo(4))
.subscribe(t);
t.assertError(TooMuchDataException.class);
t.assertNotCompleted();
t.assertNoValues();
}
@Test
public void testReturnMultipleEventsEndingWhenOverMaxBytes() throws Exception {
TestSubscriber<ByteBuf> t = new TestSubscriber<>();
toByteBufObservable("first", "second", "third")
.compose(CollectBytes.upTo(7))
.subscribe(t);
t.assertError(TooMuchDataException.class);
t.assertNotCompleted();
t.assertNoValues();
}
@Test
public void testUnsubscribeFromUpstream() throws Exception {
final List<String> emittedBufs = new ArrayList<>();
toByteBufObservable("first", "second", "third")
.doOnNext(new Action1<ByteBuf>() {
@Override
public void call(ByteBuf byteBuf) {
emittedBufs.add(byteBuf.toString(Charset.defaultCharset()));
}
})
.compose(CollectBytes.upTo(7))
.subscribe(new TestSubscriber<>());
Assert.assertEquals(Arrays.asList("first", "second"), emittedBufs);
}
@Test(expected = IllegalArgumentException.class)
public void testExceptionOnNegativeMaxBytes() throws Exception {
CollectBytes.upTo(-1);
}
private Observable<ByteBuf> toByteBufObservable(String... values) {
return Observable.from(values)
.map(new Func1<String, ByteBuf>() {
@Override
public ByteBuf call(String s) {
return getByteBuf(s);
}
});
}
private ByteBuf getBytes(int length, int value) {
ByteBuf buffer = Unpooled.buffer(length, length);
for (int i = 0; i < length; ++i) {
buffer.writeByte(value);
}
return buffer;
}
private ByteBuf getByteBuf(String s) {
return ReferenceCountUtil.releaseLater(Unpooled.copiedBuffer(s, Charset.defaultCharset()));
}
private ByteBuf[] getByteBufs(String... s) {
ByteBuf[] bufs = new ByteBuf[s.length];
for (int i = 0; i < s.length; ++i) {
bufs[i] = getByteBuf(s[i]);
}
return bufs;
}
}