/** * Copyright (c) 2018 LEAP Encryption Access Project and contributers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package se.leap.bitmaskclient.testutils.matchers; import android.os.Bundle; import android.os.Parcelable; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import java.util.HashMap; import java.util.Iterator; import java.util.Set; /** * Created by cyberta on 09.01.18. */ public class BundleMatcher extends BaseMatcher { private final HashMap expectedIntegers; private final HashMap expectedStrings; private final HashMap expectedBooleans; private final HashMap expectedParcelables; private HashMap unfoundExpectedInteger = new HashMap<>(); private HashMap unfoundExpectedBoolean = new HashMap<>(); private HashMap unfoundExpectedString = new HashMap<>(); private HashMap unfoundExpectedParcelable = new HashMap<>(); private HashMap unexpectedAdditionalObjects = new HashMap<>(); public BundleMatcher(HashMap expectedIntegers, HashMap expectedStrings, HashMap expectedBooleans, HashMap expectedParcelables) { this.expectedBooleans = expectedBooleans; this.expectedIntegers = expectedIntegers; this.expectedStrings = expectedStrings; this.expectedParcelables = expectedParcelables; } @Override public boolean matches(Object item) { if (item instanceof Bundle) { Bundle actualBundle = (Bundle) item; return checkActualBundleHasAllExpectedBooleanValues(actualBundle) && checkActualBundleHasAllExpectedStringValues(actualBundle) && checkActualBundleHasAllExpectedIntValues(actualBundle) && checkActualBundleHasAllExpectedParcelableValues(actualBundle) && checkUnexpectedAdditionalValuesIn(actualBundle); } return false; } @Override public void describeTo(Description description) { description.appendText("Bundle didn't match expectation!"); if (!unfoundExpectedInteger.isEmpty()) { Iterator iterator = unfoundExpectedInteger.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (unfoundExpectedInteger.get(key) == null) { description.appendText("\n unfound Integer in actual Bundle: ").appendValue(iterator.next()); } else { description.appendText("\n expected Integer for key " + key + ": ").appendValue(expectedIntegers.get(key)). appendText("\n found Integer was: ").appendValue(unfoundExpectedInteger.get(key)); } } } if (!unfoundExpectedBoolean.isEmpty()) { Iterator iterator = unfoundExpectedBoolean.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (unfoundExpectedBoolean.get(key) == null) { description.appendText("\n unfound Boolean in actual Bundle: ").appendValue(iterator.next()); } else { description.appendText("\n expected Boolean for key " + key + ": ").appendValue(expectedBooleans.get(key)). appendText("\n found Boolean was: ").appendValue(unfoundExpectedBoolean.get(key)); } } } if (!unfoundExpectedString.isEmpty()) { Iterator iterator = unfoundExpectedString.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (unfoundExpectedString.get(key) == null) { description.appendText("\n unfound String in actual Bundle: ").appendValue(iterator.next()); } else { description.appendText("\n expected String for key " + key + ": ").appendValue(expectedStrings.get(key)). appendText("\n found String was: ").appendValue(unfoundExpectedString.get(key)); } } } if (!unfoundExpectedParcelable.isEmpty()) { Iterator iterator = unfoundExpectedInteger.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (unfoundExpectedParcelable.get(key) == null) { description.appendText("\n unfound Parcelable in actual Bundle: ").appendValue(iterator.next()); } else { description.appendText("\n expected Parcelable or key " + key + ": ").appendValue(expectedParcelables.get(key)). appendText("\n found Parcelable was: ").appendValue(unfoundExpectedParcelable.get(key)); } } } if (!unexpectedAdditionalObjects.isEmpty()) { Iterator iterator = unexpectedAdditionalObjects.keySet().iterator(); while (iterator.hasNext()) { String key = iterator.next(); Object value = unexpectedAdditionalObjects.get(key); if (value instanceof String) { description.appendText("\n unexpected String found in actual Bundle: ").appendValue(key).appendText(", ").appendValue(value); } else if (value instanceof Boolean) { description.appendText("\n unexpected Boolean found in actual Bundle: ").appendValue(key).appendText(", ").appendValue(value); } else if (value instanceof Integer) { description.appendText("\n unexpected Integer found in actual Bundle: ").appendValue(key).appendText(", ").appendValue(value); } else if (value instanceof Parcelable) { description.appendText("\n unexpected Parcelable found in actual Bundle: ").appendValue(key).appendText(", ").appendValue(value); } else { description.appendText("\n unexpected Object found in actual Bundle: ").appendValue(key).appendText(", ").appendValue(value); } } } } private boolean checkActualBundleHasAllExpectedBooleanValues(Bundle actualBundle) { Set booleanKeys = expectedBooleans.keySet(); for (String key : booleanKeys) { Object valueObject = actualBundle.get(key); if (!(valueObject instanceof Boolean) || valueObject != expectedBooleans.get(key)) { unfoundExpectedBoolean.put(key, (Boolean) valueObject); return false; } } return true; } private boolean checkActualBundleHasAllExpectedStringValues(Bundle actualBundle) { Set stringKeys = expectedStrings.keySet(); for (String key : stringKeys) { Object valueObject = actualBundle.get(key); if (!(valueObject instanceof String) || !valueObject.equals(expectedStrings.get(key))) { unfoundExpectedString.put(key, (String) valueObject); return false; } } return true; } private boolean checkActualBundleHasAllExpectedIntValues(Bundle actualBundle) { Set stringKeys = expectedIntegers.keySet(); for (String key : stringKeys) { Object valueObject = actualBundle.get(key); if (!(valueObject instanceof Integer) || ((Integer) valueObject).compareTo(expectedIntegers.get(key)) != 0) { unfoundExpectedInteger.put(key, (Integer) valueObject); return false; } } return true; } private boolean checkActualBundleHasAllExpectedParcelableValues(Bundle actualBundle) { Set stringKeys = expectedParcelables.keySet(); for (String key : stringKeys) { Object valueObject = actualBundle.get(key); if (!(valueObject instanceof Parcelable) || !valueObject.equals(expectedParcelables.get(key))) { unfoundExpectedParcelable.put(key, (Parcelable) valueObject); return false; } } return true; } private boolean checkUnexpectedAdditionalValuesIn(Bundle actualBundle) { Set keys = actualBundle.keySet(); for (String key : keys) { if (!expectedStrings.containsKey(key) && !expectedIntegers.containsKey(key) && !expectedBooleans.containsKey(key) && !expectedParcelables.containsKey(key) ) { unexpectedAdditionalObjects.put(key, actualBundle.getString(key)); } } return unexpectedAdditionalObjects.isEmpty(); } }