Enable and fix a number of lints, test on the oldest supported SDK (#19)

diff --git a/.travis.yml b/.travis.yml
index 1acfc69..415bad4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,23 +2,25 @@
 
 dart:
   - dev
+  - 2.0.0
 
 dart_task:
   - test
 
-# Only run one instance of the formatter and the analyzer, rather than running
-# them against each Dart version.
 matrix:
   include:
   - dart: dev
     dart_task: dartfmt
   - dart: dev
-    dart_task: dartanalyzer
+    dart_task:
+      dartanalyzer: --fatal-infos --fatal-warnings .
+  - dart: 2.0.0
+    dart_task:
+      dartanalyzer: --fatal-warnings .
 
-# Only building master means that we don't run two builds for each pull request.
 branches:
   only: [master]
 
 cache:
- directories:
-   - $HOME/.pub-cache
+  directories:
+    - $HOME/.pub-cache
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..1384ade
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,65 @@
+include: package:pedantic/analysis_options.yaml
+analyzer:
+  strong-mode:
+    implicit-casts: false
+  errors:
+    unused_element: error
+    unused_import: error
+    unused_local_variable: error
+    dead_code: error
+linter:
+  rules:
+    #- annotate_overrides
+    - avoid_function_literals_in_foreach_calls
+    - avoid_init_to_null
+    - avoid_null_checks_in_equality_operators
+    - avoid_relative_lib_imports
+    - avoid_returning_null
+    - avoid_unused_constructor_parameters
+    - await_only_futures
+    - camel_case_types
+    - cancel_subscriptions
+    - comment_references
+    - constant_identifier_names
+    - control_flow_in_finally
+    - directives_ordering
+    - empty_catches
+    - empty_constructor_bodies
+    - empty_statements
+    - hash_and_equals
+    - implementation_imports
+    - invariant_booleans
+    - iterable_contains_unrelated_type
+    - library_names
+    - library_prefixes
+    - list_remove_unrelated_type
+    - no_adjacent_strings_in_list
+    - non_constant_identifier_names
+    - omit_local_variable_types
+    - only_throw_errors
+    - overridden_fields
+    - package_api_docs
+    - package_names
+    - package_prefixed_library_names
+    - prefer_adjacent_string_concatenation
+    - prefer_collection_literals
+    - prefer_conditional_assignment
+    - prefer_const_constructors
+    - prefer_final_fields
+    - prefer_generic_function_type_aliases
+    - prefer_initializing_formals
+    - prefer_interpolation_to_compose_strings
+    #- prefer_single_quotes
+    - prefer_typing_uninitialized_variables
+    - slash_for_doc_comments
+    - test_types_in_equals
+    - throw_in_finally
+    - type_init_formals
+    - unnecessary_brace_in_string_interps
+    - unnecessary_const
+    - unnecessary_getters_setters
+    - unnecessary_lambdas
+    - unnecessary_new
+    - unnecessary_null_aware_assignments
+    - unnecessary_statements
+    - unnecessary_this
diff --git a/lib/src/descriptor.dart b/lib/src/descriptor.dart
index 363bc90..43de75d 100644
--- a/lib/src/descriptor.dart
+++ b/lib/src/descriptor.dart
@@ -4,6 +4,8 @@
 
 import 'dart:async';
 
+import 'sandbox.dart';
+
 /// A declarative description of a filesystem entry.
 ///
 /// This may be extended outside this package.
diff --git a/lib/src/directory_descriptor.dart b/lib/src/directory_descriptor.dart
index 0b9f36f..4674a10 100644
--- a/lib/src/directory_descriptor.dart
+++ b/lib/src/directory_descriptor.dart
@@ -29,7 +29,7 @@
 
   /// Returns a `dart:io` [Directory] object that refers to this file within
   /// [sandbox].
-  Directory get io => new Directory(p.join(sandbox, name));
+  Directory get io => Directory(p.join(sandbox, name));
 
   DirectoryDescriptor(String name, Iterable<Descriptor> contents)
       : contents = contents.toList(),
@@ -38,17 +38,17 @@
   /// Creates a directory descriptor named [name] that describes the physical
   /// directory at [path].
   factory DirectoryDescriptor.fromFilesystem(String name, String path) {
-    return new DirectoryDescriptor(
+    return DirectoryDescriptor(
         name,
-        new Directory(path).listSync().map((entity) {
+        Directory(path).listSync().map((entity) {
           // Ignore hidden files.
           if (p.basename(entity.path).startsWith(".")) return null;
 
           if (entity is Directory) {
-            return new DirectoryDescriptor.fromFilesystem(
+            return DirectoryDescriptor.fromFilesystem(
                 p.basename(entity.path), entity.path);
           } else if (entity is File) {
-            return new FileDescriptor(
+            return FileDescriptor(
                 p.basename(entity.path), entity.readAsBytesSync());
           }
           // Ignore broken symlinks.
@@ -57,13 +57,13 @@
 
   Future create([String parent]) async {
     var fullPath = p.join(parent ?? sandbox, name);
-    await new Directory(fullPath).create(recursive: true);
+    await Directory(fullPath).create(recursive: true);
     await Future.wait(contents.map((entry) => entry.create(fullPath)));
   }
 
   Future validate([String parent]) async {
     var fullPath = p.join(parent ?? sandbox, name);
-    if (!(await new Directory(fullPath).exists())) {
+    if (!(await Directory(fullPath).exists())) {
       fail('Directory not found: "${prettyPath(fullPath)}".');
     }
 
@@ -75,7 +75,7 @@
   /// contents of the [FileDescriptor] at the given relative [url], which may be
   /// a [Uri] or a [String].
   ///
-  /// The [parent] parameter should only be passed by subclasses of
+  /// The [parents] parameter should only be passed by subclasses of
   /// [DirectoryDescriptor] that are recursively calling [load]. It's the
   /// URL-format path of the directories that have been loaded so far.
   Stream<List<int>> load(url, [String parents]) {
@@ -85,15 +85,15 @@
     } else if (url is Uri) {
       path = url.toString();
     } else {
-      throw new ArgumentError.value(url, "url", "must be a Uri or a String.");
+      throw ArgumentError.value(url, "url", "must be a Uri or a String.");
     }
 
     if (!p.url.isWithin('.', path)) {
-      throw new ArgumentError.value(
+      throw ArgumentError.value(
           url, "url", "must be relative and beneath the base URL.");
     }
 
-    return StreamCompleter.fromFuture(new Future.sync(() {
+    return StreamCompleter.fromFuture(Future.sync(() {
       var split = p.url.split(p.url.normalize(path));
       var file = split.length == 1;
       var matchingEntries = contents.where((entry) {
@@ -124,7 +124,7 @@
   String describe() {
     if (contents.isEmpty) return name;
 
-    var buffer = new StringBuffer();
+    var buffer = StringBuffer();
     buffer.writeln(name);
     for (var entry in contents.take(contents.length - 1)) {
       var entryString =
diff --git a/lib/src/file_descriptor.dart b/lib/src/file_descriptor.dart
index 5220b6e..b755ee5 100644
--- a/lib/src/file_descriptor.dart
+++ b/lib/src/file_descriptor.dart
@@ -36,17 +36,17 @@
   /// To match a [Matcher] against a file's binary contents, use [new
   /// FileDescriptor.binaryMatcher] instead.
   factory FileDescriptor(String name, contents) {
-    if (contents is String) return new _StringFileDescriptor(name, contents);
+    if (contents is String) return _StringFileDescriptor(name, contents);
     if (contents is List) {
-      return new _BinaryFileDescriptor(name, contents.cast<int>());
+      return _BinaryFileDescriptor(name, contents.cast<int>());
     }
-    if (contents == null) return new _BinaryFileDescriptor(name, []);
-    return new _MatcherFileDescriptor(name, contents);
+    if (contents == null) return _BinaryFileDescriptor(name, []);
+    return _MatcherFileDescriptor(name, contents as Matcher);
   }
 
   /// Returns a `dart:io` [File] object that refers to this file within
   /// [sandbox].
-  File get io => new File(p.join(sandbox, name));
+  File get io => File(p.join(sandbox, name));
 
   /// Creates a new binary [FileDescriptor] with [name] that matches its binary
   /// contents against [matcher].
@@ -54,7 +54,7 @@
   /// The [create], [read], and [readAsBytes] methods are unsupported for this
   /// descriptor.
   factory FileDescriptor.binaryMatcher(String name, Matcher matcher) =>
-      new _MatcherFileDescriptor(name, matcher, isBinary: true);
+      _MatcherFileDescriptor(name, matcher, isBinary: true);
 
   /// A protected constructor that's only intended for subclasses.
   FileDescriptor.protected(String name) : super(name);
@@ -62,7 +62,7 @@
   Future create([String parent]) async {
     // Create the stream before we call [File.openWrite] because it may fail
     // fast (e.g. if this is a matcher file).
-    var file = new File(p.join(parent ?? sandbox, name)).openWrite();
+    var file = File(p.join(parent ?? sandbox, name)).openWrite();
     try {
       await readAsBytes().listen(file.add).asFuture();
     } finally {
@@ -73,11 +73,11 @@
   Future validate([String parent]) async {
     var fullPath = p.join(parent ?? sandbox, name);
     var pretty = prettyPath(fullPath);
-    if (!(await new File(fullPath).exists())) {
+    if (!(await File(fullPath).exists())) {
       fail('File not found: "$pretty".');
     }
 
-    await _validate(pretty, await new File(fullPath).readAsBytes());
+    await _validate(pretty, await File(fullPath).readAsBytes());
   }
 
   /// Validates that [binaryContents] matches the expected contents of
@@ -106,7 +106,7 @@
 
   _BinaryFileDescriptor(String name, this._contents) : super.protected(name);
 
-  Stream<List<int>> readAsBytes() => new Stream.fromIterable([_contents]);
+  Stream<List<int>> readAsBytes() => Stream.fromIterable([_contents]);
 
   Future _validate(String prettPath, List<int> actualContents) async {
     if (const IterableEquality().equals(_contents, actualContents)) return null;
@@ -124,12 +124,12 @@
   Future<String> read() async => _contents;
 
   Stream<List<int>> readAsBytes() =>
-      new Stream.fromIterable([utf8.encode(_contents)]);
+      Stream.fromIterable([utf8.encode(_contents)]);
 
   Future _validate(String prettyPath, List<int> actualContents) {
     var actualContentsText = utf8.decode(actualContents);
     if (_contents == actualContentsText) return null;
-    throw fail(_textMismatchMessage(prettyPath, _contents, actualContentsText));
+    fail(_textMismatchMessage(prettyPath, _contents, actualContentsText));
   }
 
   String _textMismatchMessage(
@@ -177,20 +177,19 @@
   /// contents.
   final bool _isBinary;
 
-  _MatcherFileDescriptor(String name, this._matcher, {bool isBinary: false})
+  _MatcherFileDescriptor(String name, this._matcher, {bool isBinary = false})
       : _isBinary = isBinary,
         super.protected(name);
 
   Stream<List<int>> readAsBytes() =>
-      throw new UnsupportedError("Matcher files can't be created or read.");
+      throw UnsupportedError("Matcher files can't be created or read.");
 
   Future _validate(String prettyPath, List<int> actualContents) async {
     try {
       expect(
           _isBinary ? actualContents : utf8.decode(actualContents), _matcher);
     } on TestFailure catch (error) {
-      throw new TestFailure(
-          'Invalid contents for file "$prettyPath":\n' + error.message);
+      fail('Invalid contents for file "$prettyPath":\n${error.message}');
     }
   }
 }
diff --git a/lib/src/nothing_descriptor.dart b/lib/src/nothing_descriptor.dart
index 2d62cb0..98abe61 100644
--- a/lib/src/nothing_descriptor.dart
+++ b/lib/src/nothing_descriptor.dart
@@ -23,11 +23,11 @@
   Future validate([String parent]) async {
     var fullPath = p.join(parent ?? sandbox, name);
     var pretty = prettyPath(fullPath);
-    if (new File(fullPath).existsSync()) {
+    if (File(fullPath).existsSync()) {
       fail('Expected nothing to exist at "$pretty", but found a file.');
-    } else if (new Directory(fullPath).existsSync()) {
+    } else if (Directory(fullPath).existsSync()) {
       fail('Expected nothing to exist at "$pretty", but found a directory.');
-    } else if (new Link(fullPath).existsSync()) {
+    } else if (Link(fullPath).existsSync()) {
       fail('Expected nothing to exist at "$pretty", but found a link.');
     }
   }
diff --git a/lib/src/pattern_descriptor.dart b/lib/src/pattern_descriptor.dart
index 0d2b60d..3432876 100644
--- a/lib/src/pattern_descriptor.dart
+++ b/lib/src/pattern_descriptor.dart
@@ -16,7 +16,7 @@
 /// A function that takes a name for a [Descriptor] and returns a [Descriptor].
 /// This is used for [PatternDescriptor]s, where the name isn't known
 /// ahead-of-time.
-typedef Descriptor _EntryCreator(String name);
+typedef _EntryCreator = Descriptor Function(String name);
 
 /// A descriptor that matches filesystem entity names by [Pattern] rather than
 /// by exact [String].
@@ -31,20 +31,19 @@
   /// matching [pattern].
   final _EntryCreator _fn;
 
-  PatternDescriptor(Pattern pattern, Descriptor child(String basename))
-      : pattern = pattern,
-        _fn = child,
+  PatternDescriptor(this.pattern, Descriptor child(String basename))
+      : _fn = child,
         super('$pattern');
 
   /// Validates that there is some filesystem entity in [parent] that matches
   /// [pattern] and the child entry. This finds all entities in [parent]
-  /// matching [pattern], then passes each of their names to the [EntityCreator]
-  /// and validates the result. If exactly one succeeds, [this] is considered
-  /// valid.
+  /// matching [pattern], then passes each of their names to `child` provided
+  /// in the constructor and validates the result. If exactly one succeeds,
+  /// `this` is considered valid.
   Future validate([String parent]) async {
     var inSandbox = parent == null;
     parent ??= sandbox;
-    var matchingEntries = await new Directory(parent)
+    var matchingEntries = await Directory(parent)
         .list()
         .map((entry) =>
             entry is File ? entry.resolveSymbolicLinksSync() : entry.path)
@@ -54,13 +53,13 @@
 
     var location = inSandbox ? "sandbox" : '"${prettyPath(parent)}"';
     if (matchingEntries.isEmpty) {
-      fail('No entries found in $location matching ${_patternDescription}.');
+      fail('No entries found in $location matching $_patternDescription.');
     }
 
     var results = await Future.wait(matchingEntries.map((entry) {
       var basename = p.basename(entry);
       return runZoned(() {
-        return Result.capture(new Future.sync(() async {
+        return Result.capture(Future.sync(() async {
           await _fn(basename).validate(parent);
           return basename;
         }));
@@ -72,7 +71,7 @@
     }).toList());
 
     var successes = results.where((result) => result.isValue).toList();
-    if (successes.length == 0) {
+    if (successes.isEmpty) {
       await waitAndReportErrors(results.map((result) => result.asFuture));
     } else if (successes.length > 1) {
       fail('Multiple valid entries found in $location matching '
@@ -88,13 +87,13 @@
     if (pattern is! RegExp) return '$pattern';
 
     var regExp = pattern as RegExp;
-    var flags = new StringBuffer();
+    var flags = StringBuffer();
     if (!regExp.isCaseSensitive) flags.write('i');
     if (regExp.isMultiLine) flags.write('m');
     return '/${regExp.pattern}/$flags';
   }
 
   Future create([String parent]) {
-    throw new UnsupportedError("Pattern descriptors don't support create().");
+    throw UnsupportedError("Pattern descriptors don't support create().");
   }
 }
diff --git a/lib/src/sandbox.dart b/lib/src/sandbox.dart
index eee1252..a09145e 100644
--- a/lib/src/sandbox.dart
+++ b/lib/src/sandbox.dart
@@ -23,7 +23,7 @@
   addTearDown(() async {
     var sandbox = _sandbox;
     _sandbox = null;
-    await new Directory(sandbox).delete(recursive: true);
+    await Directory(sandbox).delete(recursive: true);
   });
 
   return _sandbox;
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 3e1d12e..9a14b70 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -40,7 +40,7 @@
   var lines = text.split('\n');
   if (lines.length == 1) return "$single$text";
 
-  var buffer = new StringBuffer("$first${lines.first}\n");
+  var buffer = StringBuffer("$first${lines.first}\n");
   for (var line in lines.skip(1).take(lines.length - 2)) {
     buffer.writeln("$prefix$line");
   }
@@ -72,7 +72,7 @@
   return Future.wait(futures.map((future) {
     // Avoid async/await so that we synchronously add error handlers for the
     // futures to keep them from top-leveling.
-    return future.catchError((error, stackTrace) {
+    return future.catchError((error, StackTrace stackTrace) {
       if (!errored) {
         errored = true;
         throw error;
diff --git a/lib/test_descriptor.dart b/lib/test_descriptor.dart
index fe27b92..cc33714 100644
--- a/lib/test_descriptor.dart
+++ b/lib/test_descriptor.dart
@@ -32,8 +32,7 @@
 ///
 /// To match a [Matcher] against a file's binary contents, use [new
 /// FileDescriptor.binaryMatcher] instead.
-FileDescriptor file(String name, [contents]) =>
-    new FileDescriptor(name, contents);
+FileDescriptor file(String name, [contents]) => FileDescriptor(name, contents);
 
 /// Creates a new [DirectoryDescriptor] descriptor with [name] and [contents].
 ///
@@ -42,13 +41,13 @@
 /// children exist. To ensure that a particular child doesn't exist, use
 /// [nothing].
 DirectoryDescriptor dir(String name, [Iterable<Descriptor> contents]) =>
-    new DirectoryDescriptor(name, contents == null ? <Descriptor>[] : contents);
+    DirectoryDescriptor(name, contents == null ? <Descriptor>[] : contents);
 
 /// Creates a new [NothingDescriptor] descriptor that asserts that no entry
 /// named [name] exists.
 ///
 /// [Descriptor.create] does nothing for this descriptor.
-NothingDescriptor nothing(String name) => new NothingDescriptor(name);
+NothingDescriptor nothing(String name) => NothingDescriptor(name);
 
 /// Creates a new [PatternDescriptor] descriptor that asserts than an entry with
 /// a name matching [pattern] exists, and matches the [Descriptor] returned
@@ -61,7 +60,7 @@
 ///
 /// [Descriptor.create] is not supported for this descriptor.
 PatternDescriptor pattern(Pattern name, Descriptor child(String basename)) =>
-    new PatternDescriptor(name, child);
+    PatternDescriptor(name, child);
 
 /// A convenience method for creating a [PatternDescriptor] descriptor that
 /// constructs a [FileDescriptor] descriptor.
diff --git a/pubspec.yaml b/pubspec.yaml
index 68e91db..d39384e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -5,7 +5,7 @@
 homepage: https://github.com/dart-lang/test_descriptor
 
 environment:
-  sdk: '>=2.0.0-dev.36.0 <3.0.0'
+  sdk: '>=2.0.0 <3.0.0'
 
 dependencies:
   async: '>=1.10.0 <3.0.0'
@@ -15,3 +15,6 @@
   stack_trace: '^1.0.0'
   test: '>=0.12.19 <2.0.0'
   term_glyph: '^1.0.0'
+
+dev_dependencies:
+  pedantic: ^1.0.0
diff --git a/test/directory_test.dart b/test/directory_test.dart
index d455e16..b03edc3 100644
--- a/test/directory_test.dart
+++ b/test/directory_test.dart
@@ -28,16 +28,16 @@
         d.file('file2.txt', 'contents2')
       ]).create();
 
-      expect(new File(p.join(d.sandbox, 'dir', 'file1.txt')).readAsString(),
+      expect(File(p.join(d.sandbox, 'dir', 'file1.txt')).readAsString(),
           completion(equals('contents1')));
-      expect(new File(p.join(d.sandbox, 'dir', 'file2.txt')).readAsString(),
+      expect(File(p.join(d.sandbox, 'dir', 'file2.txt')).readAsString(),
           completion(equals('contents2')));
       expect(
-          new File(p.join(d.sandbox, 'dir', 'subdir', 'subfile1.txt'))
+          File(p.join(d.sandbox, 'dir', 'subdir', 'subfile1.txt'))
               .readAsString(),
           completion(equals('subcontents1')));
       expect(
-          new File(p.join(d.sandbox, 'dir', 'subdir', 'subfile2.txt'))
+          File(p.join(d.sandbox, 'dir', 'subdir', 'subfile2.txt'))
               .readAsString(),
           completion(equals('subcontents2')));
     });
@@ -46,7 +46,7 @@
       await d.dir('dir').create();
       await d.dir('dir', [d.file('name.txt', 'contents')]).create();
 
-      expect(new File(p.join(d.sandbox, 'dir', 'name.txt')).readAsString(),
+      expect(File(p.join(d.sandbox, 'dir', 'name.txt')).readAsString(),
           completion(equals('contents')));
     });
   });
@@ -56,12 +56,12 @@
         () async {
       var dirPath = p.join(d.sandbox, 'dir');
       var subdirPath = p.join(dirPath, 'subdir');
-      await new Directory(subdirPath).create(recursive: true);
-      await new File(p.join(dirPath, 'file1.txt')).writeAsString('contents1');
-      await new File(p.join(dirPath, 'file2.txt')).writeAsString('contents2');
-      await new File(p.join(subdirPath, 'subfile1.txt'))
+      await Directory(subdirPath).create(recursive: true);
+      await File(p.join(dirPath, 'file1.txt')).writeAsString('contents1');
+      await File(p.join(dirPath, 'file2.txt')).writeAsString('contents2');
+      await File(p.join(subdirPath, 'subfile1.txt'))
           .writeAsString('subcontents1');
-      await new File(p.join(subdirPath, 'subfile2.txt'))
+      await File(p.join(subdirPath, 'subfile2.txt'))
           .writeAsString('subcontents2');
 
       await d.dir('dir', [
@@ -76,9 +76,9 @@
 
     test("fails if the directory doesn't exist", () async {
       var dirPath = p.join(d.sandbox, 'dir');
-      await new Directory(dirPath).create();
-      await new File(p.join(dirPath, 'file1.txt')).writeAsString('contents1');
-      await new File(p.join(dirPath, 'file2.txt')).writeAsString('contents2');
+      await Directory(dirPath).create();
+      await File(p.join(dirPath, 'file1.txt')).writeAsString('contents1');
+      await File(p.join(dirPath, 'file2.txt')).writeAsString('contents2');
 
       expect(
           d.dir('dir', [
@@ -96,13 +96,13 @@
     test("emits an error for each child that fails to validate", () async {
       var dirPath = p.join(d.sandbox, 'dir');
       var subdirPath = p.join(dirPath, 'subdir');
-      await new Directory(subdirPath).create(recursive: true);
-      await new File(p.join(dirPath, 'file1.txt')).writeAsString('contents1');
-      await new File(p.join(subdirPath, 'subfile2.txt'))
+      await Directory(subdirPath).create(recursive: true);
+      await File(p.join(dirPath, 'file1.txt')).writeAsString('contents1');
+      await File(p.join(subdirPath, 'subfile2.txt'))
           .writeAsString('subwrongtents2');
 
       var errors = 0;
-      var controller = new StreamController<String>();
+      var controller = StreamController<String>();
       runZoned(() {
         d.dir('dir', [
           d.dir('subdir', [
@@ -272,8 +272,8 @@
       ]);
 
       await dir.create();
-      var descriptor = new d.DirectoryDescriptor.fromFilesystem(
-          "dir", p.join(d.sandbox, 'dir'));
+      var descriptor =
+          d.DirectoryDescriptor.fromFilesystem("dir", p.join(d.sandbox, 'dir'));
       await descriptor.create(p.join(d.sandbox, 'dir2'));
       await dir.validate(p.join(d.sandbox, 'dir2'));
     });
@@ -288,7 +288,7 @@
         d.file('.DS_Store', 'contents2')
       ]).create();
 
-      var descriptor = new d.DirectoryDescriptor.fromFilesystem(
+      var descriptor = d.DirectoryDescriptor.fromFilesystem(
           "dir2", p.join(d.sandbox, 'dir'));
       await descriptor.create();
 
diff --git a/test/file_test.dart b/test/file_test.dart
index cbc670a..a1e803b 100644
--- a/test/file_test.dart
+++ b/test/file_test.dart
@@ -2,14 +2,12 @@
 // 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.
 
-@TestOn('vm')
-
-import 'dart:io';
 import 'dart:convert';
+@TestOn('vm')
+import 'dart:io';
 
 import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
-
 import 'package:test_descriptor/test_descriptor.dart' as d;
 
 import 'utils.dart';
@@ -19,14 +17,14 @@
     test('creates a text file', () async {
       await d.file('name.txt', 'contents').create();
 
-      expect(new File(p.join(d.sandbox, 'name.txt')).readAsString(),
+      expect(File(p.join(d.sandbox, 'name.txt')).readAsString(),
           completion(equals('contents')));
     });
 
     test('creates a binary file', () async {
       await d.file('name.txt', [0, 1, 2, 3]).create();
 
-      expect(new File(p.join(d.sandbox, 'name.txt')).readAsBytes(),
+      expect(File(p.join(d.sandbox, 'name.txt')).readAsBytes(),
           completion(equals([0, 1, 2, 3])));
     });
 
@@ -39,47 +37,46 @@
       await d.file('name.txt', 'contents1').create();
       await d.file('name.txt', 'contents2').create();
 
-      expect(new File(p.join(d.sandbox, 'name.txt')).readAsString(),
+      expect(File(p.join(d.sandbox, 'name.txt')).readAsString(),
           completion(equals('contents2')));
     });
   });
 
   group("validate()", () {
     test('succeeds if the filesystem matches a text descriptor', () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('contents');
+      await File(p.join(d.sandbox, 'name.txt')).writeAsString('contents');
       await d.file('name.txt', 'contents').validate();
     });
 
     test('succeeds if the filesystem matches a binary descriptor', () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0, 1, 2, 3]);
+      await File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0, 1, 2, 3]);
       await d.file('name.txt', [0, 1, 2, 3]).validate();
     });
 
     test('succeeds if the filesystem matches a text matcher', () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('contents');
+      await File(p.join(d.sandbox, 'name.txt')).writeAsString('contents');
       await d.file('name.txt', contains('ent')).validate();
     });
 
     test('succeeds if the filesystem matches a binary matcher', () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0, 1, 2, 3]);
-      await new d.FileDescriptor.binaryMatcher('name.txt', contains(2))
-          .validate();
+      await File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0, 1, 2, 3]);
+      await d.FileDescriptor.binaryMatcher('name.txt', contains(2)).validate();
     });
 
     test('succeeds if invalid UTF-8 matches a text matcher', () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0xC3, 0x28]);
+      await File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0xC3, 0x28]);
       await d.file('name.txt', isNot(isEmpty)).validate();
     });
 
     test("fails if the text contents don't match", () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');
+      await File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');
 
       expect(d.file('name.txt', 'contents').validate(),
           throwsA(toString(startsWith('File "name.txt" should contain:'))));
     });
 
     test("fails if the binary contents don't match", () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([5, 4, 3, 2]);
+      await File(p.join(d.sandbox, 'name.txt')).writeAsBytes([5, 4, 3, 2]);
 
       expect(
           d.file('name.txt', [0, 1, 2, 3]).validate(),
@@ -88,7 +85,7 @@
     });
 
     test("fails if the text contents don't match the matcher", () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');
+      await File(p.join(d.sandbox, 'name.txt')).writeAsString('wrong');
 
       expect(
           d.file('name.txt', contains('ent')).validate(),
@@ -97,17 +94,16 @@
     });
 
     test("fails if the binary contents don't match the matcher", () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([5, 4, 3, 2]);
+      await File(p.join(d.sandbox, 'name.txt')).writeAsBytes([5, 4, 3, 2]);
 
       expect(
-          new d.FileDescriptor.binaryMatcher('name.txt', contains(1))
-              .validate(),
+          d.FileDescriptor.binaryMatcher('name.txt', contains(1)).validate(),
           throwsA(
               toString(startsWith('Invalid contents for file "name.txt":'))));
     });
 
     test("fails if invalid UTF-8 doesn't match a text matcher", () async {
-      await new File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0xC3, 0x28]);
+      await File(p.join(d.sandbox, 'name.txt')).writeAsBytes([0xC3, 0x28]);
       expect(
           d.file('name.txt', isEmpty).validate(),
           throwsA(toString(allOf([
diff --git a/test/nothing_test.dart b/test/nothing_test.dart
index d2935d0..d117260 100644
--- a/test/nothing_test.dart
+++ b/test/nothing_test.dart
@@ -16,9 +16,8 @@
 void main() {
   test("create() does nothing", () async {
     await d.nothing('foo').create();
-    expect(new File(p.join(d.sandbox, 'foo')).exists(), completion(isFalse));
-    expect(
-        new Directory(p.join(d.sandbox, 'foo')).exists(), completion(isFalse));
+    expect(File(p.join(d.sandbox, 'foo')).exists(), completion(isFalse));
+    expect(Directory(p.join(d.sandbox, 'foo')).exists(), completion(isFalse));
   });
 
   group("validate()", () {
@@ -43,7 +42,7 @@
     });
 
     test("fails if there's a broken link", () async {
-      await new Link(p.join(d.sandbox, 'link')).create('nonexistent');
+      await Link(p.join(d.sandbox, 'link')).create('nonexistent');
       expect(
           d.nothing('link').validate(),
           throwsA(toString(equals(
diff --git a/test/pattern_test.dart b/test/pattern_test.dart
index fb9b5bb..d337b1f 100644
--- a/test/pattern_test.dart
+++ b/test/pattern_test.dart
@@ -15,14 +15,14 @@
     test("succeeds if there's a file matching the pattern and the child",
         () async {
       await d.file('foo', 'blap').create();
-      await d.filePattern(new RegExp(r'f..'), 'blap').validate();
+      await d.filePattern(RegExp(r'f..'), 'blap').validate();
     });
 
     test("succeeds if there's a directory matching the pattern and the child",
         () async {
       await d.dir('foo', [d.file('bar', 'baz')]).create();
 
-      await d.dirPattern(new RegExp(r'f..'), [d.file('bar', 'baz')]).validate();
+      await d.dirPattern(RegExp(r'f..'), [d.file('bar', 'baz')]).validate();
     });
 
     test(
@@ -32,12 +32,12 @@
       await d.file('fee', 'blak').create();
       await d.file('faa', 'blut').create();
 
-      await d.filePattern(new RegExp(r'f..'), 'blap').validate();
+      await d.filePattern(RegExp(r'f..'), 'blap').validate();
     });
 
     test("fails if there's no file matching the pattern", () {
       expect(
-          d.filePattern(new RegExp(r'f..'), 'bar').validate(),
+          d.filePattern(RegExp(r'f..'), 'bar').validate(),
           throwsA(
               toString(equals('No entries found in sandbox matching /f../.'))));
     });
@@ -45,7 +45,7 @@
     test("fails if there's a file matching the pattern but not the entry",
         () async {
       await d.file('foo', 'bap').create();
-      expect(d.filePattern(new RegExp(r'f..'), 'bar').validate(),
+      expect(d.filePattern(RegExp(r'f..'), 'bar').validate(),
           throwsA(toString(startsWith('File "foo" should contain:'))));
     });
 
@@ -53,8 +53,7 @@
         () async {
       await d.dir('foo', [d.file('bar', 'bap')]).create();
 
-      expect(
-          d.dirPattern(new RegExp(r'f..'), [d.file('bar', 'baz')]).validate(),
+      expect(d.dirPattern(RegExp(r'f..'), [d.file('bar', 'baz')]).validate(),
           throwsA(toString(startsWith('File "foo/bar" should contain:'))));
     });
 
@@ -65,7 +64,7 @@
       await d.file('fee', 'bar').create();
       await d.file('faa', 'bar').create();
       expect(
-          d.filePattern(new RegExp(r'f..'), 'bar').validate(),
+          d.filePattern(RegExp(r'f..'), 'bar').validate(),
           throwsA(toString(startsWith(
               "Multiple valid entries found in sandbox matching /f../:"))));
     });
diff --git a/test/sandbox_test.dart b/test/sandbox_test.dart
index be4a959..c34c5c6 100644
--- a/test/sandbox_test.dart
+++ b/test/sandbox_test.dart
@@ -13,13 +13,13 @@
 
 void main() {
   test("accessing the getter creates the directory", () {
-    expect(new Directory(d.sandbox).existsSync(), isTrue);
+    expect(Directory(d.sandbox).existsSync(), isTrue);
   });
 
   test("the directory is deleted after the test", () {
     String sandbox;
     addTearDown(() {
-      expect(new Directory(sandbox).existsSync(), isFalse);
+      expect(Directory(sandbox).existsSync(), isFalse);
     });
 
     sandbox = d.sandbox;