mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-14 17:23:27 -05:00
* Minimal changes to make headers appear on empty result sets * Columns for everyone! * Updating tests - some don't pass yet * Adding some more tests to verify the changes for column/row selection * null default columns * Updates to comments as per PR comments
228 lines
8.8 KiB
C#
228 lines
8.8 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.IO;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts;
|
|
using Microsoft.SqlTools.ServiceLayer.QueryExecution.DataStorage;
|
|
using Microsoft.SqlTools.ServiceLayer.UnitTests.Utility;
|
|
using NUnit.Framework;
|
|
|
|
namespace Microsoft.SqlTools.ServiceLayer.UnitTests.QueryExecution.DataStorage
|
|
{
|
|
[TestFixture]
|
|
public class SaveAsXmlFileStreamWriterTests
|
|
{
|
|
[TestCase(false)]
|
|
[TestCase(true)]
|
|
public void ConstructAndDispose(bool formatted)
|
|
{
|
|
// Setup: Create test request and storage for the output
|
|
var saveParams = new SaveResultsAsXmlRequestParams { Formatted = formatted };
|
|
var columns = Array.Empty<DbColumnWrapper>();
|
|
var output = new byte[8192];
|
|
|
|
// If: I create and dispose of an XML file writer
|
|
var xmlWriter = new SaveAsXmlFileStreamWriter(new MemoryStream(output), saveParams, columns);
|
|
xmlWriter.Dispose();
|
|
|
|
// Then:
|
|
// ... The output should be just the XML node and the root node
|
|
var rootNode = ParseOutput(output, Encoding.UTF8);
|
|
Assert.IsEmpty(rootNode.ChildNodes);
|
|
|
|
// ... If the output is formatted, there should be multiple lines
|
|
// otherwise, there should be only one line
|
|
if (formatted)
|
|
{
|
|
CollectionAssert.Contains(output, (byte)'\n');
|
|
}
|
|
else
|
|
{
|
|
CollectionAssert.DoesNotContain(output, (byte)'\n');
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void WriteRow_WithoutColumnSelection()
|
|
{
|
|
// Setup:
|
|
// ... Create request params that has no selection made
|
|
// ... Create a set of data to write
|
|
// ... Create storage for the output
|
|
var saveParams = new SaveResultsAsXmlRequestParams();
|
|
var data = new[]
|
|
{
|
|
new DbCellValue { DisplayValue = "item1", RawObject = "item1" },
|
|
new DbCellValue { DisplayValue = "null", RawObject = null }
|
|
};
|
|
var columns = new[]
|
|
{
|
|
new DbColumnWrapper(new TestDbColumn("column1")),
|
|
new DbColumnWrapper(new TestDbColumn("column2"))
|
|
};
|
|
var output = new byte[8192];
|
|
|
|
// If: I write two rows
|
|
using (var xmlWriter = new SaveAsXmlFileStreamWriter(new MemoryStream(output), saveParams, columns))
|
|
{
|
|
xmlWriter.WriteRow(data, columns);
|
|
xmlWriter.WriteRow(data, columns);
|
|
}
|
|
|
|
// Then:
|
|
// ... XML should be well formed
|
|
var rootNode = ParseOutput(output, Encoding.UTF8);
|
|
|
|
// ... Data node should have two nodes for the two rows
|
|
Assert.AreEqual(2, rootNode.ChildNodes.Count);
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
// ... Each row should have two nodes for the two cells
|
|
var row = rootNode.ChildNodes[i];
|
|
Assert.IsNotNull(row);
|
|
Assert.AreEqual(2, row.ChildNodes.Count);
|
|
for (int j = 0; j < 2; j++)
|
|
{
|
|
var cell = row.ChildNodes[j];
|
|
Assert.IsNotNull(cell);
|
|
|
|
// ... Node name should be column name
|
|
Assert.AreEqual(columns[j].ColumnName, cell.Name);
|
|
|
|
// ... Node value should be cell value
|
|
if (data[j].RawObject == null)
|
|
{
|
|
Assert.IsEmpty(cell.InnerText);
|
|
}
|
|
else
|
|
{
|
|
Assert.AreEqual(data[j].DisplayValue, cell.InnerText);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void WriteRow_WithColumnSelection()
|
|
{
|
|
// Setup:
|
|
// ... Create request params that has a selection made
|
|
// ... Create a set of data to write
|
|
// ... Create storage for the output
|
|
var saveParams = new SaveResultsAsXmlRequestParams
|
|
{
|
|
ColumnEndIndex = 2,
|
|
ColumnStartIndex = 1,
|
|
RowEndIndex = 0, // Required for being considered a "selection"
|
|
RowStartIndex = 0
|
|
};
|
|
var data = new[]
|
|
{
|
|
new DbCellValue { DisplayValue = "foo" },
|
|
new DbCellValue { DisplayValue = "item1", RawObject = "item1" },
|
|
new DbCellValue { DisplayValue = "null", RawObject = null },
|
|
new DbCellValue { DisplayValue = "bar" }
|
|
};
|
|
var columns = new[]
|
|
{
|
|
new DbColumnWrapper(new TestDbColumn("ignoredCol")),
|
|
new DbColumnWrapper(new TestDbColumn("column1")),
|
|
new DbColumnWrapper(new TestDbColumn("column2")),
|
|
new DbColumnWrapper(new TestDbColumn("ignoredCol"))
|
|
};
|
|
var output = new byte[8192];
|
|
|
|
// If: I write two rows
|
|
using (var xmlWriter = new SaveAsXmlFileStreamWriter(new MemoryStream(output), saveParams, columns))
|
|
{
|
|
xmlWriter.WriteRow(data, columns);
|
|
xmlWriter.WriteRow(data, columns);
|
|
}
|
|
|
|
// Then:
|
|
// ... XML should be well formed
|
|
var rootNode = ParseOutput(output, Encoding.UTF8);
|
|
|
|
// ... Data node should have two nodes for the two rows
|
|
Assert.AreEqual(2, rootNode.ChildNodes.Count);
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
// ... Each row should have two nodes for the two cells
|
|
var row = rootNode.ChildNodes[i];
|
|
Assert.IsNotNull(row);
|
|
Assert.AreEqual(2, row.ChildNodes.Count);
|
|
for (int j = 0; j < 1; j++)
|
|
{
|
|
var cell = row.ChildNodes[j];
|
|
var columnIndex = j + 1;
|
|
Assert.IsNotNull(cell);
|
|
|
|
// ... Node name should be column name
|
|
Assert.AreEqual(columns[columnIndex].ColumnName, cell.Name);
|
|
|
|
// ... Node value should be cell value
|
|
if (data[columnIndex].RawObject == null)
|
|
{
|
|
Assert.IsEmpty(cell.InnerText);
|
|
}
|
|
else
|
|
{
|
|
Assert.AreEqual(data[columnIndex].DisplayValue, cell.InnerText);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void WriteRow_NonDefaultEncoding()
|
|
{
|
|
// Setup:
|
|
// ... Create request params that uses a special encoding
|
|
// ... Create a set of data to write
|
|
// ... Create storage for the output
|
|
var saveParams = new SaveResultsAsXmlRequestParams { Encoding = "Windows-1252" };
|
|
var data = new[] { new DbCellValue { DisplayValue = "ü", RawObject = "ü" } };
|
|
var columns = new[] { new DbColumnWrapper(new TestDbColumn("column1")) };
|
|
byte[] output = new byte[8192];
|
|
|
|
// If: I write the row
|
|
using (var xmlWriter = new SaveAsXmlFileStreamWriter(new MemoryStream(output), saveParams, columns))
|
|
{
|
|
xmlWriter.WriteRow(data, columns);
|
|
}
|
|
|
|
// Then:
|
|
// ... The XML file should have been written properly in windows-1252 encoding
|
|
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
|
|
var encoding = Encoding.GetEncoding("Windows-1252");
|
|
var rootNode = ParseOutput(output, encoding);
|
|
|
|
// ... The umlaut should be written using Windows-1252
|
|
Assert.IsNotNull(rootNode.ChildNodes[0]); // <row>
|
|
Assert.IsNotNull(rootNode.ChildNodes[0].ChildNodes[0]); // <column1>
|
|
Assert.AreEqual(rootNode.ChildNodes[0].ChildNodes[0].InnerText, "ü");
|
|
}
|
|
|
|
private XmlNode ParseOutput(byte[] bytes, Encoding encoding)
|
|
{
|
|
var outputString = encoding.GetString(bytes)
|
|
.TrimStart(encoding.GetString(encoding.Preamble).ToCharArray()) // Trim any BOM
|
|
.Trim('\0');
|
|
var xmlDoc = new XmlDocument();
|
|
xmlDoc.LoadXml(outputString);
|
|
|
|
// Assert: Two elements at the root, XML and the root node
|
|
Assert.AreEqual(2, xmlDoc.ChildNodes.Count);
|
|
Assert.AreEqual("xml", xmlDoc.ChildNodes[0]?.Name);
|
|
Assert.AreEqual("data", xmlDoc.ChildNodes[1]?.Name);
|
|
|
|
return xmlDoc.ChildNodes[1];
|
|
}
|
|
}
|
|
}
|