コード例 #1
0
        public void ShouldUnnegateNegatedCharacterClass()
        {
            // Arrange
            var characters = new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            };
            var characterSet            = new CharacterClassCharacterSetNode(characters);
            var subtractionCharacterSet = new CharacterClassCharacterSetNode(new CharacterNode('a'));
            var subtraction             = new CharacterClassNode(subtractionCharacterSet, false);
            var characterClass          = new CharacterClassNode(characterSet, subtraction, true);
            var childNodes = new List <RegexNode> {
                new CharacterNode('x'), characterClass, new CharacterNode('y')
            };
            var root   = new ConcatenationNode(childNodes);
            var target = new CharacterClassNegationMutator();

            // Act
            var result = target.ApplyMutations(characterClass, root);

            // Assert
            var mutation = result.ShouldHaveSingleItem();

            mutation.OriginalNode.ShouldBe(characterClass);
            mutation.ReplacementNode.ToString().ShouldBe("[abc-[a]]");
            mutation.ReplacementPattern.ShouldBe("x[abc-[a]]y");
            mutation.DisplayName.ShouldBe("Regex character class negation mutation");
            mutation.Description.ShouldBe("Character class \"[^abc-[a]]\" was replaced with \"[abc-[a]]\" at offset 1.");
        }
コード例 #2
0
        public void ToStringOnNegatedCharacterClassNodeWithCharacterSetShouldReturnCharactersBetweenBrackets()
        {
            // Arrange
            var characterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, true);

            // Act
            var result = target.ToString();

            // Assert
            result.ShouldBe("[^abc]");
        }
コード例 #3
0
        public void CharacterSetShouldReturnOriginalCharacterSet()
        {
            // Arrange
            var characterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, false);

            // Act
            var result = target.CharacterSet;

            // Assert
            result.ShouldBe(characterSet);
        }
コード例 #4
0
        public void SubtractionShouldReturnNullIfNoSubtraction()
        {
            // Arrange
            var characterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, false);

            // Act
            var result = target.Subtraction;

            // Assert
            result.ShouldBeNull();
        }
コード例 #5
0
        public void CharacterSetSpanShouldStartAt2IfNegatedIsTrue()
        {
            // Arrange
            var characterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });

            _ = new CharacterClassNode(characterSet, true);

            // Act
            var(Start, _) = characterSet.GetSpan();

            // Assert
            Start.ShouldBe(2);
        }
コード例 #6
0
        public void ToStringOnCharacterClassNodeWithSubtractionSubtractionBetweenBrackets()
        {
            // Arrange
            var subtractionCharacterSet = new CharacterClassCharacterSetNode(new CharacterNode('a'));
            var subtraction             = new CharacterClassNode(subtractionCharacterSet, false);
            var characterSet            = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, subtraction, false);

            // Act
            var result = target.ToString();

            // Assert
            result.ShouldBe("[abc-[a]]");
        }
コード例 #7
0
        public void SubtractionShouldReturnOriginalSubtraction()
        {
            // Arrange
            var subtractionCharacterSet = new CharacterClassCharacterSetNode(new CharacterNode('a'));
            var subtraction             = new CharacterClassNode(subtractionCharacterSet, false);
            var characterSet            = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, subtraction, false);

            // Act
            var result = target.Subtraction;

            // Assert
            result.ShouldBe(subtraction);
        }
コード例 #8
0
        public void SubtractionSpanShouldStartAfterCharacterSetAndDash()
        {
            // Arrange
            var subtractionCharacterSet = new CharacterClassCharacterSetNode(new CharacterNode('a'));
            var subtraction             = new CharacterClassNode(subtractionCharacterSet, false);
            var characterSet            = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });

            _ = new CharacterClassNode(characterSet, subtraction, false);

            // Act
            var(Start, _) = subtraction.GetSpan();

            // Assert
            Start.ShouldBe(5);
        }
コード例 #9
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        /// <summary>
        /// Parse a character class subtraction inside a character class.
        /// Throws an exception if the outer character class is not closed with a closing ']' or if the subtraction is not the last element in the outer character class.
        /// </summary>
        /// <returns></returns>
        private CharacterClassNode ParseCharacterClassSubtraction()
        {
            CharacterClassNode subtraction = ParseCharacterClass();

            // No closing ']' for outer character class.
            if (CharsRight() == 0)
            {
                throw MakeException(RegexParseError.UnterminatedCharacterClass);
            }

            // Subtraction must be the last element in a character class.
            if (RightChar() != ']')
            {
                throw MakeException(RegexParseError.SubtractionMustBeLast);
            }

            return(subtraction);
        }
コード例 #10
0
        public void ToStringOnCharacterClassNodeWithPrefixShouldReturnPrefixBeforeCharacterClass()
        {
            // Arrange
            var comment      = new CommentGroupNode("This is a comment.");
            var characterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, false)
            {
                Prefix = comment
            };

            // Act
            var result = target.ToString();

            // Assert
            result.ShouldBe("(?#This is a comment.)[abc]");
        }
コード例 #11
0
        public void CopyingCharacterClassNodeShouldCopyNegation()
        {
            // Arrange
            var characterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c')
            });
            var replacementCharacterSet = new CharacterClassCharacterSetNode(new List <RegexNode> {
                new CharacterNode('b'), new CharacterNode('c')
            });
            var target = new CharacterClassNode(characterSet, true);

            // Act
            // ReplaceNode returns a copy of the current node.
            var result = target.ReplaceNode(characterSet, replacementCharacterSet);

            // Assert
            CharacterClassNode characterClassNode = result.ShouldBeOfType <CharacterClassNode>();

            characterClassNode.Negated.ShouldBe(target.Negated);
        }
コード例 #12
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        /// <summary>
        /// Parse characters following a dash '-' in a character class [...]. It could be part of a character range x-y or character class subtraction -[...]
        /// </summary>
        /// <param name="characterSet">The set of characters already in the characterclass.</param>
        /// <param name="previousNode">The character class element left of the dash '-'.</param>
        /// <param name="subtraction">A character class will be saved here if the dash '-' is part of a character class subtraction.</param>
        /// <returns></returns>
        private RegexNode ParseCharacterClassDash(List <RegexNode> characterSet, RegexNode previousNode, ref CharacterClassNode subtraction)
        {
            // '-' at the and of a character class is a literal character.
            if (RightChar() == ']')
            {
                characterSet.Add(previousNode);
                return(new CharacterNode('-'));
            }

            // Subtraction [...-[...]]
            else if (RightChar() == '[')
            {
                MoveRight();
                subtraction = ParseCharacterClassSubtraction();
                return(previousNode);
            }

            // Could be range.
            else
            {
                // '-' after character class shorthand, unicode category/block or range is a literal character.
                if (previousNode is CharacterClassShorthandNode || previousNode is UnicodeCategoryNode || previousNode is CharacterClassRangeNode)
                {
                    characterSet.Add(previousNode);
                    return(new CharacterNode('-'));
                }

                // Range.
                else
                {
                    return(ParseCharacterRange(previousNode));
                }
            }
        }
コード例 #13
0
ファイル: Parser.cs プロジェクト: PimRheiter/regex-parser
        /// <summary>
        /// Parse a character class [...] in response to an opening '['.
        /// </summary>
        private CharacterClassNode ParseCharacterClass()
        {
            if (CharsRight() == 0)
            {
                throw MakeException(RegexParseError.UnterminatedCharacterClass);
            }

            char               ch;
            RegexNode          previousNode;
            CharacterClassNode subtraction = null;
            var negated      = false;
            var characterSet = new List <RegexNode>();

            if (RightChar() == '^')
            {
                MoveRight();
                negated = true;
            }

            previousNode = FirstCharacterClassElement();

            while (CharsRight() > 1 && (ch = RightChar()) != ']')
            {
                MoveRight();

                switch (ch)
                {
                // Could be range or subtraction.
                case '-':
                    previousNode = ParseCharacterClassDash(characterSet, previousNode, ref subtraction);
                    break;

                // Escape character, shorthand or unicode category.
                case '\\':
                    characterSet.Add(previousNode);
                    previousNode = ParseBasicBackslash();
                    break;

                // Literal character
                default:
                    characterSet.Add(previousNode);
                    previousNode = new CharacterNode(ch);
                    break;
                }
            }

            characterSet.Add(previousNode);

            if (RightChar() == ']')
            {
                MoveRight();
                var characterSetNode = new CharacterClassCharacterSetNode(characterSet);

                if (subtraction == null)
                {
                    return(new CharacterClassNode(characterSetNode, negated));
                }

                return(new CharacterClassNode(characterSetNode, subtraction, negated));
            }

            // No closing ']'.
            throw MakeException(RegexParseError.UnterminatedCharacterClass);
        }