5#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
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];
102 ASSERT_TRUE(decoded == nil);
104 ASSERT_TRUE([
value isEqual:decoded]);
110 NSData* encoded = [codec
encode:value];
111 id decoded = [codec
decode:encoded];
113 ASSERT_TRUE(decoded == nil);
115 ASSERT_TRUE([
value isEqual:decoded]);
119TEST(FlutterStandardCodec, CanDecodeZeroLength) {
121 id decoded = [codec
decode:[NSData data]];
122 ASSERT_TRUE(decoded == nil);
125TEST(FlutterStandardCodec, CanEncodeAndDecodeNil) {
129TEST(FlutterStandardCodec, CanEncodeAndDecodeNSNull) {
130 uint8_t bytes[1] = {0x00};
134TEST(FlutterStandardCodec, CanEncodeAndDecodeYes) {
135 uint8_t bytes[1] = {0x01};
139TEST(FlutterStandardCodec, CanEncodeAndDecodeNo) {
140 uint8_t bytes[1] = {0x02};
144TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt8) {
145 uint8_t bytes[5] = {0x03, 0xfe, 0x00, 0x00, 0x00};
150TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt16) {
151 uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0x00, 0x00};
152 UInt16
value = 0xfedc;
156TEST(FlutterStandardCodec, CanEncodeAndDecodeUInt32) {
157 uint8_t bytes[9] = {0x04, 0x09, 0xba, 0xdc, 0xfe, 0x00, 0x00, 0x00, 0x00};
158 UInt32
value = 0xfedcba09;
162TEST(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]]);
170TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt8) {
171 uint8_t bytes[5] = {0x03, 0xfe, 0xff, 0xff, 0xff};
176TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt16) {
177 uint8_t bytes[5] = {0x03, 0xdc, 0xfe, 0xff, 0xff};
178 SInt16
value = 0xfedc;
182TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt32) {
183 uint8_t bytes[5] = {0x03, 0x78, 0x56, 0x34, 0x12};
187TEST(FlutterStandardCodec, CanEncodeAndDecodeSInt64) {
188 uint8_t bytes[9] = {0x04, 0xef, 0xcd, 0xab, 0x90, 0x78, 0x56, 0x34, 0x12};
192TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32) {
193 uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x60, 0xfb, 0x21, 0x09, 0x40};
198TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat64) {
199 uint8_t bytes[16] = {0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x18, 0x2d, 0x44, 0x54, 0xfb, 0x21, 0x09, 0x40};
204TEST(FlutterStandardCodec, CanEncodeAndDecodeString) {
205 uint8_t bytes[13] = {0x07, 0x0b, 0x68, 0x65, 0x6c, 0x6c, 0x6f,
206 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64};
210TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonAsciiCodePoint) {
211 uint8_t bytes[7] = {0x07, 0x05, 0x68, 0xe2, 0x98, 0xba, 0x77};
215TEST(FlutterStandardCodec, CanEncodeAndDecodeStringWithNonBMPCodePoint) {
216 uint8_t bytes[8] = {0x07, 0x06, 0x68, 0xf0, 0x9f, 0x98, 0x82, 0x77};
220TEST(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) ==
233TEST(FlutterStandardCodec, CanEncodeAndDecodeArray) {
234 NSArray*
value = @[ [NSNull null], @"hello", @3.14, @47, @{@42 : @"nested"} ];
238TEST(FlutterStandardCodec, CanEncodeAndDecodeDictionary) {
239 NSDictionary*
value =
242 [NSNull null] : [NSNull null],
243 @3.14 : @[ @"nested" ]};
247TEST(FlutterStandardCodec, CanEncodeAndDecodeByteArray) {
248 uint8_t bytes[4] = {0xBA, 0x5E, 0xBA, 0x11};
249 NSData*
data = [NSData dataWithBytes:bytes length:4];
254TEST(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]]);
264TEST(FlutterStandardCodec, CanEncodeAndDecodeInt32Array) {
265 uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
266 NSData*
data = [NSData dataWithBytes:bytes length:8];
271TEST(FlutterStandardCodec, CanEncodeAndDecodeInt64Array) {
272 uint8_t bytes[8] = {0xBA, 0x5E, 0xBA, 0x11, 0xff, 0xff, 0xff, 0xff};
273 NSData*
data = [NSData dataWithBytes:bytes length:8];
278TEST(FlutterStandardCodec, CanEncodeAndDecodeFloat32Array) {
279 uint8_t bytes[8] = {0xd8, 0x0f, 0x49, 0x40, 0x00, 0x00, 0x7a, 0x44};
280 NSData*
data = [NSData dataWithBytes:bytes length:8];
285TEST(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];
293TEST(FlutterStandardCodec, HandlesMethodCallsWithNilArguments) {
298 ASSERT_TRUE([decoded isEqual:
call]);
301TEST(FlutterStandardCodec, HandlesMethodCallsWithSingleArgument) {
306 ASSERT_TRUE([decoded isEqual:
call]);
309TEST(FlutterStandardCodec, HandlesMethodCallsWithArgumentList) {
311 NSArray* arguments = @[ @42, @"world" ];
316 ASSERT_TRUE([decoded isEqual:
call]);
319TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithNilResult) {
323 ASSERT_TRUE(decoded == nil);
326TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithSingleResult) {
330 ASSERT_TRUE([decoded isEqual:@42]);
333TEST(FlutterStandardCodec, HandlesSuccessEnvelopesWithResultMap) {
335 NSDictionary*
result = @{
@"a" : @42, @42 :
@"a"};
338 ASSERT_TRUE([decoded isEqual:
result]);
341TEST(FlutterStandardCodec, HandlesErrorEnvelopes) {
343 NSDictionary* details = @{
@"a" : @42, @42 :
@"a"};
349 ASSERT_TRUE([decoded isEqual:
error]);
352TEST(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]);
static void encode(uint8_t output[16], const uint32_t input[4])
const uint8_t uint32_t uint32_t GError ** error
TEST(FlutterStandardCodec, CanDecodeZeroLength)
static void CheckEncodeDecode(id value, NSData *expectedEncoding)
void writeValue:(id value)
instancetype errorWithCode:message:details:(NSString *code,[message] NSString *_Nullable message,[details] id _Nullable details)
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
id decode:(NSData *message)
instancetype codecWithReaderWriter:(FlutterStandardReaderWriter *readerWriter)
instancetype sharedInstance()
NSData * encode:(id message)
NSData * encodeMethodCall:(FlutterMethodCall *call)
NSData * encodeErrorEnvelope:(FlutterError *error)
FlutterMethodCall * decodeMethodCall:(NSData *message)
id decodeEnvelope:(NSData *envelope)
instancetype sharedInstance()
NSData * encodeSuccessEnvelope:(id result)
nullable id readValueOfType:(UInt8 type)
void readBytes:length:(void *destination,[length] NSUInteger length)
instancetype typedDataWithInt32:(NSData *data)
instancetype typedDataWithBytes:(NSData *data)
instancetype typedDataWithInt64:(NSData *data)
instancetype typedDataWithFloat64:(NSData *data)
instancetype typedDataWithFloat32:(NSData *data)
void writeByte:(UInt8 value)
void writeValue:(id value)
void writeBytes:length:(const void *bytes,[length] NSUInteger length)
static double time(int loops, Benchmark *bench, Target *target)
std::shared_ptr< const fml::Mapping > data