public void TrueTest()
        {
            string input = "true";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void AllPrimitiveArrayTest()
        {
            string input = "[0, 0.1, -1, -1.1, 1, 2, \"hello\", null, true, false]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void NestedArrayTest()
        {
            string input = "[[], []]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        private static void PerformRoundTrip(
            SerializationFormat sourceFormat,
            SerializationFormat destinationFormat,
            string json)
        {
            IJsonReader reader;

            switch (sourceFormat)
            {
            case SerializationFormat.Text:
                reader = JsonReader.Create(Encoding.UTF8.GetBytes(json));
                break;

            case SerializationFormat.Binary:
                reader = JsonReader.Create(JsonTestUtils.ConvertTextToBinary(json));
                break;

            case SerializationFormat.NewtonsoftText:
                reader = NewtonsoftToCosmosDBReader.CreateFromString(json);
                break;

            //case SerializationFormat.BinaryWithDictionaryEncoding:
            //    sourceDictionary = new JsonStringDictionary(capacity: 128);
            //    reader = JsonReader.Create(JsonTestUtils.ConvertTextToBinary(json, sourceDictionary), sourceDictionary);
            //    break;

            default:
                throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: {sourceFormat}");
            }

            IJsonNavigator navigator;

            switch (sourceFormat)
            {
            case SerializationFormat.Text:
                navigator = JsonNavigator.Create(Encoding.UTF8.GetBytes(json));
                break;

            case SerializationFormat.Binary:
                navigator = JsonNavigator.Create(JsonTestUtils.ConvertTextToBinary(json));
                break;

            case SerializationFormat.NewtonsoftText:
                navigator = new JsonNewtonsoftNavigator(json);
                break;

            //case SerializationFormat.BinaryWithDictionaryEncoding:
            //    sourceDictionary = new JsonStringDictionary(capacity: 128);
            //    navigator = JsonNavigator.Create(JsonTestUtils.ConvertTextToBinary(json, sourceDictionary), sourceDictionary);
            //    break;

            default:
                throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: {sourceFormat}");
            }

            object[] sources = new object[] { reader, navigator };
            foreach (object source in sources)
            {
                IJsonWriter          writer;
                JsonStringDictionary jsonStringDictionary;
                switch (destinationFormat)
                {
                case SerializationFormat.Text:
                    writer = JsonWriter.Create(JsonSerializationFormat.Text);
                    jsonStringDictionary = null;
                    break;

                case SerializationFormat.Binary:
                    writer = JsonWriter.Create(JsonSerializationFormat.Binary);
                    jsonStringDictionary = null;
                    break;

                case SerializationFormat.NewtonsoftText:
                    writer = NewtonsoftToCosmosDBWriter.CreateTextWriter();
                    jsonStringDictionary = null;
                    break;

                //case SerializationFormat.BinaryWithDictionaryEncoding:
                //    jsonStringDictionary = new JsonStringDictionary(capacity: 128);
                //    if (sourceFormat == SerializationFormat.BinaryWithDictionaryEncoding)
                //    {
                //        int index = 0;
                //        while (sourceDictionary.TryGetStringAtIndex(index++, out UtfAllString value))
                //        {
                //            Assert.IsTrue(jsonStringDictionary.TryAddString(value.Utf16String, out _));
                //        }
                //    }

                //    writer = JsonWriter.Create(JsonSerializationFormat.Binary, jsonStringDictionary);
                //    break;

                default:
                    throw new ArgumentException($"Unexpected {nameof(destinationFormat)} of type: {destinationFormat}");
                }

                switch (source)
                {
                case IJsonReader sourceReader:
                    sourceReader.WriteAll(writer);
                    break;

                case IJsonNavigator sourceNavigator:
                    sourceNavigator.WriteNode(sourceNavigator.GetRootNode(), writer);
                    break;

                default:
                    Assert.Fail("Failed to downcast source type.");
                    break;
                }

                string result = writer.SerializationFormat switch
                {
                    JsonSerializationFormat.Text => Utf8String.UnsafeFromUtf8BytesNoValidation(writer.GetResult()).ToString(),
                    JsonSerializationFormat.Binary => JsonTestUtils.ConvertBinaryToText(writer.GetResult(), jsonStringDictionary),
                    _ => throw new ArgumentException(),
                };
                string normalizedResult = JsonRoundTripsTests.NewtonsoftFormat(result);
                string normalizedJson   = JsonRoundTripsTests.NewtonsoftFormat(json);

                Assert.AreEqual(normalizedJson, normalizedResult);
            }
        }
        public void NumberLimitsTest()
        {
            // min byte
            string minByteInput = "0";

            JsonToken[] minByteTokens =
            {
                JsonToken.Number(byte.MinValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(minByteInput, minByteTokens);

            // max byte
            string maxByteInput = "255";

            JsonToken[] maxByteTokens =
            {
                JsonToken.Number(byte.MaxValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxByteInput, maxByteTokens);

            // min short
            string minShortInput = "-32768";

            JsonToken[] minShortTokens =
            {
                JsonToken.Number(short.MinValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(minShortInput, minShortTokens);

            // max short
            string maxShortInput = "32767";

            JsonToken[] maxShortTokens =
            {
                JsonToken.Number(short.MaxValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxShortInput, maxShortTokens);

            // min int
            string minIntInput = "-2147483648";

            JsonToken[] minIntTokens =
            {
                JsonToken.Number(int.MinValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(minIntInput, minIntTokens);

            // max int
            string maxIntInput = "2147483647";

            JsonToken[] maxIntTokens =
            {
                JsonToken.Number(int.MaxValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxIntInput, maxIntTokens);

            // min long
            string minLongInput = "-9223372036854775808";

            JsonToken[] minLongTokens =
            {
                JsonToken.Number(long.MinValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(minLongInput, minLongTokens);

            // max long
            string maxLongInput = "9223372036854775807";

            JsonToken[] maxLongTokens =
            {
                JsonToken.Number(long.MaxValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxLongInput, maxLongTokens);

            // min double
            string minDoubleInput = "-1.7976931348623157E+308";

            JsonToken[] minDoubleTokens =
            {
                JsonToken.Number(double.MinValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(minDoubleInput, minDoubleTokens);

            // max double
            string maxDoubleInput = "1.7976931348623157E+308";

            JsonToken[] maxDoubleTokens =
            {
                JsonToken.Number(double.MaxValue)
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxDoubleInput, maxDoubleTokens);
        }
        public void SimpleObjectTest()
        {
            string input = "{\"GlossDiv\":10,\"title\": \"example glossary\" }";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void NullTest()
        {
            string input = "null";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void EmptyArrayTest()
        {
            string input = "[  ]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void IntArrayTest()
        {
            string input = "[ -2, -1, 0, 1, 2]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void EmptyStringTest()
        {
            string input = "\"\"";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void StringTest()
        {
            string input = "\"Hello World\"";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
 private static void PerformRoundTripTest(string input, IReadOnlyList <JsonToken> tokens)
 {
     // Do the actual roundtrips
     JsonRoundTripsTests.MultiSerializationRoundTrip(input);
 }
        private static void PerformRoundTrip(SerializationFormat sourceFormat, SerializationFormat destinationFormat, string json)
        {
            IJsonReader reader;

            switch (sourceFormat)
            {
            case SerializationFormat.Text:
                reader = JsonReader.Create(Encoding.UTF8.GetBytes(json));
                break;

            case SerializationFormat.Binary:
                reader = JsonReader.Create(JsonTestUtils.ConvertTextToBinary(json));
                break;

            case SerializationFormat.NewtonsoftText:
                reader = NewtonsoftToCosmosDBReader.CreateFromString(json);
                break;

            case SerializationFormat.BinaryWithDictionaryEncoding:
                JsonStringDictionary jsonStringDictionary = new JsonStringDictionary(capacity: 128);
                reader = JsonReader.Create(JsonTestUtils.ConvertTextToBinary(json, jsonStringDictionary), jsonStringDictionary);
                break;

            default:
                throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: {sourceFormat}");
            }

            IJsonNavigator navigator;

            switch (sourceFormat)
            {
            case SerializationFormat.Text:
                navigator = JsonNavigator.Create(Encoding.UTF8.GetBytes(json));
                break;

            case SerializationFormat.Binary:
                navigator = JsonNavigator.Create(JsonTestUtils.ConvertTextToBinary(json));
                break;

            case SerializationFormat.NewtonsoftText:
                navigator = new JsonNewtonsoftNavigator(json);
                break;

            case SerializationFormat.BinaryWithDictionaryEncoding:
                JsonStringDictionary jsonStringDictionary = new JsonStringDictionary(capacity: 128);
                navigator = JsonNavigator.Create(JsonTestUtils.ConvertTextToBinary(json, jsonStringDictionary), jsonStringDictionary);
                break;

            default:
                throw new ArgumentException($"Unexpected {nameof(sourceFormat)} of type: {sourceFormat}");
            }

            object[] sources = new object[] { reader, navigator };
            foreach (object source in sources)
            {
                IJsonWriter          writer;
                JsonStringDictionary jsonStringDictionary;
                switch (destinationFormat)
                {
                case SerializationFormat.Text:
                    writer = JsonWriter.Create(JsonSerializationFormat.Text);
                    jsonStringDictionary = null;
                    break;

                case SerializationFormat.Binary:
                    writer = JsonWriter.Create(JsonSerializationFormat.Binary);
                    jsonStringDictionary = null;
                    break;

                case SerializationFormat.NewtonsoftText:
                    writer = NewtonsoftToCosmosDBWriter.CreateTextWriter();
                    jsonStringDictionary = null;
                    break;

                case SerializationFormat.BinaryWithDictionaryEncoding:
                    jsonStringDictionary = new JsonStringDictionary(capacity: 128);
                    writer = JsonWriter.Create(JsonSerializationFormat.Binary, jsonStringDictionary);
                    break;

                default:
                    throw new ArgumentException($"Unexpected {nameof(destinationFormat)} of type: {destinationFormat}");
                }

                switch (source)
                {
                case IJsonReader sourceReader:
                    writer.WriteAll(sourceReader);
                    break;

                case IJsonNavigator sourceNavigator:
                    writer.WriteJsonNode(sourceNavigator, sourceNavigator.GetRootNode());
                    break;

                default:
                    Assert.Fail("Failed to downcast source type.");
                    break;
                }

                string result;
                switch (writer.SerializationFormat)
                {
                case JsonSerializationFormat.Text:
                    result = Utf8String.UnsafeFromUtf8BytesNoValidation(writer.GetResult()).ToString();
                    break;

                case JsonSerializationFormat.Binary:
                    result = JsonTestUtils.ConvertBinaryToText(writer.GetResult(), jsonStringDictionary);
                    break;

                default:
                    throw new ArgumentException();
                }

                string normalizedResult = JsonRoundTripsTests.NewtonsoftFormat(result);
                string normalizedJson   = JsonRoundTripsTests.NewtonsoftFormat(json);

                Assert.AreEqual(normalizedJson, normalizedResult);
            }
        }
        public void ArrayLengthLimitsTest()
        {
            // empty array
            string emptyArrayInput = "[]";

            JsonToken[] emptyArrayTokens =
            {
                JsonToken.ArrayStart(),
                JsonToken.ArrayEnd()
            };

            JsonRoundTripsTests.PerformRoundTripTest(emptyArrayInput, emptyArrayTokens);

            // single item array
            string singleItemArrayInput = @"[""a""]";

            JsonToken[] singleItemArrayTokens =
            {
                JsonToken.ArrayStart(),
                JsonToken.String("a"),
                JsonToken.ArrayEnd()
            };

            JsonRoundTripsTests.PerformRoundTripTest(singleItemArrayInput, singleItemArrayTokens);

            // max 1 byte length array
            string maxByteLengthPayload = new string('a', byte.MaxValue - 1 - 1);
            string maxByteLengthInput   = @"[""" + maxByteLengthPayload + @"""]";

            JsonToken[] maxByteLengthTokens =
            {
                JsonToken.ArrayStart(),
                JsonToken.String(maxByteLengthPayload),
                JsonToken.ArrayEnd()
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxByteLengthInput, maxByteLengthTokens);

            // max 2 byte length array
            string maxUShortLengthPayload = new string('a', ushort.MaxValue - 1 - 2);
            string maxUShortLengthInput   = @"[""" + maxUShortLengthPayload + @"""]";

            JsonToken[] maxUShortLengthTokens =
            {
                JsonToken.ArrayStart(),
                JsonToken.String(maxUShortLengthPayload),
                JsonToken.ArrayEnd()
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxUShortLengthInput, maxUShortLengthTokens);

            // max 4 byte length array
            string maxUIntLengthPayload = new string('a', ushort.MaxValue);
            string maxUIntLengthInput   = @"[""" + maxUIntLengthPayload + @"""]";

            JsonToken[] maxUIntLengthTokens =
            {
                JsonToken.ArrayStart(),
                // 2 of them just to go past int.MaxValue but < uint.MaxValue
                JsonToken.String(maxUIntLengthPayload),
                JsonToken.ArrayEnd()
            };

            JsonRoundTripsTests.PerformRoundTripTest(maxUIntLengthInput, maxUIntLengthTokens);
        }
        public void WhitespaceCharacterTest()
        {
            string input = "[" + " " + "\"hello\"" + "," + "\t" + "\"my\"" + "\r" + "," + "\"name\"" + "\n" + "," + "\"is\"" + "]";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void NumberArrayTest()
        {
            string input = "[15,  22, 0.1]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void EmptyObjectTest()
        {
            string input = "{}";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void BooleanArrayTest()
        {
            string input = "[ true, false]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void FalseTest()
        {
            string input = "false";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void NullArrayTest()
        {
            string input = "[ null, null, null]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void IntegerTest()
        {
            string input = "1337";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void ObjectArrayTest()
        {
            string input = "[{}, {}]  ";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void DoubleTest()
        {
            string input = "1337.7";

            JsonRoundTripsTests.PerformRoundTripTest(input);
        }
        public void AllPrimitivesObjectTest()
        {
            string input = @"{
                ""id"": ""7029d079-4016-4436-b7da-36c0bae54ff6"",
                ""double"": 0.18963001816981939,
                ""int"": -1330192615,
                ""string"": ""XCPCFXPHHF"",
                ""boolean"": true,
                ""null"": null,
                ""datetime"": ""2526-07-11T18:18:16.4520716"",
                ""spatialPoint"": {
                    ""type"": ""Point"",
                    ""coordinates"": [
                        118.9897,
                        -46.6781
                    ]
                },
                ""text"": ""tiger diamond newbrunswick snowleopard chocolate dog snowleopard turtle cat sapphire peach sapphire vancouver white chocolate horse diamond lion superlongcolourname ruby""
            }";

            JsonToken[] token =
            {
                JsonToken.ObjectStart(),

                JsonToken.FieldName("id"),
                JsonToken.String("7029d079-4016-4436-b7da-36c0bae54ff6"),

                JsonToken.FieldName("double"),
                JsonToken.Number(0.18963001816981939),

                JsonToken.FieldName("int"),
                JsonToken.Number(-1330192615),

                JsonToken.FieldName("string"),
                JsonToken.String("XCPCFXPHHF"),

                JsonToken.FieldName("boolean"),
                JsonToken.Boolean(true),

                JsonToken.FieldName("null"),
                JsonToken.Null(),

                JsonToken.FieldName("datetime"),
                JsonToken.String("2526-07-11T18:18:16.4520716"),

                JsonToken.FieldName("spatialPoint"),
                JsonToken.ObjectStart(),
                JsonToken.FieldName("type"),
                JsonToken.String("Point"),

                JsonToken.FieldName("coordinates"),
                JsonToken.ArrayStart(),
                JsonToken.Number(118.9897),
                JsonToken.Number(-46.6781),
                JsonToken.ArrayEnd(),
                JsonToken.ObjectEnd(),

                JsonToken.FieldName("text"),
                JsonToken.String("tiger diamond newbrunswick snowleopard chocolate dog snowleopard turtle cat sapphire peach sapphire vancouver white chocolate horse diamond lion superlongcolourname ruby"),
                JsonToken.ObjectEnd(),
            };

            JsonRoundTripsTests.PerformRoundTripTest(input, token);
        }