7 #include <CoreFoundation/CoreFoundation.h>
9 #include "gtest/gtest.h"
14 @property(atomic, readonly, strong, nullable) NSObject*
left;
15 @property(atomic, readonly, strong, nullable) NSObject*
right;
16 - (instancetype)initWithLeft:(NSObject*)first right:(NSObject*)right;
20 - (instancetype)initWithLeft:(NSObject*)left right:(NSObject*)right {
34 - (void)writeValue:(
id)value;
38 - (void)writeValue:(
id)value {
39 if ([value isKindOfClass:[NSDate
class]]) {
42 NSTimeInterval time = date.timeIntervalSince1970;
43 SInt64 ms = (SInt64)(time * 1000.0);
45 }
else if ([value isKindOfClass:[
Pair class]]) {
57 - (id)readValueOfType:(UInt8)type;
61 - (id)readValueOfType:(UInt8)type {
66 NSTimeInterval time = [NSNumber numberWithLong:value].doubleValue / 1000.0;
67 return [NSDate dateWithTimeIntervalSince1970:time];
94 NSData* encoded = [codec
encode:value];
95 if (expectedEncoding == nil) {
96 ASSERT_TRUE(encoded == nil);
98 ASSERT_TRUE([encoded isEqual:expectedEncoding]);
100 id decoded = [codec
decode:encoded];
101 if (value == nil || value == [NSNull
null]) {
102 ASSERT_TRUE(decoded == nil);
104 ASSERT_TRUE([value isEqual:decoded]);
110 NSData* encoded = [codec
encode:value];
111 id decoded = [codec
decode:encoded];
112 if (value == nil || value == [NSNull
null]) {
113 ASSERT_TRUE(decoded == nil);
115 ASSERT_TRUE([value isEqual:decoded]);
119 TEST(FlutterStandardCodec, CanDecodeZeroLength) {
121 id decoded = [codec
decode:[NSData data]];
122 ASSERT_TRUE(decoded == nil);
125 TEST(FlutterStandardCodec, CanEncodeAndDecodeNil) {
129 TEST(FlutterStandardCodec, CanEncodeAndDecodeNSNull) {
130 uint8_t bytes[1] = {0x00};
134 TEST(FlutterStandardCodec, CanEncodeAndDecodeYes) {
135 uint8_t bytes[1] = {0x01};
139 TEST(FlutterStandardCodec, CanEncodeAndDecodeNo) {
140 uint8_t bytes[1] = {0x02};
144 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt8) {
145 uint8_t bytes[5] = {0x03, 0xfe, 0x00, 0x00, 0x00};
150 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt16) {
151 uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0x00, 0x00};
152 UInt16 value = 0xfedc;
156 TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt32) {
157 uint8_t bytes[9] = {0x04, 0x09, 0xba, 0xdc, 0xfe, 0x00, 0x00, 0x00, 0x00};
158 UInt32 value = 0xfedcba09;
162 TEST(FlutterStandardCodec, CanEncodeUInt64) {
164 UInt64 u64 = 0xfffffffffffffffa;
165 uint8_t bytes[9] = {0x04, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
166 NSData* encoded = [codec
encode:@(u64)];
167 ASSERT_TRUE([encoded isEqual:[NSData dataWithBytes:bytes length:9]]);
170 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt8) {
171 uint8_t bytes[5] = {0x03, 0xfe, 0xff, 0xff, 0xff};
176 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt16) {
177 uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0xff, 0xff};
178 SInt16 value = 0xfedc;
182 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt32) {
183 uint8_t bytes[5] = {0x03, 0x78, 0x56, 0x34, 0x12};
187 TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt64) {
188 uint8_t bytes[9] = {0x04, 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12};
192 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32) {
193 uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x60, 0xfb, 0x21, 0x09, 0x40};
198 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64) {
199 uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40};
201 CheckEncodeDecode(@3.14159265358979311599796346854, [NSData dataWithBytes:bytes length:16]);
204 TEST(FlutterStandardCodec, CanEncodeAndDecodeString) {
205 uint8_t bytes[13] = {0x07, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
206 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
210 TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
211 uint8_t bytes[7] = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
215 TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonBMPCodePoint) {
216 uint8_t bytes[8] = {0x07, 0x06, 0x68, 0xf0, 0x9f, 0x98, 0x82, 0x77};
220 TEST(FlutterStandardCodec, CanEncodeAndDecodeIndirectString) {
225 uint8_t bytes[7] = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
226 NSString* target =
@"h\u263Aw";
228 ASSERT_TRUE(CFStringGetCStringPtr((__bridge CFStringRef)target, kCFStringEncodingUTF8) ==
233 TEST(FlutterStandardCodec, CanEncodeAndDecodeArray) {
234 NSArray* value = @[ [NSNull null], @"hello", @3.14, @47, @{@42 : @"nested"} ];
238 TEST(FlutterStandardCodec, CanEncodeAndDecodeDictionary) {
239 NSDictionary* value =
242 [NSNull null] : [NSNull null],
243 @3.14 : @[ @"nested" ]};
247 TEST(FlutterStandardCodec, CanEncodeAndDecodeByteArray) {
248 uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
249 NSData* data = [NSData dataWithBytes:bytes length:4];
254 TEST(FlutterStandardCodec, CanEncodeAndDecodeNSData) {
256 uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
257 NSData* data = [NSData dataWithBytes:bytes length:4];
260 NSData* encoded = [codec
encode:data];
261 ASSERT_TRUE([encoded isEqual:[codec encode:standardData]]);
264 TEST(FlutterStandardCodec, CanEncodeAndDecodeInt32Array) {
265 uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
266 NSData* data = [NSData dataWithBytes:bytes length:8];
271 TEST(FlutterStandardCodec, CanEncodeAndDecodeInt64Array) {
272 uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
273 NSData* data = [NSData dataWithBytes:bytes length:8];
278 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32Array) {
279 uint8_t bytes[8] = {0xd8, 0x0f, 0x49, 0x40, 0x00, 0x00, 0x7a, 0x44};
280 NSData* data = [NSData dataWithBytes:bytes length:8];
285 TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64Array) {
286 uint8_t bytes[16] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff,
287 0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
288 NSData* data = [NSData dataWithBytes:bytes length:16];
293 TEST(FlutterStandardCodec, HandlesMethodCallsWithNilArguments) {
296 NSData* encoded = [codec encodeMethodCall:call];
298 ASSERT_TRUE([decoded isEqual:call]);
301 TEST(FlutterStandardCodec, HandlesMethodCallsWithSingleArgument) {
304 NSData* encoded = [codec encodeMethodCall:call];
306 ASSERT_TRUE([decoded isEqual:call]);
309 TEST(FlutterStandardCodec, HandlesMethodCallsWithArgumentList) {
311 NSArray* arguments = @[ @42, @"world" ];
314 NSData* encoded = [codec encodeMethodCall:call];
316 ASSERT_TRUE([decoded isEqual:call]);
319 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithNilResult) {
321 NSData* encoded = [codec encodeSuccessEnvelope:nil];
322 id decoded = [codec decodeEnvelope:encoded];
323 ASSERT_TRUE(decoded == nil);
326 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithSingleResult) {
328 NSData* encoded = [codec encodeSuccessEnvelope:@42];
329 id decoded = [codec decodeEnvelope:encoded];
330 ASSERT_TRUE([decoded isEqual:@42]);
333 TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithResultMap) {
335 NSDictionary* result = @{
@"a" : @42, @42 :
@"a"};
336 NSData* encoded = [codec encodeSuccessEnvelope:result];
337 id decoded = [codec decodeEnvelope:encoded];
338 ASSERT_TRUE([decoded isEqual:result]);
341 TEST(FlutterStandardCodec, HandlesErrorEnvelopes) {
343 NSDictionary* details = @{
@"a" : @42, @42 :
@"a"};
347 NSData* encoded = [codec encodeErrorEnvelope:error];
348 id decoded = [codec decodeEnvelope:encoded];
349 ASSERT_TRUE([decoded isEqual:error]);
352 TEST(FlutterStandardCodec, HandlesSubclasses) {
356 Pair* pair = [[
Pair alloc] initWithLeft:@1 right:@2];
357 NSData* encoded = [codec
encode:pair];
359 ASSERT_TRUE([pair.
left isEqual:decoded.
left]);
360 ASSERT_TRUE([pair.
right isEqual:decoded.
right]);