Merge pull request #30 from srawlins/nullsafety

Migrate to null safety
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 616d021..7efa79c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.2.0-nullsafety.0
+
+- Migrate to the null safety language feature.
+
 ## 0.1.9
 
 - Add `@SkippedTest` annotation and `skip_test` prefix.
diff --git a/lib/test_reflective_loader.dart b/lib/test_reflective_loader.dart
index 6430c66..3528a43 100644
--- a/lib/test_reflective_loader.dart
+++ b/lib/test_reflective_loader.dart
@@ -38,7 +38,7 @@
 
 final List<_Group> _currentGroups = <_Group>[];
 int _currentSuiteLevel = 0;
-String _currentSuiteName = null;
+String _currentSuiteName = '';
 
 /**
  * Is `true` the application is running in the checked mode.
@@ -58,7 +58,7 @@
  * create embedded suites.  If the current suite is the top-level one, perform
  * check for "solo" groups and tests, and run all or only "solo" items.
  */
-void defineReflectiveSuite(void define(), {String name}) {
+void defineReflectiveSuite(void define(), {String name = ''}) {
   String groupName = _currentSuiteName;
   _currentSuiteLevel++;
   try {
@@ -167,7 +167,7 @@
  */
 void _addTestsIfTopLevelSuite() {
   if (_currentSuiteLevel == 0) {
-    void runTests({bool allGroups, bool allTests}) {
+    void runTests({required bool allGroups, required bool allTests}) {
       for (_Group group in _currentGroups) {
         if (allGroups || group.isSolo) {
           for (_Test test in group.tests) {
@@ -196,16 +196,16 @@
  * If any other two is `null`, then the other one is returned.
  */
 String _combineNames(String base, String addition) {
-  if (base == null) {
+  if (base.isEmpty) {
     return addition;
-  } else if (addition == null) {
+  } else if (addition.isEmpty) {
     return base;
   } else {
     return '$base | $addition';
   }
 }
 
-Object _getAnnotationInstance(DeclarationMirror declaration, Type type) {
+Object? _getAnnotationInstance(DeclarationMirror declaration, Type type) {
   for (InstanceMirror annotation in declaration.metadata) {
     if (annotation.reflectee.runtimeType == type) {
       return annotation.reflectee;
@@ -227,9 +227,10 @@
 bool _hasSkippedTestAnnotation(MethodMirror method) =>
     _hasAnnotationInstance(method, skippedTest);
 
-Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
-  var invocationResult = null;
-  InstanceMirror closure;
+Future<Object?> _invokeSymbolIfExists(
+    InstanceMirror instanceMirror, Symbol symbol) {
+  Object? invocationResult = null;
+  InstanceMirror? closure;
   try {
     closure = instanceMirror.getField(symbol);
   } on NoSuchMethodError {}
@@ -248,10 +249,10 @@
  * - The test returns a future which completes with an error.
  * - An exception is thrown to the zone handler from a timer task.
  */
-Future _runFailingTest(ClassMirror classMirror, Symbol symbol) {
+Future<Object?>? _runFailingTest(ClassMirror classMirror, Symbol symbol) {
   bool passed = false;
-  return runZoned(() {
-    return new Future.sync(() => _runTest(classMirror, symbol)).then((_) {
+  return runZonedGuarded(() {
+    return new Future.sync(() => _runTest(classMirror, symbol)).then<void>((_) {
       passed = true;
       test_package.fail('Test passed - expected to fail.');
     }).catchError((e) {
@@ -261,7 +262,7 @@
       }
       // otherwise, an exception is not a failure for _runFailingTest
     });
-  }, onError: (e) {
+  }, (e, st) {
     // if passed, and we call fail(), rethrow this exception
     if (passed) {
       throw e;
@@ -270,7 +271,7 @@
   });
 }
 
-Future _runTest(ClassMirror classMirror, Symbol symbol) {
+Future<Object?> _runTest(ClassMirror classMirror, Symbol symbol) {
   InstanceMirror instanceMirror = classMirror.newInstance(new Symbol(''), []);
   return _invokeSymbolIfExists(instanceMirror, #setUp)
       .then((_) => instanceMirror.invoke(symbol, []).reflectee)
@@ -289,7 +290,7 @@
    * [issue] is a full URI describing the failure and used for tracking.
    * [reason] is a free form textual description.
    */
-  const FailingTest({String issue, String reason});
+  const FailingTest({String? issue, String? reason});
 }
 
 /**
@@ -302,7 +303,7 @@
    * [issue] is a full URI describing the failure and used for tracking.
    * [reason] is a free form textual description.
    */
-  const SkippedTest({String issue, String reason});
+  const SkippedTest({String? issue, String? reason});
 }
 
 /**
@@ -339,14 +340,15 @@
   bool get hasSoloTest => tests.any((test) => test.isSolo);
 
   void addSkippedTest(String name) {
-    String fullName = _combineNames(this.name, name);
+    var fullName = _combineNames(this.name, name);
     tests.add(new _Test.skipped(isSolo, fullName));
   }
 
   void addTest(bool isSolo, String name, MethodMirror memberMirror,
       _TestFunction function) {
-    String fullName = _combineNames(this.name, name);
-    TestTimeout timeout = _getAnnotationInstance(memberMirror, TestTimeout);
+    var fullName = _combineNames(this.name, name);
+    var timeout =
+        _getAnnotationInstance(memberMirror, TestTimeout) as TestTimeout?;
     tests.add(new _Test(isSolo, fullName, function, timeout?._timeout));
   }
 }
@@ -373,7 +375,7 @@
   final bool isSolo;
   final String name;
   final _TestFunction function;
-  final test_package.Timeout timeout;
+  final test_package.Timeout? timeout;
 
   final bool isSkipped;
 
@@ -382,6 +384,6 @@
 
   _Test.skipped(this.isSolo, this.name)
       : isSkipped = true,
-        function = null,
+        function = (() {}),
         timeout = null;
 }
diff --git a/pubspec.yaml b/pubspec.yaml
index 8cfc3fa..6d081e4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
 name: test_reflective_loader
-version: 0.1.9
+version: 0.2.0-nullsafety.0
 
 description: Support for discovering tests and test suites using reflection.
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/test_reflective_loader
 
 environment:
-  sdk: '>=1.8.0 <3.0.0'
+  sdk: '>=2.12.0-0 <3.0.0'
 
 dependencies:
-  test: '>=0.12.0 <2.0.0'
+  test: '>=1.16.0-nullsafety.12 <2.0.0'
diff --git a/test/test_reflective_loader_test.dart b/test/test_reflective_loader_test.dart
index a657b04..2c69cce 100644
--- a/test/test_reflective_loader_test.dart
+++ b/test/test_reflective_loader_test.dart
@@ -15,8 +15,6 @@
 
 @reflectiveTest
 class TestReflectiveLoaderTest {
-  String pathname;
-
   void test_passes() {
     expect(true, true);
   }