17
17
18
18
import static com .google .common .truth .Truth .assertThat ;
19
19
import static org .junit .Assert .fail ;
20
+ import static org .junit .Assume .assumeTrue ;
20
21
21
22
import com .google .gson .Gson ;
22
23
import com .google .gson .GsonBuilder ;
25
26
import com .google .gson .stream .JsonReader ;
26
27
import com .google .gson .stream .JsonToken ;
27
28
import com .google .gson .stream .JsonWriter ;
29
+ import com .google .testing .junit .testparameterinjector .TestParameter ;
30
+ import com .google .testing .junit .testparameterinjector .TestParameterInjector ;
31
+ import java .io .EOFException ;
28
32
import java .io .IOException ;
33
+ import java .util .concurrent .CountDownLatch ;
34
+ import java .util .concurrent .atomic .AtomicReference ;
29
35
import okhttp3 .mockwebserver .MockResponse ;
30
36
import okhttp3 .mockwebserver .MockWebServer ;
31
37
import okhttp3 .mockwebserver .RecordedRequest ;
32
- import org .junit .Before ;
33
38
import org .junit .Rule ;
34
39
import org .junit .Test ;
40
+ import org .junit .runner .RunWith ;
35
41
import retrofit2 .Call ;
42
+ import retrofit2 .Callback ;
36
43
import retrofit2 .Response ;
37
44
import retrofit2 .Retrofit ;
38
45
import retrofit2 .http .Body ;
39
46
import retrofit2 .http .GET ;
40
47
import retrofit2 .http .POST ;
41
48
49
+ @ RunWith (TestParameterInjector .class )
42
50
public final class GsonConverterFactoryTest {
43
51
interface AnInterface {
44
52
String getName ();
@@ -57,27 +65,27 @@ public String getName() {
57
65
}
58
66
}
59
67
60
- static final class Value {
61
- static final TypeAdapter <Value > BROKEN_ADAPTER =
62
- new TypeAdapter <Value >() {
68
+ static final class ErroringValue {
69
+ static final TypeAdapter <ErroringValue > BROKEN_ADAPTER =
70
+ new TypeAdapter <ErroringValue >() {
63
71
@ Override
64
- public void write (JsonWriter out , Value value ) {
65
- throw new AssertionError ( );
72
+ public void write (JsonWriter out , ErroringValue value ) throws IOException {
73
+ throw new EOFException ( "oops!" );
66
74
}
67
75
68
76
@ Override
69
77
@ SuppressWarnings ("CheckReturnValue" )
70
- public Value read (JsonReader reader ) throws IOException {
78
+ public ErroringValue read (JsonReader reader ) throws IOException {
71
79
reader .beginObject ();
72
80
reader .nextName ();
73
81
String theName = reader .nextString ();
74
- return new Value (theName );
82
+ return new ErroringValue (theName );
75
83
}
76
84
};
77
85
78
86
final String theName ;
79
87
80
- Value (String theName ) {
88
+ ErroringValue (String theName ) {
81
89
this .theName = theName ;
82
90
}
83
91
}
@@ -116,25 +124,36 @@ interface Service {
116
124
Call <AnInterface > anInterface (@ Body AnInterface impl );
117
125
118
126
@ GET ("/" )
119
- Call <Value > value ();
127
+ Call <ErroringValue > readErroringValue ();
128
+
129
+ @ POST ("/" )
130
+ Call <Void > writeErroringValue (@ Body ErroringValue value );
120
131
}
121
132
122
133
@ Rule public final MockWebServer server = new MockWebServer ();
123
134
124
- private Service service ;
135
+ private final boolean streaming ;
136
+ private final Service service ;
137
+
138
+ public GsonConverterFactoryTest (@ TestParameter boolean streaming ) {
139
+ this .streaming = streaming ;
125
140
126
- @ Before
127
- public void setUp () {
128
141
Gson gson =
129
142
new GsonBuilder ()
130
143
.registerTypeAdapter (AnInterface .class , new AnInterfaceAdapter ())
131
- .registerTypeAdapter (Value .class , Value .BROKEN_ADAPTER )
144
+ .registerTypeAdapter (ErroringValue .class , ErroringValue .BROKEN_ADAPTER )
132
145
.setLenient ()
133
146
.create ();
147
+
148
+ GsonConverterFactory factory = GsonConverterFactory .create (gson );
149
+ if (streaming ) {
150
+ factory = factory .withStreaming ();
151
+ }
152
+
134
153
Retrofit retrofit =
135
- new Retrofit .Builder ()
136
- .baseUrl (server .url ("/" ))
137
- .addConverterFactory (GsonConverterFactory . create ( gson ))
154
+ new Retrofit .Builder () //
155
+ .baseUrl (server .url ("/" )) //
156
+ .addConverterFactory (factory ) //
138
157
.build ();
139
158
service = retrofit .create (Service .class );
140
159
}
@@ -191,12 +210,42 @@ public void deserializeUsesConfiguration() throws IOException, InterruptedExcept
191
210
public void requireFullResponseDocumentConsumption () throws Exception {
192
211
server .enqueue (new MockResponse ().setBody ("{\" theName\" :\" value\" }" ));
193
212
194
- Call <Value > call = service .value ();
213
+ Call <ErroringValue > call = service .readErroringValue ();
195
214
try {
196
215
call .execute ();
197
216
fail ();
198
217
} catch (JsonIOException e ) {
199
218
assertThat (e ).hasMessageThat ().isEqualTo ("JSON document was not fully consumed." );
200
219
}
201
220
}
221
+
222
+ @ Test
223
+ public void serializeIsStreamed () throws InterruptedException {
224
+ assumeTrue (streaming );
225
+
226
+ Call <Void > call = service .writeErroringValue (new ErroringValue ("hi" ));
227
+
228
+ final AtomicReference <Throwable > throwableRef = new AtomicReference <>();
229
+ final CountDownLatch latch = new CountDownLatch (1 );
230
+
231
+ // If streaming were broken, the call to enqueue would throw the exception synchronously.
232
+ call .enqueue (
233
+ new Callback <Void >() {
234
+ @ Override
235
+ public void onResponse (Call <Void > call , Response <Void > response ) {
236
+ latch .countDown ();
237
+ }
238
+
239
+ @ Override
240
+ public void onFailure (Call <Void > call , Throwable t ) {
241
+ throwableRef .set (t );
242
+ latch .countDown ();
243
+ }
244
+ });
245
+ latch .await ();
246
+
247
+ Throwable throwable = throwableRef .get ();
248
+ assertThat (throwable ).isInstanceOf (EOFException .class );
249
+ assertThat (throwable ).hasMessageThat ().isEqualTo ("oops!" );
250
+ }
202
251
}
0 commit comments