a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
255 lines
8.5 KiB
C#
255 lines
8.5 KiB
C#
// 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);
|
|
}
|
|
}
|
|
}
|
|
}
|