blob: 43a19d30a890d37598726a4bba644895ac816528 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
#include "gtest/gtest.h"
#include <math.h>
// Encodes a message using FlJsonMessageCodec to a UTF-8 string.
static gchar* encode_message(FlValue* value) {
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(GError) error = nullptr;
g_autofree gchar* result = fl_json_message_codec_encode(codec, value, &error);
EXPECT_EQ(error, nullptr);
return static_cast<gchar*>(g_steal_pointer(&result));
}
// Encodes a message using FlJsonMessageCodec to a UTF-8 string. Expect the
// given error.
static void encode_error_message(FlValue* value, GQuark domain, gint code) {
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(GError) error = nullptr;
g_autofree gchar* result = fl_json_message_codec_encode(codec, value, &error);
EXPECT_TRUE(g_error_matches(error, domain, code));
EXPECT_EQ(result, nullptr);
}
// Decodes a message using FlJsonMessageCodec from UTF-8 string.
static FlValue* decode_message(const char* text) {
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(GError) error = nullptr;
g_autoptr(FlValue) value = fl_json_message_codec_decode(codec, text, &error);
EXPECT_EQ(error, nullptr);
EXPECT_NE(value, nullptr);
return fl_value_ref(value);
}
// Decodes a message using FlJsonMessageCodec from UTF-8 string. Expect the
// given error.
static void decode_error_message(const char* text, GQuark domain, gint code) {
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(GError) error = nullptr;
g_autoptr(FlValue) value = fl_json_message_codec_decode(codec, text, &error);
EXPECT_TRUE(g_error_matches(error, domain, code));
EXPECT_EQ(value, nullptr);
}
TEST(FlJsonMessageCodecTest, EncodeNullptr) {
g_autofree gchar* text = encode_message(nullptr);
EXPECT_STREQ(text, "null");
}
TEST(FlJsonMessageCodecTest, EncodeNull) {
g_autoptr(FlValue) value = fl_value_new_null();
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "null");
}
TEST(FlJsonMessageCodecTest, DecodeNull) {
g_autoptr(FlValue) value = decode_message("null");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_NULL);
}
static gchar* encode_bool(gboolean value) {
g_autoptr(FlValue) v = fl_value_new_bool(value);
return encode_message(v);
}
TEST(FlJsonMessageCodecTest, EncodeBoolFalse) {
g_autofree gchar* text = encode_bool(FALSE);
EXPECT_STREQ(text, "false");
}
TEST(FlJsonMessageCodecTest, EncodeBoolTrue) {
g_autofree gchar* text = encode_bool(TRUE);
EXPECT_STREQ(text, "true");
}
TEST(FlJsonMessageCodecTest, DecodeBoolFalse) {
g_autoptr(FlValue) value = decode_message("false");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
EXPECT_FALSE(fl_value_get_bool(value));
}
TEST(FlJsonMessageCodecTest, DecodeBoolTrue) {
g_autoptr(FlValue) value = decode_message("true");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_BOOL);
EXPECT_TRUE(fl_value_get_bool(value));
}
static gchar* encode_int(int64_t value) {
g_autoptr(FlValue) v = fl_value_new_int(value);
return encode_message(v);
}
TEST(FlJsonMessageCodecTest, EncodeIntZero) {
g_autofree gchar* text = encode_int(0);
EXPECT_STREQ(text, "0");
}
TEST(FlJsonMessageCodecTest, EncodeIntOne) {
g_autofree gchar* text = encode_int(1);
EXPECT_STREQ(text, "1");
}
TEST(FlJsonMessageCodecTest, EncodeInt12345) {
g_autofree gchar* text = encode_int(12345);
EXPECT_STREQ(text, "12345");
}
TEST(FlJsonMessageCodecTest, EncodeIntMin) {
g_autofree gchar* text = encode_int(G_MININT64);
EXPECT_STREQ(text, "-9223372036854775808");
}
TEST(FlJsonMessageCodecTest, EncodeIntMax) {
g_autofree gchar* text = encode_int(G_MAXINT64);
EXPECT_STREQ(text, "9223372036854775807");
}
TEST(FlJsonMessageCodecTest, DecodeIntZero) {
g_autoptr(FlValue) value = decode_message("0");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), 0);
}
TEST(FlJsonMessageCodecTest, DecodeIntOne) {
g_autoptr(FlValue) value = decode_message("1");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), 1);
}
TEST(FlJsonMessageCodecTest, DecodeInt12345) {
g_autoptr(FlValue) value = decode_message("12345");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), 12345);
}
TEST(FlJsonMessageCodecTest, DecodeIntMin) {
g_autoptr(FlValue) value = decode_message("-9223372036854775808");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), G_MININT64);
}
TEST(FlJsonMessageCodecTest, DecodeIntMax) {
g_autoptr(FlValue) value = decode_message("9223372036854775807");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_INT);
EXPECT_EQ(fl_value_get_int(value), G_MAXINT64);
}
TEST(FlJsonMessageCodecTest, DecodeUintMax) {
// This is bigger than an signed 64 bit integer, so we expect it to be
// represented as a double
g_autoptr(FlValue) value = decode_message("18446744073709551615");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 1.8446744073709551615e+19);
}
TEST(FlJsonMessageCodecTest, DecodeHugeNumber) {
// This is bigger than an unsigned 64 bit integer, so we expect it to be
// represented as a double
g_autoptr(FlValue) value = decode_message("184467440737095516150");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 1.84467440737095516150e+20);
}
TEST(FlJsonMessageCodecTest, DecodeIntLeadingZero1) {
decode_error_message("00", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeIntLeadingZero2) {
decode_error_message("01", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeIntDoubleNegative) {
decode_error_message("--1", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeIntPositiveSign) {
decode_error_message("+1", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeIntHexChar) {
decode_error_message("0a", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
static gchar* encode_float(double value) {
g_autoptr(FlValue) v = fl_value_new_float(value);
return encode_message(v);
}
TEST(FlJsonMessageCodecTest, EncodeFloatZero) {
g_autofree gchar* text = encode_float(0);
EXPECT_STREQ(text, "0.0");
}
TEST(FlJsonMessageCodecTest, EncodeFloatOne) {
g_autofree gchar* text = encode_float(1);
EXPECT_STREQ(text, "1.0");
}
TEST(FlJsonMessageCodecTest, EncodeFloatMinusOne) {
g_autofree gchar* text = encode_float(-1);
EXPECT_STREQ(text, "-1.0");
}
TEST(FlJsonMessageCodecTest, EncodeFloatHalf) {
g_autofree gchar* text = encode_float(0.5);
EXPECT_STREQ(text, "0.5");
}
TEST(FlJsonMessageCodecTest, EncodeFloatPi) {
g_autofree gchar* text = encode_float(M_PI);
EXPECT_STREQ(text, "3.141592653589793");
}
TEST(FlJsonMessageCodecTest, EncodeFloatMinusZero) {
g_autofree gchar* text = encode_float(-0.0);
EXPECT_STREQ(text, "-0.0");
}
// NOTE(robert-ancell): JSON doesn't support encoding of NAN and INFINITY, but
// rapidjson doesn't seem to either encode them or treat them as an error.
TEST(FlJsonMessageCodecTest, DecodeFloatZero) {
g_autoptr(FlValue) value = decode_message("0.0");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 0.0);
}
TEST(FlJsonMessageCodecTest, DecodeFloatOne) {
g_autoptr(FlValue) value = decode_message("1.0");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 1.0);
}
TEST(FlJsonMessageCodecTest, DecodeFloatMinusOne) {
g_autoptr(FlValue) value = decode_message("-1.0");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), -1.0);
}
TEST(FlJsonMessageCodecTest, DecodeFloatHalf) {
g_autoptr(FlValue) value = decode_message("0.5");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), 0.5);
}
TEST(FlJsonMessageCodecTest, DecodeFloatPi) {
g_autoptr(FlValue) value = decode_message("3.1415926535897931");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), M_PI);
}
TEST(FlJsonMessageCodecTest, DecodeFloatMinusZero) {
g_autoptr(FlValue) value = decode_message("-0.0");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_FLOAT);
EXPECT_EQ(fl_value_get_float(value), -0.0);
}
TEST(FlJsonMessageCodecTest, DecodeFloatMissingFraction) {
decode_error_message("0.", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeFloatInvalidFraction) {
decode_error_message("0.a", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
static gchar* encode_string(const gchar* value) {
g_autoptr(FlValue) v = fl_value_new_string(value);
return encode_message(v);
}
TEST(FlJsonMessageCodecTest, EncodeStringEmpty) {
g_autofree gchar* text = encode_string("");
EXPECT_STREQ(text, "\"\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringHello) {
g_autofree gchar* text = encode_string("hello");
EXPECT_STREQ(text, "\"hello\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEmptySized) {
g_autoptr(FlValue) value = fl_value_new_string_sized(nullptr, 0);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "\"\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringHelloSized) {
g_autoptr(FlValue) value = fl_value_new_string_sized("Hello World", 5);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "\"Hello\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeQuote) {
g_autofree gchar* text = encode_string("\"");
EXPECT_STREQ(text, "\"\\\"\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeBackslash) {
g_autofree gchar* text = encode_string("\\");
EXPECT_STREQ(text, "\"\\\\\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeBackspace) {
g_autofree gchar* text = encode_string("\b");
EXPECT_STREQ(text, "\"\\b\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeFormFeed) {
g_autofree gchar* text = encode_string("\f");
EXPECT_STREQ(text, "\"\\f\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeNewline) {
g_autofree gchar* text = encode_string("\n");
EXPECT_STREQ(text, "\"\\n\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeCarriageReturn) {
g_autofree gchar* text = encode_string("\r");
EXPECT_STREQ(text, "\"\\r\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeTab) {
g_autofree gchar* text = encode_string("\t");
EXPECT_STREQ(text, "\"\\t\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEscapeUnicode) {
g_autofree gchar* text = encode_string("\u0001");
EXPECT_STREQ(text, "\"\\u0001\"");
}
TEST(FlJsonMessageCodecTest, EncodeStringEmoji) {
g_autofree gchar* text = encode_string("😀");
EXPECT_STREQ(text, "\"😀\"");
}
TEST(FlJsonMessageCodecTest, DecodeStringEmpty) {
g_autoptr(FlValue) value = decode_message("\"\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "");
}
TEST(FlJsonMessageCodecTest, DecodeStringHello) {
g_autoptr(FlValue) value = decode_message("\"hello\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "hello");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeQuote) {
g_autoptr(FlValue) value = decode_message("\"\\\"\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\"");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeBackslash) {
g_autoptr(FlValue) value = decode_message("\"\\\\\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\\");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeSlash) {
g_autoptr(FlValue) value = decode_message("\"\\/\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "/");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeBackspace) {
g_autoptr(FlValue) value = decode_message("\"\\b\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\b");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeFormFeed) {
g_autoptr(FlValue) value = decode_message("\"\\f\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\f");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeNewline) {
g_autoptr(FlValue) value = decode_message("\"\\n\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\n");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeCarriageReturn) {
g_autoptr(FlValue) value = decode_message("\"\\r\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\r");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeTab) {
g_autoptr(FlValue) value = decode_message("\"\\t\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\t");
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeUnicode) {
g_autoptr(FlValue) value = decode_message("\"\\u0001\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "\u0001");
}
TEST(FlJsonMessageCodecTest, DecodeStringEmoji) {
g_autoptr(FlValue) value = decode_message("\"😀\"");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_STRING);
EXPECT_STREQ(fl_value_get_string(value), "😀");
}
TEST(FlJsonMessageCodecTest, DecodeInvalidUTF8) {
decode_error_message("\xff", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_UTF8);
}
TEST(FlJsonMessageCodecTest, DecodeStringInvalidUTF8) {
decode_error_message("\"\xff\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_UTF8);
}
TEST(FlJsonMessageCodecTest, DecodeStringBinary) {
decode_error_message("\"Hello\x01World\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringNewline) {
decode_error_message("\"Hello\nWorld\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringCarriageReturn) {
decode_error_message("\"Hello\rWorld\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringTab) {
decode_error_message("\"Hello\tWorld\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringUnterminatedEmpty) {
decode_error_message("\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringExtraQuote) {
decode_error_message("\"\"\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapedClosingQuote) {
decode_error_message("\"\\\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringUnknownEscape) {
decode_error_message("\"\\z\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringInvalidEscapeUnicode) {
decode_error_message("\"\\uxxxx\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeUnicodeNoData) {
decode_error_message("\"\\u\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeStringEscapeUnicodeShortData) {
decode_error_message("\"\\uxx\"", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, EncodeUint8ListEmpty) {
g_autoptr(FlValue) value = fl_value_new_uint8_list(nullptr, 0);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[]");
}
TEST(FlJsonMessageCodecTest, EncodeUint8List) {
uint8_t data[] = {0, 1, 2, 3, 4};
g_autoptr(FlValue) value = fl_value_new_uint8_list(data, 5);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[0,1,2,3,4]");
}
TEST(FlJsonMessageCodecTest, EncodeInt32ListEmpty) {
g_autoptr(FlValue) value = fl_value_new_int32_list(nullptr, 0);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[]");
}
TEST(FlJsonMessageCodecTest, EncodeInt32List) {
int32_t data[] = {0, -1, 2, -3, 4};
g_autoptr(FlValue) value = fl_value_new_int32_list(data, 5);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[0,-1,2,-3,4]");
}
TEST(FlJsonMessageCodecTest, EncodeInt64ListEmpty) {
g_autoptr(FlValue) value = fl_value_new_int64_list(nullptr, 0);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[]");
}
TEST(FlJsonMessageCodecTest, EncodeInt64List) {
int64_t data[] = {0, -1, 2, -3, 4};
g_autoptr(FlValue) value = fl_value_new_int64_list(data, 5);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[0,-1,2,-3,4]");
}
TEST(FlJsonMessageCodecTest, EncodeFloatListEmpty) {
g_autoptr(FlValue) value = fl_value_new_float_list(nullptr, 0);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[]");
}
TEST(FlJsonMessageCodecTest, EncodeFloatList) {
double data[] = {0, -0.5, 0.25, -0.125, 0.0625};
g_autoptr(FlValue) value = fl_value_new_float_list(data, 5);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[0.0,-0.5,0.25,-0.125,0.0625]");
}
TEST(FlJsonMessageCodecTest, EncodeListEmpty) {
g_autoptr(FlValue) value = fl_value_new_list();
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[]");
}
TEST(FlJsonMessageCodecTest, EncodeListTypes) {
g_autoptr(FlValue) value = fl_value_new_list();
fl_value_append_take(value, fl_value_new_null());
fl_value_append_take(value, fl_value_new_bool(TRUE));
fl_value_append_take(value, fl_value_new_int(42));
fl_value_append_take(value, fl_value_new_float(-1.5));
fl_value_append_take(value, fl_value_new_string("hello"));
fl_value_append_take(value, fl_value_new_list());
fl_value_append_take(value, fl_value_new_map());
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[null,true,42,-1.5,\"hello\",[],{}]");
}
TEST(FlJsonMessageCodecTest, EncodeListNested) {
g_autoptr(FlValue) even_numbers = fl_value_new_list();
g_autoptr(FlValue) odd_numbers = fl_value_new_list();
for (int i = 0; i < 10; i++) {
if (i % 2 == 0)
fl_value_append_take(even_numbers, fl_value_new_int(i));
else
fl_value_append_take(odd_numbers, fl_value_new_int(i));
}
g_autoptr(FlValue) value = fl_value_new_list();
fl_value_append(value, even_numbers);
fl_value_append(value, odd_numbers);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "[[0,2,4,6,8],[1,3,5,7,9]]");
}
TEST(FlJsonMessageCodecTest, DecodeListEmpty) {
g_autoptr(FlValue) value = decode_message("[]");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_LIST);
EXPECT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlJsonMessageCodecTest, DecodeListNoComma) {
decode_error_message("[0,1,2,3 4]", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeListUnterminatedEmpty) {
decode_error_message("[", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeListStartUnterminate) {
decode_error_message("]", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeListUnterminated) {
decode_error_message("[0,1,2,3,4", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeListDoubleTerminated) {
decode_error_message("[0,1,2,3,4]]", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, EncodeMapEmpty) {
g_autoptr(FlValue) value = fl_value_new_map();
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text, "{}");
}
TEST(FlJsonMessageCodecTest, EncodeMapNullKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_null(), fl_value_new_string("null"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapBoolKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_bool(TRUE),
fl_value_new_string("bool"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapIntKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_int(42), fl_value_new_string("int"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapFloatKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_float(M_PI),
fl_value_new_string("float"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapUint8ListKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_uint8_list(nullptr, 0),
fl_value_new_string("uint8_list"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapInt32ListKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_int32_list(nullptr, 0),
fl_value_new_string("int32_list"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapInt64ListKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_int64_list(nullptr, 0),
fl_value_new_string("int64_list"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapFloatListKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_float_list(nullptr, 0),
fl_value_new_string("float_list"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapListKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_list(), fl_value_new_string("list"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapMapKey) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_map(), fl_value_new_string("map"));
encode_error_message(value, FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_OBJECT_KEY_TYPE);
}
TEST(FlJsonMessageCodecTest, EncodeMapValueTypes) {
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_take(value, fl_value_new_string("null"), fl_value_new_null());
fl_value_set_take(value, fl_value_new_string("bool"),
fl_value_new_bool(TRUE));
fl_value_set_take(value, fl_value_new_string("int"), fl_value_new_int(42));
fl_value_set_take(value, fl_value_new_string("float"),
fl_value_new_float(-1.5));
fl_value_set_take(value, fl_value_new_string("string"),
fl_value_new_string("hello"));
fl_value_set_take(value, fl_value_new_string("list"), fl_value_new_list());
fl_value_set_take(value, fl_value_new_string("map"), fl_value_new_map());
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text,
"{\"null\":null,\"bool\":true,\"int\":42,\"float\":-"
"1.5,\"string\":\"hello\",\"list\":[],\"map\":{}}");
}
TEST(FlJsonMessageCodecTest, EncodeMapNested) {
g_autoptr(FlValue) str_to_int = fl_value_new_map();
const char* numbers[] = {"zero", "one", "two", "three", nullptr};
for (int i = 0; numbers[i] != nullptr; i++) {
fl_value_set_take(str_to_int, fl_value_new_string(numbers[i]),
fl_value_new_int(i));
}
g_autoptr(FlValue) value = fl_value_new_map();
fl_value_set_string(value, "str-to-int", str_to_int);
g_autofree gchar* text = encode_message(value);
EXPECT_STREQ(text,
"{\"str-to-int\":{\"zero\":0,\"one\":1,\"two\":2,\"three\":3}}");
}
TEST(FlJsonMessageCodecTest, DecodeMapEmpty) {
g_autoptr(FlValue) value = decode_message("{}");
ASSERT_EQ(fl_value_get_type(value), FL_VALUE_TYPE_MAP);
EXPECT_EQ(fl_value_get_length(value), static_cast<size_t>(0));
}
TEST(FlJsonMessageCodecTest, DecodeMapUnterminatedEmpty) {
decode_error_message("{", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeMapStartUnterminate) {
decode_error_message("}", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeMapNoComma) {
decode_error_message("{\"zero\":0 \"one\":1}", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeMapNoColon) {
decode_error_message("{\"zero\" 0,\"one\":1}", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeMapUnterminated) {
decode_error_message("{\"zero\":0,\"one\":1", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeMapDoubleTerminated) {
decode_error_message("{\"zero\":0,\"one\":1}}", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, DecodeUnknownWord) {
decode_error_message("foo", FL_JSON_MESSAGE_CODEC_ERROR,
FL_JSON_MESSAGE_CODEC_ERROR_INVALID_JSON);
}
TEST(FlJsonMessageCodecTest, EncodeDecode) {
g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
g_autoptr(FlValue) input = fl_value_new_list();
fl_value_append_take(input, fl_value_new_null());
fl_value_append_take(input, fl_value_new_bool(TRUE));
fl_value_append_take(input, fl_value_new_int(42));
fl_value_append_take(input, fl_value_new_float(M_PI));
fl_value_append_take(input, fl_value_new_string("hello"));
fl_value_append_take(input, fl_value_new_list());
fl_value_append_take(input, fl_value_new_map());
g_autoptr(GError) error = nullptr;
g_autofree gchar* message =
fl_json_message_codec_encode(codec, input, &error);
ASSERT_NE(message, nullptr);
EXPECT_EQ(error, nullptr);
g_autoptr(FlValue) output =
fl_json_message_codec_decode(codec, message, &error);
EXPECT_EQ(error, nullptr);
EXPECT_NE(output, nullptr);
EXPECT_TRUE(fl_value_equal(input, output));
}