78 lines
2.5 KiB
Dart
78 lines
2.5 KiB
Dart
/// Unit test for cake_wallet-0001: exchange_view_model token injection
|
|
/// dedup uses List.any() O(T*L) instead of Set O(T).
|
|
///
|
|
/// Simulates the _injectUserEthTokensIntoCurrencyLists pattern with
|
|
/// List.any() (defect) vs Set.contains() (fix) and measures op-counts.
|
|
|
|
int opsDefect = 0;
|
|
int opsFix = 0;
|
|
|
|
class FakeToken {
|
|
final String contractAddress;
|
|
FakeToken(this.contractAddress);
|
|
}
|
|
|
|
/// Defect: linear scan of list for each token (original pattern)
|
|
bool listContainsToken(List<FakeToken> list, FakeToken token) {
|
|
return list.any((item) {
|
|
opsDefect++;
|
|
return item.contractAddress.toLowerCase() == token.contractAddress.toLowerCase();
|
|
});
|
|
}
|
|
|
|
/// Fix: set-based lookup
|
|
bool setContainsToken(Set<String> addrSet, FakeToken token) {
|
|
opsFix++;
|
|
return addrSet.contains(token.contractAddress.toLowerCase());
|
|
}
|
|
|
|
void main() {
|
|
// Simulate: receiveCurrencies has L existing tokens, injecting T new tokens
|
|
final sizes = [
|
|
[50, 278], // 50 user tokens, 278 existing currencies
|
|
[200, 500], // heavy user with many custom tokens
|
|
];
|
|
|
|
for (final pair in sizes) {
|
|
final T = pair[0];
|
|
final L = pair[1];
|
|
|
|
// Build existing currencies list
|
|
final existingList = List.generate(L, (i) => FakeToken('0x${i.toRadixString(16).padLeft(40, '0')}'));
|
|
// Build user tokens (half overlap, half new)
|
|
final userTokens = List.generate(T, (i) {
|
|
final idx = i < T ~/ 2 ? i : L + i; // first half overlaps, second half new
|
|
return FakeToken('0x${idx.toRadixString(16).padLeft(40, '0')}');
|
|
});
|
|
|
|
// --- Defect path ---
|
|
opsDefect = 0;
|
|
final toAddDefect = <FakeToken>[];
|
|
for (final token in userTokens) {
|
|
if (!listContainsToken(existingList, token)) {
|
|
toAddDefect.add(token);
|
|
}
|
|
}
|
|
|
|
// --- Fix path ---
|
|
opsFix = 0;
|
|
final addrSet = existingList.map((t) => t.contractAddress.toLowerCase()).toSet();
|
|
final toAddFix = <FakeToken>[];
|
|
for (final token in userTokens) {
|
|
if (!setContainsToken(addrSet, token)) {
|
|
toAddFix.add(token);
|
|
}
|
|
}
|
|
|
|
// Verify correctness
|
|
assert(toAddDefect.length == toAddFix.length,
|
|
'FAIL: results differ (defect=${toAddDefect.length}, fix=${toAddFix.length})');
|
|
|
|
final ratio = opsDefect / opsFix;
|
|
print('T=$T L=$L: defect=$opsDefect fix=$opsFix ratio=${ratio.toStringAsFixed(1)}x '
|
|
'${ratio > 2 ? "PASS" : "FAIL"}');
|
|
assert(ratio > 2, 'FAIL: expected significant speedup, got ${ratio}x');
|
|
}
|
|
|
|
print('cake_wallet-0001: ALL PASS');
|
|
}
|