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

org.tudalgo.algoutils.reflect.TestUtils Maven / Gradle / Ivy

There is a newer version: 0.9.0
Show newest version
package org.tudalgo.algoutils.reflect;

import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import org.sourcegrade.jagr.api.testing.RuntimeClassLoader;
import org.sourcegrade.jagr.api.testing.extension.TestCycleResolver;
import org.tudalgo.algoutils.tutor.general.Utils;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * A utility class used for JUnit tests which provides reflective access to some properties and
 * assertions.
 * This class is deprecated and will be removed in a future release.
 * Use the new API located in the {@link org.tudalgo.algoutils.tutor.general.reflections} package instead.
 *
 * @author Ruben Deisenroth
 */
@Deprecated(since = "0.7.0", forRemoval = true)
public final class TestUtils {

    /**
     * Don't let anyone instantiate this class.
     */
    private TestUtils() {
    }

    public static final int BRIDGE = 0x00000040;
    public static final int VARARGS = 0x00000080;
    public static final int SYNTHETIC = 0x00001000;
    public static final int ANNOTATION = 0x00002000;
    public static final int ENUM = 0x00004000;
    public static final int MANDATED = 0x00008000;

    /**
     * Tests whether the modifiers are correct.
     *
     * @param expected the expected modifier count
     * @param actual   the actual modifier count
     * @param name     the name of the field to be checked
     */
    public static void assertModifier(final int expected, final int actual, final String name) {
        if (expected < 0) {
            return;
        }
        assertEquals(expected, actual, String.format("Falsche Modifiers für %s! Gefordert: %s Erhalten: %s", name,
            Modifier.toString(expected), Modifier.toString(actual)));
    }

    /**
     * Tests whether the modifiers of a class are correct.
     *
     * @param expected the expected modifier count
     * @param clazz    the class to be checked
     */
    public static void assertModifier(final int expected, final Class clazz) {
        assertModifier(expected, clazz.getModifiers(), "Klasse " + clazz.getName());
    }

    /**
     * Tests whether the modifiers of a method are correct.
     *
     * @param expected the expected modifier count
     * @param method   the method to be checked
     */
    public static void assertModifier(final int expected, final Method method) {
        assertModifier(expected, method.getModifiers(),
            "Methode " + method.getDeclaringClass() + "." + method.getName());
    }

    /**
     * Tests whether the modifiers of a constructor are correct.
     *
     * @param expected    the expected modifier count
     * @param constructor the constructor to be checked
     */
    public static void assertModifier(final int expected, final Constructor constructor) {
        assertModifier(expected, constructor.getModifiers(),
            "Konstruktor " + constructor.getDeclaringClass() + "." + constructor.getName());
    }

    /**
     * Tests whether the modifiers of a field are correct.
     *
     * @param expected the expected modifier count
     * @param attribut the field to be checked
     */
    public static void assertModifier(final int expected, final Field attribut) {
        assertModifier(expected, attribut.getModifiers(),
            "Attribut " + attribut.getDeclaringClass() + "." + attribut.getName());
    }

    /**
     * Calculates the similarity (a number within 0 and 1) between two strings.
     *
     * @param s1 the first string used for the calculation of the similarity
     * @param s2 the second string used for the calculation  of the similarity
     * @return the similarity
     */
    public static double similarity(final String s1, final String s2) {
        String longer = s1;
        String shorter = s2;
        if (s1.length() < s2.length()) {
            longer = s2;
            shorter = s1;
        }
        final int longerLength = longer.length();
        if (longerLength == 0) {
            return 1.0;
            /* both strings are zero length */
        }
        /*
         * // If you have Apache Commons Text, you can use it to calculate the edit
         * distance: LevenshteinDistance levenshteinDistance = new
         * LevenshteinDistance(); return (longerLength -
         * levenshteinDistance.apply(longer, shorter)) / (double) longerLength;
         */
        return (longerLength - editDistance(longer, shorter)) / (double) longerLength;
    }

    /**
     * Calculates the similarity (a number within 0 and 1) between two strings.
     *
     * @param s1 the first string used for the calculation of the similarity
     * @param s2 the second string used for the calculation  of the similarity
     * @return the calculated similarity (a number within 0 and 1) between two strings.
     * @see Levenshtein distance -
     * Java
     */
    public static int editDistance(String s1, String s2) {
        s1 = s1.toLowerCase();
        s2 = s2.toLowerCase();

        final int[] costs = new int[s2.length() + 1];
        for (int i = 0; i <= s1.length(); i++) {
            int lastValue = i;
            for (int j = 0; j <= s2.length(); j++) {
                if (i == 0) {
                    costs[j] = j;
                } else {
                    if (j > 0) {
                        int newValue = costs[j - 1];
                        if (s1.charAt(i - 1) != s2.charAt(j - 1)) {
                            newValue = Math.min(Math.min(newValue, lastValue), costs[j]) + 1;
                        }
                        costs[j - 1] = lastValue;
                        lastValue = newValue;
                    }
                }
            }
            if (i > 0) {
                costs[s2.length()] = lastValue;
            }
        }
        return costs[s2.length()];
    }

    /**
     * Scans all classes accessible from the context class loader which belong to the given package
     * and subpackages.
     *
     * @param packageName The base package name
     * @return the found classes
     * @throws IOException if an I/O Exception occurs
     */
    public static Class[] getClasses(final String packageName) throws IOException {
        final var cycle = TestCycleResolver.getTestCycle();
        if (cycle != null) {
            RuntimeClassLoader classLoader = cycle.getClassLoader();
            // Autograder Run
            return classLoader.getClassNames().stream()
                .filter(name -> name.startsWith(packageName))
                .map(classLoader::loadClass)
                .toArray(Class[]::new);
        } else {
            // Regular Junit Run
            final ClassLoader loader = Thread.currentThread().getContextClassLoader();
            return ClassPath.from(loader).getTopLevelClasses(packageName).stream().map(ClassInfo::load).toArray(Class[]::new);
        }
    }

    /**
     * Returns {@code true} if {@link TestCycleResolver#getTestCycle} does not return {@code null}.
     * This method is deprecated and will be removed in a future release.
     * Use {@link Utils#isJagrRun()} instead.
     *
     * @return {@code true} if {@link TestCycleResolver#getTestCycle} does not return {@code null}
     */
    @Deprecated(since = "0.7.0", forRemoval = true)
    public static boolean isAutograderRun() {
        return TestCycleResolver.getTestCycle() != null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy