1
1
package io .flutter .plugin .common ;
2
2
3
3
import static org .mockito .ArgumentMatchers .anyInt ;
4
+ import static org .mockito .ArgumentMatchers .argThat ;
4
5
import static org .mockito .ArgumentMatchers .eq ;
5
6
import static org .mockito .Mockito .mock ;
6
7
import static org .mockito .Mockito .times ;
11
12
import io .flutter .embedding .engine .FlutterJNI ;
12
13
import io .flutter .embedding .engine .dart .DartExecutor ;
13
14
import java .nio .ByteBuffer ;
14
- import java .nio .charset .Charset ;
15
- import java .util .Locale ;
16
15
import org .junit .Test ;
17
16
import org .junit .runner .RunWith ;
17
+ import org .mockito .ArgumentMatcher ;
18
18
import org .robolectric .annotation .Config ;
19
19
20
20
@ Config (manifest = Config .NONE )
21
21
@ RunWith (AndroidJUnit4 .class )
22
22
public class MethodChannelTest {
23
23
@ Test
24
- public void methodChannel_resizeChannelBuffer () {
24
+ public void resizeChannelBufferMessageIsWellformed () {
25
25
FlutterJNI mockFlutterJNI = mock (FlutterJNI .class );
26
26
DartExecutor dartExecutor = new DartExecutor (mockFlutterJNI , mock (AssetManager .class ));
27
27
String channel = "flutter/test" ;
@@ -30,15 +30,68 @@ public void methodChannel_resizeChannelBuffer() {
30
30
int newSize = 3 ;
31
31
rawChannel .resizeChannelBuffer (newSize );
32
32
33
- Charset charset = Charset .forName ("UTF-8" );
34
- String messageString = String .format (Locale .US , "resize\r %s\r %d" , channel , newSize );
35
- final byte [] bytes = messageString .getBytes (charset );
36
- ByteBuffer packet = ByteBuffer .allocateDirect (bytes .length );
37
- packet .put (bytes );
33
+ // Created from the following Dart code:
34
+ // MethodCall methodCall = const MethodCall('resize', ['flutter/test', 3]);
35
+ // const StandardMethodCodec().encodeMethodCall(methodCall).buffer.asUint8List();
36
+ final byte [] expected = {
37
+ 7 , 6 , 114 , 101 , 115 , 105 , 122 , 101 , 12 , 2 , 7 , 12 , 102 , 108 , 117 , 116 , 116 , 101 , 114 , 47 , 116 ,
38
+ 101 , 115 , 116 , 3 , 3 , 0 , 0 , 0
39
+ };
38
40
39
- // Verify that DartExecutor sent the correct message to FlutterJNI.
41
+ // Verify that the correct message was sent to FlutterJNI.
42
+ ArgumentMatcher <ByteBuffer > packetMatcher =
43
+ new ByteBufferContentMatcher (ByteBuffer .wrap (expected ));
40
44
verify (mockFlutterJNI , times (1 ))
41
45
.dispatchPlatformMessage (
42
- eq (BasicMessageChannel .CHANNEL_BUFFERS_CHANNEL ), eq (packet ), anyInt (), anyInt ());
46
+ eq (BasicMessageChannel .CHANNEL_BUFFERS_CHANNEL ),
47
+ argThat (packetMatcher ),
48
+ anyInt (),
49
+ anyInt ());
50
+ }
51
+
52
+ @ Test
53
+ public void overflowChannelBufferMessageIsWellformed () {
54
+ FlutterJNI mockFlutterJNI = mock (FlutterJNI .class );
55
+ DartExecutor dartExecutor = new DartExecutor (mockFlutterJNI , mock (AssetManager .class ));
56
+ String channel = "flutter/test" ;
57
+ MethodChannel rawChannel = new MethodChannel (dartExecutor , channel );
58
+
59
+ rawChannel .allowChannelBufferOverflow (true );
60
+
61
+ // Created from the following Dart code:
62
+ // MethodCall methodCall = const MethodCall('overflow', ['flutter/test', true]);
63
+ // const StandardMethodCodec().encodeMethodCall(methodCall).buffer.asUint8List();
64
+ final byte [] expected = {
65
+ 7 , 8 , 111 , 118 , 101 , 114 , 102 , 108 , 111 , 119 , 12 , 2 , 7 , 12 , 102 , 108 , 117 , 116 , 116 , 101 , 114 ,
66
+ 47 , 116 , 101 , 115 , 116 , 1
67
+ };
68
+
69
+ // Verify that the correct message was sent to FlutterJNI.
70
+ ArgumentMatcher <ByteBuffer > packetMatcher =
71
+ new ByteBufferContentMatcher (ByteBuffer .wrap (expected ));
72
+ verify (mockFlutterJNI , times (1 ))
73
+ .dispatchPlatformMessage (
74
+ eq (BasicMessageChannel .CHANNEL_BUFFERS_CHANNEL ),
75
+ argThat (packetMatcher ),
76
+ anyInt (),
77
+ anyInt ());
78
+ }
79
+ }
80
+
81
+ // Custom ByteBuffer matcher which calls rewind on both buffers before calling equals.
82
+ // ByteBuffer.equals might return true when comparing byte buffers with different content if
83
+ // both have no remaining elements.
84
+ class ByteBufferContentMatcher implements ArgumentMatcher <ByteBuffer > {
85
+ private ByteBuffer expected ;
86
+
87
+ public ByteBufferContentMatcher (ByteBuffer expected ) {
88
+ this .expected = expected ;
89
+ }
90
+
91
+ @ Override
92
+ public boolean matches (ByteBuffer received ) {
93
+ expected .rewind ();
94
+ received .rewind ();
95
+ return received .equals (expected );
43
96
}
44
97
}
0 commit comments