diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/LeaderboardService.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/LeaderboardService.java index acd65c41..ee3c2c3e 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/LeaderboardService.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/LeaderboardService.java @@ -161,90 +161,8 @@ private int calculateTotalScore(List reviews, int numberOfIss double totalScore = reviewsByPullRequestId .values() .stream() - .map(pullRequestReviews -> { - // All reviews are for the same pull request - int complexityScore = calculateComplexityScore(pullRequestReviews.get(0).getPullRequest()); - - double approvalWeight = 2.0; - double approvalScore = pullRequestReviews - .stream() - .filter(review -> review.getState() == PullRequestReview.State.APPROVED) - .filter(review -> review.getAuthor().getId() != review.getPullRequest().getAuthor().getId()) - .map(review -> approvalWeight * calculateCodeReviewBonus(review.getComments().size(), complexityScore)) - .reduce(0.0, Double::sum); - - double changesRequestedWeight = 2.5; - double changesRequestedScore = pullRequestReviews - .stream() - .filter(review -> review.getState() == PullRequestReview.State.CHANGES_REQUESTED) - .filter(review -> review.getAuthor().getId() != review.getPullRequest().getAuthor().getId()) - .map(review -> changesRequestedWeight * calculateCodeReviewBonus(review.getComments().size(), complexityScore)) - .reduce(0.0, Double::sum); - - double commentWeight = 1.5; - double commentScore = pullRequestReviews - .stream() - .filter(review -> review.getState() == PullRequestReview.State.COMMENTED || review.getState() == PullRequestReview.State.UNKNOWN) - .filter(review -> review.getAuthor().getId() != review.getPullRequest().getAuthor().getId()) - .map(review -> commentWeight * calculateCodeReviewBonus(review.getComments().size(), complexityScore)) - .reduce(0.0, Double::sum); - - double issueCommentScore = commentWeight * numberOfIssueComments; - - double interactionScore = approvalScore + changesRequestedScore + commentScore + issueCommentScore; - return 10 * interactionScore * complexityScore / (interactionScore + complexityScore); - }) + .map(pullRequestReviews -> ScoringService.calculateReviewScore(pullRequestReviews, numberOfIssueComments)) .reduce(0.0, Double::sum); return (int) Math.ceil(totalScore); } - - /** - * Calculates the complexity score for a given pull request. - * Possible values: 1, 3, 7, 17, 33. - * Taken from the original leaderboard implementation script. - * - * @param pullRequest - * @return score - */ - private int calculateComplexityScore(PullRequest pullRequest) { - Double complexityScore = - ((pullRequest.getChangedFiles() * 3) + - (pullRequest.getCommits() * 0.5) + - pullRequest.getAdditions() + - pullRequest.getDeletions()) / - 10; - if (complexityScore < 10) { - return 1; // Simple - } else if (complexityScore < 50) { - return 3; // Medium - } else if (complexityScore < 100) { - return 7; // Large - } else if (complexityScore < 500) { - return 17; // Huge - } - return 33; // Overly complex - } - - /** - * Calculates the code review bonus for a given number of code comments and complexity score. - * The bonus is a value between 0 and 2. - * Taken from the original leaderboard implementation script. - * - * @param codeComments - * @param complexityScore - * @return bonus - */ - private double calculateCodeReviewBonus(int codeComments, int complexityScore) { - double maxBonus = 2; - - double codeReviewBonus = 1; - if (codeComments < complexityScore) { - // Function goes from 0 at codeComments = 0 to 1 at codeComments = complexityScore - codeReviewBonus += 2 * Math.sqrt(complexityScore) * Math.sqrt(codeComments) / (codeComments + complexityScore); - } else { - // Saturate at 1 - codeReviewBonus += 1; - } - return codeReviewBonus / 2 * maxBonus; - } } diff --git a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/ScoringService.java b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/ScoringService.java index 8c751549..20907aed 100644 --- a/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/ScoringService.java +++ b/server/application-server/src/main/java/de/tum/in/www1/hephaestus/leaderboard/ScoringService.java @@ -13,46 +13,65 @@ public class ScoringService { private static final Logger logger = LoggerFactory.getLogger(ScoringService.class); public static double calculateReviewScore(List pullRequestReviews) { - return ScoringService.calculateReviewScore(pullRequestReviews, 0); + return calculateReviewScore(pullRequestReviews, 0); } public static double calculateReviewScore(List pullRequestReviews, int numberOfIssueComments) { // All reviews are for the same pull request - int complexityScore = ScoringService.calculateComplexityScore(pullRequestReviews.get(0).getPullRequest()); + int complexityScore = calculateComplexityScore(pullRequestReviews.get(0).getPullRequest()); - int approvalReviews = (int) pullRequestReviews + double approvalWeight = 2.0; + double approvalScore = pullRequestReviews .stream() .filter(review -> review.getState() == PullRequestReview.State.APPROVED) - .count(); - int changesRequestedReviews = (int) pullRequestReviews + .filter(review -> review.getAuthor().getId() != review.getPullRequest().getAuthor().getId()) + .map(review -> approvalWeight * calculateCodeReviewBonus(review.getComments().size(), complexityScore)) + .reduce(0.0, Double::sum); + + double changesRequestedWeight = 2.5; + double changesRequestedScore = pullRequestReviews .stream() .filter(review -> review.getState() == PullRequestReview.State.CHANGES_REQUESTED) - .count(); - int commentReviews = (int) pullRequestReviews - .stream() - .filter(review -> review.getState() == PullRequestReview.State.COMMENTED) - .filter(review -> review.getBody() != null) // Only count if there is a comment - .count(); - int unknownReviews = (int) pullRequestReviews - .stream() - .filter(review -> review.getState() == PullRequestReview.State.UNKNOWN) - .filter(review -> review.getBody() != null) // Only count if there is a comment - .count(); + .filter(review -> review.getAuthor().getId() != review.getPullRequest().getAuthor().getId()) + .map(review -> changesRequestedWeight * calculateCodeReviewBonus(review.getComments().size(), complexityScore)) + .reduce(0.0, Double::sum); - int codeComments = pullRequestReviews + double commentWeight = 1.5; + double commentScore = pullRequestReviews .stream() - .map(review -> review.getComments().size()) - .reduce(0, Integer::sum); + .filter(review -> review.getState() == PullRequestReview.State.COMMENTED || review.getState() == PullRequestReview.State.UNKNOWN) + .filter(review -> review.getAuthor().getId() != review.getPullRequest().getAuthor().getId()) + .map(review -> commentWeight * calculateCodeReviewBonus(review.getComments().size(), complexityScore)) + .reduce(0.0, Double::sum); - double interactionScore = - (approvalReviews * 1.5 + - changesRequestedReviews * 2.0 + - (commentReviews + unknownReviews + numberOfIssueComments) + - codeComments * 0.5); + double issueCommentScore = commentWeight * numberOfIssueComments; + + double interactionScore = approvalScore + changesRequestedScore + commentScore + issueCommentScore; + return 10 * interactionScore * complexityScore / (interactionScore + complexityScore); + } - double complexityBonus = 1 + (complexityScore - 1) / 32.0; - return 5 * interactionScore * complexityBonus; + /** + * Calculates the code review bonus for a given number of code comments and complexity score. + * The bonus is a value between 0 and 2. + * Taken from the original leaderboard implementation script. + * + * @param codeComments + * @param complexityScore + * @return bonus + */ + public static double calculateCodeReviewBonus(int codeComments, int complexityScore) { + double maxBonus = 2; + + double codeReviewBonus = 1; + if (codeComments < complexityScore) { + // Function goes from 0 at codeComments = 0 to 1 at codeComments = complexityScore + codeReviewBonus += 2 * Math.sqrt(complexityScore) * Math.sqrt(codeComments) / (codeComments + complexityScore); + } else { + // Saturate at 1 + codeReviewBonus += 1; + } + return codeReviewBonus / 2 * maxBonus; } public static double calculateReviewScore(IssueComment issueComment) { diff --git a/webapp/src/app/user/review-activity-card/review-activity-card.component.html b/webapp/src/app/user/review-activity-card/review-activity-card.component.html index 4af450a0..1e4b8cb9 100644 --- a/webapp/src/app/user/review-activity-card/review-activity-card.component.html +++ b/webapp/src/app/user/review-activity-card/review-activity-card.component.html @@ -18,7 +18,7 @@ {{ this.repositoryName() }} #{{ this.pullRequest()?.number }}
- + +{{ this.score() }}