The following page summarizes the results for the manual inspection of
mutants. First the results for the twelve mutants that violated the most
invariants and are not detected by the original test suite are shown, and then
the results for twelve randomly chosen mutants that do not violate
invariants and are not detected by the test suite.
Every mutation is described as follows:
- First a table gives the location, the type of the mutation and whether it was considered non-equivalent
- Then the source code context of the mutation is given. The line that is mutated is shown in bold.
- After that a source code statement that corresponds to the mutation is shown. Although the mutations are applied to bytecode directly, the mutated statements are given in Java source code, if possible. (Not all mutations that are legal bytecode can be expressed in Java source code)
- Finally, if possible, we give a unit test that detects the mutation.
Invariant Violating Mutants
Results for the twelve mutants that violated the most invariants and are not detected by the original test suite.Mutation 1
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.Context | 102 | RIC_MINUS_1 | true |
Source Code Context
public Context(ContextSupport contextSupport)
{
this.contextSupport = contextSupport;
this.nodeSet = Collections.EMPTY_LIST;
this.size = 0;
this.position = 0;
}
Mutated Statement
Unit Test for Mutation
Context c = new Context(new ContextSupport());
assertEquals(0, c.getPosition());
}
Mutation 2
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 618 | RIC_ZERO | true |
Source Code Context
Token token = new Token(TokenTypes.PLUS,
getXPath(),
currentPosition(),
currentPosition()+1 );
consume();
return token;
}
Mutated Statement
Unit Test for Mutation
try {
XPathReader xp = new XPathReader();
xp.parse("+");
fail("Expect exception");
} catch (SAXPathException e) {
// Expect this exception
assertEquals("Unexpected '+'", e.getMessage());
} catch (Exception e) {
fail("Did not expect this exception");
}
}
Mutation 3
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 618 | RIC_MINUS_1 | true |
Source Code Context
Token token = new Token(TokenTypes.PLUS,
getXPath(),
currentPosition(),
currentPosition()+1 );
consume();
return token;
}
Mutated Statement
Unit Test for Mutation
try {
XPathReader xp = new XPathReader();
xp.parse("+");
fail("Expect exception");
} catch (SAXPathException e) {
// Expect this exception
assertEquals("Unexpected '+'", e.getMessage());
} catch (Exception e) {
fail("Did not expect this exception");
}
}
Mutation 4
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathReader | 1082 | RIC_PLUS_1 | true |
Source Code Context
private XPathSyntaxException createSyntaxException(String message) {
String xpath = this.lexer.getXPath();
int position = LT(1).getTokenBegin();
return new XPathSyntaxException(xpath, position, message);
}
Mutated Statement
Unit Test for Mutation
try {
XPathReader xp = new XPathReader();
xp.parse("+Y");
fail("Expect exception");
} catch (XPathSyntaxException e) {
// Expect this exception
assertEquals("Unexpected '+'", e.getMessage());
System.out.println(e);
// after mutation +Y: 1: Unexpected '+'
assertEquals(0,e.getPosition());
} catch (Exception e) {
fail("Did not expect this exception");
}
}
Mutation 5
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.pattern.LocationPathPattern | 107 | NEGATE_JUMP | true |
Source Code Context
if ( parentPattern != null ) {
parentPattern = parentPattern.simplify();
}
if ( ancestorPattern != null ) {
ancestorPattern = ancestorPattern.simplify();
}
if ( filters == null ) {
if ( parentPattern == null && ancestorPattern == null ) {
return nodeTest;
}
if ( parentPattern != null && ancestorPattern == null ) {
if ( nodeTest instanceof AnyNodeTest ) {
return parentPattern;
}
}
}
return this; }
Mutated Statement
Unit Test for Mutation
LocationPathPattern p = new LocationPathPattern();
p.setAncestorPattern(null);
Pattern simple = p.simplify();
assertFalse(simple.toString().equals(p.toString()));
}
Mutation 6
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.expr.DefaultLocationPath | 126 | RIC_MINUS_1 | true |
Source Code Context
return false;
}
Mutated Statement
In Java bytecode the original statement isIRETURN
IRETURN
Unit Test for Mutation
DefaultXPathFactory factory = new DefaultXPathFactory();
try {
LocationPath locationPath = factory.createRelativeLocationPath();
assertFalse(locationPath.isAbsolute());
} catch (JaxenException e) {
e.printStackTrace();
fail(e.toString());
}
}
Mutation 7
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.expr.DefaultLocationPath | 126 | RIC_PLUS_1 | true |
Source Code Context
return false;
}
Mutated Statement
In Java bytecode the original statement isIRETURN
IRETURN
Unit Test for Mutation
DefaultXPathFactory factory = new DefaultXPathFactory();
try {
LocationPath locationPath = factory.createRelativeLocationPath();
assertFalse(locationPath.isAbsolute());
} catch (JaxenException e) {
e.printStackTrace();
fail(e.toString());
}
}
Mutation 8
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.JaxenRuntimeException | 140 | RIC_PLUS_1 | false |
Source Code Context
super.printStackTrace( s );
if (JaxenException.javaVersion < 1.4 && getCause() != null) {
s.print( "Caused by: " );
getCause().printStackTrace( s );
}
}
Mutated Statement
Unit Test for Mutation
No unit test for this mutation since it is considered equivalent, Since the code of the if bracnh mimics the default behaviour, of Java 1.4 for Java versions < 1.4. During a mutation this code is executed and the expected behaviour is carried out by the program instead of the Java environment.
Mutation 9
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.JaxenRuntimeException | 140 | NEGATE_JUMP | false |
Source Code Context
super.printStackTrace( s );
if (JaxenException.javaVersion < 1.4 && getCause() != null) {
s.print( "Caused by: " );
getCause().printStackTrace( s );
}
}
Mutated Statement
Unit Test for Mutation
No unit test for this mutation (see Mutation 9).
Mutation 10
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 274 | RIC_MINUS_1 | true |
Source Code Context
currentPosition(),
endPosition() );
}
else {
token = new Token( TokenTypes.ERROR,
getXPath(),
currentPosition(),
endPosition() );
}
} ...
Mutated Statement
token = new Token( TokenTypes.ERROR - 1,
Unit Test for Mutation
XPathLexer lexer = new XPathLexer("/numbers numbers");
Token token;
token = lexer.nextToken();
assertEquals("/", TokenTypes.getTokenText(token.getTokenType()));
token = lexer.nextToken();
assertEquals("(identifier)", TokenTypes.getTokenText(token
.getTokenType()));
token = lexer.nextToken();
assertEquals("(error)", TokenTypes.getTokenText(token.getTokenType()));
}
Mutation 11
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 274 | RIC_ZERO | true |
Source Code Context
currentPosition(),
endPosition() );
}
else {
token = new Token( TokenTypes.ERROR,
getXPath(),
currentPosition(),
endPosition() );
}
} ...
Mutated Statement
token = new Token( 0,
Unit Test for Mutation
XPathLexer lexer = new XPathLexer("/numbers numbers");
Token token;
token = lexer.nextToken();
assertEquals("/", TokenTypes.getTokenText(token.getTokenType()));
token = lexer.nextToken();
assertEquals("(identifier)", TokenTypes.getTokenText(token
.getTokenType()));
token = lexer.nextToken();
assertEquals("(error)", TokenTypes.getTokenText(token.getTokenType()));
}
Mutation 12
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 649 | ARITHMETIC_REPLACE | true |
Source Code Context
getXPath(),
currentPosition(),
currentPosition()+1 );
...
Mutated Statement
currentPosition()-1 );,
Unit Test for Mutation
try {
XPathReader xp = new XPathReader();
xp.parse("1@");
fail("Expect exception");
} catch (SAXPathException e) {
// Expect this exception
assertEquals("Unexpected '@'", e.getMessage());
} catch (Exception e) {
fail("Did not expect this exception" + e);
}
}
Non Invariant Violating Mutants
Results for twelve randomly chosen mutants that do not violate invariants and are not detected by the original test suite.Mutation 1
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.Verifier | 302 | RIC_MINUS_1 | true |
Source Code Context
if (c < 0x1FF6) return false; if (c <= 0x1FFC) return true;
if (c == 0x2126) return true;
if (c < 0x212A) return false; if (c <= 0x212B) return true;
if (c == 0x212E) return true;
if (c < 0x2180) return false; if (c <= 0x2182) return true;
if (c == 0x3007) return true;
if (c < 0x3021) return false; if (c <= 0x3029) return true;
if (c < 0x3041) return false; if (c <= 0x3094) return true;
if (c < 0x30A1) return false; if (c <= 0x30FA) return true;
if (c < 0x3105) return false; if (c <= 0x312C) return true;
if (c < 0x4E00) return false; if (c <= 0x9FA5) return true;
if (c < 0xAC00) return false; if (c <= 0xD7A3) return true;
...
Mutated Statement
Unit Test for Mutation
char c = 0x30A0;
boolean combiningChar = Verifier.isXMLLetter(c);
assertEquals(false, combiningChar);
}
Mutation 2
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 900 | RIC_MINUS_1 | false |
Source Code Context
if ( currentPosition + ( i - 1 ) >= endPosition() ) {
return (char) -1;
}
return getXPath().charAt( currentPosition() + (i - 1) );
}
Mutated Statement
return (char) -2;
Unit Test for Mutation
Considered equivalent, since in callers of LA() it is checked for non negativity. Minus one is used to represent a value that is not occupied by chars in other words, which is also true for -2.
Mutation 3
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.xom.DocumentNavigator | 377 | RIC_PLUS_1 | false |
Source Code Context
if (uri != null && uri.length() > 0 && (! map.containsKey(prefix))) {
map.put(prefix, new XPathNamespace(elt, uri, prefix));
return true;
}
return false;
}
Mutated Statement
Original bytecode:
Unit Test for Mutation
Mutation does not change program behaviour since, the contstant two is loaded instead of one, and following jumps is just checking for non zero
Mutation 4
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.XPathFunctionContext | 149 | NEGATE_JUMP | true |
Source Code Context
registerXPathFunctions();
if (includeExtensionFunctions) {
registerXSLTFunctions();
registerExtensionFunctions();
}
}
Mutated Statement
Unit Test for Mutation
XPathFunctionContext xfunc = new XPathFunctionContext();
assertTrue(null!= xfunc.getFunction(null,null, "evaluate"));
}
Mutation 5
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.xom.DocumentNavigator$IndexIterator | 224 | RIC_PLUS_1 | false |
Source Code Context
return pos < end;
}
Mutated Statement
see Mutation 3
Mutation 6
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.util.DescendantAxisIterator | 109 | RIC_PLUS_1 | false |
Source Code Context
while (!children.hasNext()) {
if (stack.isEmpty()) {
return false;
}
children = (Iterator) stack.remove(stack.size()-1);
}
return true;
}
Mutated Statement
see Mutation 3
Mutation 7
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.function.NormalizeSpaceFunction | 171 | RIC_PLUS_1 | false |
Source Code Context
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
}
Mutated Statement
see Mutation 3
Mutation 8
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.function.ext.UpperFunction | 86 | RIC_PLUS_1 | --- |
Source Code Context
List args) throws FunctionCallException {
Navigator navigator = context.getNavigator();
int size = args.size();
if (size > 0) {
Object text = args.get(0);
Locale locale = null;
if (size > 1) {
locale = getLocale( args.get(1), navigator );
}
return evaluate( text, locale, navigator );
}
throw new FunctionCallException( "upper-case() requires at least one argument." );
}
Mutated Statement
if (size > 2) {
Unit Test for Mutation
Failed to write unit test for this one, since sytem locale is used which does the right thing in most cases.Mutation 9
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.Verifier | 456 | RIC_MINUS_1 | false |
Source Code Context
if (c < 0x00B6) return false; // quick short circuit
// Extenders
if (c == 0x00B7) return true;
if (c == 0x02D0) return true;
if (c == 0x02D1) return true;
if (c == 0x0387) return true;
if (c == 0x0640) return true;
if (c == 0x0E46) return true;
if (c == 0x0EC6) return true;
if (c == 0x3005) return true;
if (c < 0x3031) return false; if (c <= 0x3035) return true;
if (c < 0x309D) return false; if (c <= 0x309E) return true;
if (c < 0x30FC) return false; if (c <= 0x30FE) return true;
return false; }
Mutated Statement
if (c < 0x00B6-1) return false;
Unit Test for Mutation
No unit test since the mutation does not cause different behaviour of the function (in both cases false ist returned for 0x00B6).
Mutation 10
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 615 | RIC_MINUS_1 | true |
Source Code Context
Token token = new Token( TokenTypes.LEFT_BRACKET,
getXPath(),
currentPosition(),
currentPosition()+1 );
consume();
return token;
}
Mutated Statement
currentPosition() + 1 - 1 );
Unit Test for Mutation
try {
XPathReader xp = new XPathReader();
xp.parse("[");
fail("Expect exception " );
} catch (SAXPathException e) {
// Expect this exception
assertEquals("Unexpected '['", e.getMessage());
} catch (Exception e) {
fail("Did not expect this exception" + e);
}
}
Mutation 11
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.SAXPathException | 139 | RIC_PLUS_1 | false |
Source Code Context
if (causeSet) throw new IllegalStateException("Cause cannot be reset");
if (cause == this) throw new IllegalArgumentException("Exception cannot be its own cause");
causeSet = true;
this.cause = cause;
return this;
}
Mutated Statement
see Mutation 3
Mutation 12
Class | Line number | Type | Non Equivalent |
---|---|---|---|
org.jaxen.saxpath.base.XPathLexer | 615 | RIC_MINUS_1 | true |
Source Code Context
if (arg.getNodeType() == this.getNodeType()) {
NamespaceNode other = (NamespaceNode) arg;
if (other.name == null && this.name != null) return false;
else if (other.name != null && this.name == null) return false;
else if (other.value == null && this.value != null) return false;
else if (other.value != null && this.value == null) return false;
else if (other.name == null && this.name == null) {
return other.value.equals(this.value);
}
return other.name.equals(this.name) && other.value.equals(this.value);
}
return false;
}
Mutated Statement
else if (other.name != null && this.name != null) return false;
Unit Test for Mutation
public void testMutation() {
NamespaceNode node1 = new NamespaceNode(null,"a", "aaa");
NamespaceNode other1 = new NamespaceNode(null,"a", "aaa");
boolean isEqual = node1.isEqualNode(other1);
assertTrue("Expcted namespace nodes not to be equal", isEqual);
}