WIP: use Mockito

This commit is contained in:
Daniel Langbein 2025-01-21 13:12:45 +00:00
parent e631d5161e
commit 5ea120013c
Signed by: langfingaz
GPG Key ID: 6C47C753F0823002
3 changed files with 155 additions and 0 deletions

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}