Migrate localizations_utils to null safety (#78939)

diff --git a/packages/flutter_tools/lib/src/localizations/localizations_utils.dart b/packages/flutter_tools/lib/src/localizations/localizations_utils.dart
index 267adf6..393e80e 100644
--- a/packages/flutter_tools/lib/src/localizations/localizations_utils.dart
+++ b/packages/flutter_tools/lib/src/localizations/localizations_utils.dart
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// @dart = 2.8
-
 import 'package:meta/meta.dart';
 import 'package:yaml/yaml.dart';
 
@@ -22,11 +20,11 @@
 @immutable
 class LocaleInfo implements Comparable<LocaleInfo> {
   const LocaleInfo({
-    this.languageCode,
-    this.scriptCode,
-    this.countryCode,
-    this.length,
-    this.originalString,
+    required this.languageCode,
+    required this.scriptCode,
+    required this.countryCode,
+    required this.length,
+    required this.originalString,
   });
 
   /// Simple parser. Expects the locale string to be in the form of 'language_script_COUNTRY'
@@ -41,8 +39,8 @@
     final List<String> codes = locale.split('_'); // [language, script, country]
     assert(codes.isNotEmpty && codes.length < 4);
     final String languageCode = codes[0];
-    String scriptCode;
-    String countryCode;
+    String? scriptCode;
+    String? countryCode;
     int length = codes.length;
     String originalString = locale;
     if (codes.length == 2) {
@@ -112,8 +110,8 @@
   }
 
   final String languageCode;
-  final String scriptCode;
-  final String countryCode;
+  final String? scriptCode;
+  final String? countryCode;
   final int length;             // The number of fields. Ranges from 1-3.
   final String originalString;  // Original un-parsed locale string.
 
@@ -149,7 +147,7 @@
 // See also //master/tools/gen_locale.dart in the engine repo.
 Map<String, List<String>> _parseSection(String section) {
   final Map<String, List<String>> result = <String, List<String>>{};
-  List<String> lastHeading;
+  late List<String> lastHeading;
   for (final String line in section.split('\n')) {
     if (line == '') {
       continue;
@@ -165,7 +163,7 @@
     final String name = line.substring(0, colon);
     final String value = line.substring(colon + 2);
     lastHeading = result.putIfAbsent(name, () => <String>[]);
-    result[name].add(value);
+    result[name]!.add(value);
   }
   return result;
 }
@@ -184,11 +182,11 @@
       languageSubtagRegistry.split('%%').skip(1).map<Map<String, List<String>>>(_parseSection).toList();
   for (final Map<String, List<String>> section in sections) {
     assert(section.containsKey('Type'), section.toString());
-    final String type = section['Type'].single;
+    final String type = section['Type']!.single;
     if (type == 'language' || type == 'region' || type == 'script') {
       assert(section.containsKey('Subtag') && section.containsKey('Description'), section.toString());
-      final String subtag = section['Subtag'].single;
-      String description = section['Description'].join(' ');
+      final String subtag = section['Subtag']!.single;
+      String description = section['Description']!.join(' ');
       if (description.startsWith('United ')) {
         description = 'the $description';
       }
@@ -220,10 +218,10 @@
   final List<String> subtags = tag.split('_');
   assert(subtags.isNotEmpty);
   assert(_languages.containsKey(subtags[0]));
-  final String language = _languages[subtags[0]];
+  final String language = _languages[subtags[0]]!;
   String output = language;
-  String region;
-  String script;
+  String? region;
+  String? script;
   if (subtags.length == 2) {
     region = _regions[subtags[1]];
     script = _scripts[subtags[1]];
@@ -311,50 +309,50 @@
   /// The `--arb-dir` argument.
   ///
   /// The directory where all input localization files should reside.
-  final Uri arbDirectory;
+  final Uri? arbDirectory;
 
   /// The `--template-arb-file` argument.
   ///
   /// This URI is relative to [arbDirectory].
-  final Uri templateArbFile;
+  final Uri? templateArbFile;
 
   /// The `--output-localization-file` argument.
   ///
   /// This URI is relative to [arbDirectory].
-  final Uri outputLocalizationsFile;
+  final Uri? outputLocalizationsFile;
 
   /// The `--untranslated-messages-file` argument.
   ///
   /// This URI is relative to [arbDirectory].
-  final Uri untranslatedMessagesFile;
+  final Uri? untranslatedMessagesFile;
 
   /// The `--header` argument.
   ///
   /// The header to prepend to the generated Dart localizations.
-  final String header;
+  final String? header;
 
   /// The `--output-class` argument.
-  final String outputClass;
+  final String? outputClass;
 
   /// The `--output-dir` argument.
   ///
   /// The directory where all output localization files should be generated.
-  final Uri outputDirectory;
+  final Uri? outputDirectory;
 
   /// The `--preferred-supported-locales` argument.
-  final List<String> preferredSupportedLocales;
+  final List<String>? preferredSupportedLocales;
 
   /// The `--header-file` argument.
   ///
   /// A file containing the header to prepend to the generated
   /// Dart localizations.
-  final Uri headerFile;
+  final Uri? headerFile;
 
   /// The `--use-deferred-loading` argument.
   ///
   /// Whether to generate the Dart localization file with locales imported
   /// as deferred.
-  final bool deferredLoading;
+  final bool? deferredLoading;
 
   /// The `--synthetic-package` argument.
   ///
@@ -375,8 +373,8 @@
 /// [LocalizationOptions] with all fields as `null` if the config file exists
 /// but is empty.
 LocalizationOptions parseLocalizationsOptions({
-  @required File file,
-  @required Logger logger,
+  required File file,
+  required Logger logger,
 }) {
   final String contents = file.readAsStringSync();
   if (contents.trim().isEmpty) {
@@ -387,26 +385,25 @@
     logger.printError('Expected ${file.path} to contain a map, instead was $yamlNode');
     throw Exception();
   }
-  final YamlMap yamlMap = yamlNode as YamlMap;
   return LocalizationOptions(
-    arbDirectory: _tryReadUri(yamlMap, 'arb-dir', logger),
-    templateArbFile: _tryReadUri(yamlMap, 'template-arb-file', logger),
-    outputLocalizationsFile: _tryReadUri(yamlMap, 'output-localization-file', logger),
-    untranslatedMessagesFile: _tryReadUri(yamlMap, 'untranslated-messages-file', logger),
-    header: _tryReadString(yamlMap, 'header', logger),
-    outputClass: _tryReadString(yamlMap, 'output-class', logger),
-    outputDirectory: _tryReadUri(yamlMap, 'output-dir', logger),
-    preferredSupportedLocales: _tryReadStringList(yamlMap, 'preferred-supported-locales', logger),
-    headerFile: _tryReadUri(yamlMap, 'header-file', logger),
-    deferredLoading: _tryReadBool(yamlMap, 'use-deferred-loading', logger),
-    useSyntheticPackage: _tryReadBool(yamlMap, 'synthetic-package', logger) ?? true,
-    areResourceAttributesRequired: _tryReadBool(yamlMap, 'required-resource-attributes', logger) ?? false,
+    arbDirectory: _tryReadUri(yamlNode, 'arb-dir', logger),
+    templateArbFile: _tryReadUri(yamlNode, 'template-arb-file', logger),
+    outputLocalizationsFile: _tryReadUri(yamlNode, 'output-localization-file', logger),
+    untranslatedMessagesFile: _tryReadUri(yamlNode, 'untranslated-messages-file', logger),
+    header: _tryReadString(yamlNode, 'header', logger),
+    outputClass: _tryReadString(yamlNode, 'output-class', logger),
+    outputDirectory: _tryReadUri(yamlNode, 'output-dir', logger),
+    preferredSupportedLocales: _tryReadStringList(yamlNode, 'preferred-supported-locales', logger),
+    headerFile: _tryReadUri(yamlNode, 'header-file', logger),
+    deferredLoading: _tryReadBool(yamlNode, 'use-deferred-loading', logger),
+    useSyntheticPackage: _tryReadBool(yamlNode, 'synthetic-package', logger) ?? true,
+    areResourceAttributesRequired: _tryReadBool(yamlNode, 'required-resource-attributes', logger) ?? false,
   );
 }
 
 // Try to read a `bool` value or null from `yamlMap`, otherwise throw.
-bool _tryReadBool(YamlMap yamlMap, String key, Logger logger) {
-  final Object value = yamlMap[key];
+bool? _tryReadBool(YamlMap yamlMap, String key, Logger logger) {
+  final Object? value = yamlMap[key];
   if (value == null) {
     return null;
   }
@@ -414,12 +411,12 @@
     logger.printError('Expected "$key" to have a bool value, instead was "$value"');
     throw Exception();
   }
-  return value as bool;
+  return value;
 }
 
 // Try to read a `String` value or null from `yamlMap`, otherwise throw.
-String _tryReadString(YamlMap yamlMap, String key, Logger logger) {
-  final Object value = yamlMap[key];
+String? _tryReadString(YamlMap yamlMap, String key, Logger logger) {
+  final Object? value = yamlMap[key];
   if (value == null) {
     return null;
   }
@@ -427,11 +424,11 @@
     logger.printError('Expected "$key" to have a String value, instead was "$value"');
     throw Exception();
   }
-  return value as String;
+  return value;
 }
 
-List<String> _tryReadStringList(YamlMap yamlMap, String key, Logger logger) {
-  final Object value = yamlMap[key];
+List<String>? _tryReadStringList(YamlMap yamlMap, String key, Logger logger) {
+  final Object? value = yamlMap[key];
   if (value == null) {
     return null;
   }
@@ -446,12 +443,12 @@
 }
 
 // Try to read a valid `Uri` or null from `yamlMap`, otherwise throw.
-Uri _tryReadUri(YamlMap yamlMap, String key, Logger logger) {
-  final String value = _tryReadString(yamlMap, key, logger);
+Uri? _tryReadUri(YamlMap yamlMap, String key, Logger logger) {
+  final String? value = _tryReadString(yamlMap, key, logger);
   if (value == null) {
     return null;
   }
-  final Uri uri = Uri.tryParse(value);
+  final Uri? uri = Uri.tryParse(value);
   if (uri == null) {
     logger.printError('"$value" must be a relative file URI');
   }
diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/localizations_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
index 4b951e1..2078159 100644
--- a/packages/flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/targets/localizations_test.dart
@@ -19,7 +19,7 @@
 void main() {
   // Verifies that values are correctly passed through the localizations
   // target, but does not validate them beyond the serialized data type.
-  testUsingContext('generateLocalizations forwards arguments correctly', () async {
+  testWithoutContext('generateLocalizations forwards arguments correctly', () async {
     final FileSystem fileSystem = MemoryFileSystem.test();
     final Logger logger = BufferLogger.test();
     final Directory flutterProjectDirectory = fileSystem
@@ -76,7 +76,7 @@
     verify(mockLocalizationsGenerator.writeOutputFiles(logger, isFromYaml: true)).called(1);
   });
 
-  testUsingContext('generateLocalizations throws exception on missing flutter: generate: true flag', () async {
+  testWithoutContext('generateLocalizations throws exception on missing flutter: generate: true flag', () async {
     final FileSystem fileSystem = MemoryFileSystem.test();
     final BufferLogger logger = BufferLogger.test();
     final Directory arbDirectory = fileSystem.directory('arb')
diff --git a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart
index 15515c5..0745daf 100644
--- a/packages/flutter_tools/test/general.shard/generate_localizations_test.dart
+++ b/packages/flutter_tools/test/general.shard/generate_localizations_test.dart
@@ -12,15 +12,13 @@
 import 'package:flutter_tools/src/base/file_system.dart';
 import 'package:flutter_tools/src/base/logger.dart';
 import 'package:flutter_tools/src/convert.dart';
-import 'package:flutter_tools/src/globals.dart' as globals;
 import 'package:flutter_tools/src/localizations/gen_l10n.dart';
 import 'package:flutter_tools/src/localizations/gen_l10n_types.dart';
 import 'package:flutter_tools/src/localizations/localizations_utils.dart';
-import 'package:test/test.dart';
 
-final String defaultL10nPathString = globals.fs.path.join('lib', 'l10n');
-final String syntheticPackagePath = globals.fs.path.join('.dart_tool', 'flutter_gen');
-final String syntheticL10nPackagePath = globals.fs.path.join(syntheticPackagePath, 'gen_l10n');
+import '../src/common.dart';
+import '../src/context.dart';
+
 const String defaultTemplateArbFileName = 'app_en.arb';
 const String defaultOutputFileString = 'output-localization-file.dart';
 const String defaultClassNameString = 'AppLocalizations';
@@ -71,16 +69,23 @@
 
 void main() {
   MemoryFileSystem fs;
+  String defaultL10nPathString;
+  String syntheticPackagePath;
+  String syntheticL10nPackagePath;
 
   setUp(() {
     fs = MemoryFileSystem(
       style: Platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix
     );
+
+    defaultL10nPathString = fs.path.join('lib', 'l10n');
+    syntheticPackagePath = fs.path.join('.dart_tool', 'flutter_gen');
+    syntheticL10nPackagePath = fs.path.join(syntheticPackagePath, 'gen_l10n');
     precacheLanguageAndRegionTags();
   });
 
   group('Setters', () {
-    test('setInputDirectory fails if the directory does not exist', () {
+    testWithoutContext('setInputDirectory fails if the directory does not exist', () {
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
         generator.setInputDirectory('lib');
@@ -95,7 +100,7 @@
       );
     });
 
-    test('setInputDirectory fails if input string is null', () {
+    testWithoutContext('setInputDirectory fails if input string is null', () {
       _standardFlutterDirectoryL10nSetup(fs);
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
@@ -111,7 +116,7 @@
       );
     });
 
-    test(
+    testWithoutContext(
       'setOutputDirectory fails if output string is null while not using the '
       'synthetic package option',
       () {
@@ -132,7 +137,7 @@
       },
     );
 
-    test('setTemplateArbFile fails if inputDirectory is null', () {
+    testWithoutContext('setTemplateArbFile fails if inputDirectory is null', () {
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
         generator.setTemplateArbFile(defaultTemplateArbFileName);
@@ -147,7 +152,7 @@
       );
     });
 
-    test('setTemplateArbFile fails if templateArbFileName is null', () {
+    testWithoutContext('setTemplateArbFile fails if templateArbFileName is null', () {
       _standardFlutterDirectoryL10nSetup(fs);
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
@@ -163,7 +168,7 @@
       );
     });
 
-    test('setTemplateArbFile fails if input string is null', () {
+    testWithoutContext('setTemplateArbFile fails if input string is null', () {
       _standardFlutterDirectoryL10nSetup(fs);
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
@@ -179,7 +184,7 @@
       );
     });
 
-    test('setBaseOutputFile fails if input string is null', () {
+    testWithoutContext('setBaseOutputFile fails if input string is null', () {
       _standardFlutterDirectoryL10nSetup(fs);
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
@@ -195,7 +200,7 @@
       );
     });
 
-    test('setting className fails if input string is null', () {
+    testWithoutContext('setting className fails if input string is null', () {
       _standardFlutterDirectoryL10nSetup(fs);
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       try {
@@ -211,7 +216,7 @@
       );
     });
 
-    test('sets absolute path of the target Flutter project', () {
+    testUsingContext('sets absolute path of the target Flutter project', () {
       // Set up project directory.
       final Directory l10nDirectory = fs.currentDirectory
         .childDirectory('absolute')
@@ -269,7 +274,7 @@
       );
     });
 
-    test('throws error when directory at absolute path does not exist', () {
+    testWithoutContext('throws error when directory at absolute path does not exist', () {
       // Set up project directory.
       final Directory l10nDirectory = fs.currentDirectory
         .childDirectory('lib')
@@ -317,7 +322,7 @@
         }
       });
 
-      test('fails on string with spaces', () {
+      testWithoutContext('fails on string with spaces', () {
         try {
           generator.className = 'String with spaces';
         } on L10nException catch (e) {
@@ -330,7 +335,7 @@
         );
       });
 
-      test('fails on non-alphanumeric symbols', () {
+      testWithoutContext('fails on non-alphanumeric symbols', () {
         try {
           generator.className = 'TestClass@123';
         } on L10nException catch (e) {
@@ -343,7 +348,7 @@
         );
       });
 
-      test('fails on camel-case', () {
+      testWithoutContext('fails on camel-case', () {
         try {
           generator.className = 'camelCaseClassName';
         } on L10nException catch (e) {
@@ -356,7 +361,7 @@
         );
       });
 
-      test('fails when starting with a number', () {
+      testWithoutContext('fails when starting with a number', () {
         try {
           generator.className = '123ClassName';
         } on L10nException catch (e) {
@@ -371,7 +376,7 @@
     });
   });
 
-  test('correctly adds a headerString when it is set', () {
+  testUsingContext('correctly adds a headerString when it is set', () {
     _standardFlutterDirectoryL10nSetup(fs);
 
     LocalizationsGenerator generator;
@@ -392,7 +397,7 @@
     expect(generator.header, '/// Sample header');
   });
 
-  test('correctly adds a headerFile when it is set', () {
+  testUsingContext('correctly adds a headerFile when it is set', () {
     fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true)
       ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
@@ -417,7 +422,7 @@
     expect(generator.header, '/// Sample header in a text file');
   });
 
-  test('sets templateArbFileName with more than one underscore correctly', () {
+  testUsingContext('sets templateArbFileName with more than one underscore correctly', () {
     final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true);
     l10nDirectory.childFile('app_localizations_en.arb')
@@ -446,7 +451,7 @@
     expect(outputDirectory.childFile('output-localization-file_es.dart').existsSync(), isTrue);
   });
 
-  test('filenames with invalid locales should not be recognized', () {
+  testUsingContext('filenames with invalid locales should not be recognized', () {
     final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true);
     l10nDirectory.childFile('app_localizations_en.arb')
@@ -472,7 +477,7 @@
     fail('Using app_en_CA_foo.arb should fail as it is not a valid locale.');
   });
 
-  test('correctly creates an untranslated messages file (useSyntheticPackage = true)', () {
+  testUsingContext('correctly creates an untranslated messages file (useSyntheticPackage = true)', () {
     fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true)
       ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
@@ -510,7 +515,7 @@
     expect(unimplementedOutputString, contains('subtitle'));
   });
 
-  test('correctly creates an untranslated messages file (useSyntheticPackage = false)', () {
+  testUsingContext('correctly creates an untranslated messages file (useSyntheticPackage = false)', () {
     fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true)
       ..childFile(defaultTemplateArbFileName).writeAsStringSync(twoMessageArbFileString)
@@ -549,7 +554,7 @@
     expect(unimplementedOutputString, contains('subtitle'));
   });
 
-  test(
+  testUsingContext(
     'untranslated messages suggestion is printed when translation is missing: '
     'command line message',
     () {
@@ -588,7 +593,7 @@
     },
   );
 
-  test(
+  testUsingContext(
     'untranslated messages suggestion is printed when translation is missing: '
     'l10n.yaml message',
     () {
@@ -625,7 +630,7 @@
     },
   );
 
-  test(
+  testUsingContext(
     'unimplemented messages suggestion is not printed when all messages '
     'are fully translated',
     () {
@@ -656,7 +661,7 @@
     },
   );
 
-  test('untranslated messages file included in generated JSON list of outputs', () {
+  testUsingContext('untranslated messages file included in generated JSON list of outputs', () {
     _standardFlutterDirectoryL10nSetup(fs);
 
     LocalizationsGenerator generator;
@@ -689,7 +694,7 @@
     expect(outputList, contains(contains('unimplemented_message_translations.json')));
   });
 
-  test(
+  testUsingContext(
     'uses inputPathString as outputPathString when the outputPathString is '
     'null while not using the synthetic package option',
     () {
@@ -719,7 +724,7 @@
     },
   );
 
-  test(
+  testUsingContext(
     'correctly generates output files in non-default output directory if it '
     'already exists while not using the synthetic package option',
     () {
@@ -763,7 +768,7 @@
     },
   );
 
-  test(
+  testUsingContext(
     'correctly creates output directory if it does not exist and writes files '
     'in it while not using the synthetic package option',
     () {
@@ -795,7 +800,7 @@
     },
   );
 
-  test('creates list of inputs and outputs when file path is specified', () {
+  testUsingContext('creates list of inputs and outputs when file path is specified', () {
     _standardFlutterDirectoryL10nSetup(fs);
 
     LocalizationsGenerator generator;
@@ -833,7 +838,7 @@
     expect(outputList, contains(fs.path.absolute(syntheticL10nPackagePath, 'output-localization-file_es.dart')));
   });
 
-  test('setting both a headerString and a headerFile should fail', () {
+  testUsingContext('setting both a headerString and a headerFile should fail', () {
     fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true)
       ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
@@ -860,7 +865,7 @@
     fail('Setting both headerFile and headerString should fail');
   });
 
-  test('setting a headerFile that does not exist should fail', () {
+  testUsingContext('setting a headerFile that does not exist should fail', () {
     final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
       ..createSync(recursive: true);
     l10nDirectory.childFile(defaultTemplateArbFileName)
@@ -889,7 +894,7 @@
     fail('Setting headerFile that does not exist should fail');
   });
 
-  test('setting useDefferedLoading to null should fail', () {
+  testUsingContext('setting useDefferedLoading to null should fail', () {
     _standardFlutterDirectoryL10nSetup(fs);
 
     LocalizationsGenerator generator;
@@ -913,7 +918,7 @@
   });
 
   group('loadResources', () {
-    test('correctly initializes supportedLocales and supportedLanguageCodes properties', () {
+    testUsingContext('correctly initializes supportedLocales and supportedLanguageCodes properties', () {
       _standardFlutterDirectoryL10nSetup(fs);
 
       LocalizationsGenerator generator;
@@ -935,7 +940,7 @@
       expect(generator.supportedLocales.contains(LocaleInfo.fromString('es')), true);
     });
 
-    test('correctly sorts supportedLocales and supportedLanguageCodes alphabetically', () {
+    testUsingContext('correctly sorts supportedLocales and supportedLanguageCodes alphabetically', () {
       final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true);
       // Write files in non-alphabetical order so that read performs in that order
@@ -966,7 +971,7 @@
       expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('zh'));
     });
 
-    test('adds preferred locales to the top of supportedLocales and supportedLanguageCodes', () {
+    testUsingContext('adds preferred locales to the top of supportedLocales and supportedLanguageCodes', () {
       final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true);
       l10nDirectory.childFile('app_en.arb')
@@ -998,7 +1003,7 @@
       expect(generator.supportedLocales.elementAt(2), LocaleInfo.fromString('en'));
     });
 
-    test(
+    testUsingContext(
       'throws an error attempting to add preferred locales '
       'when there is no corresponding arb file for that '
       'locale',
@@ -1040,7 +1045,7 @@
       },
     );
 
-    test('correctly sorts arbPathString alphabetically', () {
+    testUsingContext('correctly sorts arbPathString alphabetically', () {
       final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true);
       // Write files in non-alphabetical order so that read performs in that order
@@ -1071,7 +1076,7 @@
       expect(generator.arbPathStrings.elementAt(2), fs.path.join('lib', 'l10n', 'app_zh.arb'));
     });
 
-    test('correctly parses @@locale property in arb file', () {
+    testUsingContext('correctly parses @@locale property in arb file', () {
       const String arbFileWithEnLocale = '''
 {
   "@@locale": "en",
@@ -1116,7 +1121,7 @@
       expect(generator.supportedLocales.contains(LocaleInfo.fromString('zh')), true);
     });
 
-    test('correctly requires @@locale property in arb file to match the filename locale suffix', () {
+    testUsingContext('correctly requires @@locale property in arb file to match the filename locale suffix', () {
       const String arbFileWithEnLocale = '''
 {
   "@@locale": "en",
@@ -1164,7 +1169,7 @@
       );
     });
 
-    test("throws when arb file's locale could not be determined", () {
+    testUsingContext("throws when arb file's locale could not be determined", () {
       fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true)
         ..childFile('app.arb')
@@ -1188,7 +1193,7 @@
         'should fail'
       );
     });
-    test('throws when the same locale is detected more than once', () {
+    testUsingContext('throws when the same locale is detected more than once', () {
       const String secondMessageArbFileString = '''
 {
   "market": "MARKET",
@@ -1225,7 +1230,7 @@
       );
     });
 
-    test('throws when the base locale does not exist', () {
+    testUsingContext('throws when the base locale does not exist', () {
       final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true);
       l10nDirectory.childFile('app_en_US.arb')
@@ -1254,7 +1259,7 @@
   });
 
   group('writeOutputFiles', () {
-    test('message without placeholders - should generate code comment with description and template message translation', () {
+    testUsingContext('message without placeholders - should generate code comment with description and template message translation', () {
       _standardFlutterDirectoryL10nSetup(fs);
       final LocalizationsGenerator generator = LocalizationsGenerator(fs);
       final BufferLogger testLogger = BufferLogger.test();
@@ -1286,7 +1291,7 @@
   /// **'Title'**'''));
     });
 
-    test('template message translation handles newline characters', () {
+    testUsingContext('template message translation handles newline characters', () {
       final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true);
       l10nDirectory.childFile(defaultTemplateArbFileName)
@@ -1331,7 +1336,7 @@
   /// **'Title \n of the application'**'''));
     });
 
-    test('message with placeholders - should generate code comment with description and template message translation', () {
+    testUsingContext('message with placeholders - should generate code comment with description and template message translation', () {
       final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
         ..createSync(recursive: true);
       l10nDirectory.childFile(defaultTemplateArbFileName)
@@ -1386,7 +1391,7 @@
   /// **'The price of this item is: \${price}'**'''));
     });
 
-    test('should generate a file per language', () {
+    testUsingContext('should generate a file per language', () {
       const String singleEnCaMessageArbFileString = '''
 {
   "title": "Canadian Title"
@@ -1420,7 +1425,7 @@
       expect(englishLocalizationsFile, contains('class AppLocalizationsEn extends AppLocalizations'));
     });
 
-    test('language imports are sorted when preferredSupportedLocaleString is given', () {
+    testUsingContext('language imports are sorted when preferredSupportedLocaleString is given', () {
       fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
         ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
         ..childFile('app_zh.arb').writeAsStringSync(singleZhMessageArbFileString)
@@ -1454,7 +1459,7 @@
 '''));
     });
 
-    test('imports are deferred and loaded when useDeferredImports are set', () {
+    testUsingContext('imports are deferred and loaded when useDeferredImports are set', () {
       fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
         ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString);
 
@@ -1484,7 +1489,7 @@
     });
 
     group('DateTime tests', () {
-      test('throws an exception when improperly formatted date is passed in', () {
+      testUsingContext('throws an exception when improperly formatted date is passed in', () {
         const String singleDateMessageArbFileString = '''
 {
   "@@locale": "en",
@@ -1524,7 +1529,7 @@
         fail('Improper date formatting should throw an exception');
       });
 
-      test('throws an exception when no format attribute is passed in', () {
+      testUsingContext('throws an exception when no format attribute is passed in', () {
         const String singleDateMessageArbFileString = '''
 {
   "springBegins": "Spring begins on {springStartDate}",
@@ -1561,7 +1566,7 @@
         fail('Improper date formatting should throw an exception');
       });
 
-      test('throws an exception when improperly formatted number is passed in', () {
+      testUsingContext('throws an exception when improperly formatted number is passed in', () {
         const String singleDateMessageArbFileString = '''
 {
   "courseCompletion": "You have completed {progress} of the course.",
@@ -1603,7 +1608,7 @@
     });
 
     group('plural messages', () {
-      test('should throw attempting to generate a plural message without placeholders', () {
+      testUsingContext('should throw attempting to generate a plural message without placeholders', () {
         const String pluralMessageWithoutPlaceholdersAttribute = '''
 {
   "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
@@ -1635,7 +1640,7 @@
         fail('Generating class methods without placeholders should not succeed');
       });
 
-      test('should throw attempting to generate a plural message with an empty placeholders map', () {
+      testUsingContext('should throw attempting to generate a plural message with an empty placeholders map', () {
         const String pluralMessageWithEmptyPlaceholdersMap = '''
 {
   "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
@@ -1668,7 +1673,7 @@
         fail('Generating class methods without placeholders should not succeed');
       });
 
-      test('should throw attempting to generate a plural message with no resource attributes', () {
+      testUsingContext('should throw attempting to generate a plural message with no resource attributes', () {
         const String pluralMessageWithoutResourceAttributes = '''
 {
   "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}"
@@ -1697,7 +1702,7 @@
         fail('Generating plural class method without resource attributes should not succeed');
       });
 
-      test('should throw attempting to generate a plural message with incorrect format for placeholders', () {
+      testUsingContext('should throw attempting to generate a plural message with incorrect format for placeholders', () {
         const String pluralMessageWithIncorrectPlaceholderFormat = '''
 {
   "helloWorlds": "{count,plural, =0{Hello}=1{Hello World}=2{Hello two worlds}few{Hello {count} worlds}many{Hello all {count} worlds}other{Hello other {count} worlds}}",
@@ -1731,7 +1736,7 @@
       });
     });
 
-    test('intl package import should be omitted in subclass files when no plurals are included', () {
+    testUsingContext('intl package import should be omitted in subclass files when no plurals are included', () {
       fs.currentDirectory.childDirectory('lib').childDirectory('l10n')..createSync(recursive: true)
         ..childFile(defaultTemplateArbFileName).writeAsStringSync(singleMessageArbFileString)
         ..childFile('app_es.arb').writeAsStringSync(singleEsMessageArbFileString);
@@ -1757,7 +1762,7 @@
       expect(localizationsFile, isNot(contains(intlImportDartCode)));
     });
 
-    test('intl package import should be kept in subclass files when plurals are included', () {
+    testUsingContext('intl package import should be kept in subclass files when plurals are included', () {
       const String pluralMessageArb = '''
 {
   "helloWorlds": "{count,plural, =0{Hello} =1{Hello World} =2{Hello two worlds} few{Hello {count} worlds} many{Hello all {count} worlds} other{Hello other {count} worlds}}",
@@ -1801,7 +1806,7 @@
       expect(localizationsFile, contains(intlImportDartCode));
     });
 
-    test('check for string interpolation rules', () {
+    testUsingContext('check for string interpolation rules', () {
       const String enArbCheckList = '''
 {
   "one": "The number of {one} elapsed is: 44",
@@ -1941,7 +1946,7 @@
       expect(localizationsFile, contains(r'${nine}'));
     });
 
-    test('check for string interpolation rules - plurals', () {
+    testUsingContext('check for string interpolation rules - plurals', () {
       const String enArbCheckList = '''
 {
   "first": "{count,plural, =0{test {count} test} =1{哈{count}哈} =2{m{count}m} few{_{count}_} many{{count} test} other{{count}m}",
@@ -2006,7 +2011,7 @@
       expect(localizationsFile, contains(r' $count'));
     });
 
-    test(
+    testUsingContext(
       'should throw with descriptive error message when failing to parse the '
       'arb file',
       () {
@@ -2047,7 +2052,7 @@
       },
     );
 
-    test('should throw when resource is missing resource attribute (isResourceAttributeRequired = true)', () {
+    testUsingContext('should throw when resource is missing resource attribute (isResourceAttributeRequired = true)', () {
       const String arbFileWithMissingResourceAttribute = '''
 {
   "title": "Stocks"
@@ -2081,7 +2086,7 @@
     });
 
     group('checks for method/getter formatting', () {
-      test('cannot contain non-alphanumeric symbols', () {
+      testUsingContext('cannot contain non-alphanumeric symbols', () {
         const String nonAlphaNumericArbFile = '''
 {
   "title!!": "Stocks",
@@ -2113,7 +2118,7 @@
         fail('should fail due to non-alphanumeric character.');
       });
 
-      test('must start with lowercase character', () {
+      testUsingContext('must start with lowercase character', () {
         const String nonAlphaNumericArbFile = '''
 {
   "Title": "Stocks",
@@ -2145,7 +2150,7 @@
         fail('should fail since key starts with a non-lowercase.');
       });
 
-      test('cannot start with a number', () {
+      testUsingContext('cannot start with a number', () {
         const String nonAlphaNumericArbFile = '''
 {
   "123title": "Stocks",
@@ -2178,7 +2183,7 @@
     });
   });
 
-  test('should generate a valid pubspec.yaml file when using synthetic package if it does not already exist', () {
+  testUsingContext('should generate a valid pubspec.yaml file when using synthetic package if it does not already exist', () {
     _standardFlutterDirectoryL10nSetup(fs);
     LocalizationsGenerator generator;
     try {
@@ -2210,7 +2215,7 @@
     expect(pubspecDescription, "The Flutter application's synthetic package.");
   });
 
-  test('should not overwrite existing pubspec.yaml file when using synthetic package', () {
+  testUsingContext('should not overwrite existing pubspec.yaml file when using synthetic package', () {
     _standardFlutterDirectoryL10nSetup(fs);
     final File pubspecFile = fs.file(fs.path.join(syntheticPackagePath, 'pubspec.yaml'))
       ..createSync(recursive: true)