package org.threadly.util;
import static org.junit.Assert.*;
import static org.threadly.TestConstants.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.junit.Test;
@SuppressWarnings("javadoc")
public class SortUtilsTest {
private static final int BINARY_SEARCH_RANDOM_SIZE = TEST_QTY * 10;
private static final int INCREMENTAL_SEARCH_COUNT = TEST_QTY * 10;
@Test
public void getInsertionEndIndexTest() {
List<Long> list = new ArrayList<>(10);
assertEquals(0, SortUtils.getInsertionEndIndex(list, 0, true));
assertEquals(0, SortUtils.getInsertionEndIndex(list, 1, true));
assertEquals(0, SortUtils.getInsertionEndIndex(list, 10, true));
list.add(0L);
assertEquals(1, SortUtils.getInsertionEndIndex(list, 0, true));
assertEquals(1, SortUtils.getInsertionEndIndex(list, 1, true));
assertEquals(1, SortUtils.getInsertionEndIndex(list, 10, true));
list.add(0L);
assertEquals(2, SortUtils.getInsertionEndIndex(list, 0, true));
assertEquals(2, SortUtils.getInsertionEndIndex(list, 1, true));
assertEquals(2, SortUtils.getInsertionEndIndex(list, 10, true));
list.add(10L);
assertEquals(2, SortUtils.getInsertionEndIndex(list, 0, true));
assertEquals(2, SortUtils.getInsertionEndIndex(list, 1, true));
assertEquals(3, SortUtils.getInsertionEndIndex(list, 10, true));
list.add(10L);
assertEquals(2, SortUtils.getInsertionEndIndex(list, 0, true));
assertEquals(2, SortUtils.getInsertionEndIndex(list, 1, true));
assertEquals(4, SortUtils.getInsertionEndIndex(list, 10, true));
// do one insert in the middle
list.add(2, 1L);
assertEquals(2, SortUtils.getInsertionEndIndex(list, 0, true));
assertEquals(3, SortUtils.getInsertionEndIndex(list, 1, true));
assertEquals(5, SortUtils.getInsertionEndIndex(list, 10, true));
}
@Test
public void binarySearchTest() {
List<Long> list = new ArrayList<>(BINARY_SEARCH_RANDOM_SIZE + INCREMENTAL_SEARCH_COUNT + 10);
// verify against an empty list
assertEquals(-1, SortUtils.binarySearch(list, 0, true));
assertEquals(-1, SortUtils.binarySearch(list, 0, false));
// add one and verify both contains and missing
list.add(-1L);
assertEquals(-2, SortUtils.binarySearch(list, 0, true));
assertEquals(-2, SortUtils.binarySearch(list, 0, false));
assertEquals(0, SortUtils.binarySearch(list, -1, true));
assertEquals(0, SortUtils.binarySearch(list, -1, false));
// add one more and verify both contains and missing
list.add(10L);
assertEquals(-2, SortUtils.binarySearch(list, 0, true));
assertEquals(-2, SortUtils.binarySearch(list, 0, false));
assertEquals(0, SortUtils.binarySearch(list, -1, true));
assertEquals(0, SortUtils.binarySearch(list, -1, false));
assertEquals(1, SortUtils.binarySearch(list, 10, true));
assertEquals(1, SortUtils.binarySearch(list, 10, false));
// add a duplicate entry and verify both contains and missing
list.add(10L);
assertEquals(-2, SortUtils.binarySearch(list, 0, true));
assertEquals(-2, SortUtils.binarySearch(list, 0, false));
assertEquals(0, SortUtils.binarySearch(list, -1, true));
assertEquals(0, SortUtils.binarySearch(list, -1, false));
long index = SortUtils.binarySearch(list, 10, false);
assertTrue(index == 1 || index == 2);
index = SortUtils.binarySearch(list, 10, true);
assertTrue(index == 1 || index == 2);
// start above previous tests
for (long i = 20; i < INCREMENTAL_SEARCH_COUNT; i++) {
int bsResult = SortUtils.binarySearch(list, i, true);
assertTrue(bsResult < 0); // should not be in list yet
int insertionIndex;
if (bsResult < 0) {
insertionIndex = Math.abs(bsResult) - 1;
} else {
insertionIndex = bsResult;
}
list.add(insertionIndex, i);
assertEquals(insertionIndex, SortUtils.binarySearch(list, i, true));
assertEquals(insertionIndex, SortUtils.binarySearch(list, i, false));
}
Random random = new Random(Clock.lastKnownTimeMillis());
for (int i = 0; i < BINARY_SEARCH_RANDOM_SIZE; i++) {
long testItem = random.nextInt(BINARY_SEARCH_RANDOM_SIZE);
int bsResult = SortUtils.binarySearch(list, testItem, true);
int insertionIndex;
if (bsResult < 0) {
insertionIndex = Math.abs(bsResult) - 1;
} else {
insertionIndex = bsResult;
}
list.add(insertionIndex, testItem);
int raSearch = SortUtils.binarySearch(list, testItem, true);
int nonraSearch = SortUtils.binarySearch(list, testItem, false);
assertTrue(raSearch >= 0);
assertTrue(nonraSearch >= 0);
}
}
}