relatica/test/pages_manager_test.dart

138 wiersze
4.1 KiB
Dart

import 'dart:collection';
import 'dart:math';
import 'package:flutter_test/flutter_test.dart';
import 'package:relatica/friendica_client/paged_response.dart';
import 'package:relatica/friendica_client/pages_manager.dart';
import 'package:relatica/friendica_client/paging_data.dart';
import 'package:relatica/models/exec_error.dart';
import 'package:result_monad/result_monad.dart';
//Ensure works for ascending and descending tests
void main() async {
test('Full range test', () async {
final pm = _buildPagesManager();
final numbers = <int>[];
final initial = await pm.initialize(10);
for (var e in initial.value.data) {
numbers.add(e.id);
}
var current = initial.value;
while (current.next != null) {
final result = await pm.nextWithResult(current);
current = result.value;
for (var e in result.value.data) {
numbers.add(e.id);
}
}
current = initial.value;
while (current.previous != null) {
final result = await pm.previousWithResult(current);
current = result.value;
for (var e in result.value.data) {
numbers.add(e.id);
}
}
numbers.sort();
final expected = elements.map((e) => e.id).toList();
expected.sort();
expect(numbers.length, equals(elements.length));
expect(numbers, equals(expected));
_checkPagesOrder(pm.pages);
});
test('End fills test', () async {
final pm = _buildPagesManager();
final numbers = <int>[];
final initial = await pm.initialize(10);
for (var e in initial.value.data.reversed) {
numbers.add(e.id);
}
var moreWork = true;
while (moreWork) {
final nextFromEnd = await pm.nextFromEnd();
final previousFromBeginning = await pm.previousFromBeginning();
nextFromEnd.andThenSuccess(
(r) => r.data.reversed.forEach((e) => numbers.add(e.id)));
previousFromBeginning.andThenSuccess(
(r) => r.data.forEach((e) => numbers.insert(0, e.id)));
moreWork = nextFromEnd.isSuccess || previousFromBeginning.isSuccess;
}
for (var i = 0; i < numbers.length - 1; i++) {
expect(numbers[i], greaterThan(numbers[i + 1]));
}
numbers.sort();
expect(numbers.length, equals(elements.length));
expect(numbers, equals(elements.map((e) => e.id)));
_checkPagesOrder(pm.pages);
});
}
void _checkPagesOrder(UnmodifiableListView<PagedResponse> pages) {
expect(pages.first.previous, equals(null));
expect(pages.last.next, equals(null));
for (var i = 1; i < pages.length - 2; i++) {
final p0 = pages[i];
final p1 = pages[i + 1];
expect(p0.previous!.minId, greaterThan(p1.previous!.minId!));
expect(p0.next!.maxId, greaterThan(p1.next!.maxId!));
}
}
class _DataElement {
final int id;
final int value;
_DataElement({required this.id, required this.value});
@override
String toString() {
return '_DataElement{id: $id}';
}
}
const count = 1000;
final elements = List.generate(
count, (index) => _DataElement(id: index, value: Random().nextInt(100)));
PagesManager<List<_DataElement>, int> _buildPagesManager() => PagesManager(
idMapper: (data) => data.map((e) => e.id).toList(),
onRequest: getDataElements);
FutureResult<PagedResponse<List<_DataElement>>, ExecError> getDataElements(
PagingData page) async {
final count = page.limit;
late final int start;
late final int stop;
if (page.isLimitOnly) {
stop = elements.length ~/ 2;
start = stop - count;
} else if (page.minId != null) {
start = page.minId!;
stop = start + count;
} else if (page.maxId != null) {
stop = page.maxId!;
start = stop - count;
} else {
return buildErrorResult(
type: ErrorType.serverError,
message: 'Unknown paging type combo (only min and max supported)',
);
}
int previous = stop;
int next = start;
final data = elements.sublist(max(0, start), min(elements.length, stop));
return Result.ok(
PagedResponse(
data,
previous: previous > elements.length - 1
? null
: PagingData(limit: count, minId: previous),
next: next < 0 ? null : PagingData(limit: count, maxId: next),
),
);
}