From 37ed0eee99e0416c02eb1a505411b874ed0fc58b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Andr=C3=A9?= <2341261+manandre@users.noreply.github.com> Date: Mon, 8 Jan 2024 18:33:14 +0100 Subject: [PATCH] Allow specifying IndentCharacter and IndentSize when writing JSON (#95292) * Add IndentText json option * Add IndentText for json source generator * Add tests * IndentText must be non-nullable * Improve performance * Add extra tests * Cleanup * Apply suggestions from code review Co-authored-by: Eirik Tsarpalis * Fixes following code review * Fixes following code review #2 * Add tests for invalid characters * Handle RawIndent length * Move all to RawIndentation * Update documentation * Additional fixes from code review * Move to the new API * Extra fixes and enhancements * Fixes from code review * Avoid introducing extra fields in JsonWriterOptions * Fix OOM error * Use bitwise logic for IndentedOrNotSkipValidation * Cache indentation options in Utf8JsonWriter * Add missing test around indentation options * New fixes from code review * Update src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs * Add test to check default values of the JsonWriterOptions properties * Fix comment --------- Co-authored-by: Eirik Tsarpalis --- .../ConsoleLoggerConfigureOptions.cs | 2 +- .../ConsoleLoggerExtensionsTests.cs | 1 + .../JsonSourceGenerationOptionsAttribute.cs | 10 + .../gen/JsonSourceGenerator.Emitter.cs | 7 + .../gen/JsonSourceGenerator.Parser.cs | 12 + .../gen/Model/SourceGenerationOptionsSpec.cs | 4 + .../System.Text.Json/ref/System.Text.Json.cs | 6 + .../src/Resources/Strings.resx | 6 + .../src/System/Text/Json/JsonConstants.cs | 9 +- .../JsonSerializerOptions.Caching.cs | 4 + .../Serialization/JsonSerializerOptions.cs | 50 + .../src/System/Text/Json/ThrowHelper.cs | 12 + .../Text/Json/Writer/JsonWriterHelper.cs | 30 +- .../Text/Json/Writer/JsonWriterOptions.cs | 46 +- .../Utf8JsonWriter.WriteProperties.Bytes.cs | 8 +- ...Utf8JsonWriter.WriteProperties.DateTime.cs | 8 +- ...onWriter.WriteProperties.DateTimeOffset.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Decimal.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Double.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Float.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Guid.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Helpers.cs | 8 +- .../Utf8JsonWriter.WriteProperties.Literal.cs | 8 +- ...JsonWriter.WriteProperties.SignedNumber.cs | 8 +- .../Utf8JsonWriter.WriteProperties.String.cs | 24 +- ...onWriter.WriteProperties.UnsignedNumber.cs | 8 +- .../Utf8JsonWriter.WriteValues.Bytes.cs | 4 +- .../Utf8JsonWriter.WriteValues.Comment.cs | 8 +- .../Utf8JsonWriter.WriteValues.DateTime.cs | 4 +- ...f8JsonWriter.WriteValues.DateTimeOffset.cs | 4 +- .../Utf8JsonWriter.WriteValues.Decimal.cs | 4 +- .../Utf8JsonWriter.WriteValues.Double.cs | 4 +- .../Utf8JsonWriter.WriteValues.Float.cs | 4 +- ...8JsonWriter.WriteValues.FormattedNumber.cs | 4 +- .../Writer/Utf8JsonWriter.WriteValues.Guid.cs | 4 +- .../Utf8JsonWriter.WriteValues.Literal.cs | 4 +- ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 4 +- .../Utf8JsonWriter.WriteValues.String.cs | 8 +- ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 4 +- .../System/Text/Json/Writer/Utf8JsonWriter.cs | 45 +- .../JsonSourceGenerationOptionsTests.cs | 6 +- .../JsonWriterOptionsTests.cs | 103 +- .../Serialization/CacheTests.cs | 2 + .../Serialization/OptionsTests.cs | 88 + .../Utf8JsonWriterTests.cs | 1603 ++++++----------- 45 files changed, 1087 insertions(+), 1131 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerConfigureOptions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerConfigureOptions.cs index c30e842d3fc3e..3b725f1cb59e0 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerConfigureOptions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerConfigureOptions.cs @@ -25,7 +25,7 @@ public void EnsureConsoleLoggerOptions_ConfigureOptions_SupportsAllProperties() Assert.Equal(3, typeof(ConsoleFormatterOptions).GetProperties(flags).Length); Assert.Equal(5, typeof(SimpleConsoleFormatterOptions).GetProperties(flags).Length); Assert.Equal(4, typeof(JsonConsoleFormatterOptions).GetProperties(flags).Length); - Assert.Equal(4, typeof(JsonWriterOptions).GetProperties(flags).Length); + Assert.Equal(6, typeof(JsonWriterOptions).GetProperties(flags).Length); } [Theory] diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerExtensionsTests.cs index 99b49170ed8e1..fec2d737c8d2c 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/Microsoft.Extensions.Logging.Console.Tests/ConsoleLoggerExtensionsTests.cs @@ -597,6 +597,7 @@ private static void VerifyHasOnlySimpleProperties(Type type) // or else NativeAOT would break Assert.True(prop.PropertyType == typeof(string) || prop.PropertyType == typeof(bool) || + prop.PropertyType == typeof(char) || prop.PropertyType == typeof(int) || prop.PropertyType.IsEnum, $"ConsoleOptions property '{type.Name}.{prop.Name}' must be a simple type in order for NativeAOT to work"); } diff --git a/src/libraries/System.Text.Json/Common/JsonSourceGenerationOptionsAttribute.cs b/src/libraries/System.Text.Json/Common/JsonSourceGenerationOptionsAttribute.cs index 8084d4a6f613f..0bfaf896c4034 100644 --- a/src/libraries/System.Text.Json/Common/JsonSourceGenerationOptionsAttribute.cs +++ b/src/libraries/System.Text.Json/Common/JsonSourceGenerationOptionsAttribute.cs @@ -125,6 +125,16 @@ public JsonSourceGenerationOptionsAttribute(JsonSerializerDefaults defaults) /// public bool WriteIndented { get; set; } + /// + /// Specifies the default value of when set. + /// + public char IndentCharacter { get; set; } + + /// + /// Specifies the default value of when set. + /// + public int IndentSize { get; set; } + /// /// Specifies the default source generation mode for type declarations that don't set a . /// diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs index db08be80c53d0..a7e396983d15a 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs @@ -1168,6 +1168,12 @@ private static void GetLogicForDefaultSerializerOptionsInit(SourceGenerationOpti if (optionsSpec.WriteIndented is bool writeIndented) writer.WriteLine($"WriteIndented = {FormatBool(writeIndented)},"); + if (optionsSpec.IndentCharacter is char indentCharacter) + writer.WriteLine($"IndentCharacter = {FormatIndentChar(indentCharacter)},"); + + if (optionsSpec.IndentSize is int indentSize) + writer.WriteLine($"IndentSize = {indentSize},"); + writer.Indentation--; writer.WriteLine("};"); @@ -1344,6 +1350,7 @@ private static string FormatJsonSerializerDefaults(JsonSerializerDefaults defaul private static string FormatBool(bool value) => value ? "true" : "false"; private static string FormatStringLiteral(string? value) => value is null ? "null" : $"\"{value}\""; + private static string FormatIndentChar(char value) => value is '\t' ? "'\\t'" : $"'{value}'"; /// /// Method used to generate JsonTypeInfo given options instance diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs index 594f7ad9770c3..3be80faceb84f 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Parser.cs @@ -280,6 +280,8 @@ private SourceGenerationOptionsSpec ParseJsonSourceGenerationOptionsAttribute(IN JsonUnmappedMemberHandling? unmappedMemberHandling = null; bool? useStringEnumConverter = null; bool? writeIndented = null; + char? indentCharacter = null; + int? indentSize = null; if (attributeData.ConstructorArguments.Length > 0) { @@ -373,6 +375,14 @@ private SourceGenerationOptionsSpec ParseJsonSourceGenerationOptionsAttribute(IN writeIndented = (bool)namedArg.Value.Value!; break; + case nameof(JsonSourceGenerationOptionsAttribute.IndentCharacter): + indentCharacter = (char)namedArg.Value.Value!; + break; + + case nameof(JsonSourceGenerationOptionsAttribute.IndentSize): + indentSize = (int)namedArg.Value.Value!; + break; + case nameof(JsonSourceGenerationOptionsAttribute.GenerationMode): generationMode = (JsonSourceGenerationMode)namedArg.Value.Value!; break; @@ -404,6 +414,8 @@ private SourceGenerationOptionsSpec ParseJsonSourceGenerationOptionsAttribute(IN UnmappedMemberHandling = unmappedMemberHandling, UseStringEnumConverter = useStringEnumConverter, WriteIndented = writeIndented, + IndentCharacter = indentCharacter, + IndentSize = indentSize, }; } diff --git a/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs b/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs index 83b587fb962f7..17126929c0e09 100644 --- a/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs +++ b/src/libraries/System.Text.Json/gen/Model/SourceGenerationOptionsSpec.cs @@ -52,6 +52,10 @@ public sealed record SourceGenerationOptionsSpec public required bool? WriteIndented { get; init; } + public required char? IndentCharacter { get; init; } + + public required int? IndentSize { get; init; } + public JsonKnownNamingPolicy? GetEffectivePropertyNamingPolicy() => PropertyNamingPolicy ?? (Defaults is JsonSerializerDefaults.Web ? JsonKnownNamingPolicy.CamelCase : null); } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 6014c8e5dc630..25ccb474dbbb6 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -395,6 +395,8 @@ public JsonSerializerOptions(System.Text.Json.JsonSerializerOptions options) { } public System.Text.Json.Serialization.JsonUnknownTypeHandling UnknownTypeHandling { get { throw null; } set { } } public System.Text.Json.Serialization.JsonUnmappedMemberHandling UnmappedMemberHandling { get { throw null; } set { } } public bool WriteIndented { get { throw null; } set { } } + public char IndentCharacter { get { throw null; } set { } } + public int IndentSize { get { throw null; } set { } } [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ObsoleteAttribute("JsonSerializerOptions.AddContext is obsolete. To register a JsonSerializerContext, use either the TypeInfoResolver or TypeInfoResolverChain properties.", DiagnosticId="SYSLIB0049", UrlFormat="https://aka.ms/dotnet-warnings/{0}")] public void AddContext() where TContext : System.Text.Json.Serialization.JsonSerializerContext, new() { } @@ -440,6 +442,8 @@ public partial struct JsonWriterOptions private int _dummyPrimitive; public System.Text.Encodings.Web.JavaScriptEncoder? Encoder { readonly get { throw null; } set { } } public bool Indented { get { throw null; } set { } } + public char IndentCharacter { get { throw null; } set { } } + public int IndentSize { get { throw null; } set { } } public int MaxDepth { readonly get { throw null; } set { } } public bool SkipValidation { get { throw null; } set { } } } @@ -1075,6 +1079,8 @@ public JsonSourceGenerationOptionsAttribute(System.Text.Json.JsonSerializerDefau public System.Text.Json.Serialization.JsonUnmappedMemberHandling UnmappedMemberHandling { get { throw null; } set { } } public bool UseStringEnumConverter { get { throw null; } set { } } public bool WriteIndented { get { throw null; } set { } } + public char IndentCharacter { get { throw null; } set { } } + public int IndentSize { get { throw null; } set { } } } [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("JsonStringEnumConverter cannot be statically analyzed and requires runtime code generation. Applications should use the generic JsonStringEnumConverter instead.")] public partial class JsonStringEnumConverter : System.Text.Json.Serialization.JsonConverterFactory diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 411d20d45d6be..acd31cc6cce25 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -708,4 +708,10 @@ Either the JSON value is not in a supported format, or is out of bounds for a Half. + + Supported indentation characters are space and horizontal tab. + + + Indentation size must be between {0} and {1}. + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 30751a04a363e..99012e30e8b36 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -47,7 +47,6 @@ internal static partial class JsonConstants // Explicitly skipping ReverseSolidus since that is handled separately public static ReadOnlySpan EscapableChars => "\"nrt/ubf"u8; - public const int SpacesPerIndent = 2; public const int RemoveFlagsBitMask = 0x7FFFFFFF; // In the worst case, an ASCII character represented as a single utf-8 byte could expand 6x when escaped. @@ -110,5 +109,13 @@ internal static partial class JsonConstants // The maximum number of parameters a constructor can have where it can be considered // for a path on deserialization where we don't box the constructor arguments. public const int UnboxedParameterCountThreshold = 4; + + // Two space characters is the default indentation. + public const char DefaultIndentCharacter = ' '; + public const char TabIndentCharacter = '\t'; + public const int DefaultIndentSize = 2; + public const int MinimumIndentSize = 0; + public const int MaximumIndentSize = 127; // If this value is changed, the impact on the options masking used in the JsonWriterOptions struct must be checked carefully. + } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs index 68551c7eedf12..f76bdea2de2a3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs @@ -511,6 +511,8 @@ public bool Equals(JsonSerializerOptions? left, JsonSerializerOptions? right) left._includeFields == right._includeFields && left._propertyNameCaseInsensitive == right._propertyNameCaseInsensitive && left._writeIndented == right._writeIndented && + left._indentCharacter == right._indentCharacter && + left._indentSize == right._indentSize && left._typeInfoResolver == right._typeInfoResolver && CompareLists(left._converters, right._converters); @@ -565,6 +567,8 @@ public int GetHashCode(JsonSerializerOptions options) AddHashCode(ref hc, options._includeFields); AddHashCode(ref hc, options._propertyNameCaseInsensitive); AddHashCode(ref hc, options._writeIndented); + AddHashCode(ref hc, options._indentCharacter); + AddHashCode(ref hc, options._indentSize); AddHashCode(ref hc, options._typeInfoResolver); AddListHashCode(ref hc, options._converters); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index 20df47b466649..78d02af2b7846 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -90,6 +90,8 @@ public static JsonSerializerOptions Web private bool _includeFields; private bool _propertyNameCaseInsensitive; private bool _writeIndented; + private char _indentCharacter = JsonConstants.DefaultIndentCharacter; + private int _indentSize = JsonConstants.DefaultIndentSize; /// /// Constructs a new instance. @@ -139,6 +141,8 @@ public JsonSerializerOptions(JsonSerializerOptions options) _includeFields = options._includeFields; _propertyNameCaseInsensitive = options._propertyNameCaseInsensitive; _writeIndented = options._writeIndented; + _indentCharacter = options._indentCharacter; + _indentSize = options._indentSize; _typeInfoResolver = options._typeInfoResolver; EffectiveMaxDepth = options.EffectiveMaxDepth; ReferenceHandlingStrategy = options.ReferenceHandlingStrategy; @@ -660,6 +664,50 @@ public bool WriteIndented } } + /// + /// Defines the indentation character being used when is enabled. Defaults to the space character. + /// + /// Allowed characters are space and horizontal tab. + /// contains an invalid character. + /// + /// Thrown if this property is set after serialization or deserialization has occurred. + /// + public char IndentCharacter + { + get + { + return _indentCharacter; + } + set + { + JsonWriterHelper.ValidateIndentCharacter(value); + VerifyMutable(); + _indentCharacter = value; + } + } + + /// + /// Defines the indentation size being used when is enabled. Defaults to two. + /// + /// Allowed values are all integers between 0 and 127, included. + /// is out of the allowed range. + /// + /// Thrown if this property is set after serialization or deserialization has occurred. + /// + public int IndentSize + { + get + { + return _indentSize; + } + set + { + JsonWriterHelper.ValidateIndentSize(value); + VerifyMutable(); + _indentSize = value; + } + } + /// /// Configures how object references are handled when reading and writing JSON. /// @@ -891,6 +939,8 @@ internal JsonWriterOptions GetWriterOptions() { Encoder = Encoder, Indented = WriteIndented, + IndentCharacter = IndentCharacter, + IndentSize = IndentSize, MaxDepth = EffectiveMaxDepth, #if !DEBUG SkipValidation = true diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs index 3d8913f8d2c78..58bd0a7172491 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.cs @@ -12,6 +12,18 @@ internal static partial class ThrowHelper // If the exception source is this value, the serializer will re-throw as JsonException. public const string ExceptionSourceValueToRethrowAsJsonException = "System.Text.Json.Rethrowable"; + [DoesNotReturn] + public static void ThrowArgumentOutOfRangeException_IndentCharacter(string parameterName) + { + throw GetArgumentOutOfRangeException(parameterName, SR.InvalidIndentCharacter); + } + + [DoesNotReturn] + public static void ThrowArgumentOutOfRangeException_IndentSize(string parameterName, int minimumSize, int maximumSize) + { + throw GetArgumentOutOfRangeException(parameterName, SR.Format(SR.InvalidIndentSize, minimumSize, maximumSize)); + } + [DoesNotReturn] public static void ThrowArgumentOutOfRangeException_MaxDepthMustBePositive(string parameterName) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs index 97037ddbff727..c34c8cd3d672f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterHelper.cs @@ -10,9 +10,8 @@ namespace System.Text.Json { internal static partial class JsonWriterHelper { - public static void WriteIndentation(Span buffer, int indent) + public static void WriteIndentation(Span buffer, int indent, byte indentByte) { - Debug.Assert(indent % JsonConstants.SpacesPerIndent == 0); Debug.Assert(buffer.Length >= indent); // Based on perf tests, the break-even point where vectorized Fill is faster @@ -20,18 +19,37 @@ public static void WriteIndentation(Span buffer, int indent) if (indent < 8) { int i = 0; - while (i < indent) + while (i + 1 < indent) { - buffer[i++] = JsonConstants.Space; - buffer[i++] = JsonConstants.Space; + buffer[i++] = indentByte; + buffer[i++] = indentByte; + } + + if (i < indent) + { + buffer[i] = indentByte; } } else { - buffer.Slice(0, indent).Fill(JsonConstants.Space); + buffer.Slice(0, indent).Fill(indentByte); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateIndentCharacter(char value) + { + if (value is not JsonConstants.DefaultIndentCharacter and not JsonConstants.TabIndentCharacter) + ThrowHelper.ThrowArgumentOutOfRangeException_IndentCharacter(nameof(value)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ValidateIndentSize(int value) + { + if (value is < JsonConstants.MinimumIndentSize or > JsonConstants.MaximumIndentSize) + ThrowHelper.ThrowArgumentOutOfRangeException_IndentSize(nameof(value), JsonConstants.MinimumIndentSize, JsonConstants.MaximumIndentSize); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void ValidateProperty(ReadOnlySpan propertyName) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs index 2d89a261e3353..1d89e5d6aa149 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/JsonWriterOptions.cs @@ -43,6 +43,48 @@ public bool Indented } } + /// + /// Defines the indentation character used by when is enabled. Defaults to the space character. + /// + /// Allowed characters are space and horizontal tab. + /// contains an invalid character. + public char IndentCharacter + { + readonly get => (_optionsMask & IndentCharacterBit) != 0 ? JsonConstants.TabIndentCharacter : JsonConstants.DefaultIndentCharacter; + set + { + JsonWriterHelper.ValidateIndentCharacter(value); + if (value is not JsonConstants.DefaultIndentCharacter) + _optionsMask |= IndentCharacterBit; + else + _optionsMask &= ~IndentCharacterBit; + } + } + + /// + /// Defines the indentation size used by when is enabled. Defaults to two. + /// + /// Allowed values are integers between 0 and 127, included. + /// is out of the allowed range. + public int IndentSize + { + readonly get => EncodeIndentSize((_optionsMask & IndentSizeMask) >> 3); + set + { + JsonWriterHelper.ValidateIndentSize(value); + _optionsMask = (_optionsMask & ~IndentSizeMask) | (EncodeIndentSize(value) << 3); + } + } + + // Encoding is applied by swapping 0 with the default value to ensure default(JsonWriterOptions) instances are well-defined. + // As this operation is symmetrical, it can also be used to decode. + private static int EncodeIndentSize(int value) => value switch + { + 0 => JsonConstants.DefaultIndentSize, + JsonConstants.DefaultIndentSize => 0, + _ => value + }; + /// /// Gets or sets the maximum depth allowed when writing JSON, with the default (i.e. 0) indicating a max depth of 1000. /// @@ -93,9 +135,11 @@ public bool SkipValidation } } - internal bool IndentedOrNotSkipValidation => _optionsMask != SkipValidationBit; // Equivalent to: Indented || !SkipValidation; + internal bool IndentedOrNotSkipValidation => (_optionsMask & (IndentBit | SkipValidationBit)) != SkipValidationBit; // Equivalent to: Indented || !SkipValidation; private const int IndentBit = 1; private const int SkipValidationBit = 2; + private const int IndentCharacterBit = 4; + private const int IndentSizeMask = JsonConstants.MaximumIndentSize << 3; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs index 9c4785e56bfab..a8d53aef63dec 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Bytes.cs @@ -280,7 +280,7 @@ private void WriteBase64Minimized(ReadOnlySpan escapedPropertyName, ReadOn private void WriteBase64Indented(ReadOnlySpan escapedPropertyName, ReadOnlySpan bytes) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int encodedLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length); @@ -309,7 +309,7 @@ private void WriteBase64Indented(ReadOnlySpan escapedPropertyName, ReadOnl WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -330,7 +330,7 @@ private void WriteBase64Indented(ReadOnlySpan escapedPropertyName, ReadOnl private void WriteBase64Indented(ReadOnlySpan escapedPropertyName, ReadOnlySpan bytes) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int encodedLength = Base64.GetMaxEncodedToUtf8Length(bytes.Length); @@ -359,7 +359,7 @@ private void WriteBase64Indented(ReadOnlySpan escapedPropertyName, ReadOnl WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs index 55c079f008faa..392facd7d85ee 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTime.cs @@ -284,7 +284,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, DateTi private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTime value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatDateTimeOffsetLength - 7 - s_newLineLength); @@ -311,7 +311,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -333,7 +333,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTime value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatDateTimeOffsetLength - 7 - s_newLineLength); @@ -359,7 +359,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs index 9ace783d791e4..313693b3b7665 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.DateTimeOffset.cs @@ -283,7 +283,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, DateTi private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTimeOffset value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatDateTimeOffsetLength - 7 - s_newLineLength); @@ -310,7 +310,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -332,7 +332,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTimeOffset value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatDateTimeOffsetLength - 7 - s_newLineLength); @@ -358,7 +358,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, DateTim WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs index 933fcffc4fc1b..3f1af56067cd9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Decimal.cs @@ -277,7 +277,7 @@ private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, decima private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatDecimalLength - 5 - s_newLineLength); @@ -304,7 +304,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -323,7 +323,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatDecimalLength - 5 - s_newLineLength); @@ -349,7 +349,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, decimal WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs index 73bcc75f72ede..eee0535903cfa 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Double.cs @@ -281,7 +281,7 @@ private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, double private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatDoubleLength - 5 - s_newLineLength); @@ -308,7 +308,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -327,7 +327,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatDoubleLength - 5 - s_newLineLength); @@ -353,7 +353,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, double WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs index bb695740d290f..133c95ece5d86 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Float.cs @@ -281,7 +281,7 @@ private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, float private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatSingleLength - 5 - s_newLineLength); @@ -308,7 +308,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float v WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -327,7 +327,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float v private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatSingleLength - 5 - s_newLineLength); @@ -353,7 +353,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, float v WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs index a0c5713374ca1..1ded7b8f3f6a1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Guid.cs @@ -285,7 +285,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, Guid v private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatGuidLength - 7 - s_newLineLength); @@ -312,7 +312,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid va WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -335,7 +335,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid va private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatGuidLength - 7 - s_newLineLength); @@ -361,7 +361,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, Guid va WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs index cd56c0a99aa9e..c09aaa40c8a23 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Helpers.cs @@ -89,7 +89,7 @@ private void WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName, private void WritePropertyNameIndented(ReadOnlySpan escapedPropertyName, byte token) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - 6 - s_newLineLength); @@ -115,7 +115,7 @@ private void WritePropertyNameIndented(ReadOnlySpan escapedPropertyName, b WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -161,7 +161,7 @@ private void WritePropertyNameMinimized(ReadOnlySpan escapedPropertyName, private void WritePropertyNameIndented(ReadOnlySpan escapedPropertyName, byte token) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - 6 - s_newLineLength); @@ -188,7 +188,7 @@ private void WritePropertyNameIndented(ReadOnlySpan escapedPropertyName, b WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs index e73131b7192f9..aff0da471b1a3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.Literal.cs @@ -427,7 +427,7 @@ private void WriteLiteralSection(ReadOnlySpan escapedPropertyNameSection, private void WriteLiteralIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(value.Length <= JsonConstants.MaxUnescapedTokenSize); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - value.Length - 5 - s_newLineLength); @@ -455,7 +455,7 @@ private void WriteLiteralIndented(ReadOnlySpan escapedPropertyName, ReadOn WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -473,7 +473,7 @@ private void WriteLiteralIndented(ReadOnlySpan escapedPropertyName, ReadOn private void WriteLiteralIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(value.Length <= JsonConstants.MaxUnescapedTokenSize); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - value.Length - 5 - s_newLineLength); @@ -500,7 +500,7 @@ private void WriteLiteralIndented(ReadOnlySpan escapedPropertyName, ReadOn WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs index 10c390a98ffc4..82694f738cc76 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.SignedNumber.cs @@ -353,7 +353,7 @@ private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, long v private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatInt64Length - 5 - s_newLineLength); @@ -380,7 +380,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long va WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -399,7 +399,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long va private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatInt64Length - 5 - s_newLineLength); @@ -425,7 +425,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, long va WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs index 7db29516ddbe0..16629ea424f4c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.String.cs @@ -187,7 +187,7 @@ private void WriteStringMinimizedPropertyName(ReadOnlySpan escapedProperty private void WriteStringIndentedPropertyName(ReadOnlySpan escapedPropertyName) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxEscapedTokenSize); Debug.Assert(escapedPropertyName.Length < (int.MaxValue - 5 - indent - s_newLineLength) / JsonConstants.MaxExpansionFactorWhileTranscoding); @@ -213,7 +213,7 @@ private void WriteStringIndentedPropertyName(ReadOnlySpan escapedPropertyN WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -375,7 +375,7 @@ private void WriteStringPropertyNameSection(ReadOnlySpan escapedPropertyNa private void WriteStringIndentedPropertyName(ReadOnlySpan escapedPropertyName) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length <= JsonConstants.MaxEscapedTokenSize); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - 5 - s_newLineLength); @@ -402,7 +402,7 @@ private void WriteStringIndentedPropertyName(ReadOnlySpan escapedPropertyN WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -1513,7 +1513,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedPropertyName, ReadOn private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize); Debug.Assert(escapedPropertyName.Length < ((int.MaxValue - 7 - indent - s_newLineLength) / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length); @@ -1541,7 +1541,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -1563,7 +1563,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - escapedValue.Length - 7 - s_newLineLength); @@ -1590,7 +1590,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -1614,7 +1614,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length - 7 - indent - s_newLineLength); @@ -1642,7 +1642,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -1665,7 +1665,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnlySpan escapedValue) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedValue.Length <= JsonConstants.MaxEscapedTokenSize); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - escapedValue.Length - 7 - indent - s_newLineLength); @@ -1693,7 +1693,7 @@ private void WriteStringIndented(ReadOnlySpan escapedPropertyName, ReadOnl WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs index ab73c36582c64..37aad46266599 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteProperties.UnsignedNumber.cs @@ -362,7 +362,7 @@ private void WriteNumberMinimized(ReadOnlySpan escapedPropertyName, ulong private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - JsonConstants.MaximumFormatUInt64Length - 5 - s_newLineLength); @@ -389,7 +389,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong v WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; @@ -408,7 +408,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong v private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedPropertyName.Length < int.MaxValue - indent - JsonConstants.MaximumFormatUInt64Length - 5 - s_newLineLength); @@ -434,7 +434,7 @@ private void WriteNumberIndented(ReadOnlySpan escapedPropertyName, ulong v WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = JsonConstants.Quote; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs index 6d04df1c3ce6e..31500fb2b00ec 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Bytes.cs @@ -88,7 +88,7 @@ private void WriteBase64Minimized(ReadOnlySpan bytes) private void WriteBase64Indented(ReadOnlySpan bytes) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); // Base64.GetMaxEncodedToUtf8Length checks to make sure the length is <= int.MaxValue / 4 * 3, // as a length longer than that would overflow int.MaxValue when Base64 encoded. However, we @@ -124,7 +124,7 @@ private void WriteBase64Indented(ReadOnlySpan bytes) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs index 7e3d3a30d661b..93f11451f454d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Comment.cs @@ -105,7 +105,7 @@ private void WriteCommentMinimized(ReadOnlySpan value) private void WriteCommentIndented(ReadOnlySpan value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(value.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - 4 - s_newLineLength); @@ -123,7 +123,7 @@ private void WriteCommentIndented(ReadOnlySpan value) if (_tokenType != JsonTokenType.None || _commentAfterNoneOrPropertyName) { WriteNewLine(output); - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } @@ -212,7 +212,7 @@ private void WriteCommentMinimized(ReadOnlySpan utf8Value) private void WriteCommentIndented(ReadOnlySpan utf8Value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(utf8Value.Length < int.MaxValue - indent - 4 - s_newLineLength); @@ -230,7 +230,7 @@ private void WriteCommentIndented(ReadOnlySpan utf8Value) { WriteNewLine(output); - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs index f87753be0ae37..ad8a887cdf55a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTime.cs @@ -66,7 +66,7 @@ private void WriteStringValueMinimized(DateTime value) private void WriteStringValueIndented(DateTime value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line int maxRequired = indent + JsonConstants.MaximumFormatDateTimeOffsetLength + 3 + s_newLineLength; @@ -89,7 +89,7 @@ private void WriteStringValueIndented(DateTime value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs index 2608606375b39..1ee48004f21fd 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.DateTimeOffset.cs @@ -67,7 +67,7 @@ private void WriteStringValueMinimized(DateTimeOffset value) private void WriteStringValueIndented(DateTimeOffset value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line int maxRequired = indent + JsonConstants.MaximumFormatDateTimeOffsetLength + 3 + s_newLineLength; @@ -90,7 +90,7 @@ private void WriteStringValueIndented(DateTimeOffset value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index 2462b667fe8ba..35089030c2d45 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -63,7 +63,7 @@ private void WriteNumberValueMinimized(decimal value) private void WriteNumberValueIndented(decimal value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int maxRequired = indent + JsonConstants.MaximumFormatDecimalLength + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line @@ -85,7 +85,7 @@ private void WriteNumberValueIndented(decimal value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index 036b9e3d12254..b638931ce1229 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -67,7 +67,7 @@ private void WriteNumberValueMinimized(double value) private void WriteNumberValueIndented(double value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int maxRequired = indent + JsonConstants.MaximumFormatDoubleLength + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line @@ -89,7 +89,7 @@ private void WriteNumberValueIndented(double value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index 5e173a7dc0ece..c1755c7c4dc5d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -67,7 +67,7 @@ private void WriteNumberValueMinimized(float value) private void WriteNumberValueIndented(float value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int maxRequired = indent + JsonConstants.MaximumFormatSingleLength + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line @@ -89,7 +89,7 @@ private void WriteNumberValueIndented(float value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs index f9005243fac4c..f4c902e184af4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.FormattedNumber.cs @@ -67,7 +67,7 @@ private void WriteNumberValueMinimized(ReadOnlySpan utf8Value) private void WriteNumberValueIndented(ReadOnlySpan utf8Value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(utf8Value.Length < int.MaxValue - indent - 1 - s_newLineLength); @@ -91,7 +91,7 @@ private void WriteNumberValueIndented(ReadOnlySpan utf8Value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs index 227af26a3d2c0..695cc83e03680 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Guid.cs @@ -67,7 +67,7 @@ private void WriteStringValueMinimized(Guid value) private void WriteStringValueIndented(Guid value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); // 2 quotes, and optionally, 1 list separator and 1-2 bytes for new line int maxRequired = indent + JsonConstants.MaximumFormatGuidLength + 3 + s_newLineLength; @@ -90,7 +90,7 @@ private void WriteStringValueIndented(Guid value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs index b4bcc5b480246..8c0dee44e785e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Literal.cs @@ -86,7 +86,7 @@ private void WriteLiteralMinimized(ReadOnlySpan utf8Value) private void WriteLiteralIndented(ReadOnlySpan utf8Value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(utf8Value.Length <= 5); int maxRequired = indent + utf8Value.Length + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line @@ -109,7 +109,7 @@ private void WriteLiteralIndented(ReadOnlySpan utf8Value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index dd47dfe230550..b2126de77fb2f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -76,7 +76,7 @@ private void WriteNumberValueMinimized(long value) private void WriteNumberValueIndented(long value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int maxRequired = indent + JsonConstants.MaximumFormatInt64Length + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line @@ -98,7 +98,7 @@ private void WriteNumberValueIndented(long value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index 6513d001930b7..4ede0fc9bce93 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -143,7 +143,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedValue) private void WriteStringIndented(ReadOnlySpan escapedValue) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedValue.Length < (int.MaxValue / JsonConstants.MaxExpansionFactorWhileTranscoding) - indent - 3 - s_newLineLength); @@ -169,7 +169,7 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } @@ -290,7 +290,7 @@ private void WriteStringMinimized(ReadOnlySpan escapedValue) private void WriteStringIndented(ReadOnlySpan escapedValue) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(escapedValue.Length < int.MaxValue - indent - 3 - s_newLineLength); @@ -315,7 +315,7 @@ private void WriteStringIndented(ReadOnlySpan escapedValue) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index a348c125c8172..82ec4677b2224 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -78,7 +78,7 @@ private void WriteNumberValueMinimized(ulong value) private void WriteNumberValueIndented(ulong value) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int maxRequired = indent + JsonConstants.MaximumFormatUInt64Length + 1 + s_newLineLength; // Optionally, 1 list separator and 1-2 bytes for new line @@ -100,7 +100,7 @@ private void WriteNumberValueIndented(ulong value) { WriteNewLine(output); } - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs index c84b864a0cfec..315b7a30b8e20 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.cs @@ -58,6 +58,10 @@ public sealed partial class Utf8JsonWriter : IDisposable, IAsyncDisposable private JsonWriterOptions _options; // Since JsonWriterOptions is a struct, use a field to avoid a copy for internal code. + // Cache indentation settings from JsonWriterOptions to avoid recomputing them in the hot path. + private byte _indentByte; + private int _indentLength; + /// /// Returns the amount of bytes written by the so far /// that have not yet been flushed to the output and committed. @@ -80,7 +84,7 @@ public sealed partial class Utf8JsonWriter : IDisposable, IAsyncDisposable /// public JsonWriterOptions Options => _options; - private int Indentation => CurrentDepth * JsonConstants.SpacesPerIndent; + private int Indentation => CurrentDepth * _indentLength; internal JsonTokenType TokenType => _tokenType; @@ -112,12 +116,7 @@ public Utf8JsonWriter(IBufferWriter bufferWriter, JsonWriterOptions option } _output = bufferWriter; - _options = options; - - if (_options.MaxDepth == 0) - { - _options.MaxDepth = JsonWriterOptions.DefaultMaxDepth; // If max depth is not set, revert to the default depth. - } + SetOptions(options); } /// @@ -141,14 +140,21 @@ public Utf8JsonWriter(Stream utf8Json, JsonWriterOptions options = default) throw new ArgumentException(SR.StreamNotWritable); _stream = utf8Json; + SetOptions(options); + + _arrayBufferWriter = new ArrayBufferWriter(); + } + + private void SetOptions(JsonWriterOptions options) + { _options = options; + _indentByte = (byte)_options.IndentCharacter; + _indentLength = options.IndentSize; if (_options.MaxDepth == 0) { _options.MaxDepth = JsonWriterOptions.DefaultMaxDepth; // If max depth is not set, revert to the default depth. } - - _arrayBufferWriter = new ArrayBufferWriter(); } /// @@ -245,11 +251,7 @@ internal void Reset(IBufferWriter bufferWriter, JsonWriterOptions options) Debug.Assert(_output is null && _stream is null && _arrayBufferWriter is null); _output = bufferWriter; - _options = options; - if (_options.MaxDepth == 0) - { - _options.MaxDepth = JsonWriterOptions.DefaultMaxDepth; // If max depth is not set, revert to the default depth. - } + SetOptions(options); } internal static Utf8JsonWriter CreateEmptyInstanceForCaching() => new Utf8JsonWriter(); @@ -553,7 +555,7 @@ private void ValidateStart() private void WriteStartIndented(byte token) { int indent = Indentation; - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); int minRequired = indent + 1; // 1 start token int maxRequired = minRequired + 3; // Optionally, 1 list separator and 1-2 bytes for new line @@ -573,7 +575,7 @@ private void WriteStartIndented(byte token) if (_tokenType is not JsonTokenType.PropertyName and not JsonTokenType.None || _commentAfterNoneOrPropertyName) { WriteNewLine(output); - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; } @@ -994,10 +996,10 @@ private void WriteEndIndented(byte token) { // The end token should be at an outer indent and since we haven't updated // current depth yet, explicitly subtract here. - indent -= JsonConstants.SpacesPerIndent; + indent -= _indentLength; } - Debug.Assert(indent <= 2 * _options.MaxDepth); + Debug.Assert(indent <= _indentLength * _options.MaxDepth); Debug.Assert(_options.SkipValidation || _tokenType != JsonTokenType.None); int maxRequired = indent + 3; // 1 end token, 1-2 bytes for new line @@ -1011,7 +1013,7 @@ private void WriteEndIndented(byte token) WriteNewLine(output); - JsonWriterHelper.WriteIndentation(output.Slice(BytesPending), indent); + WriteIndentation(output.Slice(BytesPending), indent); BytesPending += indent; output[BytesPending++] = token; @@ -1029,6 +1031,11 @@ private void WriteNewLine(Span output) output[BytesPending++] = JsonConstants.LineFeed; } + private void WriteIndentation(Span buffer, int indent) + { + JsonWriterHelper.WriteIndentation(buffer, indent, _indentByte); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private void UpdateBitStackOnStart(byte token) { diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSourceGenerationOptionsTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSourceGenerationOptionsTests.cs index eb855b0241dfd..9c1c30818f6b2 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSourceGenerationOptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/JsonSourceGenerationOptionsTests.cs @@ -78,6 +78,8 @@ public static void ContextWithAllOptionsSet_GeneratesExpectedOptions() UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode, UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow, WriteIndented = true, + IndentCharacter = '\t', + IndentSize = 1, TypeInfoResolver = ContextWithAllOptionsSet.Default, }; @@ -104,7 +106,9 @@ public static void ContextWithAllOptionsSet_GeneratesExpectedOptions() ReadCommentHandling = JsonCommentHandling.Skip, UnknownTypeHandling = JsonUnknownTypeHandling.JsonNode, UnmappedMemberHandling = JsonUnmappedMemberHandling.Disallow, - WriteIndented = true)] + WriteIndented = true, + IndentCharacter = '\t', + IndentSize = 1)] [JsonSerializable(typeof(PersonStruct))] public partial class ContextWithAllOptionsSet : JsonSerializerContext { } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonWriterOptionsTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonWriterOptionsTests.cs index 41a6c5c203a91..127ca9601150d 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonWriterOptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/JsonWriterOptionsTests.cs @@ -15,6 +15,8 @@ public static void JsonWriterOptionsDefaultCtor() var expectedOption = new JsonWriterOptions { Indented = false, + IndentCharacter = ' ', + IndentSize = 2, SkipValidation = false, MaxDepth = 0, }; @@ -29,6 +31,8 @@ public static void JsonWriterOptionsCtor() var expectedOption = new JsonWriterOptions { Indented = false, + IndentCharacter = ' ', + IndentSize = 2, SkipValidation = false, MaxDepth = 0, }; @@ -36,26 +40,92 @@ public static void JsonWriterOptionsCtor() } [Theory] - [InlineData(true, true, 0)] - [InlineData(true, false, 1)] - [InlineData(false, true, 1024)] - [InlineData(false, false, 1024 * 1024)] - public static void JsonWriterOptions(bool indented, bool skipValidation, int maxDepth) + [InlineData(true, '\t', 1, true, 0)] + [InlineData(true, ' ', 127, false, 1)] + [InlineData(false, ' ', 0, true, 1024)] + [InlineData(false, ' ', 4, false, 1024 * 1024)] + public static void JsonWriterOptions(bool indented, char indentCharacter, int indentSize, bool skipValidation, int maxDepth) { var options = new JsonWriterOptions(); options.Indented = indented; + options.IndentCharacter = indentCharacter; + options.IndentSize = indentSize; options.SkipValidation = skipValidation; options.MaxDepth = maxDepth; var expectedOption = new JsonWriterOptions { Indented = indented, + IndentCharacter = indentCharacter, + IndentSize = indentSize, SkipValidation = skipValidation, MaxDepth = maxDepth, }; Assert.Equal(expectedOption, options); } + [Theory] + [InlineData(true, '\t', 1, true, 0)] + [InlineData(true, ' ', 127, false, 1)] + [InlineData(false, ' ', 0, true, 1024)] + [InlineData(false, ' ', 4, false, 1024 * 1024)] + public static void JsonWriterOptions_Properties(bool indented, char indentCharacter, int indentSize, bool skipValidation, int maxDepth) + { + var options = new JsonWriterOptions(); + options.Indented = indented; + options.IndentCharacter = indentCharacter; + options.IndentSize = indentSize; + options.SkipValidation = skipValidation; + options.MaxDepth = maxDepth; + + Assert.Equal(indented, options.Indented); + Assert.Equal(indentCharacter, options.IndentCharacter); + Assert.Equal(indentSize, options.IndentSize); + Assert.Equal(skipValidation, options.SkipValidation); + Assert.Equal(maxDepth, options.MaxDepth); + } + + [Fact] + public static void JsonWriterOptions_DefaultValues() + { + JsonWriterOptions options = default; + + Assert.False(options.Indented); + Assert.Equal(' ', options.IndentCharacter); + Assert.Equal(2, options.IndentSize); + Assert.False(options.SkipValidation); + Assert.Equal(0, options.MaxDepth); + } + + [Fact] + public static void JsonWriterOptions_MultipleValues() + { + JsonWriterOptions defaultOptions = default; + var options = new JsonWriterOptions(); + + options.Indented = true; + options.Indented = defaultOptions.Indented; + Assert.Equal(defaultOptions.Indented, options.Indented); + + options.IndentCharacter = '\t'; + options.IndentCharacter = defaultOptions.IndentCharacter; + Assert.Equal(defaultOptions.IndentCharacter, options.IndentCharacter); + + options.IndentSize = 127; + options.IndentSize = defaultOptions.IndentSize; + Assert.Equal(defaultOptions.IndentSize, options.IndentSize); + + options.SkipValidation = true; + options.SkipValidation = defaultOptions.SkipValidation; + Assert.Equal(defaultOptions.SkipValidation, options.SkipValidation); + + options.MaxDepth = 1024 * 1024; + options.MaxDepth = defaultOptions.MaxDepth; + Assert.Equal(defaultOptions.MaxDepth, options.MaxDepth); + + Assert.Equal(defaultOptions, options); + } + [Theory] [InlineData(-1)] [InlineData(-100)] @@ -64,5 +134,28 @@ public static void JsonWriterOptions_MaxDepth_InvalidParameters(int maxDepth) var options = new JsonWriterOptions(); Assert.Throws(() => options.MaxDepth = maxDepth); } + + [Theory] + [InlineData('\f')] + [InlineData('\n')] + [InlineData('\r')] + [InlineData('\0')] + [InlineData('a')] + public static void JsonWriterOptions_IndentCharacter_InvalidCharacter(char character) + { + var options = new JsonWriterOptions(); + Assert.Throws(() => options.IndentCharacter = character); + } + + [Theory] + [InlineData(-1)] + [InlineData(128)] + [InlineData(int.MinValue)] + [InlineData(int.MaxValue)] + public static void JsonWriterOptions_IndentSize_OutOfRange(int size) + { + var options = new JsonWriterOptions(); + Assert.Throws(() => options.IndentSize = size); + } } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs index 25c9e2084048b..50c6d865268fd 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/CacheTests.cs @@ -371,6 +371,8 @@ public static void JsonSerializerOptions_EqualityComparer_ChangingAnySettingShou yield return (GetProp(nameof(JsonSerializerOptions.ReadCommentHandling)), JsonCommentHandling.Skip); yield return (GetProp(nameof(JsonSerializerOptions.UnknownTypeHandling)), JsonUnknownTypeHandling.JsonNode); yield return (GetProp(nameof(JsonSerializerOptions.WriteIndented)), true); + yield return (GetProp(nameof(JsonSerializerOptions.IndentCharacter)), '\t'); + yield return (GetProp(nameof(JsonSerializerOptions.IndentSize)), 1); yield return (GetProp(nameof(JsonSerializerOptions.ReferenceHandler)), ReferenceHandler.Preserve); yield return (GetProp(nameof(JsonSerializerOptions.TypeInfoResolver)), new DefaultJsonTypeInfoResolver()); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/OptionsTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/OptionsTests.cs index 28bd0fb86cfe3..cbca460362c4b 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/OptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/OptionsTests.cs @@ -330,6 +330,90 @@ public static void WriteIndented() Assert.Contains(Environment.NewLine, json); } + [Theory] + [InlineData('\f')] + [InlineData('\n')] + [InlineData('\r')] + [InlineData('\0')] + [InlineData('a')] + public static void IndentCharacters_WithInvalidChartacters_ThrowsArgumentOutOfRangeException(char character) + { + var options = new JsonSerializerOptions(); + Assert.Throws(() => options.IndentCharacter = character); + } + + [Theory] + [InlineData(-1)] + [InlineData(128)] + [InlineData(int.MinValue)] + [InlineData(int.MaxValue)] + public static void IndentSize_WithInvalidSize_ThrowsArgumentOutOfRangeException(int size) + { + var options = new JsonSerializerOptions(); + Assert.Throws(() => options.IndentSize = size); + } + + [Fact] + public static void IndentCharacter() + { + var obj = new BasicCompany(); + obj.Initialize(); + + // Verify default value. + var defaultIndent = " "; + string json = JsonSerializer.Serialize(obj); + Assert.DoesNotContain(defaultIndent, json); + + // Verify default value on options. + var options = new JsonSerializerOptions(); + json = JsonSerializer.Serialize(obj, options); + Assert.DoesNotContain(defaultIndent, json); + + // Enable default indentation. + options = new JsonSerializerOptions(); + options.WriteIndented = true; + json = JsonSerializer.Serialize(obj, options); + Assert.Contains(defaultIndent, json); + + // Set custom indentCharacter without enabling indentation + var tab = '\t'; + Assert.DoesNotContain(tab, json); + options = new JsonSerializerOptions(); + options.IndentCharacter = tab; + json = JsonSerializer.Serialize(obj, options); + Assert.DoesNotContain(tab, json); + + // Set custom indentCharacter with indentation enabled + options = new JsonSerializerOptions(); + options.WriteIndented = true; + options.IndentCharacter = tab; + json = JsonSerializer.Serialize(obj, options); + Assert.Contains(tab, json); + } + + [Fact] + public static void IndentSize() + { + var obj = new BasicCompany(); + obj.Initialize(); + + var tab = '\t'; + // Set custom indentSize without enabling indentation + var options = new JsonSerializerOptions(); + options.IndentCharacter = tab; + options.IndentSize = 1; + var json = JsonSerializer.Serialize(obj, options); + Assert.DoesNotContain(tab, json); + + // Set custom indentSize with indentation enabled + options = new JsonSerializerOptions(); + options.WriteIndented = true; + options.IndentCharacter = tab; + options.IndentSize = 4; + json = JsonSerializer.Serialize(obj, options); + Assert.Contains(new string(tab, 4), json); + } + [Fact] public static void ExtensionDataUsesReaderOptions() { @@ -1329,6 +1413,10 @@ and not nameof(JsonSerializerOptions.IsReadOnly)) // Property is not structural { property.SetValue(options, 32); } + else if (propertyType == typeof(string)) + { + property.SetValue(options, "\t"); + } else if (propertyType == typeof(IList)) { options.Converters.Add(new JsonStringEnumConverter()); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs index 331f81947ae5d..643762183c713 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Utf8JsonWriterTests.cs @@ -8,6 +8,7 @@ using System.Globalization; using System.IO; using System.IO.Pipelines; +using System.Linq; using System.Text.Encodings.Web; using System.Text.Unicode; using System.Threading; @@ -64,15 +65,14 @@ public partial class Utf8JsonWriterTests /*Comment at start of doc*//*Multiple comment line*/{/*Comment before first object property*//*Multiple comment line*/"property1":/*Comment of string property value*/"stringValue","property2":/*Comment of object property value*/{}/*Comment in the middle of object*/,"property3":/*Comment of array property value*/[]/*Comment after the last property*/}/*Comment at end of doc*/ """; + public static IEnumerable JsonOptions_TestData() => + from options in JsonOptions() + select new object[] { options }; + [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void NullCtor(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void NullCtor(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - Assert.Throws(() => new Utf8JsonWriter((Stream)null)); Assert.Throws(() => new Utf8JsonWriter((IBufferWriter)null)); Assert.Throws(() => new Utf8JsonWriter((Stream)null, options)); @@ -80,13 +80,9 @@ public void NullCtor(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void CantWriteToNonWritableStream(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void CantWriteToNonWritableStream(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var stream = new MemoryStream(); stream.Dispose(); @@ -836,14 +832,9 @@ public void WriteLargeJsonToStreamWithoutFlushing() } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InitialState(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InitialState(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var stream = new MemoryStream(); using (var writer = new Utf8JsonWriter(stream, options)) { @@ -851,8 +842,8 @@ public void InitialState(bool formatted, bool skipValidation) Assert.Equal(0, writer.BytesPending); Assert.Equal(0, writer.CurrentDepth); Assert.Null(writer.Options.Encoder); - Assert.Equal(formatted, writer.Options.Indented); - Assert.Equal(skipValidation, writer.Options.SkipValidation); + Assert.Equal(options.Indented, writer.Options.Indented); + Assert.Equal(options.SkipValidation, writer.Options.SkipValidation); Assert.Equal(0, stream.Position); } @@ -863,21 +854,16 @@ public void InitialState(bool formatted, bool skipValidation) Assert.Equal(0, writer.BytesPending); Assert.Equal(0, writer.CurrentDepth); Assert.Null(writer.Options.Encoder); - Assert.Equal(formatted, writer.Options.Indented); - Assert.Equal(skipValidation, writer.Options.SkipValidation); + Assert.Equal(options.Indented, writer.Options.Indented); + Assert.Equal(options.SkipValidation, writer.Options.SkipValidation); Assert.Equal(0, output.FormattedCount); } } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void Reset(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void Reset(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var stream = new MemoryStream(); using var writeToStream = new Utf8JsonWriter(stream, options); writeToStream.WriteNumberValue(1); @@ -890,8 +876,8 @@ public void Reset(bool formatted, bool skipValidation) Assert.Equal(0, writeToStream.BytesPending); Assert.Equal(0, writeToStream.CurrentDepth); Assert.Null(writeToStream.Options.Encoder); - Assert.Equal(formatted, writeToStream.Options.Indented); - Assert.Equal(skipValidation, writeToStream.Options.SkipValidation); + Assert.Equal(options.Indented, writeToStream.Options.Indented); + Assert.Equal(options.SkipValidation, writeToStream.Options.SkipValidation); Assert.True(stream.Position != 0); long previousWritten = stream.Position; @@ -910,8 +896,8 @@ public void Reset(bool formatted, bool skipValidation) Assert.Equal(0, writeToIBW.BytesPending); Assert.Equal(0, writeToIBW.CurrentDepth); Assert.Null(writeToIBW.Options.Encoder); - Assert.Equal(formatted, writeToIBW.Options.Indented); - Assert.Equal(skipValidation, writeToIBW.Options.SkipValidation); + Assert.Equal(options.Indented, writeToIBW.Options.Indented); + Assert.Equal(options.SkipValidation, writeToIBW.Options.SkipValidation); Assert.True(output.FormattedCount != 0); previousWritten = output.FormattedCount; @@ -920,14 +906,9 @@ public void Reset(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void ResetWithSameOutput(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void ResetWithSameOutput(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var stream = new MemoryStream(); using var writeToStream = new Utf8JsonWriter(stream, options); writeToStream.WriteNumberValue(1); @@ -940,8 +921,8 @@ public void ResetWithSameOutput(bool formatted, bool skipValidation) Assert.Equal(0, writeToStream.BytesPending); Assert.Equal(0, writeToStream.CurrentDepth); Assert.Null(writeToStream.Options.Encoder); - Assert.Equal(formatted, writeToStream.Options.Indented); - Assert.Equal(skipValidation, writeToStream.Options.SkipValidation); + Assert.Equal(options.Indented, writeToStream.Options.Indented); + Assert.Equal(options.SkipValidation, writeToStream.Options.SkipValidation); Assert.True(stream.Position != 0); long previousWritten = stream.Position; @@ -966,8 +947,8 @@ public void ResetWithSameOutput(bool formatted, bool skipValidation) Assert.Equal(0, writeToIBW.BytesPending); Assert.Equal(0, writeToIBW.CurrentDepth); Assert.Null(writeToIBW.Options.Encoder); - Assert.Equal(formatted, writeToIBW.Options.Indented); - Assert.Equal(skipValidation, writeToIBW.Options.SkipValidation); + Assert.Equal(options.Indented, writeToIBW.Options.Indented); + Assert.Equal(options.SkipValidation, writeToIBW.Options.SkipValidation); Assert.True(output.FormattedCount != 0); previousWritten = output.FormattedCount; @@ -982,14 +963,9 @@ public void ResetWithSameOutput(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void ResetChangeOutputMode(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void ResetChangeOutputMode(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var stream = new MemoryStream(); using var writeToStream = new Utf8JsonWriter(stream, options); writeToStream.WriteNumberValue(1); @@ -1003,8 +979,8 @@ public void ResetChangeOutputMode(bool formatted, bool skipValidation) Assert.Equal(0, writeToStream.BytesPending); Assert.Equal(0, writeToStream.CurrentDepth); Assert.Null(writeToStream.Options.Encoder); - Assert.Equal(formatted, writeToStream.Options.Indented); - Assert.Equal(skipValidation, writeToStream.Options.SkipValidation); + Assert.Equal(options.Indented, writeToStream.Options.Indented); + Assert.Equal(options.SkipValidation, writeToStream.Options.SkipValidation); Assert.True(stream.Position != 0); long previousWrittenStream = stream.Position; @@ -1034,8 +1010,8 @@ public void ResetChangeOutputMode(bool formatted, bool skipValidation) Assert.Equal(0, writeToIBW.BytesPending); Assert.Equal(0, writeToIBW.CurrentDepth); Assert.Null(writeToIBW.Options.Encoder); - Assert.Equal(formatted, writeToIBW.Options.Indented); - Assert.Equal(skipValidation, writeToIBW.Options.SkipValidation); + Assert.Equal(options.Indented, writeToIBW.Options.Indented); + Assert.Equal(options.SkipValidation, writeToIBW.Options.SkipValidation); Assert.True(output.FormattedCount != 0); previousWrittenStream = stream.Position; @@ -1054,14 +1030,9 @@ public void ResetChangeOutputMode(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidReset(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InvalidReset(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var stream = new MemoryStream(); using var writeToStream = new Utf8JsonWriter(stream, options); @@ -1082,13 +1053,9 @@ public void InvalidReset(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void FlushEmpty(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void FlushEmpty(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(0); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1104,13 +1071,9 @@ public void FlushEmpty(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task FlushEmptyAsync(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public async Task FlushEmptyAsync(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(0); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1126,13 +1089,9 @@ public async Task FlushEmptyAsync(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void FlushMultipleTimes(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void FlushMultipleTimes(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(256); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1168,13 +1127,9 @@ public void FlushMultipleTimes(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task FlushMultipleTimesAsync(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public async Task FlushMultipleTimesAsync(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(256); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1210,13 +1165,9 @@ public async Task FlushMultipleTimesAsync(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void DisposeAutoFlushes(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void DisposeAutoFlushes(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(256); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1240,13 +1191,9 @@ public void DisposeAutoFlushes(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task DisposeAutoFlushesAsync(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public async Task DisposeAutoFlushesAsync(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(256); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1270,13 +1217,9 @@ public async Task DisposeAutoFlushesAsync(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void UseAfterDisposeInvalid(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void UseAfterDisposeInvalid(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(256); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1316,13 +1259,9 @@ public void UseAfterDisposeInvalid(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task UseAfterDisposeInvalidAsync(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public async Task UseAfterDisposeInvalidAsync(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new FixedSizedBufferWriter(256); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1419,13 +1358,9 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidBufferWriter(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InvalidBufferWriter(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new InvalidBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1434,34 +1369,26 @@ public void InvalidBufferWriter(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task WriteLargeToStream(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public async Task WriteLargeToStream(JsonWriterOptions options) { var stream = new MemoryStream(); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + await WriteLargeToStreamHelper(stream, options); - string expectedString = GetExpectedLargeString(formatted); + string expectedString = GetExpectedLargeString(options); string actualString = Encoding.UTF8.GetString(stream.ToArray()); Assert.Equal(expectedString, actualString); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void GrowBeyondBufferSize(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void GrowBeyondBufferSize(JsonWriterOptions options) { const int InitialGrowthSize = 256; var output = new FixedSizedBufferWriter(InitialGrowthSize); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + byte[] utf8String = "this is a string long enough to overflow the buffer and cause an exception to be thrown."u8.ToArray(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -1496,14 +1423,14 @@ private static async Task WriteLargeToStreamHelper(Stream stream, JsonWriterOpti jsonUtf8.WriteEndArray(); } - private static string GetExpectedLargeString(bool prettyPrint) + private static string GetExpectedLargeString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartArray(); @@ -1515,19 +1442,15 @@ private static string GetExpectedLargeString(bool prettyPrint) json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void FixedSizeBufferWriter_Guid(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void FixedSizeBufferWriter_Guid(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - - int sizeTooSmall = 256; + int sizeTooSmall = options.Indented ? options.IndentSize + 229 : 225; + sizeTooSmall = Math.Max(sizeTooSmall, 256); var output = new FixedSizedBufferWriter(sizeTooSmall); byte[] utf8String = Encoding.UTF8.GetBytes(new string('a', 215)); @@ -1541,7 +1464,7 @@ public void FixedSizeBufferWriter_Guid(bool formatted, bool skipValidation) Assert.Throws(() => jsonUtf8.WriteStringValue(guid)); } - sizeTooSmall += formatted ? 9 : 1; + sizeTooSmall += options.Indented ? options.IndentSize + 40 : 38; output = new FixedSizedBufferWriter(sizeTooSmall); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -1552,7 +1475,7 @@ public void FixedSizeBufferWriter_Guid(bool formatted, bool skipValidation) } string actualStr = Encoding.UTF8.GetString(output.Formatted); - if (!formatted) + if (!options.Indented) { Assert.Equal(257, output.Formatted.Length); } @@ -1560,15 +1483,11 @@ public void FixedSizeBufferWriter_Guid(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void FixedSizeBufferWriter_DateTime(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - - int sizeTooSmall = 256; + int sizeTooSmall = options.Indented ? options.IndentSize + 240 : 236; + sizeTooSmall = Math.Max(sizeTooSmall, 256); var output = new FixedSizedBufferWriter(sizeTooSmall); byte[] utf8String = Encoding.UTF8.GetBytes(new string('a', 232)); @@ -1582,7 +1501,7 @@ public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) Assert.Throws(() => jsonUtf8.WriteStringValue(date)); } - sizeTooSmall += formatted ? 23 : 15; + sizeTooSmall += options.Indented ? options.IndentSize + 37 : 35; output = new FixedSizedBufferWriter(sizeTooSmall); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -1593,7 +1512,7 @@ public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) } string actualStr = Encoding.UTF8.GetString(output.Formatted); - if (!formatted) + if (!options.Indented) { Assert.Equal(257, output.Formatted.Length); } @@ -1601,15 +1520,11 @@ public void FixedSizeBufferWriter_DateTime(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void FixedSizeBufferWriter_DateTimeOffset(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - - int sizeTooSmall = 256; + int sizeTooSmall = options.Indented ? options.IndentSize + 240 : 236; + sizeTooSmall = Math.Max(sizeTooSmall, 256); var output = new FixedSizedBufferWriter(sizeTooSmall); byte[] utf8String = Encoding.UTF8.GetBytes(new string('a', 226)); @@ -1623,7 +1538,7 @@ public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValida Assert.Throws(() => jsonUtf8.WriteStringValue(date)); } - sizeTooSmall += formatted ? 23 : 15; + sizeTooSmall += options.Indented ? options.IndentSize + 37 : 35; output = new FixedSizedBufferWriter(sizeTooSmall); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -1634,7 +1549,7 @@ public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValida } string actualStr = Encoding.UTF8.GetString(output.Formatted); - if (!formatted) + if (!options.Indented) { Assert.Equal(257, output.Formatted.Length); } @@ -1642,13 +1557,9 @@ public void FixedSizeBufferWriter_DateTimeOffset(bool formatted, bool skipValida } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void FixedSizeBufferWriter_Decimal(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var random = new Random(42); for (int i = 0; i < 1_000; i++) @@ -1707,7 +1618,8 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) } { - int sizeTooSmall = 256; + int sizeTooSmall = options.Indented ? options.IndentSize + 230 : 226; + sizeTooSmall = Math.Max(sizeTooSmall, 256); var output = new FixedSizedBufferWriter(sizeTooSmall); byte[] utf8String = Encoding.UTF8.GetBytes(new string('a', 222)); @@ -1721,7 +1633,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) Assert.Throws(() => jsonUtf8.WriteNumberValue(value)); } - sizeTooSmall += formatted ? 9 : 1; + sizeTooSmall += options.Indented ? options.IndentSize + 33 : 31; output = new FixedSizedBufferWriter(sizeTooSmall); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -1733,7 +1645,7 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) } string actualStr = Encoding.UTF8.GetString(output.Formatted); - if (!formatted) + if (!options.Indented) { Assert.Equal(257, output.Formatted.Length); } @@ -1741,134 +1653,117 @@ public void FixedSizeBufferWriter_Decimal(bool formatted, bool skipValidation) } } + public static IEnumerable InvalidJsonDueToWritingMultipleValues_TestData() => + JsonOptionsWith([ + JsonValueKind.Array, + JsonValueKind.Object, + JsonValueKind.String, + JsonValueKind.Number, + JsonValueKind.True, + JsonValueKind.False, + JsonValueKind.Null, + ]); + [Theory] - [InlineData(JsonValueKind.Array, true, true)] - [InlineData(JsonValueKind.Array, true, false)] - [InlineData(JsonValueKind.Array, false, true)] - [InlineData(JsonValueKind.Array, false, false)] - [InlineData(JsonValueKind.Object, true, true)] - [InlineData(JsonValueKind.Object, true, false)] - [InlineData(JsonValueKind.Object, false, true)] - [InlineData(JsonValueKind.Object, false, false)] - [InlineData(JsonValueKind.String, true, true)] - [InlineData(JsonValueKind.String, true, false)] - [InlineData(JsonValueKind.String, false, true)] - [InlineData(JsonValueKind.String, false, false)] - [InlineData(JsonValueKind.Number, true, true)] - [InlineData(JsonValueKind.Number, true, false)] - [InlineData(JsonValueKind.Number, false, true)] - [InlineData(JsonValueKind.Number, false, false)] - [InlineData(JsonValueKind.True, true, true)] - [InlineData(JsonValueKind.True, true, false)] - [InlineData(JsonValueKind.True, false, true)] - [InlineData(JsonValueKind.True, false, false)] - [InlineData(JsonValueKind.False, true, true)] - [InlineData(JsonValueKind.False, true, false)] - [InlineData(JsonValueKind.False, false, true)] - [InlineData(JsonValueKind.False, false, false)] - [InlineData(JsonValueKind.Null, true, true)] - [InlineData(JsonValueKind.Null, true, false)] - [InlineData(JsonValueKind.Null, false, true)] - [InlineData(JsonValueKind.Null, false, false)] - public void InvalidJsonDueToWritingMultipleValues(JsonValueKind kind, bool formatted, bool skipValidation) - { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(InvalidJsonDueToWritingMultipleValues_TestData))] + public void InvalidJsonDueToWritingMultipleValues(JsonWriterOptions options, JsonValueKind kind) + { var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject("foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject("foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartArray(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartArray(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndObject(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndObject(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndArray(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndArray(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WritePropertyName("foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WritePropertyName("foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteString("key", "foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteString("key", "foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStringValue("foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStringValue("foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumber("key", 123), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumber("key", 123), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumberValue(123), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumberValue(123), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", true), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", true), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(true), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(true), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", false), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", false), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(false), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(false), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNull("key"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNull("key"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNullValue(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNullValue(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) @@ -1880,133 +1775,105 @@ public void InvalidJsonDueToWritingMultipleValues(JsonValueKind kind, bool forma } [Theory] - [InlineData(JsonValueKind.Array, true, true)] - [InlineData(JsonValueKind.Array, true, false)] - [InlineData(JsonValueKind.Array, false, true)] - [InlineData(JsonValueKind.Array, false, false)] - [InlineData(JsonValueKind.Object, true, true)] - [InlineData(JsonValueKind.Object, true, false)] - [InlineData(JsonValueKind.Object, false, true)] - [InlineData(JsonValueKind.Object, false, false)] - [InlineData(JsonValueKind.String, true, true)] - [InlineData(JsonValueKind.String, true, false)] - [InlineData(JsonValueKind.String, false, true)] - [InlineData(JsonValueKind.String, false, false)] - [InlineData(JsonValueKind.Number, true, true)] - [InlineData(JsonValueKind.Number, true, false)] - [InlineData(JsonValueKind.Number, false, true)] - [InlineData(JsonValueKind.Number, false, false)] - [InlineData(JsonValueKind.True, true, true)] - [InlineData(JsonValueKind.True, true, false)] - [InlineData(JsonValueKind.True, false, true)] - [InlineData(JsonValueKind.True, false, false)] - [InlineData(JsonValueKind.False, true, true)] - [InlineData(JsonValueKind.False, true, false)] - [InlineData(JsonValueKind.False, false, true)] - [InlineData(JsonValueKind.False, false, false)] - [InlineData(JsonValueKind.Null, true, true)] - [InlineData(JsonValueKind.Null, true, false)] - [InlineData(JsonValueKind.Null, false, true)] - [InlineData(JsonValueKind.Null, false, false)] - public void InvalidJsonDueToWritingMultipleValuesWithComments(JsonValueKind kind, bool formatted, bool skipValidation) - { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(InvalidJsonDueToWritingMultipleValues_TestData))] + public void InvalidJsonDueToWritingMultipleValuesWithComments(JsonWriterOptions options, JsonValueKind kind) + { var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject("foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartObject("foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartArray(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStartArray(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndObject(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndObject(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndArray(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteEndArray(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WritePropertyName("foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WritePropertyName("foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteString("key", "foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteString("key", "foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteStringValue("foo"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteStringValue("foo"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumber("key", 123), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumber("key", 123), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumberValue(123), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNumberValue(123), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", true), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", true), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(true), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(true), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", false), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBoolean("key", false), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(false), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteBooleanValue(false), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNull("key"), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNull("key"), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { WritePreamble(jsonUtf8, kind, addComments: true); - ValidateAction(jsonUtf8, () => jsonUtf8.WriteNullValue(), skipValidation); + ValidateAction(jsonUtf8, () => jsonUtf8.WriteNullValue(), options.SkipValidation); } using (var jsonUtf8 = new Utf8JsonWriter(output, options)) @@ -2078,18 +1945,14 @@ private void ValidateAction(Utf8JsonWriter writer, Action action, bool skipValid } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidJsonMismatch(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InvalidJsonMismatch(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2101,7 +1964,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2113,7 +1976,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartArray("property at start"); } @@ -2125,7 +1988,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject("property at start"); } @@ -2138,7 +2001,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartArray("property inside array"); } @@ -2151,7 +2014,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject(); } @@ -2164,7 +2027,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2177,7 +2040,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStringValue("key"); } @@ -2190,7 +2053,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteString("key", "value"); } @@ -2203,7 +2066,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteString(JsonEncodedText.Encode("key"), JsonEncodedText.Encode("value")); } @@ -2216,7 +2079,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2229,7 +2092,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartArray(); } @@ -2244,7 +2107,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartArray(); jsonUtf8.WriteStartArray(); jsonUtf8.WriteEndArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2259,7 +2122,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); jsonUtf8.WriteStartObject("some object"); jsonUtf8.WriteEndObject(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2272,7 +2135,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject("some object"); jsonUtf8.WriteEndObject(); @@ -2289,7 +2152,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) jsonUtf8.WriteStartObject(); jsonUtf8.WriteStartArray("test array"); jsonUtf8.WriteEndArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2303,7 +2166,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartArray(); jsonUtf8.WriteEndArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2317,7 +2180,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WriteEndObject(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2331,7 +2194,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartArray(); jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2345,7 +2208,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WriteStartObject("test object"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2357,7 +2220,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); jsonUtf8.WritePropertyName(JsonEncodedText.Encode("test name")); @@ -2376,7 +2239,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartArray(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); } @@ -2390,7 +2253,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); } @@ -2404,7 +2267,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartArray("test name"); } @@ -2418,7 +2281,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject("test name"); } @@ -2432,7 +2295,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2446,7 +2309,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteString("another property name", "some value"); } @@ -2460,7 +2323,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteNumber("another property name", 12345); } @@ -2474,7 +2337,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteNull("another property name"); } @@ -2488,7 +2351,7 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) { jsonUtf8.WriteStartObject(); jsonUtf8.WritePropertyName("first name"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteBoolean("another property name", true); } @@ -2500,13 +2363,9 @@ public void InvalidJsonMismatch(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidJsonIncomplete(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InvalidJsonIncomplete(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) @@ -2554,19 +2413,15 @@ public void InvalidJsonIncomplete(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidJsonPrimitive(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InvalidJsonPrimitive(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteNumberValue(12345); } @@ -2579,7 +2434,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartArray(); } @@ -2592,7 +2447,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject(); } @@ -2605,7 +2460,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartArray("property name"); } @@ -2618,7 +2473,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject("property name"); } @@ -2631,7 +2486,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteString("property name", "value"); } @@ -2644,7 +2499,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteString(JsonEncodedText.Encode("property name"), JsonEncodedText.Encode("value")); } @@ -2657,7 +2512,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndArray(); } @@ -2670,7 +2525,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteEndObject(); } @@ -2683,7 +2538,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNumberValue(12345); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); } @@ -2696,7 +2551,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteBooleanValue(true); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); } @@ -2709,7 +2564,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteNullValue(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); } @@ -2722,7 +2577,7 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStringValue("some string"); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WritePropertyName("test name"); } @@ -2734,13 +2589,9 @@ public void InvalidJsonPrimitive(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void InvalidNumbersJson(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void InvalidNumbersJson(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) @@ -2831,12 +2682,12 @@ public void InvalidJsonContinueShouldSucceed(bool formatted) var sb = new StringBuilder(); for (int i = 0; i < 100; i++) { - if (formatted) + if (options.Indented) sb.Append(Environment.NewLine); sb.Append("]"); } sb.Append(","); - if (formatted) + if (options.Indented) sb.Append(Environment.NewLine); sb.Append("[]"); @@ -2844,19 +2695,15 @@ public void InvalidJsonContinueShouldSucceed(bool formatted) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteSeparateProperties(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteSeparateProperties(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); var stringWriter = new StringWriter(); var json = new JsonTextWriter(stringWriter) { - Formatting = formatted ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, }; json.WriteStartObject(); @@ -2875,7 +2722,7 @@ public void WriteSeparateProperties(bool formatted, bool skipValidation) json.Flush(); - string expectedStr = stringWriter.ToString(); + string expectedStr = HandleIndent(stringWriter.ToString(), options); using var jsonUtf8 = new Utf8JsonWriter(output, options); jsonUtf8.WriteStartObject(); @@ -2896,13 +2743,9 @@ public void WriteSeparateProperties(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritingTooDeep(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritingTooDeep(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -2916,15 +2759,11 @@ public void WritingTooDeep(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritingTooDeepProperty(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritingTooDeepProperty(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(1024); - + var capacity = 3 + 1000 * (11 + 1001 * options.IndentSize / 2); + var output = new ArrayBufferWriter(capacity); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); @@ -2936,6 +2775,7 @@ public void WritingTooDeepProperty(bool formatted, bool skipValidation) Assert.Throws(() => jsonUtf8.WriteStartArray("name")); } + output = new ArrayBufferWriter(capacity); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); @@ -2946,6 +2786,7 @@ public void WritingTooDeepProperty(bool formatted, bool skipValidation) Assert.Throws(() => jsonUtf8.WriteStartArray("name"u8)); } + output = new ArrayBufferWriter(capacity); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { jsonUtf8.WriteStartObject(); @@ -3017,11 +2858,8 @@ public static void CustomMaxDepth_DepthExceedingLimit_ShouldFail(int maxDepth) [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritingTooLargeProperty(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritingTooLargeProperty(JsonWriterOptions options) { try { @@ -3034,8 +2872,7 @@ public void WritingTooLargeProperty(bool formatted, bool skipValidation) key.AsSpan().Fill((byte)'a'); keyChars.AsSpan().Fill('a'); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(1024); + var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -3062,11 +2899,8 @@ public void WritingTooLargeProperty(bool formatted, bool skipValidation) [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritingTooLargePropertyStandalone(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritingTooLargePropertyStandalone(JsonWriterOptions options) { try { @@ -3079,8 +2913,7 @@ public void WritingTooLargePropertyStandalone(bool formatted, bool skipValidatio key.AsSpan().Fill((byte)'a'); keyChars.AsSpan().Fill('a'); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(1024); + var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -3102,19 +2935,15 @@ public void WritingTooLargePropertyStandalone(bool formatted, bool skipValidatio [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritingTooLargeBase64Bytes(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritingTooLargeBase64Bytes(JsonWriterOptions options) { try { byte[] value = new byte[200_000_000]; value.AsSpan().Fill((byte)'a'); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(value.Length); + var output = new ArrayBufferWriter(value.Length); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -3185,11 +3014,8 @@ public void WritingTooLargeBase64Bytes(bool formatted, bool skipValidation) [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritingHugeBase64Bytes(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritingHugeBase64Bytes(JsonWriterOptions options) { try { @@ -3197,8 +3023,7 @@ public void WritingHugeBase64Bytes(bool formatted, bool skipValidation) value.AsSpan().Fill(168); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(1024); + var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) { @@ -3245,12 +3070,9 @@ public void WritingHugeBase64Bytes(bool formatted, bool skipValidation) // https://github.com/dotnet/runtime/issues/30746 [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] + [MemberData(nameof(JsonOptions_TestData))] [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/45464", ~RuntimeConfiguration.Release)] - public void Writing3MBBase64Bytes(bool formatted, bool skipValidation) + public void Writing3MBBase64Bytes(JsonWriterOptions options) { byte[] value = new byte[3 * 1024 * 1024]; @@ -3260,9 +3082,8 @@ public void Writing3MBBase64Bytes(bool formatted, bool skipValidation) Base64.EncodeToUtf8(value, base64StringUtf8, out _, out int bytesWritten); string expectedValue = Encoding.UTF8.GetString(base64StringUtf8.AsSpan(0, bytesWritten).ToArray()); - string expectedJson = formatted ? $"{{{Environment.NewLine} \"foo\": \"{expectedValue}\"{Environment.NewLine}}}" : $"{{\"foo\":\"{expectedValue}\"}}"; + string expectedJson = options.Indented ? $"{{{Environment.NewLine}{GetIndentText(options)}\"foo\": \"{expectedValue}\"{Environment.NewLine}}}" : $"{{\"foo\":\"{expectedValue}\"}}"; - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using (var jsonUtf8 = new Utf8JsonWriter(output, options)) @@ -3309,16 +3130,12 @@ public void Writing3MBBase64Bytes(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteSingleValue(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteSingleValue(JsonWriterOptions options) { string expectedStr = "123456789012345"; - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + var output = new ArrayBufferWriter(1024); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -3330,15 +3147,12 @@ public void WriteSingleValue(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteHelloWorld(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteHelloWorld(JsonWriterOptions options) { string propertyName = "message"; string value = "Hello, World!"; - string expectedStr = GetHelloWorldExpectedString(prettyPrint: formatted, propertyName, value); + string expectedStr = GetHelloWorldExpectedString(options, propertyName, value); JsonEncodedText encodedPropertyName = JsonEncodedText.Encode(propertyName); JsonEncodedText encodedValue = JsonEncodedText.Encode(value); @@ -3346,8 +3160,7 @@ public void WriteHelloWorld(bool formatted, bool skipValidation) ReadOnlySpan utf8PropertyName = "message"u8; ReadOnlySpan utf8Value = "Hello, World!"u8; - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + for (int i = 0; i < 32; i++) { var output = new ArrayBufferWriter(32); @@ -3527,18 +3340,13 @@ public void WriteHelloWorld(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteHelloWorldEscaped(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteHelloWorldEscaped(JsonWriterOptions options) { string propertyName = "mess> propertyNameSpan = propertyName.AsSpan(); ReadOnlySpan valueSpan = value.AsSpan(); ReadOnlySpan propertyNameSpanUtf8 = Encoding.UTF8.GetBytes(propertyName); @@ -3734,14 +3542,10 @@ public void WriteHelloWorldEscaped(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritePartialHelloWorld(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritePartialHelloWorld(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -3753,15 +3557,15 @@ public void WritePartialHelloWorld(bool formatted, bool skipValidation) jsonUtf8.WriteString("message", "Hello, World!"); Assert.Equal(0, jsonUtf8.BytesCommitted); - if (formatted) - Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesPending); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(26 + options.IndentSize + Environment.NewLine.Length + 1, jsonUtf8.BytesPending); // new lines, indentation, white space else Assert.Equal(26, jsonUtf8.BytesPending); jsonUtf8.Flush(); - if (formatted) - Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(26 + options.IndentSize + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); // new lines, indentation, white space else Assert.Equal(26, jsonUtf8.BytesCommitted); @@ -3770,50 +3574,41 @@ public void WritePartialHelloWorld(bool formatted, bool skipValidation) jsonUtf8.WriteString("message", "Hello, World!"); jsonUtf8.WriteEndObject(); - if (formatted) - Assert.Equal(26 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); + if (options.Indented) + Assert.Equal(26 + options.IndentSize + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); else Assert.Equal(26, jsonUtf8.BytesCommitted); - if (formatted) - Assert.Equal(27 + 2 + (2 * Environment.NewLine.Length) + 1, jsonUtf8.BytesPending); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(27 + options.IndentSize + (2 * Environment.NewLine.Length) + 1, jsonUtf8.BytesPending); // new lines, indentation, white space else Assert.Equal(27, jsonUtf8.BytesPending); jsonUtf8.Flush(); - if (formatted) - Assert.Equal(53 + (2 * 2) + (3 * Environment.NewLine.Length) + (1 * 2), jsonUtf8.BytesCommitted); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(53 + (2 * options.IndentSize) + (3 * Environment.NewLine.Length) + (1 * 2), jsonUtf8.BytesCommitted); // new lines, indentation, white space else Assert.Equal(53, jsonUtf8.BytesCommitted); Assert.Equal(0, jsonUtf8.BytesPending); } + public static IEnumerable WriteBase64String_TestData() => + JsonOptionsWith([ + "message", + "escape mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + ]); + [Theory] - [InlineData(true, true, "message")] - [InlineData(true, false, "message")] - [InlineData(false, true, "message")] - [InlineData(false, false, "message")] - [InlineData(true, true, "escape mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteBase64String(bool formatted, bool skipValidation, string inputValue) + [MemberData(nameof(WriteBase64String_TestData))] + public void WriteBase64String(JsonWriterOptions options, string inputValue) { string propertyName = inputValue; byte[] value = { 1, 2, 3, 4, 5, 6 }; - string expectedStr = GetBase64ExpectedString(prettyPrint: formatted, propertyName, value); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetBase64ExpectedString(options, propertyName, value); ReadOnlySpan propertyNameSpan = propertyName.AsSpan(); ReadOnlySpan propertyNameSpanUtf8 = Encoding.UTF8.GetBytes(propertyName); @@ -3865,14 +3660,9 @@ public void WriteBase64String(bool formatted, bool skipValidation, string inputV } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WritePartialBase64String(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WritePartialBase64String(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -3884,15 +3674,15 @@ public void WritePartialBase64String(bool formatted, bool skipValidation) jsonUtf8.WriteBase64String("message", new byte[] { 201, 153, 199 }); Assert.Equal(0, jsonUtf8.BytesCommitted); - if (formatted) - Assert.Equal(17 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesPending); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(17 + options.IndentSize + Environment.NewLine.Length + 1, jsonUtf8.BytesPending); // new lines, indentation, white space else Assert.Equal(17, jsonUtf8.BytesPending); jsonUtf8.Flush(); - if (formatted) - Assert.Equal(17 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(17 + options.IndentSize + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); // new lines, indentation, white space else Assert.Equal(17, jsonUtf8.BytesCommitted); @@ -3901,20 +3691,20 @@ public void WritePartialBase64String(bool formatted, bool skipValidation) jsonUtf8.WriteBase64String("message", new byte[] { 201, 153, 199 }); jsonUtf8.WriteEndObject(); - if (formatted) - Assert.Equal(17 + 2 + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); + if (options.Indented) + Assert.Equal(17 + options.IndentSize + Environment.NewLine.Length + 1, jsonUtf8.BytesCommitted); else Assert.Equal(17, jsonUtf8.BytesCommitted); - if (formatted) - Assert.Equal(18 + 2 + (2 * Environment.NewLine.Length) + 1, jsonUtf8.BytesPending); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(18 + options.IndentSize + (2 * Environment.NewLine.Length) + 1, jsonUtf8.BytesPending); // new lines, indentation, white space else Assert.Equal(18, jsonUtf8.BytesPending); jsonUtf8.Flush(); - if (formatted) - Assert.Equal(35 + (2 * 2) + (3 * Environment.NewLine.Length) + (1 * 2), jsonUtf8.BytesCommitted); // new lines, indentation, white space + if (options.Indented) + Assert.Equal(35 + (2 * options.IndentSize) + (3 * Environment.NewLine.Length) + (1 * 2), jsonUtf8.BytesCommitted); // new lines, indentation, white space else Assert.Equal(35, jsonUtf8.BytesCommitted); @@ -3922,13 +3712,9 @@ public void WritePartialBase64String(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteInvalidPartialJson(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteInvalidPartialJson(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -3942,7 +3728,7 @@ public void WriteInvalidPartialJson(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.BytesCommitted); Assert.Equal(0, jsonUtf8.BytesPending); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStringValue("Hello, World!"); jsonUtf8.WriteEndArray(); @@ -3955,15 +3741,11 @@ public void WriteInvalidPartialJson(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteInvalidBase64(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteInvalidBase64(JsonWriterOptions options) { { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(10); + var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); jsonUtf8.WriteStartObject(); @@ -3976,7 +3758,7 @@ public void WriteInvalidBase64(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.BytesCommitted); Assert.Equal(0, jsonUtf8.BytesPending); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteBase64StringValue(new byte[] { 1, 2 }); jsonUtf8.WriteEndArray(); @@ -3988,8 +3770,7 @@ public void WriteInvalidBase64(bool formatted, bool skipValidation) } } { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(10); + var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); jsonUtf8.WriteStartArray(); @@ -4002,7 +3783,7 @@ public void WriteInvalidBase64(bool formatted, bool skipValidation) Assert.Equal(1, jsonUtf8.BytesCommitted); Assert.Equal(0, jsonUtf8.BytesPending); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteBase64String("foo", new byte[] { 1, 2 }); jsonUtf8.WriteEndObject(); @@ -4060,15 +3841,11 @@ public void WriteBase64DoesNotEscapeLarge() } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteInvalidDepthPartial(JsonWriterOptions options) { { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(10); + var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); jsonUtf8.WriteStartObject(); @@ -4077,7 +3854,7 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) Assert.Equal(0, jsonUtf8.CurrentDepth); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject(); } @@ -4088,15 +3865,14 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) } { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(10); + var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); jsonUtf8.WriteStartObject(); jsonUtf8.WriteEndObject(); jsonUtf8.Flush(); - if (skipValidation) + if (options.SkipValidation) { jsonUtf8.WriteStartObject("name"); } @@ -4107,24 +3883,18 @@ public void WriteInvalidDepthPartial(bool formatted, bool skipValidation) } } + public static IEnumerable WriteComments_TestData() => + JsonOptionsWith([ + "comment", + "comm>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + ]); + [Theory] - [InlineData(true, true, "comment")] - [InlineData(true, false, "comment")] - [InlineData(false, true, "comment")] - [InlineData(false, false, "comment")] - [InlineData(true, true, "comm>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteCommentsInArray(bool formatted, bool skipValidation, string comment) - { - string expectedStr = GetCommentInArrayExpectedString(prettyPrint: formatted, comment); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(WriteComments_TestData))] + public void WriteCommentsInArray(JsonWriterOptions options, string comment) + { + string expectedStr = GetCommentInArrayExpectedString(options, comment); for (int i = 0; i < 3; i++) { @@ -4175,23 +3945,10 @@ public void WriteCommentsInArray(bool formatted, bool skipValidation, string com } [Theory] - [InlineData(true, true, "comment")] - [InlineData(true, false, "comment")] - [InlineData(false, true, "comment")] - [InlineData(false, false, "comment")] - [InlineData(true, true, "comm>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteCommentsInObject(bool formatted, bool skipValidation, string comment) - { - string expectedStr = GetCommentInObjectExpectedString(prettyPrint: formatted, comment); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(WriteComments_TestData))] + public void WriteCommentsInObject(JsonWriterOptions options, string comment) + { + string expectedStr = GetCommentInObjectExpectedString(options, comment); for (int i = 0; i < 3; i++) { @@ -4245,14 +4002,9 @@ private static void WriteCommentValue(Utf8JsonWriter jsonUtf8, int i, string com } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteInvalidComment(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteInvalidComment(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(32); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -4270,14 +4022,9 @@ public void WriteInvalidComment(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteCommentsInvalidTextAllowed(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteCommentsInvalidTextAllowed(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(32); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -4298,18 +4045,18 @@ public void WriteCommentsInvalidTextAllowed(bool formatted, bool skipValidation) jsonUtf8.WriteCommentValue(comment.AsSpan()); jsonUtf8.Flush(); - string expectedStr = GetCommentExpectedString(prettyPrint: formatted); + string expectedStr = GetCommentExpectedString(options); JsonTestHelper.AssertContents(expectedStr, output); } - private static string GetCommentExpectedString(bool prettyPrint) + private static string GetCommentExpectedString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; @@ -4331,7 +4078,7 @@ private static string GetCommentExpectedString(bool prettyPrint) json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } [Theory] @@ -4421,17 +4168,12 @@ public void WriteCommentsInObject_ComparedWithStringLiteral(bool formatted, stri } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteStrings(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteStrings(JsonWriterOptions options) { string value = "temp"; - string expectedStr = GetStringsExpectedString(prettyPrint: formatted, value); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + string expectedStr = GetStringsExpectedString(options, value); + for (int i = 0; i < 3; i++) { var output = new ArrayBufferWriter(1024); @@ -4462,32 +4204,21 @@ public void WriteStrings(bool formatted, bool skipValidation) } } + public static IEnumerable WriteHelloWorldEscaped_AdditionalCases_TestData() => + JsonOptionsWith([ + "mess\nage", + "message" + ], + [ + "Hello, \nWorld!", + "Hello, World!" + ]); + [Theory] - [InlineData(true, true, "mess\nage", "Hello, \nWorld!")] - [InlineData(true, false, "mess\nage", "Hello, \nWorld!")] - [InlineData(false, true, "mess\nage", "Hello, \nWorld!")] - [InlineData(false, false, "mess\nage", "Hello, \nWorld!")] - [InlineData(true, true, "message", "Hello, \nWorld!")] - [InlineData(true, false, "message", "Hello, \nWorld!")] - [InlineData(false, true, "message", "Hello, \nWorld!")] - [InlineData(false, false, "message", "Hello, \nWorld!")] - [InlineData(true, true, "mess\nage", "Hello, World!")] - [InlineData(true, false, "mess\nage", "Hello, World!")] - [InlineData(false, true, "mess\nage", "Hello, World!")] - [InlineData(false, false, "mess\nage", "Hello, World!")] - [InlineData(true, true, "message", "Hello, World!")] - [InlineData(true, false, "message", "Hello, World!")] - [InlineData(false, true, "message", "Hello, World!")] - [InlineData(false, false, "message", "Hello, World!")] - [InlineData(true, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>mess\nage", ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Hello, \nWorld!")] - public void WriteHelloWorldEscaped_AdditionalCases(bool formatted, bool skipValidation, string key, string value) - { - string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, key, value, StringEscapeHandling.EscapeHtml); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(WriteHelloWorldEscaped_AdditionalCases_TestData))] + public void WriteHelloWorldEscaped_AdditionalCases(JsonWriterOptions options, string key, string value) + { + string expectedStr = GetEscapedExpectedString(options, key, value, StringEscapeHandling.EscapeHtml); byte[] keyUtf8 = Encoding.UTF8.GetBytes(key); byte[] valueUtf8 = Encoding.UTF8.GetBytes(value); @@ -4626,11 +4357,8 @@ public void WriteHelloWorldEscaped_AdditionalCases(bool formatted, bool skipVali } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void EscapeAsciiCharacters(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void EscapeAsciiCharacters(JsonWriterOptions options) { var propertyArray = new char[128]; @@ -4650,9 +4378,8 @@ public void EscapeAsciiCharacters(bool formatted, bool skipValidation) string propertyName = new string(propertyArray); string value = new string(propertyArray); - string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeHtml); + string expectedStr = GetEscapedExpectedString(options, propertyName, value, StringEscapeHandling.EscapeHtml); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; for (int i = 0; i < 6; i++) { var output = new ArrayBufferWriter(1024); @@ -4693,11 +4420,8 @@ public void EscapeAsciiCharacters(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void EscapeCharacters(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void EscapeCharacters(JsonWriterOptions options) { // Do not include surrogate pairs. var propertyArray = new char[0xD800 + (0xFFFF - 0xE000) + 1]; @@ -4713,9 +4437,8 @@ public void EscapeCharacters(bool formatted, bool skipValidation) string propertyName = new string(propertyArray); string value = new string(propertyArray); - string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii); + string expectedStr = GetEscapedExpectedString(options, propertyName, value, StringEscapeHandling.EscapeNonAscii); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; for (int i = 0; i < 6; i++) { var output = new ArrayBufferWriter(1024); @@ -4756,20 +4479,16 @@ public void EscapeCharacters(bool formatted, bool skipValidation) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void HighSurrogateMissingGetsReplaced(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void HighSurrogateMissingGetsReplaced(JsonWriterOptions options) { var propertyArray = new char[10] { 'a', (char)0xD800, (char)0xDC00, (char)0xD803, (char)0xDE6D, (char)0xD834, (char)0xDD1E, (char)0xDBFF, (char)0xDFFF, 'a' }; string propertyName = new string(propertyArray); string value = new string(propertyArray); - string expectedStr = GetEscapedExpectedString(prettyPrint: formatted, propertyName, value, StringEscapeHandling.EscapeNonAscii); + string expectedStr = GetEscapedExpectedString(options, propertyName, value, StringEscapeHandling.EscapeNonAscii); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; for (int i = 0; i < 6; i++) { var output = new ArrayBufferWriter(1024); @@ -5074,13 +4793,9 @@ public void CustomEscaper(string value, string expectedStr) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteCustomStrings(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteCustomStrings(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(10); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -5094,19 +4809,15 @@ public void WriteCustomStrings(bool formatted, bool skipValidation) jsonUtf8.WriteEndObject(); jsonUtf8.Flush(); - JsonTestHelper.AssertContents(GetCustomExpectedString(formatted), output); + JsonTestHelper.AssertContents(GetCustomExpectedString(options), output); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteStartEnd(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteStartEnd(JsonWriterOptions options) { - string expectedStr = GetStartEndExpectedString(prettyPrint: formatted); + string expectedStr = GetStartEndExpectedString(options); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; var output = new ArrayBufferWriter(1024); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -5157,16 +4868,12 @@ public void WriteStartEndInvalid(bool formatted) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteStartEndWithPropertyNameArray(JsonWriterOptions options) { - string expectedStr = GetStartEndWithPropertyArrayExpectedString(prettyPrint: formatted); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetStartEndWithPropertyArrayExpectedString(options); + for (int i = 0; i < 3; i++) { var output = new ArrayBufferWriter(1024); @@ -5195,16 +4902,15 @@ public void WriteStartEndWithPropertyNameArray(bool formatted, bool skipValidati } } + public static IEnumerable WriteStartEndWithPropertyName_TestData() => + JsonOptionsWith([ + 10, + 100 + ]); + [Theory] - [InlineData(true, true, 10)] - [InlineData(true, false, 10)] - [InlineData(false, true, 10)] - [InlineData(false, false, 10)] - [InlineData(true, true, 100)] - [InlineData(true, false, 100)] - [InlineData(false, true, 100)] - [InlineData(false, false, 100)] - public void WriteStartEndWithPropertyNameArrayDifferentKeyLengths(bool formatted, bool skipValidation, int keyLength) + [MemberData(nameof(WriteStartEndWithPropertyName_TestData))] + public void WriteStartEndWithPropertyNameArrayDifferentKeyLengths(JsonWriterOptions options, int keyLength) { var keyChars = new char[keyLength]; for (int i = 0; i < keyChars.Length; i++) @@ -5213,9 +4919,7 @@ public void WriteStartEndWithPropertyNameArrayDifferentKeyLengths(bool formatted } var key = new string(keyChars); - string expectedStr = GetStartEndWithPropertyArrayExpectedString(key, prettyPrint: formatted, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetStartEndWithPropertyArrayExpectedString(key, options, escape: true); for (int i = 0; i < 3; i++) { @@ -5246,15 +4950,10 @@ public void WriteStartEndWithPropertyNameArrayDifferentKeyLengths(bool formatted } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteStartEndWithPropertyNameObject(JsonWriterOptions options) { - string expectedStr = GetStartEndWithPropertyObjectExpectedString(prettyPrint: formatted); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetStartEndWithPropertyObjectExpectedString(options); for (int i = 0; i < 3; i++) { @@ -5285,15 +4984,8 @@ public void WriteStartEndWithPropertyNameObject(bool formatted, bool skipValidat } [Theory] - [InlineData(true, true, 10)] - [InlineData(true, false, 10)] - [InlineData(false, true, 10)] - [InlineData(false, false, 10)] - [InlineData(true, true, 100)] - [InlineData(true, false, 100)] - [InlineData(false, true, 100)] - [InlineData(false, false, 100)] - public void WriteStartEndWithPropertyNameObjectDifferentKeyLengths(bool formatted, bool skipValidation, int keyLength) + [MemberData(nameof(WriteStartEndWithPropertyName_TestData))] + public void WriteStartEndWithPropertyNameObjectDifferentKeyLengths(JsonWriterOptions options, int keyLength) { var keyChars = new char[keyLength]; for (int i = 0; i < keyChars.Length; i++) @@ -5302,9 +4994,7 @@ public void WriteStartEndWithPropertyNameObjectDifferentKeyLengths(bool formatte } var key = new string(keyChars); - string expectedStr = GetStartEndWithPropertyObjectExpectedString(key, prettyPrint: formatted, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetStartEndWithPropertyObjectExpectedString(key, options, escape: true); for (int i = 0; i < 3; i++) { @@ -5335,15 +5025,10 @@ public void WriteStartEndWithPropertyNameObjectDifferentKeyLengths(bool formatte } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteArrayWithProperty(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteArrayWithProperty(JsonWriterOptions options) { - string expectedStr = GetArrayWithPropertyExpectedString(prettyPrint: formatted); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetArrayWithPropertyExpectedString(options); for (int i = 0; i < 3; i++) { @@ -5373,36 +5058,22 @@ public void WriteArrayWithProperty(bool formatted, bool skipValidation) } } + public static IEnumerable WriteBooleanValue_TestData() => + JsonOptionsWith([ + true, + false + ], + [ + "message", + "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + ]); + [Theory] - [InlineData(true, true, true, "message")] - [InlineData(true, false, true, "message")] - [InlineData(false, true, true, "message")] - [InlineData(false, false, true, "message")] - [InlineData(true, true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, true, false, "message")] - [InlineData(true, false, false, "message")] - [InlineData(false, true, false, "message")] - [InlineData(false, false, false, "message")] - [InlineData(true, true, false, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteBooleanValue(bool formatted, bool skipValidation, bool value, string keyString) - { - string expectedStr = GetBooleanExpectedString(prettyPrint: formatted, keyString, value, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(WriteBooleanValue_TestData))] + public void WriteBooleanValue(JsonWriterOptions options, bool value, string keyString) + { + string expectedStr = GetBooleanExpectedString(options, keyString, value, escape: true); for (int i = 0; i < 4; i++) { @@ -5442,24 +5113,18 @@ public void WriteBooleanValue(bool formatted, bool skipValidation, bool value, s } } + public static IEnumerable WriteValue_TestData() => + JsonOptionsWith([ + "message", + "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" + ]); + [Theory] - [InlineData(true, true, "message")] - [InlineData(true, false, "message")] - [InlineData(false, true, "message")] - [InlineData(false, false, "message")] - [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteNullValue(bool formatted, bool skipValidation, string keyString) - { - string expectedStr = GetNullExpectedString(prettyPrint: formatted, keyString, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(WriteValue_TestData))] + public void WriteNullValue(JsonWriterOptions options, string keyString) + { + string expectedStr = GetNullExpectedString(options, keyString, escape: true); for (int i = 0; i < 4; i++) { @@ -5502,36 +5167,21 @@ public void WriteNullValue(bool formatted, bool skipValidation, string keyString } } + public static IEnumerable WriteIntegerValue_TestData() => + JsonOptionsWith([ + 0, + -1, + 1, + int.MaxValue, + int.MinValue, + 12345 + ]); + [Theory] - [InlineData(true, true, 0)] - [InlineData(true, false, 0)] - [InlineData(false, true, 0)] - [InlineData(false, false, 0)] - [InlineData(true, true, -1)] - [InlineData(true, false, -1)] - [InlineData(false, true, -1)] - [InlineData(false, false, -1)] - [InlineData(true, true, 1)] - [InlineData(true, false, 1)] - [InlineData(false, true, 1)] - [InlineData(false, false, 1)] - [InlineData(true, true, int.MaxValue)] - [InlineData(true, false, int.MaxValue)] - [InlineData(false, true, int.MaxValue)] - [InlineData(false, false, int.MaxValue)] - [InlineData(true, true, int.MinValue)] - [InlineData(true, false, int.MinValue)] - [InlineData(false, true, int.MinValue)] - [InlineData(false, false, int.MinValue)] - [InlineData(true, true, 12345)] - [InlineData(true, false, 12345)] - [InlineData(false, true, 12345)] - [InlineData(false, false, 12345)] - public void WriteIntegerValue(bool formatted, bool skipValidation, int value) - { - string expectedStr = GetPropertyExpectedString(prettyPrint: formatted, value); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + [MemberData(nameof(WriteIntegerValue_TestData))] + public void WriteIntegerValue(JsonWriterOptions options, int value) + { + string expectedStr = GetPropertyExpectedString(options, value); for (int i = 0; i < 4; i++) { @@ -5564,20 +5214,17 @@ public void WriteIntegerValue(bool formatted, bool skipValidation, int value) } } + public static IEnumerable WriteFloatValue_TestData() => + JsonOptionsWith([ + float.MinValue, + float.MaxValue + ]); + [Theory] - [InlineData(true, true, float.MinValue)] - [InlineData(true, false, float.MinValue)] - [InlineData(false, true, float.MinValue)] - [InlineData(false, false, float.MinValue)] - [InlineData(true, true, float.MaxValue)] - [InlineData(true, false, float.MaxValue)] - [InlineData(false, true, float.MaxValue)] - [InlineData(false, false, float.MaxValue)] - public void WriteFloatValue(bool formatted, bool skipValidation, float value) + [MemberData(nameof(WriteFloatValue_TestData))] + public void WriteFloatValue(JsonWriterOptions options, float value) { - string expectedStr = GetPropertyExpectedString(prettyPrint: formatted, value); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetPropertyExpectedString(options, value); for (int i = 0; i < 4; i++) { @@ -5610,20 +5257,17 @@ public void WriteFloatValue(bool formatted, bool skipValidation, float value) } } + public static IEnumerable WriteDoubleValue_TestData() => + JsonOptionsWith([ + double.MinValue, + double.MaxValue + ]); + [Theory] - [InlineData(true, true, double.MinValue)] - [InlineData(true, false, double.MinValue)] - [InlineData(false, true, double.MinValue)] - [InlineData(false, false, double.MinValue)] - [InlineData(true, true, double.MaxValue)] - [InlineData(true, false, double.MaxValue)] - [InlineData(false, true, double.MaxValue)] - [InlineData(false, false, double.MaxValue)] - public void WriteDoubleValue(bool formatted, bool skipValidation, double value) + [MemberData(nameof(WriteDoubleValue_TestData))] + public void WriteDoubleValue(JsonWriterOptions options, double value) { - string expectedStr = GetPropertyExpectedString(prettyPrint: formatted, value); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetPropertyExpectedString(options, value); for (int i = 0; i < 4; i++) { @@ -5658,19 +5302,8 @@ public void WriteDoubleValue(bool formatted, bool skipValidation, double value) [Theory] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] - [InlineData(true, true, "message")] - [InlineData(true, false, "message")] - [InlineData(false, true, "message")] - [InlineData(false, false, "message")] - [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteNumbers(bool formatted, bool skipValidation, string keyString) + [MemberData(nameof(WriteValue_TestData))] + public void WriteNumbers(JsonWriterOptions options, string keyString) { var random = new Random(42); const int numberOfItems = 1_000; @@ -5798,9 +5431,7 @@ public void WriteNumbers(bool formatted, bool skipValidation, string keyString) } } - string expectedStr = GetNumbersExpectedString(prettyPrint: formatted, keyString, ints, uints, longs, ulongs, floats, doubles, decimals, escape: false); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetNumbersExpectedString(options, keyString, ints, uints, longs, ulongs, floats, doubles, decimals, escape: false); for (int j = 0; j < 3; j++) { @@ -5884,14 +5515,9 @@ public void WriteNumbers(bool formatted, bool skipValidation, string keyString) } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteNumberValueInt32(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteNumberValueInt32(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -5908,19 +5534,14 @@ public void WriteNumberValueInt32(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteNumberValueInt64(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteNumberValueInt64(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -5937,19 +5558,14 @@ public void WriteNumberValueInt64(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteNumberValueUInt32(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteNumberValueUInt32(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -5966,19 +5582,14 @@ public void WriteNumberValueUInt32(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteNumberValueUInt64(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteNumberValueUInt64(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -5995,23 +5606,14 @@ public void WriteNumberValueUInt64(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } [Theory] - [InlineData(true, true, float.MinValue)] - [InlineData(true, false, float.MinValue)] - [InlineData(false, true, float.MinValue)] - [InlineData(false, false, float.MinValue)] - [InlineData(true, true, float.MaxValue)] - [InlineData(true, false, float.MaxValue)] - [InlineData(false, true, float.MaxValue)] - [InlineData(false, false, float.MaxValue)] - public void WriteNumberValueSingle(bool formatted, bool skipValidation, float value) - { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + [MemberData(nameof(WriteFloatValue_TestData))] + public void WriteNumberValueSingle(JsonWriterOptions options, float value) + { var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -6027,23 +5629,14 @@ public void WriteNumberValueSingle(bool formatted, bool skipValidation, float va jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } [Theory] - [InlineData(true, true, double.MinValue)] - [InlineData(true, false, double.MinValue)] - [InlineData(false, true, double.MinValue)] - [InlineData(false, false, double.MinValue)] - [InlineData(true, true, double.MaxValue)] - [InlineData(true, false, double.MaxValue)] - [InlineData(false, true, double.MaxValue)] - [InlineData(false, false, double.MaxValue)] - public void WriteNumberValueDouble(bool formatted, bool skipValidation, double value) - { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + [MemberData(nameof(WriteDoubleValue_TestData))] + public void WriteNumberValueDouble(JsonWriterOptions options, double value) + { var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -6059,19 +5652,14 @@ public void WriteNumberValueDouble(bool formatted, bool skipValidation, double v jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteNumberValueDecimal(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteNumberValueDecimal(JsonWriterOptions options) { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - var output = new ArrayBufferWriter(); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -6088,7 +5676,7 @@ public void WriteNumberValueDecimal(bool formatted, bool skipValidation) jsonUtf8.WriteEndArray(); jsonUtf8.Flush(); - string expectedStr = GetNumbersExpectedString(formatted, numberOfElements, value); + string expectedStr = GetNumbersExpectedString(options, numberOfElements, value); JsonTestHelper.AssertContents(expectedStr, output); } @@ -6168,19 +5756,8 @@ private static void WriteStringHelper(JsonWriterOptions options, string keyStrin } [Theory] - [InlineData(true, true, "message")] - [InlineData(true, false, "message")] - [InlineData(false, true, "message")] - [InlineData(false, false, "message")] - [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteGuidsValue(bool formatted, bool skipValidation, string keyString) + [MemberData(nameof(WriteValue_TestData))] + public void WriteGuidsValue(JsonWriterOptions options, string keyString) { const int numberOfItems = 1_000; @@ -6190,9 +5767,7 @@ public void WriteGuidsValue(bool formatted, bool skipValidation, string keyStrin guids[i] = Guid.NewGuid(); } - string expectedStr = GetGuidsExpectedString(prettyPrint: formatted, keyString, guids, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetGuidsExpectedString(options, keyString, guids, escape: true); ReadOnlySpan keyUtf16 = keyString.AsSpan(); ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); @@ -6235,19 +5810,8 @@ public void WriteGuidsValue(bool formatted, bool skipValidation, string keyStrin } [Theory] - [InlineData(true, true, "message")] - [InlineData(true, false, "message")] - [InlineData(false, true, "message")] - [InlineData(false, false, "message")] - [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteDateTimesValue(bool formatted, bool skipValidation, string keyString) + [MemberData(nameof(WriteValue_TestData))] + public void WriteDateTimesValue(JsonWriterOptions options, string keyString) { var random = new Random(42); const int numberOfItems = 1_000; @@ -6259,9 +5823,7 @@ public void WriteDateTimesValue(bool formatted, bool skipValidation, string keyS for (int i = 0; i < numberOfItems; i++) dates[i] = start.AddDays(random.Next(range)); - string expectedStr = GetDatesExpectedString(prettyPrint: formatted, keyString, dates, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetDatesExpectedString(options, keyString, dates, escape: true); ReadOnlySpan keyUtf16 = keyString.AsSpan(); ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); @@ -6304,19 +5866,8 @@ public void WriteDateTimesValue(bool formatted, bool skipValidation, string keyS } [Theory] - [InlineData(true, true, "message")] - [InlineData(true, false, "message")] - [InlineData(false, true, "message")] - [InlineData(false, false, "message")] - [InlineData(true, true, "mess>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(true, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, true, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - [InlineData(false, false, ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")] - public void WriteDateTimeOffsetsValue(bool formatted, bool skipValidation, string keyString) + [MemberData(nameof(WriteValue_TestData))] + public void WriteDateTimeOffsetsValue(JsonWriterOptions options, string keyString) { var random = new Random(42); const int numberOfItems = 1_000; @@ -6328,9 +5879,7 @@ public void WriteDateTimeOffsetsValue(bool formatted, bool skipValidation, strin for (int i = 0; i < numberOfItems; i++) dates[i] = new DateTimeOffset(start.AddDays(random.Next(range))); - string expectedStr = GetDatesExpectedString(prettyPrint: formatted, keyString, dates, escape: true); - - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; + string expectedStr = GetDatesExpectedString(options, keyString, dates, escape: true); ReadOnlySpan keyUtf16 = keyString.AsSpan(); ReadOnlySpan keyUtf8 = Encoding.UTF8.GetBytes(keyString); @@ -6379,11 +5928,8 @@ public void WriteDateTimeOffsetsValue(bool formatted, bool skipValidation, strin [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteLargeKeyOrValue(JsonWriterOptions options) { try { @@ -6396,8 +5942,6 @@ public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) key.AsSpan().Fill((byte)'a'); value.AsSpan().Fill((byte)'b'); - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - { var output = new ArrayBufferWriter(1024); using var jsonUtf8 = new Utf8JsonWriter(output, options); @@ -6427,16 +5971,12 @@ public void WriteLargeKeyOrValue(bool formatted, bool skipValidation) [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteLargeKeyValue(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteLargeKeyValue(JsonWriterOptions options) { try { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + Span key; Span value; @@ -6461,16 +6001,12 @@ public void WriteLargeKeyValue(bool formatted, bool skipValidation) [PlatformSpecific(TestPlatforms.Windows | TestPlatforms.OSX)] [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public void WriteLargeKeyEscapedValue(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteLargeKeyEscapedValue(JsonWriterOptions options) { try { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - + Span key; Span value; @@ -6855,16 +6391,11 @@ private static void WriteStringHelper(JsonEncodedText text, string expectedMessa [ConditionalTheory(typeof(Environment), nameof(Environment.Is64BitProcess))] [OuterLoop] - [InlineData(true, true)] - [InlineData(false, true)] - [InlineData(true, false)] - [InlineData(false, false)] - public void WriteTooLargeArguments(bool formatted, bool skipValidation) + [MemberData(nameof(JsonOptions_TestData))] + public void WriteTooLargeArguments(JsonWriterOptions options) { try { - var options = new JsonWriterOptions { Indented = formatted, SkipValidation = skipValidation }; - byte[] bytesTooLarge; char[] charsTooLarge; var bytes = new byte[5]; @@ -7252,6 +6783,20 @@ public static void WriteStringValue_JsonEncodedTextProperty_NullString() (writer, value) => writer.WriteString(jet, value)); } + [Fact] + public static void WriteStringValue_IndentationOptions() + { + var options = new JsonWriterOptions(); + var expectedOutput = GetCustomExpectedString(options); + + options.IndentCharacter = '\t'; + options.IndentSize = 127; + + var output = GetCustomExpectedString(options); + + Assert.Equal(expectedOutput, output); + } + private delegate void WriteValueSpanAction( Utf8JsonWriter writer, ReadOnlySpan value); @@ -7405,14 +6950,14 @@ private static void WriteNullValue_InArray( JsonTestHelper.AssertContents($"[{nullValue},{wireValue},{wireValue}]", output); } - private static string GetHelloWorldExpectedString(bool prettyPrint, string propertyName, string value) + private static string GetHelloWorldExpectedString(JsonWriterOptions options, string propertyName, string value) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml }; @@ -7425,17 +6970,17 @@ private static string GetHelloWorldExpectedString(bool prettyPrint, string prope json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetBase64ExpectedString(bool prettyPrint, string propertyName, byte[] value) + private static string GetBase64ExpectedString(JsonWriterOptions options, string propertyName, byte[] value) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml }; @@ -7453,23 +6998,23 @@ private static string GetBase64ExpectedString(bool prettyPrint, string propertyN json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetCommentInArrayExpectedString(bool prettyPrint, string comment) + private static string GetCommentInArrayExpectedString(JsonWriterOptions options, string comment) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; json.WriteComment(comment); - CompensateNewLine(prettyPrint, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); json.WriteStartArray(); for (int j = 0; j < 10; j++) json.WriteComment(comment); @@ -7483,87 +7028,87 @@ private static string GetCommentInArrayExpectedString(bool prettyPrint, string c json.WriteComment(comment); json.WriteEnd(); - CompensateNewLine(prettyPrint, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); json.WriteComment(comment); json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetCommentInObjectExpectedString(bool prettyPrint, string comment) + private static string GetCommentInObjectExpectedString(JsonWriterOptions options, string comment) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; json.WriteComment(comment); - CompensateNewLine(prettyPrint, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); json.WriteStartObject(); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter, 2); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter, 2); json.WriteComment(comment); json.WritePropertyName("property1"); - CompensateWhitespaces(prettyPrint, json, streamWriter); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter); json.WriteComment(comment); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter); json.WriteStartArray(); json.WriteEndArray(); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter, 2); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter, 2); json.WriteComment(comment); json.WritePropertyName("property2"); - CompensateWhitespaces(prettyPrint, json, streamWriter); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter); json.WriteComment(comment); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter); json.WriteStartObject(); json.WriteEndObject(); - CompensateNewLine(prettyPrint, json, streamWriter); - CompensateWhitespaces(prettyPrint, json, streamWriter, 2); + CompensateNewLine(options.Indented, json, streamWriter); + CompensateWhitespaces(options.Indented, json, streamWriter, 2); json.WriteComment(comment); json.WriteEnd(); - CompensateNewLine(prettyPrint, json, streamWriter); + CompensateNewLine(options.Indented, json, streamWriter); json.WriteComment(comment); json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetStringsExpectedString(bool prettyPrint, string value) + private static string GetStringsExpectedString(JsonWriterOptions options, string value) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartArray(); @@ -7573,15 +7118,15 @@ private static string GetStringsExpectedString(bool prettyPrint, string value) json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetEscapedExpectedString(bool prettyPrint, string propertyName, string value, StringEscapeHandling escaping, bool escape = true) + private static string GetEscapedExpectedString(JsonWriterOptions options, string propertyName, string value, StringEscapeHandling escaping, bool escape = true) { using (TextWriter stringWriter = new StringWriter()) using (var json = new JsonTextWriter(stringWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = escaping }) { @@ -7591,18 +7136,18 @@ private static string GetEscapedExpectedString(bool prettyPrint, string property json.WriteEnd(); json.Flush(); - return stringWriter.ToString(); + return HandleIndent(stringWriter.ToString(), options); } } - private static string GetCustomExpectedString(bool prettyPrint) + private static string GetCustomExpectedString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartObject(); @@ -7615,17 +7160,17 @@ private static string GetCustomExpectedString(bool prettyPrint) json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetStartEndExpectedString(bool prettyPrint) + private static string GetStartEndExpectedString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartArray(); @@ -7635,17 +7180,17 @@ private static string GetStartEndExpectedString(bool prettyPrint) json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetStartEndWithPropertyArrayExpectedString(bool prettyPrint) + private static string GetStartEndWithPropertyArrayExpectedString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartObject(); @@ -7656,17 +7201,17 @@ private static string GetStartEndWithPropertyArrayExpectedString(bool prettyPrin json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetStartEndWithPropertyArrayExpectedString(string key, bool prettyPrint, bool escape = false) + private static string GetStartEndWithPropertyArrayExpectedString(string key, JsonWriterOptions options, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml }; @@ -7678,17 +7223,17 @@ private static string GetStartEndWithPropertyArrayExpectedString(string key, boo json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetStartEndWithPropertyObjectExpectedString(bool prettyPrint) + private static string GetStartEndWithPropertyObjectExpectedString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartObject(); @@ -7699,17 +7244,17 @@ private static string GetStartEndWithPropertyObjectExpectedString(bool prettyPri json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetStartEndWithPropertyObjectExpectedString(string key, bool prettyPrint, bool escape = false) + private static string GetStartEndWithPropertyObjectExpectedString(string key, JsonWriterOptions options, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml }; @@ -7721,17 +7266,17 @@ private static string GetStartEndWithPropertyObjectExpectedString(string key, bo json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetArrayWithPropertyExpectedString(bool prettyPrint) + private static string GetArrayWithPropertyExpectedString(JsonWriterOptions options) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartObject(); @@ -7741,17 +7286,17 @@ private static string GetArrayWithPropertyExpectedString(bool prettyPrint) json.WriteEndObject(); json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetBooleanExpectedString(bool prettyPrint, string keyString, bool value, bool escape = false) + private static string GetBooleanExpectedString(JsonWriterOptions options, string keyString, bool value, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; @@ -7771,17 +7316,17 @@ private static string GetBooleanExpectedString(bool prettyPrint, string keyStrin json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetNullExpectedString(bool prettyPrint, string keyString, bool escape = false) + private static string GetNullExpectedString(JsonWriterOptions options, string keyString, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; @@ -7801,17 +7346,17 @@ private static string GetNullExpectedString(bool prettyPrint, string keyString, json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetPropertyExpectedString(bool prettyPrint, T value) + private static string GetPropertyExpectedString(JsonWriterOptions options, T value) { var sb = new StringBuilder(); StringWriter stringWriter = new StringWriter(sb); var json = new JsonTextWriter(stringWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartObject(); @@ -7821,17 +7366,17 @@ private static string GetPropertyExpectedString(bool prettyPrint, T value) json.Flush(); - return sb.ToString(); + return HandleIndent(sb.ToString(), options); } - private static string GetNumbersExpectedString(bool prettyPrint, string keyString, int[] ints, uint[] uints, long[] longs, ulong[] ulongs, float[] floats, double[] doubles, decimal[] decimals, bool escape = false) + private static string GetNumbersExpectedString(JsonWriterOptions options, string keyString, int[] ints, uint[] uints, long[] longs, ulong[] ulongs, float[] floats, double[] doubles, decimal[] decimals, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None + Formatting = options.Indented ? Formatting.Indented : Formatting.None }; json.WriteStartObject(); @@ -7887,7 +7432,7 @@ private static string GetNumbersExpectedString(bool prettyPrint, string keyStrin json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } private static string GetExpectedString_RelaxedEscaping(bool prettyPrint, string keyString) @@ -7918,14 +7463,14 @@ private static string GetExpectedString_RelaxedEscaping(bool prettyPrint, string return Encoding.UTF8.GetString(ms.ToArray()); } - private static string GetGuidsExpectedString(bool prettyPrint, string keyString, Guid[] guids, bool escape = false) + private static string GetGuidsExpectedString(JsonWriterOptions options, string keyString, Guid[] guids, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml }; @@ -7947,17 +7492,17 @@ private static string GetGuidsExpectedString(bool prettyPrint, string keyString, json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetNumbersExpectedString(bool prettyPrint, int numberOfElements, T value) + private static string GetNumbersExpectedString(JsonWriterOptions options, int numberOfElements, T value) { var sb = new StringBuilder(); StringWriter stringWriter = new StringWriter(sb); var json = new JsonTextWriter(stringWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, }; json.WriteStartArray(); @@ -7969,17 +7514,17 @@ private static string GetNumbersExpectedString(bool prettyPrint, int numberOf json.Flush(); - return sb.ToString(); + return HandleIndent(sb.ToString(), options); } - private static string GetDatesExpectedString(bool prettyPrint, string keyString, DateTime[] dates, bool escape = false) + private static string GetDatesExpectedString(JsonWriterOptions options, string keyString, DateTime[] dates, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; @@ -8001,17 +7546,17 @@ private static string GetDatesExpectedString(bool prettyPrint, string keyString, json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } - private static string GetDatesExpectedString(bool prettyPrint, string keyString, DateTimeOffset[] dates, bool escape = false) + private static string GetDatesExpectedString(JsonWriterOptions options, string keyString, DateTimeOffset[] dates, bool escape = false) { var ms = new MemoryStream(); TextWriter streamWriter = new StreamWriter(ms, new UTF8Encoding(false), 1024, true); var json = new JsonTextWriter(streamWriter) { - Formatting = prettyPrint ? Formatting.Indented : Formatting.None, + Formatting = options.Indented ? Formatting.Indented : Formatting.None, StringEscapeHandling = StringEscapeHandling.EscapeHtml, }; @@ -8033,7 +7578,7 @@ private static string GetDatesExpectedString(bool prettyPrint, string keyString, json.Flush(); - return Encoding.UTF8.GetString(ms.ToArray()); + return HandleIndent(Encoding.UTF8.GetString(ms.ToArray()), options); } private static void CompensateWhitespaces(bool prettyPrint, JsonTextWriter json, TextWriter streamWriter, int whitespaceCount = 1) @@ -8054,6 +7599,13 @@ private static void CompensateNewLine(bool prettyPrint, JsonTextWriter json, Tex } } + private static string HandleIndent(string text, JsonWriterOptions options) + { + return text.Replace(" ", GetIndentText(options)); + } + + private static string GetIndentText(JsonWriterOptions options) => new(options.IndentCharacter, options.IndentSize); + public static IEnumerable JsonEncodedTextStrings { get @@ -8069,6 +7621,35 @@ public static IEnumerable JsonEncodedTextStrings }; } } + + private static IEnumerable JsonOptions() + { + return from indented in new[] { true, false } + from skipValidation in new[] { true, false } + from indentCharacter in indented ? new char?[] { null, ' ', '\t' } : [] + from indentSize in indented ? new int?[] { null, 0, 1, 2, 127 } : [] + select CreateOptions(indented, indentCharacter, indentSize, skipValidation); + + static JsonWriterOptions CreateOptions(bool indented, char? indentCharacter, int? indentSize, bool skipValidation) + { + var options = new JsonWriterOptions { Indented = indented, SkipValidation = skipValidation }; + if (indentCharacter is not null) options.IndentCharacter = (char)indentCharacter; + if (indentSize is not null) options.IndentSize = (int)indentSize; + return options; + } + } + + private static IEnumerable JsonOptionsWith(IEnumerable others) => + from options in JsonOptions() + from inputValue in others + select new object[] { options, inputValue }; + + private static IEnumerable JsonOptionsWith(IEnumerable others, IEnumerable anothers) => + from options in JsonOptions() + from inputValue in others + from anotherValue in anothers + select new object[] { options, inputValue, anotherValue }; + } public static class WriterHelpers