Skip to content

Commit

Permalink
Merge pull request #11 from Microsoft/testing
Browse files Browse the repository at this point in the history
Additional testing
  • Loading branch information
davilimap authored May 9, 2017
2 parents fe158bf + 9b04165 commit 9ffc6fd
Show file tree
Hide file tree
Showing 5 changed files with 509 additions and 5 deletions.
323 changes: 323 additions & 0 deletions src/Microsoft.VisualStudio.Jdt.Tests/JsonTransformationTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE file in the project root for full license information.

namespace Microsoft.VisualStudio.Jdt.Tests
{
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Xunit;

/// <summary>
/// Test class for <see cref="JsonTransformation"/>
/// </summary>
public class JsonTransformationTest
{
private static readonly string SimpleSourceString = @"{ 'A': 1 }";

private readonly JsonTransformationTestLogger logger;

/// <summary>
/// Initializes a new instance of the <see cref="JsonTransformationTest"/> class.
/// </summary>
public JsonTransformationTest()
{
// xUnit creates a new instance of the class for each test, so a new logger is created
this.logger = new JsonTransformationTestLogger();
}

/// <summary>
/// Tests the error caused when an invalid verb is found
/// </summary>
[Fact]
public void InvalidVerb()
{
string transformString = @"{
'@jdt.invalid': false
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error should be where at the location of the invalid verb
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 56, true);
}

/// <summary>
/// Tests the error caused by a verb having an invalid value
/// </summary>
[Fact]
public void InvalidVerbValue()
{
string transformString = @"{
'@jdt.remove': 10
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the location of the invalid value
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 58, true);
}

/// <summary>
/// Tests the error caused when an invalid attribute is found within a verb
/// </summary>
[Fact]
public void InvalidAttribute()
{
string transformString = @"{
'@jdt.replace': {
'@jdt.invalid': false
}
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the position of the invalid attribute
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 3, 58, true);
}

/// <summary>
/// Tests the error caused when a required attribute is not found
/// </summary>
[Fact]
public void MissingAttribute()
{
string transformString = @"{
'@jdt.rename': {
'@jdt.path': 'A'
}
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the beginning of the object with the missing attribute
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 57, true);
}

/// <summary>
/// Tests the error caused when a verb object contains attributes and other objects
/// </summary>
[Fact]
public void MixedAttributes()
{
string transformString = @"{
'@jdt.rename': {
'@jdt.path': 'A',
'@jdt.value': 'Astar',
'NotAttribute': true
}
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the beginning of the object with the mixed attribute
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 57, true);
}

/// <summary>
/// Tests the error caused when an attribute has an incorrect value
/// </summary>
[Fact]
public void WrongAttributeValue()
{
string transformString = @"{
'@jdt.remove': {
'@jdt.path': false
}
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the position of the invalid value
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 3, 61, true);
}

/// <summary>
/// Tests the error caused when a path attribute returns no result
/// </summary>
[Fact]
public void RemoveNonExistantNode()
{
string transformString = @"{
'@jdt.remove': {
'@jdt.path': 'B'
}
}";

this.TryTransformTest(SimpleSourceString, transformString, true);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.ErrorLog);

// The warning location should be at the position of the path value that yielded no results
LogHasSingleEntry(this.logger.WarningLog, ErrorLocation.Transform.ToString(), 3, 59, false);
}

/// <summary>
/// Tests the error caused when attempting to remove the root node
/// </summary>
[Fact]
public void RemoveRoot()
{
string transformString = @"{
'@jdt.remove': true
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the position of the remove value
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 60, true);
}

/// <summary>
/// Tests the error when a rename value is invalid
/// </summary>
[Fact]
public void InvalidRenameValue()
{
string transformString = @"{
'@jdt.rename': {
'A': 10
}
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The error location should be at the position of the rename property
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 3, 47, true);
}

/// <summary>
/// Tests the error caused when attempting to rename a non-existant node
/// </summary>
[Fact]
public void RenameNonExistantNode()
{
string transformString = @"{
'@jdt.rename': {
'B': 'Bstar'
}
}";

this.TryTransformTest(SimpleSourceString, transformString, true);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.ErrorLog);

// The position of the warning should be a the beginning of the rename property
LogHasSingleEntry(this.logger.WarningLog, ErrorLocation.Transform.ToString(), 3, 47, false);
}

/// <summary>
/// Test the error when attempting to replace the root with a non-object token
/// </summary>
[Fact]
public void ReplaceRoot()
{
string transformString = @"{
'@jdt.replace': 10
}";

this.TryTransformTest(SimpleSourceString, transformString, false);

Assert.Empty(this.logger.MessageLog);
Assert.Empty(this.logger.WarningLog);

// The position of the error should be at the value of replace that caused it
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 59, true);
}

/// <summary>
/// Tests that an exception is thrown when <see cref="JsonTransformation.Apply(Stream)"/> is called
/// </summary>
[Fact]
public void ThrowAndLogException()
{
string transformString = @"{
'@jdt.invalid': false
}";
using (var transformStream = this.GetStreamFromString(transformString))
using (var sourceStream = this.GetStreamFromString(SimpleSourceString))
{
JsonTransformation transform = new JsonTransformation(transformStream, this.logger);
var exception = Record.Exception(() => transform.Apply(sourceStream));
Assert.NotNull(exception);
Assert.IsType<JdtException>(exception);
var jdtException = exception as JdtException;
Assert.Contains("invalid", jdtException.Message);
Assert.Equal(ErrorLocation.Transform, jdtException.Location);
Assert.Equal(2, jdtException.LineNumber);
Assert.Equal(56, jdtException.LinePosition);
}
}

private static void LogHasSingleEntry(List<JsonTransformationTestLogger.TestLogEntry> log, string fileName, int lineNumber, int linePosition, bool fromException)
{
Assert.Single(log);
var errorEntry = log.Single();
Assert.Equal(fileName, errorEntry.FileName);
Assert.Equal(lineNumber, errorEntry.LineNumber);
Assert.Equal(linePosition, errorEntry.LinePosition);
Assert.Equal(fromException, errorEntry.FromException);
}

private void TryTransformTest(string sourceString, string transformString, bool shouldTransformSucceed)
{
using (var transformStream = this.GetStreamFromString(transformString))
using (var sourceStream = this.GetStreamFromString(sourceString))
{
JsonTransformation transform = new JsonTransformation(transformStream, this.logger);
Stream result = null;

var exception = Record.Exception(() => result = transform.Apply(sourceStream));

if (shouldTransformSucceed)
{
Assert.NotNull(result);
Assert.Null(exception);
}
else
{
Assert.Null(result);
Assert.NotNull(exception);
Assert.IsType<JdtException>(exception);
}
}
}

private Stream GetStreamFromString(string s)
{
MemoryStream stringStream = new MemoryStream();
StreamWriter stringWriter = new StreamWriter(stringStream);
stringWriter.Write(s);
stringWriter.Flush();
stringStream.Position = 0;

return stringStream;
}
}
}
Loading

0 comments on commit 9ffc6fd

Please sign in to comment.