[analysis_server] Modify code action/refactor tests to verify whole set of edits

The goal here is to ensure tests can't accidentally check only a subset of edits made during the command execution.

Not all tests have been migrated (only refactorings and a few that happened to use some of the same methods for verification).

Change-Id: I5589e8e667e957aee3ea55f741b1b49a3859d6bd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312304
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index ba36560..1d9d91d 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -23,11 +23,21 @@
   final Map<num, Completer<ResponseMessage>> _completers = {};
   String dartSdkPath = dirname(dirname(Platform.resolvedExecutable));
 
+  /// Tracks the current overlay content so that when we apply edits they can
+  /// be applied in the same way a real client would apply them.
+  final _overlayContent = <Uri, String>{};
+
   LspByteStreamServerChannel get channel => client!.channel!;
 
   @override
   Stream<Message> get serverToClient => client!.serverToClient;
 
+  @override
+  Future<void> closeFile(Uri uri) {
+    _overlayContent.remove(uri);
+    return super.closeFile(uri);
+  }
+
   /// Sends a request to the server and unwraps the result. Throws if the
   /// response was not successful or returned an error.
   @override
@@ -46,12 +56,39 @@
     }
   }
 
+  @override
+  String? getCurrentFileContent(Uri uri) {
+    // First try and overlay the test has set.
+    if (_overlayContent.containsKey(uri)) {
+      return _overlayContent[uri];
+    }
+
+    // Otherwise fall back to the disk.
+    try {
+      return File(uri.toFilePath()).readAsStringSync();
+    } catch (_) {
+      return null;
+    }
+  }
+
   void newFile(String path, String content) =>
       File(path).writeAsStringSync(content);
 
   void newFolder(String path) => Directory(path).createSync(recursive: true);
 
   @override
+  Future<void> openFile(Uri uri, String content, {int version = 1}) {
+    _overlayContent[uri] = content;
+    return super.openFile(uri, content, version: version);
+  }
+
+  @override
+  Future<void> replaceFile(int newVersion, Uri uri, String content) {
+    _overlayContent[uri] = content;
+    return super.replaceFile(newVersion, uri, content);
+  }
+
+  @override
   void sendNotificationToServer(NotificationMessage notification) =>
       channel.sendNotification(notification);
 
diff --git a/pkg/analysis_server/test/lsp/code_actions_abstract.dart b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
index e6a45af..115e6a7 100644
--- a/pkg/analysis_server/test/lsp/code_actions_abstract.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_abstract.dart
@@ -51,52 +51,6 @@
     );
   }
 
-  /// Executes [command] which is expected to call back to the client to apply
-  /// a [WorkspaceEdit].
-  ///
-  /// Changes are applied to [contents] to be verified by the caller.
-  Future<void> executeCommandForEdits(
-    Command command,
-    // TODO(dantup): Change this map to use Uris for files.
-    Map<String, String> contents, {
-    bool expectDocumentChanges = false,
-    ProgressToken? workDoneToken,
-  }) async {
-    ApplyWorkspaceEditParams? editParams;
-
-    final commandResponse = await handleExpectedRequest<Object?,
-        ApplyWorkspaceEditParams, ApplyWorkspaceEditResult>(
-      Method.workspace_applyEdit,
-      ApplyWorkspaceEditParams.fromJson,
-      () => executeCommand(command, workDoneToken: workDoneToken),
-      handler: (edit) {
-        // When the server sends the edit back, just keep a copy and say we
-        // applied successfully (it'll be verified by the caller).
-        editParams = edit;
-        return ApplyWorkspaceEditResult(applied: true);
-      },
-    );
-    // Successful edits return an empty success() response.
-    expect(commandResponse, isNull);
-
-    // Ensure the edit came back, and using the expected change type.
-    expect(editParams, isNotNull);
-    final edit = editParams!.edit;
-    if (expectDocumentChanges) {
-      expect(edit.changes, isNull);
-      expect(edit.documentChanges, isNotNull);
-    } else {
-      expect(edit.changes, isNotNull);
-      expect(edit.documentChanges, isNull);
-    }
-
-    if (expectDocumentChanges) {
-      applyDocumentChanges(contents, edit.documentChanges!);
-    } else {
-      applyChanges(contents, edit.changes!);
-    }
-  }
-
   /// Expects that command [commandName] was logged to the analytics manager.
   void expectCommandLogged(String commandName) {
     expect(
@@ -155,32 +109,8 @@
       (codeAction) => codeAction.command!,
     );
 
-    await verifyCommandEdits(command, content, expectedContent,
+    await verifyCommandEdits(command, expectedContent,
         expectDocumentChanges: expectDocumentChanges,
         workDoneToken: workDoneToken);
   }
-
-  /// Verifies that executing the given command on the server results in an edit
-  /// being sent in the client that updates the main file to match the expected
-  /// content.
-  Future<void> verifyCommandEdits(
-    Command command,
-    String content,
-    String expectedContent, {
-    bool expectDocumentChanges = false,
-    ProgressToken? workDoneToken,
-  }) async {
-    final contents = {
-      mainFilePath: withoutMarkers(content),
-    };
-
-    await executeCommandForEdits(
-      command,
-      contents,
-      expectDocumentChanges: expectDocumentChanges,
-      workDoneToken: workDoneToken,
-    );
-
-    expect(contents[mainFilePath], equals(expectedContent));
-  }
 }
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index c73685c..b61aa86 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -40,6 +40,7 @@
 }
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 int test() => 42;
 void f() {
   var a = test();
@@ -105,6 +106,7 @@
 }
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 int get test => 42;
 void f() {
   var a = test;
@@ -168,8 +170,9 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print('Test!');
   newMethod();
@@ -178,7 +181,7 @@
 void newMethod() {
   print('Test!');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -197,7 +200,7 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     const expectedContent = '''
 void f() {
   print('Test!');
@@ -207,7 +210,7 @@
 void newMethod() {
   print('Test!');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -251,7 +254,7 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
 
@@ -276,7 +279,7 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize(
       textDocumentCapabilities: withCodeActionKinds(
@@ -326,8 +329,9 @@
 
 Object Container(Object text) => null;
 Object Text(Object text) => null;
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 Object F() {
   return Container(text());
 }
@@ -336,7 +340,7 @@
 
 Object Container(Object text) => null;
 Object Text(Object text) => null;
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -354,7 +358,7 @@
 import 'dart:convert';
 ^
 void f() {}
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -370,7 +374,7 @@
 import 'dart:io' as io;
 
 i^o.File a;
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -408,8 +412,9 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print('Test!');
   newMethod();
@@ -418,7 +423,7 @@
 void newMethod() {
   print('Test!');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize(
         windowCapabilities:
@@ -444,8 +449,9 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print('Test!');
   newMethod();
@@ -454,7 +460,7 @@
 void newMethod() {
   print('Test!');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -480,8 +486,9 @@
   print('Test!');
   [[print('Test!');]]
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print('Test!');
   newMethod();
@@ -490,7 +497,7 @@
 void newMethod() {
   print('Test!');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize(
         windowCapabilities:
@@ -518,7 +525,7 @@
 
 void doFoo(void Function() a) => a();
 
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -559,7 +566,7 @@
 
 void doFoo(void Function() a) => a();
 
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize(
       // We expect an error notification so don't fail on it.
@@ -601,7 +608,7 @@
 
 void doFoo(void Function() a) => a();
 
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -644,15 +651,16 @@
 }
 
 void foo(int arg) {}
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   var arg = 1 + 2;
   foo(arg);
 }
 
 void foo(int arg) {}
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -673,8 +681,9 @@
 }
 
 void foo(int arg) {}
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   var arg = "test";
   var arg2 = 1 + 2;
@@ -682,7 +691,7 @@
 }
 
 void foo(int arg) {}
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -704,13 +713,14 @@
 void f() {
   test(1, 2);
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print(1);
   print(2);
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -732,13 +742,14 @@
 void f() {
   test(1, 2);
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print(1);
   print(2);
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -762,15 +773,16 @@
     test(1, 2);
   }
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 class A {
   void f() {
     print(1);
     print(2);
   }
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -794,15 +806,16 @@
     test(1, 2);
   }
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 class A {
   void f() {
     print(1);
     print(2);
   }
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -818,10 +831,11 @@
   Future<void> test_methodToGetter_function_startOfParameterList() async {
     const content = '''
 int test[[]]() => 42;
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 int get test => 42;
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -837,10 +851,11 @@
   Future<void> test_methodToGetter_function_startOfTypeParameterList() async {
     const content = '''
 int test[[]]<T>() => 42;
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 int get test<T> => 42;
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -858,12 +873,13 @@
 class A {
   int test[[]]() => 42;
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 class A {
   int get test => 42;
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -881,12 +897,13 @@
 class A {
   int test[[]]<T>() => 42;
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 class A {
   int get test<T> => 42;
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -939,8 +956,9 @@
     );
   }
 }
-    ''';
+''';
     final expectedContent = '''
+>>>>>>>>>> lib/main.dart
 import 'package:flutter/material.dart';
 
 class MyWidget extends StatelessWidget {
@@ -968,7 +986,7 @@
     );
   }
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -986,7 +1004,7 @@
 import 'dart:convert';
 ^
 void f() {}
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -1025,14 +1043,15 @@
   print(a);
   print(a);
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   print(1);
   print(1);
   print(1);
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -1063,8 +1082,9 @@
 void bar() {
   print('test');
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void foo1() {
   print('test');
 }
@@ -1076,7 +1096,7 @@
 void bar() {
   print('test');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
@@ -1102,8 +1122,9 @@
 void ba^r() {
   print('test');
 }
-    ''';
+''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void foo1() {
   print('test');
 }
@@ -1111,7 +1132,7 @@
 void foo2() {
   print('test');
 }
-    ''';
+''';
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
 
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index 1547d00..c34c8a5 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
@@ -71,6 +71,7 @@
 final b = new Set<String>();
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 final a = Object();
 final b = <String>{};
 ''';
@@ -102,6 +103,7 @@
 }
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   const a = 'test';
 }
@@ -134,6 +136,7 @@
 }
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 void f() {
   const a = 'test';
 }
@@ -263,6 +266,7 @@
 int? a;
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 int? a;
 ''';
 
@@ -292,6 +296,7 @@
 int minified(int x, int y) => min(x, y);
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 import 'dart:async';
 import 'dart:math';
 
@@ -320,6 +325,7 @@
 int minified(int x, int y) => min(x, y);
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 import 'dart:async';
 import 'dart:math';
 
@@ -489,6 +495,7 @@
 String a;
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 String a;
 String b;
 ''';
@@ -510,6 +517,7 @@
 String a;
 ''';
     const expectedContent = '''
+>>>>>>>>>> lib/main.dart
 String a;
 String b;
 ''';
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 4451af0..8b86110 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -97,7 +97,7 @@
 void f() {
   MyClass^
 }
-    ''';
+''';
 
     await initializeServer();
 
@@ -123,7 +123,7 @@
 void f() {
   MyClass^
 }
-    ''';
+''';
 
     await initializeServer();
 
@@ -149,7 +149,7 @@
 void f() {
   MyClass^
 }
-    ''';
+''';
 
     await initializeServer();
 
@@ -173,7 +173,7 @@
 void f() {
   MyEnum^
 }
-    ''';
+''';
 
     await initializeServer();
 
@@ -210,7 +210,7 @@
 void f() {
   enumFunc(MyEnum^)
 }
-    ''';
+''';
 
     await initializeServer();
 
@@ -238,7 +238,7 @@
 class A {}
 
 A^
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await provideConfig(
@@ -289,7 +289,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await provideConfig(
@@ -385,7 +385,7 @@
   @^
   int a = 1;
 }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -402,7 +402,7 @@
 class B {
   @^
 }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -418,7 +418,7 @@
     final content = '''
     // foo ^
     void f() {}
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -431,7 +431,7 @@
     // at the end of a file would return results.
     final content = '''
     // foo ^
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -650,7 +650,7 @@
     return const Placeholder();
   }
 }
-    ''';
+''';
 
     await provideConfig(
       () => initialize(
@@ -700,7 +700,7 @@
     void f() {
       [[myFu^]]
     }
-    ''';
+''';
 
     await checkCompleteFunctionCallInsertText(
       content,
@@ -717,7 +717,7 @@
     void f() {
       [[myFu^]]
     }
-    ''';
+''';
 
     await checkCompleteFunctionCallInsertText(
       content,
@@ -735,7 +735,7 @@
     void f() {
       [[myFu^]]
     }
-    ''';
+''';
 
     await provideConfig(
       () => initialize(
@@ -768,7 +768,7 @@
     void f() {
       [[myFu^]]
     }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await provideConfig(
@@ -814,7 +814,7 @@
     // Now, we never supply `insertText` and always use `textEdit`.
     final content = '''
 final a = Stri^
-    ''';
+''';
 
     /// Helper to verify a completion is as expected.
     void expectCorrectCompletion(CompletionItem item) {
@@ -852,7 +852,7 @@
   Future<void> test_completeFunctionCalls_show() async {
     final content = '''
     import 'dart:math' show mi^
-    ''';
+''';
 
     await provideConfig(
       () => initialize(
@@ -953,7 +953,7 @@
       MyClass a;
       a.abc^
     }
-    ''';
+''';
 
     // Tell the server we only support the Field CompletionItemKind.
     await initialize(
@@ -975,7 +975,7 @@
     // Brace should not trigger completion if a normal code block.
     final content = r'''
     main () {^}
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, ['{'], isEmpty);
   }
 
@@ -984,7 +984,7 @@
     // Brace should trigger completion if at the start of an interpolated expression
     final content = r'''
     var a = '${^';
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r'{'], isNotEmpty);
   }
 
@@ -992,7 +992,7 @@
     // Brace should not trigger completion if in a raw string.
     final content = r'''
     var a = r'${^';
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r'{'], isEmpty);
   }
 
@@ -1001,7 +1001,7 @@
     // expression.
     final content = r'''
     var a = '{^';
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r'{'], isEmpty);
   }
 
@@ -1011,7 +1011,7 @@
 void f({int? a}) {
   f(a:^
 }
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r':'], isNotEmpty);
   }
 
@@ -1023,7 +1023,7 @@
     case:^
   }
 }
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r':'], isEmpty);
   }
 
@@ -1035,7 +1035,7 @@
     default:^
   }
 }
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r':'], isEmpty);
   }
 
@@ -1043,7 +1043,7 @@
     // Colons should trigger completion after argument names.
     final content = r'''
 import 'package:^';
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r':'], isNotEmpty);
   }
 
@@ -1076,7 +1076,7 @@
     // after typing 'package:foo/' completion should give the next folder segments.
     final content = r'''
     import 'package:test/^';
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r'/'], isNotEmpty);
   }
 
@@ -1084,7 +1084,7 @@
     // Slashes should not trigger completion when typing in a normal expression.
     final content = r'''
     var a = 1 /^
-    ''';
+''';
     await _checkResultsForTriggerCharacters(content, [r'/'], isEmpty);
   }
 
@@ -1151,7 +1151,7 @@
     class Student extends Person {
       nam^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -1174,7 +1174,7 @@
       var x = '';
       print(^);
     }
-    ''';
+''';
 
     final pluginResult = plugin.CompletionGetSuggestionsResult(
       content.indexOf('^'),
@@ -1210,7 +1210,7 @@
 void f() {
   ^
 }
-    ''';
+''';
 
     final pluginResult = plugin.CompletionGetSuggestionsResult(
       content.indexOf('^'),
@@ -1253,7 +1253,7 @@
 void f() {
   fooFromDartIO
 }
-    '''));
+'''));
   }
 
   Future<void> test_fromPlugin_nonDartFile() async {
@@ -1266,7 +1266,7 @@
     );
 
     query: SELECT ^ FROM foo;
-    ''';
+''';
 
     final pluginResult = plugin.CompletionGetSuggestionsResult(
       content.indexOf('^'),
@@ -1304,7 +1304,7 @@
       var x = '';
       print(^);
     }
-    ''';
+''';
 
     final pluginResult = plugin.CompletionGetSuggestionsResult(
       content.indexOf('^'),
@@ -1361,7 +1361,7 @@
 }
 
 abstract class MyItem implements NotNullableName, NullableName {}
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -1383,7 +1383,7 @@
       MyClass a;
       a.^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -1475,7 +1475,7 @@
       MyClass a;
       a.abc^def
     }
-    ''';
+''';
 
     await initialize(
       textDocumentCapabilities: withCompletionItemInsertReplaceSupport(
@@ -1512,7 +1512,7 @@
         return const Placeholder();
       }
     }
-    ''';
+''';
 
     await initialize(
         textDocumentCapabilities: withCompletionItemInsertTextModeSupport(
@@ -1533,7 +1533,7 @@
     void foo() {
       ^
     }
-    ''';
+''';
 
     await initialize(
         textDocumentCapabilities: withCompletionItemInsertTextModeSupport(
@@ -1553,7 +1553,7 @@
   Future<void> test_insideString() async {
     final content = '''
     var a = "This is ^a test"
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -1572,7 +1572,7 @@
       MyClass a;
       a.abc^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -1595,7 +1595,7 @@
       MyClass a;
       a.abc^
     }
-    ''';
+''';
 
     await initialize(
         textDocumentCapabilities: withCompletionItemDeprecatedFlagSupport(
@@ -1620,7 +1620,7 @@
       MyClass a;
       a.abc^
     }
-    ''';
+''';
 
     await initialize(
         textDocumentCapabilities: withCompletionItemTagSupport(
@@ -1642,7 +1642,7 @@
   A a = A();
   a.^
 }
-    ''';
+''';
 
     // Create a class with fields aaa1 to aaa500 in the other file.
     newFile(
@@ -1675,7 +1675,7 @@
   A a = A();
   a.^
 }
-    ''';
+''';
 
     // Create a class with fields aaa1 to aaa500 in the other file.
     newFile(
@@ -1714,7 +1714,7 @@
     void myFunction() {
       [[myFunctio^]]
     }
-    ''';
+''';
 
     await initialize(
       textDocumentCapabilities: withCompletionItemInsertReplaceSupport(
@@ -1756,7 +1756,7 @@
 void f(String a, {String? b}) {
   f([[^b]]);
 }
-    ''';
+''';
 
     await initialize(
       textDocumentCapabilities: withCompletionItemInsertReplaceSupport(
@@ -1811,7 +1811,7 @@
         return const Placeholder();
       }
     }
-    ''';
+''';
 
     await initialize(
       textDocumentCapabilities: withCompletionItemInsertTextModeSupport(
@@ -1840,7 +1840,7 @@
 void f() {
   var a = Item^
 }
-    ''';
+''';
 
     // Create classes `Item1` to `Item20` along with a field named `item`.
     // The classes will rank higher in the position above and push
@@ -1886,7 +1886,7 @@
 void f() {
   fo^
 }
-    ''';
+''';
 
     // Create fields for1 to for20 in the other file.
     newFile(
@@ -2077,7 +2077,7 @@
     }
 
     void myFunction({String aaaa, String aaab, String aaac}) {}
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2090,7 +2090,7 @@
     class A { const A({int one}); }
     @A(^)
     void f() { }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2114,7 +2114,7 @@
     class A { const A({int one}); }
     @A(^)
     void f() { }
-    ''';
+''';
 
     await initialize(
         textDocumentCapabilities: withCompletionItemSnippetSupport(
@@ -2147,7 +2147,7 @@
         two: 2,
       );
     }
-    ''';
+''';
 
     await initialize(
         textDocumentCapabilities: withCompletionItemSnippetSupport(
@@ -2186,7 +2186,7 @@
     void f() {
       fo^
     }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize();
@@ -2205,7 +2205,7 @@
     void f() {
       MyClass a = new MyCla^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2228,7 +2228,7 @@
       MyClass a;
       a.abc^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2255,7 +2255,7 @@
       // Should match only Two and Three
       UniqueNamedClassForLspT^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2275,7 +2275,7 @@
       // Should match only Two and Three
       UniqueNamedClassForLspT^hree
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2295,7 +2295,7 @@
       // Should match all three
       ^UniqueNamedClassForLspT
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2318,7 +2318,7 @@
       MyClass a;
       a.^
     }
-    ''';
+''';
 
     await initialize();
     await openFile(mainFileUri, withoutMarkers(content));
@@ -2353,7 +2353,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2410,7 +2410,7 @@
 void f() {
   InOtherFile
 }
-    '''));
+'''));
   }
 
   Future<void> test_unimportedSymbols_dartDocPreference_full() =>
@@ -2460,7 +2460,7 @@
 void f() {
   MyExported^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2504,7 +2504,7 @@
 void f() {
   MyExported^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2538,7 +2538,7 @@
 void f() {
   MyDuplicated^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2585,7 +2585,7 @@
 void f() {
   x(MyExported^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2637,7 +2637,7 @@
 void f() {
   x(MyExportedEnum.One
 }
-    '''));
+'''));
   }
 
   Future<void> test_unimportedSymbols_enumValuesAlreadyImported() async {
@@ -2668,7 +2668,7 @@
 void f() {
   x(MyExported^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2712,7 +2712,7 @@
 void f() {
   MyExported^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2739,7 +2739,7 @@
 void f() {
   MyClas^
 }
-    ''';
+''';
 
     final expectedContent = '''
 import 'package:test/my_class.dart';
@@ -2747,7 +2747,7 @@
 void f() {
   MyClass
 }
-    ''';
+''';
 
     final completionLabel = 'MyClass';
 
@@ -2771,7 +2771,7 @@
 void f() {
   ''.myExtensionMet^
 }
-    ''';
+''';
 
     final expectedContent = '''
 import 'package:test/my_extension.dart';
@@ -2779,7 +2779,7 @@
 void f() {
   ''.myExtensionMethod
 }
-    ''';
+''';
 
     final completionLabel = 'myExtensionMethod()';
     await _checkCompletionEdits(
@@ -2815,7 +2815,7 @@
 void f() {
   MyExported^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2850,7 +2850,7 @@
 void f() {
   InOtherF^il
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2918,7 +2918,7 @@
 void f() {
   InOtherFile
 }
-    '''));
+'''));
     // In insert mode, we'd have the trailing "il" still after the caret.
     expect(newContentInsertMode, equals('''
 import '../other_file.dart';
@@ -2926,22 +2926,26 @@
 void f() {
   InOtherFileil
 }
-    '''));
+'''));
   }
 
   Future<void> test_unimportedSymbols_insertsIntoPartFiles() async {
     // File we'll be adding an import for.
     newFile(
       join(projectFolderPath, 'other_file.dart'),
-      'class InOtherFile {}',
+      ''''
+class InOtherFile {}
+''',
     );
 
     // File that will have the import added.
-    final parentContent = '''part 'main.dart';''';
-    final parentFilePath = newFile(
+    final parentContent = '''
+part 'main.dart';
+''';
+    newFile(
       join(projectFolderPath, 'lib', 'parent.dart'),
       parentContent,
-    ).path;
+    );
 
     // File that we're invoking completion in.
     final content = '''
@@ -2949,7 +2953,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -2983,41 +2987,14 @@
 void f() {
   InOtherFile
 }
-    '''));
+'''));
 
-    // Execute the associated command (which will handle edits in other files).
-    ApplyWorkspaceEditParams? editParams;
-    final commandResponse = await handleExpectedRequest<Object?,
-        ApplyWorkspaceEditParams, ApplyWorkspaceEditResult>(
-      Method.workspace_applyEdit,
-      ApplyWorkspaceEditParams.fromJson,
-      () => executeCommand(resolved.command!),
-      handler: (edit) {
-        // When the server sends the edit back, just keep a copy and say we
-        // applied successfully (it'll be verified below).
-        editParams = edit;
-        return ApplyWorkspaceEditResult(applied: true);
-      },
-    );
-    // Successful edits return an empty success() response.
-    expect(commandResponse, isNull);
-
-    // Ensure the edit came back.
-    expect(editParams, isNotNull);
-    expect(editParams!.edit.changes, isNotNull);
-
-    // Ensure applying the changes will give us the expected content.
-    final contents = {
-      parentFilePath: withoutMarkers(parentContent),
-    };
-    applyChanges(contents, editParams!.edit.changes!);
-
-    // Check the parent file was modified to include the import by the edits
-    // that came from the server.
-    expect(contents[parentFilePath], equals('''
+    await verifyCommandEdits(resolved.command!, '''
+>>>>>>>>>> lib/parent.dart
 import '../other_file.dart';
 
-part 'main.dart';'''));
+part 'main.dart';
+''');
   }
 
   Future<void>
@@ -3026,7 +3003,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -3056,7 +3033,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -3127,7 +3104,7 @@
 void f() {
   var a = InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -3168,7 +3145,7 @@
 void f() {
   var a = InOtherFile.fromJson
 }
-    '''));
+'''));
   }
 
   Future<void> test_unimportedSymbols_overrides() async {
@@ -3202,7 +3179,7 @@
 class BaseImpl extends Base {
   myMet^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize(
@@ -3238,7 +3215,7 @@
     return super.myMethod(a, b, c);
   }
 }
-    '''));
+'''));
   }
 
   Future<void>
@@ -3257,7 +3234,7 @@
 void f() {
   MyClas^
 }
-    ''';
+''';
 
     final expectedContent = '''
 import '../nested2/imported.dart';
@@ -3265,7 +3242,7 @@
 void f() {
   MyClass
 }
-    ''';
+''';
 
     final completionLabel = 'MyClass';
 
@@ -3295,7 +3272,7 @@
 void f() {
   MyClas^
 }
-    ''';
+''';
 
     final expectedContent = '''
 import 'package:test/nested2/imported.dart';
@@ -3303,7 +3280,7 @@
 void f() {
   MyClass
 }
-    ''';
+''';
 
     final completionLabel = 'MyClass';
 
@@ -3325,7 +3302,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     // Support applyEdit, but explicitly disable the suggestions.
@@ -3360,7 +3337,7 @@
 void f() {
   InOtherF^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initialize();
@@ -3384,7 +3361,7 @@
       MyClass a;
       a.abc^
     }
-    ''';
+''';
 
     newFile(mainFilePath, withoutMarkers(content));
     await initialize();
@@ -3533,7 +3510,7 @@
 void f() {
   ^
 }
-    ''';
+''';
 
     final initialAnalysis = waitForAnalysisComplete();
     await initializeWithSnippetSupport();
diff --git a/pkg/analysis_server/test/lsp/rename_test.dart b/pkg/analysis_server/test/lsp/rename_test.dart
index 973e6ce..7ba81a2 100644
--- a/pkg/analysis_server/test/lsp/rename_test.dart
+++ b/pkg/analysis_server/test/lsp/rename_test.dart
@@ -281,9 +281,11 @@
             withResourceOperationKinds(emptyWorkspaceClientCapabilities,
                 [ResourceOperationKind.Rename])),
       );
-      // Ensure we now only have the newly-renamed file and not the old one
-      // (its contents will have been checked by the function above).
-      expect(contents.keys.single, equals(newMainFilePath));
+
+      expect(contents, hasLength(2));
+      expect(contents[newMainFilePath], expectedContent);
+      expect(contents.containsKey(mainFilePath), isTrue);
+      expect(contents[mainFilePath], isNull); // Deleted (renamed)
     }
 
     /// Helper that will respond to the window/showMessageRequest request from
@@ -337,9 +339,11 @@
               withResourceOperationKinds(emptyWorkspaceClientCapabilities,
                   [ResourceOperationKind.Rename])),
         );
-        // Ensure we now only have the newly-renamed file and not the old one
-        // (its contents will have been checked by the function above).
-        expect(contents.keys.single, equals(newMainFilePath));
+
+        expect(contents, hasLength(2));
+        expect(contents[newMainFilePath], expectedContent);
+        expect(contents.containsKey(mainFilePath), isTrue);
+        expect(contents[mainFilePath], isNull); // Deleted (renamed)
       },
       {'renameFilesWithClasses': 'always'},
     );
@@ -387,9 +391,8 @@
         );
         // Expect that main was renamed to my_new_main and the other file was
         // updated.
-        expect(contents.containsKey(mainFilePath), isFalse);
-        expect(contents.containsKey(newMainFilePath), isTrue);
-        expect(contents.containsKey(otherFilePath), isTrue);
+        expect(contents.containsKey(mainFilePath), isTrue);
+        expect(contents[mainFilePath], isNull); // Deleted (renamed)
         expect(contents[newMainFilePath], expectedContent);
         expect(contents[otherFilePath], expectedOtherContent);
       },
@@ -1013,7 +1016,7 @@
     );
   }
 
-  Future<Map<String, String>> _test_rename_withDocumentChanges(
+  Future<Map<String, String?>> _test_rename_withDocumentChanges(
     String content,
     String newName,
     String? expectedContent, {
@@ -1022,7 +1025,7 @@
     bool sendRenameVersion = true,
     WorkspaceClientCapabilities? workspaceCapabilities,
     bool supportsWindowShowMessageRequest = true,
-    Map<String, String>? contents,
+    Map<String, String?>? contents,
   }) async {
     contents ??= {};
     filePath ??= mainFilePath;
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 2bfda56..2262c1c 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -101,10 +101,99 @@
     return info;
   }
 
+  /// Executes [command] which is expected to call back to the client to apply
+  /// a [WorkspaceEdit].
+  ///
+  /// Changes are applied to [contents] to be verified by the caller.
+  Future<void> executeCommandForEdits(
+    Command command,
+    Map<String, String?> contents, {
+    bool expectDocumentChanges = false,
+    ProgressToken? workDoneToken,
+  }) async {
+    ApplyWorkspaceEditParams? editParams;
+
+    final commandResponse = await handleExpectedRequest<Object?,
+        ApplyWorkspaceEditParams, ApplyWorkspaceEditResult>(
+      Method.workspace_applyEdit,
+      ApplyWorkspaceEditParams.fromJson,
+      () => executeCommand(command, workDoneToken: workDoneToken),
+      handler: (edit) {
+        // When the server sends the edit back, just keep a copy and say we
+        // applied successfully (it'll be verified by the caller).
+        editParams = edit;
+        return ApplyWorkspaceEditResult(applied: true);
+      },
+    );
+    // Successful edits return an empty success() response.
+    expect(commandResponse, isNull);
+
+    // Ensure the edit came back, and using the expected change type.
+    expect(editParams, isNotNull);
+    final edit = editParams!.edit;
+    if (expectDocumentChanges) {
+      expect(edit.changes, isNull);
+      expect(edit.documentChanges, isNotNull);
+      applyDocumentChanges(contents, edit.documentChanges!);
+    } else {
+      expect(edit.changes, isNotNull);
+      expect(edit.documentChanges, isNull);
+      applyChanges(contents, edit.changes!);
+    }
+  }
+
+  void expectChanges(Map<Uri, List<TextEdit>> changes, String expected) {
+    final editedContents = <String, String?>{};
+    applyChanges(editedContents, changes);
+    expectEditedContent(editedContents, expected);
+  }
+
   void expectContextBuilds() =>
       expect(server.contextBuilds - _previousContextBuilds, greaterThan(0),
           reason: 'Contexts should have been rebuilt');
 
+  Map<String, String?> expectDocumentChanges(
+    List<Either4<CreateFile, DeleteFile, RenameFile, TextDocumentEdit>> changes,
+    String expected,
+  ) {
+    final editedContents = <String, String?>{};
+    applyDocumentChanges(editedContents, changes);
+    expectEditedContent(editedContents, expected);
+    return editedContents;
+  }
+
+  void expectEditedContent(
+      Map<String, String?> editedContents, String expected) {
+    final buffer = StringBuffer();
+    for (final entry in editedContents.entries.sortedBy((entry) => entry.key)) {
+      // Write the path in a common format for Windows/non-Windows.
+      final relativePath = path
+          .relative(
+            entry.key,
+            from: projectFolderPath,
+          )
+          .replaceAll(r'\', '/');
+      final content = entry.value;
+      // TODO(dantup): Extract this (and the applying of edits) to a class
+      //  that can also update the test expectations, and record renames better
+      //  than just a delete/create.
+      if (content == null) {
+        buffer.write('>>>>>>>>>> $relativePath deleted\n');
+      } else if (content.trim().isEmpty) {
+        buffer.write('>>>>>>>>>> $relativePath empty\n');
+      } else {
+        buffer.write('>>>>>>>>>> $relativePath\n$content');
+        // If the content didn't end with a newline we need to add one, but
+        // add a marked so it's clear there was no trailing newline.
+        if (!content.endsWith('\n')) {
+          buffer.write('<<<<<<<<<<\n');
+        }
+      }
+    }
+
+    expect(buffer.toString().trim(), equals(expected.trim()));
+  }
+
   void expectNoContextBuilds() =>
       expect(server.contextBuilds - _previousContextBuilds, equals(0),
           reason: 'Contexts should not have been rebuilt');
@@ -124,6 +213,17 @@
     }
   }
 
+  @override
+  String? getCurrentFileContent(Uri uri) {
+    try {
+      return server.resourceProvider
+          .getFile(uri.toFilePath())
+          .readAsStringSync();
+    } catch (_) {
+      return null;
+    }
+  }
+
   /// Finds the registration for a given LSP method.
   Registration? registrationFor(
     List<Registration> registrations,
@@ -239,6 +339,27 @@
     await server.shutdown();
   }
 
+  /// Verifies that executing the given command on the server results in an edit
+  /// being sent in the client that updates the files to match the expected
+  /// content.
+  Future<void> verifyCommandEdits(
+    Command command,
+    String expectedContent, {
+    bool expectDocumentChanges = false,
+    ProgressToken? workDoneToken,
+  }) async {
+    final contents = <String, String?>{};
+
+    await executeCommandForEdits(
+      command,
+      contents,
+      expectDocumentChanges: expectDocumentChanges,
+      workDoneToken: workDoneToken,
+    );
+
+    expectEditedContent(contents, expectedContent);
+  }
+
   /// Adds a trailing slash (direction based on path context) to [path].
   ///
   /// Throws if the path already has a trailing slash.
@@ -771,17 +892,20 @@
   Stream<Message> get serverToClient;
 
   void applyChanges(
-    Map<String, String> fileContents,
+    Map<String, String?> editedContents,
     Map<Uri, List<TextEdit>> changes,
   ) {
     changes.forEach((fileUri, edits) {
-      final path = fileUri.toFilePath();
-      fileContents[path] = applyTextEdits(fileContents[path]!, edits);
+      final filePath = fileUri.toFilePath();
+      final currentContent = editedContents.containsKey(filePath)
+          ? editedContents[filePath]
+          : getCurrentFileContent(fileUri);
+      editedContents[filePath] = applyTextEdits(currentContent!, edits);
     });
   }
 
   void applyDocumentChanges(
-    Map<String, String> fileContents,
+    Map<String, String?> editedContent,
     List<Either4<CreateFile, DeleteFile, RenameFile, TextDocumentEdit>>
         documentChanges, {
     Map<String, int>? expectedVersions,
@@ -791,41 +915,72 @@
     if (expectedVersions != null) {
       expectDocumentVersions(documentChanges, expectedVersions);
     }
-    applyResourceChanges(fileContents, documentChanges);
+    applyResourceChanges(editedContent, documentChanges);
   }
 
   void applyResourceChanges(
-    Map<String, String> oldFileContent,
+    Map<String, String?> editedContent,
     List<Either4<CreateFile, DeleteFile, RenameFile, TextDocumentEdit>> changes,
   ) {
     for (final change in changes) {
       change.map(
-        (create) => applyResourceCreate(oldFileContent, create),
-        (delete) => throw 'applyResourceChanges:Delete not currently supported',
-        (rename) => applyResourceRename(oldFileContent, rename),
-        (textDocEdit) => applyTextDocumentEdits(oldFileContent, [textDocEdit]),
+        (create) => applyResourceCreate(editedContent, create),
+        (delete) => applyResourceDelete(editedContent, delete),
+        (rename) => applyResourceRename(editedContent, rename),
+        (textDocEdit) => applyTextDocumentEdits(editedContent, [textDocEdit]),
       );
     }
   }
 
   void applyResourceCreate(
-      Map<String, String> oldFileContent, CreateFile create) {
-    final path = create.uri.toFilePath();
-    if (oldFileContent.containsKey(path)) {
-      throw 'Received create instruction for $path which already existed.';
+      Map<String, String?> editedContent, CreateFile create) {
+    final uri = create.uri;
+    final path = uri.toFilePath();
+    final currentContent = editedContent.containsKey(path)
+        ? editedContent[path]
+        : getCurrentFileContent(uri);
+    if (currentContent != null) {
+      throw 'Received create instruction for $path which already exists';
     }
-    oldFileContent[path] = '';
+    editedContent[path] = '';
+  }
+
+  void applyResourceDelete(
+      Map<String, String?> editedContent, DeleteFile delete) {
+    final uri = delete.uri;
+    final path = uri.toFilePath();
+    final currentContent = editedContent.containsKey(path)
+        ? editedContent[path]
+        : getCurrentFileContent(uri);
+
+    if (currentContent == null) {
+      throw 'Received delete instruction for $path which does not exist';
+    }
+
+    editedContent[path] = null;
   }
 
   void applyResourceRename(
-      Map<String, String> oldFileContent, RenameFile rename) {
-    final oldPath = rename.oldUri.toFilePath();
-    final newPath = rename.newUri.toFilePath();
-    if (!oldFileContent.containsKey(oldPath)) {
-      throw 'Received rename instruction for $oldPath which did not exist.';
+      Map<String, String?> editedContent, RenameFile rename) {
+    final oldUri = rename.oldUri;
+    final newUri = rename.newUri;
+    final oldPath = oldUri.toFilePath();
+    final newPath = newUri.toFilePath();
+
+    final oldContent = editedContent.containsKey(oldPath)
+        ? editedContent[oldPath]
+        : getCurrentFileContent(oldUri);
+    final newContent = editedContent.containsKey(newPath)
+        ? editedContent[newPath]
+        : getCurrentFileContent(newUri);
+
+    if (oldContent == null) {
+      throw 'Received rename instruction from $oldPath which did not exist';
+    } else if (newContent != null) {
+      throw 'Received rename instruction to $newPath which already exists';
     }
-    oldFileContent[newPath] = oldFileContent[oldPath]!;
-    oldFileContent.remove(oldPath);
+    editedContent[newPath] = oldContent;
+    editedContent[oldPath] = null;
   }
 
   String applyTextDocumentEdit(String content, TextDocumentEdit edit) {
@@ -843,14 +998,19 @@
   }
 
   void applyTextDocumentEdits(
-      Map<String, String> oldFileContent, List<TextDocumentEdit> edits) {
+      Map<String, String?> editedContent, List<TextDocumentEdit> edits) {
     for (var edit in edits) {
-      final path = edit.textDocument.uri.toFilePath();
-      if (!oldFileContent.containsKey(path)) {
-        throw 'Received edits for $path which was not provided as a file to be edited. '
+      final uri = edit.textDocument.uri;
+      final path = uri.toFilePath();
+
+      final currentContent = editedContent.containsKey(path)
+          ? editedContent[path]
+          : getCurrentFileContent(uri);
+      if (currentContent == null) {
+        throw 'Received edits for $path which does not exist. '
             'Perhaps a CreateFile change was missing from the edits?';
       }
-      oldFileContent[path] = applyTextDocumentEdit(oldFileContent[path]!, edit);
+      editedContent[path] = applyTextDocumentEdit(currentContent, edit);
     }
   }
 
@@ -1202,6 +1362,13 @@
     return expectSuccessfulResponseTo(request, CompletionList.fromJson);
   }
 
+  /// Gets the current contents of a file.
+  ///
+  /// This is used to apply edits when the server sends workspace/applyEdit. It
+  /// should reflect the content that the client would have in this case, which
+  /// would be an overlay (if the file is open) or the underlying file.
+  String? getCurrentFileContent(Uri uri);
+
   Future<Either2<List<Location>, List<LocationLink>>> getDefinition(
       Uri uri, Position pos) {
     final request = makeRequest(
diff --git a/pkg/analysis_server/test/src/services/refactoring/convert_all_formal_parameters_to_named_test.dart b/pkg/analysis_server/test/src/services/refactoring/convert_all_formal_parameters_to_named_test.dart
index 41adfbd..7397aa0 100644
--- a/pkg/analysis_server/test/src/services/refactoring/convert_all_formal_parameters_to_named_test.dart
+++ b/pkg/analysis_server/test/src/services/refactoring/convert_all_formal_parameters_to_named_test.dart
@@ -27,7 +27,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({required int? a}) {}
 
 void f() {
@@ -45,7 +46,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({required int a}) {}
 
 void f() {
@@ -63,7 +65,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({required int? a}) {}
 
 void f() {
@@ -81,7 +84,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({required int a}) {}
 
 void f() {
@@ -93,7 +97,7 @@
   Future<void> test_multiple_files() async {
     // TODO(scheglov) Unify behind `testPackageLibPath`
     final a = getFile('$projectFolderPath/lib/a.dart');
-    addSource(a.path, r'''
+    newFile(a.path, r'''
 import 'main.dart';
 
 void f2() {
@@ -109,33 +113,19 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
-void test({required int a}) {}
-
-void f() {
-  test(a: 0);
-}
-''');
-
-    // TODO(scheglov) Ask me, if you want more of this opinion.
-    // This is bad code.
-    // I don't like using content for verifying refactoring results.
-    // We need to check all changes, without a way to check only some portion.
-    // See how _writeSourceChangeToBuffer is done.
-    //
-    // And addSource() above is another hack that we rely on to support these
-    // checks here.
-    // I don't like these too.
-    // We have newFile() already, this should be enough.
-    // Don't invent more way to add files.
-    // I worked hard in DAS legacy tests to get away from it.
-    // Don't add them back.
-    assertTextExpectation(content[a.path]!, r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/a.dart
 import 'main.dart';
 
 void f2() {
   test(a: 1);
 }
+>>>>>>>>>> lib/main.dart
+void test({required int a}) {}
+
+void f() {
+  test(a: 0);
+}
 ''');
   }
 
@@ -168,7 +158,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({required int a}) {}
 
 void f() {
@@ -186,7 +177,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({required int a}) {}
 
 void f() {
@@ -195,23 +187,22 @@
 ''');
   }
 
-  Future<void> _assertNoRefactoring() async {
-    await initializeServer();
-
-    await expectNoCodeAction(
-      ConvertAllFormalParametersToNamed.constTitle,
-    );
-  }
-
-  Future<void> _executeRefactoring(String expected) async {
+  Future<void> verifyRefactoring(String expected) async {
     await initializeServer();
 
     final codeAction = await expectCodeAction(
       ConvertAllFormalParametersToNamed.constTitle,
     );
 
-    await executeRefactor(codeAction);
+    await verifyCommandEdits(codeAction.command!, expected,
+        expectDocumentChanges: true);
+  }
 
-    assertTextExpectation(content[mainFilePath]!, expected);
+  Future<void> _assertNoRefactoring() async {
+    await initializeServer();
+
+    await expectNoCodeAction(
+      ConvertAllFormalParametersToNamed.constTitle,
+    );
   }
 }
diff --git a/pkg/analysis_server/test/src/services/refactoring/convert_selected_formal_parameters_to_named_test.dart b/pkg/analysis_server/test/src/services/refactoring/convert_selected_formal_parameters_to_named_test.dart
index ed69b2d..0814dea 100644
--- a/pkg/analysis_server/test/src/services/refactoring/convert_selected_formal_parameters_to_named_test.dart
+++ b/pkg/analysis_server/test/src/services/refactoring/convert_selected_formal_parameters_to_named_test.dart
@@ -28,7 +28,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({int a, required int b, required int c, int d}) {}
 
 void f() {
@@ -46,7 +47,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, {required int b, required int c}) {}
 
 void f() {
@@ -93,7 +95,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, int d, {required int b, required int c}) {}
 
 void f() {
@@ -111,7 +114,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, {required int b}) {}
 
 void f() {
@@ -129,7 +133,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, {required int b, int c}) {}
 
 void f() {
@@ -147,7 +152,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, {required int? b}) {}
 
 void f() {
@@ -189,7 +195,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int b, {required int a}) {}
 
 void f() {
@@ -207,7 +214,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, {required int b}) {}
 
 void f() {
@@ -225,7 +233,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, int c, {required int b}) {}
 
 void f() {
@@ -245,7 +254,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   required int b,
   required int a,
@@ -269,23 +279,22 @@
     await _assertNoRefactoring();
   }
 
-  Future<void> _assertNoRefactoring() async {
-    await initializeServer();
-
-    await expectNoCodeAction(
-      ConvertSelectedFormalParametersToNamed.constTitle,
-    );
-  }
-
-  Future<void> _executeRefactoring(String expected) async {
+  Future<void> verifyRefactoring(String expected) async {
     await initializeServer();
 
     final codeAction = await expectCodeAction(
       ConvertSelectedFormalParametersToNamed.constTitle,
     );
 
-    await executeRefactor(codeAction);
+    await verifyCommandEdits(codeAction.command!, expected,
+        expectDocumentChanges: true);
+  }
 
-    assertTextExpectation(content[mainFilePath]!, expected);
+  Future<void> _assertNoRefactoring() async {
+    await initializeServer();
+
+    await expectNoCodeAction(
+      ConvertSelectedFormalParametersToNamed.constTitle,
+    );
   }
 }
diff --git a/pkg/analysis_server/test/src/services/refactoring/move_selected_formal_parameters_left_test.dart b/pkg/analysis_server/test/src/services/refactoring/move_selected_formal_parameters_left_test.dart
index 504b820..366061b 100644
--- a/pkg/analysis_server/test/src/services/refactoring/move_selected_formal_parameters_left_test.dart
+++ b/pkg/analysis_server/test/src/services/refactoring/move_selected_formal_parameters_left_test.dart
@@ -49,7 +49,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   required int b,
   required int c,
@@ -84,7 +85,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, int c, int d, int b, int e) {}
 
 void f() {
@@ -102,7 +104,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int b, int c, int a, int d) {}
 
 void f() {
@@ -124,7 +127,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   int? b,
   int? a,
@@ -150,7 +154,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   int? b,
   required int? a,
@@ -184,7 +189,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test([int b, int a, int c]) {}
 
 void f() {
@@ -237,7 +243,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   required int a,
   required int c,
@@ -264,7 +271,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   required int a,
   required int c,
@@ -291,7 +299,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test({
   required int b,
   required int a,
@@ -325,7 +334,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int a, int c, int b) {}
 
 void f() {
@@ -343,7 +353,8 @@
 }
 ''');
 
-    await _executeRefactoring(r'''
+    await verifyRefactoring(r'''
+>>>>>>>>>> lib/main.dart
 void test(int b, int a, int c) {}
 
 void f() {
@@ -352,23 +363,22 @@
 ''');
   }
 
-  Future<void> _assertNoRefactoring() async {
-    await initializeServer();
-
-    await expectNoCodeAction(
-      MoveSelectedFormalParametersLeft.constTitle,
-    );
-  }
-
-  Future<void> _executeRefactoring(String expected) async {
+  Future<void> verifyRefactoring(String expected) async {
     await initializeServer();
 
     final codeAction = await expectCodeAction(
       MoveSelectedFormalParametersLeft.constTitle,
     );
 
-    await executeRefactor(codeAction);
+    await verifyCommandEdits(codeAction.command!, expected,
+        expectDocumentChanges: true);
+  }
 
-    assertTextExpectation(content[mainFilePath]!, expected);
+  Future<void> _assertNoRefactoring() async {
+    await initializeServer();
+
+    await expectNoCodeAction(
+      MoveSelectedFormalParametersLeft.constTitle,
+    );
   }
 }
diff --git a/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart b/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart
index 9a8a252..1f7b1dc 100644
--- a/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart
+++ b/pkg/analysis_server/test/src/services/refactoring/move_top_level_to_file_test.dart
@@ -5,7 +5,6 @@
 import 'package:analysis_server/lsp_protocol/protocol.dart';
 import 'package:analysis_server/src/services/refactoring/move_top_level_to_file.dart';
 import 'package:analyzer/src/test_utilities/test_code_format.dart';
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'refactoring_test_support.dart';
@@ -40,10 +39,10 @@
   /// Test that references to getter/setters in different libraries used in
   /// a compound assignment are both imported into the destination file.
   Future<void> test_compoundAssignment_multipleLibraries() async {
-    addSource('$projectFolderPath/lib/getter.dart', '''
+    newFile('$projectFolderPath/lib/getter.dart', '''
 int get splitVariable => 0;
 ''');
-    addSource('$projectFolderPath/lib/setter.dart', '''
+    newFile('$projectFolderPath/lib/setter.dart', '''
 set splitVariable(num _) {}
 ''');
 
@@ -55,26 +54,26 @@
   splitVariable += 1;
 }
 ''';
-    var modifiedSource = '''
-import 'package:test/getter.dart';
-import 'package:test/setter.dart';
-''';
     var declarationName = 'functionToMove';
-    var newFileName = 'function_to_move.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/function_to_move.dart
 import 'package:test/getter.dart';
 import 'package:test/setter.dart';
 
 void functionToMove() {
   splitVariable += 1;
 }
+>>>>>>>>>> lib/main.dart
+import 'package:test/getter.dart';
+import 'package:test/setter.dart';
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_copyFileHeader() async {
@@ -87,26 +86,25 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'ClassToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
+// File header.
+
+class ClassToMove {}
+>>>>>>>>>> lib/main.dart
 // File header.
 
 class A {}
 
 class B {}
 ''';
-    var declarationName = 'ClassToMove';
-    var newFileName = 'class_to_move.dart';
-    var newFileContent = '''
-// File header.
-
-class ClassToMove {}
-''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_existingFile() async {
@@ -114,22 +112,23 @@
 
     /// Existing new file contents where 'ClassToMove' will be moved to.
     final newFilePath = join(projectFolderPath, 'lib', 'a.dart');
-    addSource(newFilePath, '''
+    newFile(newFilePath, '''
 int? a;
 ''');
 
     /// Expected updated new file contents.
-    const expectedNewFileContent = '''
+    const expected = '''
+>>>>>>>>>> lib/a.dart
 int? a;
 
 class A {}
+>>>>>>>>>> lib/main.dart empty
 ''';
 
     await initializeServer();
     final action = await expectCodeAction(simpleClassRefactorTitle);
-    await executeRefactor(action);
-
-    expect(content[newFilePath], expectedNewFileContent);
+    await verifyCommandEdits(action.command!, expected,
+        expectDocumentChanges: true);
   }
 
   Future<void> test_existingFile_withHeader() async {
@@ -137,26 +136,27 @@
 
     /// Existing new file contents where 'ClassToMove' will be moved to.
     final newFilePath = join(projectFolderPath, 'lib', 'a.dart');
-    addSource(newFilePath, '''
+    newFile(newFilePath, '''
 // This is a file header
 
 int? a;
 ''');
 
     /// Expected updated new file contents.
-    const expectedNewFileContent = '''
+    const expected = '''
+>>>>>>>>>> lib/a.dart
 // This is a file header
 
 int? a;
 
 class A {}
+>>>>>>>>>> lib/main.dart empty
 ''';
 
     await initializeServer();
     final action = await expectCodeAction(simpleClassRefactorTitle);
-    await executeRefactor(action);
-
-    expect(content[newFilePath], expectedNewFileContent);
+    await verifyCommandEdits(action.command!, expected,
+        expectDocumentChanges: true);
   }
 
   Future<void> test_existingFile_withImports() async {
@@ -164,57 +164,58 @@
 
     /// Existing new file contents where 'ClassToMove' will be moved to.
     final newFilePath = join(projectFolderPath, 'lib', 'a.dart');
-    addSource(newFilePath, '''
+    newFile(newFilePath, '''
 import 'dart:async';
 
 FutureOr<int>? a;
 ''');
 
     /// Expected updated new file contents.
-    const expectedNewFileContent = '''
+    const expected = '''
+>>>>>>>>>> lib/a.dart
 import 'dart:async';
 
 FutureOr<int>? a;
 
 class A {}
+>>>>>>>>>> lib/main.dart empty
 ''';
 
     await initializeServer();
     final action = await expectCodeAction(simpleClassRefactorTitle);
-    await executeRefactor(action);
-
-    expect(content[newFilePath], expectedNewFileContent);
+    await verifyCommandEdits(action.command!, expected,
+        expectDocumentChanges: true);
   }
 
   Future<void> test_imports_declarationInSrc() async {
     var libFilePath = join(projectFolderPath, 'lib', 'a.dart');
     var srcFilePath = join(projectFolderPath, 'lib', 'src', 'a.dart');
-    addSource(libFilePath, 'export "src/a.dart";');
-    addSource(srcFilePath, 'class A {}');
+    newFile(libFilePath, 'export "src/a.dart";');
+    newFile(srcFilePath, 'class A {}');
     var originalSource = '''
 import 'package:test/a.dart';
 
 A? staying;
 A? mov^ing;
 ''';
-    var modifiedSource = '''
+    var declarationName = 'moving';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/a.dart';
 
 A? staying;
-''';
-    var declarationName = 'moving';
-    var newFileName = 'moving.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/a.dart';
 
 A? moving;
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_imports_extensionMethod() async {
@@ -236,28 +237,26 @@
   A().extensionMethod();
 }
 ''';
-    var modifiedSource = '''
-import 'package:test/extensions.dart';
-
-class A {}
-''';
     var declarationName = 'f';
-    var newFileName = 'f.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/f.dart
 import 'package:test/extensions.dart';
 import 'package:test/main.dart';
 
 void f() {
   A().extensionMethod();
 }
+>>>>>>>>>> lib/main.dart
+import 'package:test/extensions.dart';
+
+class A {}
 ''';
 
     await _singleDeclaration(
         originalSource: originalSource,
-        modifiedSource: modifiedSource,
+        expected: expected,
         declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
         otherFilePath: otherFilePath,
         otherFileContent: otherFileContent);
   }
@@ -281,28 +280,26 @@
   A() + A();
 }
 ''';
-    var modifiedSource = '''
-import 'package:test/extensions.dart';
-
-class A {}
-''';
     var declarationName = 'f';
-    var newFileName = 'f.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/f.dart
 import 'package:test/extensions.dart';
 import 'package:test/main.dart';
 
 void f() {
   A() + A();
 }
+>>>>>>>>>> lib/main.dart
+import 'package:test/extensions.dart';
+
+class A {}
 ''';
 
     await _singleDeclaration(
         originalSource: originalSource,
-        modifiedSource: modifiedSource,
+        expected: expected,
         declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
         otherFilePath: otherFilePath,
         otherFileContent: otherFileContent);
   }
@@ -457,27 +454,26 @@
   A().extensionMethod();
 }
 ''';
-    var modifiedSource = '''
+    var movingDeclarationName = 'moving';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/extensions.dart' as other;
 
 class A {}
-''';
-    var movingDeclarationName = 'moving';
-    var newFileName = 'moving.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/extensions.dart' as other;
 import 'package:test/main.dart';
 
 void moving() {
   A().extensionMethod();
 }
+
 ''';
     await _singleDeclaration(
         originalSource: originalSource,
-        modifiedSource: modifiedSource,
+        expected: expected,
         declarationName: movingDeclarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
         otherFilePath: otherFilePath,
         otherFileContent: otherFileContent);
   }
@@ -501,27 +497,26 @@
   A() + A();
 }
 ''';
-    var modifiedSource = '''
+    var movingDeclarationName = 'moving';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/extensions.dart' as other;
 
 class A {}
-''';
-    var movingDeclarationName = 'moving';
-    var newFileName = 'moving.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/extensions.dart' as other;
 import 'package:test/main.dart';
 
 void moving() {
   A() + A();
 }
+
 ''';
     await _singleDeclaration(
         originalSource: originalSource,
-        modifiedSource: modifiedSource,
+        expected: expected,
         declarationName: movingDeclarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
         otherFilePath: otherFilePath,
         otherFileContent: otherFileContent);
   }
@@ -757,26 +752,27 @@
   File? f;
 }
 ''';
-    var modifiedSource = '''
-import 'dart:io';
-
-class A {}
-''';
     var declarationName = 'B';
-    var newFileName = 'b.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/b.dart
 import 'dart:io';
 
 class B {
   File? f;
 }
+>>>>>>>>>> lib/main.dart
+import 'dart:io';
+
+class A {}
+
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_imports_referenceFromMovingToStaying() async {
@@ -785,22 +781,23 @@
 
 class ClassToMove^ extends A {}
 ''';
-    var modifiedSource = '''
-class A {}
-''';
     var declarationName = 'ClassToMove';
-    var newFileName = 'class_to_move.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
 import 'package:test/main.dart';
 
 class ClassToMove extends A {}
+>>>>>>>>>> lib/main.dart
+class A {}
+
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_imports_referenceFromStayingToMoving() async {
@@ -809,22 +806,22 @@
 
 class B^ {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'B';
+
+    var expected = '''
+>>>>>>>>>> lib/b.dart
+class B {}
+>>>>>>>>>> lib/main.dart
 import 'package:test/b.dart';
 
 class A extends B {}
-''';
-    var declarationName = 'B';
-    var newFileName = 'b.dart';
-    var newFileContent = '''
-class B {}
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_imports_referenceInThirdFile_noPrefix() async {
@@ -833,35 +830,34 @@
 
 class B^ {}
 ''';
-    var modifiedSource = '''
-class A {}
-''';
     var declarationName = 'B';
-    var newFileName = 'b.dart';
-    var newFileContent = '''
-class B {}
-''';
     var otherFilePath = '$projectFolderPath/lib/c.dart';
     var otherFileContent = '''
 import 'package:test/main.dart';
 
 B? b;
 ''';
-    var modifiedOtherFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/b.dart
+class B {}
+>>>>>>>>>> lib/c.dart
 import 'package:test/b.dart';
 import 'package:test/main.dart';
 
 B? b;
+>>>>>>>>>> lib/main.dart
+class A {}
+
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
-        otherFilePath: otherFilePath,
-        otherFileContent: otherFileContent,
-        modifiedOtherFileContent: modifiedOtherFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+      otherFilePath: otherFilePath,
+      otherFileContent: otherFileContent,
+    );
   }
 
   Future<void> test_imports_referenceInThirdFile_withMultiplePrefixes() async {
@@ -870,14 +866,7 @@
 
 class B^ {}
 ''';
-    var modifiedSource = '''
-class A {}
-''';
     var declarationName = 'B';
-    var newFileName = 'b.dart';
-    var newFileContent = '''
-class B {}
-''';
     var otherFilePath = '$projectFolderPath/lib/c.dart';
     var otherFileContent = '''
 import 'package:test/main.dart';
@@ -886,7 +875,11 @@
 
 void f(p.B b, q.B b, B b) {}
 ''';
-    var modifiedOtherFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/b.dart
+class B {}
+>>>>>>>>>> lib/c.dart
 import 'package:test/b.dart';
 import 'package:test/b.dart' as p;
 import 'package:test/b.dart' as q;
@@ -895,16 +888,18 @@
 import 'package:test/main.dart' as q;
 
 void f(p.B b, q.B b, B b) {}
+>>>>>>>>>> lib/main.dart
+class A {}
+
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
-        otherFilePath: otherFilePath,
-        otherFileContent: otherFileContent,
-        modifiedOtherFileContent: modifiedOtherFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+      otherFilePath: otherFilePath,
+      otherFileContent: otherFileContent,
+    );
   }
 
   Future<void> test_imports_referenceInThirdFile_withSinglePrefix() async {
@@ -913,35 +908,34 @@
 
 class B^ {}
 ''';
-    var modifiedSource = '''
-class A {}
-''';
     var declarationName = 'B';
-    var newFileName = 'b.dart';
-    var newFileContent = '''
-class B {}
-''';
     var otherFilePath = '$projectFolderPath/lib/c.dart';
     var otherFileContent = '''
 import 'package:test/main.dart' as p;
 
 p.B? b;
 ''';
-    var modifiedOtherFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/b.dart
+class B {}
+>>>>>>>>>> lib/c.dart
 import 'package:test/b.dart' as p;
 import 'package:test/main.dart' as p;
 
 p.B? b;
+>>>>>>>>>> lib/main.dart
+class A {}
+
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
-        otherFilePath: otherFilePath,
-        otherFileContent: otherFileContent,
-        modifiedOtherFileContent: modifiedOtherFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+      otherFilePath: otherFilePath,
+      otherFileContent: otherFileContent,
+    );
   }
 
   /// Test moving declarations to a file that imports a library that exports a
@@ -952,9 +946,9 @@
     var destinationFileName = 'moving.dart';
     var destinationFilePath =
         join(projectFolderPath, 'lib', destinationFileName);
-    addSource(libFilePath, 'export "src/a.dart";');
-    addSource(srcFilePath, 'class A {}');
-    addSource(destinationFilePath, '''
+    newFile(libFilePath, 'export "src/a.dart";');
+    newFile(srcFilePath, 'class A {}');
+    newFile(destinationFilePath, '''
 import 'package:test/a.dart' hide A;
 ''');
     var originalSource = '''
@@ -963,25 +957,25 @@
 A? staying;
 A? mov^ing;
 ''';
-    var modifiedSource = '''
+    var declarationName = 'moving';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/a.dart';
 
 A? staying;
-''';
-    var declarationName = 'moving';
-
-    var expectedDestinationContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/a.dart' hide A;
 import 'package:test/a.dart';
 
 A? moving;
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: destinationFileName,
-        newFileContent: expectedDestinationContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   /// Test moving declarations to a file that imports a library that exports a
@@ -992,9 +986,9 @@
     var destinationFileName = 'moving.dart';
     var destinationFilePath =
         join(projectFolderPath, 'lib', destinationFileName);
-    addSource(libFilePath, 'export "src/a.dart";');
-    addSource(srcFilePath, 'class A {}');
-    addSource(destinationFilePath, '''
+    newFile(libFilePath, 'export "src/a.dart";');
+    newFile(srcFilePath, 'class A {}');
+    newFile(destinationFilePath, '''
 import 'package:test/a.dart' hide A;
 ''');
     var originalSource = '''
@@ -1003,25 +997,25 @@
 A? staying;
 A? mov^ing;
 ''';
-    var modifiedSource = '''
+    var declarationName = 'moving';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/a.dart' show A;
 
 A? staying;
-''';
-    var declarationName = 'moving';
-
-    var expectedDestinationContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/a.dart' hide A;
 import 'package:test/a.dart' show A;
 
 A? moving;
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: destinationFileName,
-        newFileContent: expectedDestinationContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   /// Test that if the moving declaration was imported with 'show' that any new
@@ -1029,32 +1023,32 @@
   Future<void> test_imports_showHide_sourceShows() async {
     var libFilePath = join(projectFolderPath, 'lib', 'a.dart');
     var srcFilePath = join(projectFolderPath, 'lib', 'src', 'a.dart');
-    addSource(libFilePath, 'export "src/a.dart";');
-    addSource(srcFilePath, 'class A {}');
+    newFile(libFilePath, 'export "src/a.dart";');
+    newFile(srcFilePath, 'class A {}');
     var originalSource = '''
 import 'package:test/a.dart' show A;
 
 A? staying;
 A? mov^ing;
 ''';
-    var modifiedSource = '''
+    var declarationName = 'moving';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/a.dart' show A;
 
 A? staying;
-''';
-    var declarationName = 'moving';
-    var newFileName = 'moving.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/a.dart' show A;
 
 A? moving;
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_kind_class() async {
@@ -1065,22 +1059,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'ClassToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
+class ClassToMove {}
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'ClassToMove';
-    var newFileName = 'class_to_move.dart';
-    var newFileContent = '''
-class ClassToMove {}
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_logsAction() async {
@@ -1102,23 +1096,23 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
-class A {}
 
-class B {}
-''';
-    var newFileName = 'class_to_move1.dart';
-    var newFileContent = '''
+    var expected = '''
+>>>>>>>>>> lib/class_to_move1.dart
 class ClassToMove1 {}
 
 class ClassToMove2 {}
+>>>>>>>>>> lib/main.dart
+class A {}
+
+class B {}
+
 ''';
     await _multipleDeclarations(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        count: 2,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      count: 2,
+    );
   }
 
   Future<void> test_none_comment() async {
@@ -1126,6 +1120,7 @@
 // Comm^ent
 
 class A {}
+
 ''');
     await initializeServer(experimentalOptInFlag: false);
     await expectNoCodeAction(null);
@@ -1136,6 +1131,7 @@
 imp^ort 'dart:core';
 
 class A {}
+
 ''');
     await initializeServer(experimentalOptInFlag: false);
     await expectNoCodeAction(null);
@@ -1144,12 +1140,12 @@
   /// Test that references to getter/setters in different libraries used in
   /// a postfix increment are both imported into the destination file.
   Future<void> test_postfixIncrement_multipleLibraries() async {
-    addSource('$projectFolderPath/lib/getter.dart', '''
-int get splitVariable => 0;
-''');
-    addSource('$projectFolderPath/lib/setter.dart', '''
-set splitVariable(num _) {}
-''');
+    newFile('$projectFolderPath/lib/getter.dart', '''
+    int get splitVariable => 0;
+    ''');
+    newFile('$projectFolderPath/lib/setter.dart', '''
+    set splitVariable(num _) {}
+    ''');
 
     var originalSource = '''
 import 'package:test/getter.dart';
@@ -1159,26 +1155,26 @@
   splitVariable++;
 }
 ''';
-    var modifiedSource = '''
-import 'package:test/getter.dart';
-import 'package:test/setter.dart';
-''';
     var declarationName = 'functionToMove';
-    var newFileName = 'function_to_move.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/function_to_move.dart
 import 'package:test/getter.dart';
 import 'package:test/setter.dart';
 
 void functionToMove() {
   splitVariable++;
 }
+>>>>>>>>>> lib/main.dart
+import 'package:test/getter.dart';
+import 'package:test/setter.dart';
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void>
@@ -1211,7 +1207,9 @@
     final newFileUri = Uri.file(newFilePath);
 
     /// Expected new file content.
-    const expectedNewFileContent = '''
+    const expected = '''
+>>>>>>>>>> lib/main.dart empty
+>>>>>>>>>> lib/my_new_class.dart
 class A {}
 ''';
 
@@ -1219,9 +1217,8 @@
     final action = await expectCodeAction(simpleClassRefactorTitle);
     // Replace the file URI argument with our custom path.
     replaceSaveUriArgument(action, newFileUri);
-    await executeRefactor(action);
-
-    expect(content[newFilePath], expectedNewFileContent);
+    await verifyCommandEdits(action.command!, expected,
+        expectDocumentChanges: true);
   }
 
   Future<void> test_protocol_unavailable_withoutFileCreateSupport() async {
@@ -1239,23 +1236,23 @@
 
 class Neither {}
 ''';
-    var modifiedSource = '''
 
-class Neither {}
-''';
-    var newFileName = 'either.dart';
-    var newFileContent = '''
+    var expected = '''
+>>>>>>>>>> lib/either.dart
 sealed class Either {}
 
 class Left extends Either {}
 class Right extends Either {}
+>>>>>>>>>> lib/main.dart
+
+class Neither {}
+
 ''';
     await _multipleDeclarations(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        count: 3,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      count: 3,
+    );
   }
 
   /// The code action is not available if you select a subclass of a sealed
@@ -1286,7 +1283,7 @@
 class Left extends Either {}
 ''';
 
-    addSource(otherFilePath, otherFileContent);
+    newFile(otherFilePath, otherFileContent);
 
     await initializeServer();
     await expectNoCodeAction(null);
@@ -1304,28 +1301,28 @@
 
 class Neither {}
 ''';
+
     // TODO(dantup): Track down where this extra newline is coming from.
-    var modifiedSource = '''
+    var expected = '''
+>>>>>>>>>> lib/either.dart
+sealed class Either {}
+
+class Left extends Either {}
+class Right extends Either {}
+>>>>>>>>>> lib/main.dart
 import 'package:test/either.dart';
 
 
 class LeftSub extends Left {}
 
 class Neither {}
-''';
-    var newFileName = 'either.dart';
-    var newFileContent = '''
-sealed class Either {}
 
-class Left extends Either {}
-class Right extends Either {}
 ''';
     await _multipleDeclarations(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        count: 3,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      count: 3,
+    );
   }
 
   Future<void> test_sealedClass_extends_superclassAndSubclass() async {
@@ -1337,23 +1334,23 @@
 
 class Neither {}
 ''';
-    var modifiedSource = '''
 
-class Neither {}
-''';
-    var newFileName = 'either.dart';
-    var newFileContent = '''
+    var expected = '''
+>>>>>>>>>> lib/either.dart
 sealed class Either {}
 
 class Left extends Either {}
 class Right extends Either {}
+>>>>>>>>>> lib/main.dart
+
+class Neither {}
+
 ''';
     await _multipleDeclarations(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        count: 3,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      count: 3,
+    );
   }
 
   Future<void> test_sealedClass_implements() async {
@@ -1365,23 +1362,23 @@
 
 class Neither {}
 ''';
-    var modifiedSource = '''
 
-class Neither {}
-''';
-    var newFileName = 'either.dart';
-    var newFileContent = '''
+    var expected = '''
+>>>>>>>>>> lib/either.dart
 sealed class Either {}
 
 class Left implements Either {}
 class Right implements Either {}
+>>>>>>>>>> lib/main.dart
+
+class Neither {}
+
 ''';
     await _multipleDeclarations(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        count: 3,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      count: 3,
+    );
   }
 
   Future<void> test_sealedClass_sealedSubclass_extends_superclass() async {
@@ -1395,27 +1392,27 @@
 
 class SubSubSubclass extends SubSubclass {}
 ''';
-    var modifiedSource = '''
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/sealed_root.dart';
 
 
 class SubSubSubclass extends SubSubclass {}
-''';
-    var newFileName = 'sealed_root.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/sealed_root.dart
 sealed class SealedRoot {}
 
 class Subclass extends SealedRoot {}
 sealed class SealedSubclass extends SealedRoot {}
 
 class SubSubclass extends SealedSubclass {}
+
 ''';
     await _multipleDeclarations(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        count: 4,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      count: 4,
+    );
   }
 
   Future<void> test_single_class_withTypeParameters() async {
@@ -1426,22 +1423,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'ClassToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
+class ClassToMove<T> {}
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'ClassToMove';
-    var newFileName = 'class_to_move.dart';
-    var newFileContent = '''
-class ClassToMove<T> {}
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_enum() async {
@@ -1452,22 +1449,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'EnumToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/enum_to_move.dart
+enum EnumToMove { a, b }
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'EnumToMove';
-    var newFileName = 'enum_to_move.dart';
-    var newFileContent = '''
-enum EnumToMove { a, b }
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_extension() async {
@@ -1478,22 +1475,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'ExtensionToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/extension_to_move.dart
+extension ExtensionToMove on int { }
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'ExtensionToMove';
-    var newFileName = 'extension_to_move.dart';
-    var newFileContent = '''
-extension ExtensionToMove on int { }
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_function_endOfName() async {
@@ -1504,22 +1501,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'functionToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/function_to_move.dart
+void functionToMove() { }
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'functionToMove';
-    var newFileName = 'function_to_move.dart';
-    var newFileContent = '''
-void functionToMove() { }
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_function_middleOfName() async {
@@ -1530,22 +1527,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'functionToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/function_to_move.dart
+void functionToMove() { }
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'functionToMove';
-    var newFileName = 'function_to_move.dart';
-    var newFileContent = '''
-void functionToMove() { }
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_mixin() async {
@@ -1556,22 +1553,22 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'MixinToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'MixinToMove';
-    var newFileName = 'mixin_to_move.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/mixin_to_move.dart
 mixin MixinToMove { }
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_parts_libraryToPart() async {
@@ -1580,28 +1577,29 @@
 
 class Clas^sToMove {}
 ''';
-    var modifiedSource = '''
-part 'class_to_move.dart';
-''';
     var declarationName = 'ClassToMove';
     var destinationFileName = 'class_to_move.dart';
     var destinationFilePath =
         join(projectFolderPath, 'lib', destinationFileName);
-    addSource(destinationFilePath, '''
+    newFile(destinationFilePath, '''
 part of 'main.dart';
 ''');
-    var destinationFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
 part of 'main.dart';
 
 class ClassToMove {}
+>>>>>>>>>> lib/main.dart
+part 'class_to_move.dart';
+
 ''';
 
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: destinationFileName,
-        newFileContent: destinationFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_parts_partToLibrary() async {
@@ -1610,28 +1608,29 @@
 
 class Clas^sToMove {}
 ''';
-    var modifiedSource = '''
-part of 'class_to_move.dart';
-''';
     var declarationName = 'ClassToMove';
     var destinationFileName = 'class_to_move.dart';
     var destinationFilePath =
         join(projectFolderPath, 'lib', destinationFileName);
-    addSource(destinationFilePath, '''
+    newFile(destinationFilePath, '''
 part 'main.dart';
 ''');
-    var destinationFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
 part 'main.dart';
 
 class ClassToMove {}
+>>>>>>>>>> lib/main.dart
+part of 'class_to_move.dart';
+
 ''';
 
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: destinationFileName,
-        newFileContent: destinationFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_parts_partToPart() async {
@@ -1640,21 +1639,13 @@
 
 class Clas^sToMove {}
 ''';
-    var modifiedSource = '''
-part of 'containing_library.dart';
-''';
     var declarationName = 'ClassToMove';
     var destinationFileName = 'class_to_move.dart';
     var destinationFilePath =
         join(projectFolderPath, 'lib', destinationFileName);
-    addSource(destinationFilePath, '''
+    newFile(destinationFilePath, '''
 part of 'containing_library.dart';
 ''');
-    var destinationFileContent = '''
-part of 'containing_library.dart';
-
-class ClassToMove {}
-''';
     var containingLibraryFilePath =
         join(projectFolderPath, 'lib', 'containing_library.dart');
     var containingLibraryFileContent = '''
@@ -1662,12 +1653,19 @@
 part 'class_to_move.dart';
 ''';
 
+    var expected = '''
+>>>>>>>>>> lib/class_to_move.dart
+part of 'containing_library.dart';
+
+class ClassToMove {}
+>>>>>>>>>> lib/main.dart
+part of 'containing_library.dart';
+
+''';
     await _singleDeclaration(
         originalSource: originalSource,
-        modifiedSource: modifiedSource,
+        expected: expected,
         declarationName: declarationName,
-        newFileName: destinationFileName,
-        newFileContent: destinationFileContent,
         otherFilePath: containingLibraryFilePath,
         otherFileContent: containingLibraryFileContent);
   }
@@ -1680,48 +1678,49 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'TypeToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'TypeToMove';
-    var newFileName = 'type_to_move.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/type_to_move.dart
 typedef TypeToMove = void Function();
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_variable() async {
     var originalSource = '''
 class A {}
 
+
 int variableT^oMove = 3;
 
 class B {}
 ''';
-    var modifiedSource = '''
+    var declarationName = 'variableToMove';
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 class A {}
 
 class B {}
-''';
-    var declarationName = 'variableToMove';
-    var newFileName = 'variable_to_move.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/variable_to_move.dart
 int variableToMove = 3;
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
   Future<void> test_single_variable_firstDartDoc() async {
@@ -1731,93 +1730,76 @@
 
 class B {}
 ''';
-    var modifiedSource = '''
-
-class B {}
-''';
     var declarationName = 'A';
-    var newFileName = 'a.dart';
-    var newFileContent = '''
+
+    var expected = '''
+>>>>>>>>>> lib/a.dart
 ///
 class A {}
+>>>>>>>>>> lib/main.dart
+
+class B {}
+
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: declarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: declarationName,
+    );
   }
 
-  Future<void> _multipleDeclarations(
-      {required String originalSource,
-      required String modifiedSource,
-      required int count,
-      required String newFileName,
-      required String newFileContent,
-      String? otherFilePath,
-      String? otherFileContent,
-      String? modifiedOtherFileContent}) async {
+  Future<void> _multipleDeclarations({
+    required String originalSource,
+    required int count,
+    required String expected,
+    String? otherFilePath,
+    String? otherFileContent,
+  }) async {
     await _refactor(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        actionTitle: "Move $count declarations to file",
-        newFileName: newFileName,
-        newFileContent: newFileContent,
-        otherFilePath: otherFilePath,
-        otherFileContent: otherFileContent,
-        modifiedOtherFileContent: modifiedOtherFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      actionTitle: "Move $count declarations to file",
+      otherFilePath: otherFilePath,
+      otherFileContent: otherFileContent,
+    );
   }
 
-  Future<void> _refactor(
-      {required String originalSource,
-      required String modifiedSource,
-      required String actionTitle,
-      required String newFileName,
-      required String newFileContent,
-      String? otherFilePath,
-      String? otherFileContent,
-      String? modifiedOtherFileContent}) async {
+  Future<void> _refactor({
+    required String originalSource,
+    required String actionTitle,
+    required String expected,
+    String? otherFilePath,
+    String? otherFileContent,
+  }) async {
+    if (originalSource.contains('>>>>') ||
+        (otherFileContent?.contains('>>>>>') ?? false)) {
+      throw '>>>>>';
+    }
     addTestSource(originalSource);
     if (otherFilePath != null) {
-      addSource(otherFilePath, otherFileContent!);
+      newFile(otherFilePath, otherFileContent!);
     }
 
-    /// Expected new file path/content.
-    final expectedNewFilePath = join(projectFolderPath, 'lib', newFileName);
-
     await initializeServer();
     final action = await expectCodeAction(actionTitle);
-    await executeRefactor(action);
-
-    expect(content[mainFilePath], modifiedSource);
-    // Check the new file was added to `content`. If no CreateFile resource
-    // was sent, the executeRefactor helper would've thrown when trying to
-    // apply the changes.
-    expect(content[expectedNewFilePath], newFileContent);
-    if (modifiedOtherFileContent != null) {
-      expect(content[convertPath(otherFilePath!)], modifiedOtherFileContent);
-    }
+    await verifyCommandEdits(action.command!, expected,
+        expectDocumentChanges: true);
   }
 
-  Future<void> _singleDeclaration(
-      {required String originalSource,
-      required String modifiedSource,
-      required String declarationName,
-      required String newFileName,
-      required String newFileContent,
-      String? otherFilePath,
-      String? otherFileContent,
-      String? modifiedOtherFileContent}) async {
+  Future<void> _singleDeclaration({
+    required String originalSource,
+    required String declarationName,
+    required String expected,
+    String? otherFilePath,
+    String? otherFileContent,
+  }) async {
     await _refactor(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        actionTitle: "Move '$declarationName' to file",
-        newFileName: newFileName,
-        newFileContent: newFileContent,
-        otherFilePath: otherFilePath,
-        otherFileContent: otherFileContent,
-        modifiedOtherFileContent: modifiedOtherFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      actionTitle: "Move '$declarationName' to file",
+      otherFilePath: otherFilePath,
+      otherFileContent: otherFileContent,
+    );
   }
 
   /// Tests that prefixes are included in imports copied to the new code.
@@ -1838,22 +1820,21 @@
 
 ${code.rawCode}
 ''';
-    var modifiedSource = '''
+
+    var expected = '''
+>>>>>>>>>> lib/main.dart
 import 'package:test/other.dart' as other;
-''';
-    var newFileName = 'moving.dart';
-    var newFileContent = '''
+>>>>>>>>>> lib/moving.dart
 import 'package:test/other.dart' as other;
 
 ${code.code}
 ''';
     await _singleDeclaration(
-        originalSource: originalSource,
-        modifiedSource: modifiedSource,
-        declarationName: movingDeclarationName,
-        newFileName: newFileName,
-        newFileContent: newFileContent,
-        otherFilePath: otherFilePath,
-        otherFileContent: otherFileContent);
+      originalSource: originalSource,
+      expected: expected,
+      declarationName: movingDeclarationName,
+      otherFilePath: otherFilePath,
+      otherFileContent: otherFileContent,
+    );
   }
 }
diff --git a/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart b/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart
index 647537d..596fc97 100644
--- a/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart
+++ b/pkg/analysis_server/test/src/services/refactoring/refactoring_test_support.dart
@@ -16,21 +16,10 @@
   /// The range of characters that were selected.
   Range? _range;
 
-  /// A map of file paths to their current content.
-  ///
-  /// Methods like [executeRefactor] will update this as workspace edits are
-  /// sent from the server back to the client.
-  Map<String, String> content = {};
-
   /// Return the title of the refactoring command that is expected to be
   /// available.
   String get refactoringName;
 
-  void addSource(String filePath, String code) {
-    var file = newFile(filePath, code);
-    content[file.path] = code;
-  }
-
   void addTestSource(String markedCode) {
     var testCode = TestCode.parse(markedCode);
     var positions = testCode.positions;
@@ -42,7 +31,7 @@
         _range = ranges[0].range;
       }
     }
-    addSource(mainFilePath, testCode.code);
+    newFile(mainFilePath, testCode.code);
   }
 
   void assertTextExpectation(String actual, String expected) {
@@ -54,11 +43,11 @@
     expect(actual, expected);
   }
 
-  /// Executes the [action], updating [content] with edits sent by the server.
+  /// Executes the refactor in [action].
   Future<void> executeRefactor(CodeAction action) async {
     await executeCommandForEdits(
       action.command!,
-      content,
+      {},
       expectDocumentChanges: true,
     );
   }