From f2d26453ed330e49590194ceda5bc3c5f3b8e822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Sat, 2 Mar 2024 17:01:12 +0100 Subject: [PATCH] Fix calculating average with optional arithmetic average on and no grade with average in second semester (#2448) --- .../ui/modules/grade/GradeAverageProvider.kt | 27 ++++++--- .../modules/grade/GradeAverageProviderTest.kt | 56 +++++++++++++++++-- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt index e8a5fa25..8da59eaf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt @@ -159,7 +159,7 @@ class GradeAverageProvider @Inject constructor( ?.updateModifiers(student, config).orEmpty() (updatedSecondSemesterGrades + updatedFirstSemesterGrades).calcAverage( - config.isOptionalArithmeticAverage + isOptionalArithmeticAverage = config.isOptionalArithmeticAverage, ) } else { secondSemesterSubject.average @@ -173,13 +173,21 @@ class GradeAverageProvider @Inject constructor( config: AverageCalcParams, ): Double { return if (!isAnyVulcanAverage || config.forceAverageCalc) { - val divider = if (secondSemesterSubject.grades.any { it.weightValue > .0 }) 2 else 1 + val isSecondSemesterHasWeightGrade = secondSemesterSubject.grades + .any { it.weightValue > .0 } + val isSecondSemesterHasArithmeticGrade = secondSemesterSubject.grades + .all { it.weightValue == .0 } && config.isOptionalArithmeticAverage + val isSecondSemesterHaveAverage = + isSecondSemesterHasWeightGrade || isSecondSemesterHasArithmeticGrade + + val divider = if (isSecondSemesterHaveAverage) 2 else 1 val secondSemesterAverage = secondSemesterSubject.grades .updateModifiers(student, config) - .calcAverage(config.isOptionalArithmeticAverage) + .calcAverage(isOptionalArithmeticAverage = config.isOptionalArithmeticAverage) val firstSemesterAverage = firstSemesterSubject?.grades ?.updateModifiers(student, config) - ?.calcAverage(config.isOptionalArithmeticAverage) ?: secondSemesterAverage + ?.calcAverage(isOptionalArithmeticAverage = config.isOptionalArithmeticAverage) + ?: secondSemesterAverage (secondSemesterAverage + firstSemesterAverage) / divider } else { @@ -225,7 +233,7 @@ class GradeAverageProvider @Inject constructor( subject = summary.subject, average = if (!isAnyAverage || params.forceAverageCalc) { grades.updateModifiers(student, params) - .calcAverage(params.isOptionalArithmeticAverage) + .calcAverage(isOptionalArithmeticAverage = params.isOptionalArithmeticAverage) } else summary.average, points = summary.pointsSum, summary = summary, @@ -286,8 +294,13 @@ class GradeAverageProvider @Inject constructor( proposedPoints = "", finalPoints = "", pointsSum = "", - average = if (calcAverage) details.updateModifiers(student, params) - .calcAverage(params.isOptionalArithmeticAverage) else .0 + average = when { + calcAverage -> details + .updateModifiers(student, params) + .calcAverage(isOptionalArithmeticAverage = params.isOptionalArithmeticAverage) + + else -> .0 + } ) } } diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt index 6a717f6f..4f0f80fe 100644 --- a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt +++ b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt @@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test @@ -112,8 +113,8 @@ class GradeAverageProviderTest { private val secondGradeWithModifier = listOf( // avg: 3.375 - getGrade(24, "Język polski", 3.0, -0.50), - getGrade(24, "Język polski", 4.0, 0.25) + getGrade(24, "Język polski", 3.0, -0.50, entry = "3-"), + getGrade(24, "Język polski", 4.0, 0.25, entry = "4+") ) private val secondSummariesWithModifier = listOf( @@ -122,8 +123,8 @@ class GradeAverageProviderTest { private val noWeightGrades = listOf( // standard: 0.0, arithmetic: 4.0 - getGrade(22, "Matematyka", 5.0, 0.0, 0.0), - getGrade(22, "Matematyka", 3.0, 0.0, 0.0), + getGrade(22, "Matematyka", 5.0, 0.0, 0.0, "5"), + getGrade(22, "Matematyka", 3.0, 0.0, 0.0, "3"), getGrade(22, "Matematyka", 1.0, 0.0, 0.0, "np.") ) @@ -132,7 +133,7 @@ class GradeAverageProviderTest { ) private val noWeightGradesArithmeticSummary = listOf( - getSummary(23, "Matematyka", 4.0) + getSummary(23, "Matematyka", .0) ) @Before @@ -211,6 +212,51 @@ class GradeAverageProviderTest { ) // from summary: 4,0 } + @Test + fun `calc current semester arithmetic average with no weights in second semester`() = runTest { + every { preferencesRepository.gradeAverageForceCalcFlow } returns flowOf(false) + every { preferencesRepository.isOptionalArithmeticAverageFlow } returns flowOf(true) + every { preferencesRepository.gradeAverageModeFlow } returns flowOf(GradeAverageMode.BOTH_SEMESTERS) + coEvery { + gradeRepository.getGrades( + student = student, + semester = semesters[1], + forceRefresh = true, + ) + } returns resourceFlow { + Triple( + first = noWeightGrades, + second = noWeightGradesArithmeticSummary, + third = emptyList(), + ) + } + coEvery { + gradeRepository.getGrades( + student = student, + semester = semesters[2], + forceRefresh = true, + ) + } returns resourceFlow { + Triple( + first = noWeightGrades, + second = noWeightGradesArithmeticSummary, + third = emptyList(), + ) + } + + val items = gradeAverageProvider.getGradesDetailsWithAverage( + student = student, + semesterId = semesters[2].semesterId, + forceRefresh = true + ).getResult() + + assertEquals( + 4.0, + items.single { it.subject == "Matematyka" }.average, + .0 + ) // from summary: 4,0 + } + @Test fun `calc current semester average with load from cache sequence`() { every { preferencesRepository.gradeAverageForceCalcFlow } returns flowOf(true)