PowerShell/test/xUnit/csharp/test_Utils.cs
Dongbo Wang c606b1ca37 Refactor ConvertTo-Json to expose JsonObject.ConvertToJson as a public API (#8682)
We have the public API `JsonObject.ConvertFromJson` to convert from JSON string in the PowerShell context. It would be good to have a public API for conversion to JSON. This PR refactors the `ConvertTo-Json` cmdlet to move the core implementation to `JsonObject.ConvertToJson`, and make `ConvertTo-Json` call that public method.

This would help the Azure Function PowerShell worker. Currently, we depends on [calling the cmdlet](729710d259/src/PowerShell/PowerShellManager.cs (L198-L205)) to convert object to JSON which is expensive. Once we have the public method `JsonObject.ConvertToJson` exposed, we can call the API directly to avoid a command invocation.
2019-01-23 10:39:12 -08:00

150 lines
5.4 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Management.Automation;
using System.Management.Automation.Internal;
using System.Threading;
using System.Reflection;
using Microsoft.PowerShell.Commands;
using Xunit;
namespace PSTests.Parallel
{
public static class UtilsTests
{
[SkippableFact]
public static void TestIsWinPEHost()
{
Skip.IfNot(Platform.IsWindows);
Assert.False(Utils.IsWinPEHost());
}
[Fact]
public static void TestHistoryStack()
{
var historyStack = new HistoryStack<string>(20);
Assert.Equal(0, historyStack.UndoCount);
Assert.Equal(0, historyStack.RedoCount);
historyStack.Push("first item");
historyStack.Push("second item");
Assert.Equal(2, historyStack.UndoCount);
Assert.Equal(0, historyStack.RedoCount);
Assert.Equal("second item", historyStack.Undo("second item"));
Assert.Equal("first item", historyStack.Undo("first item"));
Assert.Equal(0, historyStack.UndoCount);
Assert.Equal(2, historyStack.RedoCount);
Assert.Equal("first item", historyStack.Redo("first item"));
Assert.Equal(1, historyStack.UndoCount);
Assert.Equal(1, historyStack.RedoCount);
// Pushing a new item should invalidate the RedoCount
historyStack.Push("third item");
Assert.Equal(2, historyStack.UndoCount);
Assert.Equal(0, historyStack.RedoCount);
// Check for the correct exception when the Redo/Undo stack is empty.
Assert.Throws<InvalidOperationException>(() => historyStack.Redo("bar"));
historyStack.Undo("third item");
historyStack.Undo("first item");
Assert.Equal(0, historyStack.UndoCount);
Assert.Throws<InvalidOperationException>(() => historyStack.Undo("foo"));
}
[Fact]
public static void TestBoundedStack()
{
uint capacity = 20;
var boundedStack = new BoundedStack<string>(capacity);
Assert.Throws<InvalidOperationException>(() => boundedStack.Pop());
for (int i = 0; i < capacity; i++)
{
boundedStack.Push($"{i}");
}
for (int i = 0; i < capacity; i++)
{
var poppedItem = boundedStack.Pop();
Assert.Equal($"{20 - 1 - i}", poppedItem);
}
Assert.Throws<InvalidOperationException>(() => boundedStack.Pop());
}
[Fact]
public static void TestConvertToJsonBasic()
{
var context = new JsonObject.ConvertToJsonContext(maxDepth: 1, enumsAsStrings: false, compressOutput: true);
string expected = "{\"name\":\"req\",\"type\":\"http\"}";
OrderedDictionary hash = new OrderedDictionary {
{"name", "req"},
{"type", "http"}
};
string json = JsonObject.ConvertToJson(hash, in context);
Assert.Equal(expected, json);
hash.Add("self", hash);
json = JsonObject.ConvertToJson(hash, context);
expected = "{\"name\":\"req\",\"type\":\"http\",\"self\":{\"name\":\"req\",\"type\":\"http\",\"self\":\"System.Collections.Specialized.OrderedDictionary\"}}";
Assert.Equal(expected, json);
}
[Fact]
public static void TestConvertToJsonWithEnum()
{
var context = new JsonObject.ConvertToJsonContext(maxDepth: 1, enumsAsStrings: false, compressOutput: true);
string expected = "{\"type\":1}";
Hashtable hash = new Hashtable {
{"type", CommandTypes.Alias}
};
string json = JsonObject.ConvertToJson(hash, in context);
Assert.Equal(expected, json);
context = new JsonObject.ConvertToJsonContext(maxDepth: 1, enumsAsStrings: true, compressOutput: true);
json = JsonObject.ConvertToJson(hash, in context);
expected = "{\"type\":\"Alias\"}";
Assert.Equal(expected, json);
}
[Fact]
public static void TestConvertToJsonWithoutCompress()
{
var context = new JsonObject.ConvertToJsonContext(maxDepth: 1, enumsAsStrings: true, compressOutput: false);
string expected = @"{
""type"": ""Alias""
}";
Hashtable hash = new Hashtable {
{"type", CommandTypes.Alias}
};
string json = JsonObject.ConvertToJson(hash, in context);
Assert.Equal(expected, json);
}
[Fact]
public static void TestConvertToJsonCancellation()
{
var source = new CancellationTokenSource();
var context = new JsonObject.ConvertToJsonContext(
maxDepth: 1,
enumsAsStrings: true,
compressOutput: false,
source.Token,
Newtonsoft.Json.StringEscapeHandling.Default,
targetCmdlet: null);
source.Cancel();
Hashtable hash = new Hashtable {
{"type", CommandTypes.Alias}
};
string json = JsonObject.ConvertToJson(hash, in context);
Assert.Null(json);
}
}
}