[analysis_server] Update setState + closure completions to use the correct line endings

+ update completion tests to always use normalized code

Change-Id: If6e2f838f23c8cdbb0590a7e408d51897d8b4a46
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/443560
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/candidate_suggestion.dart b/pkg/analysis_server/lib/src/services/completion/dart/candidate_suggestion.dart
index 0304159..4ce4e5d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/candidate_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/candidate_suggestion.dart
@@ -81,6 +81,9 @@
   /// The identation to be used for a multi-line completion.
   final String indent;
 
+  /// The EOL marker to be used for a multi-line completion.
+  final String endOfLine;
+
   /// Initialize a newly created candidate suggestion to suggest a closure that
   /// conforms to the given [functionType].
   ///
@@ -92,6 +95,7 @@
     required super.matcherScore,
     required this.includeTypes,
     required this.indent,
+    required this.endOfLine,
     this.useBlockStatement = true,
   });
 
@@ -125,10 +129,11 @@
     int selectionOffset;
     if (useBlockStatement) {
       displayText = '$parametersDisplayString {}';
-      stringBuffer.writeln(' {');
+      stringBuffer.write(' {');
+      stringBuffer.write(endOfLine);
       stringBuffer.write('$indent  ');
       selectionOffset = stringBuffer.length;
-      stringBuffer.writeln();
+      stringBuffer.write(endOfLine);
       stringBuffer.write('$indent}');
     } else {
       displayText = '$parametersDisplayString =>';
@@ -981,11 +986,15 @@
   /// The identation to be used for a multi-line completion.
   final String indent;
 
+  /// The EOL marker to be used for a multi-line completion.
+  final String endOfLine;
+
   /// Initialize a newly created candidate suggestion to suggest the [element].
   SetStateMethodSuggestion({
     required this.element,
     required this.referencingInterface,
     required this.indent,
+    required this.endOfLine,
     required super.importData,
     required super.matcherScore,
     required super.replacementRange,
@@ -1011,10 +1020,11 @@
     // Build the completion and the selection offset.
     var buffer = StringBuffer();
 
-    buffer.writeln('setState(() {');
+    buffer.write('setState(() {');
+    buffer.write(endOfLine);
     buffer.write('$indent  ');
     var selectionOffset = buffer.length;
-    buffer.writeln();
+    buffer.write(endOfLine);
     buffer.write('$indent});');
     var completion = buffer.toString();
     _data = _Data(completion, selectionOffset, displayText: 'setState(() {});');
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_state.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_state.dart
index d6badd2..47ed054 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_state.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_state.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/utilities.dart';
 import 'package:analysis_server_plugin/src/utilities/selection.dart';
@@ -11,6 +13,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/utilities/completion_matcher.dart';
+import 'package:analyzer_plugin/src/utilities/extensions/string_extension.dart';
 
 /// The information used to compute the suggestions for a completion request.
 class CompletionState {
@@ -47,6 +50,9 @@
     return selection.coveringNode.thisOrAncestorOfType<ClassMember>();
   }
 
+  /// The EOL marker for the completion text.
+  String get endOfLine => request.content.endOfLine ?? Platform.lineTerminator;
+
   /// Indicates if types should be specified whenever possible.
   bool get includeTypes => codeStyleOptions.specifyTypes;
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart
index d63b802..d6e9e5a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/declaration_helper.dart
@@ -2058,6 +2058,7 @@
             referencingInterface: referencingInterface,
             matcherScore: matcherScore,
             indent: state.indent,
+            endOfLine: state.endOfLine,
             addTypeAnnotation: addTypeAnnotation,
             keyword: keyword,
           );
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart
index 6532d63..4c6299b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/in_scope_completion_pass.dart
@@ -3300,6 +3300,7 @@
         matcherScore: 0.0,
         includeTypes: includeTypes,
         indent: state.indent,
+        endOfLine: state.endOfLine,
       ),
     );
     collector.addSuggestion(
@@ -3310,6 +3311,7 @@
         useBlockStatement: false,
         includeTypes: includeTypes,
         indent: state.indent,
+        endOfLine: state.endOfLine,
       ),
     );
   }
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart
index 65cb0b3..1aa6c242 100644
--- a/pkg/analysis_server/test/lsp/completion_dart_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -63,6 +63,9 @@
 
 abstract class AbstractCompletionTest extends AbstractLspAnalysisServerTest
     with CompletionTestMixin {
+  late String content;
+  late final code = TestCode.parseNormalized(content);
+
   AbstractCompletionTest() {
     defaultInitializationOptions = {
       // Default to a high budget for tests because everything is cold and
@@ -91,7 +94,7 @@
 
   void _enableLints(List<String> lintNames) {
     registerLintRules();
-    var lintsYaml = lintNames.map((name) => '    - $name\n').join();
+    var lintsYaml = lintNames.map((name) => '    - $name$eol').join();
     newFile(analysisOptionsPath, '''
 linter:
   rules:
@@ -102,9 +105,6 @@
 
 @reflectiveTest
 class CompletionDocumentationResolutionTest extends AbstractCompletionTest {
-  late String content;
-  late final code = TestCode.parse(content);
-
   Future<CompletionItem> getCompletionItem(String label) async {
     var completions = await getCompletion(mainFileUri, code.position.position);
     return completions.singleWhere((c) => c.label == label);
@@ -269,7 +269,6 @@
 ''';
     await initializeServer();
 
-    var code = TestCode.parse(content);
     var completion = await getCompletionItem('value');
     expect(completion, isNotNull);
 
@@ -282,7 +281,7 @@
     ]);
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 class A {
   A([this.value]);
   A? value;
@@ -305,7 +304,6 @@
 ''';
     await initializeServer();
 
-    var code = TestCode.parse(content);
     var completion = await getCompletionItem('name');
     expect(completion, isNotNull);
 
@@ -318,7 +316,7 @@
     ]);
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 void f(({int name, int other}) r) {
   if (r case (:var name)) {}
 }
@@ -342,7 +340,7 @@
 ''';
     _enableLints([LintNames.always_specify_types]);
     await initializeServer();
-    var code = TestCode.parse(content);
+
     var completion = await getCompletionItem('name');
     expect(completion, isNotNull);
     var resolved = await resolveCompletion(completion);
@@ -351,7 +349,7 @@
     ]);
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'my_types.dart' hide MyType2;
 
 void f(Other r) {
@@ -378,7 +376,7 @@
 ''';
     _enableLints([LintNames.always_specify_types]);
     await initializeServer();
-    var code = TestCode.parse(content);
+
     var completion = await getCompletionItem('name');
     var resolved = await resolveCompletion(completion);
     var newContent = applyTextEdits(
@@ -389,7 +387,7 @@
     );
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'package:test/my_types.dart';
 
 import 'other.dart';
@@ -416,7 +414,7 @@
 ''';
     _enableLints([LintNames.always_specify_types]);
     await initializeServer();
-    var code = TestCode.parse(content);
+
     var completion = await getCompletionItem('name');
     expect(completion, isNotNull);
     var resolved = await resolveCompletion(completion);
@@ -425,7 +423,7 @@
     ]);
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'my_types.dart' show Other, MyType;
 
 void f(Other r) {
@@ -449,7 +447,7 @@
 ''';
     _enableLints([LintNames.always_specify_types]);
     await initializeServer();
-    var code = TestCode.parse(content);
+
     var completion = await getCompletionItem('name');
     expect(completion, isNotNull);
     var resolved = await resolveCompletion(completion);
@@ -458,7 +456,7 @@
     ]);
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'my_types.dart' as t;
 
 void f(t.Other r) {
@@ -509,7 +507,6 @@
   }) async {
     completionFileUri ??= mainFileUri;
 
-    var code = TestCode.parse(content);
     await initialize();
     await openFile(completionFileUri, code.code);
 
@@ -533,7 +530,7 @@
       if (completion == null) {
         fail(
           'Did not find completion "$label" with detail "$detail" in completion results:'
-          '\n    ${completions.map((c) => '${c.label} (${c.detail})').join('\n    ')}',
+          '$eol    ${completions.map((c) => '${c.label} (${c.detail})').join('$eol    ')}',
         );
       }
 
@@ -583,7 +580,7 @@
   }
 
   Future<void> test_combinator_function() async {
-    var content = '''
+    content = '''
 import 'dart:math' show min^
 ''';
 
@@ -598,7 +595,7 @@
   }
 
   Future<void> test_constructor_argument() async {
-    var content = '''
+    content = '''
 var a = Foo(^);
 
 class Foo {
@@ -618,7 +615,7 @@
   }
 
   Future<void> test_constructor_factory_argument() async {
-    var content = '''
+    content = '''
 var a = Foo(^);
 
 class Foo {
@@ -642,7 +639,7 @@
     newFile(fileAPath, '''
 String a(String a, {String b}) {}
 ''');
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   a^
@@ -663,7 +660,7 @@
     newFile(fileAPath, '''
 String a() {}
 ''');
-    var content = '''
+    content = '''
 import 'a.dart';
 String f() {
   a^
@@ -684,7 +681,7 @@
     newFile(fileAPath, '''
 void a(String a, {String b}) {}
 ''');
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   a^
@@ -705,7 +702,7 @@
     newFile(fileAPath, '''
 void a() {}
 ''');
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   a^
@@ -723,7 +720,7 @@
   }
 
   Future<void> test_local_function_returnType_args() async {
-    var content = '''
+    content = '''
 String f(String a, {String b}) {
   f^
 }
@@ -739,7 +736,7 @@
   }
 
   Future<void> test_local_function_returnType_noArgs() async {
-    var content = '''
+    content = '''
 String f() {
   f^
 }
@@ -756,7 +753,7 @@
   }
 
   Future<void> test_local_function_void_args() async {
-    var content = '''
+    content = '''
 void f(String a, {String b}) {
   f^
 }
@@ -773,7 +770,7 @@
   }
 
   Future<void> test_local_function_void_noArgs() async {
-    var content = '''
+    content = '''
 void f() {
   f^
 }
@@ -790,7 +787,7 @@
   }
 
   Future<void> test_local_getter() async {
-    var content = '''
+    content = '''
 String a => '';
 void f() {
   a^
@@ -807,7 +804,7 @@
   }
 
   Future<void> test_local_getterAndSetter() async {
-    var content = '''
+    content = '''
 set a(String value) {}
 String get a => '';
 void f() {
@@ -825,7 +822,7 @@
   }
 
   Future<void> test_local_override_annotation_equals() async {
-    var content = '''
+    content = '''
 class Base {
 }
 
@@ -844,7 +841,7 @@
   }
 
   Future<void> test_local_override_annotation_method() async {
-    var content = '''
+    content = '''
 class Base {
   String aa(String a) => '';
 }
@@ -867,7 +864,7 @@
   ///
   /// https://github.com/dart-lang/sdk/issues/59929
   Future<void> test_local_override_getterAndSetter() async {
-    var content = '''
+    content = '''
 class A {
   int? value;
 }
@@ -900,7 +897,7 @@
   }
 
   Future<void> test_local_override_name() async {
-    var content = '''
+    content = '''
 class Base {
   String aa(String a) => '';
 }
@@ -920,7 +917,7 @@
   }
 
   Future<void> test_local_setter() async {
-    var content = '''
+    content = '''
 set a(String value) {}
 void f() {
   a^
@@ -940,7 +937,7 @@
     newFile(fileAPath, '''
 String a(String a, {String b}) {}
 ''');
-    var content = '''
+    content = '''
 void f() {
   a^
 }
@@ -961,7 +958,7 @@
     newFile(fileAPath, '''
 String a() {}
 ''');
-    var content = '''
+    content = '''
 String f() {
   a^
 }
@@ -982,7 +979,7 @@
     newFile(fileAPath, '''
 void a(String a, {String b}) {}
 ''');
-    var content = '''
+    content = '''
 void f() {
   a^
 }
@@ -1003,7 +1000,7 @@
     newFile(fileAPath, '''
 void a() {}
 ''');
-    var content = '''
+    content = '''
 void f() {
   a^
 }
@@ -1027,7 +1024,7 @@
     newFile(testFileAPath, '''
 void a(String a, {String b}) {}
 ''');
-    var content = '''
+    content = '''
 void f() {
   a^
 }
@@ -1046,7 +1043,7 @@
   }
 
   Future<void> test_nullNotEmpty() async {
-    var content = '''
+    content = '''
 bool a = ^
 ''';
 
@@ -1063,7 +1060,7 @@
   }
 
   Future<void> test_record() async {
-    var content = r'''
+    content = r'''
 void f((int, int) record) {
   record.$^
 }
@@ -1080,7 +1077,7 @@
   }
 
   Future<void> test_variable() async {
-    var content = r'''
+    content = r'''
 void f(int variable) {
   varia^
 }
@@ -1106,7 +1103,7 @@
     required bool includesSummary,
     required bool includesFull,
   }) async {
-    var content = '''
+    content = '''
 /// Summary.
 ///
 /// Full.
@@ -1118,7 +1115,7 @@
     await provideConfig(initialize, {
       if (preference != null) 'documentation': preference,
     });
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -1151,7 +1148,7 @@
       class InOtherFile {}
 ''');
 
-    var content = '''
+    content = '''
 void f() {
   InOtherF^
 }
@@ -1160,7 +1157,7 @@
     await provideConfig(initialize, {
       if (preference != null) 'documentation': preference,
     });
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -1190,9 +1187,11 @@
     required String? editText,
     InsertTextFormat? insertTextFormat,
   }) async {
+    this.content = content;
+
     setCompletionItemSnippetSupport();
     await provideConfig(initialize, {'completeFunctionCalls': true});
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere(
@@ -1230,7 +1229,7 @@
     String colorHex,
   ) async {
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var completion = res.singleWhere((c) => c.label == label);
@@ -1245,7 +1244,7 @@
       (markup) => markup.value,
       (string) => string,
     );
-    expect(docs, anyOf(equals(colorHex), endsWith('\n\n$colorHex')));
+    expect(docs, anyOf(equals(colorHex), endsWith('$eol$eol$colorHex')));
   }
 
   /// Expect [item] to use the default edit range, inserting the value [text].
@@ -1262,7 +1261,7 @@
   }
 
   Future<void> test_annotation_beforeMember() async {
-    var content = '''
+    content = '''
 class B {
   @^
   int a = 1;
@@ -1270,7 +1269,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var completions = await getCompletion(mainFileUri, code.position.position);
     var labels = completions.map((c) => c.label).toList();
@@ -1280,14 +1279,14 @@
   }
 
   Future<void> test_annotation_endOfClass() async {
-    var content = '''
+    content = '''
 class B {
   @^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var completions = await getCompletion(mainFileUri, code.position.position);
     var labels = completions.map((c) => c.label).toList();
@@ -1297,7 +1296,7 @@
   }
 
   Future<void> test_closure() async {
-    var content = '''
+    content = '''
 void f({void Function(int a, String b) closure}) {}
 
 void g() {
@@ -1323,7 +1322,7 @@
   }
 
   Future<void> test_closure_requiredNamed() async {
-    var content = '''
+    content = '''
 void f({void Function({int a, required String b}) closure}) {}
 
 void g() {
@@ -1351,7 +1350,7 @@
   }
 
   Future<void> test_color_material() async {
-    var content = '''
+    content = '''
 import 'package:flutter/material.dart';
 var a = Colors.re^
 ''';
@@ -1360,7 +1359,7 @@
   }
 
   Future<void> test_color_materialAccent() async {
-    var content = '''
+    content = '''
 import 'package:flutter/material.dart';
 var a = Colors.redAcce^
 ''';
@@ -1369,13 +1368,13 @@
   }
 
   Future<void> test_comment() async {
-    var content = '''
+    content = '''
 // foo ^
 void f() {}
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res, isEmpty);
@@ -1384,12 +1383,12 @@
   Future<void> test_comment_endOfFile_withNewline() async {
     // Checks for a previous bug where invoking completion inside a comment
     // at the end of a file would return results.
-    var content = '''
+    content = '''
     // foo ^
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res, isEmpty);
@@ -1398,10 +1397,10 @@
   Future<void> test_comment_endOfFile_withoutNewline() async {
     // Checks for a previous bug where invoking completion inside a comment
     // at the very end of a file with no trailing newline would return results.
-    var content = '// foo ^';
+    content = '// foo ^';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res, isEmpty);
@@ -1602,7 +1601,7 @@
     // Flutter's setState method has special handling inside SuggestionBuilder
     // that already adds in a selection (which overlaps with completeFunctionCalls).
     // Ensure we don't end up with two sets of parens/placeholders in this case.
-    var content = '''
+    content = '''
 import 'package:flutter/material.dart';
 
 class MyWidget extends StatefulWidget {
@@ -1621,7 +1620,7 @@
 
     setCompletionItemSnippetSupport();
     await provideConfig(initialize, {'completeFunctionCalls': true});
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label.startsWith('setState('));
@@ -1635,7 +1634,7 @@
     expect(item.insertTextFormat, equals(InsertTextFormat.Snippet));
     expect(item.insertText, isNull);
     var textEdit = toTextEdit(item.textEdit!);
-    expect(textEdit.newText, 'setState(() {\n      \$0\n    });');
+    expect(textEdit.newText, 'setState(() {$eol      \$0$eol    });');
     expect(textEdit.range, equals(code.range.range));
   }
 
@@ -1656,7 +1655,7 @@
   }
 
   Future<void> test_completeFunctionCalls_noParameters() async {
-    var content = '''
+    content = '''
 void myFunction() {}
 
 void f() {
@@ -1673,7 +1672,7 @@
   }
 
   Future<void> test_completeFunctionCalls_optionalParameters() async {
-    var content = '''
+    content = '''
 void myFunction({int a}) {}
 
 void f() {
@@ -1691,7 +1690,7 @@
   }
 
   Future<void> test_completeFunctionCalls_requiredNamed() async {
-    var content = '''
+    content = '''
 void myFunction(String a, int b, {required String c, String d = ''}) {}
 
 void f() {
@@ -1701,7 +1700,7 @@
 
     setCompletionItemSnippetSupport();
     await provideConfig(initialize, {'completeFunctionCalls': true});
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'myFunction(…)');
@@ -1720,7 +1719,7 @@
       otherFile,
       "void myFunction(String a, int b, {required String c, String d = ''}) {}",
     );
-    var content = '''
+    content = '''
 void f() {
   [!myFu^!]
 }
@@ -1728,7 +1727,7 @@
 
     setCompletionItemSnippetSupport();
     await provideConfig(initialize, {'completeFunctionCalls': true});
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -1760,7 +1759,7 @@
     // not provided both `insertText` and `textEdit` back in the resolve call.
     //
     // Now, we never supply `insertText` and always use `textEdit`.
-    var content = '''
+    content = '''
 final a = Stri^
 ''';
 
@@ -1777,7 +1776,7 @@
 
     setCompletionItemSnippetSupport();
     await provideConfig(initialize, {'completeFunctionCalls': true});
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -1792,13 +1791,13 @@
   }
 
   Future<void> test_completeFunctionCalls_show() async {
-    var content = '''
+    content = '''
 import 'dart:math' show mi^
 ''';
 
     setCompletionItemSnippetSupport();
     await provideConfig(initialize, {'completeFunctionCalls': true});
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'min(…)');
@@ -1840,10 +1839,10 @@
     newFile(join(projectFolderPath, 'file.dart'), '');
     newFolder(join(projectFolderPath, 'folder'));
 
-    var content = "import '^';";
+    content = "import '^';";
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
 
@@ -1865,10 +1864,10 @@
       CompletionItemKind.Module,
     ]);
 
-    var content = "import '^';";
+    content = "import '^';";
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
 
@@ -1884,7 +1883,7 @@
     // Tell the server we only support the Field CompletionItemKind.
     setCompletionItemKinds([CompletionItemKind.Field]);
 
-    var content = '''
+    content = '''
 class MyClass {
   String abcdefghij;
 }
@@ -1896,7 +1895,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var kinds = res.map((item) => item.kind).toList();
@@ -1910,7 +1909,7 @@
 
   Future<void> test_completionTrigger_brace_block() async {
     // Brace should not trigger completion if a normal code block.
-    var content = r'''
+    content = r'''
 main () {^}
 ''';
     await _checkResultsForTriggerCharacters(content, ['{'], isEmpty);
@@ -1919,7 +1918,7 @@
   Future<void>
   test_completionTrigger_brace_interpolatedStringExpression() async {
     // Brace should trigger completion if at the start of an interpolated expression
-    var content = r'''
+    content = r'''
 var a = '${^';
 ''';
     await _checkResultsForTriggerCharacters(content, [r'{'], isNotEmpty);
@@ -1927,7 +1926,7 @@
 
   Future<void> test_completionTrigger_brace_rawString() async {
     // Brace should not trigger completion if in a raw string.
-    var content = r'''
+    content = r'''
 var a = r'${^';
 ''';
     await _checkResultsForTriggerCharacters(content, [r'{'], isEmpty);
@@ -1936,7 +1935,7 @@
   Future<void> test_completionTrigger_brace_string() async {
     // Brace should not trigger completion if not at the start of an interpolated
     // expression.
-    var content = r'''
+    content = r'''
 var a = '{^';
 ''';
     await _checkResultsForTriggerCharacters(content, [r'{'], isEmpty);
@@ -1944,7 +1943,7 @@
 
   Future<void> test_completionTrigger_colon_argument() async {
     // Colons should trigger completion after argument names.
-    var content = r'''
+    content = r'''
 void f({int? a}) {
   f(a:^
 }
@@ -1954,7 +1953,7 @@
 
   Future<void> test_completionTrigger_colon_case() async {
     // Colons should not trigger completion in a switch case.
-    var content = r'''
+    content = r'''
 void f(int a) {
   switch (a) {
     case:^
@@ -1966,7 +1965,7 @@
 
   Future<void> test_completionTrigger_colon_default() async {
     // Colons should not trigger completion in a switch case.
-    var content = r'''
+    content = r'''
 void f(int a) {
   switch (a) {
     default:^
@@ -1978,7 +1977,7 @@
 
   Future<void> test_completionTrigger_colon_import() async {
     // Colons should trigger completion after argument names.
-    var content = r'''
+    content = r'''
 import 'package:^';
 ''';
     await _checkResultsForTriggerCharacters(content, [r':'], isNotEmpty);
@@ -1986,32 +1985,32 @@
 
   Future<void> test_completionTrigger_quotes_endingString() async {
     // Completion triggered by a quote ending a string should not return results.
-    var content = "foo(''^);";
+    content = "foo(''^);";
     await _checkResultsForTriggerCharacters(content, ["'", '"'], isEmpty);
   }
 
   Future<void> test_completionTrigger_quotes_startingImport() async {
     // Completion triggered by a quote for import should return results.
-    var content = "import '^'";
+    content = "import '^'";
     await _checkResultsForTriggerCharacters(content, ["'", '"'], isNotEmpty);
   }
 
   Future<void> test_completionTrigger_quotes_startingString() async {
     // Completion triggered by a quote for normal string should not return results.
-    var content = "foo('^');";
+    content = "foo('^');";
     await _checkResultsForTriggerCharacters(content, ["'", '"'], isEmpty);
   }
 
   Future<void> test_completionTrigger_quotes_terminatingImport() async {
     // Completion triggered by a quote ending an import should not return results.
-    var content = "import ''^";
+    content = "import ''^";
     await _checkResultsForTriggerCharacters(content, ["'", '"'], isEmpty);
   }
 
   Future<void> test_completionTrigger_slash_directivePath() async {
     // Slashes should trigger completion when typing in directive paths, eg.
     // after typing 'package:foo/' completion should give the next folder segments.
-    var content = r'''
+    content = r'''
     import 'package:test/^';
 ''';
     await _checkResultsForTriggerCharacters(content, [r'/'], isNotEmpty);
@@ -2019,7 +2018,7 @@
 
   Future<void> test_completionTrigger_slash_divide() async {
     // Slashes should not trigger completion when typing in a normal expression.
-    var content = r'''
+    content = r'''
 var a = 1 /^
 ''';
     await _checkResultsForTriggerCharacters(content, [r'/'], isEmpty);
@@ -2128,7 +2127,7 @@
 
   Future<void> test_filterText_constructorParens() async {
     // Constructor parens should not be included in filterText.
-    var content = '''
+    content = '''
 class MyClass {}
 
 void f() {
@@ -2137,7 +2136,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'MyClass()'), isTrue);
@@ -2156,7 +2155,7 @@
     // of the label. That text should _not_ appear in filterText as it will
     // affect the editors relevance ranking as the user types.
     // https://github.com/dart-lang/sdk/issues/45157
-    var content = '''
+    content = '''
 abstract class Person {
   String get name;
 }
@@ -2167,7 +2166,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'override name => …');
@@ -2180,7 +2179,7 @@
     // of the label. That text should _not_ appear in filterText as it will
     // affect the editors relevance ranking as the user types.
     // https://github.com/dart-lang/sdk/issues/45157
-    var content = '''
+    content = '''
 abstract class Base {
   void myMethod() {};
 }
@@ -2191,7 +2190,6 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'override myMethod() { … }');
@@ -2204,7 +2202,7 @@
   ///
   /// https://github.com/Dart-Code/Dart-Code/issues/4499
   Future<void> test_getter_narrowedBySubclass() async {
-    var content = '''
+    content = '''
 void f(MyItem item) {
   item.na^
 }
@@ -2222,7 +2220,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var name = res.singleWhere((c) => c.label == 'name');
@@ -2230,7 +2228,7 @@
   }
 
   Future<void> test_gettersAndSetters() async {
-    var content = '''
+    content = '''
 class MyClass {
   String get justGetter => '';
   set justSetter(String value) {}
@@ -2245,7 +2243,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var getter = res.singleWhere((c) => c.label == 'justGetter');
@@ -2260,72 +2258,72 @@
   }
 
   Future<void> test_import() async {
-    var content = '''
+    content = '''
 import '^';
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'dart:async'), isTrue);
   }
 
   Future<void> test_import_configuration() async {
-    var content = '''
+    content = '''
 import 'dart:core' if (dart.library.io) '^';
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'dart:async'), isTrue);
   }
 
   Future<void> test_import_configuration_eof() async {
-    var content = '''
+    content = '''
 import 'dart:core' if (dart.library.io) '^
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'dart:async'), isTrue);
   }
 
   Future<void> test_import_configuration_partial() async {
-    var content = '''
+    content = '''
 import 'dart:core' if (dart.library.io) 'dart:^';
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'dart:async'), isTrue);
   }
 
   Future<void> test_import_eof() async {
-    var content = '''
+    content = '''
 import '^
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'dart:async'), isTrue);
   }
 
   Future<void> test_import_partial() async {
-    var content = '''
+    content = '''
 import 'dart:^';
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'dart:async'), isTrue);
@@ -2341,7 +2339,7 @@
 var myVariable = 1;
 ''');
 
-    var content = '''
+    content = '''
 import 'import.dart' hide myVariable;
 
 void main() {
@@ -2375,7 +2373,7 @@
 }
 ''');
 
-    var content = '''
+    content = '''
 import 'import.dart' show MyEnum;
 
 void main() {
@@ -2404,7 +2402,7 @@
   Future<void> test_insertReplaceRanges() async {
     setCompletionItemInsertReplaceSupport();
 
-    var content = '''
+    content = '''
 class MyClass {
   String abcdefghij;
 }
@@ -2416,7 +2414,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
@@ -2426,18 +2424,18 @@
     var replaced = applyTextEdits(code.code, [
       textEditForReplace(item.textEdit!),
     ]);
-    expect(replaced, contains('a.abcdefghij\n'));
+    expect(replaced, contains('a.abcdefghij$eol'));
     // When using the insert range, we should retain what was after the caret
     // ("def" in this case).
     var inserted = applyTextEdits(code.code, [
       textEditForInsert(item.textEdit!),
     ]);
-    expect(inserted, contains('a.abcdefghijdef\n'));
+    expect(inserted, contains('a.abcdefghijdef$eol'));
   }
 
   Future<void> test_insertTextMode_multiline() async {
     setCompletionItemInsertTextModeSupport();
-    var content = '''
+    content = '''
 import 'package:flutter/material.dart';
 
 class _MyWidgetState extends State<MyWidget> {
@@ -2450,7 +2448,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label.startsWith('setState'));
@@ -2458,21 +2456,21 @@
     // Multiline completions should always set insertTextMode.asIs.
     expect(item.insertText, isNull);
     var textEdit = toTextEdit(item.textEdit!);
-    expect(textEdit.newText, contains('\n'));
+    expect(textEdit.newText, contains(eol));
     expect(item.insertTextMode, equals(InsertTextMode.asIs));
   }
 
   Future<void> test_insertTextMode_singleLine() async {
     setCompletionItemInsertTextModeSupport();
 
-    var content = '''
+    content = '''
 void foo() {
   ^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label.startsWith('foo'));
@@ -2499,33 +2497,33 @@
   }
 
   Future<void> test_inside_nonLateFinal() async {
-    var content = '''
+    content = '''
 class MyClass {
   String get myGetter => '';
   final myField = myG^
 }
 ''';
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res, isEmpty);
   }
 
   Future<void> test_insideString() async {
-    var content = '''
+    content = '''
 var a = "This is ^a test"
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res, isEmpty);
   }
 
   Future<void> test_isDeprecated_notSupported() async {
-    var content = '''
+    content = '''
 class MyClass {
   @deprecated
   String abcdefghij;
@@ -2538,7 +2536,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'abcdefghij');
@@ -2550,7 +2548,7 @@
 
   Future<void> test_isDeprecated_supportedFlag() async {
     setCompletionItemDeprecatedFlagSupport();
-    var content = '''
+    content = '''
 class MyClass {
   @deprecated
   String abcdefghij;
@@ -2563,7 +2561,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'abcdefghij');
@@ -2576,7 +2574,7 @@
   Future<void> test_isDeprecated_supportedTag() async {
     setCompletionItemTagSupport([CompletionItemTag.Deprecated]);
 
-    var content = '''
+    content = '''
 class MyClass {
   @deprecated
   String abcdefghij;
@@ -2589,7 +2587,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var item = res.singleWhere((c) => c.label == 'abcdefghij');
@@ -2600,14 +2598,13 @@
   }
 
   Future<void> test_isIncomplete_falseIfAllIncluded() async {
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   A a = A();
   a.^
 }
 ''';
-    var code = TestCode.parse(content);
 
     // Create a class with fields aaa1 to aaa500 in the other file.
     newFile(
@@ -2616,7 +2613,7 @@
         'class A {',
         for (var i = 1; i <= 500; i++) 'String get aaa$i => "";',
         '}',
-      ].join('\n'),
+      ].join(eol),
     );
 
     await initialize();
@@ -2630,14 +2627,13 @@
   }
 
   Future<void> test_isIncomplete_trueIfNotAllIncluded() async {
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   A a = A();
   a.^
 }
 ''';
-    var code = TestCode.parse(content);
 
     // Create a class with fields aaa1 to aaa500 in the other file.
     newFile(
@@ -2647,7 +2643,7 @@
         for (var i = 1; i <= 500; i++) '  String get aaa$i => "";',
         '  String get aaa => "";',
         '}',
-      ].join('\n'),
+      ].join(eol),
     );
 
     await provideConfig(initialize, {'maxCompletionItems': 200});
@@ -2664,12 +2660,11 @@
     setCompletionItemInsertReplaceSupport();
     setCompletionListDefaults(['editRange']);
 
-    var content = '''
+    content = '''
 void myFunction() {
   [!myFunctio^!]
 }
 ''';
-    var code = TestCode.parse(content);
 
     await initialize();
     await openFile(mainFileUri, code.code);
@@ -2701,12 +2696,11 @@
     //
     // Additionally, because the caret is before the identifier, we will have
     // separate default insert/replace ranges.
-    var content = '''
+    content = '''
 void f(String a, {String? b}) {
   f([!^b!]);
 }
 ''';
-    var code = TestCode.parse(content);
 
     await initialize();
     await openFile(mainFileUri, code.code);
@@ -2746,7 +2740,7 @@
     // We only normally set InsertTextMode on multiline completions (where it
     // matters), so ensure there's a multiline completion in the results for
     // testing.
-    var content = '''
+    content = '''
 import 'package:flutter/material.dart';
 
 class _MyWidgetState extends State<MyWidget> {
@@ -2757,7 +2751,6 @@
   }
 }
 ''';
-    var code = TestCode.parse(content);
 
     await initialize();
     await openFile(mainFileUri, code.code);
@@ -2773,13 +2766,12 @@
   /// Exact matches should always be included when completion lists are
   /// truncated, even if they ranked poorly.
   Future<void> test_maxCompletionItems_doesNotExcludeExactMatches() async {
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   var a = Item^
 }
 ''';
-    var code = TestCode.parse(content);
 
     // Create classes `Item1` to `Item20` along with a field named `item`.
     // The classes will rank higher in the position above and push
@@ -2789,7 +2781,7 @@
       [
         'String item = "";',
         for (var i = 1; i <= 20; i++) 'class Item$i {}',
-      ].join('\n'),
+      ].join(eol),
     );
 
     await provideConfig(initialize, {'maxCompletionItems': 10});
@@ -2808,13 +2800,12 @@
   /// because they are not ranked like other completions and might be
   /// truncated when they are exactly what the user wants.
   Future<void> test_maxCompletionItems_doesNotExcludeSnippets() async {
-    var content = '''
+    content = '''
 import 'a.dart';
 void f() {
   fo^
 }
 ''';
-    var code = TestCode.parse(content);
 
     // Create fields for1 to for20 in the other file.
     newFile(
@@ -2823,7 +2814,7 @@
         for (var i = 1; i <= 20; i++)
           'String for$i = '
               ';',
-      ].join('\n'),
+      ].join(eol),
     );
 
     setCompletionItemSnippetSupport();
@@ -2847,7 +2838,7 @@
   }
 
   Future<void> test_namedArg_flutterChildren() async {
-    var content = '''
+    content = '''
 import 'package:flutter/widgets.dart';
 
 final a = Flex(c^);
@@ -2872,7 +2863,7 @@
     // Flutter's widget classes have special handling that adds `[]` after the
     // children named arg, but this should not occur if there's already a value
     // for this named arg.
-    var content = '''
+    content = '''
 import 'package:flutter/widgets.dart';
 
 final a = Flex(c^: []);
@@ -2901,7 +2892,7 @@
       required String expectedReplace,
       required String expectedInsert,
     }) async {
-      var content = '''
+      content = '''
 class A { const A({int argOne, int argTwo, String argThree}); }
 final varOne = '';
 $code
@@ -2990,7 +2981,7 @@
     // identifier to be used as the `targetPrefix` which would filter out
     // other symbol.
     // https://github.com/Dart-Code/Dart-Code/issues/2672#issuecomment-666085575
-    var content = '''
+    content = '''
 void f() {
   myFunction(
     ^
@@ -3002,21 +2993,21 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'aaab: '), isTrue);
   }
 
   Future<void> test_namedArg_plainText() async {
-    var content = '''
+    content = '''
 class A { const A({int one}); }
 @A(^)
 void f() { }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'one: '), isTrue);
@@ -3033,7 +3024,7 @@
   }
 
   Future<void> test_namedArg_snippetStringSelection_endOfString() async {
-    var content = '''
+    content = '''
 class A { const A({int one}); }
 @A(^)
 void f() { }
@@ -3041,7 +3032,7 @@
 
     setCompletionItemSnippetSupport();
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'one: '), isTrue);
@@ -3061,7 +3052,7 @@
 
   Future<void>
   test_namedArgTrailing_snippetStringSelection_insideString() async {
-    var content = '''
+    content = '''
 void f({int one, int two}) {
   f(
     ^
@@ -3072,7 +3063,7 @@
 
     setCompletionItemSnippetSupport();
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'one: '), isTrue);
@@ -3102,7 +3093,7 @@
   }
 
   Future<void> test_noOperators_propertyAccessExternal() async {
-    var content = '''
+    content = '''
 class A {
   int operator-() => 0;
   int operator-(int other) => 0;
@@ -3114,7 +3105,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var completions = await getCompletion(mainFileUri, code.position.position);
     var labels = completions.map((c) => c.label).toList();
@@ -3124,7 +3115,7 @@
   }
 
   Future<void> test_noOperators_propertyAccessInternal() async {
-    var content = '''
+    content = '''
 class A {
   int operator-() => 0;
   int operator-(int other) => 0;
@@ -3136,7 +3127,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var completions = await getCompletion(mainFileUri, code.position.position);
     var labels = completions.map((c) => c.label).toList();
@@ -3146,7 +3137,7 @@
   }
 
   Future<void> test_noOperators_superPropertyAccess() async {
-    var content = '''
+    content = '''
 class A {
   int operator-() => 0;
   int operator-(int other) => 0;
@@ -3160,7 +3151,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var completions = await getCompletion(mainFileUri, code.position.position);
     var labels = completions.map((c) => c.label).toList();
@@ -3170,7 +3161,7 @@
   }
 
   Future<void> test_nullableTypes() async {
-    var content = '''
+    content = '''
 String? foo(int? a, [int b = 1]) {}
 
 void f() {
@@ -3179,7 +3170,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3189,7 +3180,7 @@
   }
 
   Future<void> test_operators_override() async {
-    var content = '''
+    content = '''
 class A {
   int operator-() => 0;
   int operator-(int other) => 0;
@@ -3201,7 +3192,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var completions = await getCompletion(mainFileUri, code.position.position);
     var labels = completions.map((c) => c.label).toList();
@@ -3211,7 +3202,7 @@
   }
 
   Future<void> test_plainText() async {
-    var content = '''
+    content = '''
 class MyClass {
   String abcdefghij;
 }
@@ -3223,7 +3214,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'abcdefghij'), isTrue);
@@ -3238,7 +3229,7 @@
   }
 
   Future<void> test_prefixed_enumMember() async {
-    var content = '''
+    content = '''
 import 'main.dart' as self;
 
 enum MyEnum {
@@ -3252,14 +3243,14 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'one'), isTrue);
   }
 
   Future<void> test_prefixFilter_endOfSymbol() async {
-    var content = '''
+    content = '''
 class UniqueNamedClassForLspOne {}
 class UniqueNamedClassForLspTwo {}
 class UniqueNamedClassForLspThree {}
@@ -3271,7 +3262,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
@@ -3280,7 +3271,7 @@
   }
 
   Future<void> test_prefixFilter_midSymbol() async {
-    var content = '''
+    content = '''
 class UniqueNamedClassForLspOne {}
 class UniqueNamedClassForLspTwo {}
 class UniqueNamedClassForLspThree {}
@@ -3292,7 +3283,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
@@ -3301,7 +3292,7 @@
   }
 
   Future<void> test_prefixFilter_startOfSymbol() async {
-    var content = '''
+    content = '''
 class UniqueNamedClassForLspOne {}
 class UniqueNamedClassForLspTwo {}
 class UniqueNamedClassForLspThree {}
@@ -3313,7 +3304,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isTrue);
@@ -3322,7 +3313,7 @@
   }
 
   Future<void> test_setters() async {
-    var content = '''
+    content = '''
 class MyClass {
   set stringSetter(String a) {}
   set noArgSetter() {}
@@ -3337,7 +3328,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var setters =
@@ -3356,7 +3347,7 @@
   }
 
   Future<void> test_sort_sortsByRelevance() async {
-    var content = '''
+    content = '''
 class UniquePrefixABC {}
 class UniquePrefixAaBbCc {}
 
@@ -3378,7 +3369,7 @@
   }
 
   Future<void> test_sort_truncatesByFuzzyScore() async {
-    var content = '''
+    content = '''
 class UniquePrefixABC {}
 class UniquePrefixAaBbCc {}
 
@@ -3408,14 +3399,14 @@
 class InOtherFile {}
 ''');
 
-    var content = '''
+    content = '''
 void f() {
   InOtherF^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3463,7 +3454,7 @@
     // Ensure both edits were made - the completion, and the inserted import.
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import '../other_file.dart';
 
 void f() {
@@ -3520,7 +3511,7 @@
 export 'source_file.dart';
 ''');
 
-    var content = '''
+    content = '''
 import 'reexport1.dart';
 import 'reexport2.dart';
 
@@ -3530,7 +3521,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3552,7 +3543,7 @@
 export 'source_file.dart';
 ''');
 
-    var content = '''
+    content = '''
 import 'reexport1.dart';
 
 void f() {
@@ -3561,7 +3552,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3585,14 +3576,14 @@
       'class MyDuplicatedClass {}',
     );
 
-    var content = '''
+    content = '''
 void f() {
   MyDuplicated^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3622,7 +3613,7 @@
 void x(MyExportedEnum e) {}
 ''');
 
-    var content = '''
+    content = '''
 import 'package:test/function_x.dart';
 
 void f() {
@@ -3631,7 +3622,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3678,7 +3669,7 @@
     // Ensure both edits were made - the completion, and the inserted import.
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'package:test/enum.dart';
 import 'package:test/function_x.dart';
 
@@ -3702,7 +3693,7 @@
 export 'enum.dart';
 ''');
 
-    var content = '''
+    content = '''
 import 'reexport1.dart';
 
 void f() {
@@ -3711,7 +3702,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3740,14 +3731,14 @@
       'import "extensions.dart";',
     );
 
-    var content = '''
+    content = '''
 void f(String a) {
   a.empt^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3772,7 +3763,7 @@
     );
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'package:test/extensions.dart';
 
 void f(String a) {
@@ -3793,7 +3784,7 @@
 export 'source_file.dart';
 ''');
 
-    var content = '''
+    content = '''
 import 'reexport1.dart';
 
 void f() {
@@ -3802,7 +3793,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3820,7 +3811,7 @@
       'class MyClass {}',
     );
 
-    var content = '''
+    content = '''
 void f() {
   MyClas^
 }
@@ -3852,7 +3843,7 @@
 }
 ''');
 
-    var content = '''
+    content = '''
 void f() {
   ''.myExtensionMet^
 }
@@ -3887,14 +3878,14 @@
 export 'source_file.dart';
 ''');
 
-    var content = '''
+    content = '''
 void f() {
   MyExported^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3920,14 +3911,14 @@
 class InOtherFile {}
 ''');
 
-    var content = '''
+    content = '''
 void f() {
   InOtherF^il
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -3983,7 +3974,7 @@
     // Ensure both edits were made - the completion, and the inserted import.
     expect(
       newContentReplaceMode,
-      equals('''
+      equalsNormalized('''
 import '../other_file.dart';
 
 void f() {
@@ -3994,7 +3985,7 @@
     // In insert mode, we'd have the trailing "il" still after the caret.
     expect(
       newContentInsertMode,
-      equals('''
+      equalsNormalized('''
 import '../other_file.dart';
 
 void f() {
@@ -4017,7 +4008,7 @@
     newFile(join(projectFolderPath, 'lib', 'parent.dart'), parentContent);
 
     // File that we're invoking completion in.
-    var content = '''
+    content = '''
 part of 'parent.dart';
 void f() {
   InOtherF^
@@ -4025,7 +4016,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -4051,7 +4042,7 @@
     );
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 part of 'parent.dart';
 void f() {
   InOtherFile
@@ -4069,12 +4060,11 @@
 
   Future<void>
   test_unimportedSymbols_isIncompleteNotSetIfBudgetNotExhausted() async {
-    var content = '''
+    content = '''
 void f() {
   InOtherF^
 }
 ''';
-    var code = TestCode.parse(content);
 
     await initialize(
       initializationOptions: {
@@ -4097,12 +4087,11 @@
       'class InOtherFile {}',
     );
 
-    var content = '''
+    content = '''
 void f() {
   InOtherF^
 }
 ''';
-    var code = TestCode.parse(content);
 
     await initialize(
       initializationOptions: {
@@ -4127,7 +4116,7 @@
 class MyClass3 {}
 ''');
 
-    var content = '''
+    content = '''
 import 'package:test/my_classes.dart' hide MyClass1, MyClass2;
 void f() {
   MyClas^
@@ -4157,7 +4146,7 @@
 class MyClass2 {}
 ''');
 
-    var content = '''
+    content = '''
 import 'package:test/my_classes.dart' hide MyClass1;
 void f() {
   MyClas^
@@ -4187,7 +4176,7 @@
 class MyClass2 {}
 ''');
 
-    var content = '''
+    content = '''
 import 'package:test/my_classes.dart' show MyClass2;
 void f() {
   MyClas^
@@ -4220,7 +4209,7 @@
 class MyClass2 {}
 ''');
 
-    var content = '''
+    content = '''
 import 'package:test/my_classes.dart' as p1 show MyClass2;
 void f() {
   MyClas^
@@ -4254,9 +4243,9 @@
     var otherFilePath = join(projectFolderPath, 'lib', 'other_file.dart');
     var otherFileUri = pathContext.toUri(otherFilePath);
 
-    var mainFileCode = TestCode.parse('MyOtherClass^');
+    content = 'MyOtherClass^';
     await initialize();
-    await openFile(mainFileUri, mainFileCode.code);
+    await openFile(mainFileUri, code.code);
     await initialAnalysis;
 
     // Start with a blank file.
@@ -4270,10 +4259,7 @@
     await pumpEventQueue(times: 5000);
 
     // Ensure the class appears in completion.
-    var completions = await getCompletion(
-      mainFileUri,
-      mainFileCode.position.position,
-    );
+    var completions = await getCompletion(mainFileUri, code.position.position);
     var matching = completions.where((c) => c.label == 'MyOtherClass').toList();
     expect(matching, hasLength(1));
   }
@@ -4286,14 +4272,14 @@
 }
 ''');
 
-    var content = '''
+    content = '''
 void f() {
   var a = InOtherF^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -4326,7 +4312,7 @@
     // Ensure both edits were made - the completion, and the inserted import.
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import '../other_file.dart';
 
 void f() {
@@ -4356,7 +4342,7 @@
     // A will already be imported
     // B will already be imported but with a prefix
     // C & D are not imported and need importing (return + parameter types)
-    var content = '''
+    content = '''
 import 'package:test/a.dart';
 import 'package:test/b.dart' as b;
 import 'package:test/base.dart';
@@ -4367,7 +4353,7 @@
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -4386,7 +4372,7 @@
 
     expect(
       newContent,
-      equals('''
+      equalsNormalized('''
 import 'package:test/a.dart';
 import 'package:test/b.dart' as b;
 import 'package:test/base.dart';
@@ -4424,7 +4410,7 @@
     // Create a file that will be auto-imported from completion.
     newFile(importedFilePath, 'class MyClass {}');
 
-    var content = '''
+    content = '''
 void f() {
   MyClas^
 }
@@ -4470,7 +4456,7 @@
     // Create a file that will be auto-imported from completion.
     newFile(importedFilePath, 'class MyClass {}');
 
-    var content = '''
+    content = '''
 void f() {
   MyClas^
 }
@@ -4497,7 +4483,7 @@
   Future<void> test_unimportedSymbols_unavailableIfDisabled() async {
     newFile(join(projectFolderPath, 'other_file.dart'), 'class InOtherFile {}');
 
-    var content = '''
+    content = '''
 void f() {
   InOtherF^
 }
@@ -4510,7 +4496,7 @@
         'suggestFromUnimportedLibraries': false,
       },
     );
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -4528,14 +4514,14 @@
 
     newFile(join(projectFolderPath, 'other_file.dart'), 'class InOtherFile {}');
 
-    var content = '''
+    content = '''
 void f() {
   InOtherF^
 }
 ''';
 
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     await initialAnalysis;
     var res = await getCompletion(mainFileUri, code.position.position);
@@ -4547,7 +4533,7 @@
   }
 
   Future<void> test_unopenFile() async {
-    var content = '''
+    content = '''
 class MyClass {
   String abcdefghij;
 }
@@ -4557,7 +4543,6 @@
   a.abc^
 }
 ''';
-    var code = TestCode.parse(content);
 
     newFile(mainFilePath, code.code);
     await initialize();
@@ -4584,7 +4569,6 @@
     String completionLabel,
     String expectedContent,
   ) async {
-    var code = TestCode.parse(content);
     await initialize();
     await openFile(fileUri, code.code);
     await initialAnalysis;
@@ -4601,7 +4585,7 @@
       ].followedBy(resolvedCompletion.additionalTextEdits!).toList(),
     );
 
-    expect(newContent, equals(expectedContent));
+    expect(newContent, equalsNormalized(expectedContent));
   }
 
   Future<void> _checkResultsForTriggerCharacters(
@@ -4609,7 +4593,6 @@
     List<String> triggerCharacters,
     Matcher expectedResults,
   ) async {
-    var code = TestCode.parse(content);
     await initialize();
     await openFile(mainFileUri, code.code);
 
@@ -4635,28 +4618,30 @@
 @reflectiveTest
 class DartSnippetCompletionTest extends SnippetCompletionTest {
   Future<void> test_snippets_class() async {
-    var content = '''
+    content = '''
 clas^
 ''';
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: ClassDeclaration.prefix,
       label: ClassDeclaration.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 class ${1:ClassName} {
   $0
 }
-''');
+'''),
+    );
   }
 
   /// Checks that the `enableSnippets` setting can disable snippets even if the
   /// client supports them.
   Future<void> test_snippets_disabled() async {
-    var content = '^';
+    content = '^';
 
     // Support is set in setUp, but here we disable the user preference.
     await provideConfig(initialize, {'enableSnippets': false});
@@ -4665,7 +4650,7 @@
   }
 
   Future<void> test_snippets_doWhile() async {
-    var content = '''
+    content = '''
 void f() {
   do^
 }
@@ -4673,18 +4658,20 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: DoStatement.prefix,
       label: DoStatement.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void f() {
   do {
     $0
   } while (${1:condition});
 }
-''');
+'''),
+    );
   }
 
   /// Snippets completions may abort if documents are modified (because they
@@ -4692,12 +4679,11 @@
   /// prevent non-Snippet completion results from being returned (because this
   /// happens frequently while typing).
   Future<void> test_snippets_failureDoesNotPreventNonSnippets() async {
-    var content = '''
+    content = '''
 void f() {
   ^
 }
 ''';
-    var code = TestCode.parse(content);
 
     await initialize();
     await openFile(mainFileUri, code.code);
@@ -4729,7 +4715,7 @@
 
   Future<void>
   test_snippets_flutterStateless_notAvailable_notFlutterProject() async {
-    var content = '''
+    content = '''
 class A {}
 
 stle^
@@ -4742,7 +4728,7 @@
   }
 
   Future<void> test_snippets_for() async {
-    var content = '''
+    content = '''
 void f() {
   for^
 }
@@ -4750,22 +4736,24 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: ForStatement.prefix,
       label: ForStatement.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void f() {
   for (var i = 0; i < ${1:count}; i++) {
     $0
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_forIn() async {
-    var content = '''
+    content = '''
 void f() {
   forin^
 }
@@ -4773,22 +4761,24 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: ForInStatement.prefix,
       label: ForInStatement.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void f() {
   for (var ${1:element} in ${2:collection}) {
     $0
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_functionClassMember() async {
-    var content = '''
+    content = '''
 class A {
   fun^
 }
@@ -4796,22 +4786,24 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FunctionDeclaration.prefix,
       label: FunctionDeclaration.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 class A {
   ${1:void} ${2:name}(${3:params}) {
     $0
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_functionNested() async {
-    var content = '''
+    content = '''
 void a() {
   fun^
 }
@@ -4819,41 +4811,45 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FunctionDeclaration.prefix,
       label: FunctionDeclaration.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void a() {
   ${1:void} ${2:name}(${3:params}) {
     $0
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_functionTopLevel() async {
-    var content = '''
+    content = '''
 fun^
 ''';
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FunctionDeclaration.prefix,
       label: FunctionDeclaration.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 ${1:void} ${2:name}(${3:params}) {
   $0
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_if() async {
-    var content = '''
+    content = '''
 void f() {
   if^
 }
@@ -4861,22 +4857,24 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: IfStatement.prefix,
       label: IfStatement.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void f() {
   if (${1:condition}) {
     $0
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_ifElse() async {
-    var content = '''
+    content = '''
 void f() {
   if^
 }
@@ -4884,12 +4882,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: IfElseStatement.prefix,
       label: IfElseStatement.label,
     );
     var fourSpaces = '    ';
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 void f() {
   if (\${1:condition}) {
     \$0
@@ -4897,7 +4896,8 @@
 $fourSpaces
   }
 }
-''');
+'''),
+    );
   }
 
   /// Fetch snippets with itemDefaults enabled to ensure we don't return any
@@ -4909,26 +4909,28 @@
       'insertTextMode',
       'insertTextFormat',
     ]);
-    var content = '''
+    content = '''
 fu^
 ''';
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FunctionDeclaration.prefix,
       label: FunctionDeclaration.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 ${1:void} ${2:name}(${3:params}) {
   $0
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_mainFunction() async {
-    var content = '''
+    content = '''
 class A {}
 
 main^
@@ -4938,12 +4940,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: MainFunction.prefix,
       label: MainFunction.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 class A {}
 
 void main(List<String> args) {
@@ -4951,24 +4954,25 @@
 }
 
 class B {}
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_notSupported() async {
-    var content = '^';
+    content = '^';
 
     // If we don't send support for Snippet CompletionItem kinds, we don't
     // expect any snippets at all.
     setCompletionItemSnippetSupport(false);
     await initialize();
-    var code = TestCode.parse(content);
+
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     expect(res.any((c) => c.kind == CompletionItemKind.Snippet), isFalse);
   }
 
   Future<void> test_snippets_switch() async {
-    var content = '''
+    content = '''
 void f() {
   swi^
 }
@@ -4976,12 +4980,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: SwitchStatement.prefix,
       label: SwitchStatement.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void f() {
   switch (${1:expression}) {
     case ${2:value}:
@@ -4990,12 +4995,13 @@
     default:
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_testBlock() async {
     mainFilePath = join(projectFolderPath, 'test', 'foo_test.dart');
-    var content = '''
+    content = '''
 void f() {
   test^
 }
@@ -5003,12 +5009,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: TestDefinition.prefix,
       label: TestDefinition.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 import 'package:test/test.dart';
 
 void f() {
@@ -5016,12 +5023,13 @@
     $0
   });
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_testGroupBlock() async {
     mainFilePath = join(projectFolderPath, 'test', 'foo_test.dart');
-    var content = '''
+    content = '''
 void f() {
   group^
 }
@@ -5029,12 +5037,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: TestGroupDefinition.prefix,
       label: TestGroupDefinition.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 import 'package:test/test.dart';
 
 void f() {
@@ -5042,11 +5051,12 @@
     $0
   });
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_tryCatch() async {
-    var content = '''
+    content = '''
 void f() {
   tr^
 }
@@ -5054,12 +5064,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: TryCatchStatement.prefix,
       label: TryCatchStatement.label,
     );
     var fourSpaces = '    ';
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 void f() {
   try {
     \$0
@@ -5067,11 +5078,12 @@
 $fourSpaces
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_while() async {
-    var content = '''
+    content = '''
 void f() {
   while^
 }
@@ -5079,18 +5091,20 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: WhileStatement.prefix,
       label: WhileStatement.label,
     );
 
-    expect(updated, r'''
+    expect(
+      updated,
+      equalsNormalized(r'''
 void f() {
   while (${1:condition}) {
     $0
   }
 }
-''');
+'''),
+    );
   }
 }
 
@@ -5110,7 +5124,7 @@
   }
 
   Future<void> test_snippets_flutterStateful() async {
-    var content = '''
+    content = '''
 import 'package:flutter/widgets.dart';
 
 class A {}
@@ -5122,12 +5136,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FlutterStatefulWidget.prefix,
       label: FlutterStatefulWidget.label,
     );
 
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 import 'package:flutter/widgets.dart';
 
 class A {}
@@ -5147,11 +5162,12 @@
 }
 
 class B {}
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_flutterStatefulWithAnimationController() async {
-    var content = '''
+    content = '''
 import 'package:flutter/widgets.dart';
 
 class A {}
@@ -5163,12 +5179,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FlutterStatefulWidgetWithAnimationController.prefix,
       label: FlutterStatefulWidgetWithAnimationController.label,
     );
 
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 import 'package:flutter/widgets.dart';
 
 class A {}
@@ -5203,11 +5220,12 @@
 }
 
 class B {}
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_flutterStateless() async {
-    var content = '''
+    content = '''
 import 'package:flutter/widgets.dart';
 
 class A {}
@@ -5219,12 +5237,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FlutterStatelessWidget.prefix,
       label: FlutterStatelessWidget.label,
     );
 
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 import 'package:flutter/widgets.dart';
 
 class A {}
@@ -5239,11 +5258,12 @@
 }
 
 class B {}
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_flutterStateless_addsImports() async {
-    var content = '''
+    content = '''
 class A {}
 
 stle^
@@ -5253,12 +5273,13 @@
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FlutterStatelessWidget.prefix,
       label: FlutterStatelessWidget.label,
     );
 
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 $expectedImports
 
 class A {}
@@ -5273,22 +5294,24 @@
 }
 
 class B {}
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_flutterStateless_addsImports_onlyPrefix() async {
-    var content = '''
+    content = '''
 stless^
 ''';
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FlutterStatelessWidget.prefix,
       label: FlutterStatelessWidget.label,
     );
 
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 $expectedImports
 
 class \${1:MyWidget} extends StatelessWidget {
@@ -5299,22 +5322,24 @@
     return \${0:const Placeholder()};
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_flutterStateless_addsImports_zeroOffset() async {
-    var content = '''
+    content = '''
 ^
 '''; // Deliberate trailing newline to ensure imports aren't inserted at "end".
 
     await initialize();
     var updated = await expectAndApplySnippet(
-      content,
       prefix: FlutterStatelessWidget.prefix,
       label: FlutterStatelessWidget.label,
     );
 
-    expect(updated, '''
+    expect(
+      updated,
+      equalsNormalized('''
 $expectedImports
 
 class \${1:MyWidget} extends StatelessWidget {
@@ -5325,11 +5350,12 @@
     return \${0:const Placeholder()};
   }
 }
-''');
+'''),
+    );
   }
 
   Future<void> test_snippets_flutterStateless_notAvailable_notTopLevel() async {
-    var content = '''
+    content = '''
 class A {
 
   stle^
@@ -5342,10 +5368,9 @@
   }
 
   Future<void> test_snippets_flutterStateless_outsideAnalysisRoot() async {
-    var content = '''
+    content = '''
 stle^
 ''';
-    var code = TestCode.parse(content);
 
     await initialize();
     var otherFileUri = pathContext.toUri(convertPath('/other/file.dart'));
@@ -5358,14 +5383,15 @@
 
 abstract class SnippetCompletionTest extends AbstractLspAnalysisServerTest
     with CompletionTestMixin {
+  late String content;
+  late final code = TestCode.parseNormalized(content);
+
   /// Expect that there is a snippet for [prefix] at [position] with the label
   /// [label] and return the results of applying it to [content].
-  Future<String> expectAndApplySnippet(
-    String content, {
+  Future<String> expectAndApplySnippet({
     required String prefix,
     required String label,
   }) async {
-    var code = TestCode.parse(content);
     var (snippet: snippet, defaults: defaults) = await expectSnippet(
       code,
       prefix: prefix,
@@ -5408,7 +5434,6 @@
   /// Expect that there is no snippet for [prefix] at the position of `^` within
   /// [content].
   Future<void> expectNoSnippet(String content, String prefix) async {
-    var code = TestCode.parse(content);
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var hasSnippet = res.any((c) => c.filterText == prefix);
@@ -5417,7 +5442,6 @@
 
   /// Expect that there are no snippets at the position of `^` within [content].
   Future<void> expectNoSnippets(String content) async {
-    var code = TestCode.parse(content);
     await openFile(mainFileUri, code.code);
     var res = await getCompletion(mainFileUri, code.position.position);
     var hasAnySnippet = res.any((c) => c.kind == CompletionItemKind.Snippet);
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index d679ceb..cc08490 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -17,6 +17,7 @@
 import 'package:analysis_server/src/utilities/mocks.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/platform.dart';
 import 'package:analyzer/src/test_utilities/test_code_format.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
@@ -78,6 +79,9 @@
   LspClientCapabilities get editorClientCapabilities =>
       server.editorClientCapabilities!;
 
+  /// The line terminator being used for test files and to be expected in edits.
+  String get eol => testEol;
+
   String get mainFileAugmentationPath => fromUri(mainFileAugmentationUri);
 
   /// The path that is not in [projectFolderPath], contains external packages.
@@ -140,6 +144,12 @@
     return info;
   }
 
+  /// Returns a matcher that checks that the input matches [expected] after
+  /// newlines have been normalized to the current platforms (only in
+  /// [expected]).
+  Matcher equalsNormalized(String expected) =>
+      equals(normalizeNewlinesForPlatform(expected));
+
   void expectContextBuilds() => expect(
     server.contextBuilds - _previousContextBuilds,
     greaterThan(0),
diff --git a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
index 653eefd..8205bf8 100644
--- a/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
+++ b/pkg/analysis_server/test/services/completion/postfix/postfix_completion_test.dart
@@ -37,7 +37,7 @@
     if (change.edits.isNotEmpty) {
       // We use a carat in the expected code to prevent lines containing only
       // whitespace from being made empty.
-      var expectedCode = TestCode.parse(normalizeSource(expected));
+      var expectedCode = TestCode.parseNormalized(expected);
       var resultCode = SourceEdit.applySequence(
         testCode,
         change.edits[0].edits,
@@ -68,7 +68,7 @@
   }
 
   Future<void> _prepareProcessor(String key, String code) async {
-    testCodeCode = TestCode.parse(normalizeSource(code));
+    testCodeCode = TestCode.parseNormalized(code);
 
     verifyNoTestUnitErrors = false;
     await resolveTestCode(testCodeCode.code);
diff --git a/pkg/analysis_server/test/services/snippets/snippet_request_test.dart b/pkg/analysis_server/test/services/snippets/snippet_request_test.dart
index e590d9a..01ad7d3 100644
--- a/pkg/analysis_server/test/services/snippets/snippet_request_test.dart
+++ b/pkg/analysis_server/test/services/snippets/snippet_request_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/src/services/snippets/dart_snippet_request.dart';
 import 'package:analysis_server/src/services/snippets/snippet_context.dart';
-import 'package:analyzer/src/test_utilities/platform.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';
@@ -625,7 +624,7 @@
     String content,
     SnippetContext expectedContext,
   ) async {
-    var code = TestCode.parse(normalizeNewlinesForPlatform(content));
+    var code = TestCode.parseNormalized(content);
     var offset = code.position.offset;
     var expectedReplacementRange = code.range.sourceRange;
     await resolveTestCode(code.code);
diff --git a/pkg/analyzer/lib/src/test_utilities/platform.dart b/pkg/analyzer/lib/src/test_utilities/platform.dart
index 6157220..c076b4c 100644
--- a/pkg/analyzer/lib/src/test_utilities/platform.dart
+++ b/pkg/analyzer/lib/src/test_utilities/platform.dart
@@ -4,6 +4,13 @@
 
 import 'dart:io';
 
+/// The EOL being used for file content in the current test run.
+String get testEol =>
+    // TODO(dantup): Support overridding this with an env var to allow testing
+    //  `\n` on Windows or `\r\n` on non-Windows, to ensure we don't have any
+    //  code just assuming the platform EOL (instead of the files EOL).
+    Platform.lineTerminator;
+
 /// Normalizes content to use platform-specific newlines.
 ///
 /// This ensures that when running on Windows, '\r\n' is used, even though
@@ -16,5 +23,5 @@
   }
 
   var newlinePattern = RegExp(r'\r?\n'); // Either '\r\n' or '\n'.
-  return input.replaceAll(newlinePattern, Platform.lineTerminator);
+  return input.replaceAll(newlinePattern, testEol);
 }
diff --git a/pkg/analyzer/lib/src/test_utilities/test_code_format.dart b/pkg/analyzer/lib/src/test_utilities/test_code_format.dart
index d128cda..2ffffd2 100644
--- a/pkg/analyzer/lib/src/test_utilities/test_code_format.dart
+++ b/pkg/analyzer/lib/src/test_utilities/test_code_format.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/test_utilities/platform.dart';
 import 'package:collection/collection.dart';
 
 /// A class for parsing and representing test code that contains special markup
@@ -183,6 +184,23 @@
       ranges: ranges.values.toList(),
     );
   }
+
+  /// A version of [TestCode.parse] that normalizes newlines in the code to
+  /// match that for the current platform so that tests on Windows test using
+  /// `\r\n` and tests on other platforms test using `\n`.
+  static TestCode parseNormalized(
+    String markedCode, {
+    bool positionShorthand = true,
+    bool rangeShorthand = true,
+    bool zeroWidthMarker = true,
+  }) {
+    return parse(
+      normalizeNewlinesForPlatform(markedCode),
+      positionShorthand: positionShorthand,
+      rangeShorthand: rangeShorthand,
+      zeroWidthMarker: zeroWidthMarker,
+    );
+  }
 }
 
 /// A marked position in the test code.