Files

2084 lines
82 KiB
C#

#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
#if !(NET20 || NET35 || NET40 || PORTABLE40)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json.Tests.TestObjects.JsonTextReaderTests;
using Newtonsoft.Json.Utilities;
#if DNXCORE50
using Xunit;
using Test = Xunit.FactAttribute;
using Assert = Newtonsoft.Json.Tests.XUnitAssert;
#else
using NUnit.Framework;
#endif
using Newtonsoft.Json.Tests.TestObjects;
namespace Newtonsoft.Json.Tests
{
[TestFixture]
public class JsonTextWriterAsyncTests : TestFixtureBase
{
public class LazyStringWriter : StringWriter
{
public LazyStringWriter(IFormatProvider formatProvider) : base(formatProvider)
{
}
public override Task FlushAsync()
{
return DoDelay(base.FlushAsync());
}
public override Task WriteAsync(char value)
{
return DoDelay(base.WriteAsync(value));
}
public override Task WriteAsync(char[] buffer, int index, int count)
{
return DoDelay(base.WriteAsync(buffer, index, count));
}
public override Task WriteAsync(string value)
{
return DoDelay(base.WriteAsync(value));
}
public override Task WriteLineAsync()
{
return DoDelay(base.WriteLineAsync());
}
public override Task WriteLineAsync(char value)
{
return DoDelay(base.WriteLineAsync(value));
}
public override Task WriteLineAsync(char[] buffer, int index, int count)
{
return DoDelay(base.WriteLineAsync(buffer, index, count));
}
public override Task WriteLineAsync(string value)
{
return DoDelay(base.WriteLineAsync(value));
}
private async Task DoDelay(Task t)
{
await Task.Delay(TimeSpan.FromSeconds(0.01));
await t;
}
}
#if !(NETSTANDARD1_0 || PORTABLE) || NETSTANDARD2_0 || NET6_0_OR_GREATER
[Test]
public async Task WriteLazy()
{
LazyStringWriter sw = new LazyStringWriter(CultureInfo.InvariantCulture);
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.Indentation = 4;
writer.Formatting = Formatting.Indented;
await writer.WriteStartObjectAsync();
await writer.WritePropertyNameAsync("PropByte");
await writer.WriteValueAsync((byte)1);
await writer.WritePropertyNameAsync("PropSByte");
await writer.WriteValueAsync((sbyte)2);
await writer.WritePropertyNameAsync("PropShort");
await writer.WriteValueAsync((short)3);
await writer.WritePropertyNameAsync("PropUInt");
await writer.WriteValueAsync((uint)4);
await writer.WritePropertyNameAsync("PropUShort");
await writer.WriteValueAsync((ushort)5);
await writer.WritePropertyNameAsync("PropUri");
await writer.WriteValueAsync(new Uri("http://localhost/"));
await writer.WritePropertyNameAsync("PropRaw");
await writer.WriteRawValueAsync("'raw string'");
await writer.WritePropertyNameAsync("PropObjectNull");
await writer.WriteValueAsync((object)null);
await writer.WritePropertyNameAsync("PropObjectBigInteger");
await writer.WriteValueAsync((object)System.Numerics.BigInteger.Parse("123456789012345678901234567890"));
await writer.WritePropertyNameAsync("PropUndefined");
await writer.WriteUndefinedAsync();
await writer.WritePropertyNameAsync(@"PropEscaped ""name""", true);
await writer.WriteNullAsync();
await writer.WritePropertyNameAsync(@"PropUnescaped", false);
await writer.WriteNullAsync();
await writer.WritePropertyNameAsync("PropArray");
await writer.WriteStartArrayAsync();
await writer.WriteValueAsync("string!");
await writer.WriteEndArrayAsync();
await writer.WritePropertyNameAsync("PropNested");
await writer.WriteStartArrayAsync();
await writer.WriteStartArrayAsync();
await writer.WriteStartArrayAsync();
await writer.WriteStartArrayAsync();
await writer.WriteStartArrayAsync();
await writer.WriteEndArrayAsync();
await writer.WriteEndArrayAsync();
await writer.WriteEndArrayAsync();
await writer.WriteEndArrayAsync();
await writer.WriteEndArrayAsync();
await writer.WriteEndObjectAsync();
}
StringAssert.AreEqual(@"{
""PropByte"": 1,
""PropSByte"": 2,
""PropShort"": 3,
""PropUInt"": 4,
""PropUShort"": 5,
""PropUri"": ""http://localhost/"",
""PropRaw"": 'raw string',
""PropObjectNull"": null,
""PropObjectBigInteger"": 123456789012345678901234567890,
""PropUndefined"": undefined,
""PropEscaped \""name\"""": null,
""PropUnescaped"": null,
""PropArray"": [
""string!""
],
""PropNested"": [
[
[
[
[]
]
]
]
]
}", sw.ToString());
}
[Test]
public async Task WriteLazy_Property()
{
LazyStringWriter sw = new LazyStringWriter(CultureInfo.InvariantCulture);
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.Indentation = 4;
writer.Formatting = Formatting.Indented;
await writer.WriteStartArrayAsync();
await writer.WriteStartObjectAsync();
await writer.WritePropertyNameAsync("IncompleteProp");
await writer.WriteEndArrayAsync();
}
StringAssert.AreEqual(@"[
{
""IncompleteProp"": null
}
]", sw.ToString());
}
#endif
[Test]
public async Task BufferTestAsync()
{
FakeArrayPool arrayPool = new FakeArrayPool();
string longString = new string('A', 2000);
string longEscapedString = "Hello!" + new string('!', 50) + new string('\n', 1000) + "Good bye!";
string longerEscapedString = "Hello!" + new string('!', 2000) + new string('\n', 1000) + "Good bye!";
for (int i = 0; i < 1000; i++)
{
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.ArrayPool = arrayPool;
await writer.WriteStartObjectAsync();
await writer.WritePropertyNameAsync("Prop1");
await writer.WriteValueAsync(new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc));
await writer.WritePropertyNameAsync("Prop2");
await writer.WriteValueAsync(longString);
await writer.WritePropertyNameAsync("Prop3");
await writer.WriteValueAsync(longEscapedString);
await writer.WritePropertyNameAsync("Prop4");
await writer.WriteValueAsync(longerEscapedString);
await writer.WriteEndObjectAsync();
}
if ((i + 1) % 100 == 0)
{
Console.WriteLine("Allocated buffers: " + arrayPool.FreeArrays.Count);
}
}
Assert.AreEqual(0, arrayPool.UsedArrays.Count);
Assert.AreEqual(3, arrayPool.FreeArrays.Count);
}
[Test]
public async Task BufferTest_WithErrorAsync()
{
FakeArrayPool arrayPool = new FakeArrayPool();
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
try
{
// dispose will free used buffers
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.ArrayPool = arrayPool;
await writer.WriteStartObjectAsync();
await writer.WritePropertyNameAsync("Prop1");
await writer.WriteValueAsync(new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc));
await writer.WritePropertyNameAsync("Prop2");
await writer.WriteValueAsync("This is an escaped \n string!");
await writer.WriteValueAsync("Error!");
}
Assert.Fail();
}
catch
{
}
Assert.AreEqual(0, arrayPool.UsedArrays.Count);
Assert.AreEqual(1, arrayPool.FreeArrays.Count);
}
[Test]
public async Task NewLineAsync()
{
MemoryStream ms = new MemoryStream();
using (var streamWriter = new StreamWriter(ms, new UTF8Encoding(false)) { NewLine = "\n" })
using (var jsonWriter = new JsonTextWriter(streamWriter)
{
CloseOutput = true,
Indentation = 2,
Formatting = Formatting.Indented
})
{
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("prop");
await jsonWriter.WriteValueAsync(true);
await jsonWriter.WriteEndObjectAsync();
}
byte[] data = ms.ToArray();
string json = Encoding.UTF8.GetString(data, 0, data.Length);
Assert.AreEqual(@"{" + '\n' + @" ""prop"": true" + '\n' + "}", json);
}
[Test]
public async Task QuoteNameAndStringsAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
JsonTextWriter writer = new JsonTextWriter(sw) { QuoteName = false };
await writer.WriteStartObjectAsync();
await writer.WritePropertyNameAsync("name");
await writer.WriteValueAsync("value");
await writer.WriteEndObjectAsync();
await writer.FlushAsync();
Assert.AreEqual(@"{name:""value""}", sb.ToString());
}
[Test]
public async Task CloseOutputAsync()
{
MemoryStream ms = new MemoryStream();
JsonTextWriter writer = new JsonTextWriter(new StreamWriter(ms));
Assert.IsTrue(ms.CanRead);
await writer.CloseAsync();
Assert.IsFalse(ms.CanRead);
ms = new MemoryStream();
writer = new JsonTextWriter(new StreamWriter(ms)) { CloseOutput = false };
Assert.IsTrue(ms.CanRead);
await writer.CloseAsync();
Assert.IsTrue(ms.CanRead);
}
#if !(PORTABLE) || NETSTANDARD1_3 || NETSTANDARD2_0 || NET6_0_OR_GREATER
[Test]
public async Task WriteIConvertableAsync()
{
var sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
await writer.WriteValueAsync(new ConvertibleInt(1));
Assert.AreEqual("1", sw.ToString());
}
#endif
[Test]
public async Task ValueFormattingAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync('@');
await jsonWriter.WriteValueAsync("\r\n\t\f\b?{\\r\\n\"\'");
await jsonWriter.WriteValueAsync(true);
await jsonWriter.WriteValueAsync(10);
await jsonWriter.WriteValueAsync(10.99);
await jsonWriter.WriteValueAsync(0.99);
await jsonWriter.WriteValueAsync(0.000000000000000001d);
await jsonWriter.WriteValueAsync(0.000000000000000001m);
await jsonWriter.WriteValueAsync((string)null);
await jsonWriter.WriteValueAsync((object)null);
await jsonWriter.WriteValueAsync("This is a string.");
await jsonWriter.WriteNullAsync();
await jsonWriter.WriteUndefinedAsync();
await jsonWriter.WriteEndArrayAsync();
}
string expected = @"[""@"",""\r\n\t\f\b?{\\r\\n\""'"",true,10,10.99,0.99,1E-18,0.000000000000000001,null,null,""This is a string."",null,undefined]";
string result = sb.ToString();
Assert.AreEqual(expected, result);
}
[Test]
public async Task NullableValueFormattingAsync()
{
StringWriter sw = new StringWriter();
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync((char?)null);
await jsonWriter.WriteValueAsync((char?)'c');
await jsonWriter.WriteValueAsync((bool?)null);
await jsonWriter.WriteValueAsync((bool?)true);
await jsonWriter.WriteValueAsync((byte?)null);
await jsonWriter.WriteValueAsync((byte?)1);
await jsonWriter.WriteValueAsync((sbyte?)null);
await jsonWriter.WriteValueAsync((sbyte?)1);
await jsonWriter.WriteValueAsync((short?)null);
await jsonWriter.WriteValueAsync((short?)1);
await jsonWriter.WriteValueAsync((ushort?)null);
await jsonWriter.WriteValueAsync((ushort?)1);
await jsonWriter.WriteValueAsync((int?)null);
await jsonWriter.WriteValueAsync((int?)1);
await jsonWriter.WriteValueAsync((uint?)null);
await jsonWriter.WriteValueAsync((uint?)1);
await jsonWriter.WriteValueAsync((long?)null);
await jsonWriter.WriteValueAsync((long?)1);
await jsonWriter.WriteValueAsync((ulong?)null);
await jsonWriter.WriteValueAsync((ulong?)1);
await jsonWriter.WriteValueAsync((double?)null);
await jsonWriter.WriteValueAsync((double?)1.1);
await jsonWriter.WriteValueAsync((float?)null);
await jsonWriter.WriteValueAsync((float?)1.1);
await jsonWriter.WriteValueAsync((decimal?)null);
await jsonWriter.WriteValueAsync((decimal?)1.1m);
await jsonWriter.WriteValueAsync((DateTime?)null);
await jsonWriter.WriteValueAsync((DateTime?)new DateTime(DateTimeUtils.InitialJavaScriptDateTicks, DateTimeKind.Utc));
await jsonWriter.WriteValueAsync((DateTimeOffset?)null);
await jsonWriter.WriteValueAsync((DateTimeOffset?)new DateTimeOffset(DateTimeUtils.InitialJavaScriptDateTicks, TimeSpan.Zero));
await jsonWriter.WriteEndArrayAsync();
}
string json = sw.ToString();
string expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""1970-01-01T00:00:00Z"",null,""1970-01-01T00:00:00+00:00""]";
Assert.AreEqual(expected, json);
}
[Test]
public async Task WriteValueObjectWithNullableAsync()
{
StringWriter sw = new StringWriter();
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
char? value = 'c';
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync((object)value);
await jsonWriter.WriteEndArrayAsync();
}
string json = sw.ToString();
string expected = @"[""c""]";
Assert.AreEqual(expected, json);
}
[Test]
public async Task WriteValueObjectWithUnsupportedValueAsync()
{
await ExceptionAssert.ThrowsAsync<JsonWriterException>(async () =>
{
StringWriter sw = new StringWriter();
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(new Version(1, 1, 1, 1));
await jsonWriter.WriteEndArrayAsync();
}
}, @"Unsupported type: System.Version. Use the JsonSerializer class to get the object's JSON representation. Path ''.");
}
[Test]
public async Task StringEscapingAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(@"""These pretzels are making me thirsty!""");
await jsonWriter.WriteValueAsync("Jeff's house was burninated.");
await jsonWriter.WriteValueAsync("1. You don't talk about fight club.\r\n2. You don't talk about fight club.");
await jsonWriter.WriteValueAsync("35% of\t statistics\n are made\r up.");
await jsonWriter.WriteEndArrayAsync();
}
string expected = @"[""\""These pretzels are making me thirsty!\"""",""Jeff's house was burninated."",""1. You don't talk about fight club.\r\n2. You don't talk about fight club."",""35% of\t statistics\n are made\r up.""]";
string result = sb.ToString();
Assert.AreEqual(expected, result);
}
[Test]
public async Task WriteEndAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("CPU");
await jsonWriter.WriteValueAsync("Intel");
await jsonWriter.WritePropertyNameAsync("PSU");
await jsonWriter.WriteValueAsync("500W");
await jsonWriter.WritePropertyNameAsync("Drives");
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync("DVD read/writer");
await jsonWriter.WriteCommentAsync("(broken)");
await jsonWriter.WriteValueAsync("500 gigabyte hard drive");
await jsonWriter.WriteValueAsync("200 gigabyte hard drive");
await jsonWriter.WriteEndObjectAsync();
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
}
string expected = @"{
""CPU"": ""Intel"",
""PSU"": ""500W"",
""Drives"": [
""DVD read/writer""
/*(broken)*/,
""500 gigabyte hard drive"",
""200 gigabyte hard drive""
]
}";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task CloseWithRemainingContentAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("CPU");
await jsonWriter.WriteValueAsync("Intel");
await jsonWriter.WritePropertyNameAsync("PSU");
await jsonWriter.WriteValueAsync("500W");
await jsonWriter.WritePropertyNameAsync("Drives");
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync("DVD read/writer");
await jsonWriter.WriteCommentAsync("(broken)");
await jsonWriter.WriteValueAsync("500 gigabyte hard drive");
await jsonWriter.WriteValueAsync("200 gigabyte hard drive");
await jsonWriter.CloseAsync();
}
string expected = @"{
""CPU"": ""Intel"",
""PSU"": ""500W"",
""Drives"": [
""DVD read/writer""
/*(broken)*/,
""500 gigabyte hard drive"",
""200 gigabyte hard drive""
]
}";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task IndentingAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("CPU");
await jsonWriter.WriteValueAsync("Intel");
await jsonWriter.WritePropertyNameAsync("PSU");
await jsonWriter.WriteValueAsync("500W");
await jsonWriter.WritePropertyNameAsync("Drives");
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync("DVD read/writer");
await jsonWriter.WriteCommentAsync("(broken)");
await jsonWriter.WriteValueAsync("500 gigabyte hard drive");
await jsonWriter.WriteValueAsync("200 gigabyte hard drive");
await jsonWriter.WriteEndAsync();
await jsonWriter.WriteEndObjectAsync();
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
}
// {
// "CPU": "Intel",
// "PSU": "500W",
// "Drives": [
// "DVD read/writer"
// /*(broken)*/,
// "500 gigabyte hard drive",
// "200 gigabyte hard drive"
// ]
// }
string expected = @"{
""CPU"": ""Intel"",
""PSU"": ""500W"",
""Drives"": [
""DVD read/writer""
/*(broken)*/,
""500 gigabyte hard drive"",
""200 gigabyte hard drive""
]
}";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task StateAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
await jsonWriter.WriteStartObjectAsync();
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
Assert.AreEqual("", jsonWriter.Path);
await jsonWriter.WritePropertyNameAsync("CPU");
Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
Assert.AreEqual("CPU", jsonWriter.Path);
await jsonWriter.WriteValueAsync("Intel");
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
Assert.AreEqual("CPU", jsonWriter.Path);
await jsonWriter.WritePropertyNameAsync("Drives");
Assert.AreEqual(WriteState.Property, jsonWriter.WriteState);
Assert.AreEqual("Drives", jsonWriter.Path);
await jsonWriter.WriteStartArrayAsync();
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
await jsonWriter.WriteValueAsync("DVD read/writer");
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
Assert.AreEqual("Drives[0]", jsonWriter.Path);
await jsonWriter.WriteEndAsync();
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
Assert.AreEqual("Drives", jsonWriter.Path);
await jsonWriter.WriteEndObjectAsync();
Assert.AreEqual(WriteState.Start, jsonWriter.WriteState);
Assert.AreEqual("", jsonWriter.Path);
}
}
[Test]
public async Task FloatingPointNonFiniteNumbers_SymbolAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol;
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteValueAsync(double.PositiveInfinity);
await jsonWriter.WriteValueAsync(double.NegativeInfinity);
await jsonWriter.WriteValueAsync(float.NaN);
await jsonWriter.WriteValueAsync(float.PositiveInfinity);
await jsonWriter.WriteValueAsync(float.NegativeInfinity);
await jsonWriter.WriteEndArrayAsync();
await jsonWriter.FlushAsync();
}
string expected = @"[
NaN,
Infinity,
-Infinity,
NaN,
Infinity,
-Infinity
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task FloatingPointNonFiniteNumbers_ZeroAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.DefaultValue;
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteValueAsync(double.PositiveInfinity);
await jsonWriter.WriteValueAsync(double.NegativeInfinity);
await jsonWriter.WriteValueAsync(float.NaN);
await jsonWriter.WriteValueAsync(float.PositiveInfinity);
await jsonWriter.WriteValueAsync(float.NegativeInfinity);
await jsonWriter.WriteValueAsync((double?)double.NaN);
await jsonWriter.WriteValueAsync((double?)double.PositiveInfinity);
await jsonWriter.WriteValueAsync((double?)double.NegativeInfinity);
await jsonWriter.WriteValueAsync((float?)float.NaN);
await jsonWriter.WriteValueAsync((float?)float.PositiveInfinity);
await jsonWriter.WriteValueAsync((float?)float.NegativeInfinity);
await jsonWriter.WriteEndArrayAsync();
await jsonWriter.FlushAsync();
}
string expected = @"[
0.0,
0.0,
0.0,
0.0,
0.0,
0.0,
null,
null,
null,
null,
null,
null
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task FloatingPointNonFiniteNumbers_StringAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.String;
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteValueAsync(double.PositiveInfinity);
await jsonWriter.WriteValueAsync(double.NegativeInfinity);
await jsonWriter.WriteValueAsync(float.NaN);
await jsonWriter.WriteValueAsync(float.PositiveInfinity);
await jsonWriter.WriteValueAsync(float.NegativeInfinity);
await jsonWriter.WriteEndArrayAsync();
await jsonWriter.FlushAsync();
}
string expected = @"[
""NaN"",
""Infinity"",
""-Infinity"",
""NaN"",
""Infinity"",
""-Infinity""
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task FloatingPointNonFiniteNumbers_QuoteCharAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.String;
jsonWriter.QuoteChar = '\'';
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteValueAsync(double.PositiveInfinity);
await jsonWriter.WriteValueAsync(double.NegativeInfinity);
await jsonWriter.WriteValueAsync(float.NaN);
await jsonWriter.WriteValueAsync(float.PositiveInfinity);
await jsonWriter.WriteValueAsync(float.NegativeInfinity);
await jsonWriter.WriteEndArrayAsync();
await jsonWriter.FlushAsync();
}
string expected = @"[
'NaN',
'Infinity',
'-Infinity',
'NaN',
'Infinity',
'-Infinity'
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task WriteRawInStartAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol;
await jsonWriter.WriteRawAsync("[1,2,3,4,5]");
await jsonWriter.WriteWhitespaceAsync(" ");
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteEndArrayAsync();
}
string expected = @"[1,2,3,4,5] [
NaN
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task WriteRawInArrayAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol;
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteRawAsync(",[1,2,3,4,5]");
await jsonWriter.WriteRawAsync(",[1,2,3,4,5]");
await jsonWriter.WriteValueAsync(float.NaN);
await jsonWriter.WriteEndArrayAsync();
}
string expected = @"[
NaN,[1,2,3,4,5],[1,2,3,4,5],
NaN
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task WriteRawInObjectAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WriteRawAsync(@"""PropertyName"":[1,2,3,4,5]");
await jsonWriter.WriteEndAsync();
}
string expected = @"{""PropertyName"":[1,2,3,4,5]}";
string result = sb.ToString();
Assert.AreEqual(expected, result);
}
[Test]
public async Task WriteTokenAsync()
{
CancellationToken cancel = CancellationToken.None;
JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]"));
reader.Read();
reader.Read();
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
await writer.WriteTokenAsync(reader, cancel);
Assert.AreEqual("1", sw.ToString());
}
[Test]
public async Task WriteRawValueAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
int i = 0;
string rawJson = "[1,2]";
await jsonWriter.WriteStartObjectAsync();
while (i < 3)
{
await jsonWriter.WritePropertyNameAsync("d" + i);
await jsonWriter.WriteRawValueAsync(rawJson);
i++;
}
await jsonWriter.WriteEndObjectAsync();
}
Assert.AreEqual(@"{""d0"":[1,2],""d1"":[1,2],""d2"":[1,2]}", sb.ToString());
}
[Test]
public async Task WriteObjectNestedInConstructorAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("con");
await jsonWriter.WriteStartConstructorAsync("Ext.data.JsonStore");
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("aa");
await jsonWriter.WriteValueAsync("aa");
await jsonWriter.WriteEndObjectAsync();
await jsonWriter.WriteEndConstructorAsync();
await jsonWriter.WriteEndObjectAsync();
}
Assert.AreEqual(@"{""con"":new Ext.data.JsonStore({""aa"":""aa""})}", sb.ToString());
}
[Test]
public async Task WriteFloatingPointNumberAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol;
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(0.0);
await jsonWriter.WriteValueAsync(0f);
await jsonWriter.WriteValueAsync(0.1);
await jsonWriter.WriteValueAsync(1.0);
await jsonWriter.WriteValueAsync(1.000001);
await jsonWriter.WriteValueAsync(0.000001);
await jsonWriter.WriteValueAsync(double.Epsilon);
await jsonWriter.WriteValueAsync(double.PositiveInfinity);
await jsonWriter.WriteValueAsync(double.NegativeInfinity);
await jsonWriter.WriteValueAsync(double.NaN);
await jsonWriter.WriteValueAsync(double.MaxValue);
await jsonWriter.WriteValueAsync(double.MinValue);
await jsonWriter.WriteValueAsync(float.PositiveInfinity);
await jsonWriter.WriteValueAsync(float.NegativeInfinity);
await jsonWriter.WriteValueAsync(float.NaN);
await jsonWriter.WriteEndArrayAsync();
}
#if !(NETSTANDARD2_0 || NETSTANDARD1_3 || NET6_0_OR_GREATER)
Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,4.94065645841247E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString());
#else
Assert.AreEqual(@"[0.0,0.0,0.1,1.0,1.000001,1E-06,5E-324,Infinity,-Infinity,NaN,1.7976931348623157E+308,-1.7976931348623157E+308,Infinity,-Infinity,NaN]", sb.ToString());
#endif
}
[Test]
public async Task WriteIntegerNumberAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw) { Formatting = Formatting.Indented })
{
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(int.MaxValue);
await jsonWriter.WriteValueAsync(int.MinValue);
await jsonWriter.WriteValueAsync(0);
await jsonWriter.WriteValueAsync(-0);
await jsonWriter.WriteValueAsync(9L);
await jsonWriter.WriteValueAsync(9UL);
await jsonWriter.WriteValueAsync(long.MaxValue);
await jsonWriter.WriteValueAsync(long.MinValue);
await jsonWriter.WriteValueAsync(ulong.MaxValue);
await jsonWriter.WriteValueAsync(ulong.MinValue);
await jsonWriter.WriteEndArrayAsync();
}
Console.WriteLine(sb.ToString());
StringAssert.AreEqual(@"[
2147483647,
-2147483648,
0,
0,
9,
9,
9223372036854775807,
-9223372036854775808,
18446744073709551615,
0
]", sb.ToString());
}
[Test]
public async Task WriteTokenDirectAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteTokenAsync(JsonToken.StartArray);
await jsonWriter.WriteTokenAsync(JsonToken.Integer, 1);
await jsonWriter.WriteTokenAsync(JsonToken.StartObject);
await jsonWriter.WriteTokenAsync(JsonToken.PropertyName, "string");
await jsonWriter.WriteTokenAsync(JsonToken.Integer, int.MaxValue);
await jsonWriter.WriteTokenAsync(JsonToken.EndObject);
await jsonWriter.WriteTokenAsync(JsonToken.EndArray);
}
Assert.AreEqual(@"[1,{""string"":2147483647}]", sb.ToString());
}
[Test]
public async Task WriteTokenDirect_BadValueAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteTokenAsync(JsonToken.StartArray);
await ExceptionAssert.ThrowsAsync<FormatException>(async () => { await jsonWriter.WriteTokenAsync(JsonToken.Integer, "three"); }, "Input string was not in a correct format.");
await ExceptionAssert.ThrowsAsync<ArgumentNullException>(async () => { await jsonWriter.WriteTokenAsync(JsonToken.Integer); }, @"Value cannot be null.
Parameter name: value", "Value cannot be null. (Parameter 'value')");
}
}
[Test]
public async Task WriteTokenNullCheckAsync()
{
using (JsonWriter jsonWriter = new JsonTextWriter(new StringWriter()))
{
await ExceptionAssert.ThrowsAsync<ArgumentNullException>(async () => { await jsonWriter.WriteTokenAsync(null); });
await ExceptionAssert.ThrowsAsync<ArgumentNullException>(async () => { await jsonWriter.WriteTokenAsync(null, true); });
}
}
[Test]
public async Task TokenTypeOutOfRangeAsync()
{
using (JsonWriter jsonWriter = new JsonTextWriter(new StringWriter()))
{
ArgumentOutOfRangeException ex = await ExceptionAssert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await jsonWriter.WriteTokenAsync((JsonToken)int.MinValue));
Assert.AreEqual("token", ex.ParamName);
ex = await ExceptionAssert.ThrowsAsync<ArgumentOutOfRangeException>(async () => await jsonWriter.WriteTokenAsync((JsonToken)int.MinValue, "test"));
Assert.AreEqual("token", ex.ParamName);
}
}
[Test]
public async Task BadWriteEndArrayAsync()
{
await ExceptionAssert.ThrowsAsync<JsonWriterException>(async () =>
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonWriter jsonWriter = new JsonTextWriter(sw))
{
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(0.0);
await jsonWriter.WriteEndArrayAsync();
await jsonWriter.WriteEndArrayAsync();
}
}, "No token to close. Path ''.");
}
[Test]
public async Task IndentationAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
jsonWriter.FloatFormatHandling = FloatFormatHandling.Symbol;
Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
jsonWriter.Indentation = 5;
Assert.AreEqual(5, jsonWriter.Indentation);
jsonWriter.IndentChar = '_';
Assert.AreEqual('_', jsonWriter.IndentChar);
jsonWriter.QuoteName = true;
Assert.AreEqual(true, jsonWriter.QuoteName);
jsonWriter.QuoteChar = '\'';
Assert.AreEqual('\'', jsonWriter.QuoteChar);
await jsonWriter.WriteStartObjectAsync();
await jsonWriter.WritePropertyNameAsync("propertyName");
await jsonWriter.WriteValueAsync(double.NaN);
jsonWriter.IndentChar = '?';
Assert.AreEqual('?', jsonWriter.IndentChar);
jsonWriter.Indentation = 6;
Assert.AreEqual(6, jsonWriter.Indentation);
await jsonWriter.WritePropertyNameAsync("prop2");
await jsonWriter.WriteValueAsync(123);
await jsonWriter.WriteEndObjectAsync();
}
string expected = @"{
_____'propertyName': NaN,
??????'prop2': 123
}";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task WriteSingleBytesAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
string text = "Hello world.";
byte[] data = Encoding.UTF8.GetBytes(text);
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
await jsonWriter.WriteValueAsync(data);
}
string expected = @"""SGVsbG8gd29ybGQu""";
string result = sb.ToString();
Assert.AreEqual(expected, result);
byte[] d2 = Convert.FromBase64String(result.Trim('"'));
Assert.AreEqual(text, Encoding.UTF8.GetString(d2, 0, d2.Length));
}
[Test]
public async Task WriteBytesInArrayAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
string text = "Hello world.";
byte[] data = Encoding.UTF8.GetBytes(text);
using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
{
jsonWriter.Formatting = Formatting.Indented;
Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
await jsonWriter.WriteStartArrayAsync();
await jsonWriter.WriteValueAsync(data);
await jsonWriter.WriteValueAsync(data);
await jsonWriter.WriteValueAsync((object)data);
await jsonWriter.WriteValueAsync((byte[])null);
await jsonWriter.WriteValueAsync((Uri)null);
await jsonWriter.WriteEndArrayAsync();
}
string expected = @"[
""SGVsbG8gd29ybGQu"",
""SGVsbG8gd29ybGQu"",
""SGVsbG8gd29ybGQu"",
null,
null
]";
string result = sb.ToString();
StringAssert.AreEqual(expected, result);
}
[Test]
public async Task PathAsync()
{
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
using (JsonTextWriter writer = new JsonTextWriter(sw))
{
writer.Formatting = Formatting.Indented;
await writer.WriteStartArrayAsync();
Assert.AreEqual("", writer.Path);
await writer.WriteStartObjectAsync();
Assert.AreEqual("[0]", writer.Path);
await writer.WritePropertyNameAsync("Property1");
Assert.AreEqual("[0].Property1", writer.Path);
await writer.WriteStartArrayAsync();
Assert.AreEqual("[0].Property1", writer.Path);
await writer.WriteValueAsync(1);
Assert.AreEqual("[0].Property1[0]", writer.Path);
await writer.WriteStartArrayAsync();
Assert.AreEqual("[0].Property1[1]", writer.Path);
await writer.WriteStartArrayAsync();
Assert.AreEqual("[0].Property1[1][0]", writer.Path);
await writer.WriteStartArrayAsync();
Assert.AreEqual("[0].Property1[1][0][0]", writer.Path);
await writer.WriteEndObjectAsync();
Assert.AreEqual("[0]", writer.Path);
await writer.WriteStartObjectAsync();
Assert.AreEqual("[1]", writer.Path);
await writer.WritePropertyNameAsync("Property2");
Assert.AreEqual("[1].Property2", writer.Path);
await writer.WriteStartConstructorAsync("Constructor1");
Assert.AreEqual("[1].Property2", writer.Path);
await writer.WriteNullAsync();
Assert.AreEqual("[1].Property2[0]", writer.Path);
await writer.WriteStartArrayAsync();
Assert.AreEqual("[1].Property2[1]", writer.Path);
await writer.WriteValueAsync(1);
Assert.AreEqual("[1].Property2[1][0]", writer.Path);
await writer.WriteEndAsync();
Assert.AreEqual("[1].Property2[1]", writer.Path);
await writer.WriteEndObjectAsync();
Assert.AreEqual("[1]", writer.Path);
await writer.WriteEndArrayAsync();
Assert.AreEqual("", writer.Path);
}
StringAssert.AreEqual(@"[
{
""Property1"": [
1,
[
[
[]
]
]
]
},
{
""Property2"": new Constructor1(
null,
[
1
]
)
}
]", sb.ToString());
}
[Test]
public async Task DateTimeZoneHandlingAsync()
{
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw)
{
DateTimeZoneHandling = DateTimeZoneHandling.Utc
};
await writer.WriteValueAsync(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified));
Assert.AreEqual(@"""2000-01-01T01:01:01Z""", sw.ToString());
}
[Test]
public async Task HtmlStringEscapeHandlingAsync()
{
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw)
{
StringEscapeHandling = StringEscapeHandling.EscapeHtml
};
string script = @"<script type=""text/javascript"">alert('hi');</script>";
await writer.WriteValueAsync(script);
string json = sw.ToString();
Assert.AreEqual(@"""\u003cscript type=\u0022text/javascript\u0022\u003ealert(\u0027hi\u0027);\u003c/script\u003e""", json);
JsonTextReader reader = new JsonTextReader(new StringReader(json));
Assert.AreEqual(script, reader.ReadAsString());
}
[Test]
public async Task NonAsciiStringEscapeHandlingAsync()
{
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw)
{
StringEscapeHandling = StringEscapeHandling.EscapeNonAscii
};
string unicode = "\u5f20";
await writer.WriteValueAsync(unicode);
string json = sw.ToString();
Assert.AreEqual(8, json.Length);
Assert.AreEqual(@"""\u5f20""", json);
JsonTextReader reader = new JsonTextReader(new StringReader(json));
Assert.AreEqual(unicode, reader.ReadAsString());
sw = new StringWriter();
writer = new JsonTextWriter(sw)
{
StringEscapeHandling = StringEscapeHandling.Default
};
await writer.WriteValueAsync(unicode);
json = sw.ToString();
Assert.AreEqual(3, json.Length);
Assert.AreEqual("\"\u5f20\"", json);
}
[Test]
public async Task WriteEndOnPropertyAsync()
{
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.QuoteChar = '\'';
await writer.WriteStartObjectAsync();
await writer.WritePropertyNameAsync("Blah");
await writer.WriteEndAsync();
Assert.AreEqual("{'Blah':null}", sw.ToString());
}
[Test]
public async Task QuoteCharAsync()
{
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.Formatting = Formatting.Indented;
writer.QuoteChar = '\'';
await writer.WriteStartArrayAsync();
await writer.WriteValueAsync(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc));
await writer.WriteValueAsync(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero));
writer.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
await writer.WriteValueAsync(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc));
await writer.WriteValueAsync(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero));
writer.DateFormatString = "yyyy gg";
await writer.WriteValueAsync(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc));
await writer.WriteValueAsync(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero));
await writer.WriteValueAsync(new byte[] { 1, 2, 3 });
await writer.WriteValueAsync(TimeSpan.Zero);
await writer.WriteValueAsync(new Uri("http://www.google.com/"));
await writer.WriteValueAsync(Guid.Empty);
await writer.WriteEndAsync();
StringAssert.AreEqual(@"[
'2000-01-01T01:01:01Z',
'2000-01-01T01:01:01+00:00',
'\/Date(946688461000)\/',
'\/Date(946688461000+0000)\/',
'2000 A.D.',
'2000 A.D.',
'AQID',
'00:00:00',
'http://www.google.com/',
'00000000-0000-0000-0000-000000000000'
]", sw.ToString());
}
[Test]
public async Task CultureAsync()
{
CultureInfo culture = new CultureInfo("en-NZ");
culture.DateTimeFormat.AMDesignator = "a.m.";
culture.DateTimeFormat.PMDesignator = "p.m.";
StringWriter sw = new StringWriter();
JsonTextWriter writer = new JsonTextWriter(sw);
writer.Formatting = Formatting.Indented;
writer.DateFormatString = "yyyy tt";
writer.Culture = culture;
writer.QuoteChar = '\'';
await writer.WriteStartArrayAsync();
await writer.WriteValueAsync(new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Utc));
await writer.WriteValueAsync(new DateTimeOffset(2000, 1, 1, 1, 1, 1, TimeSpan.Zero));
await writer.WriteEndAsync();
StringAssert.AreEqual(@"[
'2000 a.m.',
'2000 a.m.'
]", sw.ToString());
}
[Test]
public async Task CompareNewStringEscapingWithOldAsync()
{
char c = (char)0;
do
{
StringWriter swNew = new StringWriter();
JsonTextWriter jsonWriter = new JsonTextWriter(new StreamWriter(Stream.Null));
await JavaScriptUtils.WriteEscapedJavaScriptStringAsync(swNew, c.ToString(), '"', true, JavaScriptUtils.DoubleQuoteCharEscapeFlags, StringEscapeHandling.Default, jsonWriter, null);
StringWriter swOld = new StringWriter();
WriteEscapedJavaScriptStringOld(swOld, c.ToString(), '"', true);
string newText = swNew.ToString();
string oldText = swOld.ToString();
if (newText != oldText)
{
throw new Exception("Difference for char '{0}' (value {1}). Old text: {2}, New text: {3}".FormatWith(CultureInfo.InvariantCulture, c, (int)c, oldText, newText));
}
c++;
} while (c != char.MaxValue);
}
private const string EscapedUnicodeText = "!";
private static void WriteEscapedJavaScriptStringOld(TextWriter writer, string s, char delimiter, bool appendDelimiters)
{
// leading delimiter
if (appendDelimiters)
{
writer.Write(delimiter);
}
if (s != null)
{
char[] chars = null;
char[] unicodeBuffer = null;
int lastWritePosition = 0;
for (int i = 0; i < s.Length; i++)
{
var c = s[i];
// don't escape standard text/numbers except '\' and the text delimiter
if (c >= ' ' && c < 128 && c != '\\' && c != delimiter)
{
continue;
}
string escapedValue;
switch (c)
{
case '\t':
escapedValue = @"\t";
break;
case '\n':
escapedValue = @"\n";
break;
case '\r':
escapedValue = @"\r";
break;
case '\f':
escapedValue = @"\f";
break;
case '\b':
escapedValue = @"\b";
break;
case '\\':
escapedValue = @"\\";
break;
case '\u0085': // Next Line
escapedValue = @"\u0085";
break;
case '\u2028': // Line Separator
escapedValue = @"\u2028";
break;
case '\u2029': // Paragraph Separator
escapedValue = @"\u2029";
break;
case '\'':
// this charater is being used as the delimiter
escapedValue = @"\'";
break;
case '"':
// this charater is being used as the delimiter
escapedValue = "\\\"";
break;
default:
if (c <= '\u001f')
{
if (unicodeBuffer == null)
{
unicodeBuffer = new char[6];
}
StringUtils.ToCharAsUnicode(c, unicodeBuffer);
// slightly hacky but it saves multiple conditions in if test
escapedValue = EscapedUnicodeText;
}
else
{
escapedValue = null;
}
break;
}
if (escapedValue == null)
{
continue;
}
if (i > lastWritePosition)
{
if (chars == null)
{
chars = s.ToCharArray();
}
// write unchanged chars before writing escaped text
writer.Write(chars, lastWritePosition, i - lastWritePosition);
}
lastWritePosition = i + 1;
if (!string.Equals(escapedValue, EscapedUnicodeText))
{
writer.Write(escapedValue);
}
else
{
writer.Write(unicodeBuffer);
}
}
if (lastWritePosition == 0)
{
// no escaped text, write entire string
writer.Write(s);
}
else
{
if (chars == null)
{
chars = s.ToCharArray();
}
// write remaining text
writer.Write(chars, lastWritePosition, s.Length - lastWritePosition);
}
}
// trailing delimiter
if (appendDelimiters)
{
writer.Write(delimiter);
}
}
[Test]
public async Task CustomJsonTextWriterTestsAsync()
{
StringWriter sw = new StringWriter();
CustomJsonTextWriter writer = new CustomAsyncJsonTextWriter(sw) { Formatting = Formatting.Indented };
await writer.WriteStartObjectAsync();
Assert.AreEqual(WriteState.Object, writer.WriteState);
await writer.WritePropertyNameAsync("Property1");
Assert.AreEqual(WriteState.Property, writer.WriteState);
Assert.AreEqual("Property1", writer.Path);
await writer.WriteNullAsync();
Assert.AreEqual(WriteState.Object, writer.WriteState);
await writer.WriteEndObjectAsync();
Assert.AreEqual(WriteState.Start, writer.WriteState);
StringAssert.AreEqual(@"{{{
""1ytreporP"": NULL!!!
}}}", sw.ToString());
}
[Test]
public async Task QuoteDictionaryNamesAsync()
{
var d = new Dictionary<string, int>
{
{ "a", 1 },
};
var jsonSerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
};
var serializer = JsonSerializer.Create(jsonSerializerSettings);
using (var stringWriter = new StringWriter())
{
using (var writer = new JsonTextWriter(stringWriter) { QuoteName = false })
{
serializer.Serialize(writer, d);
await writer.CloseAsync();
}
StringAssert.AreEqual(@"{
a: 1
}", stringWriter.ToString());
}
}
[Test]
public async Task WriteCommentsAsync()
{
string json = @"//comment*//*hi*/
{//comment
Name://comment
true//comment after true" + StringUtils.CarriageReturn + @"
,//comment after comma" + StringUtils.CarriageReturnLineFeed + @"
""ExpiryDate""://comment" + StringUtils.LineFeed + @"
new
" + StringUtils.LineFeed +
@"Constructor
(//comment
null//comment
),
""Price"": 3.99,
""Sizes"": //comment
[//comment
""Small""//comment
]//comment
}//comment
//comment 1 ";
JsonTextReader r = new JsonTextReader(new StringReader(json));
StringWriter sw = new StringWriter();
JsonTextWriter w = new JsonTextWriter(sw);
w.Formatting = Formatting.Indented;
await w.WriteTokenAsync(r, true);
StringAssert.AreEqual(@"/*comment*//*hi*/*/{/*comment*/
""Name"": /*comment*/ true/*comment after true*//*comment after comma*/,
""ExpiryDate"": /*comment*/ new Constructor(
/*comment*/,
null
/*comment*/
),
""Price"": 3.99,
""Sizes"": /*comment*/ [
/*comment*/
""Small""
/*comment*/
]/*comment*/
}/*comment *//*comment 1 */", sw.ToString());
}
[Test]
public void AsyncMethodsAlreadyCancelled()
{
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
source.Cancel();
var writer = new JsonTextWriter(new StreamWriter(Stream.Null));
Assert.IsTrue(writer.CloseAsync(token).IsCanceled);
Assert.IsTrue(writer.FlushAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteCommentAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WriteEndArrayAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndConstructorAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndObjectAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteNullAsync(token).IsCanceled);
Assert.IsTrue(writer.WritePropertyNameAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WritePropertyNameAsync("test", false, token).IsCanceled);
Assert.IsTrue(writer.WriteRawAsync("{}", token).IsCanceled);
Assert.IsTrue(writer.WriteRawValueAsync("{}", token).IsCanceled);
Assert.IsTrue(writer.WriteStartArrayAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteStartConstructorAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WriteStartObjectAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteTokenAsync(JsonToken.Comment, token).IsCanceled);
Assert.IsTrue(writer.WriteTokenAsync(JsonToken.Boolean, true, token).IsCanceled);
JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]"));
Assert.IsTrue(writer.WriteTokenAsync(reader, token).IsCanceled);
Assert.IsTrue(writer.WriteUndefinedAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(bool), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(bool?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte[]), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(char), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(char?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTime), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTime?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTimeOffset), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTimeOffset?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(decimal), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(decimal?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(double), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(double?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(float), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(float?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Guid), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Guid?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(int), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(int?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(long), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(long?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(object), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(sbyte), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(sbyte?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(short), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(short?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(TimeSpan), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(TimeSpan?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(uint), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(uint?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ulong), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ulong?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Uri), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ushort), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ushort?), token).IsCanceled);
Assert.IsTrue(writer.WriteWhitespaceAsync(" ", token).IsCanceled);
}
private class NoOverridesDerivedJsonTextWriter : JsonTextWriter
{
public NoOverridesDerivedJsonTextWriter(TextWriter textWriter) : base(textWriter)
{
}
}
private class MinimalOverridesDerivedJsonWriter : JsonWriter
{
public override void Flush()
{
}
}
[Test]
public void AsyncMethodsAlreadyCancelledOnTextWriterSubclass()
{
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
source.Cancel();
var writer = new NoOverridesDerivedJsonTextWriter(new StreamWriter(Stream.Null));
Assert.IsTrue(writer.CloseAsync(token).IsCanceled);
Assert.IsTrue(writer.FlushAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteCommentAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WriteEndArrayAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndConstructorAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndObjectAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteNullAsync(token).IsCanceled);
Assert.IsTrue(writer.WritePropertyNameAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WritePropertyNameAsync("test", false, token).IsCanceled);
Assert.IsTrue(writer.WriteRawAsync("{}", token).IsCanceled);
Assert.IsTrue(writer.WriteRawValueAsync("{}", token).IsCanceled);
Assert.IsTrue(writer.WriteStartArrayAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteStartConstructorAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WriteStartObjectAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteTokenAsync(JsonToken.Comment, token).IsCanceled);
Assert.IsTrue(writer.WriteTokenAsync(JsonToken.Boolean, true, token).IsCanceled);
JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]"));
Assert.IsTrue(writer.WriteTokenAsync(reader, token).IsCanceled);
Assert.IsTrue(writer.WriteUndefinedAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(bool), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(bool?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte[]), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(char), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(char?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTime), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTime?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTimeOffset), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTimeOffset?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(decimal), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(decimal?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(double), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(double?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(float), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(float?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Guid), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Guid?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(int), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(int?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(long), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(long?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(object), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(sbyte), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(sbyte?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(short), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(short?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(TimeSpan), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(TimeSpan?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(uint), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(uint?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ulong), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ulong?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Uri), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ushort), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ushort?), token).IsCanceled);
Assert.IsTrue(writer.WriteWhitespaceAsync(" ", token).IsCanceled);
}
[Test]
public void AsyncMethodsAlreadyCancelledOnWriterSubclass()
{
CancellationTokenSource source = new CancellationTokenSource();
CancellationToken token = source.Token;
source.Cancel();
var writer = new MinimalOverridesDerivedJsonWriter();
Assert.IsTrue(writer.CloseAsync(token).IsCanceled);
Assert.IsTrue(writer.FlushAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteCommentAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WriteEndArrayAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndConstructorAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteEndObjectAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteNullAsync(token).IsCanceled);
Assert.IsTrue(writer.WritePropertyNameAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WritePropertyNameAsync("test", false, token).IsCanceled);
Assert.IsTrue(writer.WriteRawAsync("{}", token).IsCanceled);
Assert.IsTrue(writer.WriteRawValueAsync("{}", token).IsCanceled);
Assert.IsTrue(writer.WriteStartArrayAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteStartConstructorAsync("test", token).IsCanceled);
Assert.IsTrue(writer.WriteStartObjectAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteTokenAsync(JsonToken.Comment, token).IsCanceled);
Assert.IsTrue(writer.WriteTokenAsync(JsonToken.Boolean, true, token).IsCanceled);
JsonTextReader reader = new JsonTextReader(new StringReader("[1,2,3,4,5]"));
Assert.IsTrue(writer.WriteTokenAsync(reader, token).IsCanceled);
Assert.IsTrue(writer.WriteUndefinedAsync(token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(bool), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(bool?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(byte[]), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(char), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(char?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTime), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTime?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTimeOffset), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(DateTimeOffset?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(decimal), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(decimal?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(double), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(double?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(float), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(float?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Guid), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Guid?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(int), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(int?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(long), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(long?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(object), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(sbyte), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(sbyte?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(short), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(short?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(TimeSpan), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(TimeSpan?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(uint), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(uint?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ulong), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ulong?), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(Uri), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ushort), token).IsCanceled);
Assert.IsTrue(writer.WriteValueAsync(default(ushort?), token).IsCanceled);
Assert.IsTrue(writer.WriteWhitespaceAsync(" ", token).IsCanceled);
}
[Test]
public async Task FailureOnStartWriteProperty()
{
JsonTextWriter writer = new JsonTextWriter(new ThrowingWriter(' '));
writer.Formatting = Formatting.Indented;
await writer.WriteStartObjectAsync();
await ExceptionAssert.ThrowsAsync<InvalidOperationException>(async () => await writer.WritePropertyNameAsync("aa"));
}
[Test]
public async Task FailureOnStartWriteObject()
{
JsonTextWriter writer = new JsonTextWriter(new ThrowingWriter('{'));
await ExceptionAssert.ThrowsAsync<InvalidOperationException>(async () => await writer.WriteStartObjectAsync());
}
public class ThrowingWriter : TextWriter
{
// allergic to certain characters, this null-stream writer throws on any attempt to write them.
private char[] _singleCharBuffer = new char[1];
public ThrowingWriter(params char[] throwChars)
{
ThrowChars = throwChars;
}
public char[] ThrowChars { get; set; }
public override Encoding Encoding => Encoding.UTF8;
public override Task WriteAsync(char value)
{
_singleCharBuffer[0] = value;
return WriteAsync(_singleCharBuffer, 0, 1);
}
public override Task WriteAsync(char[] buffer, int index, int count)
{
if (buffer.Skip(index).Take(count).Any(c => ThrowChars.Contains(c)))
{
// Pre-4.6 equivalent to .FromException()
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
tcs.SetException(new InvalidOperationException());
return tcs.Task;
}
return Task.Delay(0);
}
public override Task WriteAsync(string value)
{
return WriteAsync(value.ToCharArray(), 0, value.Length);
}
public override void Write(char value)
{
throw new NotImplementedException();
}
}
}
public class CustomAsyncJsonTextWriter : CustomJsonTextWriter
{
public CustomAsyncJsonTextWriter(TextWriter textWriter) : base(textWriter)
{
}
public override Task WritePropertyNameAsync(string name, CancellationToken cancellationToken = default(CancellationToken))
{
return WritePropertyNameAsync(name, true, cancellationToken);
}
public override async Task WritePropertyNameAsync(string name, bool escape, CancellationToken cancellationToken = default(CancellationToken))
{
await SetWriteStateAsync(JsonToken.PropertyName, name, cancellationToken);
if (QuoteName)
{
await _writer.WriteAsync(QuoteChar);
}
await _writer.WriteAsync(new string(name.ToCharArray().Reverse().ToArray()));
if (QuoteName)
{
await _writer.WriteAsync(QuoteChar);
}
await _writer.WriteAsync(':');
}
public override async Task WriteNullAsync(CancellationToken cancellationToken = default(CancellationToken))
{
await SetWriteStateAsync(JsonToken.Null, null, cancellationToken);
await _writer.WriteAsync("NULL!!!");
}
public override async Task WriteStartObjectAsync(CancellationToken cancellationToken = default(CancellationToken))
{
await SetWriteStateAsync(JsonToken.StartObject, null, cancellationToken);
await _writer.WriteAsync("{{{");
}
public override Task WriteEndObjectAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return SetWriteStateAsync(JsonToken.EndObject, null, cancellationToken);
}
protected override Task WriteEndAsync(JsonToken token, CancellationToken cancellationToken)
{
if (token == JsonToken.EndObject)
{
return _writer.WriteAsync("}}}");
}
else
{
return base.WriteEndAsync(token, cancellationToken);
}
}
}
}
#endif