import 'dart:typed_data'; import 'package:serverpod_offline_sync/src/database/merge_utils/unique_resolver.dart'; import 'package:test/test.dart'; import 'package:uuid/uuid.dart'; void main() { group('Given byte values such as a bytea column holds,', () { final bytes = Uint8List.fromList(List.generate(4096, (i) => i % 251)); test( 'when comparing equal and differing bytes, ' 'then they compare by content.', () { final same = Uint8List.fromList(bytes); final changed = Uint8List.fromList(bytes)..[4000] ^= 1; final shorter = Uint8List.sublistView(bytes, 0, 4095); expect(projectionValuesEqual(bytes, same), isTrue); expect(projectionValuesEqual(bytes, changed), isFalse); expect(projectionValuesEqual(bytes, shorter), isFalse); expect(projectionValuesEqual(bytes, null), isFalse); }, ); test( 'when comparing payloads alike in their first 16 bytes, ' 'then they are not taken for the same UUID.', () { final payload = Uint8List.fromList('{"schemaVersion":1,"a":1}'.codeUnits); final other = Uint8List.fromList('{"schemaVersion":1,"a":2}'.codeUnits); expect(tryUuidValue(payload), isNull); expect( canonicalProjectionValue(payload), isNot(canonicalProjectionValue(other)), ); }, ); test( 'when comparing many payloads of a few kilobytes, ' 'then it takes no more than a moment.', () { final same = Uint8List.fromList(bytes); final watch = Stopwatch()..start(); for (var i = 0; i < 1000; i++) { projectionValuesEqual(bytes, same); } // Byte by byte through a failing UUID parse, this took minutes. expect(watch.elapsed, lessThan(const Duration(seconds: 2))); }, ); }); group('Given UUIDs in their forms,', () { final uuid = const Uuid().v7obj(); test( 'when comparing a UUID with its string and its bytes, ' 'then they are the same.', () { expect(tryUuidValue(uuid.uuid), uuid); expect(tryUuidValue(Uint8List.fromList(uuid.toBytes())), uuid); expect(projectionValuesEqual(uuid, uuid.uuid), isTrue); expect(projectionValuesEqual(uuid.uuid, uuid), isTrue); expect( projectionValuesEqual(Uint8List.fromList(uuid.toBytes()), uuid), isTrue, ); }, ); test( 'when comparing what is no UUID, ' 'then it is none and compares as itself.', () { expect(tryUuidValue('not a uuid'), isNull); expect(tryUuidValue('x' * 36), isNull); expect(tryUuidValue(42), isNull); expect(tryUuidValue(DateTime.utc(2026)), isNull); expect(projectionValuesEqual(42, 42), isTrue); expect(projectionValuesEqual(42, 43), isFalse); expect(projectionValuesEqual([1, 'a'], [1, 'a']), isTrue); expect(projectionValuesEqual({'a': 1}, {'a': 2}), isFalse); }, ); }); }