예제 #1
0
  /** {@inheritDoc} */
  @Override
  public void afterStatement(Statement statement, Scope scope, Throwable exception) {
    try {
      for (VariableReference var : statement.getVariableReferences()) {
        if (var.equals(statement.getReturnValue())
            || var.equals(statement.getReturnValue().getAdditionalVariableReference())) continue;
        Object object = var.getObject(scope);

        if (var.isPrimitive()) {
          ConstantValue value = new ConstantValue(test, var.getGenericClass());
          value.setValue(object);
          // logger.info("Statement before inlining: " + statement.getCode());
          statement.replace(var, value);
          // logger.info("Statement after inlining: " + statement.getCode());
        } else if (var.isString() && object != null) {
          ConstantValue value = new ConstantValue(test, var.getGenericClass());
          try {
            String val = StringEscapeUtils.unescapeJava(object.toString());
            value.setValue(val);
            statement.replace(var, value);
          } catch (IllegalArgumentException e) {
            // Exceptions may happen if strings are not valid unicode
            logger.info("Cannot escape invalid string: " + object);
          }
          // logger.info("Statement after inlining: " + statement.getCode());
        } else if (var.isArrayIndex()) {
          // If this is an array index and there is an object outside the array
          // then replace the array index with that object
          for (VariableReference otherVar : scope.getElements(var.getType())) {
            Object otherObject = otherVar.getObject(scope);
            if (otherObject == object
                && !otherVar.isArrayIndex()
                && otherVar.getStPosition() < statement.getPosition()) {
              statement.replace(var, otherVar);
              break;
            }
          }
        } else {
          // TODO: Ignoring exceptions during getObject, but keeping the assertion for now
          if (object == null) {
            ConstantValue value = new ConstantValue(test, var.getGenericClass());
            value.setValue(null);
            // logger.info("Statement before inlining: " + statement.getCode());
            statement.replace(var, value);
            // logger.info("Statement after inlining: " + statement.getCode());
          }
        }
      }
    } catch (CodeUnderTestException e) {
      logger.warn("Not inlining test: " + e.getCause());
      // throw new AssertionError("This case isn't handled yet: " + e.getCause()
      //        + ", " + Arrays.asList(e.getStackTrace()));
    }
  }
예제 #2
0
  /**
   * Set variable to new value
   *
   * @param reference VariableReference
   * @param o Value
   */
  public synchronized void setObject(VariableReference reference, Object o) {
    // Learn some dynamic information about this object
    if (reference instanceof ArrayReference) {
      ArrayReference arrayRef = (ArrayReference) reference;
      if (o != null && !o.getClass().isArray())
        System.out.println("Trying to access object of class " + o.getClass() + " as array: " + o);
      else if (o != null) {
        Object value = o;
        List<Integer> lengths = new ArrayList<Integer>();
        int idx = 0;
        while ((value != null) && value.getClass().isArray()) {
          if (idx == lengths.size()) {
            lengths.add(Array.getLength(value));
          } else {
            lengths.set(idx, Array.getLength(value));
          }
          if (Array.getLength(value) == 0) break;
          value = Array.get(value, 0);
          idx++;
        }
        arrayRef.setLengths(lengths);
      } else arrayRef.setArrayLength(0);
    }

    // TODO: Changing array types might invalidate array assignments - how to treat this properly?
    if (o != null
        && !o.getClass().equals(reference.getVariableClass())
        && reference.getGenericClass().getNumParameters() == 0
        && !reference.isPrimitive() // && !reference.getGenericClass().isClass()
        && !o.getClass().isArray()) { // && !(reference instanceof ArrayReference)) {
      if (TestUsageChecker.canUse(o.getClass())) {
        if (Proxy.isProxyClass(o.getClass())) {
          reference.setType(o.getClass().getSuperclass());
        } else if (o.getClass().getName().contains("EnhancerByMockito")) {
          /*
          tricky: this is a functional mock for a class X. We do not want to set
          scopes on mock objects, as their class definitions are created on the fly
          and will be missing on different processes (eg communications between Master
          and Client).
          If X is a class, then the mock will extend it. However, if it was an interface,
          then we need to look at all of its interface to find the correct one
          */
          String mockName = o.getClass().getName();
          Class<?> target = o.getClass().getSuperclass();
          if (!mockName.startsWith(target.getName() + "$")) {
            for (Class<?> inter : o.getClass().getInterfaces()) {
              if (mockName.startsWith(inter.getName() + "$")) {
                target = inter;
                break;
              }
            }
          }
          reference.setType(target);

        } else {
          reference.setType(o.getClass());
        }
      }
    }
    pool.put(reference, o);
  }