cleaned up code and using parameterized tests

This commit is contained in:
Jan-Peter Klein
2023-06-14 16:10:11 +02:00
parent 3120751d3e
commit d680c5812d
4 changed files with 144 additions and 219 deletions
@@ -1,22 +0,0 @@
package org.cryptomator.ui.common;
import com.google.common.io.CharStreams;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
public class HttpHelper {
private HttpHelper(){
throw new IllegalStateException("Utility class");
}
public static String readBody(HttpResponse<InputStream> response) throws IOException {
try (var in = response.body(); var reader = new InputStreamReader(in, StandardCharsets.UTF_8)) {
return CharStreams.toString(reader);
}
}
}
@@ -60,7 +60,7 @@ public class ErrorController implements FxController {
private final Environment environment;
private final BooleanProperty copiedDetails = new SimpleBooleanProperty();
private final BooleanProperty lookUpSolutionVisibility = new SimpleBooleanProperty();
private final BooleanProperty errorSolutionFound = new SimpleBooleanProperty();
private final BooleanProperty isLoadingHttpResponse = new SimpleBooleanProperty();
private ErrorDiscussion matchingErrorDiscussion;
@@ -132,13 +132,13 @@ public class ErrorController implements FxController {
private void loadHttpResponse(HttpResponse<InputStream> response){
if (response.statusCode() == 200) {
Map<String,ErrorDiscussion> map = new Gson().fromJson(
Map<String,ErrorDiscussion> errorDiscussionMap = new Gson().fromJson(
new InputStreamReader(response.body(),StandardCharsets.UTF_8),
new TypeToken<Map<String,ErrorDiscussion>>(){}.getType());
if(map.values().stream().anyMatch(this::isPartialMatchFilter)) {
if(errorDiscussionMap.values().stream().anyMatch(this::isPartialMatchFilter)) {
Comparator<ErrorDiscussion> comp = this::compareExactMatch;
Optional<ErrorDiscussion> value = map.values().stream().min(comp
Optional<ErrorDiscussion> value = errorDiscussionMap.values().stream().min(comp
.thenComparing(this::compareSecondLevelMatch)
.thenComparing(this::compareThirdLevelMatch)
.thenComparing(this::compareIsAnswered)
@@ -146,7 +146,7 @@ public class ErrorController implements FxController {
if(value.isPresent()){
matchingErrorDiscussion = value.get();
lookUpSolutionVisibility.set(true);
errorSolutionFound.set(true);
}
}
}
@@ -156,10 +156,30 @@ public class ErrorController implements FxController {
return errorDiscussion.title.contains(" " + errorCode.methodCode());
}
/**
* Compares two ErrorDiscussion objects based on their upvote counts and returns the result.
*
* @param ed1 The first ErrorDiscussion object.
* @param ed2 The second ErrorDiscussion object.
* @return An integer indicating which ErrorDiscussion object has a higher upvote count:
* - A positive value if ed2 has a higher upvote count than ed1,
* - A negative value if ed1 has a higher upvote count than ed2,
* - Or 0 if both upvote counts are equal.
*/
public int compareUpvoteCount(ErrorDiscussion ed1, ErrorDiscussion ed2) {
return Integer.compare(ed2.upvoteCount, ed1.upvoteCount);
}
/**
* Compares two ErrorDiscussion objects based on their answered status and returns the result.
*
* @param ed1 The first ErrorDiscussion object.
* @param ed2 The second ErrorDiscussion object.
* @return An integer indicating the answered status of the ErrorDiscussion objects:
* - A negative value (-1) if ed1 is considered answered and ed2 is considered unanswered,
* - A positive value (1) if ed1 is considered unanswered and ed2 is considered answered,
* - Or 0 if both ErrorDiscussion objects are considered answered or unanswered.
*/
public int compareIsAnswered(ErrorDiscussion ed1, ErrorDiscussion ed2) {
if (ed1.answer!=null && ed2.answer==null) {
return -1;
@@ -169,6 +189,17 @@ public class ErrorController implements FxController {
return 0;
}
}
/**
* Compares two ErrorDiscussion objects based on the presence of an exact match with the error code in their titles and returns the result.
*
* @param ed1 The first ErrorDiscussion object.
* @param ed2 The second ErrorDiscussion object.
* @return An integer indicating the comparison result based on the presence of an exact match with the error code in the titles:
* - A negative value (-1) if ed1 has an exact match with the error code in the title and ed2 does not have a match,
* - A positive value (1) if ed1 does not have a match and ed2 has an exact match with the error code in the title,
* - Or 0 if both ErrorDiscussion objects either have an exact match or do not have a match with the error code in the titles.
*/
public int compareExactMatch(ErrorDiscussion ed1, ErrorDiscussion ed2) {
if (ed1.title.contains(getErrorCode()) && !ed2.title.contains(getErrorCode())) {
return -1;
@@ -179,6 +210,16 @@ public class ErrorController implements FxController {
}
}
/**
* Compares two ErrorDiscussion objects based on the presence of a second-level match with the error code in their titles and returns the result.
*
* @param ed1 The first ErrorDiscussion object.
* @param ed2 The second ErrorDiscussion object.
* @return An integer indicating the comparison result based on the presence of a second-level match with the error code in the titles:
* - A negative value (-1) if ed1 has a second-level match with the error code in the title and ed2 does not have a match,
* - A positive value (1) if ed1 does not have a match and ed2 has a second-level match with the error code in the title,
* - Or 0 if both ErrorDiscussion objects either have a second-level match or do not have a match with the error code in the titles.
*/
public int compareSecondLevelMatch(ErrorDiscussion ed1, ErrorDiscussion ed2) {
String value = " " + errorCode.methodCode() + ErrorCode.DELIM + errorCode.rootCauseCode();
if (ed1.title.contains(value) && !ed2.title.contains(value)) {
@@ -190,6 +231,16 @@ public class ErrorController implements FxController {
}
}
/**
* Compares two ErrorDiscussion objects based on the presence of a third-level match with the error code in their titles and returns the result.
*
* @param ed1 The first ErrorDiscussion object.
* @param ed2 The second ErrorDiscussion object.
* @return An integer indicating the comparison result based on the presence of a third-level match with the error code in the titles:
* - A negative value (-1) if ed1 has a third-level match with the error code in the title and ed2 does not have a match,
* - A positive value (1) if ed1 does not have a match and ed2 has a third-level match with the error code in the title,
* - Or 0 if both ErrorDiscussion objects either have a third-level match or do not have a match with the error code in the titles.
*/
public int compareThirdLevelMatch(ErrorDiscussion ed1, ErrorDiscussion ed2) {
String value = " " + errorCode.methodCode();
if (ed1.title.contains(value) && !ed2.title.contains(value)) {
@@ -226,12 +277,12 @@ public class ErrorController implements FxController {
return copiedDetails.get();
}
public BooleanProperty lookUpSolutionVisibilityProperty() {
return lookUpSolutionVisibility;
public BooleanProperty errorSolutionFoundProperty() {
return errorSolutionFound;
}
public boolean getLookUpSolutionVisibility() {
return lookUpSolutionVisibility.get();
public boolean getErrorSolutionFound() {
return errorSolutionFound.get();
}
public BooleanProperty isLoadingHttpResponseProperty() {
+5 -5
View File
@@ -34,19 +34,19 @@
<FormattedLabel styleClass="label-extra-large" format="%error.message" arg1="${controller.errorCode}"/>
<FontAwesome5Spinner glyphSize="24" visible="${controller.isLoadingHttpResponse}" managed="${controller.isLoadingHttpResponse}"/>
<VBox visible="${!controller.isLoadingHttpResponse}" managed="${!controller.isLoadingHttpResponse}">
<Label text="%error.existingSolutionDescription" wrapText="true" visible="${controller.lookUpSolutionVisibility}" managed="${controller.lookUpSolutionVisibility}"/>
<Hyperlink styleClass="hyperlink-underline" text="%error.hyperlink.solution" onAction="#showSolution" contentDisplay="LEFT" visible="${controller.lookUpSolutionVisibility}" managed="${controller.lookUpSolutionVisibility}">
<Label text="%error.existingSolutionDescription" wrapText="true" visible="${controller.errorSolutionFound}" managed="${controller.errorSolutionFound}"/>
<Hyperlink styleClass="hyperlink-underline" text="%error.hyperlink.solution" onAction="#showSolution" contentDisplay="LEFT" visible="${controller.errorSolutionFound}" managed="${controller.errorSolutionFound}">
<graphic>
<FontAwesome5IconView glyph="LINK" glyphSize="12"/>
</graphic>
</Hyperlink>
<Label text="%error.description" wrapText="true" visible="${!controller.lookUpSolutionVisibility}" managed="${!controller.lookUpSolutionVisibility}"/>
<Hyperlink styleClass="hyperlink-underline" text="%error.hyperlink.lookup" onAction="#searchError" contentDisplay="LEFT" visible="${!controller.lookUpSolutionVisibility}" managed="${!controller.lookUpSolutionVisibility}">
<Label text="%error.description" wrapText="true" visible="${!controller.errorSolutionFound}" managed="${!controller.errorSolutionFound}"/>
<Hyperlink styleClass="hyperlink-underline" text="%error.hyperlink.lookup" onAction="#searchError" contentDisplay="LEFT" visible="${!controller.errorSolutionFound}" managed="${!controller.errorSolutionFound}">
<graphic>
<FontAwesome5IconView glyph="LINK" glyphSize="12"/>
</graphic>
</Hyperlink>
<Hyperlink styleClass="hyperlink-underline" text="%error.hyperlink.report" onAction="#reportError" contentDisplay="LEFT" visible="${!controller.lookUpSolutionVisibility}" managed="${!controller.lookUpSolutionVisibility}">
<Hyperlink styleClass="hyperlink-underline" text="%error.hyperlink.report" onAction="#reportError" contentDisplay="LEFT" visible="${!controller.errorSolutionFound}" managed="${!controller.errorSolutionFound}">
<graphic>
<FontAwesome5IconView glyph="LINK" glyphSize="12"/>
</graphic>
@@ -4,11 +4,8 @@ import org.cryptomator.common.Environment;
import org.cryptomator.common.ErrorCode;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.Mockito;
import javafx.application.Application;
@@ -54,199 +51,98 @@ class ErrorControllerTest {
return ed;
}
@Test
@DisplayName("If the upvoteCounts of both ErrorDiscussions are equal, it returns 0")
void testCompareUpvoteCount1() {
ErrorDiscussion ed1 = createErrorDiscussion("",10,null);
ErrorDiscussion ed2 = createErrorDiscussion("",10,null);
int result = errorController.compareUpvoteCount(ed1, ed2);
Assertions.assertEquals(0, result);
}
@Test
@DisplayName("If the upvoteCount of the first ErrorDiscussion is greater than the second, it returns < 0.")
void testCompareUpvoteCount2() {
ErrorDiscussion ed1 = createErrorDiscussion("",10,null);
ErrorDiscussion ed2 = createErrorDiscussion("",5,null);
int result = errorController.compareUpvoteCount(ed1, ed2);
Assertions.assertTrue(result < 0);
}
@Test
@DisplayName("If the upvoteCount of the second ErrorDiscussion is greater than the first, it returns > 0.")
void testCompareUpvoteCount3() {
ErrorDiscussion ed1 = createErrorDiscussion("",8,null);
ErrorDiscussion ed2 = createErrorDiscussion("",15,null);
int result = errorController.compareUpvoteCount(ed1, ed2);
Assertions.assertTrue(result > 0);
}
@Test
@DisplayName("If both ErrorDiscussions has an answer, it returns 0.")
void testCompareIsAnswered1() {
ErrorDiscussion ed1 = createErrorDiscussion("",0, new ErrorDiscussion.Answer());
ErrorDiscussion ed2 = createErrorDiscussion("",0, new ErrorDiscussion.Answer());
int result = errorController.compareIsAnswered(ed1,ed2);
Assertions.assertEquals( 0, result);
}
@Test
@DisplayName("If both ErrorDiscussions doesn't have an answer, it returns 0.")
void testCompareIsAnswered2() {
ErrorDiscussion ed1 = createErrorDiscussion("",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("",0, null);
int result = errorController.compareIsAnswered(ed1,ed2);
Assertions.assertEquals(0, result);
}
@Test
@DisplayName("If the first ErrorDiscussion has an answer and the second doesn't, it returns < 0.")
void testCompareIsAnswered3() {
ErrorDiscussion ed1 = createErrorDiscussion("",0, new ErrorDiscussion.Answer());
ErrorDiscussion ed2 = createErrorDiscussion("",0,null);
int result = errorController.compareIsAnswered(ed1,ed2);
Assertions.assertTrue(result < 0);
}
@Test
@DisplayName("If the second ErrorDiscussion has an answer and the first doesn't, it returns > 0.")
void testCompareIsAnswered4() {
ErrorDiscussion ed1 = createErrorDiscussion("",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("",0, new ErrorDiscussion.Answer());
int result = errorController.compareIsAnswered(ed1,ed2);
Assertions.assertTrue(result > 0);
@ParameterizedTest
@CsvSource(textBlock = """
10, 5, -1
8, 15, 1
""")
public void testCompareUpvoteCount1(int leftUpvoteCount, int rightUpvoteCount, int expectedResult) {
var left = createErrorDiscussion("", leftUpvoteCount, null);
var right = createErrorDiscussion("", rightUpvoteCount, null);
int result = errorController.compareUpvoteCount(left, right);
Assertions.assertTrue(result*expectedResult>0);
}
@ParameterizedTest
@ValueSource(strings={"0000:0000:0000","6HU1:12H1:HU7J"})
@DisplayName("If both ErrorDiscussions has a title that contains the full ErrorCode or both doesn't, it returns 0.")
void testCompareExactMatch1(String errorCodeParameter) {
Mockito.when(errorCode.toString()).thenReturn(errorCodeParameter);
ErrorDiscussion ed1 = createErrorDiscussion("Error 0000:0000:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 0000:0000:0000",0, null);
int result = errorController.compareExactMatch(ed1,ed2);
Assertions.assertEquals(0, result);
@CsvSource(textBlock = """
10, 10
""")
public void testCompareUpvoteCount2(int leftUpvoteCount, int rightUpvoteCount) {
var left = createErrorDiscussion("", leftUpvoteCount, null);
var right = createErrorDiscussion("", rightUpvoteCount, null);
int result = errorController.compareUpvoteCount(left, right);
Assertions.assertEquals(0,result);
}
@Test
@DisplayName("If the first ErrorDiscussion has a title that contains the full ErrorCode and the second doesn't, it returns < 0.")
void testCompareExactMatch2() {
@ParameterizedTest
@CsvSource(textBlock = """
false, false, 0
true, true, 0
true, false, -1
false, true, 1
""")
public void testCompareIsAnswered(boolean leftIsAnswered, boolean rightIsAnswered, int expectedResult) {
var answer = new ErrorDiscussion.Answer();
var left = createErrorDiscussion("", 0, leftIsAnswered ? answer : null);
var right = createErrorDiscussion("", 0, rightIsAnswered ? answer : null);
int result = errorController.compareIsAnswered(left, right);
Assertions.assertEquals(expectedResult, result);
}
@ParameterizedTest
@CsvSource(textBlock = """
Error 0000:0000:0000, Error 0000:0000:0000, 0
Error 6HU1:12H1:HU7J, Error 0000:0000:0000, -1
Error 0000:0000:0000, Error 6HU1:12H1:HU7J, 1
""")
public void testCompareExactMatch(String leftTitle, String rightTitle, int expectedResult) {
Mockito.when(errorCode.toString()).thenReturn("6HU1:12H1:HU7J");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:HU7J",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 0000:0000:0000",0, null);
int result = errorController.compareExactMatch(ed1,ed2);
Assertions.assertTrue(result < 0);
}
@Test
@DisplayName("If the second ErrorDiscussion has a title that contains the full ErrorCode and the first doesn't, it returns > 0.")
void testCompareExactMatch3() {
Mockito.when(errorController.getErrorCode()).thenReturn("6HU1:12H1:HU7J");
ErrorDiscussion ed1 = createErrorDiscussion("Error 0000:0000:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HU1:12H1:HU7J",0, null);
int result = errorController.compareExactMatch(ed1,ed2);
Assertions.assertTrue(result > 0);
var left = createErrorDiscussion(leftTitle, 0, null);
var right = createErrorDiscussion(rightTitle, 0,null);
int result = errorController.compareExactMatch(left,right);
Assertions.assertEquals(expectedResult, result);
}
@Nested
public class CompareSecondLevelMatch{
@BeforeEach
void beforeEach(){
Mockito.when(errorCode.methodCode()).thenReturn("6HU1");
Mockito.when(errorCode.rootCauseCode()).thenReturn("12H1");
}
@Test
@DisplayName("If both ErrorDiscussions has a title that contains the first two blocks of the ErrorCode, it returns 0.")
void testCompareSecondLevelMatch1() {
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
int result = errorController.compareSecondLevelMatch(ed1,ed2);
Assertions.assertEquals(0, result);
}
@Test
@DisplayName("If both ErrorDiscussions doesn't have a title that contains the first two blocks of the ErrorCode, it returns 0.")
void testCompareSecondLevelMatch2() {
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU3:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HU1:1221:0000",0, null);
int result = errorController.compareSecondLevelMatch(ed1,ed2);
Assertions.assertEquals(0, result);
}
@Test
@DisplayName("If the first ErrorDiscussion has a title that contains the first two blocks of the ErrorCode and the second doesn't, it returns < 0.")
void testCompareSecondLevelMatch3() {
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HU1:1221:0000",0, null);
int result = errorController.compareSecondLevelMatch(ed1,ed2);
Assertions.assertTrue(result < 0);
}
@Test
@DisplayName("If the second ErrorDiscussion has a title that contains the first two blocks of the ErrorCode and the first doesn't, it returns > 0.")
void testCompareSecondLevelMatch4() {
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:1211:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
int result = errorController.compareSecondLevelMatch(ed1,ed2);
Assertions.assertTrue(result > 0);
}
}
@Test
@DisplayName("If both ErrorDiscussions has a title that contains the first block of the ErrorCode, it returns 0.")
void testCompareThirdLevelMatch1() {
@ParameterizedTest
@CsvSource(textBlock = """
Error 6HU1:12H1:0000, Error 6HU1:12H1:0000, 0
Error 0000:0000:0000, Error 0000:0000:0000, 0
Error 6HU1:12H1:0000, Error 0000:0000:0000, -1
Error 0000:0000:0000, Error 6HU1:12H1:0000, 1
""")
public void testCompareSecondLevelMatch(String leftTitle, String rightTitle, int expectedResult) {
Mockito.when(errorCode.methodCode()).thenReturn("6HU1");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HU1:1211:0000",0, null);
int result = errorController.compareThirdLevelMatch(ed1,ed2);
Assertions.assertEquals(0, result);
Mockito.when(errorCode.rootCauseCode()).thenReturn("12H1");
var left = createErrorDiscussion(leftTitle, 0, null);
var right = createErrorDiscussion(rightTitle, 0,null);
int result = errorController.compareSecondLevelMatch(left,right);
Assertions.assertEquals(expectedResult, result);
}
@Test
@DisplayName("If both ErrorDiscussions doesn't have a title that contains the first block of the ErrorCode, it returns 0.")
void testCompareThirdLevelMatch2() {
@ParameterizedTest
@CsvSource(textBlock = """
Error 6HU1:0000:0000, Error 6HU1:0000:0000, 0
Error 0000:0000:0000, Error 0000:0000:0000, 0
Error 6HU1:0000:0000, Error 0000:0000:0000, -1
Error 0000:0000:0000, Error 6HU1:0000:0000, 1
""")
public void testCompareThirdLevelMatch(String leftTitle, String rightTitle, int expectedResult) {
Mockito.when(errorCode.methodCode()).thenReturn("6HU1");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HUB:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HUA:1211:0000",0, null);
int result = errorController.compareThirdLevelMatch(ed1,ed2);
Assertions.assertEquals(0, result);
var left = createErrorDiscussion(leftTitle, 0, null);
var right = createErrorDiscussion(rightTitle, 0,null);
int result = errorController.compareThirdLevelMatch(left,right);
Assertions.assertEquals(expectedResult, result);
}
@Test
@DisplayName("If the first ErrorDiscussion has a title that contains the first block of the ErrorCode and the second doesn't, it returns < 0.")
void testCompareThirdLevelMatch3() {
@ParameterizedTest
@CsvSource(textBlock = """
Error 6HU1:0000:0000, true
Error 0000:0000:0000, false
""")
public void testIsPartialMatchFilter(String title, boolean expectedResult) {
Mockito.when(errorCode.methodCode()).thenReturn("6HU1");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HUA:1211:0000",0, null);
int result = errorController.compareThirdLevelMatch(ed1,ed2);
Assertions.assertTrue(result < 0);
}
@Test
@DisplayName("If the second ErrorDiscussion has a title that contains the first block of the ErrorCode and the first doesn't, it returns > 0.")
void testCompareThirdLevelMatch4() {
Mockito.when(errorCode.methodCode()).thenReturn("6HUA");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
ErrorDiscussion ed2 = createErrorDiscussion("Error 6HUA:1211:0000",0, null);
int result = errorController.compareThirdLevelMatch(ed1,ed2);
Assertions.assertTrue(result > 0);
}
@Test
@DisplayName("If the title of the ErrorDiscussion contains the first block of the ErrorCode, it returns true.")
void testIsPartialMatchFilter1(){
Mockito.when(errorCode.methodCode()).thenReturn("6HUA");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HUA:12H1:0000",0, null);
boolean result = errorController.isPartialMatchFilter(ed1);
Assertions.assertTrue(result);
}
@Test
@DisplayName("If the title of the ErrorDiscussion doesn't contains the first block of the ErrorCode, it returns false.")
void testIsPartialMatchFilter2(){
Mockito.when(errorCode.methodCode()).thenReturn("6HUA");
ErrorDiscussion ed1 = createErrorDiscussion("Error 6HU1:12H1:0000",0, null);
boolean result = errorController.isPartialMatchFilter(ed1);
Assertions.assertFalse(result);
var ed = createErrorDiscussion(title, 0, null);
boolean result = errorController.isPartialMatchFilter(ed);
Assertions.assertEquals(expectedResult, result);
}
}