mirror of
https://gitlab.uni-marburg.de/langbeid/powersort.git
synced 2025-01-21 19:50:35 +01:00
WIP: use Mockito
This commit is contained in:
parent
e631d5161e
commit
5ea120013c
@ -0,0 +1,58 @@
|
|||||||
|
package de.uni_marburg.powersort.FinnSort;
|
||||||
|
|
||||||
|
import de.uni_marburg.powersort.JUnitUtil;
|
||||||
|
import de.uni_marburg.powersort.benchmark.NaturalOrder;
|
||||||
|
import org.junit.jupiter.api.RepeatedTest;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.converter.ConvertWith;
|
||||||
|
import org.junit.jupiter.params.provider.CsvSource;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
public class FasterFinnSortMockitoTest {
|
||||||
|
@ParameterizedTest
|
||||||
|
@CsvSource({
|
||||||
|
"4|5|6|1|2|3",
|
||||||
|
"100|10|11|1|2|3",
|
||||||
|
"100|11|10|3|2|1",
|
||||||
|
"24|25|26|27|28|21|22|23|18|19|20|4|5|6|7|8|9|10|11|12|13|14|15|16|17|3|1|2",
|
||||||
|
})
|
||||||
|
void foo(@ConvertWith(JUnitUtil.IntegerArrayConverter.class) Integer[] a) {
|
||||||
|
printPowers(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printPowers(Object[] a) {
|
||||||
|
FasterFinnSort<Object> ffs = new FasterFinnSort<>(a, NaturalOrder.INSTANCE, null, 0, 0);
|
||||||
|
FasterFinnSort<Object> spiedFfs = spy(ffs);
|
||||||
|
|
||||||
|
// Don't extend short runs with `binarySort()`
|
||||||
|
when(spiedFfs.minRunLength(anyInt())).thenReturn(0);
|
||||||
|
|
||||||
|
// Capture calculated power values.
|
||||||
|
final ResultCaptor<Integer> resultCaptor = new ResultCaptor<>();
|
||||||
|
doAnswer(resultCaptor).when(spiedFfs).power(anyInt(), anyInt());
|
||||||
|
|
||||||
|
|
||||||
|
sort(a, spiedFfs);
|
||||||
|
|
||||||
|
|
||||||
|
List<Integer> calculatedPowers = resultCaptor.getAllValues();
|
||||||
|
System.out.println(Arrays.toString(calculatedPowers.toArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sorts the given array using FasterFinnSort.
|
||||||
|
*/
|
||||||
|
void sort(Object[] a, FasterFinnSort<Object> ffs) {
|
||||||
|
// Don't sort short array with `binarySort()`
|
||||||
|
boolean forcePowersortShortArray = true;
|
||||||
|
|
||||||
|
FasterFinnSortWrapper.sort(a, 0, a.length, NaturalOrder.INSTANCE, null, 0, 0, ffs, forcePowersortShortArray);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package de.uni_marburg.powersort.FinnSort;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import static de.uni_marburg.powersort.FinnSort.FasterFinnSort.MIN_MERGE;
|
||||||
|
import static de.uni_marburg.powersort.FinnSort.FasterFinnSort.binarySort;
|
||||||
|
import static de.uni_marburg.powersort.FinnSort.FasterFinnSort.countRunAndMakeAscending;
|
||||||
|
|
||||||
|
public class FasterFinnSortWrapper {
|
||||||
|
/**
|
||||||
|
* Copy of `FasterFinnSort.java`. Param `ts` has been added to allow dependency injection for testing.
|
||||||
|
*
|
||||||
|
* @param ts: If non-null, the creation of `ts` with `new FasterFinnSort<>(a, c, work, workBase, workLen)` in this methods body is skipped. Instead, the given `ts` is used.
|
||||||
|
*/
|
||||||
|
public static <T> void sort(T[] a, int lo, int hi, Comparator<? super T> c,
|
||||||
|
T[] work, int workBase, int workLen,
|
||||||
|
FasterFinnSort<T> ts, boolean forcePowersortShortArray) {
|
||||||
|
assert c != null && a != null && lo >= 0 && lo <= hi && hi <= a.length;
|
||||||
|
|
||||||
|
int nRemaining = hi - lo;
|
||||||
|
if (nRemaining < 2)
|
||||||
|
return; // Arrays of size 0 and 1 are always sorted
|
||||||
|
|
||||||
|
// If array is small, do a "mini-TimSort" with no merges
|
||||||
|
if (!forcePowersortShortArray && nRemaining < MIN_MERGE) {
|
||||||
|
int initRunLen = countRunAndMakeAscending(a, lo, hi, c);
|
||||||
|
binarySort(a, lo, hi, lo + initRunLen, c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* March over the array once, left to right, finding natural runs,
|
||||||
|
* extending short natural runs to minRun elements, and merging runs
|
||||||
|
* to maintain stack invariant.
|
||||||
|
*/
|
||||||
|
if (ts == null) ts = new FasterFinnSort<>(a, c, work, workBase, workLen);
|
||||||
|
int minRun = ts.minRunLength(nRemaining);
|
||||||
|
System.out.println("minRun: " + minRun);
|
||||||
|
do {
|
||||||
|
// Identify next run
|
||||||
|
int runLen = countRunAndMakeAscending(a, lo, hi, c);
|
||||||
|
System.out.println("runLen: " + runLen);
|
||||||
|
|
||||||
|
// If run is short, extend to min(minRun, nRemaining)
|
||||||
|
if (runLen < minRun) {
|
||||||
|
System.out.println("Extend run of length " + runLen + " to " + Math.min(minRun, nRemaining));
|
||||||
|
int force = nRemaining <= minRun ? nRemaining : minRun;
|
||||||
|
binarySort(a, lo, lo + force, lo + runLen, c);
|
||||||
|
runLen = force;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push run onto pending-run stack, and maybe merge
|
||||||
|
ts.pushRun(lo, runLen, hi - lo);
|
||||||
|
ts.mergeCollapse();
|
||||||
|
|
||||||
|
// Advance to find next run
|
||||||
|
lo += runLen;
|
||||||
|
nRemaining -= runLen;
|
||||||
|
} while (nRemaining != 0);
|
||||||
|
|
||||||
|
// Merge all remaining runs to complete sort
|
||||||
|
assert lo == hi;
|
||||||
|
ts.mergeForceCollapse();
|
||||||
|
assert ts.stackSize == 1;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package de.uni_marburg.powersort.FinnSort;
|
||||||
|
|
||||||
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Source: https://stackoverflow.com/a/25694142/6334421
|
||||||
|
* <p>
|
||||||
|
* Alternative which didn't work: https://github.com/mockito/mockito/issues/2422
|
||||||
|
*/
|
||||||
|
public class ResultCaptor<T> implements Answer {
|
||||||
|
private final List<T> results = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all captured values.
|
||||||
|
*/
|
||||||
|
public List<T> getAllValues() {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T answer(InvocationOnMock invocationOnMock) throws Throwable {
|
||||||
|
T result = (T) invocationOnMock.callRealMethod();
|
||||||
|
results.add(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user