Fix new pedantic lints, disallow implicit casts (#40)

- annotate_overrides
- prefer_single_quotes

There is a minor breaking change in `VersionConstraint.unionOf` if any callers
were passing a custom subtype of `VersionConstraint` and _also_ always had
a constraint with `.isAny` of `true`. There are no known remaining callers of
this API and it should be removed - allowing a technically breaking change that
no one will hit allows us to have nice static types within the method.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index c970ea7..248e8c6 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,7 +1,9 @@
 include: package:pedantic/analysis_options.yaml
+
 analyzer:
-#  strong-mode:
-#    implicit-casts: false
+  strong-mode:
+    implicit-casts: false
+
 linter:
   rules:
     - always_declare_return_types
diff --git a/lib/src/patterns.dart b/lib/src/patterns.dart
index 8829447..d5f1897 100644
--- a/lib/src/patterns.dart
+++ b/lib/src/patterns.dart
@@ -13,7 +13,7 @@
 
 /// Parses a comparison operator ("<", ">", "<=", or ">=") at the beginning of
 /// a string.
-final startComparison = RegExp(r"^[<>]=?");
+final startComparison = RegExp(r'^[<>]=?');
 
 /// The "compatible with" operator.
-const compatibleWithChar = "^";
+const compatibleWithChar = '^';
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 031af52..eb38409 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -83,9 +83,13 @@
   /// of the parsed version.
   final String _text;
 
+  @override
   Version get min => this;
+  @override
   Version get max => this;
+  @override
   bool get includeMin => true;
+  @override
   bool get includeMax => true;
 
   Version._(this.major, this.minor, this.patch, String preRelease, String build,
@@ -99,9 +103,9 @@
 
   /// Creates a new [Version] object.
   factory Version(int major, int minor, int patch, {String pre, String build}) {
-    var text = "$major.$minor.$patch";
-    if (pre != null) text += "-$pre";
-    if (build != null) text += "+$build";
+    var text = '$major.$minor.$patch';
+    if (pre != null) text += '-$pre';
+    if (build != null) text += '+$build';
 
     return Version._(major, minor, patch, pre, build, text);
   }
@@ -157,15 +161,16 @@
     }).toList();
   }
 
-  bool operator ==(other) {
-    if (other is! Version) return false;
-    return major == other.major &&
-        minor == other.minor &&
-        patch == other.patch &&
-        _equality.equals(preRelease, other.preRelease) &&
-        _equality.equals(build, other.build);
-  }
+  @override
+  bool operator ==(Object other) =>
+      other is Version &&
+      major == other.major &&
+      minor == other.minor &&
+      patch == other.patch &&
+      _equality.equals(preRelease, other.preRelease) &&
+      _equality.equals(build, other.build);
 
+  @override
   int get hashCode =>
       major ^
       minor ^
@@ -178,7 +183,9 @@
   bool operator <=(Version other) => compareTo(other) <= 0;
   bool operator >=(Version other) => compareTo(other) >= 0;
 
+  @override
   bool get isAny => false;
+  @override
   bool get isEmpty => false;
 
   /// Whether or not this is a pre-release version.
@@ -237,7 +244,7 @@
   }
 
   /// Returns the first possible pre-release of this version.
-  Version get firstPreRelease => Version(major, minor, patch, pre: "0");
+  Version get firstPreRelease => Version(major, minor, patch, pre: '0');
 
   /// Returns whether this is the first possible pre-release of its version.
   bool get isFirstPreRelease => preRelease.length == 1 && preRelease.first == 0;
@@ -247,15 +254,20 @@
   Version _incrementPatch() => Version(major, minor, patch + 1);
 
   /// Tests if [other] matches this version exactly.
+  @override
   bool allows(Version other) => this == other;
 
+  @override
   bool allowsAll(VersionConstraint other) => other.isEmpty || other == this;
 
+  @override
   bool allowsAny(VersionConstraint other) => other.allows(this);
 
+  @override
   VersionConstraint intersect(VersionConstraint other) =>
       other.allows(this) ? this : VersionConstraint.empty;
 
+  @override
   VersionConstraint union(VersionConstraint other) {
     if (other.allows(this)) return other;
 
@@ -282,9 +294,11 @@
     return VersionConstraint.unionOf([this, other]);
   }
 
+  @override
   VersionConstraint difference(VersionConstraint other) =>
       other.allows(this) ? VersionConstraint.empty : this;
 
+  @override
   int compareTo(VersionRange other) {
     if (other is Version) {
       if (major != other.major) return major.compareTo(other.major);
@@ -307,6 +321,7 @@
     }
   }
 
+  @override
   String toString() => _text;
 
   /// Compares a dot-separated component of two versions.
@@ -338,7 +353,7 @@
           return 1;
         } else {
           // Compare two strings.
-          return aPart.compareTo(bPart);
+          return (aPart as String).compareTo(bPart as String);
         }
       }
     }
diff --git a/lib/src/version_constraint.dart b/lib/src/version_constraint.dart
index 6dfd396..ac39b6b 100644
--- a/lib/src/version_constraint.dart
+++ b/lib/src/version_constraint.dart
@@ -54,7 +54,7 @@
     skipWhitespace();
 
     // Handle the "any" constraint.
-    if (text == "any") return any;
+    if (text == 'any') return any;
 
     // Try to parse and consume a version number.
     Version matchVersion() {
@@ -190,7 +190,7 @@
       Iterable<VersionConstraint> constraints) {
     var constraint = VersionRange();
     for (var other in constraints) {
-      constraint = constraint.intersect(other);
+      constraint = constraint.intersect(other) as VersionRange;
     }
     return constraint;
   }
@@ -201,9 +201,10 @@
   /// [constraints] is empty, this returns a constraint that allows no versions.
   factory VersionConstraint.unionOf(Iterable<VersionConstraint> constraints) {
     var flattened = constraints.expand((constraint) {
-      if (constraint.isEmpty) return [];
+      if (constraint.isEmpty) return <VersionRange>[];
       if (constraint is VersionUnion) return constraint.ranges;
-      return [constraint];
+      if (constraint is VersionRange) return [constraint];
+      throw ArgumentError('Unknown VersionConstraint type $constraint.');
     }).toList();
 
     if (flattened.isEmpty) return VersionConstraint.empty;
@@ -212,14 +213,6 @@
       return VersionConstraint.any;
     }
 
-    // Only allow Versions and VersionRanges here so we can more easily reason
-    // about everything in [flattened]. _EmptyVersions and VersionUnions are
-    // filtered out above.
-    for (var constraint in flattened) {
-      if (constraint is VersionRange) continue;
-      throw ArgumentError('Unknown VersionConstraint type $constraint.');
-    }
-
     flattened.sort();
 
     var merged = <VersionRange>[];
@@ -230,7 +223,8 @@
               !areAdjacent(merged.last, constraint))) {
         merged.add(constraint);
       } else {
-        merged[merged.length - 1] = merged.last.union(constraint);
+        merged[merged.length - 1] =
+            merged.last.union(constraint) as VersionRange;
       }
     }
 
@@ -271,21 +265,30 @@
 class _EmptyVersion implements VersionConstraint {
   const _EmptyVersion();
 
+  @override
   bool get isEmpty => true;
 
+  @override
   bool get isAny => false;
 
+  @override
   bool allows(Version other) => false;
 
+  @override
   bool allowsAll(VersionConstraint other) => other.isEmpty;
 
+  @override
   bool allowsAny(VersionConstraint other) => false;
 
+  @override
   VersionConstraint intersect(VersionConstraint other) => this;
 
+  @override
   VersionConstraint union(VersionConstraint other) => other;
 
+  @override
   VersionConstraint difference(VersionConstraint other) => this;
 
+  @override
   String toString() => '<empty>';
 }
diff --git a/lib/src/version_range.dart b/lib/src/version_range.dart
index 8ac79da..2c40884 100644
--- a/lib/src/version_range.dart
+++ b/lib/src/version_range.dart
@@ -84,6 +84,7 @@
 
   VersionRange._(this.min, this.max, this.includeMin, this.includeMax);
 
+  @override
   bool operator ==(other) {
     if (other is! VersionRange) return false;
 
@@ -93,17 +94,21 @@
         includeMax == other.includeMax;
   }
 
+  @override
   int get hashCode =>
       min.hashCode ^
       (max.hashCode * 3) ^
       (includeMin.hashCode * 5) ^
       (includeMax.hashCode * 7);
 
+  @override
   bool get isEmpty => false;
 
+  @override
   bool get isAny => min == null && max == null;
 
   /// Tests if [other] falls within this version range.
+  @override
   bool allows(Version other) {
     if (min != null) {
       if (other < min) return false;
@@ -118,6 +123,7 @@
     return true;
   }
 
+  @override
   bool allowsAll(VersionConstraint other) {
     if (other.isEmpty) return true;
     if (other is Version) return allows(other);
@@ -133,6 +139,7 @@
     throw ArgumentError('Unknown VersionConstraint type $other.');
   }
 
+  @override
   bool allowsAny(VersionConstraint other) {
     if (other.isEmpty) return false;
     if (other is Version) return allows(other);
@@ -148,6 +155,7 @@
     throw ArgumentError('Unknown VersionConstraint type $other.');
   }
 
+  @override
   VersionConstraint intersect(VersionConstraint other) {
     if (other.isEmpty) return other;
     if (other is VersionUnion) return other.intersect(this);
@@ -206,6 +214,7 @@
     throw ArgumentError('Unknown VersionConstraint type $other.');
   }
 
+  @override
   VersionConstraint union(VersionConstraint other) {
     if (other is Version) {
       if (allows(other)) return this;
@@ -271,6 +280,7 @@
     return VersionConstraint.unionOf([this, other]);
   }
 
+  @override
   VersionConstraint difference(VersionConstraint other) {
     if (other.isEmpty) return this;
 
@@ -383,6 +393,7 @@
     throw ArgumentError('Unknown VersionConstraint type $other.');
   }
 
+  @override
   int compareTo(VersionRange other) {
     if (min == null) {
       if (other.min == null) return _compareMax(other);
@@ -413,6 +424,7 @@
     return 0;
   }
 
+  @override
   String toString() {
     var buffer = StringBuffer();
 
@@ -429,7 +441,7 @@
         if (max.isFirstPreRelease) {
           // Since `"<$max"` would parse the same as `"<$max-0"`, we just emit
           // `<$max` to avoid confusing "-0" suffixes.
-          buffer.write("${max.major}.${max.minor}.${max.patch}");
+          buffer.write('${max.major}.${max.minor}.${max.patch}');
         } else {
           buffer.write(max);
 
@@ -439,7 +451,7 @@
               min.isPreRelease &&
               equalsWithoutPreRelease(min, max);
           if (!max.isPreRelease && max.build.isEmpty && !minIsPreReleaseOfMax) {
-            buffer.write("-∞");
+            buffer.write('-∞');
           }
         }
       }
@@ -454,5 +466,6 @@
   CompatibleWithVersionRange(Version version)
       : super._(version, version.nextBreaking.firstPreRelease, true, false);
 
+  @override
   String toString() => '^$min';
 }
diff --git a/lib/src/version_union.dart b/lib/src/version_union.dart
index b774163..8a23522 100644
--- a/lib/src/version_union.dart
+++ b/lib/src/version_union.dart
@@ -25,8 +25,10 @@
   ///   those constraints that they don't match.
   final List<VersionRange> ranges;
 
+  @override
   bool get isEmpty => false;
 
+  @override
   bool get isAny => false;
 
   /// Creates a union from a list of ranges with no pre-processing.
@@ -37,9 +39,11 @@
   /// VersionConstraint.unionOf] instead.
   VersionUnion.fromRanges(this.ranges);
 
+  @override
   bool allows(Version version) =>
       ranges.any((constraint) => constraint.allows(version));
 
+  @override
   bool allowsAll(VersionConstraint other) {
     var ourRanges = ranges.iterator;
     var theirRanges = _rangesFor(other).iterator;
@@ -61,6 +65,7 @@
     return theirRanges.current == null;
   }
 
+  @override
   bool allowsAny(VersionConstraint other) {
     var ourRanges = ranges.iterator;
     var theirRanges = _rangesFor(other).iterator;
@@ -86,6 +91,7 @@
     return false;
   }
 
+  @override
   VersionConstraint intersect(VersionConstraint other) {
     var ourRanges = ranges.iterator;
     var theirRanges = _rangesFor(other).iterator;
@@ -98,7 +104,7 @@
     while (ourRanges.current != null && theirRanges.current != null) {
       var intersection = ourRanges.current.intersect(theirRanges.current);
 
-      if (!intersection.isEmpty) newRanges.add(intersection);
+      if (!intersection.isEmpty) newRanges.add(intersection as VersionRange);
 
       // Move the constraint with the lower max value forward. This ensures that
       // we keep both lists in sync as much as possible, and that large ranges
@@ -116,6 +122,7 @@
     return VersionUnion.fromRanges(newRanges);
   }
 
+  @override
   VersionConstraint difference(VersionConstraint other) {
     var ourRanges = ranges.iterator;
     var theirRanges = _rangesFor(other).iterator;
@@ -200,15 +207,18 @@
     throw ArgumentError('Unknown VersionConstraint type $constraint.');
   }
 
+  @override
   VersionConstraint union(VersionConstraint other) =>
       VersionConstraint.unionOf([this, other]);
 
-  bool operator ==(other) {
-    if (other is! VersionUnion) return false;
-    return const ListEquality().equals(ranges, other.ranges);
-  }
+  @override
+  bool operator ==(Object other) =>
+      other is VersionUnion &&
+      const ListEquality().equals(ranges, other.ranges);
 
+  @override
   int get hashCode => const ListEquality().hash(ranges);
 
-  String toString() => ranges.join(" or ");
+  @override
+  String toString() => ranges.join(' or ');
 }
diff --git a/test/utils.dart b/test/utils.dart
index a0fd684..eb3358a 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -34,16 +34,19 @@
 
   _VersionConstraintMatcher(this._expected, this._allow);
 
+  @override
   bool matches(item, Map matchState) =>
       (item is VersionConstraint) &&
       _expected.every((version) => item.allows(version) == _allow);
 
+  @override
   Description describe(Description description) {
     description.addAll(' ${_allow ? "allows" : "does not allow"} versions ',
         ', ', '', _expected);
     return description;
   }
 
+  @override
   Description describeMismatch(
       item, Description mismatchDescription, Map matchState, bool verbose) {
     if (item is! VersionConstraint) {
diff --git a/test/version_constraint_test.dart b/test/version_constraint_test.dart
index 1e48391..c9d8e61 100644
--- a/test/version_constraint_test.dart
+++ b/test/version_constraint_test.dart
@@ -152,14 +152,14 @@
 
     test('throws FormatException on a bad string', () {
       var bad = [
-        "", "   ", // Empty string.
-        "foo", // Bad text.
-        ">foo", // Bad text after operator.
-        "^foo", // Bad text after "^".
-        "1.0.0 foo", "1.0.0foo", // Bad text after version.
-        "anything", // Bad text after "any".
-        "<>1.0.0", // Multiple operators.
-        "1.0.0<" // Trailing operator.
+        '', '   ', // Empty string.
+        'foo', // Bad text.
+        '>foo', // Bad text after operator.
+        '^foo', // Bad text after "^".
+        '1.0.0 foo', '1.0.0foo', // Bad text after version.
+        'anything', // Bad text after "any".
+        '<>1.0.0', // Multiple operators.
+        '1.0.0<' // Trailing operator.
       ];
 
       for (var text in bad) {
diff --git a/test/version_range_test.dart b/test/version_range_test.dart
index cfd66d9..bf280c2 100644
--- a/test/version_range_test.dart
+++ b/test/version_range_test.dart
@@ -19,22 +19,22 @@
 
     group("doesn't make the max a pre-release if", () {
       test("it's already a pre-release", () {
-        expect(VersionRange(max: Version.parse("1.2.4-pre")).max,
-            equals(Version.parse("1.2.4-pre")));
+        expect(VersionRange(max: Version.parse('1.2.4-pre')).max,
+            equals(Version.parse('1.2.4-pre')));
       });
 
-      test("includeMax is true", () {
+      test('includeMax is true', () {
         expect(VersionRange(max: v124, includeMax: true).max, equals(v124));
       });
 
-      test("min is a prerelease of max", () {
-        expect(VersionRange(min: Version.parse("1.2.4-pre"), max: v124).max,
+      test('min is a prerelease of max', () {
+        expect(VersionRange(min: Version.parse('1.2.4-pre'), max: v124).max,
             equals(v124));
       });
 
-      test("max has a build identifier", () {
-        expect(VersionRange(max: Version.parse("1.2.4+1")).max,
-            equals(Version.parse("1.2.4+1")));
+      test('max has a build identifier', () {
+        expect(VersionRange(max: Version.parse('1.2.4+1')).max,
+            equals(Version.parse('1.2.4+1')));
       });
     });
 
@@ -472,71 +472,71 @@
           VersionRange(min: v123, max: v124).intersect(v114).isEmpty, isTrue);
     });
 
-    test("with a range with a pre-release min, returns an empty constraint",
+    test('with a range with a pre-release min, returns an empty constraint',
         () {
       expect(
           VersionRange(max: v200)
-              .intersect(VersionConstraint.parse(">=2.0.0-dev")),
+              .intersect(VersionConstraint.parse('>=2.0.0-dev')),
           equals(VersionConstraint.empty));
     });
 
-    test("with a range with a pre-release max, returns the original", () {
+    test('with a range with a pre-release max, returns the original', () {
       expect(
           VersionRange(max: v200)
-              .intersect(VersionConstraint.parse("<2.0.0-dev")),
+              .intersect(VersionConstraint.parse('<2.0.0-dev')),
           equals(VersionRange(max: v200)));
     });
 
-    group("with includeMaxPreRelease", () {
+    group('with includeMaxPreRelease', () {
       test('preserves includeMaxPreRelease if the max version is included', () {
         expect(
             includeMaxPreReleaseRange
-                .intersect(VersionConstraint.parse("<1.0.0")),
-            equals(VersionConstraint.parse("<1.0.0")));
+                .intersect(VersionConstraint.parse('<1.0.0')),
+            equals(VersionConstraint.parse('<1.0.0')));
         expect(
             includeMaxPreReleaseRange
-                .intersect(VersionConstraint.parse("<2.0.0")),
-            equals(VersionConstraint.parse("<2.0.0")));
+                .intersect(VersionConstraint.parse('<2.0.0')),
+            equals(VersionConstraint.parse('<2.0.0')));
         expect(includeMaxPreReleaseRange.intersect(includeMaxPreReleaseRange),
             equals(includeMaxPreReleaseRange));
         expect(
             includeMaxPreReleaseRange
-                .intersect(VersionConstraint.parse("<3.0.0")),
+                .intersect(VersionConstraint.parse('<3.0.0')),
             equals(includeMaxPreReleaseRange));
         expect(
             includeMaxPreReleaseRange
-                .intersect(VersionConstraint.parse(">1.1.4")),
+                .intersect(VersionConstraint.parse('>1.1.4')),
             equals(VersionRange(
                 min: v114, max: v200, alwaysIncludeMaxPreRelease: true)));
       });
 
       test(
-          "and a range with a pre-release min, returns "
-          "an intersection", () {
+          'and a range with a pre-release min, returns '
+          'an intersection', () {
         expect(
             includeMaxPreReleaseRange
-                .intersect(VersionConstraint.parse(">=2.0.0-dev")),
-            equals(VersionConstraint.parse(">=2.0.0-dev <2.0.0")));
+                .intersect(VersionConstraint.parse('>=2.0.0-dev')),
+            equals(VersionConstraint.parse('>=2.0.0-dev <2.0.0')));
       });
 
       test(
-          "and a range with a pre-release max, returns "
-          "the narrower constraint", () {
+          'and a range with a pre-release max, returns '
+          'the narrower constraint', () {
         expect(
             includeMaxPreReleaseRange
-                .intersect(VersionConstraint.parse("<2.0.0-dev")),
-            equals(VersionConstraint.parse("<2.0.0-dev")));
+                .intersect(VersionConstraint.parse('<2.0.0-dev')),
+            equals(VersionConstraint.parse('<2.0.0-dev')));
       });
     });
   });
 
   group('union()', () {
-    test("with a version returns the range if it contains the version", () {
+    test('with a version returns the range if it contains the version', () {
       var range = VersionRange(min: v114, max: v124);
       expect(range.union(v123), equals(range));
     });
 
-    test("with a version on the edge of the range, expands the range", () {
+    test('with a version on the edge of the range, expands the range', () {
       expect(
           VersionRange(min: v114, max: v124, alwaysIncludeMaxPreRelease: true)
               .union(v124),
@@ -546,7 +546,7 @@
     });
 
     test(
-        "with a version allows both the range and the version if the range "
+        'with a version allows both the range and the version if the range '
         "doesn't contain the version", () {
       var result = VersionRange(min: v003, max: v114).union(v124);
       expect(result, allows(v010));
@@ -554,7 +554,7 @@
       expect(result, allows(v124));
     });
 
-    test("returns a VersionUnion for a disjoint range", () {
+    test('returns a VersionUnion for a disjoint range', () {
       var result = VersionRange(min: v003, max: v114)
           .union(VersionRange(min: v130, max: v200));
       expect(result, allows(v080));
@@ -562,7 +562,7 @@
       expect(result, allows(v140));
     });
 
-    test("considers open ranges disjoint", () {
+    test('considers open ranges disjoint', () {
       var result = VersionRange(min: v003, max: v114)
           .union(VersionRange(min: v114, max: v200));
       expect(result, allows(v080));
@@ -576,13 +576,13 @@
       expect(result, allows(v140));
     });
 
-    test("returns a merged range for an overlapping range", () {
+    test('returns a merged range for an overlapping range', () {
       var result = VersionRange(min: v003, max: v114)
           .union(VersionRange(min: v080, max: v200));
       expect(result, equals(VersionRange(min: v003, max: v200)));
     });
 
-    test("considers closed ranges overlapping", () {
+    test('considers closed ranges overlapping', () {
       var result = VersionRange(min: v003, max: v114, includeMax: true)
           .union(VersionRange(min: v114, max: v200));
       expect(result, equals(VersionRange(min: v003, max: v200)));
@@ -601,7 +601,7 @@
       expect(result, equals(VersionRange(min: v003, max: v200)));
     });
 
-    test("includes edges if either range does", () {
+    test('includes edges if either range does', () {
       var result = VersionRange(min: v003, max: v114, includeMin: true)
           .union(VersionRange(min: v003, max: v114, includeMax: true));
       expect(
@@ -610,69 +610,69 @@
               min: v003, max: v114, includeMin: true, includeMax: true)));
     });
 
-    test("with a range with a pre-release min, returns a constraint with a gap",
+    test('with a range with a pre-release min, returns a constraint with a gap',
         () {
       var result =
-          VersionRange(max: v200).union(VersionConstraint.parse(">=2.0.0-dev"));
+          VersionRange(max: v200).union(VersionConstraint.parse('>=2.0.0-dev'));
       expect(result, allows(v140));
-      expect(result, doesNotAllow(Version.parse("2.0.0-alpha")));
-      expect(result, allows(Version.parse("2.0.0-dev")));
-      expect(result, allows(Version.parse("2.0.0-dev.1")));
-      expect(result, allows(Version.parse("2.0.0")));
+      expect(result, doesNotAllow(Version.parse('2.0.0-alpha')));
+      expect(result, allows(Version.parse('2.0.0-dev')));
+      expect(result, allows(Version.parse('2.0.0-dev.1')));
+      expect(result, allows(Version.parse('2.0.0')));
     });
 
-    test("with a range with a pre-release max, returns the larger constraint",
+    test('with a range with a pre-release max, returns the larger constraint',
         () {
       expect(
-          VersionRange(max: v200).union(VersionConstraint.parse("<2.0.0-dev")),
-          equals(VersionConstraint.parse("<2.0.0-dev")));
+          VersionRange(max: v200).union(VersionConstraint.parse('<2.0.0-dev')),
+          equals(VersionConstraint.parse('<2.0.0-dev')));
     });
 
-    group("with includeMaxPreRelease", () {
+    group('with includeMaxPreRelease', () {
       test('adds includeMaxPreRelease if the max version is included', () {
         expect(
-            includeMaxPreReleaseRange.union(VersionConstraint.parse("<1.0.0")),
+            includeMaxPreReleaseRange.union(VersionConstraint.parse('<1.0.0')),
             equals(includeMaxPreReleaseRange));
         expect(includeMaxPreReleaseRange.union(includeMaxPreReleaseRange),
             equals(includeMaxPreReleaseRange));
         expect(
-            includeMaxPreReleaseRange.union(VersionConstraint.parse("<2.0.0")),
+            includeMaxPreReleaseRange.union(VersionConstraint.parse('<2.0.0')),
             equals(includeMaxPreReleaseRange));
         expect(
-            includeMaxPreReleaseRange.union(VersionConstraint.parse("<3.0.0")),
-            equals(VersionConstraint.parse("<3.0.0")));
+            includeMaxPreReleaseRange.union(VersionConstraint.parse('<3.0.0')),
+            equals(VersionConstraint.parse('<3.0.0')));
       });
 
-      test("and a range with a pre-release min, returns any", () {
+      test('and a range with a pre-release min, returns any', () {
         expect(
             includeMaxPreReleaseRange
-                .union(VersionConstraint.parse(">=2.0.0-dev")),
+                .union(VersionConstraint.parse('>=2.0.0-dev')),
             equals(VersionConstraint.any));
       });
 
-      test("and a range with a pre-release max, returns the original", () {
+      test('and a range with a pre-release max, returns the original', () {
         expect(
             includeMaxPreReleaseRange
-                .union(VersionConstraint.parse("<2.0.0-dev")),
+                .union(VersionConstraint.parse('<2.0.0-dev')),
             equals(includeMaxPreReleaseRange));
       });
     });
   });
 
   group('difference()', () {
-    test("with an empty range returns the original range", () {
+    test('with an empty range returns the original range', () {
       expect(
           VersionRange(min: v003, max: v114)
               .difference(VersionConstraint.empty),
           equals(VersionRange(min: v003, max: v114)));
     });
 
-    test("with a version outside the range returns the original range", () {
+    test('with a version outside the range returns the original range', () {
       expect(VersionRange(min: v003, max: v114).difference(v200),
           equals(VersionRange(min: v003, max: v114)));
     });
 
-    test("with a version in the range splits the range", () {
+    test('with a version in the range splits the range', () {
       expect(
           VersionRange(min: v003, max: v114).difference(v072),
           equals(VersionConstraint.unionOf([
@@ -682,43 +682,43 @@
           ])));
     });
 
-    test("with the max version makes the max exclusive", () {
+    test('with the max version makes the max exclusive', () {
       expect(
           VersionRange(min: v003, max: v114, includeMax: true).difference(v114),
           equals(VersionRange(
               min: v003, max: v114, alwaysIncludeMaxPreRelease: true)));
     });
 
-    test("with the min version makes the min exclusive", () {
+    test('with the min version makes the min exclusive', () {
       expect(
           VersionRange(min: v003, max: v114, includeMin: true).difference(v003),
           equals(VersionRange(min: v003, max: v114)));
     });
 
-    test("with a disjoint range returns the original", () {
+    test('with a disjoint range returns the original', () {
       expect(
           VersionRange(min: v003, max: v114)
               .difference(VersionRange(min: v123, max: v140)),
           equals(VersionRange(min: v003, max: v114)));
     });
 
-    test("with an adjacent range returns the original", () {
+    test('with an adjacent range returns the original', () {
       expect(
           VersionRange(min: v003, max: v114, includeMax: true)
               .difference(VersionRange(min: v114, max: v140)),
           equals(VersionRange(min: v003, max: v114, includeMax: true)));
     });
 
-    test("with a range at the beginning cuts off the beginning of the range",
+    test('with a range at the beginning cuts off the beginning of the range',
         () {
       expect(
           VersionRange(min: v080, max: v130)
               .difference(VersionRange(min: v010, max: v114)),
-          equals(VersionConstraint.parse(">=1.1.4-0 <1.3.0")));
+          equals(VersionConstraint.parse('>=1.1.4-0 <1.3.0')));
       expect(
           VersionRange(min: v080, max: v130)
               .difference(VersionRange(max: v114)),
-          equals(VersionConstraint.parse(">=1.1.4-0 <1.3.0")));
+          equals(VersionConstraint.parse('>=1.1.4-0 <1.3.0')));
       expect(
           VersionRange(min: v080, max: v130)
               .difference(VersionRange(min: v010, max: v114, includeMax: true)),
@@ -730,10 +730,10 @@
       expect(
           VersionRange(min: v080, max: v130, includeMax: true)
               .difference(VersionRange(min: v080, max: v130)),
-          equals(VersionConstraint.parse(">=1.3.0-0 <=1.3.0")));
+          equals(VersionConstraint.parse('>=1.3.0-0 <=1.3.0')));
     });
 
-    test("with a range at the end cuts off the end of the range", () {
+    test('with a range at the end cuts off the end of the range', () {
       expect(
           VersionRange(min: v080, max: v130)
               .difference(VersionRange(min: v114, max: v140)),
@@ -758,17 +758,17 @@
           equals(v080));
     });
 
-    test("with a range in the middle cuts the range in half", () {
+    test('with a range in the middle cuts the range in half', () {
       expect(
           VersionRange(min: v003, max: v130)
               .difference(VersionRange(min: v072, max: v114)),
           equals(VersionConstraint.unionOf([
             VersionRange(min: v003, max: v072, includeMax: true),
-            VersionConstraint.parse(">=1.1.4-0 <1.3.0")
+            VersionConstraint.parse('>=1.1.4-0 <1.3.0')
           ])));
     });
 
-    test("with a totally covering range returns empty", () {
+    test('with a totally covering range returns empty', () {
       expect(
           VersionRange(min: v114, max: v200)
               .difference(VersionRange(min: v072, max: v300)),
@@ -786,24 +786,24 @@
 
     test(
         "with a version union that doesn't cover the range, returns the "
-        "original", () {
+        'original', () {
       expect(
           VersionRange(min: v114, max: v140)
               .difference(VersionConstraint.unionOf([v010, v200])),
           equals(VersionRange(min: v114, max: v140)));
     });
 
-    test("with a version union that intersects the ends, chops them off", () {
+    test('with a version union that intersects the ends, chops them off', () {
       expect(
           VersionRange(min: v114, max: v140).difference(
               VersionConstraint.unionOf([
             VersionRange(min: v080, max: v123),
             VersionRange(min: v130, max: v200)
           ])),
-          equals(VersionConstraint.parse(">=1.2.3-0 <=1.3.0")));
+          equals(VersionConstraint.parse('>=1.2.3-0 <=1.3.0')));
     });
 
-    test("with a version union that intersects the middle, chops it up", () {
+    test('with a version union that intersects the middle, chops it up', () {
       expect(
           VersionRange(min: v114, max: v140)
               .difference(VersionConstraint.unionOf([v123, v124, v130])),
@@ -818,42 +818,42 @@
           ])));
     });
 
-    test("with a version union that covers the whole range, returns empty", () {
+    test('with a version union that covers the whole range, returns empty', () {
       expect(
           VersionRange(min: v114, max: v140).difference(
               VersionConstraint.unionOf([v003, VersionRange(min: v010)])),
           equals(VersionConstraint.empty));
     });
 
-    test("with a range with a pre-release min, returns the original", () {
+    test('with a range with a pre-release min, returns the original', () {
       expect(
           VersionRange(max: v200)
-              .difference(VersionConstraint.parse(">=2.0.0-dev")),
+              .difference(VersionConstraint.parse('>=2.0.0-dev')),
           equals(VersionRange(max: v200)));
     });
 
-    test("with a range with a pre-release max, returns null", () {
+    test('with a range with a pre-release max, returns null', () {
       expect(
           VersionRange(max: v200)
-              .difference(VersionConstraint.parse("<2.0.0-dev")),
+              .difference(VersionConstraint.parse('<2.0.0-dev')),
           equals(VersionConstraint.empty));
     });
 
-    group("with includeMaxPreRelease", () {
-      group("for the minuend", () {
-        test("preserves includeMaxPreRelease if the max version is included",
+    group('with includeMaxPreRelease', () {
+      group('for the minuend', () {
+        test('preserves includeMaxPreRelease if the max version is included',
             () {
           expect(
               includeMaxPreReleaseRange
-                  .difference(VersionConstraint.parse("<1.0.0")),
+                  .difference(VersionConstraint.parse('<1.0.0')),
               equals(VersionRange(
-                  min: Version.parse("1.0.0-0"),
+                  min: Version.parse('1.0.0-0'),
                   max: v200,
                   includeMin: true,
                   alwaysIncludeMaxPreRelease: true)));
           expect(
               includeMaxPreReleaseRange
-                  .difference(VersionConstraint.parse("<2.0.0")),
+                  .difference(VersionConstraint.parse('<2.0.0')),
               equals(VersionRange(
                   min: v200.firstPreRelease,
                   max: v200,
@@ -864,50 +864,50 @@
               equals(VersionConstraint.empty));
           expect(
               includeMaxPreReleaseRange
-                  .difference(VersionConstraint.parse("<3.0.0")),
+                  .difference(VersionConstraint.parse('<3.0.0')),
               equals(VersionConstraint.empty));
         });
 
-        test("with a range with a pre-release min, adjusts the max", () {
+        test('with a range with a pre-release min, adjusts the max', () {
           expect(
               includeMaxPreReleaseRange
-                  .difference(VersionConstraint.parse(">=2.0.0-dev")),
-              equals(VersionConstraint.parse("<2.0.0-dev")));
+                  .difference(VersionConstraint.parse('>=2.0.0-dev')),
+              equals(VersionConstraint.parse('<2.0.0-dev')));
         });
 
-        test("with a range with a pre-release max, adjusts the min", () {
+        test('with a range with a pre-release max, adjusts the min', () {
           expect(
               includeMaxPreReleaseRange
-                  .difference(VersionConstraint.parse("<2.0.0-dev")),
-              equals(VersionConstraint.parse(">=2.0.0-dev <2.0.0")));
+                  .difference(VersionConstraint.parse('<2.0.0-dev')),
+              equals(VersionConstraint.parse('>=2.0.0-dev <2.0.0')));
         });
       });
 
-      group("for the subtrahend", () {
+      group('for the subtrahend', () {
         group("doesn't create a pre-release minimum", () {
-          test("when cutting off the bottom", () {
+          test('when cutting off the bottom', () {
             expect(
-                VersionConstraint.parse("<3.0.0")
+                VersionConstraint.parse('<3.0.0')
                     .difference(includeMaxPreReleaseRange),
                 equals(VersionRange(min: v200, max: v300, includeMin: true)));
           });
 
-          test("with splitting down the middle", () {
+          test('with splitting down the middle', () {
             expect(
-                VersionConstraint.parse("<4.0.0").difference(VersionRange(
+                VersionConstraint.parse('<4.0.0').difference(VersionRange(
                     min: v200,
                     max: v300,
                     includeMin: true,
                     alwaysIncludeMaxPreRelease: true)),
                 equals(VersionConstraint.unionOf([
                   VersionRange(max: v200, alwaysIncludeMaxPreRelease: true),
-                  VersionConstraint.parse(">=3.0.0 <4.0.0")
+                  VersionConstraint.parse('>=3.0.0 <4.0.0')
                 ])));
           });
 
-          test("can leave a single version", () {
+          test('can leave a single version', () {
             expect(
-                VersionConstraint.parse("<=2.0.0")
+                VersionConstraint.parse('<=2.0.0')
                     .difference(includeMaxPreReleaseRange),
                 equals(v200));
           });
@@ -922,7 +922,7 @@
   });
 
   group('compareTo()', () {
-    test("orders by minimum first", () {
+    test('orders by minimum first', () {
       _expectComparesSmaller(VersionRange(min: v003, max: v080),
           VersionRange(min: v010, max: v072));
       _expectComparesSmaller(VersionRange(min: v003, max: v080),
@@ -931,36 +931,36 @@
           VersionRange(min: v010, max: v114));
     });
 
-    test("orders by maximum second", () {
+    test('orders by maximum second', () {
       _expectComparesSmaller(VersionRange(min: v003, max: v010),
           VersionRange(min: v003, max: v072));
     });
 
-    test("includeMin comes before !includeMin", () {
+    test('includeMin comes before !includeMin', () {
       _expectComparesSmaller(
           VersionRange(min: v003, max: v080, includeMin: true),
           VersionRange(min: v003, max: v080, includeMin: false));
     });
 
-    test("includeMax comes after !includeMax", () {
+    test('includeMax comes after !includeMax', () {
       _expectComparesSmaller(
           VersionRange(min: v003, max: v080, includeMax: false),
           VersionRange(min: v003, max: v080, includeMax: true));
     });
 
-    test("includeMaxPreRelease comes after !includeMaxPreRelease", () {
+    test('includeMaxPreRelease comes after !includeMaxPreRelease', () {
       _expectComparesSmaller(
           VersionRange(max: v200), includeMaxPreReleaseRange);
     });
 
-    test("no minimum comes before small minimum", () {
+    test('no minimum comes before small minimum', () {
       _expectComparesSmaller(
           VersionRange(max: v010), VersionRange(min: v003, max: v010));
       _expectComparesSmaller(VersionRange(max: v010, includeMin: true),
           VersionRange(min: v003, max: v010));
     });
 
-    test("no maximium comes after large maximum", () {
+    test('no maximium comes after large maximum', () {
       _expectComparesSmaller(
           VersionRange(min: v003, max: v300), VersionRange(min: v003));
       _expectComparesSmaller(VersionRange(min: v003, max: v300),
@@ -971,7 +971,7 @@
 
 void _expectComparesSmaller(VersionRange smaller, VersionRange larger) {
   expect(smaller.compareTo(larger), lessThan(0),
-      reason: "expected $smaller to sort below $larger");
+      reason: 'expected $smaller to sort below $larger');
   expect(larger.compareTo(smaller), greaterThan(0),
-      reason: "expected $larger to sort above $smaller");
+      reason: 'expected $larger to sort above $smaller');
 }
diff --git a/test/version_test.dart b/test/version_test.dart
index 634148b..df0d25b 100644
--- a/test/version_test.dart
+++ b/test/version_test.dart
@@ -167,11 +167,11 @@
   });
 
   group('union()', () {
-    test("with the same version returns the version", () {
+    test('with the same version returns the version', () {
       expect(v123.union(v123), equals(v123));
     });
 
-    test("with a different version returns a version that matches both", () {
+    test('with a different version returns a version that matches both', () {
       var result = v123.union(v080);
       expect(result, allows(v123));
       expect(result, allows(v080));
@@ -180,12 +180,12 @@
       expect(result, doesNotAllow(v114));
     });
 
-    test("with a range returns the range if it contains the version", () {
+    test('with a range returns the range if it contains the version', () {
       var range = VersionRange(min: v114, max: v124);
       expect(v123.union(range), equals(range));
     });
 
-    test("with a range with the version on the edge, expands the range", () {
+    test('with a range with the version on the edge, expands the range', () {
       expect(
           v124.union(VersionRange(
               min: v114, max: v124, alwaysIncludeMaxPreRelease: true)),
@@ -199,7 +199,7 @@
     });
 
     test(
-        "with a range allows both the range and the version if the range "
+        'with a range allows both the range and the version if the range '
         "doesn't contain the version", () {
       var result = v123.union(VersionRange(min: v003, max: v114));
       expect(result, allows(v123));
@@ -208,15 +208,15 @@
   });
 
   group('difference()', () {
-    test("with the same version returns an empty constraint", () {
+    test('with the same version returns an empty constraint', () {
       expect(v123.difference(v123), isEmpty);
     });
 
-    test("with a different version returns the original version", () {
+    test('with a different version returns the original version', () {
       expect(v123.difference(v080), equals(v123));
     });
 
-    test("returns an empty constraint with a range that contains the version",
+    test('returns an empty constraint with a range that contains the version',
         () {
       expect(v123.difference(VersionRange(min: v114, max: v124)), isEmpty);
     });
diff --git a/test/version_union_test.dart b/test/version_union_test.dart
index 11a5ecd..89f9a85 100644
--- a/test/version_union_test.dart
+++ b/test/version_union_test.dart
@@ -82,7 +82,7 @@
           ])));
     });
 
-    test("merges overlapping ranges", () {
+    test('merges overlapping ranges', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v003, max: v072),
@@ -96,7 +96,7 @@
           ])));
     });
 
-    test("merges adjacent ranges", () {
+    test('merges adjacent ranges', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v003, max: v072, includeMax: true),
@@ -128,7 +128,7 @@
           isNot(equals(VersionRange(min: v003, max: v080))));
     });
 
-    test("merges version numbers into ranges", () {
+    test('merges version numbers into ranges', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v003, max: v072),
@@ -142,7 +142,7 @@
           ])));
     });
 
-    test("merges adjacent version numbers into ranges", () {
+    test('merges adjacent version numbers into ranges', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(
@@ -319,7 +319,7 @@
             isTrue);
       });
 
-      test("returns false if no constraint matches", () {
+      test('returns false if no constraint matches', () {
         expect(
             union.allowsAny(VersionConstraint.unionOf([
               v003,
@@ -331,8 +331,8 @@
     });
   });
 
-  group("intersect()", () {
-    test("with an overlapping version, returns that version", () {
+  group('intersect()', () {
+    test('with an overlapping version, returns that version', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v010, max: v080),
@@ -341,7 +341,7 @@
           equals(v072));
     });
 
-    test("with a non-overlapping version, returns an empty constraint", () {
+    test('with a non-overlapping version, returns an empty constraint', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v010, max: v080),
@@ -350,7 +350,7 @@
           isEmpty);
     });
 
-    test("with an overlapping range, returns that range", () {
+    test('with an overlapping range, returns that range', () {
       var range = VersionRange(min: v072, max: v080);
       expect(
           VersionConstraint.unionOf([
@@ -360,7 +360,7 @@
           equals(range));
     });
 
-    test("with a non-overlapping range, returns an empty constraint", () {
+    test('with a non-overlapping range, returns an empty constraint', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v010, max: v080),
@@ -369,7 +369,7 @@
           isEmpty);
     });
 
-    test("with a parially-overlapping range, returns the overlapping parts",
+    test('with a parially-overlapping range, returns the overlapping parts',
         () {
       expect(
           VersionConstraint.unionOf([
@@ -382,13 +382,13 @@
           ])));
     });
 
-    group("for a union,", () {
+    group('for a union,', () {
       var union = VersionConstraint.unionOf([
         VersionRange(min: v003, max: v080),
         VersionRange(min: v123, max: v130)
       ]);
 
-      test("returns the overlapping parts", () {
+      test('returns the overlapping parts', () {
         expect(
             union.intersect(VersionConstraint.unionOf([
               v010,
@@ -415,7 +415,7 @@
     });
   });
 
-  group("difference()", () {
+  group('difference()', () {
     test("ignores ranges that don't intersect", () {
       expect(
           VersionConstraint.unionOf([
@@ -432,7 +432,7 @@
           ])));
     });
 
-    test("removes overlapping portions", () {
+    test('removes overlapping portions', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v010, max: v080),
@@ -446,7 +446,7 @@
           ])));
     });
 
-    test("removes multiple portions from the same range", () {
+    test('removes multiple portions from the same range', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v010, max: v114),
@@ -462,7 +462,7 @@
           ])));
     });
 
-    test("removes the same range from multiple ranges", () {
+    test('removes the same range from multiple ranges', () {
       expect(
           VersionConstraint.unionOf([
             VersionRange(min: v010, max: v072),