117 lines
4.0 KiB
Dart
117 lines
4.0 KiB
Dart
import 'dart:ui';
|
|
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:ikar/backend/modules/shared_content.dart';
|
|
import 'package:ikar/frontend/widgets/attachment/bubbles/album_layout.dart';
|
|
import 'package:ikar/models/attachment.dart';
|
|
|
|
SharedMediaItem _item(String messageId, int time, int photoId) =>
|
|
SharedMediaItem(
|
|
messageId: messageId,
|
|
chatId: 1,
|
|
senderId: 2,
|
|
time: time,
|
|
attachment: PhotoAttachment(photoId: photoId),
|
|
);
|
|
|
|
void main() {
|
|
group('AlbumLayout.rows', () {
|
|
test('ten square photos grow from pairs to triples', () {
|
|
expect(AlbumLayout.rows(List.filled(10, 1.0)), [2, 2, 3, 3]);
|
|
});
|
|
|
|
test('rows never hold more than four tiles', () {
|
|
for (var count = 2; count <= AlbumLayout.maxTiles; count++) {
|
|
final rows = AlbumLayout.rows(List.filled(count, 0.7), narrow: true);
|
|
expect(rows.fold<int>(0, (sum, row) => sum + row), count);
|
|
expect(rows.every((row) => row >= 1 && row <= 4), isTrue);
|
|
}
|
|
});
|
|
});
|
|
|
|
group('AlbumLayout.layout', () {
|
|
const mixed = [1.78, 0.56, 1.0, 0.75, 1.33, 3.2, 0.5, 1.6, 0.8, 1.0];
|
|
|
|
Rect bounds(List<Rect> tiles) =>
|
|
tiles.reduce((a, b) => a.expandToInclude(b));
|
|
|
|
double area(Rect rect) => rect.width * rect.height;
|
|
|
|
test('tiles cover the album without overlapping', () {
|
|
for (var count = 2; count <= mixed.length; count++) {
|
|
for (final ratios in [
|
|
mixed.sublist(0, count),
|
|
mixed.reversed.take(count).toList(),
|
|
List.filled(count, 0.6),
|
|
List.filled(count, 1.9),
|
|
]) {
|
|
final grid = AlbumLayout.layout(ratios);
|
|
expect(grid.tiles, hasLength(count));
|
|
expect(grid.aspectRatio, greaterThan(0));
|
|
|
|
final box = bounds(grid.tiles);
|
|
expect(box.left, closeTo(0, 1e-9));
|
|
expect(box.top, closeTo(0, 1e-9));
|
|
expect(box.right, closeTo(1, 1e-9));
|
|
expect(box.bottom, closeTo(1, 1e-9));
|
|
|
|
final covered = grid.tiles.fold<double>(0, (sum, t) => sum + area(t));
|
|
expect(covered, closeTo(1, 1e-6), reason: '$ratios');
|
|
|
|
for (var i = 0; i < count; i++) {
|
|
expect(grid.tiles[i].width, greaterThan(0));
|
|
expect(grid.tiles[i].height, greaterThan(0));
|
|
for (var j = i + 1; j < count; j++) {
|
|
final overlap = grid.tiles[i].intersect(grid.tiles[j]);
|
|
final overlaps = overlap.width > 1e-9 && overlap.height > 1e-9;
|
|
expect(overlaps, isFalse, reason: '$ratios: $i and $j');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
test('a tall photo among three spans the full height on the left', () {
|
|
final grid = AlbumLayout.layout([0.6, 1.0, 1.0]);
|
|
expect(grid.tiles[0].left, 0);
|
|
expect(grid.tiles[0].top, 0);
|
|
expect(grid.tiles[0].bottom, closeTo(1, 1e-9));
|
|
expect(grid.tiles[1].left, grid.tiles[0].right);
|
|
expect(grid.tiles[2].left, grid.tiles[0].right);
|
|
expect(grid.tiles[2].top, grid.tiles[1].bottom);
|
|
});
|
|
|
|
test('a wide first photo of four sits above a row of three', () {
|
|
final grid = AlbumLayout.layout([1.6, 1.0, 1.0, 1.0]);
|
|
expect(grid.tiles[0].width, closeTo(1, 1e-9));
|
|
for (final tile in grid.tiles.skip(1)) {
|
|
expect(tile.top, grid.tiles[0].bottom);
|
|
}
|
|
});
|
|
|
|
test('unknown sizes fall back to squares', () {
|
|
final grid = AlbumLayout.layout([0, double.nan, 1]);
|
|
expect(grid.tiles, hasLength(3));
|
|
expect(grid.aspectRatio.isFinite, isTrue);
|
|
});
|
|
});
|
|
|
|
test('media feed keeps album order when photos share a timestamp', () {
|
|
final items = [
|
|
for (var i = 0; i < 40; i++) _item('old$i', 1000 + i, 500 + i),
|
|
_item('album', 5000, 1),
|
|
_item('album', 5000, 2),
|
|
_item('album', 5000, 3),
|
|
];
|
|
|
|
sortMediaNewestFirst(items);
|
|
|
|
final album = items.where((item) => item.messageId == 'album').toList();
|
|
expect(items.take(3).every((item) => item.messageId == 'album'), isTrue);
|
|
expect(
|
|
[for (final item in album) (item.attachment as PhotoAttachment).photoId],
|
|
[1, 2, 3],
|
|
);
|
|
});
|
|
}
|