Skip to content
Snippets Groups Projects
MinFourHeapTests.java 8.77 KiB
Newer Older
WinJ's avatar
WinJ committed
package provided;
Winston Jodjana's avatar
Winston Jodjana committed

import cse332.interfaces.worklists.PriorityWorkList;
import cse332.interfaces.worklists.WorkList;
import datastructures.worklists.MinFourHeap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.TimeUnit;

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

public class MinFourHeapTests {
WinJ's avatar
WinJ committed
    private static final int SEED = 42;
Winston Jodjana's avatar
Winston Jodjana committed

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_hasWork_empty_noWork() {
        WorkList<Integer> STUDENT_INT = new MinFourHeap<>(Integer::compareTo);
Winston Jodjana's avatar
Winston Jodjana committed
        assertFalse(STUDENT_INT.hasWork());
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_hasWork_oneElement_hasWork() {
        WorkList<Integer> STUDENT_INT = new MinFourHeap<>(Integer::compareTo);
Winston Jodjana's avatar
Winston Jodjana committed
        STUDENT_INT.add(1);
        assertTrue(STUDENT_INT.hasWork());
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_addNextHasWork_manyElements_noWork() {
        WorkList<Double> STUDENT_DOUBLE = new MinFourHeap<>(Double::compareTo);
Winston Jodjana's avatar
Winston Jodjana committed
        for (int i = 0; i < 1000; i++) {
            STUDENT_DOUBLE.add(Math.random());
        }
        for (int i = 0; i < 1000; i++) {
            STUDENT_DOUBLE.next();
        }
        assertFalse(STUDENT_DOUBLE.hasWork());
    }
    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_peek_fewElements_throwsException() {
        WorkList<Integer> STUDENT_INT = new MinFourHeap<>(Integer::compareTo);
        assertThrows(NoSuchElementException.class, () -> {
            STUDENT_INT.peek();
        });
Winston Jodjana's avatar
Winston Jodjana committed

        addAndRemove(STUDENT_INT, 42, 10);
WinJ's avatar
WinJ committed
        assertThrows(NoSuchElementException.class, () -> {
            STUDENT_INT.peek();
        });
Winston Jodjana's avatar
Winston Jodjana committed
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_next_fewElements_throwsException() {
        WorkList<Integer> STUDENT_INT = new MinFourHeap<>(Integer::compareTo);
        assertThrows(NoSuchElementException.class, () -> {
            STUDENT_INT.next();
        });
Winston Jodjana's avatar
Winston Jodjana committed

        addAndRemove(STUDENT_INT, 42, 10);
WinJ's avatar
WinJ committed
        assertThrows(NoSuchElementException.class, () -> {
            STUDENT_INT.next();
        });
Winston Jodjana's avatar
Winston Jodjana committed
    }
    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_clear_fewElements_empty() {
        WorkList<String> STUDENT_STR = new MinFourHeap<>(String::compareTo);
Winston Jodjana's avatar
Winston Jodjana committed
        addAll(STUDENT_STR, new String[]{"Beware", "the", "Jabberwock", "my", "son!"});

        assertTrue(STUDENT_STR.hasWork());
        assertEquals(5, STUDENT_STR.size());

        STUDENT_STR.clear();
        assertFalse(STUDENT_STR.hasWork());
        assertEquals(0, STUDENT_STR.size());
WinJ's avatar
WinJ committed
        assertThrows(NoSuchElementException.class, () -> {
            STUDENT_STR.peek();
        });
        assertThrows(NoSuchElementException.class, () -> {
            STUDENT_STR.next();
        });
Winston Jodjana's avatar
Winston Jodjana committed
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_addNext_fewElements_correctStructure() {
Winston Jodjana's avatar
Winston Jodjana committed
        PriorityWorkList<String> heap = new MinFourHeap<>(String::compareTo);
        String[] tests = { "a", "b", "c", "d", "e" };
        for (int i = 0; i < 5; i++) {
            String str = tests[i] + "a";
            heap.add(str);
        }

        for (int i = 0; i < 5; i++) {
            String str_heap = heap.next();
            String str = (char) ('a' + i) + "a";
            assertEquals(str, str_heap);
        }
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_addPeekNext_differentOrderings_correctStructure() {
Winston Jodjana's avatar
Winston Jodjana committed
        PriorityWorkList<String> ordered = new MinFourHeap<>(String::compareTo);
        PriorityWorkList<String> reversed = new MinFourHeap<>(String::compareTo);
        PriorityWorkList<String> random = new MinFourHeap<>(String::compareTo);

        addAll(ordered, new String[]{"a", "b", "c", "d", "e"});
        addAll(reversed, new String[]{"e", "d", "c", "b", "a"});
        addAll(random, new String[]{"d", "b", "c", "e", "a"});

        assertTrue(isSame("a", ordered.peek(), reversed.peek(), random.peek()));
        assertTrue(isSame("a", ordered.next(), reversed.next(), random.next()));
        assertTrue(isSame("b", ordered.next(), reversed.next(), random.next()));

        addAll(ordered, new String[] {"a", "a", "b", "c", "z"});
        addAll(reversed, new String[] {"z", "c", "b", "a", "a"});
        addAll(random, new String[] {"c", "z", "a", "b", "a"});

        String[] expected = new String[] {"a", "a", "b", "c", "c", "d", "e", "z"};
        for (String e : expected) {
            assertTrue(isSame(e, ordered.peek(), reversed.peek(), random.peek()));
            assertTrue(isSame(e, ordered.next(), reversed.next(), random.next()));
        }
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_addNext_manyElements_correctStructure() {
Winston Jodjana's avatar
Winston Jodjana committed
        PriorityWorkList<String> heap = new MinFourHeap<>(String::compareTo);
        int n = 10000;

        // Add them
        for (int i = 0; i < n; i++) {
            String str = String.format("%05d", i * 37 % n);
            heap.add(str);
        }
        // Delete them all
        for (int i = 0; i < n; i++) {
            String s = heap.next();
            assertEquals(i , Integer.parseInt(s));
        }
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_customComparator_manyElements_correctStructure() {
        Random RAND = new Random(SEED);
Winston Jodjana's avatar
Winston Jodjana committed
        PriorityWorkList<Coordinate> student = new MinFourHeap<>(Coordinate::compareTo);
        Queue<Coordinate> reference = new PriorityQueue<>();

        for (int i = 0; i < 10000; i++) {
            Coordinate coord = new Coordinate(RAND.nextInt(10000) - 5000, RAND.nextInt(10000) - 5000);
            student.add(coord);
            reference.add(coord);
        }
        assertEquals(reference.size(), student.size());

        while (!reference.isEmpty()) {
            assertEquals(reference.peek() , student.peek());
            assertEquals(reference.remove() , student.next());
        }
    }

    @Test()
    @Timeout(value = 3000, unit = TimeUnit.MILLISECONDS)
WinJ's avatar
WinJ committed
    public void test_addNext_severalElements_correctStructure() {
Winston Jodjana's avatar
Winston Jodjana committed
        PriorityWorkList<Integer> heap = new MinFourHeap<>(Integer::compareTo);
        addAll(heap, new Integer[] {10, 10, 15, 1, 17, 16, 100, 101, 102, 103, 105, 106, 107, 108});

        Object[] heapData = getField(heap, "data");
        String heapStr = Arrays.toString(heapData);
        String heapExp = "[1, 10, 15, 10, 17, 16, 100, 101, 102, 103, 105, 106, 107, 108";

        heap.next();
        heap.next();
        heap.next();

        Object[] heapData2 = getField(heap, "data");
        String heapStr2 = Arrays.toString(heapData2);
        String heapExp2 = "[15, 16, 103, 107, 17, 108, 100, 101, 102, 106, 105,";

        assertTrue(heapStr.contains(heapExp));
        assertTrue(heapStr2.contains(heapExp2));
    }

    public static class Coordinate implements Comparable<Coordinate> {
        private final int x;
        private final int y;

        public Coordinate(int x, int y) {
            this.x = x;
            this.y = y;
        }

        // What exactly this comparable method is doing is somewhat arbitrary.
        public int compareTo(Coordinate other) {
            if (this.x != other.x) {
                return this.x - other.x;
            } else {
                return this.y - other.y;
            }
        }
    }


    private boolean isSame(String... args) {
        String first = args[0];
        for (String arg : args) {
            if (!first.equals(arg)) {
                return false;
            }
        }
        return true;
    }

    protected static <E> void addAll(WorkList<E> worklist, E[] values) {
        for (E value : values) {
            worklist.add(value);
        }
    }

    protected static <E> void addAndRemove(WorkList<E> worklist, E value, int amount) {
        for (int i = 0; i < amount; i++) {
            worklist.add(value);
        }
        for (int i = 0; i < amount; i++) {
            worklist.next();
        }
    }

    protected <T> T getField(Object o, String fieldName) {
        try {
            Field field = o.getClass().getSuperclass().getDeclaredField(fieldName);
            field.setAccessible(true);
            Object f = field.get(o);
            return (T) f;
        } catch (Exception var6) {
            try {
                Field field = o.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Object f = field.get(o);
                return (T) f;
            } catch (Exception var5) {
                return null;
            }
        }
    }
}