Flutter Engine
flutter_standard_codec_unittest.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
6 
7 #include "gtest/gtest.h"
8 
9 void checkEncodeDecode(id value, NSData* expectedEncoding) {
11  NSData* encoded = [codec encode:value];
12  if (expectedEncoding == nil)
13  ASSERT_TRUE(encoded == nil);
14  else
15  ASSERT_TRUE([encoded isEqual:expectedEncoding]);
16  id decoded = [codec decode:encoded];
17  if (value == nil || value == [NSNull null])
18  ASSERT_TRUE(decoded == nil);
19  else
20  ASSERT_TRUE([value isEqual:decoded]);
21 }
22 
25  NSData* encoded = [codec encode:value];
26  id decoded = [codec decode:encoded];
27  if (value == nil || value == [NSNull null])
28  ASSERT_TRUE(decoded == nil);
29  else
30  ASSERT_TRUE([value isEqual:decoded]);
31 }
32 
33 TEST(FlutterStandardCodec, CanEncodeAndDecodeNil) {
34  checkEncodeDecode(nil, nil);
35 }
36 
37 TEST(FlutterStandardCodec, CanEncodeAndDecodeNSNull) {
38  uint8_t bytes[1] = {0x00};
39  checkEncodeDecode([NSNull null], [NSData dataWithBytes:bytes length:1]);
40 }
41 
42 TEST(FlutterStandardCodec, CanEncodeAndDecodeYes) {
43  uint8_t bytes[1] = {0x01};
44  checkEncodeDecode(@YES, [NSData dataWithBytes:bytes length:1]);
45 }
46 
47 TEST(FlutterStandardCodec, CanEncodeAndDecodeNo) {
48  uint8_t bytes[1] = {0x02};
49  checkEncodeDecode(@NO, [NSData dataWithBytes:bytes length:1]);
50 }
51 
52 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt8) {
53  uint8_t bytes[5] = {0x03, 0xfe, 0x00, 0x00, 0x00};
54  UInt8 value = 0xfe;
55  checkEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
56 }
57 
58 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt16) {
59  uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0x00, 0x00};
60  UInt16 value = 0xfedc;
61  checkEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
62 }
63 
64 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt32) {
65  uint8_t bytes[9] = {0x04, 0x09, 0xba, 0xdc, 0xfe, 0x00, 0x00, 0x00, 0x00};
66  UInt32 value = 0xfedcba09;
67  checkEncodeDecode(@(value), [NSData dataWithBytes:bytes length:9]);
68 }
69 
70 TEST(FlutterStandardCodec, CanEncodeUInt64) {
72  UInt64 u64 = 0xfffffffffffffffa;
73  uint8_t bytes[9] = {0x04, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
74  NSData* encoded = [codec encode:@(u64)];
75  ASSERT_TRUE([encoded isEqual:[NSData dataWithBytes:bytes length:9]]);
76 }
77 
78 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt8) {
79  uint8_t bytes[5] = {0x03, 0xfe, 0xff, 0xff, 0xff};
80  SInt8 value = 0xfe;
81  checkEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
82 }
83 
84 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt16) {
85  uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0xff, 0xff};
86  SInt16 value = 0xfedc;
87  checkEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
88 }
89 
90 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt32) {
91  uint8_t bytes[5] = {0x03, 0x78, 0x56, 0x34, 0x12};
92  checkEncodeDecode(@(0x12345678), [NSData dataWithBytes:bytes length:5]);
93 }
94 
95 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt64) {
96  uint8_t bytes[9] = {0x04, 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12};
97  checkEncodeDecode(@(0x1234567890abcdef), [NSData dataWithBytes:bytes length:9]);
98 }
99 
100 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32) {
101  uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102  0x00, 0x00, 0x00, 0x60, 0xfb, 0x21, 0x09, 0x40};
103  checkEncodeDecode(@3.1415927f, [NSData dataWithBytes:bytes length:16]);
104 }
105 
106 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64) {
107  uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108  0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40};
109  checkEncodeDecode(@3.14159265358979311599796346854, [NSData dataWithBytes:bytes length:16]);
110 }
111 
112 TEST(FlutterStandardCodec, CanEncodeAndDecodeString) {
113  uint8_t bytes[13] = {0x07, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
114  0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
115  checkEncodeDecode(@"hello world", [NSData dataWithBytes:bytes length:13]);
116 }
117 
118 TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
119  uint8_t bytes[7] = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
120  checkEncodeDecode(@"h\u263Aw", [NSData dataWithBytes:bytes length:7]);
121 }
122 
123 TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonBMPCodePoint) {
124  uint8_t bytes[8] = {0x07, 0x06, 0x68, 0xf0, 0x9f, 0x98, 0x82, 0x77};
125  checkEncodeDecode(@"h\U0001F602w", [NSData dataWithBytes:bytes length:8]);
126 }
127 
128 TEST(FlutterStandardCodec, CanEncodeAndDecodeArray) {
129  NSArray* value = @[ [NSNull null], @"hello", @3.14, @47, @{@42 : @"nested"} ];
130  checkEncodeDecode(value);
131 }
132 
133 TEST(FlutterStandardCodec, CanEncodeAndDecodeDictionary) {
134  NSDictionary* value =
135  @{@"a" : @3.14,
136  @"b" : @47,
137  [NSNull null] : [NSNull null],
138  @3.14 : @[ @"nested" ]};
139  checkEncodeDecode(value);
140 }
141 
142 TEST(FlutterStandardCodec, CanEncodeAndDecodeByteArray) {
143  uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
144  NSData* data = [NSData dataWithBytes:bytes length:4];
145  FlutterStandardTypedData* value = [FlutterStandardTypedData typedDataWithBytes:data];
146  checkEncodeDecode(value);
147 }
148 
149 TEST(FlutterStandardCodec, CanEncodeAndDecodeNSData) {
151  uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
152  NSData* data = [NSData dataWithBytes:bytes length:4];
153  FlutterStandardTypedData* standardData = [FlutterStandardTypedData typedDataWithBytes:data];
154 
155  NSData* encoded = [codec encode:data];
156  ASSERT_TRUE([encoded isEqual:[codec encode:standardData]]);
157 }
158 
159 TEST(FlutterStandardCodec, CanEncodeAndDecodeInt32Array) {
160  uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
161  NSData* data = [NSData dataWithBytes:bytes length:8];
162  FlutterStandardTypedData* value = [FlutterStandardTypedData typedDataWithInt32:data];
163  checkEncodeDecode(value);
164 }
165 
166 TEST(FlutterStandardCodec, CanEncodeAndDecodeInt64Array) {
167  uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
168  NSData* data = [NSData dataWithBytes:bytes length:8];
169  FlutterStandardTypedData* value = [FlutterStandardTypedData typedDataWithInt64:data];
170  checkEncodeDecode(value);
171 }
172 
173 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64Array) {
174  uint8_t bytes[16] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff,
175  0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
176  NSData* data = [NSData dataWithBytes:bytes length:16];
177  FlutterStandardTypedData* value = [FlutterStandardTypedData typedDataWithFloat64:data];
178  checkEncodeDecode(value);
179 }
180 
181 TEST(FlutterStandardCodec, HandlesMethodCallsWithNilArguments) {
182  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
183  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"hello" arguments:nil];
184  NSData* encoded = [codec encodeMethodCall:call];
185  FlutterMethodCall* decoded = [codec decodeMethodCall:encoded];
186  ASSERT_TRUE([decoded isEqual:call]);
187 }
188 
189 TEST(FlutterStandardCodec, HandlesMethodCallsWithSingleArgument) {
190  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
191  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"hello" arguments:@42];
192  NSData* encoded = [codec encodeMethodCall:call];
193  FlutterMethodCall* decoded = [codec decodeMethodCall:encoded];
194  ASSERT_TRUE([decoded isEqual:call]);
195 }
196 
197 TEST(FlutterStandardCodec, HandlesMethodCallsWithArgumentList) {
198  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
199  NSArray* arguments = @[ @42, @"world" ];
200  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"hello"
201  arguments:arguments];
202  NSData* encoded = [codec encodeMethodCall:call];
203  FlutterMethodCall* decoded = [codec decodeMethodCall:encoded];
204  ASSERT_TRUE([decoded isEqual:call]);
205 }
206 
207 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithNilResult) {
208  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
209  NSData* encoded = [codec encodeSuccessEnvelope:nil];
210  id decoded = [codec decodeEnvelope:encoded];
211  ASSERT_TRUE(decoded == nil);
212 }
213 
214 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithSingleResult) {
215  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
216  NSData* encoded = [codec encodeSuccessEnvelope:@42];
217  id decoded = [codec decodeEnvelope:encoded];
218  ASSERT_TRUE([decoded isEqual:@42]);
219 }
220 
221 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithResultMap) {
222  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
223  NSDictionary* result = @{@"a" : @42, @42 : @"a"};
224  NSData* encoded = [codec encodeSuccessEnvelope:result];
225  id decoded = [codec decodeEnvelope:encoded];
226  ASSERT_TRUE([decoded isEqual:result]);
227 }
228 
229 TEST(FlutterStandardCodec, HandlesErrorEnvelopes) {
230  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
231  NSDictionary* details = @{@"a" : @42, @42 : @"a"};
232  FlutterError* error = [FlutterError errorWithCode:@"errorCode"
233  message:@"something failed"
234  details:details];
235  NSData* encoded = [codec encodeErrorEnvelope:error];
236  id decoded = [codec decodeEnvelope:encoded];
237  ASSERT_TRUE([decoded isEqual:error]);
238 }
FlMethodResponse GError ** error
uint8_t value
size_t length
TEST(FlutterStandardCodec, CanEncodeAndDecodeNil)
void checkEncodeDecode(id value, NSData *expectedEncoding)