blob: 57dd5537c061f7d7b3d4e0840e0bbfdbdf68d4f1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Alexander Kurtakov <akurtako@redhat.com> - Bug 459343
*******************************************************************************/
package org.eclipse.core.tests.internal.watson;
import java.util.Random;
import java.util.Vector;
import org.eclipse.core.internal.watson.*;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
/**
* Framework for running tests on element tree components.
* Supplies convenience methods and some representative element trees.
*/
abstract class TestUtil extends WatsonTest implements IPathConstants {
public TestUtil(String name) {
super(name);
}
static final IElementComparator fComparator = TestElementComparator.getComparator();
/**
* Asserts that the given comparison value has the added
* bit set, and the changed/removed bits blank
*/
static void assertAdded(int compare) {
assertTrue(compare == TestElementComparator.ADDED);
}
/**
* Asserts that the given comparison value has the changed
* bit set, and the added/removed bits blank
*/
static void assertChanged(int compare) {
assertTrue(compare == TestElementComparator.CHANGED);
}
/**
* Asserts that two trees are equal. If they are not
* an AssertionFailedError is thrown.
* @param message the detail message for this assertion
* @param expected the expected value of a tree
* @param actual the actual value of a tree
*/
static protected void assertEqualTrees(String message, ElementTree expected, ElementTree actual) {
assertEqualTrees(message, expected, actual, Path.ROOT, ElementTreeWriter.D_INFINITE);
}
/**
* Asserts that two trees are equal. If they are not
* an AssertionFailedError is thrown.
* @param message the detail message for this assertion
* @param expected the expected value of a tree
* @param actual the actual value of a tree
* @param depth The depth to compare to.
*/
static protected void assertEqualTrees(String message, ElementTree expected, ElementTree actual, int depth) {
assertEqualTrees(message, expected, actual, Path.ROOT, depth);
}
/**
* Asserts that two trees are equal from the given path downwards. If they are not
* an AssertionFailedError is thrown.
* @param message the detail message for this assertion
* @param expected the expected value of a tree
* @param actual the actual value of a tree
*/
static protected void assertEqualTrees(String message, ElementTree expected, ElementTree actual, IPath path) {
assertEqualTrees(message, expected, actual, path, ElementTreeWriter.D_INFINITE);
}
/**
* Asserts that two trees are equal. If they are not
* an AssertionFailedError is thrown.
* @param message the detail message for this assertion
* @param expected the expected value of a tree
* @param actual the actual value of a tree
* @param depth The depth to compare to.
*/
static protected void assertEqualTrees(String msg, ElementTree expected, ElementTree actual, IPath path, int depth) {
/* check node at current path */
assertTrue(msg, expected.includes(path));
assertTrue(msg, actual.includes(path));
assertEquals(msg, expected.getElementData(path), actual.getElementData(path));
if (depth != 0) {
/* get the children */
IPath[] expectedChildren = expected.getChildren(path);
IPath[] actualChildren = actual.getChildren(path);
assertTrue("Number of children", expectedChildren.length == actualChildren.length);
int newDepth = depth;
if (depth != ElementTreeWriter.D_INFINITE) {
--newDepth;
}
for (int i = 0; i < expectedChildren.length; i++) {
assertEquals("children IDs", expectedChildren[i], actualChildren[i]);
assertEqualTrees("Recursive call", expected, actual, expectedChildren[i], newDepth);
}
}
}
/**
* Asserts that the given tree contains all of the given paths
*/
static protected void assertHasPaths(ElementTree tree, IPath[] paths) {
for (int i = 0; i < paths.length; i++) {
assertTrue("assertHasPaths" + i, tree.includes(paths[i]));
}
}
/**
* Asserts that the given comparison value has the changed
* bit set, and the added/removed bits blank
*/
static void assertNoChange(int compare) {
assertTrue(compare == 0);
}
/**
* Asserts that the given tree doesn not contain all of the given paths
*/
static protected void assertNoPaths(ElementTree tree, IPath[] paths) {
for (int i = 0; i < paths.length; i++) {
assertTrue("assertNoPaths: " + paths[i], !tree.includes(paths[i]));
}
}
/**
* Asserts that the given comparison value has the removed
* bit set, and the changed/added bits blank
*/
static void assertRemoved(int compare) {
assertTrue(compare == TestElementComparator.REMOVED);
}
/**
* Asserts that the Test ElementTree has its original structure
*/
static protected void assertTreeStructure(ElementTree tree) {
assertHasPaths(tree, getTreePaths());
IPath[] children = tree.getChildren(Path.ROOT);
assertTrue(children.length == 1);
/* solution children */
children = tree.getChildren(children[0]);
assertTrue(children.length == 2);
assertTrue(tree.getChildren(project1).length == 0);
/* project2 children */
children = tree.getChildren(children[1]);
assertTrue(children.length == 3);
assertTrue(tree.getChildren(file1).length == 0);
assertTrue(tree.getChildren(folder2).length == 0);
/* folder1 children */
children = tree.getChildren(children[1]);
assertTrue(children.length == 3);
assertTrue(tree.getChildren(file2).length == 0);
assertTrue(tree.getChildren(folder4).length == 0);
/* folder3 children */
children = tree.getChildren(children[1]);
assertTrue(children.length == 1);
assertTrue(tree.getChildren(file3).length == 0);
}
static ElementTree createTestElementTree() {
/**
* This is a sample element tree on which tests are performed.
* The Paths in this tree are found in IPathConstants. The tree's
* basic structure is as follows:
* solution
* project1
* project2
* file1
* folder1
* file2
* folder3
* file3
* folder4
* folder2
*/
ElementTree tree = new ElementTree();
tree.createElement(solution, new String("solution"));
tree.createElement(project1, new String("project1"));
tree.createElement(project2, new String("project2"));
tree.createElement(file1, new String("file1"));
tree.createElement(folder1, new String("folder1"));
tree.createElement(folder2, new String("folder2"));
tree.createElement(file2, new String("file2"));
tree.createElement(folder3, new String("folder3"));
tree.createElement(folder4, new String("folder4"));
tree.createElement(file3, new String("file3"));
return tree;
}
/**
* Does several routine operations on the subtree rooted at
* the given path. Opens a new delta after every operation.
* Returns an array of all the intermediary ElementTrees.
*/
static protected ElementTree[] doManyRoutineOperations(ElementTree tree, IPath path) {
Vector<ElementTree> trees = new Vector<>();
trees.addElement(tree);
int repeat = 1;
/* create file elements */
tree = tree.newEmptyDelta();
IPath[] files = getFilePaths(path);
for (IPath file : files) {
Object data = file.toString();
tree.createElement(file, data);
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
}
/* modify the data of all file elements a few times */
for (int i = 0; i < repeat; i++) {
Object data = "data" + i;
for (IPath file : files) {
tree.setElementData(file, data);
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
}
}
/* delete all file elements */
for (IPath file : files) {
tree.deleteElement(file);
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
}
ElementTree[] results = new ElementTree[trees.size()];
trees.copyInto(results);
return results;
}
/**
* Does several routine operations on the subtree rooted at
* the given path. Returns an array of all the intermediary elementtrees.
*/
static protected ElementTree[] doRoutineOperations(ElementTree tree, IPath path) {
Vector<ElementTree> trees = new Vector<>();
trees.addElement(tree);
int repeat = 1;
/* create file elements */
tree = tree.newEmptyDelta();
IPath[] files = getFilePaths(path);
for (IPath file : files) {
Object data = file.toString();
tree.createElement(file, data);
}
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
/* modify the data of all file elements a few times */
for (int i = 0; i < repeat; i++) {
Object data = "data" + i;
for (IPath file : files) {
tree.setElementData(file, data);
}
}
tree.immutable();
trees.addElement(tree);
tree = tree.newEmptyDelta();
/* delete all file elements */
for (IPath file : files) {
tree.deleteElement(file);
}
tree.immutable();
trees.addElement(tree);
ElementTree[] results = new ElementTree[trees.size()];
trees.copyInto(results);
return results;
}
/**
* Returns an element tree comparator
*/
static IElementComparator getComparator() {
return fComparator;
}
/**
* Returns an array of paths below the given path.
*/
static protected IPath[] getFilePaths(IPath project3) {
String[] names = getJavaLangUnits();
IPath[] paths = new IPath[names.length];
for (int i = 0; i < paths.length; i++) {
paths[i] = project3.append(names[i]);
}
return paths;
}
/**
* Returns strings representing javalang classes
*/
static protected String[] getJavaLangUnits() {
return new String[] {"AbstractMethodError.java", "ArithmeticException.java", "ArrayIndexOutOfBoundsException.java", "ArrayStoreException.java", "Boolean.java", "Byte.java", "Character.java", "Class.java", "ClassCastException.java", "ClassCircularityError.java", "ClassFormatError.java", "ClassLoader.java", "ClassNotFoundException.java", "Cloneable.java", "CloneNotSupportedException.java", "Compiler.java", "Double.java", "Error.java",};
}
/**
* Returns the paths for all the elements in the tree in top-down order
*/
static protected IPath[] getTreePaths() {
return new IPath[] {solution, project1, project2, folder1, folder2, folder3, folder4, file1, file2, file3};
}
/**
* Randomly scrambles an array.
*/
static protected void scramble(Object[] first) {
Random random = new Random(System.currentTimeMillis());
final int len = first.length;
for (int i = 0; i < len * 100; i++) {
/* get any array offset */
int off1 = (int) (random.nextFloat() * len);
if (off1 == len) {
continue;
}
/* get another array offset */
int off2 = (int) (random.nextFloat() * len);
if (off2 == len) {
continue;
}
/* switch */
Object temp = first[off1];
first[off1] = first[off2];
first[off2] = temp;
}
}
/**
* Randomly scrambles two arrays, ensuring that both
* arrays undergo the same permutation.
*/
static protected void scramble(Object[] first, Object[] second) {
assertTrue(first.length == second.length);
Random random = new Random(System.currentTimeMillis());
final int len = first.length;
for (int i = 0; i < len * 100; i++) {
/* get any array offset */
int off1 = (int) (random.nextFloat() * len);
if (off1 == len) {
continue;
}
/* get another array offset */
int off2 = (int) (random.nextFloat() * len);
if (off2 == len) {
continue;
}
/* switch */
Object temp = first[off1];
first[off1] = first[off2];
first[off2] = temp;
temp = second[off1];
second[off1] = second[off2];
second[off2] = temp;
}
}
}