diff --git a/lib/stats/model/average_stat.dart b/lib/stats/model/average_stat.dart index 0ab0f3f..f9d4f85 100644 --- a/lib/stats/model/average_stat.dart +++ b/lib/stats/model/average_stat.dart @@ -3,11 +3,17 @@ import 'package:kubrs_app/solve/utils/duration_formatter.dart'; import 'package:kubrs_app/stats/model/stat.dart'; class AverageStat extends Stat with EquatableMixin { - AverageStat(this._value, this._nbSolves); - AverageStat.empty(this._nbSolves) : _value = null; + AverageStat(this._value, this._nbSolves) : _dnf = false; + AverageStat.empty(this._nbSolves) + : _value = null, + _dnf = false; + AverageStat.dnf(this._nbSolves) + : _value = null, + _dnf = true; final int? _value; final int _nbSolves; + final bool _dnf; @override String getDisplayedName() { @@ -16,6 +22,7 @@ class AverageStat extends Stat with EquatableMixin { @override String getDisplayedValue() { + if (_dnf) return 'DNF'; if (_value == null) return '-'; final duration = Duration(milliseconds: _value!); return DurationFormatter.format(duration); diff --git a/lib/stats/model/best_stat.dart b/lib/stats/model/best_stat.dart index 321e4f8..4db646b 100644 --- a/lib/stats/model/best_stat.dart +++ b/lib/stats/model/best_stat.dart @@ -3,10 +3,16 @@ import 'package:kubrs_app/solve/utils/duration_formatter.dart'; import 'package:kubrs_app/stats/model/stat.dart'; class BestStat extends Stat with EquatableMixin { - BestStat(this._value); - BestStat.empty() : _value = null; + BestStat(this._value) : _dnf = false; + BestStat.empty() + : _value = null, + _dnf = false; + BestStat.dnf() + : _value = null, + _dnf = true; final int? _value; + final bool _dnf; @override String getDisplayedName() { @@ -15,6 +21,7 @@ class BestStat extends Stat with EquatableMixin { @override String getDisplayedValue() { + if (_dnf) return 'DNF'; if (_value == null) return '-'; final duration = Duration(milliseconds: _value!); return DurationFormatter.format(duration); diff --git a/lib/stats/model/mean_stat.dart b/lib/stats/model/mean_stat.dart index 65a4ce5..870342c 100644 --- a/lib/stats/model/mean_stat.dart +++ b/lib/stats/model/mean_stat.dart @@ -3,11 +3,17 @@ import 'package:kubrs_app/solve/utils/duration_formatter.dart'; import 'package:kubrs_app/stats/model/stat.dart'; class MeanStat extends Stat with EquatableMixin { - MeanStat(this._value, this._nbSolves); - MeanStat.empty(this._nbSolves) : _value = null; + MeanStat(this._value, this._nbSolves) : _dnf = false; + MeanStat.empty(this._nbSolves) + : _value = null, + _dnf = false; + MeanStat.dnf(this._nbSolves) + : _value = null, + _dnf = true; final int? _value; final int _nbSolves; + final bool _dnf; @override String getDisplayedName() { @@ -16,6 +22,7 @@ class MeanStat extends Stat with EquatableMixin { @override String getDisplayedValue() { + if (_dnf) return 'DNF'; if (_value == null) return '-'; final duration = Duration(milliseconds: _value!); return DurationFormatter.format(duration); diff --git a/lib/stats/model/worst_stat.dart b/lib/stats/model/worst_stat.dart index 556abcc..cd5d5b2 100644 --- a/lib/stats/model/worst_stat.dart +++ b/lib/stats/model/worst_stat.dart @@ -3,10 +3,16 @@ import 'package:kubrs_app/solve/utils/duration_formatter.dart'; import 'package:kubrs_app/stats/model/stat.dart'; class WorstStat extends Stat with EquatableMixin { - WorstStat(this._value); - WorstStat.empty() : _value = null; + WorstStat(this._value) : _dnf = false; + WorstStat.empty() + : _value = null, + _dnf = false; + WorstStat.dnf() + : _value = null, + _dnf = true; final int? _value; + final bool _dnf; @override String getDisplayedName() { @@ -15,6 +21,7 @@ class WorstStat extends Stat with EquatableMixin { @override String getDisplayedValue() { + if (_dnf) return 'DNF'; if (_value == null) return '-'; final duration = Duration(milliseconds: _value!); return DurationFormatter.format(duration); diff --git a/lib/stats/utils/stats_calculator.dart b/lib/stats/utils/stats_calculator.dart index fad89c6..3d0f749 100644 --- a/lib/stats/utils/stats_calculator.dart +++ b/lib/stats/utils/stats_calculator.dart @@ -9,12 +9,14 @@ import 'package:kubrs_app/stats/model/worst_stat.dart'; class StatsCalculator { static Stat computeBest(List solves) { if (solves.isEmpty) return BestStat.empty(); + if (solves.every((s) => s.dnf)) return BestStat.dnf(); final times = _getTimes(solves); return BestStat(times.min); } static Stat computeWorst(List solves) { if (solves.isEmpty) return WorstStat.empty(); + if (solves.every((s) => s.dnf)) return WorstStat.dnf(); final times = _getTimes(solves); return WorstStat(times.max); } @@ -24,6 +26,7 @@ class StatsCalculator { if (nbSolves <= 0 || nbSolves > solves.length) { return MeanStat.empty(nbSolves); } + if (solves.every((s) => s.dnf)) return MeanStat.dnf(nbSolves); final times = _getTimes(solves.take(nbSolves)); final mean = times.average.round(); return MeanStat(mean, nbSolves); @@ -34,6 +37,7 @@ class StatsCalculator { if (nbSolves <= 0 || nbSolves > solves.length) { return AverageStat.empty(nbSolves); } + if (solves.every((s) => s.dnf)) return AverageStat.dnf(nbSolves); final times = _getTimes(solves.take(nbSolves)); final minTimeIndex = times.indexOf(times.min); times.removeAt(minTimeIndex); diff --git a/test/stats/utils/stats_calculator_test.dart b/test/stats/utils/stats_calculator_test.dart index 4ce9552..4dc3c8d 100644 --- a/test/stats/utils/stats_calculator_test.dart +++ b/test/stats/utils/stats_calculator_test.dart @@ -30,12 +30,19 @@ void main() { _buildSolve(10009), ]; + final dnfSolves = List.generate(5, (_) => _buildDnfSolve()); + group('BestStat', () { test('returns empty best when solves are empty', () { final bestStat = StatsCalculator.computeBest(List.empty()); expect(bestStat, BestStat.empty()); }); + test('returns DNF best when every solve is DNF', () { + final bestStat = StatsCalculator.computeBest(dnfSolves); + expect(bestStat, BestStat.dnf()); + }); + test('computes best with +2 correctly', () { final bestStat = StatsCalculator.computeBest(solvesWithPlusTwo); expect(bestStat, BestStat(7000)); @@ -48,6 +55,11 @@ void main() { expect(worstStat, WorstStat.empty()); }); + test('returns DNF worst when every solve is DNF', () { + final worstStat = StatsCalculator.computeWorst(dnfSolves); + expect(worstStat, WorstStat.dnf()); + }); + test('computes worst with +2 correctly', () { final worstStat = StatsCalculator.computeWorst(solvesWithPlusTwo); expect(worstStat, WorstStat(11000)); @@ -60,6 +72,11 @@ void main() { expect(meanStat, MeanStat.empty(5)); }); + test('returns DNF mean when every solve is DNF', () { + final meanStat = StatsCalculator.computeMean(dnfSolves); + expect(meanStat, MeanStat.dnf(dnfSolves.length)); + }); + test('computes mean with +2 correctly', () { final meanStat = StatsCalculator.computeMean(solvesWithPlusTwo); expect(meanStat, MeanStat(10000, 5)); @@ -82,6 +99,11 @@ void main() { expect(averageStat, AverageStat.empty(5)); }); + test('returns DNF average when every solve is DNF', () { + final averageStat = StatsCalculator.computeAverage(dnfSolves); + expect(averageStat, AverageStat.dnf(dnfSolves.length)); + }); + test('computes average with +2 correctly', () { final averageStat = StatsCalculator.computeAverage(solvesWithPlusTwo); expect(averageStat, AverageStat(10667, 5)); @@ -119,3 +141,13 @@ Solve _buildPlusTwoSolve(int timeInMillis) { plusTwo: true, ); } + +Solve _buildDnfSolve() { + return Solve( + uid: '', + timestamp: DateTime(2000), + time: const Duration(minutes: 10), + scramble: '', + dnf: true, + ); +}