Fix newly enforced package:pedantic lints (#31)

- always_declare_return_types
- annotate_overrides
- prefer_collection_literals
- prefer_single_quotes
- use_function_type_syntax_for_parameters

Bump min SDK to 2.2.0 to allow Set literals.
diff --git a/.travis.yml b/.travis.yml
index 40fba06..b2a4fd7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@
 
 dart:
   - dev
-  - 2.1.0
+  - 2.2.0
 
 # See https://docs.travis-ci.com/user/languages/dart/ for details.
 dart_task:
diff --git a/lib/glob.dart b/lib/glob.dart
index c43c40f..6f6add6 100644
--- a/lib/glob.dart
+++ b/lib/glob.dart
@@ -90,7 +90,7 @@
       {p.Context context, bool recursive = false, bool caseSensitive}) {
     context ??= p.context;
     caseSensitive ??= context.style == p.Style.windows ? false : true;
-    if (recursive) pattern += "{,/**}";
+    if (recursive) pattern += '{,/**}';
 
     var parser = Parser(pattern, context, caseSensitive: caseSensitive);
     return Glob._(pattern, context, parser.parse(), recursive);
@@ -111,7 +111,7 @@
   Stream<FileSystemEntity> list({String root, bool followLinks = true}) {
     if (context.style != p.style) {
       throw StateError("Can't list glob \"$this\"; it matches "
-          "${context.style} paths, but this platform uses ${p.style} paths.");
+          '${context.style} paths, but this platform uses ${p.style} paths.');
     }
 
     _listTree ??= ListTree(_ast);
@@ -132,7 +132,7 @@
   List<FileSystemEntity> listSync({String root, bool followLinks = true}) {
     if (context.style != p.style) {
       throw StateError("Can't list glob \"$this\"; it matches "
-          "${context.style} paths, but this platform uses ${p.style} paths.");
+          '${context.style} paths, but this platform uses ${p.style} paths.');
     }
 
     _listTree ??= ListTree(_ast);
@@ -142,6 +142,7 @@
   /// Returns whether this glob matches [path].
   bool matches(String path) => matchAsPrefix(path) != null;
 
+  @override
   Match matchAsPrefix(String path, [int start = 0]) {
     // Globs are like anchored RegExps in that they only match entire paths, so
     // if the match starts anywhere after the first character it can't succeed.
@@ -165,10 +166,12 @@
     return null;
   }
 
+  @override
   Iterable<Match> allMatches(String path, [int start = 0]) {
     var match = matchAsPrefix(path, start);
     return match == null ? [] : [match];
   }
 
+  @override
   String toString() => pattern;
 }
diff --git a/lib/src/ast.dart b/lib/src/ast.dart
index 5620c56..1ee0fcf 100644
--- a/lib/src/ast.dart
+++ b/lib/src/ast.dart
@@ -57,14 +57,17 @@
   /// The nodes in the sequence.
   final List<AstNode> nodes;
 
+  @override
   bool get canMatchAbsolute => nodes.first.canMatchAbsolute;
 
+  @override
   bool get canMatchRelative => nodes.first.canMatchRelative;
 
   SequenceNode(Iterable<AstNode> nodes, {bool caseSensitive = true})
       : nodes = nodes.toList(),
         super._(caseSensitive);
 
+  @override
   OptionsNode flattenOptions() {
     if (nodes.isEmpty) {
       return OptionsNode([this], caseSensitive: caseSensitive);
@@ -119,12 +122,12 @@
     var componentsToReturn = <SequenceNode>[];
     List<AstNode> currentComponent;
 
-    addNode(AstNode node) {
+    void addNode(AstNode node) {
       currentComponent ??= [];
       currentComponent.add(node);
     }
 
-    finishComponent() {
+    void finishComponent() {
       if (currentComponent == null) return;
       componentsToReturn
           .add(SequenceNode(currentComponent, caseSensitive: caseSensitive));
@@ -145,7 +148,7 @@
       }
 
       var text = literal.text;
-      if (context.style == p.Style.windows) text = text.replaceAll("/", "\\");
+      if (context.style == p.Style.windows) text = text.replaceAll('/', '\\');
       Iterable<String> components = context.split(text);
 
       // If the first component is absolute, that means it's a separator (on
@@ -160,7 +163,7 @@
             // roots properly. That means that if there is a root, it'll still
             // have backslashes, where forward slashes are required for globs.
             // So we switch it back here.
-            root = root.replaceAll("\\", "/");
+            root = root.replaceAll('\\', '/');
           }
           addNode(LiteralNode(root, caseSensitive: caseSensitive));
         }
@@ -186,14 +189,18 @@
     return componentsToReturn;
   }
 
+  @override
   String _toRegExp() => nodes.map((node) => node._toRegExp()).join();
 
+  @override
   bool operator ==(Object other) =>
       other is SequenceNode &&
       const IterableEquality().equals(nodes, other.nodes);
 
+  @override
   int get hashCode => const IterableEquality().hash(nodes);
 
+  @override
   String toString() => nodes.join();
 }
 
@@ -201,12 +208,16 @@
 class StarNode extends AstNode {
   StarNode({bool caseSensitive = true}) : super._(caseSensitive);
 
+  @override
   String _toRegExp() => '[^/]*';
 
+  @override
   bool operator ==(Object other) => other is StarNode;
 
+  @override
   int get hashCode => 0;
 
+  @override
   String toString() => '*';
 }
 
@@ -220,6 +231,7 @@
   DoubleStarNode(this._context, {bool caseSensitive = true})
       : super._(caseSensitive);
 
+  @override
   String _toRegExp() {
     // Double star shouldn't match paths with a leading "../", since these paths
     // wouldn't be listed with this glob. We only check for "../" at the
@@ -245,10 +257,13 @@
     return buffer.toString();
   }
 
+  @override
   bool operator ==(Object other) => other is DoubleStarNode;
 
+  @override
   int get hashCode => 1;
 
+  @override
   String toString() => '**';
 }
 
@@ -256,12 +271,16 @@
 class AnyCharNode extends AstNode {
   AnyCharNode({bool caseSensitive = true}) : super._(caseSensitive);
 
+  @override
   String _toRegExp() => '[^/]';
 
+  @override
   bool operator ==(Object other) => other is AnyCharNode;
 
+  @override
   int get hashCode => 2;
 
+  @override
   String toString() => '?';
 }
 
@@ -279,6 +298,7 @@
       : ranges = ranges.toSet(),
         super._(caseSensitive);
 
+  @override
   OptionsNode flattenOptions() {
     if (negated || ranges.any((range) => !range.isSingleton)) {
       return super.flattenOptions();
@@ -294,6 +314,7 @@
     }), caseSensitive: caseSensitive);
   }
 
+  @override
   String _toRegExp() {
     var buffer = StringBuffer();
 
@@ -323,13 +344,16 @@
     return buffer.toString();
   }
 
+  @override
   bool operator ==(Object other) =>
       other is RangeNode &&
       other.negated == negated &&
       SetEquality().equals(ranges, other.ranges);
 
+  @override
   int get hashCode => (negated ? 1 : 3) * const SetEquality().hash(ranges);
 
+  @override
   String toString() {
     var buffer = StringBuffer()..write('[');
     for (var range in ranges) {
@@ -348,27 +372,34 @@
   /// The options to match.
   final List<SequenceNode> options;
 
+  @override
   bool get canMatchAbsolute => options.any((node) => node.canMatchAbsolute);
 
+  @override
   bool get canMatchRelative => options.any((node) => node.canMatchRelative);
 
   OptionsNode(Iterable<SequenceNode> options, {bool caseSensitive = true})
       : options = options.toList(),
         super._(caseSensitive);
 
+  @override
   OptionsNode flattenOptions() =>
       OptionsNode(options.expand((option) => option.flattenOptions().options),
           caseSensitive: caseSensitive);
 
+  @override
   String _toRegExp() =>
       '(?:${options.map((option) => option._toRegExp()).join("|")})';
 
+  @override
   bool operator ==(Object other) =>
       other is OptionsNode &&
       const UnorderedIterableEquality().equals(options, other.options);
 
+  @override
   int get hashCode => const UnorderedIterableEquality().hash(options);
 
+  @override
   String toString() => '{${options.join(',')}}';
 }
 
@@ -382,23 +413,29 @@
   /// This is used to determine whether this could match an absolute path.
   final p.Context _context;
 
+  @override
   bool get canMatchAbsolute {
     var nativeText =
         _context.style == p.Style.windows ? text.replaceAll('/', '\\') : text;
     return _context.isAbsolute(nativeText);
   }
 
+  @override
   bool get canMatchRelative => !canMatchAbsolute;
 
   LiteralNode(this.text, {p.Context context, bool caseSensitive = true})
       : _context = context,
         super._(caseSensitive);
 
+  @override
   String _toRegExp() => regExpQuote(text);
 
+  @override
   bool operator ==(Object other) => other is LiteralNode && other.text == text;
 
+  @override
   int get hashCode => text.hashCode;
 
+  @override
   String toString() => text;
 }
diff --git a/lib/src/list_tree.dart b/lib/src/list_tree.dart
index 0572382..82f12c5 100644
--- a/lib/src/list_tree.dart
+++ b/lib/src/list_tree.dart
@@ -56,7 +56,7 @@
   /// A map from filesystem roots to the list tree for those roots.
   ///
   /// A relative glob will use `.` as its root.
-  final _trees = Map<String, _ListTreeNode>();
+  final _trees = <String, _ListTreeNode>{};
 
   /// Whether paths listed might overlap.
   ///
@@ -81,7 +81,7 @@
       // root's just ".".
       if (firstNode is LiteralNode) {
         var text = firstNode.text;
-        if (Platform.isWindows) text.replaceAll("/", "\\");
+        if (Platform.isWindows) text.replaceAll('/', '\\');
         if (p.isAbsolute(text)) {
           // If the path is absolute, the root should be the only thing in the
           // first component.
@@ -181,7 +181,7 @@
 
     // TODO: Rather than filtering here, avoid double-listing directories
     // in the first place.
-    var seen = Set<String>();
+    var seen = <String>{};
     return group.stream.where((entity) => seen.add(entity.path));
   }
 
@@ -197,7 +197,7 @@
 
     // TODO: Rather than filtering here, avoid double-listing directories
     // in the first place.
-    var seen = Set<String>();
+    var seen = <String>{};
     return result.where((entity) => seen.add(entity.path)).toList();
   }
 }
@@ -266,7 +266,7 @@
 
   /// Creates a node with no children and no validator.
   _ListTreeNode()
-      : children = Map<SequenceNode, _ListTreeNode>(),
+      : children = <SequenceNode, _ListTreeNode>{},
         _validator = null;
 
   /// Creates a recursive node the given [validator].
@@ -469,7 +469,8 @@
     return _validator.matches(toPosixPath(p.context, path));
   }
 
-  String toString() => "($_validator) $children";
+  @override
+  String toString() => '($_validator) $children';
 }
 
 /// Joins each [components] into a new glob where each component is separated by
diff --git a/lib/src/parser.dart b/lib/src/parser.dart
index 3fa58ae..20ade31 100644
--- a/lib/src/parser.dart
+++ b/lib/src/parser.dart
@@ -92,7 +92,7 @@
     if (_scanner.matches(']')) _scanner.error('unexpected "]".');
     var negated = _scanner.scan('!') || _scanner.scan('^');
 
-    readRangeChar() {
+    int readRangeChar() {
       var char = _scanner.readChar();
       if (negated || char != _slash) return char;
       _scanner.error('"/" may not be used in a range.',
@@ -119,7 +119,7 @@
         var end = readRangeChar();
 
         if (end < char) {
-          _scanner.error("Range out of order.",
+          _scanner.error('Range out of order.',
               position: start, length: _scanner.position - start);
         }
         ranges.add(Range(char, end));
diff --git a/lib/src/stream_pool.dart b/lib/src/stream_pool.dart
index dfb8ca5..8317ae6 100644
--- a/lib/src/stream_pool.dart
+++ b/lib/src/stream_pool.dart
@@ -12,7 +12,7 @@
   final StreamController<T> _controller;
 
   /// Subscriptions to the streams that make up the pool.
-  final _subscriptions = Map<Stream<T>, StreamSubscription<T>>();
+  final _subscriptions = <Stream<T>, StreamSubscription<T>>{};
 
   /// Whether this pool should be closed when it becomes empty.
   bool _closeWhenEmpty = false;
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 268c273..74a809c 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -23,40 +23,50 @@
   /// Whether [this] contains [value].
   bool contains(int value) => value >= min && value <= max;
 
+  @override
   bool operator ==(Object other) =>
       other is Range && other.min == min && other.max == max;
 
+  @override
   int get hashCode => 3 * min + 7 * max;
 }
 
 /// An implementation of [Match] constructed by [Glob]s.
 class GlobMatch implements Match {
+  @override
   final String input;
+  @override
   final Pattern pattern;
+  @override
   final int start = 0;
 
+  @override
   int get end => input.length;
+  @override
   int get groupCount => 0;
 
   GlobMatch(this.input, this.pattern);
 
+  @override
   String operator [](int group) => this.group(group);
 
+  @override
   String group(int group) {
     if (group != 0) throw RangeError.range(group, 0, 0);
     return input;
   }
 
+  @override
   List<String> groups(List<int> groupIndices) =>
       groupIndices.map((index) => group(index)).toList();
 }
 
-final _quote = RegExp(r"[+*?{}|[\]\\().^$-]");
+final _quote = RegExp(r'[+*?{}|[\]\\().^$-]');
 
 /// Returns [contents] with characters that are meaningful in regular
 /// expressions backslash-escaped.
 String regExpQuote(String contents) =>
-    contents.replaceAllMapped(_quote, (char) => "\\${char[0]}");
+    contents.replaceAllMapped(_quote, (char) => '\\${char[0]}');
 
 /// Returns [path] with all its separators replaced with forward slashes.
 ///
diff --git a/pubspec.yaml b/pubspec.yaml
index f2c65e5..7454ccd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -6,7 +6,7 @@
 homepage: https://github.com/dart-lang/glob
 
 environment:
-  sdk: '>=2.1.0 <3.0.0'
+  sdk: '>=2.2.0 <3.0.0'
 
 dependencies:
   async: '>=1.2.0 <3.0.0'
diff --git a/test/glob_test.dart b/test/glob_test.dart
index 3923031..281a413 100644
--- a/test/glob_test.dart
+++ b/test/glob_test.dart
@@ -7,85 +7,85 @@
 import 'package:test/test.dart';
 
 void main() {
-  group("Glob.quote()", () {
-    test("quotes all active characters", () {
-      expect(Glob.quote("*{[?\\}],-"), equals(r"\*\{\[\?\\\}\]\,\-"));
+  group('Glob.quote()', () {
+    test('quotes all active characters', () {
+      expect(Glob.quote('*{[?\\}],-'), equals(r'\*\{\[\?\\\}\]\,\-'));
     });
 
     test("doesn't quote inactive characters", () {
-      expect(Glob.quote("abc~`_+="), equals("abc~`_+="));
+      expect(Glob.quote('abc~`_+='), equals('abc~`_+='));
     });
   });
 
-  group("Glob.matches()", () {
-    test("returns whether the path matches the glob", () {
-      var glob = Glob("foo*");
-      expect(glob.matches("foobar"), isTrue);
-      expect(glob.matches("baz"), isFalse);
+  group('Glob.matches()', () {
+    test('returns whether the path matches the glob', () {
+      var glob = Glob('foo*');
+      expect(glob.matches('foobar'), isTrue);
+      expect(glob.matches('baz'), isFalse);
     });
 
-    test("only matches the entire path", () {
-      var glob = Glob("foo");
-      expect(glob.matches("foo/bar"), isFalse);
-      expect(glob.matches("bar/foo"), isFalse);
+    test('only matches the entire path', () {
+      var glob = Glob('foo');
+      expect(glob.matches('foo/bar'), isFalse);
+      expect(glob.matches('bar/foo'), isFalse);
     });
   });
 
-  group("Glob.matchAsPrefix()", () {
-    test("returns a match if the path matches the glob", () {
-      var glob = Glob("foo*");
-      expect(glob.matchAsPrefix("foobar"), isA<Match>());
-      expect(glob.matchAsPrefix("baz"), isNull);
+  group('Glob.matchAsPrefix()', () {
+    test('returns a match if the path matches the glob', () {
+      var glob = Glob('foo*');
+      expect(glob.matchAsPrefix('foobar'), isA<Match>());
+      expect(glob.matchAsPrefix('baz'), isNull);
     });
 
-    test("returns null for start > 0", () {
-      var glob = Glob("*");
-      expect(glob.matchAsPrefix("foobar", 1), isNull);
+    test('returns null for start > 0', () {
+      var glob = Glob('*');
+      expect(glob.matchAsPrefix('foobar', 1), isNull);
     });
   });
 
-  group("Glob.allMatches()", () {
-    test("returns a single match if the path matches the glob", () {
-      var matches = Glob("foo*").allMatches("foobar");
+  group('Glob.allMatches()', () {
+    test('returns a single match if the path matches the glob', () {
+      var matches = Glob('foo*').allMatches('foobar');
       expect(matches, hasLength(1));
       expect(matches.first, isA<Match>());
     });
 
     test("returns an empty list if the path doesn't match the glob", () {
-      expect(Glob("foo*").allMatches("baz"), isEmpty);
+      expect(Glob('foo*').allMatches('baz'), isEmpty);
     });
 
-    test("returns no matches for start > 0", () {
-      var glob = Glob("*");
-      expect(glob.allMatches("foobar", 1), isEmpty);
+    test('returns no matches for start > 0', () {
+      var glob = Glob('*');
+      expect(glob.allMatches('foobar', 1), isEmpty);
     });
   });
 
-  group("GlobMatch", () {
-    var glob = Glob("foo*");
-    var match = glob.matchAsPrefix("foobar");
+  group('GlobMatch', () {
+    var glob = Glob('foo*');
+    var match = glob.matchAsPrefix('foobar');
 
-    test("returns the string as input", () {
-      expect(match.input, equals("foobar"));
+    test('returns the string as input', () {
+      expect(match.input, equals('foobar'));
     });
 
-    test("returns the glob as the pattern", () {
+    test('returns the glob as the pattern', () {
       expect(match.pattern, equals(glob));
     });
 
-    test("returns the span of the string for start and end", () {
+    test('returns the span of the string for start and end', () {
       expect(match.start, equals(0));
-      expect(match.end, equals("foobar".length));
+      expect(match.end, equals('foobar'.length));
     });
 
-    test("has a single group that contains the whole string", () {
+    test('has a single group that contains the whole string', () {
       expect(match.groupCount, equals(0));
-      expect(match[0], equals("foobar"));
-      expect(match.group(0), equals("foobar"));
-      expect(match.groups([0]), equals(["foobar"]));
+      expect(match[0], equals('foobar'));
+      expect(match.group(0), equals('foobar'));
+      expect(match.groups([0]), equals(['foobar']));
     });
 
-    test("throws a range error for an invalid group", () {
+    test('throws a range error for an invalid group', () {
       expect(() => match[1], throwsRangeError);
       expect(() => match[-1], throwsRangeError);
       expect(() => match.group(1), throwsRangeError);
@@ -93,19 +93,19 @@
     });
   });
 
-  test("globs are case-sensitive by default for Posix and URL contexts", () {
-    expect("foo", contains(Glob("foo", context: p.posix)));
-    expect("FOO", isNot(contains(Glob("foo", context: p.posix))));
-    expect("foo", isNot(contains(Glob("FOO", context: p.posix))));
+  test('globs are case-sensitive by default for Posix and URL contexts', () {
+    expect('foo', contains(Glob('foo', context: p.posix)));
+    expect('FOO', isNot(contains(Glob('foo', context: p.posix))));
+    expect('foo', isNot(contains(Glob('FOO', context: p.posix))));
 
-    expect("foo", contains(Glob("foo", context: p.url)));
-    expect("FOO", isNot(contains(Glob("foo", context: p.url))));
-    expect("foo", isNot(contains(Glob("FOO", context: p.url))));
+    expect('foo', contains(Glob('foo', context: p.url)));
+    expect('FOO', isNot(contains(Glob('foo', context: p.url))));
+    expect('foo', isNot(contains(Glob('FOO', context: p.url))));
   });
 
-  test("globs are case-insensitive by default for Windows contexts", () {
-    expect("foo", contains(Glob("foo", context: p.windows)));
-    expect("FOO", contains(Glob("foo", context: p.windows)));
-    expect("foo", contains(Glob("FOO", context: p.windows)));
+  test('globs are case-insensitive by default for Windows contexts', () {
+    expect('foo', contains(Glob('foo', context: p.windows)));
+    expect('FOO', contains(Glob('foo', context: p.windows)));
+    expect('foo', contains(Glob('FOO', context: p.windows)));
   });
 }
diff --git a/test/list_test.dart b/test/list_test.dart
index 2504f55..5fac113 100644
--- a/test/list_test.dart
+++ b/test/list_test.dart
@@ -14,246 +14,246 @@
 
 void main() {
   setUp(() async {
-    await d.dir("foo", [
-      d.file("bar"),
-      d.dir("baz", [d.file("bang"), d.file("qux")])
+    await d.dir('foo', [
+      d.file('bar'),
+      d.dir('baz', [d.file('bang'), d.file('qux')])
     ]).create();
   });
 
-  group("list()", () {
+  group('list()', () {
     test("fails if the context doesn't match the system context", () {
-      expect(Glob("*", context: p.url).list, throwsStateError);
+      expect(Glob('*', context: p.url).list, throwsStateError);
     });
 
-    test("reports exceptions for non-existent case-sensitive directories", () {
-      expect(Glob("non/existent/**", caseSensitive: true).list().toList(),
+    test('reports exceptions for non-existent case-sensitive directories', () {
+      expect(Glob('non/existent/**', caseSensitive: true).list().toList(),
           throwsA(isA<FileSystemException>()));
     });
 
-    test("reports exceptions for non-existent case-insensitive directories",
+    test('reports exceptions for non-existent case-insensitive directories',
         () {
-      expect(Glob("non/existent/**", caseSensitive: false).list().toList(),
+      expect(Glob('non/existent/**', caseSensitive: false).list().toList(),
           throwsA(isA<FileSystemException>()));
     });
   });
 
-  group("listSync()", () {
+  group('listSync()', () {
     test("fails if the context doesn't match the system context", () {
-      expect(Glob("*", context: p.url).listSync, throwsStateError);
+      expect(Glob('*', context: p.url).listSync, throwsStateError);
     });
 
-    test("reports exceptions for non-existent case-sensitive directories", () {
-      expect(Glob("non/existent/**", caseSensitive: true).listSync,
+    test('reports exceptions for non-existent case-sensitive directories', () {
+      expect(Glob('non/existent/**', caseSensitive: true).listSync,
           throwsA(isA<FileSystemException>()));
     });
 
-    test("reports exceptions for non-existent case-insensitive directories",
+    test('reports exceptions for non-existent case-insensitive directories',
         () {
-      expect(Glob("non/existent/**", caseSensitive: false).listSync,
+      expect(Glob('non/existent/**', caseSensitive: false).listSync,
           throwsA(isA<FileSystemException>()));
     });
   });
 
-  group("when case-sensitive", () {
-    test("lists literals case-sensitively", () {
-      expect(Glob("foo/BAZ/qux", caseSensitive: true).listSync,
+  group('when case-sensitive', () {
+    test('lists literals case-sensitively', () {
+      expect(Glob('foo/BAZ/qux', caseSensitive: true).listSync,
           throwsA(isA<FileSystemException>()));
     });
 
-    test("lists ranges case-sensitively", () {
-      expect(Glob("foo/[BX][A-Z]z/qux", caseSensitive: true).listSync,
+    test('lists ranges case-sensitively', () {
+      expect(Glob('foo/[BX][A-Z]z/qux', caseSensitive: true).listSync,
           throwsA(isA<FileSystemException>()));
     });
 
-    test("options preserve case-sensitivity", () {
-      expect(Glob("foo/{BAZ,ZAP}/qux", caseSensitive: true).listSync,
+    test('options preserve case-sensitivity', () {
+      expect(Glob('foo/{BAZ,ZAP}/qux', caseSensitive: true).listSync,
           throwsA(isA<FileSystemException>()));
     });
   });
 
   syncAndAsync((ListFn list) {
-    group("literals", () {
-      test("lists a single literal", () async {
+    group('literals', () {
+      test('lists a single literal', () async {
         expect(
-            await list("foo/baz/qux"), equals([p.join("foo", "baz", "qux")]));
+            await list('foo/baz/qux'), equals([p.join('foo', 'baz', 'qux')]));
       });
 
-      test("lists a non-matching literal", () async {
-        expect(await list("foo/baz/nothing"), isEmpty);
+      test('lists a non-matching literal', () async {
+        expect(await list('foo/baz/nothing'), isEmpty);
       });
     });
 
-    group("star", () {
-      test("lists within filenames but not across directories", () async {
-        expect(await list("foo/b*"),
-            unorderedEquals([p.join("foo", "bar"), p.join("foo", "baz")]));
+    group('star', () {
+      test('lists within filenames but not across directories', () async {
+        expect(await list('foo/b*'),
+            unorderedEquals([p.join('foo', 'bar'), p.join('foo', 'baz')]));
       });
 
-      test("lists the empy string", () async {
-        expect(await list("foo/bar*"), equals([p.join("foo", "bar")]));
+      test('lists the empy string', () async {
+        expect(await list('foo/bar*'), equals([p.join('foo', 'bar')]));
       });
     });
 
-    group("double star", () {
-      test("lists within filenames", () async {
+    group('double star', () {
+      test('lists within filenames', () async {
         expect(
-            await list("foo/baz/**"),
+            await list('foo/baz/**'),
             unorderedEquals(
-                [p.join("foo", "baz", "qux"), p.join("foo", "baz", "bang")]));
+                [p.join('foo', 'baz', 'qux'), p.join('foo', 'baz', 'bang')]));
       });
 
-      test("lists the empty string", () async {
-        expect(await list("foo/bar**"), equals([p.join("foo", "bar")]));
+      test('lists the empty string', () async {
+        expect(await list('foo/bar**'), equals([p.join('foo', 'bar')]));
       });
 
-      test("lists recursively", () async {
+      test('lists recursively', () async {
         expect(
-            await list("foo/**"),
+            await list('foo/**'),
             unorderedEquals([
-              p.join("foo", "bar"),
-              p.join("foo", "baz"),
-              p.join("foo", "baz", "qux"),
-              p.join("foo", "baz", "bang")
+              p.join('foo', 'bar'),
+              p.join('foo', 'baz'),
+              p.join('foo', 'baz', 'qux'),
+              p.join('foo', 'baz', 'bang')
             ]));
       });
 
-      test("combines with literals", () async {
+      test('combines with literals', () async {
         expect(
-            await list("foo/ba**"),
+            await list('foo/ba**'),
             unorderedEquals([
-              p.join("foo", "bar"),
-              p.join("foo", "baz"),
-              p.join("foo", "baz", "qux"),
-              p.join("foo", "baz", "bang")
+              p.join('foo', 'bar'),
+              p.join('foo', 'baz'),
+              p.join('foo', 'baz', 'qux'),
+              p.join('foo', 'baz', 'bang')
             ]));
       });
 
-      test("lists recursively in the middle of a glob", () async {
-        await d.dir("deep", [
-          d.dir("a", [
-            d.dir("b", [
-              d.dir("c", [d.file("d"), d.file("long-file")]),
-              d.dir("long-dir", [d.file("x")])
+      test('lists recursively in the middle of a glob', () async {
+        await d.dir('deep', [
+          d.dir('a', [
+            d.dir('b', [
+              d.dir('c', [d.file('d'), d.file('long-file')]),
+              d.dir('long-dir', [d.file('x')])
             ])
           ])
         ]).create();
 
         expect(
-            await list("deep/**/?/?"),
+            await list('deep/**/?/?'),
             unorderedEquals([
-              p.join("deep", "a", "b", "c"),
-              p.join("deep", "a", "b", "c", "d")
+              p.join('deep', 'a', 'b', 'c'),
+              p.join('deep', 'a', 'b', 'c', 'd')
             ]));
       });
     });
 
-    group("any char", () {
-      test("matches a character", () async {
-        expect(await list("foo/ba?"),
-            unorderedEquals([p.join("foo", "bar"), p.join("foo", "baz")]));
+    group('any char', () {
+      test('matches a character', () async {
+        expect(await list('foo/ba?'),
+            unorderedEquals([p.join('foo', 'bar'), p.join('foo', 'baz')]));
       });
 
       test("doesn't match a separator", () async {
-        expect(await list("foo?bar"), isEmpty);
+        expect(await list('foo?bar'), isEmpty);
       });
     });
 
-    group("range", () {
-      test("matches a range of characters", () async {
-        expect(await list("foo/ba[a-z]"),
-            unorderedEquals([p.join("foo", "bar"), p.join("foo", "baz")]));
+    group('range', () {
+      test('matches a range of characters', () async {
+        expect(await list('foo/ba[a-z]'),
+            unorderedEquals([p.join('foo', 'bar'), p.join('foo', 'baz')]));
       });
 
-      test("matches a specific list of characters", () async {
-        expect(await list("foo/ba[rz]"),
-            unorderedEquals([p.join("foo", "bar"), p.join("foo", "baz")]));
+      test('matches a specific list of characters', () async {
+        expect(await list('foo/ba[rz]'),
+            unorderedEquals([p.join('foo', 'bar'), p.join('foo', 'baz')]));
       });
 
       test("doesn't match outside its range", () async {
         expect(
-            await list("foo/ba[a-x]"), unorderedEquals([p.join("foo", "bar")]));
+            await list('foo/ba[a-x]'), unorderedEquals([p.join('foo', 'bar')]));
       });
 
       test("doesn't match outside its specific list", () async {
         expect(
-            await list("foo/ba[rx]"), unorderedEquals([p.join("foo", "bar")]));
+            await list('foo/ba[rx]'), unorderedEquals([p.join('foo', 'bar')]));
       });
     });
 
     test("the same file shouldn't be non-recursively listed multiple times",
         () async {
-      await d.dir("multi", [
-        d.dir("start-end", [d.file("file")])
+      await d.dir('multi', [
+        d.dir('start-end', [d.file('file')])
       ]).create();
 
-      expect(await list("multi/{start-*/f*,*-end/*e}"),
-          equals([p.join("multi", "start-end", "file")]));
+      expect(await list('multi/{start-*/f*,*-end/*e}'),
+          equals([p.join('multi', 'start-end', 'file')]));
     });
 
     test("the same file shouldn't be recursively listed multiple times",
         () async {
-      await d.dir("multi", [
-        d.dir("a", [
-          d.dir("b", [
-            d.file("file"),
-            d.dir("c", [d.file("file")])
+      await d.dir('multi', [
+        d.dir('a', [
+          d.dir('b', [
+            d.file('file'),
+            d.dir('c', [d.file('file')])
           ]),
-          d.dir("x", [
-            d.dir("y", [d.file("file")])
+          d.dir('x', [
+            d.dir('y', [d.file('file')])
           ])
         ])
       ]).create();
 
       expect(
-          await list("multi/{*/*/*/file,a/**/file}"),
+          await list('multi/{*/*/*/file,a/**/file}'),
           unorderedEquals([
-            p.join("multi", "a", "b", "file"),
-            p.join("multi", "a", "b", "c", "file"),
-            p.join("multi", "a", "x", "y", "file")
+            p.join('multi', 'a', 'b', 'file'),
+            p.join('multi', 'a', 'b', 'c', 'file'),
+            p.join('multi', 'a', 'x', 'y', 'file')
           ]));
     });
 
-    group("with symlinks", () {
+    group('with symlinks', () {
       setUp(() async {
-        await Link(p.join(d.sandbox, "dir", "link"))
-            .create(p.join(d.sandbox, "foo", "baz"), recursive: true);
+        await Link(p.join(d.sandbox, 'dir', 'link'))
+            .create(p.join(d.sandbox, 'foo', 'baz'), recursive: true);
       });
 
-      test("follows symlinks by default", () async {
+      test('follows symlinks by default', () async {
         expect(
-            await list("dir/**"),
+            await list('dir/**'),
             unorderedEquals([
-              p.join("dir", "link"),
-              p.join("dir", "link", "bang"),
-              p.join("dir", "link", "qux")
+              p.join('dir', 'link'),
+              p.join('dir', 'link', 'bang'),
+              p.join('dir', 'link', 'qux')
             ]));
       });
 
       test("doesn't follow symlinks with followLinks: false", () async {
-        expect(await list("dir/**", followLinks: false),
-            equals([p.join("dir", "link")]));
+        expect(await list('dir/**', followLinks: false),
+            equals([p.join('dir', 'link')]));
       });
 
       test("shouldn't crash on broken symlinks", () async {
-        await Directory(p.join(d.sandbox, "foo")).delete(recursive: true);
+        await Directory(p.join(d.sandbox, 'foo')).delete(recursive: true);
 
-        expect(await list("dir/**"), equals([p.join("dir", "link")]));
+        expect(await list('dir/**'), equals([p.join('dir', 'link')]));
       });
     });
 
-    test("always lists recursively with recursive: true", () async {
+    test('always lists recursively with recursive: true', () async {
       expect(
-          await list("foo", recursive: true),
+          await list('foo', recursive: true),
           unorderedEquals([
-            "foo",
-            p.join("foo", "bar"),
-            p.join("foo", "baz"),
-            p.join("foo", "baz", "qux"),
-            p.join("foo", "baz", "bang")
+            'foo',
+            p.join('foo', 'bar'),
+            p.join('foo', 'baz'),
+            p.join('foo', 'baz', 'qux'),
+            p.join('foo', 'baz', 'bang')
           ]));
     });
 
-    test("lists an absolute glob", () async {
+    test('lists an absolute glob', () async {
       var pattern =
           separatorToForwardSlash(p.absolute(p.join(d.sandbox, 'foo/baz/**')));
 
@@ -262,52 +262,52 @@
       expect(
           result,
           unorderedEquals(
-              [p.join("foo", "baz", "bang"), p.join("foo", "baz", "qux")]));
+              [p.join('foo', 'baz', 'bang'), p.join('foo', 'baz', 'qux')]));
     });
 
     // Regression test for #4.
-    test("lists an absolute case-insensitive glob", () async {
+    test('lists an absolute case-insensitive glob', () async {
       var pattern =
           separatorToForwardSlash(p.absolute(p.join(d.sandbox, 'foo/Baz/**')));
 
       expect(
           await list(pattern, caseSensitive: false),
           unorderedEquals(
-              [p.join("foo", "baz", "bang"), p.join("foo", "baz", "qux")]));
+              [p.join('foo', 'baz', 'bang'), p.join('foo', 'baz', 'qux')]));
     });
 
-    test("lists a subdirectory that sometimes exists", () async {
-      await d.dir("top", [
-        d.dir("dir1", [
-          d.dir("subdir", [d.file("file")])
+    test('lists a subdirectory that sometimes exists', () async {
+      await d.dir('top', [
+        d.dir('dir1', [
+          d.dir('subdir', [d.file('file')])
         ]),
-        d.dir("dir2", [])
+        d.dir('dir2', [])
       ]).create();
 
-      expect(await list("top/*/subdir/**"),
-          equals([p.join("top", "dir1", "subdir", "file")]));
+      expect(await list('top/*/subdir/**'),
+          equals([p.join('top', 'dir1', 'subdir', 'file')]));
     });
 
-    group("when case-insensitive", () {
-      test("lists literals case-insensitively", () async {
-        expect(await list("foo/baz/qux", caseSensitive: false),
-            equals([p.join("foo", "baz", "qux")]));
-        expect(await list("foo/BAZ/qux", caseSensitive: false),
-            equals([p.join("foo", "baz", "qux")]));
+    group('when case-insensitive', () {
+      test('lists literals case-insensitively', () async {
+        expect(await list('foo/baz/qux', caseSensitive: false),
+            equals([p.join('foo', 'baz', 'qux')]));
+        expect(await list('foo/BAZ/qux', caseSensitive: false),
+            equals([p.join('foo', 'baz', 'qux')]));
       });
 
-      test("lists ranges case-insensitively", () async {
-        expect(await list("foo/[bx][a-z]z/qux", caseSensitive: false),
-            equals([p.join("foo", "baz", "qux")]));
-        expect(await list("foo/[BX][A-Z]z/qux", caseSensitive: false),
-            equals([p.join("foo", "baz", "qux")]));
+      test('lists ranges case-insensitively', () async {
+        expect(await list('foo/[bx][a-z]z/qux', caseSensitive: false),
+            equals([p.join('foo', 'baz', 'qux')]));
+        expect(await list('foo/[BX][A-Z]z/qux', caseSensitive: false),
+            equals([p.join('foo', 'baz', 'qux')]));
       });
 
-      test("options preserve case-insensitivity", () async {
-        expect(await list("foo/{bar,baz}/qux", caseSensitive: false),
-            equals([p.join("foo", "baz", "qux")]));
-        expect(await list("foo/{BAR,BAZ}/qux", caseSensitive: false),
-            equals([p.join("foo", "baz", "qux")]));
+      test('options preserve case-insensitivity', () async {
+        expect(await list('foo/{bar,baz}/qux', caseSensitive: false),
+            equals([p.join('foo', 'baz', 'qux')]));
+        expect(await list('foo/{BAR,BAZ}/qux', caseSensitive: false),
+            equals([p.join('foo', 'baz', 'qux')]));
       });
     });
   });
@@ -318,8 +318,8 @@
 
 /// Runs [callback] in two groups with two values of [listFn]: one that uses
 /// [Glob.list], one that uses [Glob.listSync].
-void syncAndAsync(FutureOr callback(ListFn listFn)) {
-  group("async", () {
+void syncAndAsync(FutureOr Function(ListFn) callback) {
+  group('async', () {
     callback((pattern, {recursive = false, followLinks = true, caseSensitive}) {
       var glob =
           Glob(pattern, recursive: recursive, caseSensitive: caseSensitive);
@@ -331,7 +331,7 @@
     });
   });
 
-  group("sync", () {
+  group('sync', () {
     callback((pattern, {recursive = false, followLinks = true, caseSensitive}) {
       var glob =
           Glob(pattern, recursive: recursive, caseSensitive: caseSensitive);
diff --git a/test/match_test.dart b/test/match_test.dart
index d5c1e6a..925d41f 100644
--- a/test/match_test.dart
+++ b/test/match_test.dart
@@ -8,7 +8,7 @@
 import 'package:test/test.dart';
 
 const _rawAsciiWithoutSlash = "\t\n\r !\"#\$%&'()*+`-.0123456789:;<=>?@ABCDEF"
-    "GHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~";
+    'GHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~';
 
 // URL-encode the path for a URL context.
 final asciiWithoutSlash = p.style == p.Style.url
@@ -16,326 +16,326 @@
     : _rawAsciiWithoutSlash;
 
 void main() {
-  test("literals match exactly", () {
-    expect("foo", contains(Glob("foo")));
-    expect("foo/bar", contains(Glob("foo/bar")));
-    expect("foo*", contains(Glob(r"foo\*")));
+  test('literals match exactly', () {
+    expect('foo', contains(Glob('foo')));
+    expect('foo/bar', contains(Glob('foo/bar')));
+    expect('foo*', contains(Glob(r'foo\*')));
   });
 
-  test("backslashes match nothing on Windows", () {
-    expect(r"foo\bar", isNot(contains(Glob(r"foo\\bar", context: p.windows))));
+  test('backslashes match nothing on Windows', () {
+    expect(r'foo\bar', isNot(contains(Glob(r'foo\\bar', context: p.windows))));
   });
 
-  group("star", () {
-    test("matches non-separator characters", () {
-      var glob = Glob("*");
+  group('star', () {
+    test('matches non-separator characters', () {
+      var glob = Glob('*');
       expect(asciiWithoutSlash, contains(glob));
     });
 
-    test("matches the empty string", () {
-      expect("foo", contains(Glob("foo*")));
-      expect("", contains(Glob("*")));
+    test('matches the empty string', () {
+      expect('foo', contains(Glob('foo*')));
+      expect('', contains(Glob('*')));
     });
 
     test("doesn't match separators", () {
-      var glob = Glob("*");
-      expect("foo/bar", isNot(contains(glob)));
+      var glob = Glob('*');
+      expect('foo/bar', isNot(contains(glob)));
     });
   });
 
-  group("double star", () {
-    test("matches non-separator characters", () {
-      var glob = Glob("**");
+  group('double star', () {
+    test('matches non-separator characters', () {
+      var glob = Glob('**');
       expect(asciiWithoutSlash, contains(glob));
     });
 
-    test("matches the empty string", () {
-      var glob = Glob("foo**");
-      expect("foo", contains(glob));
+    test('matches the empty string', () {
+      var glob = Glob('foo**');
+      expect('foo', contains(glob));
     });
 
-    test("matches any level of nesting", () {
-      var glob = Glob("**");
-      expect("a", contains(glob));
-      expect("a/b/c/d/e/f", contains(glob));
+    test('matches any level of nesting', () {
+      var glob = Glob('**');
+      expect('a', contains(glob));
+      expect('a/b/c/d/e/f', contains(glob));
     });
 
     test("doesn't match unresolved dot dots", () {
-      expect("../foo/bar", isNot(contains(Glob("**"))));
+      expect('../foo/bar', isNot(contains(Glob('**'))));
     });
 
-    test("matches entities containing dot dots", () {
-      expect("..foo/bar", contains(Glob("**")));
-      expect("foo../bar", contains(Glob("**")));
-      expect("foo/..bar", contains(Glob("**")));
-      expect("foo/bar..", contains(Glob("**")));
+    test('matches entities containing dot dots', () {
+      expect('..foo/bar', contains(Glob('**')));
+      expect('foo../bar', contains(Glob('**')));
+      expect('foo/..bar', contains(Glob('**')));
+      expect('foo/bar..', contains(Glob('**')));
     });
   });
 
-  group("any char", () {
-    test("matches any non-separator character", () {
-      var glob = Glob("foo?");
+  group('any char', () {
+    test('matches any non-separator character', () {
+      var glob = Glob('foo?');
       for (var char in _rawAsciiWithoutSlash.split('')) {
         if (p.style == p.Style.url) char = Uri.encodeFull(char);
-        expect("foo$char", contains(glob));
+        expect('foo$char', contains(glob));
       }
     });
 
     test("doesn't match a separator", () {
-      expect("foo/bar", isNot(contains(Glob("foo?bar"))));
+      expect('foo/bar', isNot(contains(Glob('foo?bar'))));
     });
   });
 
-  group("range", () {
-    test("can match individual characters", () {
-      var glob = Glob("foo[a<.*]");
-      expect("fooa", contains(glob));
-      expect("foo<", contains(glob));
-      expect("foo.", contains(glob));
-      expect("foo*", contains(glob));
-      expect("foob", isNot(contains(glob)));
-      expect("foo>", isNot(contains(glob)));
+  group('range', () {
+    test('can match individual characters', () {
+      var glob = Glob('foo[a<.*]');
+      expect('fooa', contains(glob));
+      expect('foo<', contains(glob));
+      expect('foo.', contains(glob));
+      expect('foo*', contains(glob));
+      expect('foob', isNot(contains(glob)));
+      expect('foo>', isNot(contains(glob)));
     });
 
-    test("can match a range of characters", () {
-      var glob = Glob("foo[a-z]");
-      expect("fooa", contains(glob));
-      expect("foon", contains(glob));
-      expect("fooz", contains(glob));
-      expect("foo`", isNot(contains(glob)));
-      expect("foo{", isNot(contains(glob)));
+    test('can match a range of characters', () {
+      var glob = Glob('foo[a-z]');
+      expect('fooa', contains(glob));
+      expect('foon', contains(glob));
+      expect('fooz', contains(glob));
+      expect('foo`', isNot(contains(glob)));
+      expect('foo{', isNot(contains(glob)));
     });
 
-    test("can match multiple ranges of characters", () {
-      var glob = Glob("foo[a-zA-Z]");
-      expect("fooa", contains(glob));
-      expect("foon", contains(glob));
-      expect("fooz", contains(glob));
-      expect("fooA", contains(glob));
-      expect("fooN", contains(glob));
-      expect("fooZ", contains(glob));
-      expect("foo?", isNot(contains(glob)));
-      expect("foo{", isNot(contains(glob)));
+    test('can match multiple ranges of characters', () {
+      var glob = Glob('foo[a-zA-Z]');
+      expect('fooa', contains(glob));
+      expect('foon', contains(glob));
+      expect('fooz', contains(glob));
+      expect('fooA', contains(glob));
+      expect('fooN', contains(glob));
+      expect('fooZ', contains(glob));
+      expect('foo?', isNot(contains(glob)));
+      expect('foo{', isNot(contains(glob)));
     });
 
-    test("can match individual characters and ranges of characters", () {
-      var glob = Glob("foo[a-z_A-Z]");
-      expect("fooa", contains(glob));
-      expect("foon", contains(glob));
-      expect("fooz", contains(glob));
-      expect("fooA", contains(glob));
-      expect("fooN", contains(glob));
-      expect("fooZ", contains(glob));
-      expect("foo_", contains(glob));
-      expect("foo?", isNot(contains(glob)));
-      expect("foo{", isNot(contains(glob)));
+    test('can match individual characters and ranges of characters', () {
+      var glob = Glob('foo[a-z_A-Z]');
+      expect('fooa', contains(glob));
+      expect('foon', contains(glob));
+      expect('fooz', contains(glob));
+      expect('fooA', contains(glob));
+      expect('fooN', contains(glob));
+      expect('fooZ', contains(glob));
+      expect('foo_', contains(glob));
+      expect('foo?', isNot(contains(glob)));
+      expect('foo{', isNot(contains(glob)));
     });
 
-    test("can be negated", () {
-      var glob = Glob("foo[^a<.*]");
-      expect("fooa", isNot(contains(glob)));
-      expect("foo<", isNot(contains(glob)));
-      expect("foo.", isNot(contains(glob)));
-      expect("foo*", isNot(contains(glob)));
-      expect("foob", contains(glob));
-      expect("foo>", contains(glob));
+    test('can be negated', () {
+      var glob = Glob('foo[^a<.*]');
+      expect('fooa', isNot(contains(glob)));
+      expect('foo<', isNot(contains(glob)));
+      expect('foo.', isNot(contains(glob)));
+      expect('foo*', isNot(contains(glob)));
+      expect('foob', contains(glob));
+      expect('foo>', contains(glob));
     });
 
-    test("never matches separators", () {
+    test('never matches separators', () {
       // "\t-~" contains "/".
-      expect("foo/bar", isNot(contains(Glob("foo[\t-~]bar"))));
-      expect("foo/bar", isNot(contains(Glob("foo[^a]bar"))));
+      expect('foo/bar', isNot(contains(Glob('foo[\t-~]bar'))));
+      expect('foo/bar', isNot(contains(Glob('foo[^a]bar'))));
     });
 
-    test("allows dangling -", () {
-      expect("-", contains(Glob(r"[-]")));
+    test('allows dangling -', () {
+      expect('-', contains(Glob(r'[-]')));
 
-      var glob = Glob(r"[a-]");
-      expect("-", contains(glob));
-      expect("a", contains(glob));
+      var glob = Glob(r'[a-]');
+      expect('-', contains(glob));
+      expect('a', contains(glob));
 
-      glob = Glob(r"[-b]");
-      expect("-", contains(glob));
-      expect("b", contains(glob));
+      glob = Glob(r'[-b]');
+      expect('-', contains(glob));
+      expect('b', contains(glob));
     });
 
-    test("allows multiple -s", () {
-      expect("-", contains(Glob(r"[--]")));
-      expect("-", contains(Glob(r"[---]")));
+    test('allows multiple -s', () {
+      expect('-', contains(Glob(r'[--]')));
+      expect('-', contains(Glob(r'[---]')));
 
-      var glob = Glob(r"[--a]");
-      expect("-", contains(glob));
-      expect("a", contains(glob));
+      var glob = Glob(r'[--a]');
+      expect('-', contains(glob));
+      expect('a', contains(glob));
     });
 
-    test("allows negated /", () {
-      expect("foo-bar", contains(Glob("foo[^/]bar")));
+    test('allows negated /', () {
+      expect('foo-bar', contains(Glob('foo[^/]bar')));
     });
 
     test("doesn't choke on RegExp-active characters", () {
-      var glob = Glob(r"foo[\]].*");
-      expect("foobar", isNot(contains(glob)));
-      expect("foo].*", contains(glob));
+      var glob = Glob(r'foo[\]].*');
+      expect('foobar', isNot(contains(glob)));
+      expect('foo].*', contains(glob));
     });
   });
 
-  group("options", () {
-    test("match if any of the options match", () {
-      var glob = Glob("foo/{bar,baz,bang}");
-      expect("foo/bar", contains(glob));
-      expect("foo/baz", contains(glob));
-      expect("foo/bang", contains(glob));
-      expect("foo/qux", isNot(contains(glob)));
+  group('options', () {
+    test('match if any of the options match', () {
+      var glob = Glob('foo/{bar,baz,bang}');
+      expect('foo/bar', contains(glob));
+      expect('foo/baz', contains(glob));
+      expect('foo/bang', contains(glob));
+      expect('foo/qux', isNot(contains(glob)));
     });
 
-    test("can contain nested operators", () {
-      var glob = Glob("foo/{ba?,*az,ban{g,f}}");
-      expect("foo/bar", contains(glob));
-      expect("foo/baz", contains(glob));
-      expect("foo/bang", contains(glob));
-      expect("foo/qux", isNot(contains(glob)));
+    test('can contain nested operators', () {
+      var glob = Glob('foo/{ba?,*az,ban{g,f}}');
+      expect('foo/bar', contains(glob));
+      expect('foo/baz', contains(glob));
+      expect('foo/bang', contains(glob));
+      expect('foo/qux', isNot(contains(glob)));
     });
 
-    test("can conditionally match separators", () {
-      var glob = Glob("foo/{bar,baz/bang}");
-      expect("foo/bar", contains(glob));
-      expect("foo/baz/bang", contains(glob));
-      expect("foo/baz", isNot(contains(glob)));
-      expect("foo/bar/bang", isNot(contains(glob)));
+    test('can conditionally match separators', () {
+      var glob = Glob('foo/{bar,baz/bang}');
+      expect('foo/bar', contains(glob));
+      expect('foo/baz/bang', contains(glob));
+      expect('foo/baz', isNot(contains(glob)));
+      expect('foo/bar/bang', isNot(contains(glob)));
     });
   });
 
-  group("normalization", () {
-    test("extra slashes are ignored", () {
-      expect("foo//bar", contains(Glob("foo/bar")));
-      expect("foo/", contains(Glob("*")));
+  group('normalization', () {
+    test('extra slashes are ignored', () {
+      expect('foo//bar', contains(Glob('foo/bar')));
+      expect('foo/', contains(Glob('*')));
     });
 
-    test("dot directories are ignored", () {
-      expect("foo/./bar", contains(Glob("foo/bar")));
-      expect("foo/.", contains(Glob("foo")));
+    test('dot directories are ignored', () {
+      expect('foo/./bar', contains(Glob('foo/bar')));
+      expect('foo/.', contains(Glob('foo')));
     });
 
-    test("dot dot directories are resolved", () {
-      expect("foo/../bar", contains(Glob("bar")));
-      expect("../foo/bar", contains(Glob("../foo/bar")));
-      expect("foo/../../bar", contains(Glob("../bar")));
+    test('dot dot directories are resolved', () {
+      expect('foo/../bar', contains(Glob('bar')));
+      expect('../foo/bar', contains(Glob('../foo/bar')));
+      expect('foo/../../bar', contains(Glob('../bar')));
     });
 
-    test("Windows separators are converted in a Windows context", () {
-      expect(r"foo\bar", contains(Glob("foo/bar", context: p.windows)));
-      expect(r"foo\bar/baz", contains(Glob("foo/bar/baz", context: p.windows)));
+    test('Windows separators are converted in a Windows context', () {
+      expect(r'foo\bar', contains(Glob('foo/bar', context: p.windows)));
+      expect(r'foo\bar/baz', contains(Glob('foo/bar/baz', context: p.windows)));
     });
   });
 
-  test("an absolute path can be matched by a relative glob", () {
+  test('an absolute path can be matched by a relative glob', () {
     var path = p.absolute('foo/bar');
-    expect(path, contains(Glob("foo/bar")));
+    expect(path, contains(Glob('foo/bar')));
   });
 
-  test("a relative path can be matched by an absolute glob", () {
+  test('a relative path can be matched by an absolute glob', () {
     var pattern = separatorToForwardSlash(p.absolute('foo/bar'));
     expect('foo/bar', contains(Glob(pattern)));
   }, testOn: 'vm');
 
-  group("with recursive: true", () {
-    var glob = Glob("foo/bar", recursive: true);
+  group('with recursive: true', () {
+    var glob = Glob('foo/bar', recursive: true);
 
-    test("still matches basic files", () {
-      expect("foo/bar", contains(glob));
+    test('still matches basic files', () {
+      expect('foo/bar', contains(glob));
     });
 
-    test("matches subfiles", () {
-      expect("foo/bar/baz", contains(glob));
-      expect("foo/bar/baz/bang", contains(glob));
+    test('matches subfiles', () {
+      expect('foo/bar/baz', contains(glob));
+      expect('foo/bar/baz/bang', contains(glob));
     });
 
     test("doesn't match suffixes", () {
-      expect("foo/barbaz", isNot(contains(glob)));
-      expect("foo/barbaz/bang", isNot(contains(glob)));
+      expect('foo/barbaz', isNot(contains(glob)));
+      expect('foo/barbaz/bang', isNot(contains(glob)));
     });
   });
 
-  test("absolute POSIX paths", () {
-    expect("/foo/bar", contains(Glob("/foo/bar", context: p.posix)));
-    expect("/foo/bar", isNot(contains(Glob("**", context: p.posix))));
-    expect("/foo/bar", contains(Glob("/**", context: p.posix)));
+  test('absolute POSIX paths', () {
+    expect('/foo/bar', contains(Glob('/foo/bar', context: p.posix)));
+    expect('/foo/bar', isNot(contains(Glob('**', context: p.posix))));
+    expect('/foo/bar', contains(Glob('/**', context: p.posix)));
   });
 
-  test("absolute Windows paths", () {
-    expect(r"C:\foo\bar", contains(Glob("C:/foo/bar", context: p.windows)));
-    expect(r"C:\foo\bar", isNot(contains(Glob("**", context: p.windows))));
-    expect(r"C:\foo\bar", contains(Glob("C:/**", context: p.windows)));
+  test('absolute Windows paths', () {
+    expect(r'C:\foo\bar', contains(Glob('C:/foo/bar', context: p.windows)));
+    expect(r'C:\foo\bar', isNot(contains(Glob('**', context: p.windows))));
+    expect(r'C:\foo\bar', contains(Glob('C:/**', context: p.windows)));
 
     expect(
-        r"\\foo\bar\baz", contains(Glob("//foo/bar/baz", context: p.windows)));
-    expect(r"\\foo\bar\baz", isNot(contains(Glob("**", context: p.windows))));
-    expect(r"\\foo\bar\baz", contains(Glob("//**", context: p.windows)));
-    expect(r"\\foo\bar\baz", contains(Glob("//foo/**", context: p.windows)));
+        r'\\foo\bar\baz', contains(Glob('//foo/bar/baz', context: p.windows)));
+    expect(r'\\foo\bar\baz', isNot(contains(Glob('**', context: p.windows))));
+    expect(r'\\foo\bar\baz', contains(Glob('//**', context: p.windows)));
+    expect(r'\\foo\bar\baz', contains(Glob('//foo/**', context: p.windows)));
   });
 
-  test("absolute URL paths", () {
-    expect(r"http://foo.com/bar",
-        contains(Glob("http://foo.com/bar", context: p.url)));
-    expect(r"http://foo.com/bar", isNot(contains(Glob("**", context: p.url))));
-    expect(r"http://foo.com/bar", contains(Glob("http://**", context: p.url)));
-    expect(r"http://foo.com/bar",
-        contains(Glob("http://foo.com/**", context: p.url)));
+  test('absolute URL paths', () {
+    expect(r'http://foo.com/bar',
+        contains(Glob('http://foo.com/bar', context: p.url)));
+    expect(r'http://foo.com/bar', isNot(contains(Glob('**', context: p.url))));
+    expect(r'http://foo.com/bar', contains(Glob('http://**', context: p.url)));
+    expect(r'http://foo.com/bar',
+        contains(Glob('http://foo.com/**', context: p.url)));
 
-    expect("/foo/bar", contains(Glob("/foo/bar", context: p.url)));
-    expect("/foo/bar", isNot(contains(Glob("**", context: p.url))));
-    expect("/foo/bar", contains(Glob("/**", context: p.url)));
+    expect('/foo/bar', contains(Glob('/foo/bar', context: p.url)));
+    expect('/foo/bar', isNot(contains(Glob('**', context: p.url))));
+    expect('/foo/bar', contains(Glob('/**', context: p.url)));
   });
 
-  group("when case-sensitive", () {
-    test("literals match case-sensitively", () {
-      expect("foo", contains(Glob("foo", caseSensitive: true)));
-      expect("FOO", isNot(contains(Glob("foo", caseSensitive: true))));
-      expect("foo", isNot(contains(Glob("FOO", caseSensitive: true))));
+  group('when case-sensitive', () {
+    test('literals match case-sensitively', () {
+      expect('foo', contains(Glob('foo', caseSensitive: true)));
+      expect('FOO', isNot(contains(Glob('foo', caseSensitive: true))));
+      expect('foo', isNot(contains(Glob('FOO', caseSensitive: true))));
     });
 
-    test("ranges match case-sensitively", () {
-      expect("foo", contains(Glob("[fx][a-z]o", caseSensitive: true)));
-      expect("FOO", isNot(contains(Glob("[fx][a-z]o", caseSensitive: true))));
-      expect("foo", isNot(contains(Glob("[FX][A-Z]O", caseSensitive: true))));
+    test('ranges match case-sensitively', () {
+      expect('foo', contains(Glob('[fx][a-z]o', caseSensitive: true)));
+      expect('FOO', isNot(contains(Glob('[fx][a-z]o', caseSensitive: true))));
+      expect('foo', isNot(contains(Glob('[FX][A-Z]O', caseSensitive: true))));
     });
 
-    test("sequences preserve case-sensitivity", () {
-      expect("foo/bar", contains(Glob("foo/bar", caseSensitive: true)));
-      expect("FOO/BAR", isNot(contains(Glob("foo/bar", caseSensitive: true))));
-      expect("foo/bar", isNot(contains(Glob("FOO/BAR", caseSensitive: true))));
+    test('sequences preserve case-sensitivity', () {
+      expect('foo/bar', contains(Glob('foo/bar', caseSensitive: true)));
+      expect('FOO/BAR', isNot(contains(Glob('foo/bar', caseSensitive: true))));
+      expect('foo/bar', isNot(contains(Glob('FOO/BAR', caseSensitive: true))));
     });
 
-    test("options preserve case-sensitivity", () {
-      expect("foo", contains(Glob("{foo,bar}", caseSensitive: true)));
-      expect("FOO", isNot(contains(Glob("{foo,bar}", caseSensitive: true))));
-      expect("foo", isNot(contains(Glob("{FOO,BAR}", caseSensitive: true))));
+    test('options preserve case-sensitivity', () {
+      expect('foo', contains(Glob('{foo,bar}', caseSensitive: true)));
+      expect('FOO', isNot(contains(Glob('{foo,bar}', caseSensitive: true))));
+      expect('foo', isNot(contains(Glob('{FOO,BAR}', caseSensitive: true))));
     });
   });
 
-  group("when case-insensitive", () {
-    test("literals match case-insensitively", () {
-      expect("foo", contains(Glob("foo", caseSensitive: false)));
-      expect("FOO", contains(Glob("foo", caseSensitive: false)));
-      expect("foo", contains(Glob("FOO", caseSensitive: false)));
+  group('when case-insensitive', () {
+    test('literals match case-insensitively', () {
+      expect('foo', contains(Glob('foo', caseSensitive: false)));
+      expect('FOO', contains(Glob('foo', caseSensitive: false)));
+      expect('foo', contains(Glob('FOO', caseSensitive: false)));
     });
 
-    test("ranges match case-insensitively", () {
-      expect("foo", contains(Glob("[fx][a-z]o", caseSensitive: false)));
-      expect("FOO", contains(Glob("[fx][a-z]o", caseSensitive: false)));
-      expect("foo", contains(Glob("[FX][A-Z]O", caseSensitive: false)));
+    test('ranges match case-insensitively', () {
+      expect('foo', contains(Glob('[fx][a-z]o', caseSensitive: false)));
+      expect('FOO', contains(Glob('[fx][a-z]o', caseSensitive: false)));
+      expect('foo', contains(Glob('[FX][A-Z]O', caseSensitive: false)));
     });
 
-    test("sequences preserve case-insensitivity", () {
-      expect("foo/bar", contains(Glob("foo/bar", caseSensitive: false)));
-      expect("FOO/BAR", contains(Glob("foo/bar", caseSensitive: false)));
-      expect("foo/bar", contains(Glob("FOO/BAR", caseSensitive: false)));
+    test('sequences preserve case-insensitivity', () {
+      expect('foo/bar', contains(Glob('foo/bar', caseSensitive: false)));
+      expect('FOO/BAR', contains(Glob('foo/bar', caseSensitive: false)));
+      expect('foo/bar', contains(Glob('FOO/BAR', caseSensitive: false)));
     });
 
-    test("options preserve case-insensitivity", () {
-      expect("foo", contains(Glob("{foo,bar}", caseSensitive: false)));
-      expect("FOO", contains(Glob("{foo,bar}", caseSensitive: false)));
-      expect("foo", contains(Glob("{FOO,BAR}", caseSensitive: false)));
+    test('options preserve case-insensitivity', () {
+      expect('foo', contains(Glob('{foo,bar}', caseSensitive: false)));
+      expect('FOO', contains(Glob('{foo,bar}', caseSensitive: false)));
+      expect('foo', contains(Glob('{FOO,BAR}', caseSensitive: false)));
     });
   });
 }
diff --git a/test/parse_test.dart b/test/parse_test.dart
index 2ea3bb9..5a075e7 100644
--- a/test/parse_test.dart
+++ b/test/parse_test.dart
@@ -7,90 +7,90 @@
 import 'package:test/test.dart';
 
 void main() {
-  test("supports backslash-escaped characters", () {
-    expect(r"*[]{,}?()", contains(Glob(r"\*\[\]\{\,\}\?\(\)")));
+  test('supports backslash-escaped characters', () {
+    expect(r'*[]{,}?()', contains(Glob(r'\*\[\]\{\,\}\?\(\)')));
     if (p.style != p.Style.windows) {
-      expect(r"foo\bar", contains(Glob(r"foo\\bar")));
+      expect(r'foo\bar', contains(Glob(r'foo\\bar')));
     }
   });
 
-  test("disallows an empty glob", () {
-    expect(() => Glob(""), throwsFormatException);
+  test('disallows an empty glob', () {
+    expect(() => Glob(''), throwsFormatException);
   });
 
-  group("range", () {
-    test("supports either ^ or ! for negated ranges", () {
-      var bang = Glob("fo[!a-z]");
-      expect("foo", isNot(contains(bang)));
-      expect("fo2", contains(bang));
+  group('range', () {
+    test('supports either ^ or ! for negated ranges', () {
+      var bang = Glob('fo[!a-z]');
+      expect('foo', isNot(contains(bang)));
+      expect('fo2', contains(bang));
 
-      var caret = Glob("fo[^a-z]");
-      expect("foo", isNot(contains(caret)));
-      expect("fo2", contains(caret));
+      var caret = Glob('fo[^a-z]');
+      expect('foo', isNot(contains(caret)));
+      expect('fo2', contains(caret));
     });
 
-    test("supports backslash-escaped characters", () {
-      var glob = Glob(r"fo[\*\--\]]");
-      expect("fo]", contains(glob));
-      expect("fo-", contains(glob));
-      expect("fo*", contains(glob));
+    test('supports backslash-escaped characters', () {
+      var glob = Glob(r'fo[\*\--\]]');
+      expect('fo]', contains(glob));
+      expect('fo-', contains(glob));
+      expect('fo*', contains(glob));
     });
 
-    test("disallows inverted ranges", () {
-      expect(() => Glob(r"[z-a]"), throwsFormatException);
+    test('disallows inverted ranges', () {
+      expect(() => Glob(r'[z-a]'), throwsFormatException);
     });
 
-    test("disallows empty ranges", () {
-      expect(() => Glob(r"[]"), throwsFormatException);
+    test('disallows empty ranges', () {
+      expect(() => Glob(r'[]'), throwsFormatException);
     });
 
-    test("disallows unclosed ranges", () {
-      expect(() => Glob(r"[abc"), throwsFormatException);
-      expect(() => Glob(r"[-"), throwsFormatException);
+    test('disallows unclosed ranges', () {
+      expect(() => Glob(r'[abc'), throwsFormatException);
+      expect(() => Glob(r'[-'), throwsFormatException);
     });
 
-    test("disallows dangling ]", () {
-      expect(() => Glob(r"abc]"), throwsFormatException);
+    test('disallows dangling ]', () {
+      expect(() => Glob(r'abc]'), throwsFormatException);
     });
 
-    test("disallows explicit /", () {
-      expect(() => Glob(r"[/]"), throwsFormatException);
-      expect(() => Glob(r"[ -/]"), throwsFormatException);
-      expect(() => Glob(r"[/-~]"), throwsFormatException);
+    test('disallows explicit /', () {
+      expect(() => Glob(r'[/]'), throwsFormatException);
+      expect(() => Glob(r'[ -/]'), throwsFormatException);
+      expect(() => Glob(r'[/-~]'), throwsFormatException);
     });
   });
 
-  group("options", () {
-    test("allows empty branches", () {
-      var glob = Glob("foo{,bar}");
-      expect("foo", contains(glob));
-      expect("foobar", contains(glob));
+  group('options', () {
+    test('allows empty branches', () {
+      var glob = Glob('foo{,bar}');
+      expect('foo', contains(glob));
+      expect('foobar', contains(glob));
     });
 
-    test("disallows empty options", () {
-      expect(() => Glob("{}"), throwsFormatException);
+    test('disallows empty options', () {
+      expect(() => Glob('{}'), throwsFormatException);
     });
 
-    test("disallows single options", () {
-      expect(() => Glob("{foo}"), throwsFormatException);
+    test('disallows single options', () {
+      expect(() => Glob('{foo}'), throwsFormatException);
     });
 
-    test("disallows unclosed options", () {
-      expect(() => Glob("{foo,bar"), throwsFormatException);
-      expect(() => Glob("{foo,"), throwsFormatException);
+    test('disallows unclosed options', () {
+      expect(() => Glob('{foo,bar'), throwsFormatException);
+      expect(() => Glob('{foo,'), throwsFormatException);
     });
 
-    test("disallows dangling }", () {
-      expect(() => Glob("foo}"), throwsFormatException);
+    test('disallows dangling }', () {
+      expect(() => Glob('foo}'), throwsFormatException);
     });
 
-    test("disallows dangling ] in options", () {
-      expect(() => Glob(r"{abc]}"), throwsFormatException);
+    test('disallows dangling ] in options', () {
+      expect(() => Glob(r'{abc]}'), throwsFormatException);
     });
   });
 
-  test("disallows unescaped parens", () {
-    expect(() => Glob("foo(bar"), throwsFormatException);
-    expect(() => Glob("foo)bar"), throwsFormatException);
+  test('disallows unescaped parens', () {
+    expect(() => Glob('foo(bar'), throwsFormatException);
+    expect(() => Glob('foo)bar'), throwsFormatException);
   });
 }