@Test
public void testMatrixIdentityOk() throws Exception {

  // This test aims to check that when we replace m with "m / e" or "m * e", "e" is the
  // identity matrix.
  final String program = "#version 300 es\n"
      + "precision highp float;\n"
      + "void main() {"
      + "  mat2 m;"
      + "  m;"
      + "}";
  for (int i = 0; i < 20; i++) {
    final TranslationUnit tu = ParseHelper.parse(program);
    IdentityMutationFinder identityMutationFinder = new IdentityMutationFinder(tu,
        new RandomWrapper(i), GenerationParams.small(ShaderKind.FRAGMENT, false));
    identityMutationFinder.findMutations().forEach(Expr2ExprMutation::apply);
    new StandardVisitor() {
      @Override
      public void visitFunctionCallExpr(FunctionCallExpr functionCallExpr) {
        super.visitFunctionCallExpr(functionCallExpr);
        if (!functionCallExpr.getCallee().equals(Constants.GLF_IDENTITY)) {
          return;
        }
        if (!(functionCallExpr.getArgs().get(0) instanceof VariableIdentifierExpr)) {
          return;
        }
        if (!(((VariableIdentifierExpr) functionCallExpr.getArgs().get(0)).getName()
            .equals("m"))) {
          return;
        }
        if (!(functionCallExpr.getArgs().get(1) instanceof BinaryExpr)) {
          return;
        }
        final BinaryExpr binaryExpr = (BinaryExpr) functionCallExpr.getArgs().get(1);
        if (!Arrays.asList(BinOp.DIV, BinOp.MUL).contains(binaryExpr.getOp())) {
          return;
        }
        if (!(binaryExpr.getRhs() instanceof TypeConstructorExpr)) {
          return;
        }
        final TypeConstructorExpr typeConstructorExpr = (TypeConstructorExpr) binaryExpr.getRhs();
        if (!typeConstructorExpr.getTypename().equals(BasicType.MAT2X2.toString())) {
          return;
        }
        if (binaryExpr.getOp() == BinOp.MUL) {
          // In the case of MUL we should be multiplying by the identity matrix.
          // The identity matrix should only have one arg, and if it is a literal it should be
          // 1.0.
          assertTrue(typeConstructorExpr.getNumArgs() == 1);
          if (typeConstructorExpr.getArg(0) instanceof FloatConstantExpr) {
            assertEquals("1.0", ((FloatConstantExpr) typeConstructorExpr.getArg(0)).getValue());
          }
        } else {
          // In the case of DIV we should be multiplying by a matrix of all 1.0s.
          assertEquals(binaryExpr.getOp(), BinOp.DIV);
          assertTrue(typeConstructorExpr.getNumArgs() == 4);
          for (int i = 0; i < 4; i++) {
            if (typeConstructorExpr.getArg(i) instanceof FloatConstantExpr) {
              assertEquals("1.0", ((FloatConstantExpr) typeConstructorExpr.getArg(i)).getValue());
            }
          }
        }
      }
    }.visit(tu);
  }
}