Skip to content

Commit 9ffc6fd

Browse files
authored
Merge pull request #11 from Microsoft/testing
Additional testing
2 parents fe158bf + 9b04165 commit 9ffc6fd

File tree

5 files changed

+509
-5
lines changed

5 files changed

+509
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
3+
4+
namespace Microsoft.VisualStudio.Jdt.Tests
5+
{
6+
using System.Collections.Generic;
7+
using System.IO;
8+
using System.Linq;
9+
using Xunit;
10+
11+
/// <summary>
12+
/// Test class for <see cref="JsonTransformation"/>
13+
/// </summary>
14+
public class JsonTransformationTest
15+
{
16+
private static readonly string SimpleSourceString = @"{ 'A': 1 }";
17+
18+
private readonly JsonTransformationTestLogger logger;
19+
20+
/// <summary>
21+
/// Initializes a new instance of the <see cref="JsonTransformationTest"/> class.
22+
/// </summary>
23+
public JsonTransformationTest()
24+
{
25+
// xUnit creates a new instance of the class for each test, so a new logger is created
26+
this.logger = new JsonTransformationTestLogger();
27+
}
28+
29+
/// <summary>
30+
/// Tests the error caused when an invalid verb is found
31+
/// </summary>
32+
[Fact]
33+
public void InvalidVerb()
34+
{
35+
string transformString = @"{
36+
'@jdt.invalid': false
37+
}";
38+
39+
this.TryTransformTest(SimpleSourceString, transformString, false);
40+
41+
Assert.Empty(this.logger.MessageLog);
42+
Assert.Empty(this.logger.WarningLog);
43+
44+
// The error should be where at the location of the invalid verb
45+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 56, true);
46+
}
47+
48+
/// <summary>
49+
/// Tests the error caused by a verb having an invalid value
50+
/// </summary>
51+
[Fact]
52+
public void InvalidVerbValue()
53+
{
54+
string transformString = @"{
55+
'@jdt.remove': 10
56+
}";
57+
58+
this.TryTransformTest(SimpleSourceString, transformString, false);
59+
60+
Assert.Empty(this.logger.MessageLog);
61+
Assert.Empty(this.logger.WarningLog);
62+
63+
// The error location should be at the location of the invalid value
64+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 58, true);
65+
}
66+
67+
/// <summary>
68+
/// Tests the error caused when an invalid attribute is found within a verb
69+
/// </summary>
70+
[Fact]
71+
public void InvalidAttribute()
72+
{
73+
string transformString = @"{
74+
'@jdt.replace': {
75+
'@jdt.invalid': false
76+
}
77+
}";
78+
79+
this.TryTransformTest(SimpleSourceString, transformString, false);
80+
81+
Assert.Empty(this.logger.MessageLog);
82+
Assert.Empty(this.logger.WarningLog);
83+
84+
// The error location should be at the position of the invalid attribute
85+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 3, 58, true);
86+
}
87+
88+
/// <summary>
89+
/// Tests the error caused when a required attribute is not found
90+
/// </summary>
91+
[Fact]
92+
public void MissingAttribute()
93+
{
94+
string transformString = @"{
95+
'@jdt.rename': {
96+
'@jdt.path': 'A'
97+
}
98+
}";
99+
100+
this.TryTransformTest(SimpleSourceString, transformString, false);
101+
102+
Assert.Empty(this.logger.MessageLog);
103+
Assert.Empty(this.logger.WarningLog);
104+
105+
// The error location should be at the beginning of the object with the missing attribute
106+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 57, true);
107+
}
108+
109+
/// <summary>
110+
/// Tests the error caused when a verb object contains attributes and other objects
111+
/// </summary>
112+
[Fact]
113+
public void MixedAttributes()
114+
{
115+
string transformString = @"{
116+
'@jdt.rename': {
117+
'@jdt.path': 'A',
118+
'@jdt.value': 'Astar',
119+
'NotAttribute': true
120+
}
121+
}";
122+
123+
this.TryTransformTest(SimpleSourceString, transformString, false);
124+
125+
Assert.Empty(this.logger.MessageLog);
126+
Assert.Empty(this.logger.WarningLog);
127+
128+
// The error location should be at the beginning of the object with the mixed attribute
129+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 57, true);
130+
}
131+
132+
/// <summary>
133+
/// Tests the error caused when an attribute has an incorrect value
134+
/// </summary>
135+
[Fact]
136+
public void WrongAttributeValue()
137+
{
138+
string transformString = @"{
139+
'@jdt.remove': {
140+
'@jdt.path': false
141+
}
142+
}";
143+
144+
this.TryTransformTest(SimpleSourceString, transformString, false);
145+
146+
Assert.Empty(this.logger.MessageLog);
147+
Assert.Empty(this.logger.WarningLog);
148+
149+
// The error location should be at the position of the invalid value
150+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 3, 61, true);
151+
}
152+
153+
/// <summary>
154+
/// Tests the error caused when a path attribute returns no result
155+
/// </summary>
156+
[Fact]
157+
public void RemoveNonExistantNode()
158+
{
159+
string transformString = @"{
160+
'@jdt.remove': {
161+
'@jdt.path': 'B'
162+
}
163+
}";
164+
165+
this.TryTransformTest(SimpleSourceString, transformString, true);
166+
167+
Assert.Empty(this.logger.MessageLog);
168+
Assert.Empty(this.logger.ErrorLog);
169+
170+
// The warning location should be at the position of the path value that yielded no results
171+
LogHasSingleEntry(this.logger.WarningLog, ErrorLocation.Transform.ToString(), 3, 59, false);
172+
}
173+
174+
/// <summary>
175+
/// Tests the error caused when attempting to remove the root node
176+
/// </summary>
177+
[Fact]
178+
public void RemoveRoot()
179+
{
180+
string transformString = @"{
181+
'@jdt.remove': true
182+
}";
183+
184+
this.TryTransformTest(SimpleSourceString, transformString, false);
185+
186+
Assert.Empty(this.logger.MessageLog);
187+
Assert.Empty(this.logger.WarningLog);
188+
189+
// The error location should be at the position of the remove value
190+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 60, true);
191+
}
192+
193+
/// <summary>
194+
/// Tests the error when a rename value is invalid
195+
/// </summary>
196+
[Fact]
197+
public void InvalidRenameValue()
198+
{
199+
string transformString = @"{
200+
'@jdt.rename': {
201+
'A': 10
202+
}
203+
}";
204+
205+
this.TryTransformTest(SimpleSourceString, transformString, false);
206+
207+
Assert.Empty(this.logger.MessageLog);
208+
Assert.Empty(this.logger.WarningLog);
209+
210+
// The error location should be at the position of the rename property
211+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 3, 47, true);
212+
}
213+
214+
/// <summary>
215+
/// Tests the error caused when attempting to rename a non-existant node
216+
/// </summary>
217+
[Fact]
218+
public void RenameNonExistantNode()
219+
{
220+
string transformString = @"{
221+
'@jdt.rename': {
222+
'B': 'Bstar'
223+
}
224+
}";
225+
226+
this.TryTransformTest(SimpleSourceString, transformString, true);
227+
228+
Assert.Empty(this.logger.MessageLog);
229+
Assert.Empty(this.logger.ErrorLog);
230+
231+
// The position of the warning should be a the beginning of the rename property
232+
LogHasSingleEntry(this.logger.WarningLog, ErrorLocation.Transform.ToString(), 3, 47, false);
233+
}
234+
235+
/// <summary>
236+
/// Test the error when attempting to replace the root with a non-object token
237+
/// </summary>
238+
[Fact]
239+
public void ReplaceRoot()
240+
{
241+
string transformString = @"{
242+
'@jdt.replace': 10
243+
}";
244+
245+
this.TryTransformTest(SimpleSourceString, transformString, false);
246+
247+
Assert.Empty(this.logger.MessageLog);
248+
Assert.Empty(this.logger.WarningLog);
249+
250+
// The position of the error should be at the value of replace that caused it
251+
LogHasSingleEntry(this.logger.ErrorLog, ErrorLocation.Transform.ToString(), 2, 59, true);
252+
}
253+
254+
/// <summary>
255+
/// Tests that an exception is thrown when <see cref="JsonTransformation.Apply(Stream)"/> is called
256+
/// </summary>
257+
[Fact]
258+
public void ThrowAndLogException()
259+
{
260+
string transformString = @"{
261+
'@jdt.invalid': false
262+
}";
263+
using (var transformStream = this.GetStreamFromString(transformString))
264+
using (var sourceStream = this.GetStreamFromString(SimpleSourceString))
265+
{
266+
JsonTransformation transform = new JsonTransformation(transformStream, this.logger);
267+
var exception = Record.Exception(() => transform.Apply(sourceStream));
268+
Assert.NotNull(exception);
269+
Assert.IsType<JdtException>(exception);
270+
var jdtException = exception as JdtException;
271+
Assert.Contains("invalid", jdtException.Message);
272+
Assert.Equal(ErrorLocation.Transform, jdtException.Location);
273+
Assert.Equal(2, jdtException.LineNumber);
274+
Assert.Equal(56, jdtException.LinePosition);
275+
}
276+
}
277+
278+
private static void LogHasSingleEntry(List<JsonTransformationTestLogger.TestLogEntry> log, string fileName, int lineNumber, int linePosition, bool fromException)
279+
{
280+
Assert.Single(log);
281+
var errorEntry = log.Single();
282+
Assert.Equal(fileName, errorEntry.FileName);
283+
Assert.Equal(lineNumber, errorEntry.LineNumber);
284+
Assert.Equal(linePosition, errorEntry.LinePosition);
285+
Assert.Equal(fromException, errorEntry.FromException);
286+
}
287+
288+
private void TryTransformTest(string sourceString, string transformString, bool shouldTransformSucceed)
289+
{
290+
using (var transformStream = this.GetStreamFromString(transformString))
291+
using (var sourceStream = this.GetStreamFromString(sourceString))
292+
{
293+
JsonTransformation transform = new JsonTransformation(transformStream, this.logger);
294+
Stream result = null;
295+
296+
var exception = Record.Exception(() => result = transform.Apply(sourceStream));
297+
298+
if (shouldTransformSucceed)
299+
{
300+
Assert.NotNull(result);
301+
Assert.Null(exception);
302+
}
303+
else
304+
{
305+
Assert.Null(result);
306+
Assert.NotNull(exception);
307+
Assert.IsType<JdtException>(exception);
308+
}
309+
}
310+
}
311+
312+
private Stream GetStreamFromString(string s)
313+
{
314+
MemoryStream stringStream = new MemoryStream();
315+
StreamWriter stringWriter = new StreamWriter(stringStream);
316+
stringWriter.Write(s);
317+
stringWriter.Flush();
318+
stringStream.Position = 0;
319+
320+
return stringStream;
321+
}
322+
}
323+
}

0 commit comments

Comments
 (0)