Skip to content

Commit 39ce989

Browse files
committed
Add and use AbstractDecoderTestCase
Introduce new base test case for decoder tests, and use it. Issue: SPR-17449
1 parent 0f2d9df commit 39ce989

20 files changed

+1048
-568
lines changed

spring-core/src/test/java/org/springframework/core/codec/AbstractDecoderTestCase.java

Lines changed: 450 additions & 0 deletions
Large diffs are not rendered by default.

spring-core/src/test/java/org/springframework/core/codec/AbstractEncoderTestCase.java

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,16 @@
2020
import java.util.function.Consumer;
2121
import java.util.stream.Stream;
2222

23-
import org.junit.After;
2423
import org.junit.Test;
2524
import org.reactivestreams.Publisher;
2625
import reactor.core.publisher.Flux;
2726
import reactor.test.StepVerifier;
2827

2928
import org.springframework.core.ResolvableType;
29+
import org.springframework.core.io.buffer.AbstractLeakCheckingTestCase;
3030
import org.springframework.core.io.buffer.DataBuffer;
3131
import org.springframework.core.io.buffer.DataBufferFactory;
3232
import org.springframework.core.io.buffer.DataBufferUtils;
33-
import org.springframework.core.io.buffer.LeakAwareDataBufferFactory;
3433
import org.springframework.lang.Nullable;
3534
import org.springframework.util.Assert;
3635
import org.springframework.util.MimeType;
@@ -46,13 +45,8 @@
4645
* @author Arjen Poutsma
4746
*/
4847
@SuppressWarnings("ProtectedField")
49-
public abstract class AbstractEncoderTestCase<T, E extends Encoder<T>> {
50-
51-
/**
52-
* The data buffer factory used by the encoder.
53-
*/
54-
protected final DataBufferFactory bufferFactory =
55-
new LeakAwareDataBufferFactory();
48+
public abstract class AbstractEncoderTestCase<T, E extends Encoder<T>> extends
49+
AbstractLeakCheckingTestCase {
5650

5751
/**
5852
* The encoder to test.
@@ -110,15 +104,6 @@ protected AbstractEncoderTestCase(E encoder, ResolvableType elementType,
110104
this.hints = hints;
111105
}
112106

113-
/**
114-
* Checks whether any of the data buffers created by {@link #bufferFactory} have not been
115-
* released, throwing an assertion error if so.
116-
*/
117-
@After
118-
public final void checkForLeaks() {
119-
((LeakAwareDataBufferFactory) this.bufferFactory).checkForLeaks();
120-
}
121-
122107
/**
123108
* Abstract template method that provides input for the encoder.
124109
* Used for {@link #encode()}, {@link #encodeError()}, and {@link #encodeCancel()}.

spring-core/src/test/java/org/springframework/core/codec/ByteArrayDecoderTests.java

Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616

1717
package org.springframework.core.codec;
1818

19-
import java.util.Collections;
19+
import java.nio.charset.StandardCharsets;
20+
import java.util.function.Consumer;
2021

2122
import org.junit.Test;
22-
import org.reactivestreams.Publisher;
2323
import reactor.core.publisher.Flux;
24-
import reactor.core.publisher.Mono;
25-
import reactor.test.StepVerifier;
2624

2725
import org.springframework.core.ResolvableType;
28-
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
2926
import org.springframework.core.io.buffer.DataBuffer;
3027
import org.springframework.util.MimeTypeUtils;
3128

@@ -34,11 +31,18 @@
3431
/**
3532
* @author Arjen Poutsma
3633
*/
37-
public class ByteArrayDecoderTests extends AbstractDataBufferAllocatingTestCase {
34+
public class ByteArrayDecoderTests extends AbstractDecoderTestCase<ByteArrayDecoder> {
3835

39-
private final ByteArrayDecoder decoder = new ByteArrayDecoder();
36+
private final byte[] fooBytes = "foo".getBytes(StandardCharsets.UTF_8);
4037

38+
private final byte[] barBytes = "bar".getBytes(StandardCharsets.UTF_8);
4139

40+
41+
public ByteArrayDecoderTests() {
42+
super(new ByteArrayDecoder());
43+
}
44+
45+
@Override
4246
@Test
4347
public void canDecode() {
4448
assertTrue(this.decoder.canDecode(ResolvableType.forClass(byte[].class),
@@ -49,50 +53,38 @@ public void canDecode() {
4953
MimeTypeUtils.APPLICATION_JSON));
5054
}
5155

56+
@Override
5257
@Test
5358
public void decode() {
54-
DataBuffer fooBuffer = stringBuffer("foo");
55-
DataBuffer barBuffer = stringBuffer("bar");
56-
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
57-
Flux<byte[]> output = this.decoder.decode(source,
58-
ResolvableType.forClassWithGenerics(Publisher.class, byte[].class),
59-
null, Collections.emptyMap());
60-
61-
StepVerifier.create(output)
62-
.consumeNextWith(bytes -> assertArrayEquals("foo".getBytes(), bytes))
63-
.consumeNextWith(bytes -> assertArrayEquals("bar".getBytes(), bytes))
64-
.expectComplete()
65-
.verify();
66-
}
59+
Flux<DataBuffer> input = Flux.concat(
60+
dataBuffer(this.fooBytes),
61+
dataBuffer(this.barBytes));
62+
63+
testDecodeAll(input, byte[].class, step -> step
64+
.consumeNextWith(expectBytes(this.fooBytes))
65+
.consumeNextWith(expectBytes(this.barBytes))
66+
.verifyComplete());
6767

68-
@Test
69-
public void decodeError() {
70-
DataBuffer fooBuffer = stringBuffer("foo");
71-
Flux<DataBuffer> source =
72-
Flux.just(fooBuffer).concatWith(Flux.error(new RuntimeException()));
73-
Flux<byte[]> output = this.decoder.decode(source,
74-
ResolvableType.forClassWithGenerics(Publisher.class, byte[].class),
75-
null, Collections.emptyMap());
76-
77-
StepVerifier.create(output)
78-
.consumeNextWith(bytes -> assertArrayEquals("foo".getBytes(), bytes))
79-
.expectError()
80-
.verify();
8168
}
8269

70+
@Override
8371
@Test
8472
public void decodeToMono() {
85-
DataBuffer fooBuffer = stringBuffer("foo");
86-
DataBuffer barBuffer = stringBuffer("bar");
87-
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
88-
Mono<byte[]> output = this.decoder.decodeToMono(source,
89-
ResolvableType.forClassWithGenerics(Publisher.class, byte[].class),
90-
null, Collections.emptyMap());
91-
92-
StepVerifier.create(output)
93-
.consumeNextWith(bytes -> assertArrayEquals("foobar".getBytes(), bytes))
94-
.expectComplete()
95-
.verify();
73+
Flux<DataBuffer> input = Flux.concat(
74+
dataBuffer(this.fooBytes),
75+
dataBuffer(this.barBytes));
76+
77+
byte[] expected = new byte[this.fooBytes.length + this.barBytes.length];
78+
System.arraycopy(this.fooBytes, 0, expected, 0, this.fooBytes.length);
79+
System.arraycopy(this.barBytes, 0, expected, this.fooBytes.length, this.barBytes.length);
80+
81+
testDecodeToMonoAll(input, byte[].class, step -> step
82+
.consumeNextWith(expectBytes(expected))
83+
.verifyComplete());
84+
}
85+
86+
private Consumer<byte[]> expectBytes(byte[] expected) {
87+
return bytes -> assertArrayEquals(expected, bytes);
9688
}
9789

9890
}

spring-core/src/test/java/org/springframework/core/codec/ByteBufferDecoderTests.java

Lines changed: 38 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@
1717
package org.springframework.core.codec;
1818

1919
import java.nio.ByteBuffer;
20-
import java.util.Collections;
20+
import java.nio.charset.StandardCharsets;
21+
import java.util.function.Consumer;
2122

2223
import org.junit.Test;
23-
import org.reactivestreams.Publisher;
2424
import reactor.core.publisher.Flux;
25-
import reactor.core.publisher.Mono;
26-
import reactor.test.StepVerifier;
2725

2826
import org.springframework.core.ResolvableType;
29-
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
3027
import org.springframework.core.io.buffer.DataBuffer;
3128
import org.springframework.util.MimeTypeUtils;
3229

@@ -35,10 +32,18 @@
3532
/**
3633
* @author Sebastien Deleuze
3734
*/
38-
public class ByteBufferDecoderTests extends AbstractDataBufferAllocatingTestCase {
35+
public class ByteBufferDecoderTests extends AbstractDecoderTestCase<ByteBufferDecoder> {
3936

40-
private final ByteBufferDecoder decoder = new ByteBufferDecoder();
37+
private final byte[] fooBytes = "foo".getBytes(StandardCharsets.UTF_8);
4138

39+
private final byte[] barBytes = "bar".getBytes(StandardCharsets.UTF_8);
40+
41+
42+
public ByteBufferDecoderTests() {
43+
super(new ByteBufferDecoder());
44+
}
45+
46+
@Override
4247
@Test
4348
public void canDecode() {
4449
assertTrue(this.decoder.canDecode(ResolvableType.forClass(ByteBuffer.class),
@@ -49,48 +54,38 @@ public void canDecode() {
4954
MimeTypeUtils.APPLICATION_JSON));
5055
}
5156

57+
@Override
5258
@Test
5359
public void decode() {
54-
DataBuffer fooBuffer = stringBuffer("foo");
55-
DataBuffer barBuffer = stringBuffer("bar");
56-
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
57-
Flux<ByteBuffer> output = this.decoder.decode(source,
58-
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
59-
null, Collections.emptyMap());
60-
61-
StepVerifier.create(output)
62-
.expectNext(ByteBuffer.wrap("foo".getBytes()), ByteBuffer.wrap("bar".getBytes()))
63-
.expectComplete()
64-
.verify();
65-
}
60+
Flux<DataBuffer> input = Flux.concat(
61+
dataBuffer(this.fooBytes),
62+
dataBuffer(this.barBytes));
63+
64+
testDecodeAll(input, ByteBuffer.class, step -> step
65+
.consumeNextWith(expectByteBuffer(ByteBuffer.wrap(this.fooBytes)))
66+
.consumeNextWith(expectByteBuffer(ByteBuffer.wrap(this.barBytes)))
67+
.verifyComplete());
68+
6669

67-
@Test
68-
public void decodeError() {
69-
DataBuffer fooBuffer = stringBuffer("foo");
70-
Flux<DataBuffer> source =
71-
Flux.just(fooBuffer).concatWith(Flux.error(new RuntimeException()));
72-
Flux<ByteBuffer> output = this.decoder.decode(source,
73-
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
74-
null, Collections.emptyMap());
75-
76-
StepVerifier.create(output)
77-
.expectNext(ByteBuffer.wrap("foo".getBytes()))
78-
.expectError()
79-
.verify();
8070
}
8171

72+
@Override
8273
@Test
8374
public void decodeToMono() {
84-
DataBuffer fooBuffer = stringBuffer("foo");
85-
DataBuffer barBuffer = stringBuffer("bar");
86-
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
87-
Mono<ByteBuffer> output = this.decoder.decodeToMono(source,
88-
ResolvableType.forClassWithGenerics(Publisher.class, ByteBuffer.class),
89-
null, Collections.emptyMap());
90-
91-
StepVerifier.create(output)
92-
.expectNext(ByteBuffer.wrap("foobar".getBytes()))
93-
.expectComplete()
94-
.verify();
75+
Flux<DataBuffer> input = Flux.concat(
76+
dataBuffer(this.fooBytes),
77+
dataBuffer(this.barBytes));
78+
ByteBuffer expected = ByteBuffer.allocate(this.fooBytes.length + this.barBytes.length);
79+
expected.put(this.fooBytes).put(this.barBytes).flip();
80+
81+
testDecodeToMonoAll(input, ByteBuffer.class, step -> step
82+
.consumeNextWith(expectByteBuffer(expected))
83+
.verifyComplete());
84+
9585
}
86+
87+
private Consumer<ByteBuffer> expectByteBuffer(ByteBuffer expected) {
88+
return actual -> assertEquals(expected, actual);
89+
}
90+
9691
}

spring-core/src/test/java/org/springframework/core/codec/DataBufferDecoderTests.java

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,33 @@
1717
package org.springframework.core.codec;
1818

1919
import java.nio.charset.StandardCharsets;
20-
import java.time.Duration;
21-
import java.util.Collections;
20+
import java.util.function.Consumer;
2221

2322
import org.junit.Test;
24-
import org.reactivestreams.Publisher;
2523
import reactor.core.publisher.Flux;
26-
import reactor.core.publisher.Mono;
2724

2825
import org.springframework.core.ResolvableType;
29-
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
3026
import org.springframework.core.io.buffer.DataBuffer;
31-
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
27+
import org.springframework.core.io.buffer.DataBufferUtils;
3228
import org.springframework.util.MimeTypeUtils;
3329

3430
import static org.junit.Assert.*;
3531

3632
/**
3733
* @author Sebastien Deleuze
3834
*/
39-
public class DataBufferDecoderTests extends AbstractDataBufferAllocatingTestCase {
35+
public class DataBufferDecoderTests extends AbstractDecoderTestCase<DataBufferDecoder> {
4036

41-
private final DataBufferDecoder decoder = new DataBufferDecoder();
37+
private final byte[] fooBytes = "foo".getBytes(StandardCharsets.UTF_8);
4238

39+
private final byte[] barBytes = "bar".getBytes(StandardCharsets.UTF_8);
40+
41+
42+
public DataBufferDecoderTests() {
43+
super(new DataBufferDecoder());
44+
}
45+
46+
@Override
4347
@Test
4448
public void canDecode() {
4549
assertTrue(this.decoder.canDecode(ResolvableType.forClass(DataBuffer.class),
@@ -50,33 +54,40 @@ public void canDecode() {
5054
MimeTypeUtils.APPLICATION_JSON));
5155
}
5256

53-
@Test
57+
@Override
5458
public void decode() {
55-
DataBuffer fooBuffer = stringBuffer("foo");
56-
DataBuffer barBuffer = stringBuffer("bar");
57-
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
58-
Flux<DataBuffer> output = this.decoder.decode(source,
59-
ResolvableType.forClassWithGenerics(Publisher.class, DataBuffer.class),
60-
null, Collections.emptyMap());
61-
62-
assertSame(source, output);
59+
Flux<DataBuffer> input = Flux.just(
60+
this.bufferFactory.wrap(this.fooBytes),
61+
this.bufferFactory.wrap(this.barBytes));
6362

64-
release(fooBuffer, barBuffer);
63+
testDecodeAll(input, DataBuffer.class, step -> step
64+
.consumeNextWith(expectDataBuffer(this.fooBytes))
65+
.consumeNextWith(expectDataBuffer(this.barBytes))
66+
.verifyComplete());
6567
}
6668

67-
@Test
68-
public void decodeToMono() {
69-
DataBuffer fooBuffer = stringBuffer("foo");
70-
DataBuffer barBuffer = stringBuffer("bar");
71-
Flux<DataBuffer> source = Flux.just(fooBuffer, barBuffer);
72-
Mono<DataBuffer> output = this.decoder.decodeToMono(source,
73-
ResolvableType.forClassWithGenerics(Publisher.class, DataBuffer.class),
74-
null, Collections.emptyMap());
75-
76-
DataBuffer outputBuffer = output.block(Duration.ofSeconds(5));
77-
assertEquals("foobar", DataBufferTestUtils.dumpString(outputBuffer, StandardCharsets.UTF_8));
78-
79-
release(outputBuffer);
69+
@Override
70+
public void decodeToMono() throws Exception {
71+
Flux<DataBuffer> input = Flux.concat(
72+
dataBuffer(this.fooBytes),
73+
dataBuffer(this.barBytes));
74+
75+
byte[] expected = new byte[this.fooBytes.length + this.barBytes.length];
76+
System.arraycopy(this.fooBytes, 0, expected, 0, this.fooBytes.length);
77+
System.arraycopy(this.barBytes, 0, expected, this.fooBytes.length, this.barBytes.length);
78+
79+
testDecodeToMonoAll(input, DataBuffer.class, step -> step
80+
.consumeNextWith(expectDataBuffer(expected))
81+
.verifyComplete());
8082
}
8183

84+
private Consumer<DataBuffer> expectDataBuffer(byte[] expected) {
85+
return actual -> {
86+
byte[] actualBytes = new byte[actual.readableByteCount()];
87+
actual.read(actualBytes);
88+
assertArrayEquals(expected, actualBytes);
89+
90+
DataBufferUtils.release(actual);
91+
};
92+
}
8293
}

0 commit comments

Comments
 (0)