예제 #1
0
        public void FourSpaceTabs()
        {
            Position position = new Position(new SourceContext("\t\tx"));
            Assert.AreEqual(1, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(5, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(9, position.Column);

            position = new Position(new SourceContext("\t   \t \tx"));
            Assert.AreEqual(1, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(5, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(6, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(7, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(8, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(9, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(10, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(13, position.Column);
        }
예제 #2
0
        public void UnixStyleNewlines()
        {
            Position position = new Position(new SourceContext("hello\nworld"));

            Assert.AreEqual(0, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(5);
            Assert.AreEqual(5, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(6, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(6, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(7, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(2, position.Column);

            position = new Position(new SourceContext("hello\nworld"));
            position = position.Advance(9);
            Assert.AreEqual(9, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(4, position.Column);
        }
예제 #3
0
        public void FourSpaceTabs()
        {
            Position position = new Position(new SourceContext("\t\tx"));

            Assert.AreEqual(1, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(5, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(9, position.Column);

            position = new Position(new SourceContext("\t   \t \tx"));
            Assert.AreEqual(1, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(5, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(6, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(7, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(8, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(9, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(10, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(13, position.Column);
        }
예제 #4
0
        private static string GetStartToCaret(string content, int position)
        {
            Position startPosition        = GetStartPosition(content, position);
            var      caretPosition        = startPosition.Advance(position - startPosition.Offset);
            var      attributeBeforeCaret = startPosition.Advance(startPosition.PotentialLength(Constants.SPACE) + 1).Constrain(caretPosition);
            var      startToCaret         = attributeBeforeCaret.Peek(attributeBeforeCaret.PotentialLength());

            return(startToCaret);
        }
예제 #5
0
        public void DefaultEndOfSourceCharacter()
        {
            var position = new Position(new SourceContext("hello world"));
            var pos2     = position.Advance(11);

            Assert.AreEqual(default(char), pos2.Peek());
        }
예제 #6
0
            public UseMasterGrammar()
            {
                ParseAction <IList <char> > whiteSpace0    = Rep(Ch(char.IsWhiteSpace));
                ParseAction <IList <char> > whiteSpace1    = Rep1(Ch(char.IsWhiteSpace));
                ParseAction <string>        startOfElement = Ch("<use");
                ParseAction <Chain <Chain <Chain <string, IList <char> >, char>, IList <char> > > startOfAttribute = Ch("master").And(whiteSpace0).And(Ch('=')).And(whiteSpace0);
                ParseAction <Chain <Chain <char, IList <char> >, char> > attrValue = Ch('\'').And(Rep(ChNot('\''))).And(Ch('\''))
                                                                                     .Or(Ch('\"').And(Rep(ChNot('\"'))).And(Ch('\"')));

                ParseAction <string> endOfElement = Ch("/>");

                ParseAction <string> useMaster = startOfElement
                                                 .And(whiteSpace1)
                                                 .And(startOfAttribute)
                                                 .And(attrValue)
                                                 .And(whiteSpace0)
                                                 .And(endOfElement)
                                                 .Build(hit => new string(hit.Left.Left.Down.Left.Down.ToArray()));

                ParseUseMaster =
                    pos =>
                {
                    for (Position scan = pos; scan.PotentialLength() != 0; scan = scan.Advance(1))
                    {
                        ParseResult <string> result = useMaster(scan);
                        if (result != null)
                        {
                            return(result);
                        }
                    }
                    return(null);
                };
            }
예제 #7
0
            public UseMasterGrammar(string prefix)
            {
                var whiteSpace0      = Rep(Ch(char.IsWhiteSpace));
                var whiteSpace1      = Rep1(Ch(char.IsWhiteSpace));
                var startOfElement   = !string.IsNullOrEmpty(prefix) ? Ch("<" + prefix + ":use") : Ch("<use");
                var startOfAttribute = Ch("master").And(whiteSpace0).And(Ch('=')).And(whiteSpace0);
                var attrValue        = Ch('\'').And(Rep(ChNot('\''))).And(Ch('\''))
                                       .Or(Ch('\"').And(Rep(ChNot('\"'))).And(Ch('\"')));

                var endOfElement = Ch("/>");

                var useMaster = startOfElement
                                .And(whiteSpace1)
                                .And(startOfAttribute)
                                .And(attrValue)
                                .And(whiteSpace0)
                                .And(endOfElement)
                                .Build(hit => new string(hit.Left.Left.Down.Left.Down.ToArray()));

                ParseUseMaster =
                    pos =>
                {
                    for (Position scan = pos; scan.PotentialLength() != 0; scan = scan.Advance(1))
                    {
                        ParseResult <string> result = useMaster(scan);
                        if (result != null)
                        {
                            return(result);
                        }
                    }
                    return(null);
                };
            }
예제 #8
0
 public void NewLeafException2()
 {
     var pos  = new Position("foo");
     var node = new ParseNode(
         dot,
         pos.Advance(),
         pos);
 }
예제 #9
0
        public void PotentialLengths()
        {
            Position position = new Position(new SourceContext("hello world"));

            Assert.AreEqual(11, position.PotentialLength());
            Assert.AreEqual(6, position.PotentialLength('w'));
            Assert.AreEqual(2, position.PotentialLength('l'));
            Assert.AreEqual(0, position.PotentialLength('h'));
            position = position.Advance(4);
            Assert.AreEqual(7, position.PotentialLength());
            Assert.AreEqual(2, position.PotentialLength('w'));
            Assert.AreEqual(5, position.PotentialLength('l'));
            Assert.AreEqual(0, position.PotentialLength('o'));
            position = position.Advance(7);
            Assert.AreEqual(0, position.PotentialLength());
            Assert.AreEqual(0, position.PotentialLength('w'));
            Assert.AreEqual(0, position.PotentialLength('l'));
        }
예제 #10
0
        public void PeekReturnsText()
        {
            Position position = new Position(new SourceContext("hello\r\nworld"));

            Assert.AreEqual("hello", position.Peek(5));
            position = position.Advance(7);
            Assert.AreEqual("w", position.Peek(1));
            Assert.AreEqual("world", position.Peek(5));
            Assert.AreEqual('w', position.Peek());
        }
        protected void ThrowParseException(string viewPath, Position position, Position rest)
        {
            string str   = string.Format("Unable to parse view {0} around line {1} column {2}", viewPath, rest.Line, rest.Column);
            int    count = Math.Min(30, rest.Offset);
            int    num2  = Math.Min(30, rest.PotentialLength());
            string str2  = position.Advance(rest.Offset - count).Peek(count);
            string str3  = rest.Peek(num2);

            throw new CompilerException(str + Environment.NewLine + str2 + "[error:]" + str3);
        }
예제 #12
0
 public void AdvanceChangesColumnOffset()
 {
     Position position = new Position(new SourceContext("hello world"));
     Assert.AreEqual(0, position.Offset);
     Assert.AreEqual(1, position.Line);
     Assert.AreEqual(1, position.Column);
     position = position.Advance(5);
     Assert.AreEqual(5, position.Offset);
     Assert.AreEqual(1, position.Line);
     Assert.AreEqual(6, position.Column);
 }
예제 #13
0
        private Snippets AsCode(AttributeNode attr)
        {
            Position begin = this.Locate(attr.Nodes.FirstOrDefault <Node>());
            Position end   = this.LocateEnd(attr.Nodes.LastOrDefault <Node>());

            if ((begin == null) || (end == null))
            {
                begin = new Position(new SourceContext(attr.Value));
                end   = begin.Advance(begin.PotentialLength());
            }
            return(base.Context.SyntaxProvider.ParseFragment(begin, end));
        }
예제 #14
0
        protected void ThrowParseException(string viewPath, Position position, Position rest)
        {
            string message = string.Format("Unable to parse view {0} around line {1} column {2}", viewPath,
                                           rest.Line, rest.Column);

            int beforeLength = Math.Min(30, rest.Offset);
            int afterLength = Math.Min(30, rest.PotentialLength());
            string before = position.Advance(rest.Offset - beforeLength).Peek(beforeLength);
            string after = rest.Peek(afterLength);

            throw new CompilerException(message + Environment.NewLine + before + "[error:]" + after);
        }
예제 #15
0
        public void AdvanceChangesColumnOffset()
        {
            Position position = new Position(new SourceContext("hello world"));

            Assert.AreEqual(0, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(5);
            Assert.AreEqual(5, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(6, position.Column);
        }
예제 #16
0
        protected void ThrowParseException(string viewPath, Position position, Position rest)
        {
            string message = string.Format("Unable to parse view {0} around line {1} column {2}", viewPath,
                                           rest.Line, rest.Column);

            int    beforeLength = Math.Min(30, rest.Offset);
            int    afterLength  = Math.Min(30, rest.PotentialLength());
            string before       = position.Advance(rest.Offset - beforeLength).Peek(beforeLength);
            string after        = rest.Peek(afterLength);

            throw new CompilerException(message + Environment.NewLine + before + "[error:]" + after);
        }
예제 #17
0
        Snippets AsCode(AttributeNode attr)
        {
            var begin = Locate(attr.Nodes.FirstOrDefault());
            var end   = LocateEnd(attr.Nodes.LastOrDefault());

            if (begin == null || end == null)
            {
                begin = new Position(new SourceContext(attr.Value));
                end   = begin.Advance(begin.PotentialLength());
            }
            return(Context.SyntaxProvider.ParseFragment(begin, end));
        }
예제 #18
0
        public void PotentialLengthConstrained()
        {
            Position position = new Position(new SourceContext("hello world"));
            var      begin    = position.Advance(4);
            var      end      = begin.Advance(3);
            var      range    = begin.Constrain(end);

            Assert.AreEqual(3, range.PotentialLength());
            Assert.AreEqual("o w", range.Peek(3));
            var done = range.Advance(3);

            Assert.AreEqual(default(char), done.Peek());
        }
예제 #19
0
        public void NewLeaf()
        {
            var str     = "string";
            var pos     = new Position(str);
            var nextPos = pos.Advance().Advance();

            var node = new ParseNode(dot, pos, nextPos);

            Assert.AreEqual(0, node.Children.Count);
            Assert.AreEqual(2, node.Length);
            Assert.AreEqual(pos, node.Position);
            Assert.AreEqual(nextPos, node.NextPosition);
            Assert.AreEqual("st", node.Value);
        }
예제 #20
0
 public Token(TokenType type, dynamic value = null, Position pos_start = null, Position pos_end = null)
 {
     Type  = type;
     Value = value;
     if (pos_start != null)
     {
         Pos_Start = pos_start.Copy();
         Pos_End   = pos_start.Copy();
         Pos_End.Advance();
     }
     if (pos_end != null)
     {
         Pos_End = pos_end.Copy();
     }
 }
예제 #21
0
        public void PotentialLengthMultiChar()
        {
            Position position = new Position(new SourceContext("hello world"));

            Assert.AreEqual(11, position.PotentialLength());
            Assert.AreEqual(0, position.PotentialLength('h', 'w', 'l'));
            Assert.AreEqual(0, position.PotentialLength('l', 'w', 'h'));
            Assert.AreEqual(11, position.PotentialLength('i', 'f'));
            Assert.AreEqual(4, position.PotentialLength('b', 'o', 'o'));
            position = position.Advance(2);
            Assert.AreEqual(0, position.PotentialLength('h', 'w', 'l'));
            Assert.AreEqual(0, position.PotentialLength('l', 'w', 'h'));
            Assert.AreEqual(9, position.PotentialLength('i', 'f'));
            Assert.AreEqual(2, position.PotentialLength('b', 'o', 'o'));
        }
예제 #22
0
        public void NewlineChangesLine()
        {
            Position position = new Position(new SourceContext("hello\r\nworld"));

            Assert.AreEqual(0, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(5);
            Assert.AreEqual(5, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(6, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(6, position.Offset);
            position = position.Advance(1);
            Assert.AreEqual(7, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(1, position.Column);

            position = new Position(new SourceContext("hello\r\nworld"));
            position = position.Advance(9);
            Assert.AreEqual(9, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(3, position.Column);
        }
예제 #23
0
        public void NewBranch1()
        {
            var str  = "string";
            var pos1 = new Position(str);
            var pos2 = pos1.Advance();
            var pos3 = pos2.Advance().Advance();

            var ch1 = new ParseNode(dot, pos1, pos2);
            var ch2 = new ParseNode(dot, pos2, pos3);

            var node = new ParseNode(dot, ch1, ch2);

            Assert.AreEqual(2, node.Children.Count);
            Assert.AreEqual(ch1, node.Children[0]);
            Assert.AreEqual(ch2, node.Children[1]);
            Assert.AreEqual(3, node.Length);
            Assert.AreEqual(pos1, node.Position);
            Assert.AreEqual(pos3, node.NextPosition);
            Assert.AreEqual(null, node.Value);
        }
예제 #24
0
        public void PeekTestChecksNextCharacters()
        {
            var position = new Position(new SourceContext("hello world"));

            Assert.That(position.PeekTest("hello"), Is.True);
            Assert.That(position.PeekTest("hello world"), Is.True);
            Assert.That(position.PeekTest("hello world!"), Is.False);
            Assert.That(position.PeekTest("Hello"), Is.False);
            Assert.That(position.PeekTest(""), Is.True);
            var more = position.Advance(4);

            Assert.That(more.PeekTest("hello"), Is.False);
            Assert.That(more.PeekTest("o"), Is.True);
            Assert.That(more.PeekTest("o world"), Is.True);
            Assert.That(more.PeekTest("o world!"), Is.False);
            var tail = more.Advance(7);

            Assert.That(tail.PeekTest(""), Is.True);
            Assert.That(tail.PeekTest("d"), Is.False);
        }
예제 #25
0
        public void Advance()
        {
            var empty = new Position(string.Empty).Advance();

            Assert.AreEqual(string.Empty, empty.String);
            Assert.AreEqual(0, empty.Index);
            Assert.AreEqual(1, empty.Line);
            Assert.AreEqual(1, empty.Column);
            Assert.IsTrue(empty.EOF);

            var str = "a\rb\nc\r\nd";
            var p   = new Position(str);

            Assert.AreEqual(0, p.Index);
            Assert.AreEqual(1, p.Line);
            Assert.AreEqual(1, p.Column);
            Assert.AreEqual('a', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(1, p.Index);
            Assert.AreEqual(1, p.Line);
            Assert.AreEqual(2, p.Column);
            Assert.AreEqual('\r', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(2, p.Index);
            Assert.AreEqual(2, p.Line);
            Assert.AreEqual(1, p.Column);
            Assert.AreEqual('b', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(3, p.Index);
            Assert.AreEqual(2, p.Line);
            Assert.AreEqual(2, p.Column);
            Assert.AreEqual('\n', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(4, p.Index);
            Assert.AreEqual(3, p.Line);
            Assert.AreEqual(1, p.Column);
            Assert.AreEqual('c', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(5, p.Index);
            Assert.AreEqual(3, p.Line);
            Assert.AreEqual(2, p.Column);
            Assert.AreEqual('\r', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(6, p.Index);
            Assert.AreEqual(3, p.Line);
            Assert.AreEqual(3, p.Column);
            Assert.AreEqual('\n', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(7, p.Index);
            Assert.AreEqual(4, p.Line);
            Assert.AreEqual(1, p.Column);
            Assert.AreEqual('d', p.String[p.Index]);
            Assert.IsFalse(p.EOF);
            p = p.Advance();

            Assert.AreEqual(8, p.Index);
            Assert.AreEqual(4, p.Line);
            Assert.AreEqual(2, p.Column);
            Assert.IsTrue(p.EOF);
            p = p.Advance();

            Assert.AreEqual(8, p.Index);
            Assert.AreEqual(4, p.Line);
            Assert.AreEqual(2, p.Column);
            Assert.IsTrue(p.EOF);
        }
예제 #26
0
        Snippets AsCode(AttributeNode attr)
        {
            var begin = Locate(attr.Nodes.FirstOrDefault());
            var end = LocateEnd(attr.Nodes.LastOrDefault());
            if (begin == null || end == null)
            {
                begin = new Position(new SourceContext(attr.Value));
                end = begin.Advance(begin.PotentialLength());
            }

            return Context.SyntaxProvider.ParseFragment(begin, end);
        }
예제 #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Range"/> struct.
 /// </summary>
 /// <param name="start">The first <see cref="Position"/> that's inside this range.</param>
 /// <param name="length">The length of this range.</param>
 public Range(Position start, int length)
     : this(start, start.Advance(length))
 {
 }
예제 #28
0
        public void NewlineChangesLine()
        {
            Position position = new Position(new SourceContext("hello\r\nworld"));
            Assert.AreEqual(0, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(5);
            Assert.AreEqual(5, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(6, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(6, position.Offset);
            position = position.Advance(1);
            Assert.AreEqual(7, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(1, position.Column);

            position = new Position(new SourceContext("hello\r\nworld"));
            position = position.Advance(9);
            Assert.AreEqual(9, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(3, position.Column);
        }
예제 #29
0
 public void PeekReturnsText()
 {
     Position position = new Position(new SourceContext("hello\r\nworld"));
     Assert.AreEqual("hello", position.Peek(5));
     position = position.Advance(7);
     Assert.AreEqual("w", position.Peek(1));
     Assert.AreEqual("world", position.Peek(5));
     Assert.AreEqual('w', position.Peek());
 }
예제 #30
0
 public void DefaultEndOfSourceCharacter()
 {
     var position = new Position(new SourceContext("hello world"));
     var pos2 = position.Advance(11);
     Assert.AreEqual(default(char), pos2.Peek());
 }
예제 #31
0
        public void UnixStyleNewlines()
        {
            Position position = new Position(new SourceContext("hello\nworld"));
            Assert.AreEqual(0, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(5);
            Assert.AreEqual(5, position.Offset);
            Assert.AreEqual(1, position.Line);
            Assert.AreEqual(6, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(6, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(1, position.Column);
            position = position.Advance(1);
            Assert.AreEqual(7, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(2, position.Column);

            position = new Position(new SourceContext("hello\nworld"));
            position = position.Advance(9);
            Assert.AreEqual(9, position.Offset);
            Assert.AreEqual(2, position.Line);
            Assert.AreEqual(4, position.Column);
        }
예제 #32
0
 public void PotentialLengths()
 {
     Position position = new Position(new SourceContext("hello world"));
     Assert.AreEqual(11, position.PotentialLength());
     Assert.AreEqual(6, position.PotentialLength('w'));
     Assert.AreEqual(2, position.PotentialLength('l'));
     Assert.AreEqual(0, position.PotentialLength('h'));
     position = position.Advance(4);
     Assert.AreEqual(7, position.PotentialLength());
     Assert.AreEqual(2, position.PotentialLength('w'));
     Assert.AreEqual(5, position.PotentialLength('l'));
     Assert.AreEqual(0, position.PotentialLength('o'));
     position = position.Advance(7);
     Assert.AreEqual(0, position.PotentialLength());
     Assert.AreEqual(0, position.PotentialLength('w'));
     Assert.AreEqual(0, position.PotentialLength('l'));
 }
예제 #33
0
 public void PotentialLengthMultiChar()
 {
     Position position = new Position(new SourceContext("hello world"));
     Assert.AreEqual(11, position.PotentialLength());
     Assert.AreEqual(0, position.PotentialLength('h', 'w', 'l'));
     Assert.AreEqual(0, position.PotentialLength('l', 'w', 'h'));
     Assert.AreEqual(11, position.PotentialLength('i', 'f'));
     Assert.AreEqual(4, position.PotentialLength('b', 'o', 'o'));
     position = position.Advance(2);
     Assert.AreEqual(0, position.PotentialLength('h', 'w', 'l'));
     Assert.AreEqual(0, position.PotentialLength('l', 'w', 'h'));
     Assert.AreEqual(9, position.PotentialLength('i', 'f'));
     Assert.AreEqual(2, position.PotentialLength('b', 'o', 'o'));
 }
예제 #34
0
 public void PotentialLengthConstrained()
 {
     Position position = new Position(new SourceContext("hello world"));
     var begin = position.Advance(4);
     var end = begin.Advance(3);
     var range = begin.Constrain(end);
     Assert.AreEqual(3, range.PotentialLength());
     Assert.AreEqual("o w", range.Peek(3));
     var done = range.Advance(3);
     Assert.AreEqual(default(char), done.Peek());
 }
예제 #35
0
 public void PeekTestChecksNextCharacters()
 {
     var position = new Position(new SourceContext("hello world"));
     Assert.That(position.PeekTest("hello"), Is.True);
     Assert.That(position.PeekTest("hello world"), Is.True);
     Assert.That(position.PeekTest("hello world!"), Is.False);
     Assert.That(position.PeekTest("Hello"), Is.False);
     Assert.That(position.PeekTest(""), Is.True);
     var more = position.Advance(4);
     Assert.That(more.PeekTest("hello"), Is.False);
     Assert.That(more.PeekTest("o"), Is.True);
     Assert.That(more.PeekTest("o world"), Is.True);
     Assert.That(more.PeekTest("o world!"), Is.False);
     var tail = more.Advance(7);
     Assert.That(tail.PeekTest(""), Is.True);
     Assert.That(tail.PeekTest("d"), Is.False);
 }