not Mutation Test

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

    ClassLine numberTypeNon Equivalent
    org.jaxen.Context102RIC_MINUS_1true

    Source Code Context


    public Context(ContextSupport contextSupport)
    {
         this.contextSupport = contextSupport;
         this.nodeSet = Collections.EMPTY_LIST;
         this.size = 0;
         this.position = 0;
    }

    Mutated Statement

         this.size = -1;

    Unit Test for Mutation

    public void testMutation() {
        Context c = new Context(new ContextSupport());
        assertEquals(0, c.getPosition());
    }

    Mutation 2

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer618RIC_ZEROtrue

    Source Code Context

    private Token plus() {
        Token token = new Token(TokenTypes.PLUS,
          getXPath(),
          currentPosition(),
          currentPosition()+1 );
        consume();
        return token;
    }

    Mutated Statement

        currentPosition()+0

    Unit Test for Mutation

    public void testMutation() {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer618RIC_MINUS_1true

    Source Code Context

    private Token plus() {
        Token token = new Token(TokenTypes.PLUS,
          getXPath(),
          currentPosition(),
          currentPosition()+1 );
        consume();
        return token;
    }

    Mutated Statement

        currentPosition()-1

    Unit Test for Mutation

    public void testMutation() {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathReader1082RIC_PLUS_1true

    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

      int position = LT(2).getTokenBegin();

    Unit Test for Mutation

    public void testMutation() {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.pattern.LocationPathPattern107NEGATE_JUMPtrue

    Source Code Context

    public Pattern simplify() {
      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

        if ( parentPattern != null && ancestorPattern != null ) {

    Unit Test for Mutation

    public void testMutation() {
      LocationPathPattern p = new LocationPathPattern();
      p.setAncestorPattern(null);
      Pattern simple = p.simplify();
      assertFalse(simple.toString().equals(p.toString()));
    }

    Mutation 6

    ClassLine numberTypeNon Equivalent
    org.jaxen.expr.DefaultLocationPath126RIC_MINUS_1true

    Source Code Context

    public boolean isAbsolute() {
      return false;
    }

    Mutated Statement

    In Java bytecode the original statement is
    ICONST_0
    IRETURN
    And the mutated version is:
    ICONST_M1
    IRETURN

    Unit Test for Mutation

    public void testMutation(){
      DefaultXPathFactory factory = new DefaultXPathFactory();
      try {
        LocationPath locationPath = factory.createRelativeLocationPath();
        assertFalse(locationPath.isAbsolute());
      } catch (JaxenException e) {
        e.printStackTrace();
        fail(e.toString());
      }
    }

    Mutation 7

    ClassLine numberTypeNon Equivalent
    org.jaxen.expr.DefaultLocationPath126RIC_PLUS_1true

    Source Code Context

    public boolean isAbsolute() {
      return false;
    }

    Mutated Statement

    In Java bytecode the original statement is
    ICONST_0
    IRETURN
    And the mutated version is:
    ICONST_1
    IRETURN

    Unit Test for Mutation

    public void testMutation(){
      DefaultXPathFactory factory = new DefaultXPathFactory();
      try {
        LocationPath locationPath = factory.createRelativeLocationPath();
        assertFalse(locationPath.isAbsolute());
      } catch (JaxenException e) {
        e.printStackTrace();
        fail(e.toString());
      }
    }

    Mutation 8

    ClassLine numberTypeNon Equivalent
    org.jaxen.JaxenRuntimeException140RIC_PLUS_1false

    Source Code Context

    public void printStackTrace ( PrintWriter s ) {
      super.printStackTrace( s );
      if (JaxenException.javaVersion < 1.4 && getCause() != null) {
        s.print( "Caused by: " );
        getCause().printStackTrace( s );
      }
    }

    Mutated Statement

      if (JaxenException.javaVersion < 2.4 && getCause() != null) {

    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

    ClassLine numberTypeNon Equivalent
    org.jaxen.JaxenRuntimeException140NEGATE_JUMPfalse

    Source Code Context

    public void printStackTrace ( PrintWriter s ) {
      super.printStackTrace( s );
      if (JaxenException.javaVersion < 1.4 && getCause() != null) {
        s.print( "Caused by: " );
        getCause().printStackTrace( s );
      }
    }

    Mutated Statement

      if (JaxenException.javaVersion >= 1.4 && getCause() != null) {

    Unit Test for Mutation

    No unit test for this mutation (see Mutation 9).

    Mutation 10

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer274RIC_MINUS_1true

    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

    public void testMutation() {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer274RIC_ZEROtrue

    Source Code Context

    ...
        currentPosition(),
        endPosition() );
      }
      else {
      token = new Token( TokenTypes.ERROR,
        getXPath(),
        currentPosition(),
        endPosition() );
      }
    } ...

    Mutated Statement


      token = new Token( 0,

    Unit Test for Mutation

    public void testMutation() {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer649ARITHMETIC_REPLACEtrue

    Source Code Context

    ... Token token = new Token( TokenTypes.AT,
     getXPath(),
     currentPosition(),
     currentPosition()+1 );
    ...

    Mutated Statement


      currentPosition()-1 );,

    Unit Test for Mutation

    public void testMutation3() {
        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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.Verifier302 RIC_MINUS_1true

    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

      if (c < 0x30A1 - 1) return false; if (c <= 0x30FA) return true;

    Unit Test for Mutation

    public void testMutation() {
      char c = 0x30A0;
      boolean combiningChar = Verifier.isXMLLetter(c);
      assertEquals(false, combiningChar);
    }

    Mutation 2

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer900RIC_MINUS_1false

    Source Code Context

    private char LA(int i) {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.xom.DocumentNavigator377RIC_PLUS_1false

    Source Code Context

    private boolean addNamespaceForElement(Element elt, String uri, String prefix, Map map) {
      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:

    ICONST_1
    Mutated statement
    ICONST_2

    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

    ClassLine numberTypeNon Equivalent
    org.jaxen.XPathFunctionContext149NEGATE_JUMPtrue

    Source Code Context

    public XPathFunctionContext(boolean includeExtensionFunctions) {
      registerXPathFunctions();
      if (includeExtensionFunctions) {
        registerXSLTFunctions();
        registerExtensionFunctions();
      }
    }

    Mutated Statement

      if (!includeExtensionFunctions) {

    Unit Test for Mutation

    public void testMutatation() throws UnresolvableException{
      XPathFunctionContext xfunc = new XPathFunctionContext();
      assertTrue(null!= xfunc.getFunction(null,null, "evaluate"));
    }

    Mutation 5

    ClassLine numberTypeNon Equivalent
    org.jaxen.xom.DocumentNavigator$IndexIterator224RIC_PLUS_1false

    Source Code Context

    public boolean hasNext() {
       return pos < end;
    }

    Mutated Statement

    see Mutation 3

    Mutation 6

    ClassLine numberTypeNon Equivalent
    org.jaxen.util.DescendantAxisIterator109RIC_PLUS_1false

    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

    ClassLine numberTypeNon Equivalent
    org.jaxen.function.NormalizeSpaceFunction171RIC_PLUS_1 false

    Source Code Context

    private static boolean isXMLSpace(char c) {
      return c == ' ' || c == '\n' || c == '\r' || c == '\t';
    }

    Mutated Statement

    see Mutation 3

    Mutation 8

    ClassLine numberTypeNon Equivalent
    org.jaxen.function.ext.UpperFunction86RIC_PLUS_1---

    Source Code Context

    public Object call(Context 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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.Verifier456RIC_MINUS_1false

    Source Code Context

    static boolean isXMLExtender(char c) {
      
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer615RIC_MINUS_1true

    Source Code Context

    private Token leftBracket() {
      Token token = new Token( TokenTypes.LEFT_BRACKET,


         getXPath(),
         currentPosition(),
        

    currentPosition()+1 );


      consume();
      return token;
    }

    Mutated Statement


        

    currentPosition() + 1 - 1 );

    Unit Test for Mutation

    public void testMutation() {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.SAXPathException139RIC_PLUS_1false

    Source Code Context

    public Throwable initCause(Throwable cause) {
      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

    ClassLine numberTypeNon Equivalent
    org.jaxen.saxpath.base.XPathLexer615RIC_MINUS_1true

    Source Code Context

    public boolean isEqualNode(Node arg) {
      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);
      }