Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

268 lines
8.6 KiB
C#

// 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);
}
}
}