From d69193e49c01dcc30de5d852f0fe6c3bc61551b7 Mon Sep 17 00:00:00 2001 From: Kitt Holland Date: Fri, 24 Feb 2017 14:40:11 -0800 Subject: [PATCH] Prettier formatting for ConvertTo-Json output. #2736 (#2787) * Prettier formatting for ConvertTo-Json output. #2736 This change standardizes JSON output to example given, as well as codemaid and online lint tools. Sample object used for testing: @{ foo = @{ first = 'a' second = 'bbbbbbbb' } barbarbarbar = @{ first = 'a' second = 'bbbbbbbb' NestedArray = @( 'Test3' 'Test4' 'Test5' 3 4 ) NestedObject = @{ MoreObject = 'AnotherObject' TestBool = $true } } array = @( 'Thing1' 'Thing2' ) dan = 15 } | ConvertTo-Json * Updated CoreCLR implementation to use NewtonSoft Indented Formatting I did not change the FullCLR behavior, I was not sure if you meant to revert my changes or to leave it as is in the current pull request. * Added tests that validate pretty Json output. Not sure if there is a better thought on how to implement these. The first two fail against current master, but succeed once this PR is applied. Third test is successful prior and post this PR. * Moved tests and removed extraneous file. Moved pretty/compressed json tests from standalone file into the existing ConvertTo-Json test file. * Updated tests for cross-platform support --- .../utility/WebCmdlet/ConvertToJsonCommand.cs | 17 ++++++++----- .../Pester.Commands.Cmdlets.Json.Tests.ps1 | 24 +++++++++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs index e020e8bf2e..eef7da897e 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WebCmdlet/ConvertToJsonCommand.cs @@ -121,7 +121,13 @@ namespace Microsoft.PowerShell.Commands // values cannot be evaluated are treated as having the value null. object preprocessedObject = ProcessValue(objectToProcess, 0); #if CORECLR - string output = JsonConvert.SerializeObject(preprocessedObject, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.None, MaxDepth = 1024 }); + JsonSerializerSettings jsonSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None, MaxDepth = 1024 }; + if (!Compress) + { + jsonSettings.Formatting = Formatting.Indented; + } + string output = JsonConvert.SerializeObject(preprocessedObject, jsonSettings); + WriteObject(output); #else // In Full CLR, we use the JavaScriptSerializer for which RecursionLimit was set to the default value of 100 (the actual recursion limit is 99 since // at 100 the exception is thrown). See https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.recursionlimit(v=vs.110).aspx @@ -131,8 +137,8 @@ namespace Microsoft.PowerShell.Commands JavaScriptSerializer helper = new JavaScriptSerializer() { RecursionLimit = (maxDepthAllowed + 2) }; helper.MaxJsonLength = Int32.MaxValue; string output = helper.Serialize(preprocessedObject); -#endif WriteObject(Compress ? output : ConvertToPrettyJsonString(output)); +#endif } } @@ -296,7 +302,7 @@ namespace Microsoft.PowerShell.Commands bool headChar = true; bool beforeQuote = true; int newSpaceCount = 0; - const int spaceCountAfterQuoteMark = 2; + const int spaceCountAfterQuoteMark = 1; for (int i = index; i < json.Length; i++) { @@ -327,7 +333,7 @@ namespace Microsoft.PowerShell.Commands int end = ConvertQuotedString(json, i + 1, result); if (beforeQuote) { - newSpaceCount += (end - i + 1); + newSpaceCount = 0; } i = end; headChar = false; @@ -335,7 +341,6 @@ namespace Microsoft.PowerShell.Commands case ':': result.Append(json[i]); AddSpaces(spaceCountAfterQuoteMark, result); - newSpaceCount += 3; headChar = false; beforeQuote = false; break; @@ -373,7 +378,7 @@ namespace Microsoft.PowerShell.Commands /// private void AddIndentations(int numberOfTabsToReturn, StringBuilder result) { - int realNumber = numberOfTabsToReturn * 4; + int realNumber = numberOfTabsToReturn * 2; for (int i = 0; i < realNumber; i++) { result.Append(' '); diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.Json.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.Json.Tests.ps1 index 9011233388..b2feb204c3 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.Json.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Pester.Commands.Cmdlets.Json.Tests.ps1 @@ -1352,6 +1352,30 @@ Describe "Validate Json serialization" -Tags "CI" { $actual | Should Be $expectedNoWhiteSpace } } + + + Context "Validate Json output is either Pretty or Compressed" { + + It "Should print a pretty Array" { + $array = 'one', 'two', 'three' + $response = $array | ConvertTo-Json + ($response -split "\r?\n")[1] | Should Be ' "one",' + } + + It "Should print a pretty dictionary" { + $dictionary = [Ordered]@{ + 'one' = 1 + 'two' = 2 + 'three' = 3 + } + $response2 = $dictionary | ConvertTo-Json + ($response2 -split "\r?\n")[1] | Should Be ' "one": 1,' + } + + It "Should minify Json with Compress switch" { + (@{ a = 1 } | ConvertTo-Json -Compress).Length | Should Be 7 + } + } } Describe "Json Bug fixes" -Tags "Feature" {