import 'dart:convert'; import 'dart:io'; import 'package:pipe/pipe.dart'; import 'package:test/test.dart'; /// A copy of the fixture, so deleting code there cannot touch the real one. String _fixtureCopy() { final from = Directory('test/fixtures/stuck_loading'); final to = Directory.systemTemp.createTempSync('pipe-verify-removed'); for (final entity in from.listSync(recursive: true)) { final relative = entity.path.substring(from.path.length + 1); final target = '${to.path}/$relative'; if (entity is Directory) { Directory(target).createSync(recursive: true); } else if (entity is File) { File(target) ..createSync(recursive: true) ..writeAsBytesSync(entity.readAsBytesSync()); } } return to.path; } void main() { test('verify reports a deleted dead handler as removed', () async { final root = _fixtureCopy(); final before = await analyzeProject( await loadProject(root), concurrency: 1, ); final baseline = decodeBaselineEntries( encodeBaseline(root, before.report.findings), ); await before.dispose(); expect( baseline.where( (e) => e.rule == ruleDeadHandler && e.label == 'NeverDispatched', ), hasLength(1), ); // Delete the dead handler instead of wiring it up. final gaps = File('$root/lib/gaps.dart'); gaps.writeAsStringSync( gaps.readAsStringSync().replaceFirst( 'on((event, emit) => emit(const GapIdle()));', '', ), ); final after = await analyzeProject(await loadProject(root), concurrency: 1); try { final verification = verifyAnalysis(analysis: after, baseline: baseline); final json = jsonDecode(jsonEncode(verification.toJson())) as Map; expect( verification.removed.map((e) => e.label), contains('NeverDispatched'), ); expect( verification.resolved.map((e) => e.label), isNot(contains('NeverDispatched')), ); expect(json['removed'], greaterThanOrEqualTo(1)); } finally { await after.dispose(); } }); }