// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
    hide NavigationTarget;
import 'package:nnbd_migration/nnbd_migration.dart';
import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
import 'package:nnbd_migration/src/front_end/migration_info.dart';
import 'package:nnbd_migration/src/front_end/migration_state.dart';
import 'package:nnbd_migration/src/front_end/navigation_tree_renderer.dart';
import 'package:nnbd_migration/src/front_end/offset_mapper.dart';
import 'package:nnbd_migration/src/front_end/path_mapper.dart';
import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
import 'package:nnbd_migration/src/preview/preview_site.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../front_end/nnbd_migration_test_base.dart';
import '../utilities/test_logger.dart';

void main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(PreviewSiteTest);
    defineReflectiveTests(PreviewSiteWithEngineTest);
  });
}

@reflectiveTest
class PreviewSiteTest with ResourceProviderMixin, PreviewSiteTestMixin {
  @override
  Future<void> performEdit(String path, int offset, String replacement) {
    final pathUri = Uri.file(path).path;
    return site
        .performEdit(Uri.parse('localhost://$pathUri?offset=$offset&end=$offset'
            '&replacement=${Uri.encodeComponent(replacement)}'));
  }

  void setUp() {
    dartfixListener = DartFixListener(null, ListenerClient());
    resourceProvider = MemoryResourceProvider();
    final migrationInfo =
        MigrationInfo({}, {}, resourceProvider.pathContext, null);
    state = MigrationState(
        null, null, dartfixListener, null, {}, (String? path) => true);
    state!.pathMapper = PathMapper(resourceProvider);
    state!.migrationInfo = migrationInfo;
    logger = TestLogger(false /*isVerbose*/);
    site = PreviewSite(state, () async {
      return state;
    }, () {}, logger);
  }

  void test_apply_regress41391() async {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final analysisOptionsPath = convertPath('/analysis_options.yaml');
    final analysisOptions = getFile(analysisOptionsPath);
    analysisOptions.writeAsStringSync('analyzer:');
    final content = 'void main() {}';
    file.writeAsStringSync(content);
    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
    // Add a source change for analysis_options, which has no UnitInfo.
    dartfixListener!.addSourceFileEdit(
        'enable experiment',
        Location(analysisOptionsPath, 9, 0, 1, 9, endLine: 1, endColumn: 9),
        SourceFileEdit(analysisOptionsPath, 0, edits: [
          SourceEdit(9, 0, '\n  enable-experiment:\n  - non-nullable')
        ]));
    // This should not crash.
    site.performApply([]);
    expect(analysisOptions.readAsStringSync(), '''
analyzer:
  enable-experiment:
  - non-nullable''');
    expect(state!.hasBeenApplied, true);
  }

  void test_applyChangesEmpty() {
    final file = getFile('/test.dart');
    file.writeAsStringSync('void main() {}');
    site.performApply([]);
    expect(file.readAsStringSync(), 'void main() {}');
    expect(state!.hasBeenApplied, true);
  }

  void test_applyChangesTwiceThrows() {
    site.performApply([]);
    expect(() => site.performApply([]), throwsA(isA<StateError>()));
  }

  void test_applyMigration_sanityCheck_dontApply() async {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = '// different content';
    final currentContent = 'void main() {}';
    file.writeAsStringSync(currentContent);
    dartfixListener!.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10, endLine: 1, endColumn: 10),
        SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
    expect(() => site.performApply([]), throwsA(isA<StateError>()));
    expect(file.readAsStringSync(), currentContent);
    expect(state!.hasBeenApplied, false);
  }

  void test_applyMultipleChanges() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = 'void main() {}';
    file.writeAsStringSync(content);
    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
    dartfixListener!.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10, endLine: 1, endColumn: 10),
        SourceFileEdit(path, 0, edits: [
          SourceEdit(10, 0, 'List args'),
          SourceEdit(13, 0, '\n  print(args);\n')
        ]));
    site.performApply([]);
    expect(file.readAsStringSync(), '''
void main(List args) {
  print(args);
}''');
    expect(state!.hasBeenApplied, true);
  }

  void test_applySingleChange() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = 'void main() {}';
    file.writeAsStringSync(content);
    site.unitInfoMap[path] = UnitInfo(path)..diskContent = content;
    dartfixListener!.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10, endLine: 1, endColumn: 10),
        SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
    site.performApply([]);
    expect(file.readAsStringSync(), 'void main(List args) {}');
    expect(state!.hasBeenApplied, true);
  }

  void test_optOutOfNullSafety_blankLines() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('  \n  \n'),
        equals('// @dart=2.9\n\n  \n  \n'));
  }

  void test_optOutOfNullSafety_blankLines_windows() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('  \r\n  \r\n'),
        equals('// @dart=2.9\r\n\r\n  \r\n  \r\n'));
  }

  void test_optOutOfNullSafety_commentThenCode() {
    expect(
        IncrementalPlan.optCodeOutOfNullSafety('// comment\n\nvoid main() {}'),
        equals('// comment\n\n// @dart=2.9\n\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_commentThenCode_windows() {
    expect(
        IncrementalPlan.optCodeOutOfNullSafety(
            '// comment\r\n\r\nvoid main() {}'),
        equals('// comment\r\n\r\n// @dart=2.9\r\n\r\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_commentThenDirective() {
    expect(
        IncrementalPlan.optCodeOutOfNullSafety(
            '// comment\nimport "dart:core";'),
        equals('// comment\n\n// @dart=2.9\n\nimport "dart:core";'));
  }

  void test_optOutOfNullSafety_commentThenDirective_multiLine() {
    expect(
        IncrementalPlan.optCodeOutOfNullSafety(
            '// comment\n// comment\nimport "dart:core";'),
        equals(
            '// comment\n// comment\n\n// @dart=2.9\n\nimport "dart:core";'));
  }

  void test_optOutOfNullSafety_commentThenSemicolon() {
    expect(
        IncrementalPlan.optCodeOutOfNullSafety('// comment\n;\nvoid main() {}'),
        equals('// comment\n\n// @dart=2.9\n\n;\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_empty() {
    expect(IncrementalPlan.optCodeOutOfNullSafety(''), equals('// @dart=2.9'));
  }

  void test_optOutOfNullSafety_singleComment_multiLine() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('// line 1\n// line 2'),
        equals('// line 1\n// line 2\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleComment_multiLine_indented() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('  // line 1\n  // line 2'),
        equals('  // line 1\n  // line 2\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleComment_singleLine() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('// comment'),
        equals('// comment\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleComment_singleLine_trailingNewline() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('// comment\n'),
        equals('// comment\n\n\n// @dart=2.9\n'));
  }

  void test_optOutOfNullSafety_singleLine() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('void main() {}'),
        equals('// @dart=2.9\n\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_singleLine_afterBlankLines() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('\n\nvoid main() {}'),
        equals('// @dart=2.9\n\n\n\nvoid main() {}'));
  }

  void test_optOutOfNullSafety_singleLine_windows() {
    expect(IncrementalPlan.optCodeOutOfNullSafety('void main() {}\r\n'),
        equals('// @dart=2.9\r\n\r\nvoid main() {}\r\n'));
  }

  void test_performEdit() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = 'int foo() {}';
    final unitInfo = UnitInfo(path)
      ..diskContent = content
      ..content = content
      ..diskChangesOffsetMapper = OffsetMapper.identity;
    site.unitInfoMap[path] = unitInfo;
    file.writeAsStringSync(content);
    performEdit(path, 3, '/*?*/');
    expect(file.readAsStringSync(), 'int/*?*/ foo() {}');
    expect(state!.hasBeenApplied, false);
    expect(state!.needsRerun, true);
    expect(unitInfo.content, 'int/*?*/ foo() {}');
  }

  void test_performEdit_sanityCheck_dontApply() {
    final path = convertPath('/test.dart');
    final file = getFile(path);
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = '// different content';
    final currentContent = 'void main() {}';
    file.writeAsStringSync(currentContent);
    expect(() => performEdit(path, 0, 'foo'), throwsA(isA<StateError>()));
    expect(file.readAsStringSync(), currentContent);
    expect(state!.hasBeenApplied, false);
  }
}

mixin PreviewSiteTestMixin {
  late PreviewSite site;
  DartFixListener? dartfixListener;
  MigrationState? state;
  TestLogger? logger;

  Future<void> performEdit(String path, int offset, String replacement) {
    final pathUri = Uri.file(path).path;
    return site
        .performEdit(Uri.parse('localhost://$pathUri?offset=$offset&end=$offset'
            '&replacement=${Uri.encodeComponent(replacement)}'));
  }
}

@reflectiveTest
class PreviewSiteWithEngineTest extends NnbdMigrationTestBase
    with ResourceProviderMixin, PreviewSiteTestMixin {
  MigrationInfo? migrationInfo;

  Future<void> setUpMigrationInfo(Map<String, String> files,
      {bool Function(String?)? shouldBeMigratedFunction,
      Iterable<String>? pathsToProcess}) async {
    shouldBeMigratedFunction ??= (String? path) => true;
    pathsToProcess ??= files.keys;
    await buildInfoForTestFiles(files,
        includedRoot: projectPath,
        shouldBeMigratedFunction: shouldBeMigratedFunction,
        pathsToProcess: pathsToProcess);
    dartfixListener = DartFixListener(null, ListenerClient());
    migrationInfo =
        MigrationInfo(infos, {}, resourceProvider.pathContext, projectPath);
    state = MigrationState(
        null, null, dartfixListener, null, {}, shouldBeMigratedFunction);
    nodeMapper = state!.nodeMapper;
    state!.pathMapper = PathMapper(resourceProvider);
    state!.migrationInfo = migrationInfo;
    logger = TestLogger(false /*isVerbose*/);
    site = PreviewSite(state, () async {
      return state;
    }, () {}, logger);
  }

  void test_applyHintAction() async {
    await setUpMigrationInfo({});
    final path = convertPath('$projectPath/bin/test.dart');
    final file = getFile(path);
    final content = r'''
int x;
int y = x;
''';
    file.writeAsStringSync(content);
    final migratedContent = '''
int? x;
int? y = x;
''';
    final unitInfo = await buildInfoForSingleTestFile(content,
        migratedContent: migratedContent);
    site.unitInfoMap[path] = unitInfo;
    await site.performHintAction(
        unitInfo.regions[1].traces[0].entries[0].hintActions[0]);
    await site.performHintAction(
        unitInfo.regions[1].traces[0].entries[2].hintActions[0]);
    expect(file.readAsStringSync(), '''
int/*?*/ x;
int/*?*/ y = x;
''');
    expect(unitInfo.content, '''
int/*?*/? x;
int/*?*/? y = x;
''');
    assertRegion(
        region: unitInfo.regions[0], offset: unitInfo.content!.indexOf('? x'));
    assertRegion(
        region: unitInfo.regions[1], offset: unitInfo.content!.indexOf('? y'));
    final targets = List<NavigationTarget>.from(unitInfo.targets);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content!.indexOf('x'),
        offsetMapper: unitInfo.offsetMapper);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content!.indexOf('y'),
        offsetMapper: unitInfo.offsetMapper);
    var trace = unitInfo.regions[1].traces[0];
    assertTraceEntry(
        unitInfo,
        trace.entries[0],
        'y',
        unitInfo.content!.indexOf('int/*?*/? y'),
        contains('y (test.dart:2:1)'));
    assertTraceEntry(unitInfo, trace.entries[1], 'y',
        unitInfo.content!.indexOf('= x;') + '= '.length, contains('data flow'));
    expect(state!.hasBeenApplied, false);
    expect(state!.needsRerun, true);
  }

  void test_applyHintAction_removeHint() async {
    await setUpMigrationInfo({});
    final path = convertPath('$projectPath/bin/test.dart');
    final file = getFile(path);
    final content = r'''
int/*!*/ x;
int y = x;
''';
    file.writeAsStringSync(content);
    final migratedContent = '''
int/*!*/ x;
int  y = x;
''';
    final unitInfo = await buildInfoForSingleTestFile(content,
        migratedContent: migratedContent);
    site.unitInfoMap[path] = unitInfo;
    await site.performHintAction(
        unitInfo.regions[0].traces[0].entries[0].hintActions[0]);
    expect(file.readAsStringSync(), '''
int x;
int y = x;
''');
    expect(unitInfo.content, '''
int x;
int  y = x;
''');
    expect(unitInfo.regions, hasLength(1));
    assertRegion(
        kind: NullabilityFixKind.typeNotMadeNullable,
        region: unitInfo.regions[0],
        offset: unitInfo.content!.indexOf('  y'));
    final targets = List<NavigationTarget>.from(unitInfo.targets);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content!.indexOf('x'),
        offsetMapper: unitInfo.offsetMapper);
    expect(state!.hasBeenApplied, false);
    expect(state!.needsRerun, true);
  }

  void test_applyMigration_doNotOptOutFileNotInPathsToProcess() async {
    final pathA = convertPath('$projectPath/lib/a.dart');
    final pathB = convertPath('$projectPath/lib/b.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({pathA: content, pathB: content},
        // Neither [pathA] nor [[pathB] should be migrated.
        shouldBeMigratedFunction: (String? path) => false,
        pathsToProcess: [pathA]);
    site.unitInfoMap[pathA] = UnitInfo(pathA)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false
      ..migrationStatus = UnitMigrationStatus.optingOut;
    site.unitInfoMap[pathB] = UnitInfo(pathB)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false
      ..migrationStatus = UnitMigrationStatus.optingOut;
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    site.performApply(navigationTree);
    expect(getFile(pathA).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
    expect(getFile(pathB).readAsStringSync(), 'void main() {}');
  }

  void test_applyMigration_migratePreviouslyOptedOutFile() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = '''
// @dart=2.9

void main() {}''';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = true;
    dartfixListener!.addSourceFileEdit(
        'remove DLV comment',
        Location(path, 0, 14, 1, 1, endLine: 3, endColumn: 1),
        SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), 'void main() {}');
    expect(logger!.stdoutBuffer.toString(), contains('''
Migrated 1 file:
    ${convertPath('lib/a.dart')}
'''));
  }

  void test_applyMigration_optOutEmptyFile() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = '';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree!.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), '// @dart=2.9');
    expect(logger!.stdoutBuffer.toString(), contains('''
Opted 1 file out of null safety with a new Dart language version comment:
    ${convertPath('lib/a.dart')}
'''));
  }

  void test_applyMigration_optOutFileWithEdits() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    dartfixListener!.addSourceFileEdit(
        'test change',
        Location(path, 10, 0, 1, 10, endLine: 1, endColumn: 10),
        SourceFileEdit(path, 0, edits: [SourceEdit(10, 0, 'List args')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree!.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
    expect(logger!.stdoutBuffer.toString(), contains('''
Opted 1 file out of null safety with a new Dart language version comment:
    ${convertPath('lib/a.dart')}
'''));
  }

  void test_applyMigration_optOutFileWithoutEdits() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree!.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
    expect(logger!.stdoutBuffer.toString(), contains('''
Opted 1 file out of null safety with a new Dart language version comment:
    ${convertPath('lib/a.dart')}
'''));
  }

  void test_applyMigration_optOutOne_migrateAnother() async {
    final pathA = convertPath('$projectPath/lib/a.dart');
    final pathB = convertPath('$projectPath/lib/b.dart');
    final content = 'void main() {}';
    await setUpMigrationInfo({pathA: content, pathB: content});
    site.unitInfoMap[pathA] = UnitInfo(pathA)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    site.unitInfoMap[pathB] = UnitInfo(pathB)
      ..diskContent = content
      ..wasExplicitlyOptedOut = false;
    dartfixListener!.addSourceFileEdit(
        'test change',
        Location(pathA, 10, 0, 1, 10, endLine: 1, endColumn: 10),
        SourceFileEdit(pathA, 0, edits: [SourceEdit(10, 0, 'List args')]));
    dartfixListener!.addSourceFileEdit(
        'test change',
        Location(pathB, 10, 0, 1, 10, endLine: 1, endColumn: 10),
        SourceFileEdit(pathB, 0, edits: [SourceEdit(10, 0, 'List args')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree![0] as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(pathA).readAsStringSync(), '''
// @dart=2.9

void main() {}''');
    expect(getFile(pathB).readAsStringSync(), '''
void main(List args) {}''');
    expect(logger!.stdoutBuffer.toString(), contains('''
Migrated 1 file:
    ${convertPath('lib/b.dart')}
Opted 1 file out of null safety with a new Dart language version comment:
    ${convertPath('lib/a.dart')}
'''));
  }

  void test_applyMigration_optOutPreviouslyOptedOutFile() async {
    final path = convertPath('$projectPath/lib/a.dart');
    final content = '''
// @dart=2.9

int a;''';
    await setUpMigrationInfo({path: content});
    site.unitInfoMap[path] = UnitInfo(path)
      ..diskContent = content
      ..wasExplicitlyOptedOut = true;
    dartfixListener!.addSourceFileEdit(
        'remove DLV comment',
        Location(path, 0, 14, 1, 1, endLine: 3, endColumn: 1),
        SourceFileEdit(path, 0, edits: [SourceEdit(0, 14, '')]));
    var navigationTree =
        NavigationTreeRenderer(migrationInfo, state!.pathMapper).render();
    var libDir = navigationTree.single as NavigationTreeDirectoryNode;
    (libDir.subtree!.single as NavigationTreeFileNode).migrationStatus =
        UnitMigrationStatus.optingOut;
    site.performApply(navigationTree);
    expect(getFile(path).readAsStringSync(), content);
    expect(logger!.stdoutBuffer.toString(), contains('''
Kept 1 file opted out of null safety:
    ${convertPath('lib/a.dart')}
'''));
  }

  void test_performEdit_multiple() async {
    await setUpMigrationInfo({});
    final path = convertPath('/test.dart');
    final file = getFile(path);
    final content = r'''
int x;
int y = x;
''';
    file.writeAsStringSync(content);
    final migratedContent = '''
int? x;
int? y = x;
''';
    final unitInfo = await buildInfoForSingleTestFile(content,
        migratedContent: migratedContent);
    site.unitInfoMap[path] = unitInfo;
    final firstEditOffset = unitInfo.regions[0].edits[0].offset;
    performEdit(path, firstEditOffset, '/*?*/');
    final secondEditOffset = unitInfo.regions[1].edits[0].offset;
    performEdit(path, secondEditOffset, '/*?*/');
    expect(file.readAsStringSync(), '''
int/*?*/ x;
int/*?*/ y = x;
''');
    expect(unitInfo.content, '''
int/*?*/? x;
int/*?*/? y = x;
''');
    assertRegion(
        region: unitInfo.regions[0], offset: unitInfo.content!.indexOf('? x'));
    assertRegion(
        region: unitInfo.regions[1], offset: unitInfo.content!.indexOf('? y'));
    final targets = List<NavigationTarget>.from(unitInfo.targets);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content!.indexOf('x'),
        offsetMapper: unitInfo.offsetMapper);
    assertInTargets(
        targets: targets,
        offset: unitInfo.content!.indexOf('y'),
        offsetMapper: unitInfo.offsetMapper);
    var trace = unitInfo.regions[1].traces[0];
    assertTraceEntry(
        unitInfo,
        trace.entries[0],
        'y',
        unitInfo.content!.indexOf('int/*?*/? y'),
        contains('y (test.dart:2:1)'));
    assertTraceEntry(unitInfo, trace.entries[1], 'y',
        unitInfo.content!.indexOf('= x;') + '= '.length, contains('data flow'));
    expect(state!.hasBeenApplied, false);
    expect(state!.needsRerun, true);
  }
}
