dart format
This commit is contained in:
@@ -8,14 +8,13 @@ CacheableFile _file({
|
||||
bool isDirectory = false,
|
||||
int? size,
|
||||
DateTime? modifiedAt,
|
||||
}) =>
|
||||
CacheableFile(
|
||||
path: '/$name',
|
||||
isDirectory: isDirectory,
|
||||
name: name,
|
||||
size: size,
|
||||
modifiedAt: modifiedAt,
|
||||
);
|
||||
}) => CacheableFile(
|
||||
path: '/$name',
|
||||
isDirectory: isDirectory,
|
||||
name: name,
|
||||
size: size,
|
||||
modifiedAt: modifiedAt,
|
||||
);
|
||||
|
||||
void main() {
|
||||
group('SortOptions.options', () {
|
||||
@@ -55,8 +54,14 @@ void main() {
|
||||
|
||||
test('size comparator orders by file size when both known', () {
|
||||
final cmp = SortOptions.getOption(SortOption.size).compare;
|
||||
expect(cmp(_file(name: 'a', size: 100), _file(name: 'b', size: 200)), lessThan(0));
|
||||
expect(cmp(_file(name: 'a', size: 200), _file(name: 'b', size: 100)), greaterThan(0));
|
||||
expect(
|
||||
cmp(_file(name: 'a', size: 100), _file(name: 'b', size: 200)),
|
||||
lessThan(0),
|
||||
);
|
||||
expect(
|
||||
cmp(_file(name: 'a', size: 200), _file(name: 'b', size: 100)),
|
||||
greaterThan(0),
|
||||
);
|
||||
});
|
||||
|
||||
test('options map contains all enum values exactly once', () {
|
||||
@@ -67,8 +72,16 @@ void main() {
|
||||
group('ListFilesResponse.sortBy', () {
|
||||
final folderA = _file(name: 'A', isDirectory: true);
|
||||
final folderB = _file(name: 'B', isDirectory: true);
|
||||
final fileA = _file(name: 'aaa', size: 100, modifiedAt: DateTime(2026, 1, 1));
|
||||
final fileB = _file(name: 'bbb', size: 50, modifiedAt: DateTime(2026, 5, 1));
|
||||
final fileA = _file(
|
||||
name: 'aaa',
|
||||
size: 100,
|
||||
modifiedAt: DateTime(2026, 1, 1),
|
||||
);
|
||||
final fileB = _file(
|
||||
name: 'bbb',
|
||||
size: 50,
|
||||
modifiedAt: DateTime(2026, 5, 1),
|
||||
);
|
||||
|
||||
// Note: sortBy uses a string-buffer sort + compareTo descending. The actual
|
||||
// list ordering reflects what users see in the file list.
|
||||
@@ -81,7 +94,10 @@ void main() {
|
||||
|
||||
test('foldersToTop=false intermixes folders and files', () {
|
||||
final response = ListFilesResponse({fileA, fileB, folderA, folderB});
|
||||
final sorted = response.sortBy(sortOption: SortOption.name, foldersToTop: false);
|
||||
final sorted = response.sortBy(
|
||||
sortOption: SortOption.name,
|
||||
foldersToTop: false,
|
||||
);
|
||||
final folderPositions = <int>[];
|
||||
for (var i = 0; i < sorted.length; i++) {
|
||||
if (sorted[i].isDirectory) folderPositions.add(i);
|
||||
@@ -94,9 +110,15 @@ void main() {
|
||||
|
||||
test('reversed flips the order within each section', () {
|
||||
final response = ListFilesResponse({fileA, fileB});
|
||||
final asc = response.sortBy(sortOption: SortOption.name, foldersToTop: false);
|
||||
final asc = response.sortBy(
|
||||
sortOption: SortOption.name,
|
||||
foldersToTop: false,
|
||||
);
|
||||
final desc = response.sortBy(
|
||||
sortOption: SortOption.name, foldersToTop: false, reversed: true);
|
||||
sortOption: SortOption.name,
|
||||
foldersToTop: false,
|
||||
reversed: true,
|
||||
);
|
||||
expect(desc, asc.reversed.toList());
|
||||
});
|
||||
|
||||
|
||||
@@ -7,15 +7,14 @@ MarianumDate _event({
|
||||
required DateTime start,
|
||||
required DateTime end,
|
||||
bool isAllDay = false,
|
||||
}) =>
|
||||
MarianumDate(
|
||||
uid: 't',
|
||||
title: 't',
|
||||
description: null,
|
||||
start: start,
|
||||
end: end,
|
||||
isAllDay: isAllDay,
|
||||
);
|
||||
}) => MarianumDate(
|
||||
uid: 't',
|
||||
title: 't',
|
||||
description: null,
|
||||
start: start,
|
||||
end: end,
|
||||
isAllDay: isAllDay,
|
||||
);
|
||||
|
||||
void main() {
|
||||
setUpAll(() async {
|
||||
@@ -66,23 +65,32 @@ void main() {
|
||||
expect(EventFormatter.longRange(e), '08.05.2026 · Ganztägig');
|
||||
});
|
||||
|
||||
test('all-day multi-day shows inclusive end (one day before exclusive end)', () {
|
||||
final e = _event(
|
||||
start: DateTime(2026, 5, 8),
|
||||
end: DateTime(2026, 5, 11), // exclusive → display "until 10.05."
|
||||
isAllDay: true,
|
||||
);
|
||||
expect(EventFormatter.longRange(e), '08.05.2026 – 10.05.2026 · Ganztägig');
|
||||
});
|
||||
test(
|
||||
'all-day multi-day shows inclusive end (one day before exclusive end)',
|
||||
() {
|
||||
final e = _event(
|
||||
start: DateTime(2026, 5, 8),
|
||||
end: DateTime(2026, 5, 11), // exclusive → display "until 10.05."
|
||||
isAllDay: true,
|
||||
);
|
||||
expect(
|
||||
EventFormatter.longRange(e),
|
||||
'08.05.2026 – 10.05.2026 · Ganztägig',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test('all-day event whose end equals start (degenerate) renders as single day', () {
|
||||
final e = _event(
|
||||
start: DateTime(2026, 5, 8),
|
||||
end: DateTime(2026, 5, 8),
|
||||
isAllDay: true,
|
||||
);
|
||||
expect(EventFormatter.longRange(e), '08.05.2026 · Ganztägig');
|
||||
});
|
||||
test(
|
||||
'all-day event whose end equals start (degenerate) renders as single day',
|
||||
() {
|
||||
final e = _event(
|
||||
start: DateTime(2026, 5, 8),
|
||||
end: DateTime(2026, 5, 8),
|
||||
isAllDay: true,
|
||||
);
|
||||
expect(EventFormatter.longRange(e), '08.05.2026 · Ganztägig');
|
||||
},
|
||||
);
|
||||
|
||||
test('zero-length same-day timed event shows single time', () {
|
||||
final at = DateTime(2026, 5, 8, 9, 30);
|
||||
@@ -103,7 +111,10 @@ void main() {
|
||||
start: DateTime(2026, 5, 8, 9),
|
||||
end: DateTime(2026, 5, 9, 11),
|
||||
);
|
||||
expect(EventFormatter.longRange(e), '08.05.2026 09:00 – 09.05.2026 11:00');
|
||||
expect(
|
||||
EventFormatter.longRange(e),
|
||||
'08.05.2026 09:00 – 09.05.2026 11:00',
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -17,18 +17,18 @@ Appointment _appt({
|
||||
bool isAllDay = false,
|
||||
Object? id,
|
||||
String? rrule,
|
||||
}) =>
|
||||
Appointment(
|
||||
id: id,
|
||||
startTime: start,
|
||||
endTime: end,
|
||||
subject: subject,
|
||||
color: Colors.blue,
|
||||
isAllDay: isAllDay,
|
||||
recurrenceRule: rrule,
|
||||
);
|
||||
}) => Appointment(
|
||||
id: id,
|
||||
startTime: start,
|
||||
endTime: end,
|
||||
subject: subject,
|
||||
color: Colors.blue,
|
||||
isAllDay: isAllDay,
|
||||
recurrenceRule: rrule,
|
||||
);
|
||||
|
||||
GetTimetableResponseObject _lesson({String? code}) => GetTimetableResponseObject(
|
||||
GetTimetableResponseObject _lesson({String? code}) =>
|
||||
GetTimetableResponseObject(
|
||||
id: 0,
|
||||
date: 0,
|
||||
startTime: 0,
|
||||
@@ -41,21 +41,25 @@ GetTimetableResponseObject _lesson({String? code}) => GetTimetableResponseObject
|
||||
);
|
||||
|
||||
CustomTimetableEvent _customEvent() => CustomTimetableEvent(
|
||||
id: 'x',
|
||||
title: '',
|
||||
description: '',
|
||||
startDate: DateTime(2026),
|
||||
endDate: DateTime(2026),
|
||||
color: null,
|
||||
rrule: '',
|
||||
createdAt: DateTime(2026),
|
||||
updatedAt: DateTime(2026),
|
||||
);
|
||||
id: 'x',
|
||||
title: '',
|
||||
description: '',
|
||||
startDate: DateTime(2026),
|
||||
endDate: DateTime(2026),
|
||||
color: null,
|
||||
rrule: '',
|
||||
createdAt: DateTime(2026),
|
||||
updatedAt: DateTime(2026),
|
||||
);
|
||||
|
||||
void main() {
|
||||
group('isAllDayLike', () {
|
||||
test('explicit isAllDay flag wins', () {
|
||||
final a = _appt(start: _at(2026, 5, 8, 9), end: _at(2026, 5, 8, 10), isAllDay: true);
|
||||
final a = _appt(
|
||||
start: _at(2026, 5, 8, 9),
|
||||
end: _at(2026, 5, 8, 10),
|
||||
isAllDay: true,
|
||||
);
|
||||
expect(isAllDayLike(a), isTrue);
|
||||
});
|
||||
|
||||
@@ -69,11 +73,20 @@ void main() {
|
||||
expect(isAllDayLike(a), isTrue);
|
||||
});
|
||||
|
||||
test('Duration.inHours truncation does not let a 9h 30min event escape', () {
|
||||
final a = _appt(start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 17, 30));
|
||||
expect(isAllDayLike(a), isTrue,
|
||||
reason: 'inHours would say 9; we compare in minutes (570 ≥ 480)');
|
||||
});
|
||||
test(
|
||||
'Duration.inHours truncation does not let a 9h 30min event escape',
|
||||
() {
|
||||
final a = _appt(
|
||||
start: _at(2026, 5, 8, 8),
|
||||
end: _at(2026, 5, 8, 17, 30),
|
||||
);
|
||||
expect(
|
||||
isAllDayLike(a),
|
||||
isTrue,
|
||||
reason: 'inHours would say 9; we compare in minutes (570 ≥ 480)',
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('isOutsideSchoolHours', () {
|
||||
@@ -85,7 +98,11 @@ void main() {
|
||||
});
|
||||
|
||||
test('all-day-like events are always outside', () {
|
||||
final a = _appt(start: _at(2026, 5, 8, 9), end: _at(2026, 5, 8, 10), isAllDay: true);
|
||||
final a = _appt(
|
||||
start: _at(2026, 5, 8, 9),
|
||||
end: _at(2026, 5, 8, 10),
|
||||
isAllDay: true,
|
||||
);
|
||||
expect(isOutsideSchoolHours(a), isTrue);
|
||||
});
|
||||
|
||||
@@ -120,7 +137,9 @@ void main() {
|
||||
|
||||
test('single non-recurring lesson lands in the right day bucket', () {
|
||||
final wednesday9 = _appt(
|
||||
start: _at(2026, 5, 6, 9), end: _at(2026, 5, 6, 10));
|
||||
start: _at(2026, 5, 6, 9),
|
||||
end: _at(2026, 5, 6, 10),
|
||||
);
|
||||
final result = partitionAppointmentsForWeek([wednesday9], monday);
|
||||
expect(result.inside[0], isEmpty);
|
||||
expect(result.inside[1], isEmpty);
|
||||
@@ -131,9 +150,10 @@ void main() {
|
||||
|
||||
test('all-day events go to the outside bucket on their day', () {
|
||||
final tuesdayAllDay = _appt(
|
||||
start: _at(2026, 5, 5),
|
||||
end: _at(2026, 5, 6),
|
||||
isAllDay: true);
|
||||
start: _at(2026, 5, 5),
|
||||
end: _at(2026, 5, 6),
|
||||
isAllDay: true,
|
||||
);
|
||||
final result = partitionAppointmentsForWeek([tuesdayAllDay], monday);
|
||||
expect(result.inside.expand((e) => e), isEmpty);
|
||||
expect(result.outside[1], hasLength(1));
|
||||
@@ -141,9 +161,13 @@ void main() {
|
||||
|
||||
test('events outside the visible week are dropped', () {
|
||||
final lastWeek = _appt(
|
||||
start: _at(2026, 4, 27, 9), end: _at(2026, 4, 27, 10));
|
||||
start: _at(2026, 4, 27, 9),
|
||||
end: _at(2026, 4, 27, 10),
|
||||
);
|
||||
final nextWeek = _appt(
|
||||
start: _at(2026, 5, 11, 9), end: _at(2026, 5, 11, 10));
|
||||
start: _at(2026, 5, 11, 9),
|
||||
end: _at(2026, 5, 11, 10),
|
||||
);
|
||||
final result = partitionAppointmentsForWeek([lastWeek, nextWeek], monday);
|
||||
expect(result.inside.expand((e) => e), isEmpty);
|
||||
expect(result.outside.expand((e) => e), isEmpty);
|
||||
@@ -151,7 +175,9 @@ void main() {
|
||||
|
||||
test('weekend events (Sat/Sun) are dropped, only Mon–Fri counted', () {
|
||||
final saturday = _appt(
|
||||
start: _at(2026, 5, 9, 9), end: _at(2026, 5, 9, 10));
|
||||
start: _at(2026, 5, 9, 9),
|
||||
end: _at(2026, 5, 9, 10),
|
||||
);
|
||||
final result = partitionAppointmentsForWeek([saturday], monday);
|
||||
expect(result.inside.expand((e) => e), isEmpty);
|
||||
});
|
||||
@@ -160,20 +186,25 @@ void main() {
|
||||
// Anchor on the Monday before our visible week, repeating weekly.
|
||||
// The visible week's Monday should produce one occurrence.
|
||||
final anchor = _appt(
|
||||
start: _at(2026, 4, 27, 9),
|
||||
end: _at(2026, 4, 27, 10),
|
||||
rrule: 'RRULE:FREQ=WEEKLY;BYDAY=MO');
|
||||
start: _at(2026, 4, 27, 9),
|
||||
end: _at(2026, 4, 27, 10),
|
||||
rrule: 'RRULE:FREQ=WEEKLY;BYDAY=MO',
|
||||
);
|
||||
final result = partitionAppointmentsForWeek([anchor], monday);
|
||||
expect(result.inside[0], hasLength(1),
|
||||
reason: 'Monday of the visible week should get one expansion');
|
||||
expect(
|
||||
result.inside[0],
|
||||
hasLength(1),
|
||||
reason: 'Monday of the visible week should get one expansion',
|
||||
);
|
||||
expect(result.inside[0].first.startTime, _at(2026, 5, 4, 9));
|
||||
});
|
||||
|
||||
test('malformed RRULE falls back to placing the anchor', () {
|
||||
final broken = _appt(
|
||||
start: _at(2026, 5, 6, 9),
|
||||
end: _at(2026, 5, 6, 10),
|
||||
rrule: 'this is not a valid rrule');
|
||||
start: _at(2026, 5, 6, 9),
|
||||
end: _at(2026, 5, 6, 10),
|
||||
rrule: 'this is not a valid rrule',
|
||||
);
|
||||
final result = partitionAppointmentsForWeek([broken], monday);
|
||||
expect(result.inside[2], hasLength(1));
|
||||
});
|
||||
@@ -181,16 +212,21 @@ void main() {
|
||||
|
||||
group('PeriodLayout', () {
|
||||
final p1 = const LessonPeriod(
|
||||
name: '1', start: TimeOfDay(hour: 8, minute: 0), end: TimeOfDay(hour: 9, minute: 0));
|
||||
name: '1',
|
||||
start: TimeOfDay(hour: 8, minute: 0),
|
||||
end: TimeOfDay(hour: 9, minute: 0),
|
||||
);
|
||||
final brk = const LessonPeriod(
|
||||
name: 'Pause',
|
||||
start: TimeOfDay(hour: 9, minute: 0),
|
||||
end: TimeOfDay(hour: 9, minute: 15),
|
||||
isBreak: true);
|
||||
name: 'Pause',
|
||||
start: TimeOfDay(hour: 9, minute: 0),
|
||||
end: TimeOfDay(hour: 9, minute: 15),
|
||||
isBreak: true,
|
||||
);
|
||||
final p2 = const LessonPeriod(
|
||||
name: '2',
|
||||
start: TimeOfDay(hour: 9, minute: 15),
|
||||
end: TimeOfDay(hour: 10, minute: 15));
|
||||
name: '2',
|
||||
start: TimeOfDay(hour: 9, minute: 15),
|
||||
end: TimeOfDay(hour: 10, minute: 15),
|
||||
);
|
||||
|
||||
final layout = PeriodLayout(
|
||||
periods: [p1, brk, p2],
|
||||
@@ -249,7 +285,11 @@ void main() {
|
||||
expect(result, hasLength(2));
|
||||
for (final cell in result) {
|
||||
expect(cell.lane, 0);
|
||||
expect(cell.laneCount, 1, reason: 'separate clusters → laneCount=1 each');
|
||||
expect(
|
||||
cell.laneCount,
|
||||
1,
|
||||
reason: 'separate clusters → laneCount=1 each',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -262,85 +302,121 @@ void main() {
|
||||
expect(result.every((c) => c.laneCount == 2), isTrue);
|
||||
});
|
||||
|
||||
test('three overlapping appointments with maxLanes=2 collapse the third into overflow', () {
|
||||
final a = _appt(start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 11));
|
||||
final b = _appt(start: _at(2026, 5, 8, 9), end: _at(2026, 5, 8, 11));
|
||||
final c = _appt(start: _at(2026, 5, 8, 10), end: _at(2026, 5, 8, 11));
|
||||
final result = assignLanes([a, b, c], maxLanes: 2);
|
||||
test(
|
||||
'three overlapping appointments with maxLanes=2 collapse the third into overflow',
|
||||
() {
|
||||
final a = _appt(start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 11));
|
||||
final b = _appt(start: _at(2026, 5, 8, 9), end: _at(2026, 5, 8, 11));
|
||||
final c = _appt(start: _at(2026, 5, 8, 10), end: _at(2026, 5, 8, 11));
|
||||
final result = assignLanes([a, b, c], maxLanes: 2);
|
||||
|
||||
final visible = result.whereType<LaidOutAppointment>().toList();
|
||||
final overflow = result.whereType<LaidOutOverflow>().toList();
|
||||
expect(visible, hasLength(1), reason: 'maxLanes-1 = 1 visible appointment');
|
||||
expect(overflow, hasLength(1));
|
||||
expect(overflow.first.appointments, hasLength(2));
|
||||
expect(overflow.first.lane, 1);
|
||||
expect(overflow.first.laneCount, 2);
|
||||
});
|
||||
final visible = result.whereType<LaidOutAppointment>().toList();
|
||||
final overflow = result.whereType<LaidOutOverflow>().toList();
|
||||
expect(
|
||||
visible,
|
||||
hasLength(1),
|
||||
reason: 'maxLanes-1 = 1 visible appointment',
|
||||
);
|
||||
expect(overflow, hasLength(1));
|
||||
expect(overflow.first.appointments, hasLength(2));
|
||||
expect(overflow.first.lane, 1);
|
||||
expect(overflow.first.laneCount, 2);
|
||||
},
|
||||
);
|
||||
|
||||
test('CustomAppointment beats a regular lesson on lane priority', () {
|
||||
final custom = _appt(
|
||||
id: CustomAppointment(_customEvent()),
|
||||
start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 10),
|
||||
start: _at(2026, 5, 8, 8),
|
||||
end: _at(2026, 5, 8, 10),
|
||||
);
|
||||
final regular = _appt(
|
||||
id: WebuntisAppointment(_lesson()),
|
||||
start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 10),
|
||||
start: _at(2026, 5, 8, 8),
|
||||
end: _at(2026, 5, 8, 10),
|
||||
);
|
||||
|
||||
final result = assignLanes([regular, custom], maxLanes: 2)
|
||||
.whereType<LaidOutAppointment>()
|
||||
.toList();
|
||||
final result = assignLanes([
|
||||
regular,
|
||||
custom,
|
||||
], maxLanes: 2).whereType<LaidOutAppointment>().toList();
|
||||
// Same startTime → priority decides: custom (0) goes left of regular (2).
|
||||
final customCell = result.firstWhere((c) => c.appointment.id is CustomAppointment);
|
||||
final regularCell = result.firstWhere((c) => c.appointment.id is WebuntisAppointment);
|
||||
final customCell = result.firstWhere(
|
||||
(c) => c.appointment.id is CustomAppointment,
|
||||
);
|
||||
final regularCell = result.firstWhere(
|
||||
(c) => c.appointment.id is WebuntisAppointment,
|
||||
);
|
||||
expect(customCell.lane, lessThan(regularCell.lane));
|
||||
});
|
||||
|
||||
test('cancelled lesson lands left of a non-cancelled one on tie', () {
|
||||
final cancelled = _appt(
|
||||
id: WebuntisAppointment(_lesson(code: 'cancelled')),
|
||||
start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 10),
|
||||
start: _at(2026, 5, 8, 8),
|
||||
end: _at(2026, 5, 8, 10),
|
||||
);
|
||||
final regular = _appt(
|
||||
id: WebuntisAppointment(_lesson()),
|
||||
start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 10),
|
||||
start: _at(2026, 5, 8, 8),
|
||||
end: _at(2026, 5, 8, 10),
|
||||
);
|
||||
|
||||
final result = assignLanes([regular, cancelled], maxLanes: 2)
|
||||
.whereType<LaidOutAppointment>()
|
||||
.toList();
|
||||
final result = assignLanes([
|
||||
regular,
|
||||
cancelled,
|
||||
], maxLanes: 2).whereType<LaidOutAppointment>().toList();
|
||||
String? codeOf(LaidOutAppointment c) {
|
||||
final id = c.appointment.id;
|
||||
return id is WebuntisAppointment ? id.lesson.code : null;
|
||||
}
|
||||
|
||||
final cancelledCell = result.firstWhere((c) => codeOf(c) == 'cancelled');
|
||||
final regularCell = result.firstWhere((c) => codeOf(c) == null);
|
||||
expect(cancelledCell.lane, lessThan(regularCell.lane));
|
||||
});
|
||||
|
||||
test('overflow time-range spans earliest start to latest end of collapsed appointments', () {
|
||||
// 4 overlapping appointments, maxLanes = 2 → 1 visible + overflow of 3.
|
||||
final a = _appt(start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 12));
|
||||
final b = _appt(start: _at(2026, 5, 8, 9), end: _at(2026, 5, 8, 10));
|
||||
final c = _appt(start: _at(2026, 5, 8, 9, 30), end: _at(2026, 5, 8, 14));
|
||||
final d = _appt(start: _at(2026, 5, 8, 10), end: _at(2026, 5, 8, 11));
|
||||
test(
|
||||
'overflow time-range spans earliest start to latest end of collapsed appointments',
|
||||
() {
|
||||
// 4 overlapping appointments, maxLanes = 2 → 1 visible + overflow of 3.
|
||||
final a = _appt(start: _at(2026, 5, 8, 8), end: _at(2026, 5, 8, 12));
|
||||
final b = _appt(start: _at(2026, 5, 8, 9), end: _at(2026, 5, 8, 10));
|
||||
final c = _appt(
|
||||
start: _at(2026, 5, 8, 9, 30),
|
||||
end: _at(2026, 5, 8, 14),
|
||||
);
|
||||
final d = _appt(start: _at(2026, 5, 8, 10), end: _at(2026, 5, 8, 11));
|
||||
|
||||
final overflow = assignLanes([a, b, c, d], maxLanes: 2)
|
||||
.whereType<LaidOutOverflow>()
|
||||
.single;
|
||||
expect(overflow.appointments, hasLength(3));
|
||||
expect(overflow.startTime, _at(2026, 5, 8, 9),
|
||||
reason: 'earliest non-visible start time');
|
||||
expect(overflow.endTime, _at(2026, 5, 8, 14),
|
||||
reason: 'latest non-visible end time');
|
||||
});
|
||||
final overflow = assignLanes([
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
], maxLanes: 2).whereType<LaidOutOverflow>().single;
|
||||
expect(overflow.appointments, hasLength(3));
|
||||
expect(
|
||||
overflow.startTime,
|
||||
_at(2026, 5, 8, 9),
|
||||
reason: 'earliest non-visible start time',
|
||||
);
|
||||
expect(
|
||||
overflow.endTime,
|
||||
_at(2026, 5, 8, 14),
|
||||
reason: 'latest non-visible end time',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
test('empty input returns an empty list', () {
|
||||
expect(assignLanes(const [], maxLanes: 2), isEmpty);
|
||||
});
|
||||
|
||||
test('asserts maxLanes >= 2', () {
|
||||
expect(() => assignLanes(const [], maxLanes: 1), throwsA(isA<AssertionError>()));
|
||||
expect(
|
||||
() => assignLanes(const [], maxLanes: 1),
|
||||
throwsA(isA<AssertionError>()),
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user