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