Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,267 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
using System.Web.Razor.Text;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Razor.Test.Text
{
public class BufferingTextReaderTest : LookaheadTextReaderTestBase
{
private const string TestString = "abcdefg";
private class DisposeTestMockTextReader : TextReader
{
public bool Disposed { get; set; }
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
Disposed = true;
}
}
protected override LookaheadTextReader CreateReader(string testString)
{
return new BufferingTextReader(new StringReader(testString));
}
[Fact]
public void ConstructorRequiresNonNullSourceReader()
{
Assert.ThrowsArgumentNull(() => new BufferingTextReader(null), "source");
}
[Fact]
public void PeekReturnsCurrentCharacterWithoutAdvancingPosition()
{
RunPeekTest("abc", peekAt: 2);
}
[Fact]
public void PeekReturnsNegativeOneAtEndOfSourceReader()
{
RunPeekTest("abc", peekAt: 3);
}
[Fact]
public void ReadReturnsCurrentCharacterAndAdvancesToNextCharacter()
{
RunReadTest("abc", readAt: 2);
}
[Fact]
public void EndingLookaheadReturnsReaderToPreviousLocation()
{
RunLookaheadTest("abcdefg", "abcb",
Read,
Lookahead(
Read,
Read),
Read);
}
[Fact]
public void MultipleLookaheadsCanBePerformed()
{
RunLookaheadTest("abcdefg", "abcbcdc",
Read,
Lookahead(
Read,
Read),
Read,
Lookahead(
Read,
Read),
Read);
}
[Fact]
public void LookaheadsCanBeNested()
{
RunLookaheadTest("abcdefg", "abcdefebc",
Read, // Appended: "a" Reader: "bcdefg"
Lookahead( // Reader: "bcdefg"
Read, // Appended: "b" Reader: "cdefg";
Read, // Appended: "c" Reader: "defg";
Read, // Appended: "d" Reader: "efg";
Lookahead( // Reader: "efg"
Read, // Appended: "e" Reader: "fg";
Read // Appended: "f" Reader: "g";
), // Reader: "efg"
Read // Appended: "e" Reader: "fg";
), // Reader: "bcdefg"
Read, // Appended: "b" Reader: "cdefg";
Read); // Appended: "c" Reader: "defg";
}
[Fact]
public void SourceLocationIsZeroWhenInitialized()
{
RunSourceLocationTest("abcdefg", SourceLocation.Zero, checkAt: 0);
}
[Fact]
public void CharacterAndAbsoluteIndicesIncreaseAsCharactersAreRead()
{
RunSourceLocationTest("abcdefg", new SourceLocation(4, 0, 4), checkAt: 4);
}
[Fact]
public void CharacterAndAbsoluteIndicesIncreaseAsSlashRInTwoCharacterNewlineIsRead()
{
RunSourceLocationTest("f\r\nb", new SourceLocation(2, 0, 2), checkAt: 2);
}
[Fact]
public void CharacterIndexResetsToZeroAndLineIndexIncrementsWhenSlashNInTwoCharacterNewlineIsRead()
{
RunSourceLocationTest("f\r\nb", new SourceLocation(3, 1, 0), checkAt: 3);
}
[Fact]
public void CharacterIndexResetsToZeroAndLineIndexIncrementsWhenSlashRInSingleCharacterNewlineIsRead()
{
RunSourceLocationTest("f\rb", new SourceLocation(2, 1, 0), checkAt: 2);
}
[Fact]
public void CharacterIndexResetsToZeroAndLineIndexIncrementsWhenSlashNInSingleCharacterNewlineIsRead()
{
RunSourceLocationTest("f\nb", new SourceLocation(2, 1, 0), checkAt: 2);
}
[Fact]
public void EndingLookaheadResetsRawCharacterAndLineIndexToValuesWhenLookaheadBegan()
{
RunEndLookaheadUpdatesSourceLocationTest();
}
[Fact]
public void OnceBufferingBeginsReadsCanContinuePastEndOfBuffer()
{
RunLookaheadTest("abcdefg", "abcbcdefg",
Read,
Lookahead(Read(2)),
Read(2),
ReadToEnd);
}
[Fact]
public void DisposeDisposesSourceReader()
{
RunDisposeTest(r => r.Dispose());
}
[Fact]
public void CloseDisposesSourceReader()
{
RunDisposeTest(r => r.Close());
}
[Fact]
public void ReadWithBufferSupportsLookahead()
{
RunBufferReadTest((reader, buffer, index, count) => reader.Read(buffer, index, count));
}
[Fact]
public void ReadBlockSupportsLookahead()
{
RunBufferReadTest((reader, buffer, index, count) => reader.ReadBlock(buffer, index, count));
}
[Fact]
public void ReadLineSupportsLookahead()
{
RunReadUntilTest(r => r.ReadLine(), expectedRaw: 8, expectedChar: 0, expectedLine: 2);
}
[Fact]
public void ReadToEndSupportsLookahead()
{
RunReadUntilTest(r => r.ReadToEnd(), expectedRaw: 11, expectedChar: 3, expectedLine: 2);
}
[Fact]
public void ReadLineMaintainsCorrectCharacterPosition()
{
RunSourceLocationTest("abc\r\ndef", new SourceLocation(5, 1, 0), r => r.ReadLine());
}
[Fact]
public void ReadToEndWorksAsInNormalTextReader()
{
RunReadToEndTest();
}
[Fact]
public void CancelBacktrackStopsNextEndLookaheadFromBacktracking()
{
RunLookaheadTest("abcdefg", "abcdefg",
Lookahead(
Read(2),
CancelBacktrack
),
ReadToEnd);
}
[Fact]
public void CancelBacktrackThrowsInvalidOperationExceptionIfCalledOutsideOfLookahead()
{
RunCancelBacktrackOutsideLookaheadTest();
}
[Fact]
public void CancelBacktrackOnlyCancelsBacktrackingForInnermostNestedLookahead()
{
RunLookaheadTest("abcdefg", "abcdabcdefg",
Lookahead(
Read(2),
Lookahead(
Read,
CancelBacktrack
),
Read
),
ReadToEnd);
}
[Fact]
public void BacktrackBufferIsClearedWhenEndReachedAndNoCurrentLookaheads()
{
// Arrange
StringReader source = new StringReader(TestString);
BufferingTextReader reader = new BufferingTextReader(source);
reader.Read(); // Reader: "bcdefg"
using (reader.BeginLookahead())
{
reader.Read(); // Reader: "cdefg"
} // Reader: "bcdefg"
reader.Read(); // Reader: "cdefg"
Assert.NotNull(reader.Buffer); // Verify our assumption that the buffer still exists
// Act
reader.Read();
// Assert
Assert.False(reader.Buffering, "The buffer was not reset when the end was reached");
Assert.Equal(0, reader.Buffer.Length);
}
private static void RunDisposeTest(Action<LookaheadTextReader> triggerAction)
{
// Arrange
DisposeTestMockTextReader source = new DisposeTestMockTextReader();
LookaheadTextReader reader = new BufferingTextReader(source);
// Act
triggerAction(reader);
// Assert
Assert.True(source.Disposed);
}
}
}

View File

@@ -0,0 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Text
{
public class LineTrackingStringBufferTest
{
[Fact]
public void CtorInitializesProperties()
{
LineTrackingStringBuffer buffer = new LineTrackingStringBuffer();
Assert.Equal(0, buffer.Length);
}
[Fact]
public void CharAtCorrectlyReturnsLocation()
{
LineTrackingStringBuffer buffer = new LineTrackingStringBuffer();
buffer.Append("foo\rbar\nbaz\r\nbiz");
LineTrackingStringBuffer.CharacterReference chr = buffer.CharAt(14);
Assert.Equal('i', chr.Character);
Assert.Equal(new SourceLocation(14, 3, 1), chr.Location);
}
}
}

View File

@@ -0,0 +1,254 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Text;
using System.Web.Razor.Resources;
using System.Web.Razor.Text;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Razor.Test.Text
{
public abstract class LookaheadTextReaderTestBase
{
protected abstract LookaheadTextReader CreateReader(string testString);
protected void RunPeekTest(string input, int peekAt = 0)
{
RunPeekOrReadTest(input, peekAt, false);
}
protected void RunReadTest(string input, int readAt = 0)
{
RunPeekOrReadTest(input, readAt, true);
}
protected void RunSourceLocationTest(string input, SourceLocation expected, int checkAt = 0)
{
RunSourceLocationTest(input, expected, r => AdvanceReader(checkAt, r));
}
protected void RunSourceLocationTest(string input, SourceLocation expected, Action<LookaheadTextReader> readerAction)
{
// Arrange
LookaheadTextReader reader = CreateReader(input);
readerAction(reader);
// Act
SourceLocation actual = reader.CurrentLocation;
// Assert
Assert.Equal(expected, actual);
}
protected void RunEndLookaheadUpdatesSourceLocationTest()
{
SourceLocation? expectedLocation = null;
SourceLocation? actualLocation = null;
RunLookaheadTest("abc\r\ndef\r\nghi", null,
Read(6),
CaptureSourceLocation(s => expectedLocation = s),
Lookahead(Read(6)),
CaptureSourceLocation(s => actualLocation = s));
// Assert
Assert.Equal(expectedLocation.Value.AbsoluteIndex, actualLocation.Value.AbsoluteIndex);
Assert.Equal(expectedLocation.Value.CharacterIndex, actualLocation.Value.CharacterIndex);
Assert.Equal(expectedLocation.Value.LineIndex, actualLocation.Value.LineIndex);
}
protected void RunReadToEndTest()
{
// Arrange
LookaheadTextReader reader = CreateReader("abcdefg");
// Act
string str = reader.ReadToEnd();
// Assert
Assert.Equal("abcdefg", str);
}
protected void RunCancelBacktrackOutsideLookaheadTest()
{
// Arrange
LookaheadTextReader reader = CreateReader("abcdefg");
// Act and Assert
Assert.Throws<InvalidOperationException>(() => reader.CancelBacktrack(), RazorResources.CancelBacktrack_Must_Be_Called_Within_Lookahead);
}
protected Action<StringBuilder, LookaheadTextReader> CaptureSourceLocation(Action<SourceLocation> capture)
{
return (_, reader) => { capture(reader.CurrentLocation); };
}
protected Action<StringBuilder, LookaheadTextReader> Read(int count)
{
return (builder, reader) =>
{
for (int i = 0; i < count; i++)
{
Read(builder, reader);
}
};
}
protected void Read(StringBuilder builder, LookaheadTextReader reader)
{
builder.Append((char)reader.Read());
}
protected void ReadToEnd(StringBuilder builder, LookaheadTextReader reader)
{
builder.Append(reader.ReadToEnd());
}
protected void CancelBacktrack(StringBuilder builder, LookaheadTextReader reader)
{
reader.CancelBacktrack();
}
protected Action<StringBuilder, LookaheadTextReader> Lookahead(params Action<StringBuilder, LookaheadTextReader>[] readerCommands)
{
return (builder, reader) =>
{
using (reader.BeginLookahead())
{
RunAll(readerCommands, builder, reader);
}
};
}
protected void RunLookaheadTest(string input, string expected, params Action<StringBuilder, LookaheadTextReader>[] readerCommands)
{
// Arrange
StringBuilder builder = new StringBuilder();
using (LookaheadTextReader reader = CreateReader(input))
{
RunAll(readerCommands, builder, reader);
}
if (expected != null)
{
Assert.Equal(expected, builder.ToString());
}
}
protected void RunReadUntilTest(Func<LookaheadTextReader, string> readMethod, int expectedRaw, int expectedChar, int expectedLine)
{
// Arrange
LookaheadTextReader reader = CreateReader("a\r\nbcd\r\nefg");
reader.Read(); // Reader: "\r\nbcd\r\nefg"
reader.Read(); // Reader: "\nbcd\r\nefg"
reader.Read(); // Reader: "bcd\r\nefg"
// Act
string read = null;
SourceLocation actualLocation;
using (reader.BeginLookahead())
{
read = readMethod(reader);
actualLocation = reader.CurrentLocation;
}
// Assert
Assert.Equal(3, reader.CurrentLocation.AbsoluteIndex);
Assert.Equal(0, reader.CurrentLocation.CharacterIndex);
Assert.Equal(1, reader.CurrentLocation.LineIndex);
Assert.Equal(expectedRaw, actualLocation.AbsoluteIndex);
Assert.Equal(expectedChar, actualLocation.CharacterIndex);
Assert.Equal(expectedLine, actualLocation.LineIndex);
Assert.Equal('b', reader.Peek());
Assert.Equal(read, readMethod(reader));
}
protected void RunBufferReadTest(Func<LookaheadTextReader, char[], int, int, int> readMethod)
{
// Arrange
LookaheadTextReader reader = CreateReader("abcdefg");
reader.Read(); // Reader: "bcdefg"
// Act
char[] buffer = new char[4];
int read = -1;
SourceLocation actualLocation;
using (reader.BeginLookahead())
{
read = readMethod(reader, buffer, 0, 4);
actualLocation = reader.CurrentLocation;
}
// Assert
Assert.Equal("bcde", new String(buffer));
Assert.Equal(4, read);
Assert.Equal(5, actualLocation.AbsoluteIndex);
Assert.Equal(5, actualLocation.CharacterIndex);
Assert.Equal(0, actualLocation.LineIndex);
Assert.Equal(1, reader.CurrentLocation.CharacterIndex);
Assert.Equal(0, reader.CurrentLocation.LineIndex);
Assert.Equal('b', reader.Peek());
}
private static void RunAll(Action<StringBuilder, LookaheadTextReader>[] readerCommands, StringBuilder builder, LookaheadTextReader reader)
{
foreach (Action<StringBuilder, LookaheadTextReader> readerCommand in readerCommands)
{
readerCommand(builder, reader);
}
}
private void RunPeekOrReadTest(string input, int offset, bool isRead)
{
using (LookaheadTextReader reader = CreateReader(input))
{
AdvanceReader(offset, reader);
// Act
int? actual = null;
if (isRead)
{
actual = reader.Read();
}
else
{
actual = reader.Peek();
}
Assert.NotNull(actual);
// Asserts
AssertReaderValueCorrect(actual.Value, input, offset, "Peek");
if (isRead)
{
AssertReaderValueCorrect(reader.Peek(), input, offset + 1, "Read");
}
else
{
Assert.Equal(actual, reader.Peek());
}
}
}
private static void AdvanceReader(int offset, LookaheadTextReader reader)
{
for (int i = 0; i < offset; i++)
{
reader.Read();
}
}
private void AssertReaderValueCorrect(int actual, string input, int expectedOffset, string methodName)
{
if (expectedOffset < input.Length)
{
Assert.Equal(input[expectedOffset], actual);
}
else
{
Assert.Equal(-1, actual);
}
}
}
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Text
{
public class SourceLocationTest
{
[Fact]
public void ConstructorWithLineAndCharacterIndexSetsAssociatedProperties()
{
// Act
SourceLocation loc = new SourceLocation(0, 42, 24);
// Assert
Assert.Equal(0, loc.AbsoluteIndex);
Assert.Equal(42, loc.LineIndex);
Assert.Equal(24, loc.CharacterIndex);
}
}
}

View File

@@ -0,0 +1,181 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Text;
using Xunit;
namespace System.Web.Razor.Test.Text
{
public class SourceLocationTrackerTest
{
private static readonly SourceLocation TestStartLocation = new SourceLocation(10, 42, 45);
[Fact]
public void ConstructorSetsCurrentLocationToZero()
{
Assert.Equal(SourceLocation.Zero, new SourceLocationTracker().CurrentLocation);
}
[Fact]
public void ConstructorWithSourceLocationSetsCurrentLocationToSpecifiedValue()
{
SourceLocation loc = new SourceLocation(10, 42, 4);
Assert.Equal(loc, new SourceLocationTracker(loc).CurrentLocation);
}
[Fact]
public void UpdateLocationAdvancesAbsoluteIndexOnNonNewlineCharacter()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('f', 'o');
// Assert
Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
}
[Fact]
public void UpdateLocationAdvancesCharacterIndexOnNonNewlineCharacter()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('f', 'o');
// Assert
Assert.Equal(46, tracker.CurrentLocation.CharacterIndex);
}
[Fact]
public void UpdateLocationDoesNotAdvanceLineIndexOnNonNewlineCharacter()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('f', 'o');
// Assert
Assert.Equal(42, tracker.CurrentLocation.LineIndex);
}
[Fact]
public void UpdateLocationAdvancesLineIndexOnSlashN()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\n', 'o');
// Assert
Assert.Equal(43, tracker.CurrentLocation.LineIndex);
}
[Fact]
public void UpdateLocationAdvancesAbsoluteIndexOnSlashN()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\n', 'o');
// Assert
Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
}
[Fact]
public void UpdateLocationResetsCharacterIndexOnSlashN()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\n', 'o');
// Assert
Assert.Equal(0, tracker.CurrentLocation.CharacterIndex);
}
[Fact]
public void UpdateLocationAdvancesLineIndexOnSlashRFollowedByNonNewlineCharacter()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\r', 'o');
// Assert
Assert.Equal(43, tracker.CurrentLocation.LineIndex);
}
[Fact]
public void UpdateLocationAdvancesAbsoluteIndexOnSlashRFollowedByNonNewlineCharacter()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\r', 'o');
// Assert
Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
}
[Fact]
public void UpdateLocationResetsCharacterIndexOnSlashRFollowedByNonNewlineCharacter()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\r', 'o');
// Assert
Assert.Equal(0, tracker.CurrentLocation.CharacterIndex);
}
[Fact]
public void UpdateLocationDoesNotAdvanceLineIndexOnSlashRFollowedBySlashN()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\r', '\n');
// Assert
Assert.Equal(42, tracker.CurrentLocation.LineIndex);
}
[Fact]
public void UpdateLocationAdvancesAbsoluteIndexOnSlashRFollowedBySlashN()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\r', '\n');
// Assert
Assert.Equal(11, tracker.CurrentLocation.AbsoluteIndex);
}
[Fact]
public void UpdateLocationAdvancesCharacterIndexOnSlashRFollowedBySlashN()
{
// Arrange
SourceLocationTracker tracker = new SourceLocationTracker(TestStartLocation);
// Act
tracker.UpdateLocation('\r', '\n');
// Assert
Assert.Equal(46, tracker.CurrentLocation.CharacterIndex);
}
}
}

View File

@@ -0,0 +1,231 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Text;
using System.Web.WebPages.TestUtils;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Razor.Test.Text
{
public class TextBufferReaderTest : LookaheadTextReaderTestBase
{
protected override LookaheadTextReader CreateReader(string testString)
{
return new TextBufferReader(new StringTextBuffer(testString));
}
[Fact]
public void ConstructorRequiresNonNullTextBuffer()
{
Assert.ThrowsArgumentNull(() => new TextBufferReader(null), "buffer");
}
[Fact]
public void PeekReturnsCurrentCharacterWithoutAdvancingPosition()
{
RunPeekTest("abc", peekAt: 2);
}
[Fact]
public void PeekReturnsNegativeOneAtEndOfSourceReader()
{
RunPeekTest("abc", peekAt: 3);
}
[Fact]
public void ReadReturnsCurrentCharacterAndAdvancesToNextCharacter()
{
RunReadTest("abc", readAt: 2);
}
[Fact]
public void EndingLookaheadReturnsReaderToPreviousLocation()
{
RunLookaheadTest("abcdefg", "abcb",
Read,
Lookahead(
Read,
Read),
Read);
}
[Fact]
public void MultipleLookaheadsCanBePerformed()
{
RunLookaheadTest("abcdefg", "abcbcdc",
Read,
Lookahead(
Read,
Read),
Read,
Lookahead(
Read,
Read),
Read);
}
[Fact]
public void LookaheadsCanBeNested()
{
RunLookaheadTest("abcdefg", "abcdefebc",
Read, // Appended: "a" Reader: "bcdefg"
Lookahead( // Reader: "bcdefg"
Read, // Appended: "b" Reader: "cdefg";
Read, // Appended: "c" Reader: "defg";
Read, // Appended: "d" Reader: "efg";
Lookahead( // Reader: "efg"
Read, // Appended: "e" Reader: "fg";
Read // Appended: "f" Reader: "g";
), // Reader: "efg"
Read // Appended: "e" Reader: "fg";
), // Reader: "bcdefg"
Read, // Appended: "b" Reader: "cdefg";
Read); // Appended: "c" Reader: "defg";
}
[Fact]
public void SourceLocationIsZeroWhenInitialized()
{
RunSourceLocationTest("abcdefg", SourceLocation.Zero, checkAt: 0);
}
[Fact]
public void CharacterAndAbsoluteIndicesIncreaseAsCharactersAreRead()
{
RunSourceLocationTest("abcdefg", new SourceLocation(4, 0, 4), checkAt: 4);
}
[Fact]
public void CharacterAndAbsoluteIndicesIncreaseAsSlashRInTwoCharacterNewlineIsRead()
{
RunSourceLocationTest("f\r\nb", new SourceLocation(2, 0, 2), checkAt: 2);
}
[Fact]
public void CharacterIndexResetsToZeroAndLineIndexIncrementsWhenSlashNInTwoCharacterNewlineIsRead()
{
RunSourceLocationTest("f\r\nb", new SourceLocation(3, 1, 0), checkAt: 3);
}
[Fact]
public void CharacterIndexResetsToZeroAndLineIndexIncrementsWhenSlashRInSingleCharacterNewlineIsRead()
{
RunSourceLocationTest("f\rb", new SourceLocation(2, 1, 0), checkAt: 2);
}
[Fact]
public void CharacterIndexResetsToZeroAndLineIndexIncrementsWhenSlashNInSingleCharacterNewlineIsRead()
{
RunSourceLocationTest("f\nb", new SourceLocation(2, 1, 0), checkAt: 2);
}
[Fact]
public void EndingLookaheadResetsRawCharacterAndLineIndexToValuesWhenLookaheadBegan()
{
RunEndLookaheadUpdatesSourceLocationTest();
}
[Fact]
public void OnceBufferingBeginsReadsCanContinuePastEndOfBuffer()
{
RunLookaheadTest("abcdefg", "abcbcdefg",
Read,
Lookahead(Read(2)),
Read(2),
ReadToEnd);
}
[Fact]
public void DisposeDisposesSourceReader()
{
RunDisposeTest(r => r.Dispose());
}
[Fact]
public void CloseDisposesSourceReader()
{
RunDisposeTest(r => r.Close());
}
[Fact]
public void ReadWithBufferSupportsLookahead()
{
RunBufferReadTest((reader, buffer, index, count) => reader.Read(buffer, index, count));
}
[Fact]
public void ReadBlockSupportsLookahead()
{
RunBufferReadTest((reader, buffer, index, count) => reader.ReadBlock(buffer, index, count));
}
[Fact]
public void ReadLineSupportsLookahead()
{
RunReadUntilTest(r => r.ReadLine(), expectedRaw: 8, expectedChar: 0, expectedLine: 2);
}
[Fact]
public void ReadToEndSupportsLookahead()
{
RunReadUntilTest(r => r.ReadToEnd(), expectedRaw: 11, expectedChar: 3, expectedLine: 2);
}
[Fact]
public void ReadLineMaintainsCorrectCharacterPosition()
{
RunSourceLocationTest("abc\r\ndef", new SourceLocation(5, 1, 0), r => r.ReadLine());
}
[Fact]
public void ReadToEndWorksAsInNormalTextReader()
{
RunReadToEndTest();
}
[Fact]
public void CancelBacktrackStopsNextEndLookaheadFromBacktracking()
{
RunLookaheadTest("abcdefg", "abcdefg",
Lookahead(
Read(2),
CancelBacktrack
),
ReadToEnd);
}
[Fact]
public void CancelBacktrackThrowsInvalidOperationExceptionIfCalledOutsideOfLookahead()
{
RunCancelBacktrackOutsideLookaheadTest();
}
[Fact]
public void CancelBacktrackOnlyCancelsBacktrackingForInnermostNestedLookahead()
{
RunLookaheadTest("abcdefg", "abcdabcdefg",
Lookahead(
Read(2),
Lookahead(
Read,
CancelBacktrack
),
Read
),
ReadToEnd);
}
private static void RunDisposeTest(Action<LookaheadTextReader> triggerAction)
{
// Arrange
StringTextBuffer source = new StringTextBuffer("abcdefg");
LookaheadTextReader reader = new TextBufferReader(source);
// Act
triggerAction(reader);
// Assert
Assert.True(source.Disposed);
}
}
}

View File

@@ -0,0 +1,251 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Web.Razor.Text;
using System.Web.WebPages.TestUtils;
using Moq;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Razor.Test.Text
{
public class TextChangeTest
{
[Fact]
public void ConstructorRequiresNonNegativeOldPosition()
{
Assert.ThrowsArgumentOutOfRange(() => new TextChange(-1, 0, new Mock<ITextBuffer>().Object, 0, 0, new Mock<ITextBuffer>().Object), "oldPosition", "Value must be greater than or equal to 0.");
}
[Fact]
public void ConstructorRequiresNonNegativeNewPosition()
{
Assert.ThrowsArgumentOutOfRange(() => new TextChange(0, 0, new Mock<ITextBuffer>().Object, -1, 0, new Mock<ITextBuffer>().Object), "newPosition", "Value must be greater than or equal to 0.");
}
[Fact]
public void ConstructorRequiresNonNegativeOldLength()
{
Assert.ThrowsArgumentOutOfRange(() => new TextChange(0, -1, new Mock<ITextBuffer>().Object, 0, 0, new Mock<ITextBuffer>().Object), "oldLength", "Value must be greater than or equal to 0.");
}
[Fact]
public void ConstructorRequiresNonNegativeNewLength()
{
Assert.ThrowsArgumentOutOfRange(() => new TextChange(0, 0, new Mock<ITextBuffer>().Object, 0, -1, new Mock<ITextBuffer>().Object), "newLength", "Value must be greater than or equal to 0.");
}
[Fact]
public void ConstructorRequiresNonNullOldBuffer()
{
Assert.ThrowsArgumentNull(() => new TextChange(0, 0, null, 0, 0, new Mock<ITextBuffer>().Object), "oldBuffer");
}
[Fact]
public void ConstructorRequiresNonNullNewBuffer()
{
Assert.ThrowsArgumentNull(() => new TextChange(0, 0, new Mock<ITextBuffer>().Object, 0, 0, null), "newBuffer");
}
[Fact]
public void ConstructorInitializesProperties()
{
// Act
ITextBuffer oldBuffer = new Mock<ITextBuffer>().Object;
ITextBuffer newBuffer = new Mock<ITextBuffer>().Object;
TextChange change = new TextChange(42, 24, oldBuffer, 1337, newBuffer);
// Assert
Assert.Equal(42, change.OldPosition);
Assert.Equal(24, change.OldLength);
Assert.Equal(1337, change.NewLength);
Assert.Same(newBuffer, change.NewBuffer);
Assert.Same(oldBuffer, change.OldBuffer);
}
[Fact]
public void TestIsDelete()
{
// Arrange
ITextBuffer oldBuffer = new Mock<ITextBuffer>().Object;
ITextBuffer newBuffer = new Mock<ITextBuffer>().Object;
TextChange change = new TextChange(0, 1, oldBuffer, 0, newBuffer);
// Assert
Assert.True(change.IsDelete);
}
[Fact]
public void TestIsInsert()
{
// Arrange
ITextBuffer oldBuffer = new Mock<ITextBuffer>().Object;
ITextBuffer newBuffer = new Mock<ITextBuffer>().Object;
TextChange change = new TextChange(0, 0, oldBuffer, 35, newBuffer);
// Assert
Assert.True(change.IsInsert);
}
[Fact]
public void TestIsReplace()
{
// Arrange
ITextBuffer oldBuffer = new Mock<ITextBuffer>().Object;
ITextBuffer newBuffer = new Mock<ITextBuffer>().Object;
TextChange change = new TextChange(0, 5, oldBuffer, 10, newBuffer);
// Assert
Assert.True(change.IsReplace);
}
[Fact]
public void OldTextReturnsOldSpanFromOldBuffer()
{
// Arrange
var newBuffer = new StringTextBuffer("test");
var oldBuffer = new StringTextBuffer("text");
var textChange = new TextChange(2, 1, oldBuffer, 1, newBuffer);
// Act
string text = textChange.OldText;
// Assert
Assert.Equal("x", text);
}
[Fact]
public void NewTextWithInsertReturnsChangedTextFromBuffer()
{
// Arrange
var newBuffer = new StringTextBuffer("test");
var oldBuffer = new StringTextBuffer("");
var textChange = new TextChange(0, 0, oldBuffer, 3, newBuffer);
// Act
string text = textChange.NewText;
// Assert
Assert.Equal("tes", text);
}
[Fact]
public void NewTextWithDeleteReturnsEmptyString()
{
// Arrange
var newBuffer = new StringTextBuffer("test");
var oldBuffer = new StringTextBuffer("");
var textChange = new TextChange(1, 1, oldBuffer, 0, newBuffer);
// Act
string text = textChange.NewText;
// Assert
Assert.Equal(String.Empty, text);
}
[Fact]
public void NewTextWithReplaceReturnsChangedTextFromBuffer()
{
// Arrange
var newBuffer = new StringTextBuffer("test");
var oldBuffer = new StringTextBuffer("");
var textChange = new TextChange(2, 2, oldBuffer, 1, newBuffer);
// Act
string text = textChange.NewText;
// Assert
Assert.Equal("s", text);
}
[Fact]
public void ApplyChangeWithInsertedTextReturnsNewContentWithChangeApplied()
{
// Arrange
var newBuffer = new StringTextBuffer("test");
var oldBuffer = new StringTextBuffer("");
var textChange = new TextChange(0, 0, oldBuffer, 3, newBuffer);
// Act
string text = textChange.ApplyChange("abcd", 0);
// Assert
Assert.Equal("tesabcd", text);
}
[Fact]
public void ApplyChangeWithRemovedTextReturnsNewContentWithChangeApplied()
{
// Arrange
var newBuffer = new StringTextBuffer("abcdefg");
var oldBuffer = new StringTextBuffer("");
var textChange = new TextChange(1, 1, oldBuffer, 0, newBuffer);
// Act
string text = textChange.ApplyChange("abcdefg", 1);
// Assert
Assert.Equal("bcdefg", text);
}
[Fact]
public void ApplyChangeWithReplacedTextReturnsNewContentWithChangeApplied()
{
// Arrange
var newBuffer = new StringTextBuffer("abcdefg");
var oldBuffer = new StringTextBuffer("");
var textChange = new TextChange(1, 1, oldBuffer, 2, newBuffer);
// Act
string text = textChange.ApplyChange("abcdefg", 1);
// Assert
Assert.Equal("bcbcdefg", text);
}
[Fact]
public void NormalizeFixesUpIntelliSenseStyleReplacements()
{
// Arrange
var newBuffer = new StringTextBuffer("Date.");
var oldBuffer = new StringTextBuffer("Date");
var original = new TextChange(0, 4, oldBuffer, 5, newBuffer);
// Act
TextChange normalized = original.Normalize();
// Assert
Assert.Equal(new TextChange(4, 0, oldBuffer, 1, newBuffer), normalized);
}
[Fact]
public void NormalizeDoesntAffectChangesWithoutCommonPrefixes()
{
// Arrange
var newBuffer = new StringTextBuffer("DateTime.");
var oldBuffer = new StringTextBuffer("Date.");
var original = new TextChange(0, 5, oldBuffer, 9, newBuffer);
// Act
TextChange normalized = original.Normalize();
// Assert
Assert.Equal(original, normalized);
}
[Fact]
public void NormalizeDoesntAffectShrinkingReplacements()
{
// Arrange
var newBuffer = new StringTextBuffer("D");
var oldBuffer = new StringTextBuffer("DateTime");
var original = new TextChange(0, 8, oldBuffer, 1, newBuffer);
// Act
TextChange normalized = original.Normalize();
// Assert
Assert.Equal(original, normalized);
}
}
}

View File

@@ -0,0 +1,186 @@
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
using System.Web.Razor.Parser;
using Xunit;
using Assert = Microsoft.TestCommon.AssertEx;
namespace System.Web.Razor.Test.Text
{
public class TextReaderExtensionsTest
{
[Fact]
public void ReadUntilWithCharThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(null, '@'), "reader");
}
[Fact]
public void ReadUntilInclusiveWithCharThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(null, '@', inclusive: true), "reader");
}
[Fact]
public void ReadUntilWithMultipleTerminatorsThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(null, '/', '>'), "reader");
}
[Fact]
public void ReadUntilInclusiveWithMultipleTerminatorsThrowsArgNullIfReaderNull()
{
// NOTE: Using named parameters would be difficult here, hence the inline comment
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(null, /* inclusive */ true, '/', '>'), "reader");
}
[Fact]
public void ReadUntilWithPredicateThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(null, c => true), "reader");
}
[Fact]
public void ReadUntilInclusiveWithPredicateThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(null, c => true, inclusive: true), "reader");
}
[Fact]
public void ReadUntilWithPredicateThrowsArgExceptionIfPredicateNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(new StringReader("Foo"), (Predicate<char>)null), "condition");
}
[Fact]
public void ReadUntilInclusiveWithPredicateThrowsArgExceptionIfPredicateNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadUntil(new StringReader("Foo"), (Predicate<char>)null, inclusive: true), "condition");
}
[Fact]
public void ReadWhileWithPredicateThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadWhile(null, c => true), "reader");
}
[Fact]
public void ReadWhileInclusiveWithPredicateThrowsArgNullIfReaderNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadWhile(null, c => true, inclusive: true), "reader");
}
[Fact]
public void ReadWhileWithPredicateThrowsArgNullIfPredicateNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadWhile(new StringReader("Foo"), (Predicate<char>)null), "condition");
}
[Fact]
public void ReadWhileInclusiveWithPredicateThrowsArgNullIfPredicateNull()
{
Assert.ThrowsArgumentNull(() => TextReaderExtensions.ReadWhile(new StringReader("Foo"), (Predicate<char>)null, inclusive: true), "condition");
}
[Fact]
public void ReadUntilWithCharReadsAllTextUpToSpecifiedCharacterButNotPast()
{
RunReaderTest("foo bar baz @biz", "foo bar baz ", '@', r => r.ReadUntil('@'));
}
[Fact]
public void ReadUntilWithCharWithInclusiveFlagReadsAllTextUpToSpecifiedCharacterButNotPastIfInclusiveFalse()
{
RunReaderTest("foo bar baz @biz", "foo bar baz ", '@', r => r.ReadUntil('@', inclusive: false));
}
[Fact]
public void ReadUntilWithCharWithInclusiveFlagReadsAllTextUpToAndIncludingSpecifiedCharacterIfInclusiveTrue()
{
RunReaderTest("foo bar baz @biz", "foo bar baz @", 'b', r => r.ReadUntil('@', inclusive: true));
}
[Fact]
public void ReadUntilWithCharReadsToEndIfSpecifiedCharacterNotFound()
{
RunReaderTest("foo bar baz", "foo bar baz", -1, r => r.ReadUntil('@'));
}
[Fact]
public void ReadUntilWithMultipleTerminatorsReadsUntilAnyTerminatorIsFound()
{
RunReaderTest("<bar/>", "<bar", '/', r => r.ReadUntil('/', '>'));
}
[Fact]
public void ReadUntilWithMultipleTerminatorsHonorsInclusiveFlagWhenFalse()
{
// NOTE: Using named parameters would be difficult here, hence the inline comment
RunReaderTest("<bar/>", "<bar", '/', r => r.ReadUntil( /* inclusive */ false, '/', '>'));
}
[Fact]
public void ReadUntilWithMultipleTerminatorsHonorsInclusiveFlagWhenTrue()
{
// NOTE: Using named parameters would be difficult here, hence the inline comment
RunReaderTest("<bar/>", "<bar/", '>', r => r.ReadUntil( /* inclusive */ true, '/', '>'));
}
[Fact]
public void ReadUntilWithPredicateStopsWhenPredicateIsTrue()
{
RunReaderTest("foo bar baz 0 zoop zork zoink", "foo bar baz ", '0', r => r.ReadUntil(c => Char.IsDigit(c)));
}
[Fact]
public void ReadUntilWithPredicateHonorsInclusiveFlagWhenFalse()
{
RunReaderTest("foo bar baz 0 zoop zork zoink", "foo bar baz ", '0', r => r.ReadUntil(c => Char.IsDigit(c), inclusive: false));
}
[Fact]
public void ReadUntilWithPredicateHonorsInclusiveFlagWhenTrue()
{
RunReaderTest("foo bar baz 0 zoop zork zoink", "foo bar baz 0", ' ', r => r.ReadUntil(c => Char.IsDigit(c), inclusive: true));
}
[Fact]
public void ReadWhileWithPredicateStopsWhenPredicateIsFalse()
{
RunReaderTest("012345a67890", "012345", 'a', r => r.ReadWhile(c => Char.IsDigit(c)));
}
[Fact]
public void ReadWhileWithPredicateHonorsInclusiveFlagWhenFalse()
{
RunReaderTest("012345a67890", "012345", 'a', r => r.ReadWhile(c => Char.IsDigit(c), inclusive: false));
}
[Fact]
public void ReadWhileWithPredicateHonorsInclusiveFlagWhenTrue()
{
RunReaderTest("012345a67890", "012345a", '6', r => r.ReadWhile(c => Char.IsDigit(c), inclusive: true));
}
private static void RunReaderTest(string testString, string expectedOutput, int expectedPeek, Func<TextReader, string> action)
{
// Arrange
StringReader reader = new StringReader(testString);
// Act
string read = action(reader);
// Assert
Assert.Equal(expectedOutput, read);
if (expectedPeek == -1)
{
Assert.True(reader.Peek() == -1, "Expected that the reader would be positioned at the end of the input stream");
}
else
{
Assert.Equal((char)expectedPeek, (char)reader.Peek());
}
}
}
}