From 3c9e9950c430b93074f403900595654fa119d435 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:42:35 +0200 Subject: [PATCH 1/7] Add and implement: 'Setting a grade weight to a negative number throws an $ArgumentError'. --- .../grades/grades_service/grades_service.dart | 2 ++ app/lib/grades/grades_service/src/term.dart | 3 ++ app/test/grades/grades_test.dart | 34 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/app/lib/grades/grades_service/grades_service.dart b/app/lib/grades/grades_service/grades_service.dart index 023409151..eb04a7f2f 100644 --- a/app/lib/grades/grades_service/grades_service.dart +++ b/app/lib/grades/grades_service/grades_service.dart @@ -758,6 +758,8 @@ class Weight extends Equatable { @override List get props => [asFactor]; + bool get isNegative => asFactor < 0; + const Weight.percent(num percent) : asFactor = percent / 100; const Weight.factor(this.asFactor); static const zero = Weight.factor(0); diff --git a/app/lib/grades/grades_service/src/term.dart b/app/lib/grades/grades_service/src/term.dart index 52a4614ea..066910933 100644 --- a/app/lib/grades/grades_service/src/term.dart +++ b/app/lib/grades/grades_service/src/term.dart @@ -549,6 +549,9 @@ class GradeModel extends Equatable { }) : assert(originalInput is String || originalInput is num); GradeModel changeWeight(Weight weight) { + if (weight.isNegative) { + throw ArgumentError('Weight must be greater than or equal to 0'); + } return copyWith(weight: weight, takenIntoAccount: weight.asFactor > 0); } diff --git a/app/test/grades/grades_test.dart b/app/test/grades/grades_test.dart index 3f102d23a..dc1d735fd 100644 --- a/app/test/grades/grades_test.dart +++ b/app/test/grades/grades_test.dart @@ -302,6 +302,40 @@ void main() { .asDouble, expected); }); + test('Setting a grade weight to a negative number throws an $ArgumentError', + () { + final controller = GradesTestController(); + + final term = termWith( + id: const TermId('term1'), + subjects: [ + subjectWith( + id: const SubjectId('Mathe'), + name: 'Mathe', + weightType: WeightType.perGrade, + grades: [ + gradeWith( + id: const GradeId('grade1'), + value: 1.0, + weight: const Weight.factor(0.2), + ), + ], + ), + ], + ); + controller.createTerm(term); + + expect( + () => controller.changeGradeWeightsForSubject( + termId: const TermId('term1'), + subjectId: const SubjectId('Mathe'), + weights: { + const GradeId('grade1'): const Weight.factor(-0.1), + }, + ), + throwsA(isA()), + ); + }); test( 'grades for a subject will be weighted by the settings in term by default', () { From 13a366e89305d00b9da16fab6e2a15e6c9a19521 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:48:04 +0200 Subject: [PATCH 2/7] Add and implement: 'Setting a grade type weight for a subject to a negative number throws an $ArgumentError' --- app/lib/grades/grades_service/src/term.dart | 3 ++ app/test/grades/grades_test.dart | 39 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/app/lib/grades/grades_service/src/term.dart b/app/lib/grades/grades_service/src/term.dart index 066910933..f7a4d31c3 100644 --- a/app/lib/grades/grades_service/src/term.dart +++ b/app/lib/grades/grades_service/src/term.dart @@ -434,6 +434,9 @@ class SubjectModel extends Equatable { SubjectModel changeGradeTypeWeight(GradeTypeId gradeType, {required Weight weight}) { + if (weight.isNegative) { + throw ArgumentError('Weight must be greater than or equal to 0'); + } return copyWith( gradeTypeWeightings: gradeTypeWeightings.add(gradeType, weight)); } diff --git a/app/test/grades/grades_test.dart b/app/test/grades/grades_test.dart index dc1d735fd..be7b30bf5 100644 --- a/app/test/grades/grades_test.dart +++ b/app/test/grades/grades_test.dart @@ -336,6 +336,45 @@ void main() { throwsA(isA()), ); }); + test( + 'Setting a grade type weight for a subject to a negative number throws an $ArgumentError', + () { + final controller = GradesTestController(); + + final term = termWith( + id: const TermId('term1'), + subjects: [ + subjectWith( + id: const SubjectId('Mathe'), + name: 'Mathe', + weightType: WeightType.perGradeType, + gradeTypeWeights: { + GradeType.presentation.id: const Weight.factor(1), + }, + grades: [ + gradeWith( + id: const GradeId('grade1'), + type: GradeType.presentation.id, + value: 1.0, + weight: const Weight.factor(0.2), + ), + ], + ), + ], + ); + controller.createTerm(term); + + expect( + () => controller.changeTermWeightsForSubject( + termId: const TermId('term1'), + subjectId: const SubjectId('Mathe'), + gradeTypeWeights: { + GradeType.presentation.id: const Weight.factor(-0.1), + }, + ), + throwsA(isA()), + ); + }); test( 'grades for a subject will be weighted by the settings in term by default', () { From 2e472ece2379ae06750581b8d471310bf0976783 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:20:01 +0200 Subject: [PATCH 3/7] Add and implement: 'Setting a grade type weight for a term to a negative number throws an $ArgumentError' --- app/lib/grades/grades_service/src/term.dart | 3 +++ app/test/grades/grades_test.dart | 30 +++++++++++++++++++++ app/test/grades/grades_test_common.dart | 8 ++++++ 3 files changed, 41 insertions(+) diff --git a/app/lib/grades/grades_service/src/term.dart b/app/lib/grades/grades_service/src/term.dart index f7a4d31c3..77fbecb03 100644 --- a/app/lib/grades/grades_service/src/term.dart +++ b/app/lib/grades/grades_service/src/term.dart @@ -152,6 +152,9 @@ class TermModel extends Equatable { TermModel changeWeightingOfGradeType(GradeTypeId type, {required Weight weight}) { + if (weight.isNegative) { + throw ArgumentError('Weight must be greater than or equal to 0'); + } final newWeights = gradeTypeWeightings.add(type, weight); final newSubjects = subjects.map((s) { final newSubject = s.copyWith(gradeTypeWeightingsFromTerm: newWeights); diff --git a/app/test/grades/grades_test.dart b/app/test/grades/grades_test.dart index be7b30bf5..a1f42b499 100644 --- a/app/test/grades/grades_test.dart +++ b/app/test/grades/grades_test.dart @@ -375,6 +375,36 @@ void main() { throwsA(isA()), ); }); + test( + 'Setting a grade type weight for a term to a negative number throws an $ArgumentError', + () { + final controller = GradesTestController(); + + final term = termWith( + id: const TermId('term1'), + gradeTypeWeights: { + GradeType.presentation.id: const Weight.factor(1), + }, + subjects: [ + subjectWith( + grades: [ + gradeWith(type: GradeType.presentation.id, value: 1.0), + ], + ), + ], + ); + controller.createTerm(term); + + expect( + () => controller.changeGradeTypeWeightForTerm( + termId: const TermId('term1'), + gradeTypeWeights: { + GradeType.presentation.id: const Weight.factor(-0.1), + }, + ), + throwsA(isA()), + ); + }); test( 'grades for a subject will be weighted by the settings in term by default', () { diff --git a/app/test/grades/grades_test_common.dart b/app/test/grades/grades_test_common.dart index 6b22334fc..c907bcbfd 100644 --- a/app/test/grades/grades_test_common.dart +++ b/app/test/grades/grades_test_common.dart @@ -193,6 +193,14 @@ class GradesTestController { } } + void changeGradeTypeWeightForTerm( + {required TermId termId, + required Map gradeTypeWeights}) { + for (var e in gradeTypeWeights.entries) { + service.term(termId).changeGradeTypeWeight(e.key, e.value); + } + } + void changeFinalGradeTypeForSubject( {required TermId termId, required SubjectId subjectId, From 0167e86d92ccc18430f2f8380aae95df10d0feb6 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:25:29 +0200 Subject: [PATCH 4/7] Add and implement: 'Setting a subject weight for a term to a negative number throws an $ArgumentError' --- app/lib/grades/grades_service/src/term.dart | 3 +++ app/test/grades/grades_test.dart | 26 +++++++++++++++++++++ app/test/grades/grades_test_common.dart | 8 +++++++ 3 files changed, 37 insertions(+) diff --git a/app/lib/grades/grades_service/src/term.dart b/app/lib/grades/grades_service/src/term.dart index 77fbecb03..d3c85a124 100644 --- a/app/lib/grades/grades_service/src/term.dart +++ b/app/lib/grades/grades_service/src/term.dart @@ -250,6 +250,9 @@ class TermModel extends Equatable { } TermModel changeWeighting(SubjectId id, Weight newWeight) { + if (newWeight.isNegative) { + throw ArgumentError('Weight must be greater than or equal to 0'); + } final subject = subjects.firstWhere((s) => s.id == id); final newSubject = subject.copyWith( weightingForTermGrade: newWeight, diff --git a/app/test/grades/grades_test.dart b/app/test/grades/grades_test.dart index a1f42b499..05e5c3fef 100644 --- a/app/test/grades/grades_test.dart +++ b/app/test/grades/grades_test.dart @@ -405,6 +405,32 @@ void main() { throwsA(isA()), ); }); + test( + 'Setting a subject weight for a term to a negative number throws an $ArgumentError', + () { + final controller = GradesTestController(); + + final term = termWith( + id: const TermId('term1'), + subjects: [ + subjectWith( + id: const SubjectId('Mathe'), + grades: [gradeWith()], + ), + ], + ); + controller.createTerm(term); + + expect( + () => controller.changeTermSubjectWeights( + termId: const TermId('term1'), + subjectWeights: { + const SubjectId('Mathe'): const Weight.factor(-0.1), + }, + ), + throwsA(isA()), + ); + }); test( 'grades for a subject will be weighted by the settings in term by default', () { diff --git a/app/test/grades/grades_test_common.dart b/app/test/grades/grades_test_common.dart index c907bcbfd..5274b5e9f 100644 --- a/app/test/grades/grades_test_common.dart +++ b/app/test/grades/grades_test_common.dart @@ -333,6 +333,14 @@ class GradesTestController { {required TermId termId, required WeightDisplayType weightDisplayType}) { service.term(termId).changeWeightDisplayType(weightDisplayType); } + + void changeTermSubjectWeights( + {required TermId termId, + required Map subjectWeights}) { + for (var e in subjectWeights.entries) { + service.term(termId).subject(e.key).changeWeightForTermGrade(e.value); + } + } } TestTerm termWith({ From 27ef6ca5edfe8dc8de824851956976a1bd69674d Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:56:31 +0200 Subject: [PATCH 5/7] Create and use `NonNegativeWeight` class. --- .../grades/grades_service/grades_service.dart | 11 ++- .../grades_service/src/grades_repository.dart | 23 ++++-- .../src/grades_service_internal.dart | 13 ++-- app/lib/grades/grades_service/src/term.dart | 76 +++++++++++-------- app/test/grades/grades_repository_test.dart | 32 ++++---- 5 files changed, 93 insertions(+), 62 deletions(-) diff --git a/app/lib/grades/grades_service/grades_service.dart b/app/lib/grades/grades_service/grades_service.dart index eb04a7f2f..43ceec4d4 100644 --- a/app/lib/grades/grades_service/grades_service.dart +++ b/app/lib/grades/grades_service/grades_service.dart @@ -752,11 +752,9 @@ class ConnectedCourse extends Equatable { }); } -class Weight extends Equatable { +class Weight { final num asFactor; num get asPercentage => asFactor * 100; - @override - List get props => [asFactor]; bool get isNegative => asFactor < 0; @@ -768,4 +766,11 @@ class Weight extends Equatable { String toString() { return 'Weight($asFactor / $asPercentage%)'; } + + @override + bool operator ==(Object other) => + identical(this, other) || other is Weight && other.asFactor == asFactor; + + @override + int get hashCode => asFactor.hashCode; } diff --git a/app/lib/grades/grades_service/src/grades_repository.dart b/app/lib/grades/grades_service/src/grades_repository.dart index 7f809dc94..7830e56c3 100644 --- a/app/lib/grades/grades_service/src/grades_repository.dart +++ b/app/lib/grades/grades_service/src/grades_repository.dart @@ -205,8 +205,8 @@ class FirestoreGradesStateRepository extends GradesStateRepository { ?.gradeComposition .gradeWeights .map((key, value) => - MapEntry(key, value.toWeight()))[dto.id] ?? - const Weight.factor(1), + MapEntry(key, value.toNonNegativeWeight()))[dto.id] ?? + NonNegativeWeight.factor(1), ); }, ).toIList(); @@ -259,14 +259,16 @@ class FirestoreGradesStateRepository extends GradesStateRepository { isFinalGradeTypeOverridden: termSubject.finalGradeType != subTerm.finalGradeTypeId, gradeTypeWeightings: termSubject.gradeComposition.gradeTypeWeights - .map((key, value) => MapEntry(GradeTypeId(key), value.toWeight())) + .map((key, value) => + MapEntry(GradeTypeId(key), value.toNonNegativeWeight())) .toIMap(), gradeTypeWeightingsFromTerm: subTerm.gradeTypeWeights - .map((key, value) => MapEntry(GradeTypeId(key), value.toWeight())) + .map((key, value) => + MapEntry(GradeTypeId(key), value.toNonNegativeWeight())) .toIMap(), weightingForTermGrade: - subTerm.subjectWeights[subject.id.value]?.toWeight() ?? - const Weight.factor(1), + subTerm.subjectWeights[subject.id.value]?.toNonNegativeWeight() ?? + NonNegativeWeight.factor(1), grades: grades .where((grade) => grade.subjectId == subject.id && grade.termId.value == termId) @@ -295,7 +297,7 @@ class FirestoreGradesStateRepository extends GradesStateRepository { // Change both to num gradeTypeWeightings: dto.gradeTypeWeights .map((key, value) => - MapEntry(GradeTypeId(key), value.toWeight())) + MapEntry(GradeTypeId(key), value.toNonNegativeWeight())) .toIMap(), ), ) @@ -385,6 +387,13 @@ class WeightDto { ); } + NonNegativeWeight toNonNegativeWeight() { + return switch (type) { + _WeightNumberType.factor => NonNegativeWeight.factor(value), + _WeightNumberType.percent => NonNegativeWeight.percent(value), + }; + } + Weight toWeight() { return switch (type) { _WeightNumberType.factor => Weight.factor(value), diff --git a/app/lib/grades/grades_service/src/grades_service_internal.dart b/app/lib/grades/grades_service/src/grades_service_internal.dart index 1c842f58a..aac99512c 100644 --- a/app/lib/grades/grades_service/src/grades_service_internal.dart +++ b/app/lib/grades/grades_service/src/grades_service_internal.dart @@ -216,7 +216,7 @@ class _GradesServiceInternal { newTerm = newTerm.addSubject(subject); } - newTerm = newTerm.changeWeighting(id, weight); + newTerm = newTerm.changeWeighting(id, weight.toNonNegativeWeightOrThrow()); _updateTerm(newTerm); } @@ -234,8 +234,8 @@ class _GradesServiceInternal { required GradeTypeId gradeType, required Weight weight, }) { - final newTerm = _term(termId) - .changeWeightingOfGradeTypeInSubject(id, gradeType, weight); + final newTerm = _term(termId).changeWeightingOfGradeTypeInSubject( + id, gradeType, weight.toNonNegativeWeightOrThrow()); _updateTerm(newTerm); } @@ -326,7 +326,8 @@ class _GradesServiceInternal { .subjects .where((element) => element.grades.any((grade) => grade.id == id)) .first; - final newTerm = _term(termId).changeWeightOfGrade(id, subject.id, weight); + final newTerm = _term(termId).changeWeightOfGrade( + id, subject.id, weight.toNonNegativeWeightOrThrow()); _updateTerm(newTerm); } @@ -341,8 +342,8 @@ class _GradesServiceInternal { {required TermId termId, required GradeTypeId gradeType, required Weight weight}) { - final newTerm = - _term(termId).changeWeightingOfGradeType(gradeType, weight: weight); + final newTerm = _term(termId).changeWeightingOfGradeType(gradeType, + weight: weight.toNonNegativeWeightOrThrow()); _updateTerm(newTerm); } diff --git a/app/lib/grades/grades_service/src/term.dart b/app/lib/grades/grades_service/src/term.dart index d3c85a124..783574209 100644 --- a/app/lib/grades/grades_service/src/term.dart +++ b/app/lib/grades/grades_service/src/term.dart @@ -15,7 +15,7 @@ class TermModel extends Equatable { final TermId id; final DateTime? createdOn; final IList subjects; - final IMap gradeTypeWeightings; + final IMap gradeTypeWeightings; final GradingSystemModel gradingSystem; final GradeTypeId finalGradeType; final bool isActiveTerm; @@ -96,7 +96,7 @@ class TermModel extends Equatable { TermModel _copyWith({ TermId? id, IList? subjects, - IMap? gradeTypeWeightings, + IMap? gradeTypeWeightings, WeightDisplayType? weightDisplayType, GradeTypeId? finalGradeType, bool? isActiveTerm, @@ -151,10 +151,7 @@ class TermModel extends Equatable { } TermModel changeWeightingOfGradeType(GradeTypeId type, - {required Weight weight}) { - if (weight.isNegative) { - throw ArgumentError('Weight must be greater than or equal to 0'); - } + {required NonNegativeWeight weight}) { final newWeights = gradeTypeWeightings.add(type, weight); final newSubjects = subjects.map((s) { final newSubject = s.copyWith(gradeTypeWeightingsFromTerm: newWeights); @@ -239,7 +236,7 @@ class TermModel extends Equatable { gradingSystem: gradingSystem, takenIntoAccount: grade.takeIntoAccount, gradeType: grade.type, - weight: const Weight.factor(1), + weight: NonNegativeWeight.factor(1), title: grade.title, details: grade.details, ); @@ -249,10 +246,7 @@ class TermModel extends Equatable { return subjects.any((s) => s.hasGrade(gradeId)); } - TermModel changeWeighting(SubjectId id, Weight newWeight) { - if (newWeight.isNegative) { - throw ArgumentError('Weight must be greater than or equal to 0'); - } + TermModel changeWeighting(SubjectId id, NonNegativeWeight newWeight) { final subject = subjects.firstWhere((s) => s.id == id); final newSubject = subject.copyWith( weightingForTermGrade: newWeight, @@ -264,7 +258,7 @@ class TermModel extends Equatable { } TermModel changeWeightingOfGradeTypeInSubject( - SubjectId id, GradeTypeId gradeType, Weight weight) { + SubjectId id, GradeTypeId gradeType, NonNegativeWeight weight) { final subject = subjects.firstWhere((s) => s.id == id); final newSubject = subject.changeGradeTypeWeight(gradeType, weight: weight); @@ -284,7 +278,7 @@ class TermModel extends Equatable { } TermModel changeWeightOfGrade( - GradeId id, SubjectId subjectId, Weight weight) { + GradeId id, SubjectId subjectId, NonNegativeWeight weight) { final subject = subjects.firstWhere((s) => s.id == subjectId); final newSubject = subject.copyWith( grades: subject.grades.replaceFirstWhere( @@ -348,9 +342,9 @@ class SubjectModel extends Equatable { final IList grades; final GradeTypeId finalGradeType; final bool isFinalGradeTypeOverridden; - final Weight weightingForTermGrade; - final IMap gradeTypeWeightings; - final IMap gradeTypeWeightingsFromTerm; + final NonNegativeWeight weightingForTermGrade; + final IMap gradeTypeWeightings; + final IMap gradeTypeWeightingsFromTerm; final WeightType weightType; final String abbreviation; final Design design; @@ -391,10 +385,11 @@ class SubjectModel extends Equatable { this.connectedCourses = const IListConst([]), this.isFinalGradeTypeOverridden = false, this.grades = const IListConst([]), - this.weightingForTermGrade = const Weight.factor(1), + NonNegativeWeight? weightingForTermGrade, this.gradeTypeWeightings = const IMapConst({}), this.gradeTypeWeightingsFromTerm = const IMapConst({}), - }) { + }) : weightingForTermGrade = + weightingForTermGrade ?? NonNegativeWeight.factor(1) { gradeVal = _getGradeVal(); } @@ -439,10 +434,7 @@ class SubjectModel extends Equatable { } SubjectModel changeGradeTypeWeight(GradeTypeId gradeType, - {required Weight weight}) { - if (weight.isNegative) { - throw ArgumentError('Weight must be greater than or equal to 0'); - } + {required NonNegativeWeight weight}) { return copyWith( gradeTypeWeightings: gradeTypeWeightings.add(gradeType, weight)); } @@ -476,10 +468,10 @@ class SubjectModel extends Equatable { IList? grades, GradeTypeId? finalGradeType, bool? isFinalGradeTypeOverridden, - Weight? weightingForTermGrade, + NonNegativeWeight? weightingForTermGrade, GradingSystemModel? gradingSystem, - IMap? gradeTypeWeightings, - IMap? gradeTypeWeightingsFromTerm, + IMap? gradeTypeWeightings, + IMap? gradeTypeWeightingsFromTerm, WeightType? weightType, IList? connectedCourses, DateTime? createdOn, @@ -515,7 +507,7 @@ class GradeModel extends Equatable { final GradingSystemModel gradingSystem; final GradeTypeId gradeType; final bool takenIntoAccount; - final Weight weight; + final NonNegativeWeight weight; final Date date; final String title; final String? details; @@ -557,10 +549,7 @@ class GradeModel extends Equatable { this.createdOn, }) : assert(originalInput is String || originalInput is num); - GradeModel changeWeight(Weight weight) { - if (weight.isNegative) { - throw ArgumentError('Weight must be greater than or equal to 0'); - } + GradeModel changeWeight(NonNegativeWeight weight) { return copyWith(weight: weight, takenIntoAccount: weight.asFactor > 0); } @@ -573,7 +562,7 @@ class GradeModel extends Equatable { GradingSystemModel? gradingSystem, GradeTypeId? gradeType, bool? takenIntoAccount, - Weight? weight, + NonNegativeWeight? weight, String? title, String? details, DateTime? createdOn, @@ -596,3 +585,28 @@ class GradeModel extends Equatable { ); } } + +/// A [Weight] that is guaranteed to be non-negative. +/// +/// Used so that we can enforce with the type system that a weight is non-negative +/// This is better than just checking for non-negativity in the code because it +/// makes it impossible to create a negative weight in the first place. +class NonNegativeWeight extends Weight { + NonNegativeWeight.fromWeight(Weight weight) : super.factor(weight.asFactor); + NonNegativeWeight.factor(num factor) : super.factor(factor) { + if (factor < 0) { + throw ArgumentError('Weight must be non-negative'); + } + } + NonNegativeWeight.percent(num percent) : super.percent(percent) { + if (percent < 0) { + throw ArgumentError('Weight must be non-negative'); + } + } +} + +extension on Weight { + NonNegativeWeight toNonNegativeWeightOrThrow() { + return NonNegativeWeight.fromWeight(this); + } +} diff --git a/app/test/grades/grades_repository_test.dart b/app/test/grades/grades_repository_test.dart index b85ca6a4b..37da2d8fc 100644 --- a/app/test/grades/grades_repository_test.dart +++ b/app/test/grades/grades_repository_test.dart @@ -277,14 +277,14 @@ void main() { term0110.changeWeightDisplayType(WeightDisplayType.percent); term0210.changeGradeTypeWeight( - GradeType.vocabularyTest.id, const Weight.factor(1.5)); + GradeType.vocabularyTest.id, NonNegativeWeight.factor(1.5)); term0210.subject(const SubjectId('mathe')) ..changeGradeTypeWeight(const GradeTypeId('my-custom-grade-type'), - const Weight.percent(200)) - ..grade(GradeId('grade-1')).changeWeight(const Weight.factor(0.5)) + NonNegativeWeight.percent(200)) + ..grade(GradeId('grade-1')).changeWeight(NonNegativeWeight.factor(0.5)) ..changeWeightType(WeightType.perGrade) - ..changeWeightForTermGrade(const Weight.percent(250)); + ..changeWeightForTermGrade(NonNegativeWeight.percent(250)); final res = repository.data; @@ -536,7 +536,7 @@ void main() { gradingSystem: GradingSystemModel.zeroToFifteenPoints, gradeType: const GradeTypeId('my-custom-grade-type'), takenIntoAccount: true, - weight: const Weight.factor(0.5), + weight: NonNegativeWeight.factor(0.5), date: Date('2024-10-02'), title: 'hallo', details: 'hello', @@ -555,8 +555,8 @@ void main() { gradingSystem: GradingSystemModel.zeroToFifteenPoints, gradeType: const GradeTypeId('vocabulary-test'), takenIntoAccount: true, - weight: const Weight.factor(1), - // weight: const Weight.factor(0.5), + weight: NonNegativeWeight.factor(1), + // weight: NonNegativeWeight.factor(0.5), // date: Date('2024-10-02'), date: Date('2024-10-03'), title: 'abcdef', @@ -565,13 +565,14 @@ void main() { ]), finalGradeType: const GradeTypeId('school-report-grade'), isFinalGradeTypeOverridden: false, - weightingForTermGrade: const Weight.factor(2.5), + weightingForTermGrade: NonNegativeWeight.factor(2.5), gradeTypeWeightings: IMapConst({ const GradeTypeId('my-custom-grade-type'): - const Weight.factor(2.0) + NonNegativeWeight.factor(2.0) }), gradeTypeWeightingsFromTerm: IMapConst({ - const GradeTypeId('vocabulary-test'): const Weight.factor(1.5) + const GradeTypeId('vocabulary-test'): + NonNegativeWeight.factor(1.5) }), weightType: WeightType.perGrade, abbreviation: 'M', @@ -589,8 +590,9 @@ void main() { ) ], ), - gradeTypeWeightings: IMapConst( - {const GradeTypeId('vocabulary-test'): const Weight.factor(1.5)}), + gradeTypeWeightings: IMapConst({ + const GradeTypeId('vocabulary-test'): NonNegativeWeight.factor(1.5) + }), gradingSystem: GradingSystemModel.zeroToFifteenPoints, finalGradeType: const GradeTypeId('school-report-grade'), isActiveTerm: true, @@ -620,7 +622,7 @@ void main() { gradingSystem: GradingSystemModel.oneToSixWithPlusAndMinus, gradeType: const GradeTypeId('my-custom-grade-type'), takenIntoAccount: false, - weight: const Weight.factor(1), + weight: NonNegativeWeight.factor(1), date: Date('2024-10-16'), title: 'hallo', details: 'ollah', @@ -638,7 +640,7 @@ void main() { gradingSystem: GradingSystemModel.austrianBehaviouralGrades, gradeType: const GradeTypeId('oral-participation'), takenIntoAccount: true, - weight: const Weight.factor(1), + weight: NonNegativeWeight.factor(1), date: Date('2024-10-18'), title: 'Beep boop', details: 'robot noises', @@ -647,7 +649,7 @@ void main() { ), finalGradeType: const GradeTypeId('oral-participation'), isFinalGradeTypeOverridden: true, - weightingForTermGrade: const Weight.factor(1), + weightingForTermGrade: NonNegativeWeight.factor(1), gradeTypeWeightings: const IMapConst({}), gradeTypeWeightingsFromTerm: const IMapConst({}), weightType: WeightType.inheritFromTerm, From 90b74d4e0e8ab10d1dacaac6cd9ea49d465c62d6 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:03:02 +0200 Subject: [PATCH 6/7] Remove redundant code in grades_test.dart --- app/test/grades/grades_test.dart | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/test/grades/grades_test.dart b/app/test/grades/grades_test.dart index 07e4b129b..10f17b06d 100644 --- a/app/test/grades/grades_test.dart +++ b/app/test/grades/grades_test.dart @@ -311,12 +311,10 @@ void main() { subjects: [ subjectWith( id: const SubjectId('Mathe'), - name: 'Mathe', weightType: WeightType.perGrade, grades: [ gradeWith( id: const GradeId('grade1'), - value: 1.0, weight: const Weight.factor(0.2), ), ], @@ -346,18 +344,12 @@ void main() { subjects: [ subjectWith( id: const SubjectId('Mathe'), - name: 'Mathe', weightType: WeightType.perGradeType, gradeTypeWeights: { GradeType.presentation.id: const Weight.factor(1), }, grades: [ - gradeWith( - id: const GradeId('grade1'), - type: GradeType.presentation.id, - value: 1.0, - weight: const Weight.factor(0.2), - ), + gradeWith(type: GradeType.presentation.id), ], ), ], From 1246bbe303ab7217a220e2c90891649d402a6005 Mon Sep 17 00:00:00 2001 From: Jonas Sander <29028262+Jonas-Sander@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:15:32 +0200 Subject: [PATCH 7/7] Fix `NonNegativeWeight.fromWeight` constructor --- app/lib/grades/grades_service/src/term.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/lib/grades/grades_service/src/term.dart b/app/lib/grades/grades_service/src/term.dart index 783574209..453020ac2 100644 --- a/app/lib/grades/grades_service/src/term.dart +++ b/app/lib/grades/grades_service/src/term.dart @@ -592,7 +592,8 @@ class GradeModel extends Equatable { /// This is better than just checking for non-negativity in the code because it /// makes it impossible to create a negative weight in the first place. class NonNegativeWeight extends Weight { - NonNegativeWeight.fromWeight(Weight weight) : super.factor(weight.asFactor); + factory NonNegativeWeight.fromWeight(Weight weight) => + NonNegativeWeight.factor(weight.asFactor); NonNegativeWeight.factor(num factor) : super.factor(factor) { if (factor < 0) { throw ArgumentError('Weight must be non-negative');