mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 01:25:40 -05:00
* Remove xunit dependency from testdriver * swap expected/actual as needed * Convert Test.Common to nunit * port hosting unit tests to nunit * port batchparser integration tests to nunit * port testdriver.tests to nunit * fix target to copy dependency * port servicelayer unittests to nunit * more unit test fixes * port integration tests to nunit * fix test method type * try using latest windows build for PRs * reduce test memory use
158 lines
5.9 KiB
C#
158 lines
5.9 KiB
C#
//
|
|
// Copyright (c) Microsoft. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
//
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.SqlTools.Hosting.Protocol;
|
|
using Newtonsoft.Json;
|
|
using NUnit.Framework;
|
|
|
|
namespace Microsoft.SqlTools.Hosting.UnitTests.ProtocolTests
|
|
{
|
|
[TestFixture]
|
|
public class MessageWriterTests
|
|
{
|
|
#region Construction Tests
|
|
|
|
[Test]
|
|
public void ConstructMissingOutputStream()
|
|
{
|
|
// If: I attempt to create a message writer without an output stream
|
|
// Then: I should get an exception
|
|
Assert.Throws<ArgumentNullException>(() => new MessageWriter(null));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region WriteMessageTests
|
|
|
|
[Test]
|
|
public async Task WriteMessageNullMessage()
|
|
{
|
|
// If: I write a null message
|
|
// Then: I should get an exception
|
|
var mw = new MessageWriter(Stream.Null);
|
|
Assert.ThrowsAsync<ArgumentNullException>(() => mw.WriteMessage(null));
|
|
}
|
|
|
|
[TestCaseSource(nameof(WriteMessageData))]
|
|
public async Task WriteMessage(object contents, Dictionary<string, object> expectedDict)
|
|
{
|
|
// NOTE: This technically tests the ability of the Message class to properly serialize
|
|
// various types of message contents. This *should* be part of the message tests
|
|
// but it is simpler to test it here.
|
|
|
|
// Setup: Create a stream to capture the output
|
|
var output = new byte[8192];
|
|
using (var outputStream = new MemoryStream(output))
|
|
{
|
|
// If: I write a message
|
|
var mw = new MessageWriter(outputStream);
|
|
await mw.WriteMessage(Message.CreateResponse(CommonObjects.MessageId, contents));
|
|
|
|
// Then:
|
|
// ... The returned bytes on the stream should compose a valid message
|
|
Assert.That(outputStream.Position, Is.Not.EqualTo(0), "outputStream.Position after WriteMessage");
|
|
var messageDict = ValidateMessageHeaders(output, (int) outputStream.Position);
|
|
|
|
// ... ID, Params, Method should be present
|
|
AssertMessage(messageDict, expectedDict);
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<object[]> WriteMessageData
|
|
{
|
|
get
|
|
{
|
|
yield return new object[]
|
|
{
|
|
null,
|
|
new Dictionary<string, object> {{"id", "123"}, {"result", null}}
|
|
};
|
|
yield return new object[]
|
|
{
|
|
"simple param",
|
|
new Dictionary<string, object> {{"id", "123"}, {"result", "simple param"}}
|
|
};
|
|
yield return new object[]
|
|
{
|
|
CommonObjects.TestMessageContents.DefaultInstance,
|
|
new Dictionary<string, object> {{"id", "123"}, {"result", CommonObjects.TestMessageContents.SerializedContents}}
|
|
};
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private Helpers
|
|
|
|
private static void AssertMessage(Dictionary<string, object> messageDict, Dictionary<string, object> expectedDict)
|
|
{
|
|
// Add the jsonrpc property to the expected dict
|
|
expectedDict.Add("jsonrpc", "2.0");
|
|
|
|
// Make sure the number of elements in both dictionaries are the same
|
|
Assert.AreEqual(expectedDict.Count, messageDict.Count);
|
|
|
|
// Make sure the elements match
|
|
foreach (var kvp in expectedDict)
|
|
{
|
|
Assert.AreEqual(expectedDict[kvp.Key], messageDict[kvp.Key]);
|
|
}
|
|
}
|
|
|
|
private static Dictionary<string, object> ValidateMessageHeaders(byte[] outputBytes, int bytesWritten)
|
|
{
|
|
// Convert the written bytes to a string
|
|
string outputString = Encoding.UTF8.GetString(outputBytes, 0, bytesWritten);
|
|
|
|
// There should be two sections to the message
|
|
string[] outputParts = outputString.Split("\r\n\r\n");
|
|
Assert.AreEqual(2, outputParts.Length);
|
|
|
|
// The first section is the headers
|
|
string[] headers = outputParts[0].Split("\r\n");
|
|
Assert.AreEqual(2, outputParts.Length);
|
|
|
|
// There should be a content-type and a content-length
|
|
int? contentLength = null;
|
|
bool contentTypeCorrect = false;
|
|
foreach (string header in headers)
|
|
{
|
|
// Headers should look like "Header-Key: HeaderValue"
|
|
string[] headerParts = header.Split(':');
|
|
Assert.AreEqual(2, headerParts.Length);
|
|
|
|
string headerKey = headerParts[0];
|
|
string headerValue = headerParts[1].Trim();
|
|
|
|
if (headerKey == "Content-Type" && headerValue.StartsWith("application/json"))
|
|
{
|
|
contentTypeCorrect = true;
|
|
}
|
|
else if (headerKey == "Content-Length")
|
|
{
|
|
contentLength = int.Parse(headerValue);
|
|
}
|
|
else
|
|
{
|
|
throw new Exception($"Invalid header provided: {headerKey}");
|
|
}
|
|
}
|
|
|
|
// Make sure the headers are correct
|
|
Assert.True(contentTypeCorrect);
|
|
Assert.AreEqual(outputParts[1].Length, contentLength);
|
|
|
|
// Deserialize the body into a dictionary
|
|
return JsonConvert.DeserializeObject<Dictionary<string, object>>(outputParts[1]);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |