blob: 9a45c93b6e2395d95a53291821e0074fc1951f51 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2019 Xored Software Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.verifications.tree;
import static java.lang.String.format;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.eclipse.rcptt.verifications.status.StatusFactory;
import org.eclipse.rcptt.verifications.status.TreeItemVerificationError;
public abstract class TreeComparison<T> {
private boolean allowUnmatched;
public TreeComparison(boolean allowUnmatched) {
this.allowUnmatched = allowUnmatched;
}
public List<TreeItemVerificationError> assertNode(TreeNode<T> expected, TreeNode<T> actual) {
List<TreeItemVerificationError> res = compare(expected.payload(), actual.payload());
String name = getName(expected.payload());
if (!res.isEmpty()) {
setPath(res, Collections.<Integer> emptyList(), name);
return res;
}
Collection<? extends TreeNode<T>> childrenE = expected.getChildren();
List<TreeNode<T>> childrenA = new ArrayList<TreeNode<T>>(actual.getChildren());
return assertChildren(childrenE, childrenA, Collections.<Integer> emptyList(), name);
}
private boolean isChildrenCountValid(int expected, int actual) {
if (expected == actual)
return true;
if (!allowUnmatched)
return false;
return actual > expected;
}
public List<TreeItemVerificationError> assertChildren(Collection<? extends TreeNode<T>> childrenExpected,
Collection<? extends TreeNode<T>> childrenActual, List<Integer> itemIndPath, String fullItemPath) {
List<TreeItemVerificationError> rv = new ArrayList<TreeItemVerificationError>();
if (!isChildrenCountValid(childrenExpected.size(), childrenActual.size())) {
rv.add(createError(
format("Different row children amount, expected %d, but was %d", childrenExpected.size(),
childrenActual.size()),
itemIndPath, fullItemPath));
}
Iterator<? extends TreeNode<T>> actualIter = childrenActual.iterator();
int i = 0;
for (TreeNode<T> expectedChild : childrenExpected) {
List<TreeItemVerificationError> firstDifference = null;
TreeNode<T> next = null;
ArrayList<Integer> indPath = new ArrayList<Integer>(itemIndPath.size() + 1);
indPath.addAll(itemIndPath);
indPath.add(i);
String fullPath = fullItemPath + "/" + getName(expectedChild.payload());
while (actualIter.hasNext()) {
next = actualIter.next();
List<TreeItemVerificationError> childRes = compare(expectedChild.payload(), next.payload());
if (childRes.isEmpty()) {
firstDifference = null;
break;
}
if (firstDifference == null)
firstDifference = childRes;
if (!allowUnmatched) {
break;
}
}
if (firstDifference != null) {
setPath(firstDifference, indPath, fullPath);
rv.addAll(firstDifference);
break;
}
if (next == null) {
rv.add(createError(
format("Expected %s, but no more elements left", getName(expectedChild.payload())),
indPath, fullPath));
return rv;
}
if (isChildrenVerificationRequired(expectedChild.payload())) {
Collection<? extends TreeNode<T>> exchildren = expectedChild.getChildren();
rv.addAll(assertChildren(exchildren, next.getChildren(), indPath, fullPath));
}
i++;
}
return rv;
}
public abstract boolean isChildrenVerificationRequired(T expectedChild);
private void setPath(List<TreeItemVerificationError> data, List<Integer> indPath, String fullPath) {
for (TreeItemVerificationError error : data) {
error.getItemIndexPath().addAll(indPath);
error.setItemPath(fullPath);
}
}
private TreeItemVerificationError createError(String firstDifference, List<Integer> indPath, String fullPath) {
TreeItemVerificationError error = StatusFactory.eINSTANCE.createTreeItemVerificationError();
error.setMessage(firstDifference);
error.getItemIndexPath().addAll(indPath);
error.setItemPath(fullPath);
return error;
}
public abstract String getName(T payload);
public abstract List<TreeItemVerificationError> compare(T expected, T actual);
}