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 static 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  }
17  id decoded = [codec decode:encoded];
18  if (value == nil || value == [NSNull null]) {
19  ASSERT_TRUE(decoded == nil);
20  } else {
21  ASSERT_TRUE([value isEqual:decoded]);
22  }
23 }
24 
25 static void CheckEncodeDecode(id value) {
27  NSData* encoded = [codec encode:value];
28  id decoded = [codec decode:encoded];
29  if (value == nil || value == [NSNull null]) {
30  ASSERT_TRUE(decoded == nil);
31  } else {
32  ASSERT_TRUE([value isEqual:decoded]);
33  }
34 }
35 
36 TEST(FlutterStandardCodec, CanDecodeZeroLength) {
38  id decoded = [codec decode:[NSData data]];
39  ASSERT_TRUE(decoded == nil);
40 }
41 
42 TEST(FlutterStandardCodec, CanEncodeAndDecodeNil) {
43  CheckEncodeDecode(nil, nil);
44 }
45 
46 TEST(FlutterStandardCodec, CanEncodeAndDecodeNSNull) {
47  uint8_t bytes[1] = {0x00};
48  CheckEncodeDecode([NSNull null], [NSData dataWithBytes:bytes length:1]);
49 }
50 
51 TEST(FlutterStandardCodec, CanEncodeAndDecodeYes) {
52  uint8_t bytes[1] = {0x01};
53  CheckEncodeDecode(@YES, [NSData dataWithBytes:bytes length:1]);
54 }
55 
56 TEST(FlutterStandardCodec, CanEncodeAndDecodeNo) {
57  uint8_t bytes[1] = {0x02};
58  CheckEncodeDecode(@NO, [NSData dataWithBytes:bytes length:1]);
59 }
60 
61 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt8) {
62  uint8_t bytes[5] = {0x03, 0xfe, 0x00, 0x00, 0x00};
63  UInt8 value = 0xfe;
64  CheckEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
65 }
66 
67 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt16) {
68  uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0x00, 0x00};
69  UInt16 value = 0xfedc;
70  CheckEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
71 }
72 
73 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt32) {
74  uint8_t bytes[9] = {0x04, 0x09, 0xba, 0xdc, 0xfe, 0x00, 0x00, 0x00, 0x00};
75  UInt32 value = 0xfedcba09;
76  CheckEncodeDecode(@(value), [NSData dataWithBytes:bytes length:9]);
77 }
78 
79 TEST(FlutterStandardCodec, CanEncodeUInt64) {
81  UInt64 u64 = 0xfffffffffffffffa;
82  uint8_t bytes[9] = {0x04, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
83  NSData* encoded = [codec encode:@(u64)];
84  ASSERT_TRUE([encoded isEqual:[NSData dataWithBytes:bytes length:9]]);
85 }
86 
87 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt8) {
88  uint8_t bytes[5] = {0x03, 0xfe, 0xff, 0xff, 0xff};
89  SInt8 value = 0xfe;
90  CheckEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
91 }
92 
93 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt16) {
94  uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0xff, 0xff};
95  SInt16 value = 0xfedc;
96  CheckEncodeDecode(@(value), [NSData dataWithBytes:bytes length:5]);
97 }
98 
99 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt32) {
100  uint8_t bytes[5] = {0x03, 0x78, 0x56, 0x34, 0x12};
101  CheckEncodeDecode(@(0x12345678), [NSData dataWithBytes:bytes length:5]);
102 }
103 
104 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt64) {
105  uint8_t bytes[9] = {0x04, 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12};
106  CheckEncodeDecode(@(0x1234567890abcdef), [NSData dataWithBytes:bytes length:9]);
107 }
108 
109 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32) {
110  uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111  0x00, 0x00, 0x00, 0x60, 0xfb, 0x21, 0x09, 0x40};
112  CheckEncodeDecode(@3.1415927f, [NSData dataWithBytes:bytes length:16]);
113 }
114 
115 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64) {
116  uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117  0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40};
118  CheckEncodeDecode(@3.14159265358979311599796346854, [NSData dataWithBytes:bytes length:16]);
119 }
120 
121 TEST(FlutterStandardCodec, CanEncodeAndDecodeString) {
122  uint8_t bytes[13] = {0x07, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
123  0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
124  CheckEncodeDecode(@"hello world", [NSData dataWithBytes:bytes length:13]);
125 }
126 
127 TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
128  uint8_t bytes[7] = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
129  CheckEncodeDecode(@"h\u263Aw", [NSData dataWithBytes:bytes length:7]);
130 }
131 
132 TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonBMPCodePoint) {
133  uint8_t bytes[8] = {0x07, 0x06, 0x68, 0xf0, 0x9f, 0x98, 0x82, 0x77};
134  CheckEncodeDecode(@"h\U0001F602w", [NSData dataWithBytes:bytes length:8]);
135 }
136 
137 TEST(FlutterStandardCodec, CanEncodeAndDecodeArray) {
138  NSArray* value = @[ [NSNull null], @"hello", @3.14, @47, @{@42 : @"nested"} ];
139  CheckEncodeDecode(value);
140 }
141 
142 TEST(FlutterStandardCodec, CanEncodeAndDecodeDictionary) {
143  NSDictionary* value =
144  @{@"a" : @3.14,
145  @"b" : @47,
146  [NSNull null] : [NSNull null],
147  @3.14 : @[ @"nested" ]};
148  CheckEncodeDecode(value);
149 }
150 
151 TEST(FlutterStandardCodec, CanEncodeAndDecodeByteArray) {
152  uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
153  NSData* data = [NSData dataWithBytes:bytes length:4];
155  CheckEncodeDecode(value);
156 }
157 
158 TEST(FlutterStandardCodec, CanEncodeAndDecodeNSData) {
160  uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
161  NSData* data = [NSData dataWithBytes:bytes length:4];
162  FlutterStandardTypedData* standardData = [FlutterStandardTypedData typedDataWithBytes:data];
163 
164  NSData* encoded = [codec encode:data];
165  ASSERT_TRUE([encoded isEqual:[codec encode:standardData]]);
166 }
167 
168 TEST(FlutterStandardCodec, CanEncodeAndDecodeInt32Array) {
169  uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
170  NSData* data = [NSData dataWithBytes:bytes length:8];
172  CheckEncodeDecode(value);
173 }
174 
175 TEST(FlutterStandardCodec, CanEncodeAndDecodeInt64Array) {
176  uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
177  NSData* data = [NSData dataWithBytes:bytes length:8];
179  CheckEncodeDecode(value);
180 }
181 
182 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32Array) {
183  uint8_t bytes[8] = {0xd8, 0x0f, 0x49, 0x40, 0x00, 0x00, 0x7a, 0x44};
184  NSData* data = [NSData dataWithBytes:bytes length:8];
186  CheckEncodeDecode(value);
187 }
188 
189 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64Array) {
190  uint8_t bytes[16] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff,
191  0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
192  NSData* data = [NSData dataWithBytes:bytes length:16];
194  CheckEncodeDecode(value);
195 }
196 
197 TEST(FlutterStandardCodec, HandlesMethodCallsWithNilArguments) {
198  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
199  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"hello" arguments:nil];
200  NSData* encoded = [codec encodeMethodCall:call];
201  FlutterMethodCall* decoded = [codec decodeMethodCall:encoded];
202  ASSERT_TRUE([decoded isEqual:call]);
203 }
204 
205 TEST(FlutterStandardCodec, HandlesMethodCallsWithSingleArgument) {
206  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
207  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"hello" arguments:@42];
208  NSData* encoded = [codec encodeMethodCall:call];
209  FlutterMethodCall* decoded = [codec decodeMethodCall:encoded];
210  ASSERT_TRUE([decoded isEqual:call]);
211 }
212 
213 TEST(FlutterStandardCodec, HandlesMethodCallsWithArgumentList) {
214  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
215  NSArray* arguments = @[ @42, @"world" ];
216  FlutterMethodCall* call = [FlutterMethodCall methodCallWithMethodName:@"hello"
217  arguments:arguments];
218  NSData* encoded = [codec encodeMethodCall:call];
219  FlutterMethodCall* decoded = [codec decodeMethodCall:encoded];
220  ASSERT_TRUE([decoded isEqual:call]);
221 }
222 
223 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithNilResult) {
224  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
225  NSData* encoded = [codec encodeSuccessEnvelope:nil];
226  id decoded = [codec decodeEnvelope:encoded];
227  ASSERT_TRUE(decoded == nil);
228 }
229 
230 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithSingleResult) {
231  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
232  NSData* encoded = [codec encodeSuccessEnvelope:@42];
233  id decoded = [codec decodeEnvelope:encoded];
234  ASSERT_TRUE([decoded isEqual:@42]);
235 }
236 
237 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithResultMap) {
238  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
239  NSDictionary* result = @{@"a" : @42, @42 : @"a"};
240  NSData* encoded = [codec encodeSuccessEnvelope:result];
241  id decoded = [codec decodeEnvelope:encoded];
242  ASSERT_TRUE([decoded isEqual:result]);
243 }
244 
245 TEST(FlutterStandardCodec, HandlesErrorEnvelopes) {
246  FlutterStandardMethodCodec* codec = [FlutterStandardMethodCodec sharedInstance];
247  NSDictionary* details = @{@"a" : @42, @42 : @"a"};
248  FlutterError* error = [FlutterError errorWithCode:@"errorCode"
249  message:@"something failed"
250  details:details];
251  NSData* encoded = [codec encodeErrorEnvelope:error];
252  id decoded = [codec decodeEnvelope:encoded];
253  ASSERT_TRUE([decoded isEqual:error]);
254 }
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition: switches.h:41
uint8_t value
size_t length
TEST(FlutterStandardCodec, CanDecodeZeroLength)
static void CheckEncodeDecode(id value, NSData *expectedEncoding)