All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.noenv.wiremongo.matching.JsonMatcher Maven / Gradle / Ivy

There is a newer version: 4.5.10
Show newest version
package com.noenv.wiremongo.matching;

import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.Objects;
import java.util.function.Function;
import java.util.stream.IntStream;

public class JsonMatcher implements Matcher {

  private final Object value;
  private final Function toJson;
  private final boolean ignoreExtraElements;
  private final boolean ignoreArrayOrder;

  JsonMatcher(JsonObject json, Function toJson) {
    this(json.getValue("equalToJson"),
      toJson,
      json.getBoolean("ignoreExtraElements", false),
      json.getBoolean("ignoreArrayOrder", false));
  }

  private JsonMatcher(Object value, Function toJson, boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    if (!(value instanceof JsonObject || value instanceof JsonArray)) {
      throw new IllegalArgumentException("value has to be a JsonObject or JsonArray");
    }
    this.value = value;
    this.toJson = toJson;
    this.ignoreExtraElements = ignoreExtraElements;
    this.ignoreArrayOrder = ignoreArrayOrder;
  }

  public static JsonMatcher equalToJson(JsonObject value) {
    return equalToJson(value, false);
  }

  public static JsonMatcher equalToJson(JsonObject value, boolean ignoreExtraElements) {
    return equalToJson(value, ignoreExtraElements, false);
  }

  public static JsonMatcher equalToJson(JsonObject value, boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    return equalToJson(value, i -> i, ignoreExtraElements, ignoreArrayOrder);
  }

  public static  JsonMatcher equalToJson(JsonObject value, Function toJson) {
    return equalToJson(value, toJson, false);
  }

  // JsonObject overloads

  public static  JsonMatcher equalToJson(JsonObject value, Function toJson, boolean ignoreExtraElements) {
    return equalToJson(value, toJson, ignoreExtraElements, false);
  }

  public static  JsonMatcher equalToJson(JsonObject value, Function toJson,
                                               boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    return new JsonMatcher<>(value, toJson, ignoreExtraElements, ignoreArrayOrder);
  }

  public static Matcher notEqualToJson(JsonObject value) {
    return notEqualToJson(value, false);
  }

  public static Matcher notEqualToJson(JsonObject value, boolean ignoreExtraElements) {
    return notEqualToJson(value, ignoreExtraElements, false);
  }

  public static Matcher notEqualToJson(JsonObject value, boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    return o -> !equalToJson(value, ignoreExtraElements, ignoreArrayOrder).matches(o);
  }

  public static JsonMatcher equalToJson(JsonArray value) {
    return equalToJson(value, false);
  }

  public static JsonMatcher equalToJson(JsonArray value, boolean ignoreExtraElements) {
    return equalToJson(value, ignoreExtraElements, false);
  }

  public static JsonMatcher equalToJson(JsonArray value, boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    return equalToJson(value, i -> i, ignoreExtraElements, ignoreArrayOrder);
  }

  public static  JsonMatcher equalToJson(JsonArray value, Function toJson) {
    return equalToJson(value, toJson, false);
  }

  // JsonArray overloads

  public static  JsonMatcher equalToJson(JsonArray value, Function toJson, boolean ignoreExtraElements) {
    return equalToJson(value, toJson, ignoreExtraElements, false);
  }

  public static  JsonMatcher equalToJson(JsonArray value, Function toJson,
                                               boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    return new JsonMatcher<>(value, toJson, ignoreExtraElements, ignoreArrayOrder);
  }

  public static Matcher notEqualToJson(JsonArray value) {
    return notEqualToJson(value, false);
  }

  public static Matcher notEqualToJson(JsonArray value, boolean ignoreExtraElements) {
    return notEqualToJson(value, ignoreExtraElements, false);
  }

  public static Matcher notEqualToJson(JsonArray value, boolean ignoreExtraElements, boolean ignoreArrayOrder) {
    return o -> !equalToJson(value, ignoreExtraElements, ignoreArrayOrder).matches(o);
  }

  @Override
  public boolean matches(T other) {
    if (value == null && other == null) {
      return true;
    }
    if (value == null || other == null) {
      return false;
    }
    return matchInternal(value, toJson.apply(other));
  }

  private boolean matchInternal(Object a, Object b) {
    if (a instanceof JsonObject && b instanceof JsonObject) {
      return matchInternal((JsonObject) a, (JsonObject) b);
    }
    if (a instanceof JsonArray && b instanceof JsonArray) {
      return matchInternal((JsonArray) a, (JsonArray) b);
    }
    if (a instanceof Number && b instanceof Number && a.getClass() != b.getClass()) {
      Number an = (Number) a;
      Number bn = (Number) b;
      if (a instanceof Float || a instanceof Double || b instanceof Float || b instanceof Double) {
        return an.doubleValue() == bn.doubleValue();
      } else {
        return an.longValue() == bn.longValue();
      }
    }
    return Objects.equals(a, b);
  }

  private boolean matchInternal(JsonObject a, JsonObject b) {
    if (!ignoreExtraElements && (a.size() != b.size())) {
      return false;
    }
    return a.stream().allMatch(e -> matchInternal(e.getValue(), b.getValue(e.getKey())));
  }

  private boolean matchInternal(JsonArray a, JsonArray b) {
    if ((!ignoreExtraElements && a.size() != b.size()) || (ignoreExtraElements && a.size() > b.size())) {
      return false;
    }
    if (ignoreArrayOrder) {
      return a.stream().allMatch(av -> b.stream().anyMatch(bv -> matchInternal(av, bv)));
    }
    return IntStream.range(0, a.size()).allMatch(i -> matchInternal(a.getValue(i), b.getValue(i)));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy