Add and use AbstractDecoderTestCase
Introduce new base test case for decoder tests, and use it. Issue: SPR-17449
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.http.codec;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -26,7 +27,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
@@ -40,7 +41,7 @@ import static org.junit.Assert.*;
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class FormHttpMessageReaderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class FormHttpMessageReaderTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private final FormHttpMessageReader reader = new FormHttpMessageReader();
|
||||
|
||||
@@ -127,4 +128,11 @@ public class FormHttpMessageReaderTests extends AbstractDataBufferAllocatingTest
|
||||
.body(body);
|
||||
}
|
||||
|
||||
private DataBuffer stringBuffer(String value) {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,14 +16,19 @@
|
||||
|
||||
package org.springframework.http.codec;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||
@@ -35,7 +40,7 @@ import static org.junit.Assert.*;
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class FormHttpMessageWriterTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class FormHttpMessageWriterTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private final FormHttpMessageWriter writer = new FormHttpMessageWriter();
|
||||
|
||||
@@ -89,4 +94,14 @@ public class FormHttpMessageWriterTests extends AbstractDataBufferAllocatingTest
|
||||
assertEquals(expected.length(), headers.getContentLength());
|
||||
}
|
||||
|
||||
private Consumer<DataBuffer> stringConsumer(String expected) {
|
||||
return dataBuffer -> {
|
||||
String value =
|
||||
DataBufferTestUtils.dumpString(dataBuffer, StandardCharsets.UTF_8);
|
||||
DataBufferUtils.release(dataBuffer);
|
||||
assertEquals(expected, value);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.http.codec;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -25,7 +26,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
@@ -38,7 +39,7 @@ import static org.junit.Assert.*;
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class ServerSentEventHttpMessageReaderTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private ServerSentEventHttpMessageReader messageReader =
|
||||
new ServerSentEventHttpMessageReader(new Jackson2JsonDecoder());
|
||||
@@ -188,4 +189,12 @@ public class ServerSentEventHttpMessageReaderTests extends AbstractDataBufferAll
|
||||
.verify();
|
||||
}
|
||||
|
||||
private DataBuffer stringBuffer(String value) {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -35,11 +34,10 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.AbstractDecoderTestCase;
|
||||
import org.springframework.core.codec.CodecException;
|
||||
import org.springframework.core.codec.DecodingException;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
@@ -62,12 +60,19 @@ import static org.springframework.http.codec.json.JacksonViewBean.MyJacksonView3
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jackson2JsonDecoderTests extends AbstractDecoderTestCase<Jackson2JsonDecoder> {
|
||||
|
||||
private Pojo pojo1 = new Pojo("f1", "b1");
|
||||
|
||||
private Pojo pojo2 = new Pojo("f2", "b2");
|
||||
|
||||
public Jackson2JsonDecoderTests() {
|
||||
super(new Jackson2JsonDecoder());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void canDecode() {
|
||||
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
|
||||
|
||||
assertTrue(decoder.canDecode(forClass(Pojo.class), APPLICATION_JSON));
|
||||
assertTrue(decoder.canDecode(forClass(Pojo.class), APPLICATION_JSON_UTF8));
|
||||
assertTrue(decoder.canDecode(forClass(Pojo.class), APPLICATION_STREAM_JSON));
|
||||
@@ -93,172 +98,111 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
decoder.getMimeTypes().add(new MimeType("text", "ecmascript"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void decodePojo() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\": \"foofoo\", \"bar\": \"barbar\"}"));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null,
|
||||
emptyMap());
|
||||
public void decode() {
|
||||
Flux<DataBuffer> input = Flux.concat(
|
||||
stringBuffer("[{\"bar\":\"b1\",\"foo\":\"f1\"},"),
|
||||
stringBuffer("{\"bar\":\"b2\",\"foo\":\"f2\"}]"));
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("foofoo", "barbar"))
|
||||
.verifyComplete();
|
||||
testDecodeAll(input, Pojo.class, step -> step
|
||||
.expectNext(pojo1)
|
||||
.expectNext(pojo2)
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodePojoWithError() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\":}"));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null,
|
||||
emptyMap());
|
||||
|
||||
StepVerifier.create(flux).verifyError(CodecException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeToList() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(
|
||||
"[{\"bar\":\"b1\",\"foo\":\"f1\"},{\"bar\":\"b2\",\"foo\":\"f2\"}]"));
|
||||
@Override
|
||||
public void decodeToMono() {
|
||||
Flux<DataBuffer> input = Flux.concat(
|
||||
stringBuffer("[{\"bar\":\"b1\",\"foo\":\"f1\"},"),
|
||||
stringBuffer("{\"bar\":\"b2\",\"foo\":\"f2\"}]"));
|
||||
|
||||
ResolvableType elementType = ResolvableType.forClassWithGenerics(List.class, Pojo.class);
|
||||
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType,
|
||||
null, emptyMap());
|
||||
|
||||
StepVerifier.create(mono)
|
||||
testDecodeToMonoAll(input, elementType, step -> step
|
||||
.expectNext(asList(new Pojo("f1", "b1"), new Pojo("f2", "b2")))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verify(), null, null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void decodeEmptyArrayToFlux() {
|
||||
Flux<DataBuffer> input = Flux.from(stringBuffer("[]"));
|
||||
|
||||
testDecode(input, Pojo.class, step -> step.verifyComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeArrayToFlux() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(
|
||||
"[{\"bar\":\"b1\",\"foo\":\"f1\"},{\"bar\":\"b2\",\"foo\":\"f2\"}]"));
|
||||
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null,
|
||||
emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("f1", "b1"))
|
||||
.expectNext(new Pojo("f2", "b2"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeStreamToFlux() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"bar\":\"b1\",\"foo\":\"f1\"}"),
|
||||
stringBuffer("{\"bar\":\"b2\",\"foo\":\"f2\"}"));
|
||||
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, APPLICATION_STREAM_JSON,
|
||||
emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("f1", "b1"))
|
||||
.expectNext(new Pojo("f2", "b2"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeEmptyArrayToFlux() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("[]"));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldLevelJsonView() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(
|
||||
public void fieldLevelJsonView() {
|
||||
Flux<DataBuffer> input = Flux.from(
|
||||
stringBuffer("{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}"));
|
||||
ResolvableType elementType = forClass(JacksonViewBean.class);
|
||||
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class);
|
||||
Flux<JacksonViewBean> flux = new Jackson2JsonDecoder()
|
||||
.decode(source, elementType, null, hints).cast(JacksonViewBean.class);
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.consumeNextWith(b -> {
|
||||
assertTrue(b.getWithView1().equals("with"));
|
||||
testDecode(input, elementType, step -> step
|
||||
.consumeNextWith(o -> {
|
||||
JacksonViewBean b = (JacksonViewBean) o;
|
||||
assertEquals("with", b.getWithView1());
|
||||
assertNull(b.getWithView2());
|
||||
assertNull(b.getWithoutView());
|
||||
})
|
||||
.verifyComplete();
|
||||
}), null, hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classLevelJsonView() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(
|
||||
public void classLevelJsonView() {
|
||||
Flux<DataBuffer> input = Flux.from(stringBuffer(
|
||||
"{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}"));
|
||||
ResolvableType elementType = forClass(JacksonViewBean.class);
|
||||
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView3.class);
|
||||
Flux<JacksonViewBean> flux = new Jackson2JsonDecoder()
|
||||
.decode(source, elementType, null, hints).cast(JacksonViewBean.class);
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.consumeNextWith(b -> {
|
||||
testDecode(input, elementType, step -> step
|
||||
.consumeNextWith(o -> {
|
||||
JacksonViewBean b = (JacksonViewBean) o;
|
||||
assertEquals("without", b.getWithoutView());
|
||||
assertNull(b.getWithView1());
|
||||
assertNull(b.getWithView2());
|
||||
assertTrue(b.getWithoutView().equals("without"));
|
||||
})
|
||||
.verifyComplete();
|
||||
.verifyComplete(), null, hints);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeEmptyBodyToMono() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.empty();
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.expectNextCount(0)
|
||||
.verifyComplete();
|
||||
public void invalidData() {
|
||||
Flux<DataBuffer> input =
|
||||
Flux.from(stringBuffer("{\"foofoo\": \"foofoo\", \"barbar\": \"barbar\""));
|
||||
testDecode(input, Pojo.class, step -> step
|
||||
.verifyError(DecodingException.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidData() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer( "{\"foofoo\": \"foofoo\", \"barbar\": \"barbar\"}"));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder(new ObjectMapper()).decode(source, elementType, null, emptyMap());
|
||||
StepVerifier.create(flux).verifyErrorMatches(ex -> ex instanceof DecodingException);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void error() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foofoo\": \"foofoo\", \"barbar\":"))
|
||||
.concatWith(Flux.error(new RuntimeException()));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder(new ObjectMapper()).decode(source, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectError(RuntimeException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noDefaultConstructor() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer( "{\"property1\":\"foo\",\"property2\":\"bar\"}"));
|
||||
public void noDefaultConstructor() {
|
||||
Flux<DataBuffer> input =
|
||||
Flux.from(stringBuffer("{\"property1\":\"foo\",\"property2\":\"bar\"}"));
|
||||
ResolvableType elementType = forClass(BeanWithNoDefaultConstructor.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, emptyMap());
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(input, elementType, null, emptyMap());
|
||||
StepVerifier.create(flux).verifyError(CodecException.class);
|
||||
}
|
||||
|
||||
@Test // SPR-15975
|
||||
public void customDeserializer() {
|
||||
DataBuffer buffer = new DefaultDataBufferFactory().wrap("{\"test\": 1}".getBytes());
|
||||
Mono<DataBuffer> input = stringBuffer("{\"test\": 1}");
|
||||
|
||||
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(new ObjectMapper());
|
||||
Flux<TestObject> decoded = decoder.decode(Mono.just(buffer),
|
||||
ResolvableType.forClass(TestObject.class), null, null).cast(TestObject.class);
|
||||
|
||||
StepVerifier.create(decoded)
|
||||
.assertNext(v -> assertEquals(1, v.getTest()))
|
||||
.verifyComplete();
|
||||
testDecode(input, TestObject.class, step -> step
|
||||
.consumeNextWith(o -> assertEquals(1, o.getTest()))
|
||||
.verifyComplete()
|
||||
);
|
||||
}
|
||||
|
||||
private Mono<DataBuffer> stringBuffer(String value) {
|
||||
return Mono.defer(() -> {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return Mono.just(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class BeanWithNoDefaultConstructor {
|
||||
|
||||
@@ -272,11 +216,11 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
}
|
||||
|
||||
public String getProperty1() {
|
||||
return property1;
|
||||
return this.property1;
|
||||
}
|
||||
|
||||
public String getProperty2() {
|
||||
return property2;
|
||||
return this.property2;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -285,7 +229,7 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
public static class TestObject {
|
||||
private int test;
|
||||
public int getTest() {
|
||||
return test;
|
||||
return this.test;
|
||||
}
|
||||
public void setTest(int test) {
|
||||
this.test = test;
|
||||
@@ -302,7 +246,7 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
|
||||
@Override
|
||||
public TestObject deserialize(JsonParser p,
|
||||
DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
DeserializationContext ctxt) throws IOException {
|
||||
JsonNode node = p.readValueAsTree();
|
||||
TestObject result = new TestObject();
|
||||
result.setTest(node.get("test").asInt());
|
||||
|
||||
@@ -16,26 +16,22 @@
|
||||
|
||||
package org.springframework.http.codec.json;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.CodecException;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.codec.AbstractDecoderTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.core.ResolvableType.forClass;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
|
||||
@@ -44,13 +40,22 @@ import static org.springframework.http.MediaType.APPLICATION_JSON;
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class Jackson2SmileDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jackson2SmileDecoderTests extends AbstractDecoderTestCase<Jackson2SmileDecoder> {
|
||||
|
||||
private final static MimeType SMILE_MIME_TYPE = new MimeType("application", "x-jackson-smile");
|
||||
private final static MimeType STREAM_SMILE_MIME_TYPE = new MimeType("application", "stream+x-jackson-smile");
|
||||
|
||||
private final Jackson2SmileDecoder decoder = new Jackson2SmileDecoder();
|
||||
private Pojo pojo1 = new Pojo("f1", "b1");
|
||||
|
||||
private Pojo pojo2 = new Pojo("f2", "b2");
|
||||
|
||||
private ObjectMapper mapper = Jackson2ObjectMapperBuilder.smile().build();
|
||||
|
||||
public Jackson2SmileDecoderTests() {
|
||||
super(new Jackson2SmileDecoder());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void canDecode() {
|
||||
assertTrue(decoder.canDecode(forClass(Pojo.class), SMILE_MIME_TYPE));
|
||||
@@ -61,76 +66,42 @@ public class Jackson2SmileDecoderTests extends AbstractDataBufferAllocatingTestC
|
||||
assertFalse(decoder.canDecode(forClass(Pojo.class), APPLICATION_JSON));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodePojo() throws Exception {
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.smile().build();
|
||||
Pojo pojo = new Pojo("foo", "bar");
|
||||
byte[] serializedPojo = mapper.writer().writeValueAsBytes(pojo);
|
||||
@Override
|
||||
public void decode() {
|
||||
Flux<DataBuffer> input = Flux.just(this.pojo1, this.pojo2)
|
||||
.map(this::writeObject)
|
||||
.flatMap(this::dataBuffer);
|
||||
|
||||
Flux<DataBuffer> source = Flux.just(this.bufferFactory.wrap(serializedPojo));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = decoder.decode(source, elementType, null, emptyMap());
|
||||
testDecodeAll(input, Pojo.class, step -> step
|
||||
.expectNext(pojo1)
|
||||
.expectNext(pojo2)
|
||||
.verifyComplete());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(pojo)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodePojoWithError() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("123"));
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = decoder.decode(source, elementType, null, emptyMap());
|
||||
private byte[] writeObject(Object o) {
|
||||
try {
|
||||
return this.mapper.writer().writeValueAsBytes(o);
|
||||
}
|
||||
catch (JsonProcessingException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
|
||||
StepVerifier.create(flux).verifyError(CodecException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeToList() throws Exception {
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.smile().build();
|
||||
List<Pojo> list = asList(new Pojo("f1", "b1"), new Pojo("f2", "b2"));
|
||||
byte[] serializedList = mapper.writer().writeValueAsBytes(list);
|
||||
Flux<DataBuffer> source = Flux.just(this.bufferFactory.wrap(serializedList));
|
||||
@Override
|
||||
public void decodeToMono() {
|
||||
List<Pojo> expected = Arrays.asList(pojo1, pojo2);
|
||||
|
||||
Flux<DataBuffer> input = Flux.just(expected)
|
||||
.map(this::writeObject)
|
||||
.flatMap(this::dataBuffer);
|
||||
|
||||
ResolvableType elementType = ResolvableType.forClassWithGenerics(List.class, Pojo.class);
|
||||
Mono<Object> mono = decoder.decodeToMono(source, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.expectNext(list)
|
||||
testDecodeToMono(input, elementType, step -> step
|
||||
.expectNext(expected)
|
||||
.expectComplete()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeListToFlux() throws Exception {
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.smile().build();
|
||||
List<Pojo> list = asList(new Pojo("f1", "b1"), new Pojo("f2", "b2"));
|
||||
byte[] serializedList = mapper.writer().writeValueAsBytes(list);
|
||||
Flux<DataBuffer> source = Flux.just(this.bufferFactory.wrap(serializedList));
|
||||
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = decoder.decode(source, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("f1", "b1"))
|
||||
.expectNext(new Pojo("f2", "b2"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeStreamToFlux() throws Exception {
|
||||
ObjectMapper mapper = Jackson2ObjectMapperBuilder.smile().build();
|
||||
List<Pojo> list = asList(new Pojo("f1", "b1"), new Pojo("f2", "b2"));
|
||||
byte[] serializedList = mapper.writer().writeValueAsBytes(list);
|
||||
Flux<DataBuffer> source = Flux.just(this.bufferFactory.wrap(serializedList));
|
||||
|
||||
ResolvableType elementType = forClass(Pojo.class);
|
||||
Flux<Object> flux = decoder.decode(source, elementType, STREAM_SMILE_MIME_TYPE, emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("f1", "b1"))
|
||||
.expectNext(new Pojo("f2", "b2"))
|
||||
.verifyComplete();
|
||||
.verify(), null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.http.codec.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -33,7 +34,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.codec.DecodingException;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -43,7 +44,7 @@ import static java.util.Collections.singletonList;
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class Jackson2TokenizerTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jackson2TokenizerTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@@ -191,11 +192,14 @@ public class Jackson2TokenizerTests extends AbstractDataBufferAllocatingTestCase
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Test(expected = DecodingException.class) // SPR-16521
|
||||
@Test // SPR-16521
|
||||
public void jsonEOFExceptionIsWrappedAsDecodingError() {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"status\": \"noClosingQuote}"));
|
||||
Flux<TokenBuffer> tokens = Jackson2Tokenizer.tokenize(source, this.jsonFactory, false);
|
||||
tokens.blockLast();
|
||||
|
||||
StepVerifier.create(tokens)
|
||||
.expectError(DecodingException.class)
|
||||
.verify();
|
||||
}
|
||||
|
||||
|
||||
@@ -222,6 +226,14 @@ public class Jackson2TokenizerTests extends AbstractDataBufferAllocatingTestCase
|
||||
builder.verifyComplete();
|
||||
}
|
||||
|
||||
private DataBuffer stringBuffer(String value) {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static class JSONAssertConsumer implements Consumer<String> {
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.StringDecoder;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
|
||||
@@ -51,7 +51,7 @@ import static org.junit.Assert.*;
|
||||
* @author Sebastien Deleuze
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MultipartHttpMessageWriterTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class MultipartHttpMessageWriterTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private final MultipartHttpMessageWriter writer =
|
||||
new MultipartHttpMessageWriter(ClientCodecConfigurer.create().getWriters());
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
package org.springframework.http.codec.protobuf;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.protobuf.Message;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.AbstractDecoderTestCase;
|
||||
import org.springframework.core.codec.DecodingException;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -38,37 +38,36 @@ import org.springframework.util.MimeType;
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.springframework.core.ResolvableType.forClass;
|
||||
import static org.springframework.core.io.buffer.DataBufferUtils.release;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link ProtobufDecoder}.
|
||||
*
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class ProtobufDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class ProtobufDecoderTests extends AbstractDecoderTestCase<ProtobufDecoder> {
|
||||
|
||||
private final static MimeType PROTOBUF_MIME_TYPE = new MimeType("application", "x-protobuf");
|
||||
|
||||
private final SecondMsg secondMsg = SecondMsg.newBuilder().setBlah(123).build();
|
||||
|
||||
private final Msg testMsg = Msg.newBuilder().setFoo("Foo").setBlah(secondMsg).build();
|
||||
private final Msg testMsg1 = Msg.newBuilder().setFoo("Foo").setBlah(secondMsg).build();
|
||||
|
||||
private final SecondMsg secondMsg2 = SecondMsg.newBuilder().setBlah(456).build();
|
||||
|
||||
private final Msg testMsg2 = Msg.newBuilder().setFoo("Bar").setBlah(secondMsg2).build();
|
||||
|
||||
private ProtobufDecoder decoder;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.decoder = new ProtobufDecoder();
|
||||
public ProtobufDecoderTests() {
|
||||
super(new ProtobufDecoder());
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void extensionRegistryNull() {
|
||||
new ProtobufDecoder(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void canDecode() {
|
||||
assertTrue(this.decoder.canDecode(forClass(Msg.class), null));
|
||||
@@ -78,115 +77,119 @@ public class ProtobufDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
assertFalse(this.decoder.canDecode(forClass(Object.class), PROTOBUF_MIME_TYPE));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void decodeToMono() {
|
||||
DataBuffer data = byteBuffer(testMsg.toByteArray());
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
Mono<DataBuffer> input = dataBuffer(this.testMsg1);
|
||||
|
||||
Mono<Message> mono = this.decoder.decodeToMono(Flux.just(data), elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.expectNext(testMsg)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeToMonoWithLargerDataBuffer() {
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(1024);
|
||||
buffer.write(testMsg.toByteArray());
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
|
||||
Mono<Message> mono = this.decoder.decodeToMono(Flux.just(buffer), elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.expectNext(testMsg)
|
||||
.verifyComplete();
|
||||
testDecodeToMonoAll(input, Msg.class, step -> step
|
||||
.expectNext(this.testMsg1)
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeChunksToMono() {
|
||||
DataBuffer buffer = byteBuffer(testMsg.toByteArray());
|
||||
Flux<DataBuffer> chunks = Flux.just(
|
||||
DataBufferUtils.retain(buffer.slice(0, 4)),
|
||||
DataBufferUtils.retain(buffer.slice(4, buffer.readableByteCount() - 4)));
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
release(buffer);
|
||||
byte[] full = this.testMsg1.toByteArray();
|
||||
byte[] chunk1 = Arrays.copyOfRange(full, 0, full.length / 2);
|
||||
byte[] chunk2 = Arrays.copyOfRange(full, chunk1.length, full.length);
|
||||
|
||||
Mono<Message> mono = this.decoder.decodeToMono(chunks, elementType, null,
|
||||
emptyMap());
|
||||
Flux<DataBuffer> input = Flux.just(chunk1, chunk2)
|
||||
.flatMap(bytes -> Mono.defer(() -> {
|
||||
DataBuffer dataBuffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
dataBuffer.write(bytes);
|
||||
return Mono.just(dataBuffer);
|
||||
}));
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.expectNext(testMsg)
|
||||
.verifyComplete();
|
||||
testDecodeToMono(input, Msg.class, step -> step
|
||||
.expectNext(this.testMsg1)
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Test
|
||||
public void decode() throws IOException {
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer();
|
||||
testMsg.writeDelimitedTo(buffer.asOutputStream());
|
||||
DataBuffer buffer2 = this.bufferFactory.allocateBuffer();
|
||||
testMsg2.writeDelimitedTo(buffer2.asOutputStream());
|
||||
public void decode() {
|
||||
Flux<DataBuffer> input = Flux.just(this.testMsg1, this.testMsg2)
|
||||
.flatMap(msg -> Mono.defer(() -> {
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer();
|
||||
try {
|
||||
msg.writeDelimitedTo(buffer.asOutputStream());
|
||||
return Mono.just(buffer);
|
||||
}
|
||||
catch (IOException e) {
|
||||
release(buffer);
|
||||
return Mono.error(e);
|
||||
}
|
||||
}));
|
||||
|
||||
Flux<DataBuffer> source = Flux.just(buffer, buffer2);
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
|
||||
Flux<Message> messages = this.decoder.decode(source, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(messages)
|
||||
.expectNext(testMsg)
|
||||
.expectNext(testMsg2)
|
||||
.verifyComplete();
|
||||
testDecodeAll(input, Msg.class, step -> step
|
||||
.expectNext(this.testMsg1)
|
||||
.expectNext(this.testMsg2)
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeSplitChunks() throws IOException {
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer();
|
||||
testMsg.writeDelimitedTo(buffer.asOutputStream());
|
||||
DataBuffer buffer2 = this.bufferFactory.allocateBuffer();
|
||||
testMsg2.writeDelimitedTo(buffer2.asOutputStream());
|
||||
Flux<DataBuffer> input = Flux.just(this.testMsg1, this.testMsg2)
|
||||
.flatMap(msg -> Mono.defer(() -> {
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer();
|
||||
try {
|
||||
msg.writeDelimitedTo(buffer.asOutputStream());
|
||||
return Mono.just(buffer);
|
||||
}
|
||||
catch (IOException e) {
|
||||
release(buffer);
|
||||
return Mono.error(e);
|
||||
}
|
||||
}))
|
||||
.flatMap(buffer -> {
|
||||
int len = buffer.readableByteCount() / 2;
|
||||
Flux<DataBuffer> result = Flux.just(
|
||||
DataBufferUtils.retain(buffer.slice(0, len)),
|
||||
DataBufferUtils
|
||||
.retain(buffer.slice(len, buffer.readableByteCount() - len))
|
||||
);
|
||||
release(buffer);
|
||||
return result;
|
||||
});
|
||||
|
||||
Flux<DataBuffer> chunks = Flux.just(
|
||||
DataBufferUtils.retain(buffer.slice(0, 4)),
|
||||
DataBufferUtils.retain(buffer.slice(4, buffer.readableByteCount() - 4)),
|
||||
DataBufferUtils.retain(buffer2.slice(0, 2)),
|
||||
DataBufferUtils.retain(buffer2
|
||||
.slice(2, buffer2.readableByteCount() - 2)));
|
||||
release(buffer, buffer2);
|
||||
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
Flux<Message> messages = this.decoder.decode(chunks, elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(messages)
|
||||
.expectNext(testMsg)
|
||||
.expectNext(testMsg2)
|
||||
.verifyComplete();
|
||||
testDecode(input, Msg.class, step -> step
|
||||
.expectNext(this.testMsg1)
|
||||
.expectNext(this.testMsg2)
|
||||
.verifyComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decodeMergedChunks() throws IOException {
|
||||
DataBuffer buffer = bufferFactory.allocateBuffer();
|
||||
testMsg.writeDelimitedTo(buffer.asOutputStream());
|
||||
testMsg.writeDelimitedTo(buffer.asOutputStream());
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer();
|
||||
this.testMsg1.writeDelimitedTo(buffer.asOutputStream());
|
||||
this.testMsg1.writeDelimitedTo(buffer.asOutputStream());
|
||||
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
Flux<Message> messages = this.decoder.decode(Mono.just(buffer), elementType, null, emptyMap());
|
||||
|
||||
StepVerifier.create(messages)
|
||||
.expectNext(testMsg)
|
||||
.expectNext(testMsg)
|
||||
.expectNext(testMsg1)
|
||||
.expectNext(testMsg1)
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceedMaxSize() {
|
||||
this.decoder.setMaxMessageSize(1);
|
||||
Flux<DataBuffer> source = Flux.just(byteBuffer(testMsg.toByteArray()));
|
||||
ResolvableType elementType = forClass(Msg.class);
|
||||
Flux<Message> messages = this.decoder.decode(source, elementType, null,
|
||||
emptyMap());
|
||||
Mono<DataBuffer> input = dataBuffer(this.testMsg1);
|
||||
|
||||
StepVerifier.create(messages)
|
||||
.verifyError(DecodingException.class);
|
||||
testDecode(input, Msg.class, step -> step
|
||||
.verifyError(DecodingException.class));
|
||||
}
|
||||
|
||||
private Mono<DataBuffer> dataBuffer(Msg msg) {
|
||||
return Mono.defer(() -> {
|
||||
byte[] bytes = msg.toByteArray();
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return Mono.just(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.http.codec.xml;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.xml.namespace.QName;
|
||||
@@ -27,7 +28,7 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
@@ -43,7 +44,7 @@ import static org.junit.Assert.*;
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class Jaxb2XmlDecoderTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private static final String POJO_ROOT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<pojo>" +
|
||||
@@ -87,7 +88,7 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
@Test
|
||||
public void splitOneBranches() {
|
||||
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder
|
||||
.decode(Flux.just(stringBuffer(POJO_ROOT)), null, null, Collections.emptyMap());
|
||||
.decode(stringBuffer(POJO_ROOT), null, null, Collections.emptyMap());
|
||||
Flux<List<XMLEvent>> result = this.decoder.split(xmlEvents, new QName("pojo"));
|
||||
|
||||
StepVerifier.create(result)
|
||||
@@ -109,7 +110,7 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
@Test
|
||||
public void splitMultipleBranches() throws Exception {
|
||||
Flux<XMLEvent> xmlEvents = this.xmlEventDecoder
|
||||
.decode(Flux.just(stringBuffer(POJO_CHILD)), null, null, Collections.emptyMap());
|
||||
.decode(stringBuffer(POJO_CHILD), null, null, Collections.emptyMap());
|
||||
Flux<List<XMLEvent>> result = this.decoder.split(xmlEvents, new QName("pojo"));
|
||||
|
||||
|
||||
@@ -157,7 +158,7 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void decodeSingleXmlRootElement() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(POJO_ROOT));
|
||||
Mono<DataBuffer> source = stringBuffer(POJO_ROOT);
|
||||
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class),
|
||||
null, Collections.emptyMap());
|
||||
|
||||
@@ -169,7 +170,7 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void decodeSingleXmlTypeElement() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(POJO_ROOT));
|
||||
Mono<DataBuffer> source = stringBuffer(POJO_ROOT);
|
||||
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(TypePojo.class),
|
||||
null, Collections.emptyMap());
|
||||
|
||||
@@ -181,7 +182,7 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void decodeMultipleXmlRootElement() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(POJO_CHILD));
|
||||
Mono<DataBuffer> source = stringBuffer(POJO_CHILD);
|
||||
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(Pojo.class),
|
||||
null, Collections.emptyMap());
|
||||
|
||||
@@ -194,7 +195,7 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void decodeMultipleXmlTypeElement() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer(POJO_CHILD));
|
||||
Mono<DataBuffer> source = stringBuffer(POJO_CHILD);
|
||||
Flux<Object> output = this.decoder.decode(source, ResolvableType.forClass(TypePojo.class),
|
||||
null, Collections.emptyMap());
|
||||
|
||||
@@ -207,8 +208,9 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void decodeError() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("<pojo>"))
|
||||
.concatWith(Flux.error(new RuntimeException()));
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
stringBuffer("<pojo>"),
|
||||
Flux.error(new RuntimeException()));
|
||||
|
||||
Mono<Object> output = this.decoder.decodeToMono(source, ResolvableType.forClass(Pojo.class),
|
||||
null, Collections.emptyMap());
|
||||
@@ -239,6 +241,16 @@ public class Jaxb2XmlDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
}
|
||||
|
||||
private Mono<DataBuffer> stringBuffer(String value) {
|
||||
return Mono.defer(() -> {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return Mono.just(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@javax.xml.bind.annotation.XmlType(name = "pojo")
|
||||
public static class TypePojo {
|
||||
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
|
||||
package org.springframework.http.codec.xml;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.junit.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
@@ -31,7 +33,7 @@ import static org.junit.Assert.*;
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class XmlEventDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public class XmlEventDecoderTests extends AbstractLeakCheckingTestCase {
|
||||
|
||||
private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
|
||||
"<pojo>" +
|
||||
@@ -45,7 +47,7 @@ public class XmlEventDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public void toXMLEventsAalto() {
|
||||
|
||||
Flux<XMLEvent> events =
|
||||
this.decoder.decode(Flux.just(stringBuffer(XML)), null, null, Collections.emptyMap());
|
||||
this.decoder.decode(stringBuffer(XML), null, null, Collections.emptyMap());
|
||||
|
||||
StepVerifier.create(events)
|
||||
.consumeNextWith(e -> assertTrue(e.isStartDocument()))
|
||||
@@ -66,7 +68,7 @@ public class XmlEventDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
decoder.useAalto = false;
|
||||
|
||||
Flux<XMLEvent> events =
|
||||
this.decoder.decode(Flux.just(stringBuffer(XML)), null, null, Collections.emptyMap());
|
||||
this.decoder.decode(stringBuffer(XML), null, null, Collections.emptyMap());
|
||||
|
||||
StepVerifier.create(events)
|
||||
.consumeNextWith(e -> assertTrue(e.isStartDocument()))
|
||||
@@ -85,8 +87,9 @@ public class XmlEventDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
|
||||
@Test
|
||||
public void decodeErrorAalto() {
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("<pojo>"))
|
||||
.concatWith(Flux.error(new RuntimeException()));
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
stringBuffer("<pojo>"),
|
||||
Flux.error(new RuntimeException()));
|
||||
|
||||
Flux<XMLEvent> events =
|
||||
this.decoder.decode(source, null, null, Collections.emptyMap());
|
||||
@@ -102,8 +105,9 @@ public class XmlEventDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
public void decodeErrorNonAalto() {
|
||||
decoder.useAalto = false;
|
||||
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("<pojo>"))
|
||||
.concatWith(Flux.error(new RuntimeException()));
|
||||
Flux<DataBuffer> source = Flux.concat(
|
||||
stringBuffer("<pojo>"),
|
||||
Flux.error(new RuntimeException()));
|
||||
|
||||
Flux<XMLEvent> events =
|
||||
this.decoder.decode(source, null, null, Collections.emptyMap());
|
||||
@@ -128,4 +132,13 @@ public class XmlEventDecoderTests extends AbstractDataBufferAllocatingTestCase {
|
||||
assertEquals(expectedData, event.asCharacters().getData());
|
||||
}
|
||||
|
||||
private Mono<DataBuffer> stringBuffer(String value) {
|
||||
return Mono.defer(() -> {
|
||||
byte[] bytes = value.getBytes(StandardCharsets.UTF_8);
|
||||
DataBuffer buffer = this.bufferFactory.allocateBuffer(bytes.length);
|
||||
buffer.write(bytes);
|
||||
return Mono.just(buffer);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user