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."); }
public void ToStringOnEmptyNodeShouldReturnEmptyString() { // Arrange var target = new CharacterClassCharacterSetNode(); // Act var result = target.ToString(); // Assert result.ShouldBe(""); }
public void ToStringShouldReturnConcatenationOfChildNodesToString() { // Arrange var childNodes = new List <RegexNode> { new CharacterNode('a'), new CharacterNode('b'), new CharacterNode('c') }; var target = new CharacterClassCharacterSetNode(childNodes); // Act var result = target.ToString(); // Assert result.ShouldBe("abc"); }
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]"); }
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); }
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(); }
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); }
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]]"); }
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); }
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); }
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]"); }
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); }
/// <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); }