From 8e684a8f6124a9318370094391ed982c26ea716a Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Mon, 10 Feb 2025 18:11:21 -0600 Subject: [PATCH 01/14] [package_config] Implement relational operators for LanguageVersion --- pkgs/package_config/CHANGELOG.md | 2 + .../lib/package_config_types.dart | 7 ++- .../lib/src/package_config.dart | 17 +++++ pkgs/package_config/pubspec.yaml | 2 +- .../test/package_config_impl_test.dart | 62 +++++++++++++++++++ 5 files changed, 88 insertions(+), 2 deletions(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 101a0fe760..3848a39b49 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,3 +1,5 @@ +## 2.2.0-wip + ## 2.1.1 - Require Dart 3.4 diff --git a/pkgs/package_config/lib/package_config_types.dart b/pkgs/package_config/lib/package_config_types.dart index 825f7acec9..5c2c3413c4 100644 --- a/pkgs/package_config/lib/package_config_types.dart +++ b/pkgs/package_config/lib/package_config_types.dart @@ -14,4 +14,9 @@ library; export 'src/errors.dart' show PackageConfigError; export 'src/package_config.dart' - show InvalidLanguageVersion, LanguageVersion, Package, PackageConfig; + show + InvalidLanguageVersion, + LanguageVersion, + LanguageVersionRelationalOperators, + Package, + PackageConfig; diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 155dfc5393..9b457226f5 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -400,3 +400,20 @@ abstract class InvalidLanguageVersion implements LanguageVersion { @override String toString(); } + +/// Relational operators for [LanguageVersion] that match +/// the behavior specified by [LanguageVersion.compareTo]. +// TODO(v3): Consider declaring on LanguageVersion class. +extension LanguageVersionRelationalOperators on LanguageVersion { + /// If this language version is less than [other]. + bool operator <(LanguageVersion other) => compareTo(other) < 0; + + /// If this language version is greater than [other]. + bool operator >(LanguageVersion other) => compareTo(other) > 0; + + /// If this language version is less than or equal to [other]. + bool operator <=(LanguageVersion other) => compareTo(other) <= 0; + + /// If this language version is greater than or equal to [other]. + bool operator >=(LanguageVersion other) => compareTo(other) >= 0; +} diff --git a/pkgs/package_config/pubspec.yaml b/pkgs/package_config/pubspec.yaml index 634d71050a..d3a1c7d382 100644 --- a/pkgs/package_config/pubspec.yaml +++ b/pkgs/package_config/pubspec.yaml @@ -1,5 +1,5 @@ name: package_config -version: 2.1.1 +version: 2.2.0-wip description: Support for reading and writing Dart Package Configuration files. repository: https://github.com/dart-lang/tools/tree/main/pkgs/package_config issue_tracker: https://github.com/dart-lang/tools/labels/package%3Apackage_config diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 0f399636ff..5012fb3c83 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -57,6 +57,68 @@ void main() { failParse('WhiteSpace 2', '1 .1'); failParse('WhiteSpace 3', '1. 1'); failParse('WhiteSpace 4', '1.1 '); + + test('compareTo valid', () { + var version = LanguageVersion(3, 5); + var sameVersion = LanguageVersion(3, 5); + var sameMajorLowerMinorVersion = LanguageVersion(3, 4); + var lowerMajorSameMinorVersion = LanguageVersion(2, 5); + var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); + var greaterMajorSameMinorVersion = LanguageVersion(4, 5); + + expect(version.compareTo(sameVersion), isZero); + expect(sameVersion.compareTo(version), isZero); + + expect(version.compareTo(sameMajorLowerMinorVersion), isPositive); + expect(version.compareTo(lowerMajorSameMinorVersion), isPositive); + + expect(version.compareTo(sameMajorGreaterMinorVersion), isNegative); + expect(version.compareTo(greaterMajorSameMinorVersion), isNegative); + }); + + test('compareTo invalid', () { + var validVersion = LanguageVersion(3, 5); + var invalidVersion = LanguageVersion.parse('', onError: (_) {}); + + expect(validVersion.compareTo(invalidVersion), isPositive); + expect(invalidVersion.compareTo(validVersion), isNegative); + }); + + test('relational valid', () { + var version = LanguageVersion(3, 5); + var sameVersion = LanguageVersion(3, 5); + var sameMajorLowerMinorVersion = LanguageVersion(3, 4); + var lowerMajorSameMinorVersion = LanguageVersion(2, 5); + var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); + var greaterMajorSameMinorVersion = LanguageVersion(4, 5); + + expect(version == sameVersion, isTrue); + expect(sameVersion == version, isTrue); + + expect(version > sameVersion, isFalse); + expect(version > sameMajorLowerMinorVersion, isTrue); + expect(version > lowerMajorSameMinorVersion, isTrue); + expect(version > sameMajorGreaterMinorVersion, isFalse); + expect(version > greaterMajorSameMinorVersion, isFalse); + + expect(version >= sameVersion, isTrue); + expect(version >= sameMajorLowerMinorVersion, isTrue); + expect(version >= lowerMajorSameMinorVersion, isTrue); + expect(version >= sameMajorGreaterMinorVersion, isFalse); + expect(version >= greaterMajorSameMinorVersion, isFalse); + + expect(version < sameVersion, isFalse); + expect(version < sameMajorLowerMinorVersion, isFalse); + expect(version < lowerMajorSameMinorVersion, isFalse); + expect(version < sameMajorGreaterMinorVersion, isTrue); + expect(version < greaterMajorSameMinorVersion, isTrue); + + expect(version <= sameVersion, isTrue); + expect(version <= sameMajorLowerMinorVersion, isFalse); + expect(version <= lowerMajorSameMinorVersion, isFalse); + expect(version <= sameMajorGreaterMinorVersion, isTrue); + expect(version <= greaterMajorSameMinorVersion, isTrue); + }); }); group('Package', () { From ccd36d8d49a6f7c4a90f4475c647462753427224 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 16:47:12 -0600 Subject: [PATCH 02/14] Use 'Whether' to begin doc comments --- .../lib/src/package_config.dart | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 9b457226f5..ae28bc49d4 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -405,15 +405,27 @@ abstract class InvalidLanguageVersion implements LanguageVersion { /// the behavior specified by [LanguageVersion.compareTo]. // TODO(v3): Consider declaring on LanguageVersion class. extension LanguageVersionRelationalOperators on LanguageVersion { - /// If this language version is less than [other]. + /// Whether this language version is less than [other]. + /// + /// For details on how language versions are compared, + /// see [LanguageVersion.compareTo]. bool operator <(LanguageVersion other) => compareTo(other) < 0; - /// If this language version is greater than [other]. + /// Whether this language version is greater than [other]. + /// + /// For details on how language versions are compared, + /// see [LanguageVersion.compareTo]. bool operator >(LanguageVersion other) => compareTo(other) > 0; - /// If this language version is less than or equal to [other]. + /// Whether this language version is less than or equal to [other]. + /// + /// For details on how language versions are compared, + /// see [LanguageVersion.compareTo]. bool operator <=(LanguageVersion other) => compareTo(other) <= 0; - /// If this language version is greater than or equal to [other]. + /// Whether this language version is greater than or equal to [other]. + /// + /// For details on how language versions are compared, + /// see [LanguageVersion.compareTo]. bool operator >=(LanguageVersion other) => compareTo(other) >= 0; } From 713303833364ea8d248ef3cd4927c359c0c2a0f1 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 18:44:24 -0600 Subject: [PATCH 03/14] Account for instance equality of InvalidLanguageVersion --- .../lib/src/package_config.dart | 79 +++++++++++++++---- .../test/package_config_impl_test.dart | 30 +++++++ 2 files changed, 95 insertions(+), 14 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index ae28bc49d4..536dc5cb94 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -401,31 +401,82 @@ abstract class InvalidLanguageVersion implements LanguageVersion { String toString(); } -/// Relational operators for [LanguageVersion] that match -/// the behavior specified by [LanguageVersion.compareTo]. +/// Relational operators for [LanguageVersion] that +/// compare versions with [LanguageVersion.compareTo]. +/// +/// An [InvalidLanguageVersion] is not less or greater than other versions +/// and is only equal to itself. // TODO(v3): Consider declaring on LanguageVersion class. extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is less than [other]. /// - /// For details on how language versions are compared, - /// see [LanguageVersion.compareTo]. - bool operator <(LanguageVersion other) => compareTo(other) < 0; + /// If either version is an [InvalidLanguageVersion], returns `false`. + /// + /// For details on how valid language versions are compared, + /// check out [LanguageVersion.compareTo]. + bool operator <(LanguageVersion other) { + // Account for invalid language versions which aren't + // greater or less than any other version. + if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { + return false; + } + + return compareTo(other) < 0; + } /// Whether this language version is greater than [other]. /// - /// For details on how language versions are compared, - /// see [LanguageVersion.compareTo]. - bool operator >(LanguageVersion other) => compareTo(other) > 0; + /// If either version is an [InvalidLanguageVersion], returns `false`. + /// + /// For details on how valid language versions are compared, + /// check out [LanguageVersion.compareTo]. + bool operator >(LanguageVersion other) { + // Account for invalid language versions which aren't + // greater or less than any other version. + if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { + return false; + } + + return compareTo(other) > 0; + } /// Whether this language version is less than or equal to [other]. /// - /// For details on how language versions are compared, - /// see [LanguageVersion.compareTo]. - bool operator <=(LanguageVersion other) => compareTo(other) <= 0; + /// If either version is an [InvalidLanguageVersion], + /// returns whether they are the same object. + /// + /// For details on how valid language versions are compared, + /// check out [LanguageVersion.compareTo]. + bool operator <=(LanguageVersion other) { + // Account for invalid language versions only being equal to themselves. + if (identical(this, other)) { + return true; + } + + if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { + return false; + } + + return compareTo(other) <= 0; + } /// Whether this language version is greater than or equal to [other]. /// - /// For details on how language versions are compared, - /// see [LanguageVersion.compareTo]. - bool operator >=(LanguageVersion other) => compareTo(other) >= 0; + /// If either version is an [InvalidLanguageVersion], + /// returns whether they are the same object. + /// + /// For details on how valid language versions are compared, + /// check out [LanguageVersion.compareTo]. + bool operator >=(LanguageVersion other) { + // Account for invalid language versions only being equal to themselves. + if (identical(this, other)) { + return true; + } + + if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { + return false; + } + + return compareTo(other) >= 0; + } } diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 5012fb3c83..05301e8200 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -119,6 +119,36 @@ void main() { expect(version <= sameMajorGreaterMinorVersion, isTrue); expect(version <= greaterMajorSameMinorVersion, isTrue); }); + + test('relational invalid', () { + var validVersion = LanguageVersion(3, 5); + var invalidVersion = LanguageVersion.parse('', onError: (_) {}); + var differentInvalidVersion = LanguageVersion.parse('-', onError: (_) {}); + + expect(validVersion == invalidVersion, false); + expect(invalidVersion == invalidVersion, true); + expect(invalidVersion == differentInvalidVersion, false); + + expect(validVersion > invalidVersion, false); + expect(invalidVersion > validVersion, false); + expect(invalidVersion > invalidVersion, false); + expect(invalidVersion > differentInvalidVersion, false); + + expect(validVersion >= invalidVersion, false); + expect(invalidVersion >= validVersion, false); + expect(invalidVersion >= invalidVersion, true); + expect(invalidVersion >= differentInvalidVersion, false); + + expect(validVersion < invalidVersion, false); + expect(invalidVersion < validVersion, false); + expect(invalidVersion < invalidVersion, false); + expect(invalidVersion < differentInvalidVersion, false); + + expect(validVersion <= invalidVersion, false); + expect(invalidVersion <= validVersion, false); + expect(invalidVersion <= invalidVersion, true); + expect(invalidVersion <= differentInvalidVersion, false); + }); }); group('Package', () { From 3bea0f9d9d555222e8f311e63d06b0754d2f5e2b Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 18:48:19 -0600 Subject: [PATCH 04/14] Consistently sort the operator declarations and their tests --- .../lib/src/package_config.dart | 32 +++++++------- .../test/package_config_impl_test.dart | 44 +++++++++---------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 536dc5cb94..3f3829a9b3 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -424,22 +424,6 @@ extension LanguageVersionRelationalOperators on LanguageVersion { return compareTo(other) < 0; } - /// Whether this language version is greater than [other]. - /// - /// If either version is an [InvalidLanguageVersion], returns `false`. - /// - /// For details on how valid language versions are compared, - /// check out [LanguageVersion.compareTo]. - bool operator >(LanguageVersion other) { - // Account for invalid language versions which aren't - // greater or less than any other version. - if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { - return false; - } - - return compareTo(other) > 0; - } - /// Whether this language version is less than or equal to [other]. /// /// If either version is an [InvalidLanguageVersion], @@ -460,6 +444,22 @@ extension LanguageVersionRelationalOperators on LanguageVersion { return compareTo(other) <= 0; } + /// Whether this language version is greater than [other]. + /// + /// If either version is an [InvalidLanguageVersion], returns `false`. + /// + /// For details on how valid language versions are compared, + /// check out [LanguageVersion.compareTo]. + bool operator >(LanguageVersion other) { + // Account for invalid language versions which aren't + // greater or less than any other version. + if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { + return false; + } + + return compareTo(other) > 0; + } + /// Whether this language version is greater than or equal to [other]. /// /// If either version is an [InvalidLanguageVersion], diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 05301e8200..e96578d486 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -95,18 +95,6 @@ void main() { expect(version == sameVersion, isTrue); expect(sameVersion == version, isTrue); - expect(version > sameVersion, isFalse); - expect(version > sameMajorLowerMinorVersion, isTrue); - expect(version > lowerMajorSameMinorVersion, isTrue); - expect(version > sameMajorGreaterMinorVersion, isFalse); - expect(version > greaterMajorSameMinorVersion, isFalse); - - expect(version >= sameVersion, isTrue); - expect(version >= sameMajorLowerMinorVersion, isTrue); - expect(version >= lowerMajorSameMinorVersion, isTrue); - expect(version >= sameMajorGreaterMinorVersion, isFalse); - expect(version >= greaterMajorSameMinorVersion, isFalse); - expect(version < sameVersion, isFalse); expect(version < sameMajorLowerMinorVersion, isFalse); expect(version < lowerMajorSameMinorVersion, isFalse); @@ -118,6 +106,18 @@ void main() { expect(version <= lowerMajorSameMinorVersion, isFalse); expect(version <= sameMajorGreaterMinorVersion, isTrue); expect(version <= greaterMajorSameMinorVersion, isTrue); + + expect(version > sameVersion, isFalse); + expect(version > sameMajorLowerMinorVersion, isTrue); + expect(version > lowerMajorSameMinorVersion, isTrue); + expect(version > sameMajorGreaterMinorVersion, isFalse); + expect(version > greaterMajorSameMinorVersion, isFalse); + + expect(version >= sameVersion, isTrue); + expect(version >= sameMajorLowerMinorVersion, isTrue); + expect(version >= lowerMajorSameMinorVersion, isTrue); + expect(version >= sameMajorGreaterMinorVersion, isFalse); + expect(version >= greaterMajorSameMinorVersion, isFalse); }); test('relational invalid', () { @@ -129,16 +129,6 @@ void main() { expect(invalidVersion == invalidVersion, true); expect(invalidVersion == differentInvalidVersion, false); - expect(validVersion > invalidVersion, false); - expect(invalidVersion > validVersion, false); - expect(invalidVersion > invalidVersion, false); - expect(invalidVersion > differentInvalidVersion, false); - - expect(validVersion >= invalidVersion, false); - expect(invalidVersion >= validVersion, false); - expect(invalidVersion >= invalidVersion, true); - expect(invalidVersion >= differentInvalidVersion, false); - expect(validVersion < invalidVersion, false); expect(invalidVersion < validVersion, false); expect(invalidVersion < invalidVersion, false); @@ -148,6 +138,16 @@ void main() { expect(invalidVersion <= validVersion, false); expect(invalidVersion <= invalidVersion, true); expect(invalidVersion <= differentInvalidVersion, false); + + expect(validVersion > invalidVersion, false); + expect(invalidVersion > validVersion, false); + expect(invalidVersion > invalidVersion, false); + expect(invalidVersion > differentInvalidVersion, false); + + expect(validVersion >= invalidVersion, false); + expect(invalidVersion >= validVersion, false); + expect(invalidVersion >= invalidVersion, true); + expect(invalidVersion >= differentInvalidVersion, false); }); }); From 9b832c9d5bf5e8d49b1d0dbd79c8022947c30dff Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 18:50:22 -0600 Subject: [PATCH 05/14] Use matchers consistent with existing tests --- .../test/package_config_impl_test.dart | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index e96578d486..5dd970c7e2 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -66,8 +66,8 @@ void main() { var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version.compareTo(sameVersion), isZero); - expect(sameVersion.compareTo(version), isZero); + expect(version.compareTo(sameVersion), 0); + expect(sameVersion.compareTo(version), 0); expect(version.compareTo(sameMajorLowerMinorVersion), isPositive); expect(version.compareTo(lowerMajorSameMinorVersion), isPositive); @@ -92,32 +92,32 @@ void main() { var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version == sameVersion, isTrue); - expect(sameVersion == version, isTrue); - - expect(version < sameVersion, isFalse); - expect(version < sameMajorLowerMinorVersion, isFalse); - expect(version < lowerMajorSameMinorVersion, isFalse); - expect(version < sameMajorGreaterMinorVersion, isTrue); - expect(version < greaterMajorSameMinorVersion, isTrue); - - expect(version <= sameVersion, isTrue); - expect(version <= sameMajorLowerMinorVersion, isFalse); - expect(version <= lowerMajorSameMinorVersion, isFalse); - expect(version <= sameMajorGreaterMinorVersion, isTrue); - expect(version <= greaterMajorSameMinorVersion, isTrue); - - expect(version > sameVersion, isFalse); - expect(version > sameMajorLowerMinorVersion, isTrue); - expect(version > lowerMajorSameMinorVersion, isTrue); - expect(version > sameMajorGreaterMinorVersion, isFalse); - expect(version > greaterMajorSameMinorVersion, isFalse); - - expect(version >= sameVersion, isTrue); - expect(version >= sameMajorLowerMinorVersion, isTrue); - expect(version >= lowerMajorSameMinorVersion, isTrue); - expect(version >= sameMajorGreaterMinorVersion, isFalse); - expect(version >= greaterMajorSameMinorVersion, isFalse); + expect(version == sameVersion, true); + expect(sameVersion == version, true); + + expect(version < sameVersion, false); + expect(version < sameMajorLowerMinorVersion, false); + expect(version < lowerMajorSameMinorVersion, false); + expect(version < sameMajorGreaterMinorVersion, true); + expect(version < greaterMajorSameMinorVersion, true); + + expect(version <= sameVersion, true); + expect(version <= sameMajorLowerMinorVersion, false); + expect(version <= lowerMajorSameMinorVersion, false); + expect(version <= sameMajorGreaterMinorVersion, true); + expect(version <= greaterMajorSameMinorVersion, true); + + expect(version > sameVersion, false); + expect(version > sameMajorLowerMinorVersion, true); + expect(version > lowerMajorSameMinorVersion, true); + expect(version > sameMajorGreaterMinorVersion, false); + expect(version > greaterMajorSameMinorVersion, false); + + expect(version >= sameVersion, true); + expect(version >= sameMajorLowerMinorVersion, true); + expect(version >= lowerMajorSameMinorVersion, true); + expect(version >= sameMajorGreaterMinorVersion, false); + expect(version >= greaterMajorSameMinorVersion, false); }); test('relational invalid', () { From 3e7629385b03ab53a2f877822a83767729ec7446 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 19:06:04 -0600 Subject: [PATCH 06/14] Add tests for identical vs equal versions --- .../test/package_config_impl_test.dart | 42 ++++++++++++------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 5dd970c7e2..a956af1829 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -60,14 +60,17 @@ void main() { test('compareTo valid', () { var version = LanguageVersion(3, 5); - var sameVersion = LanguageVersion(3, 5); + var identicalVersion = version; + var sameMajorSameMinorVersion = LanguageVersion(3, 5); var sameMajorLowerMinorVersion = LanguageVersion(3, 4); var lowerMajorSameMinorVersion = LanguageVersion(2, 5); var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version.compareTo(sameVersion), 0); - expect(sameVersion.compareTo(version), 0); + expect(version.compareTo(identicalVersion), 0); + expect(version.compareTo(sameMajorSameMinorVersion), 0); + expect(identicalVersion.compareTo(version), 0); + expect(sameMajorSameMinorVersion.compareTo(version), 0); expect(version.compareTo(sameMajorLowerMinorVersion), isPositive); expect(version.compareTo(lowerMajorSameMinorVersion), isPositive); @@ -86,34 +89,41 @@ void main() { test('relational valid', () { var version = LanguageVersion(3, 5); - var sameVersion = LanguageVersion(3, 5); + var identicalVersion = version; + var sameMajorSameMinorVersion = LanguageVersion(3, 5); var sameMajorLowerMinorVersion = LanguageVersion(3, 4); var lowerMajorSameMinorVersion = LanguageVersion(2, 5); var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version == sameVersion, true); - expect(sameVersion == version, true); + expect(version == identicalVersion, true); + expect(version == sameMajorSameMinorVersion, true); + expect(identicalVersion == version, true); + expect(sameMajorSameMinorVersion == version, true); - expect(version < sameVersion, false); + expect(version < identicalVersion, false); + expect(version < sameMajorSameMinorVersion, false); expect(version < sameMajorLowerMinorVersion, false); expect(version < lowerMajorSameMinorVersion, false); expect(version < sameMajorGreaterMinorVersion, true); expect(version < greaterMajorSameMinorVersion, true); - expect(version <= sameVersion, true); + expect(version <= identicalVersion, true); + expect(version <= sameMajorSameMinorVersion, true); expect(version <= sameMajorLowerMinorVersion, false); expect(version <= lowerMajorSameMinorVersion, false); expect(version <= sameMajorGreaterMinorVersion, true); expect(version <= greaterMajorSameMinorVersion, true); - expect(version > sameVersion, false); + expect(version > identicalVersion, false); + expect(version > sameMajorSameMinorVersion, false); expect(version > sameMajorLowerMinorVersion, true); expect(version > lowerMajorSameMinorVersion, true); expect(version > sameMajorGreaterMinorVersion, false); expect(version > greaterMajorSameMinorVersion, false); - expect(version >= sameVersion, true); + expect(version >= identicalVersion, true); + expect(version >= sameMajorSameMinorVersion, true); expect(version >= sameMajorLowerMinorVersion, true); expect(version >= lowerMajorSameMinorVersion, true); expect(version >= sameMajorGreaterMinorVersion, false); @@ -123,30 +133,32 @@ void main() { test('relational invalid', () { var validVersion = LanguageVersion(3, 5); var invalidVersion = LanguageVersion.parse('', onError: (_) {}); + var identicalInvalidVersion = invalidVersion; var differentInvalidVersion = LanguageVersion.parse('-', onError: (_) {}); expect(validVersion == invalidVersion, false); - expect(invalidVersion == invalidVersion, true); + expect(invalidVersion == validVersion, false); + expect(invalidVersion == identicalInvalidVersion, true); expect(invalidVersion == differentInvalidVersion, false); expect(validVersion < invalidVersion, false); expect(invalidVersion < validVersion, false); - expect(invalidVersion < invalidVersion, false); + expect(invalidVersion < identicalInvalidVersion, false); expect(invalidVersion < differentInvalidVersion, false); expect(validVersion <= invalidVersion, false); expect(invalidVersion <= validVersion, false); - expect(invalidVersion <= invalidVersion, true); + expect(invalidVersion <= identicalInvalidVersion, true); expect(invalidVersion <= differentInvalidVersion, false); expect(validVersion > invalidVersion, false); expect(invalidVersion > validVersion, false); - expect(invalidVersion > invalidVersion, false); + expect(invalidVersion > identicalInvalidVersion, false); expect(invalidVersion > differentInvalidVersion, false); expect(validVersion >= invalidVersion, false); expect(invalidVersion >= validVersion, false); - expect(invalidVersion >= invalidVersion, true); + expect(invalidVersion >= identicalInvalidVersion, true); expect(invalidVersion >= differentInvalidVersion, false); }); }); From 788bf44fad0699d6204b8d132db39453f56ec71b Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 19:34:54 -0600 Subject: [PATCH 07/14] Simplify tests by pulling duplication out to inline functions --- .../test/package_config_impl_test.dart | 99 +++++++------------ 1 file changed, 37 insertions(+), 62 deletions(-) diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index a956af1829..570fb4d910 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -89,77 +89,52 @@ void main() { test('relational valid', () { var version = LanguageVersion(3, 5); - var identicalVersion = version; - var sameMajorSameMinorVersion = LanguageVersion(3, 5); - var sameMajorLowerMinorVersion = LanguageVersion(3, 4); - var lowerMajorSameMinorVersion = LanguageVersion(2, 5); - var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); - var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version == identicalVersion, true); - expect(version == sameMajorSameMinorVersion, true); - expect(identicalVersion == version, true); - expect(sameMajorSameMinorVersion == version, true); - - expect(version < identicalVersion, false); - expect(version < sameMajorSameMinorVersion, false); - expect(version < sameMajorLowerMinorVersion, false); - expect(version < lowerMajorSameMinorVersion, false); - expect(version < sameMajorGreaterMinorVersion, true); - expect(version < greaterMajorSameMinorVersion, true); - - expect(version <= identicalVersion, true); - expect(version <= sameMajorSameMinorVersion, true); - expect(version <= sameMajorLowerMinorVersion, false); - expect(version <= lowerMajorSameMinorVersion, false); - expect(version <= sameMajorGreaterMinorVersion, true); - expect(version <= greaterMajorSameMinorVersion, true); - - expect(version > identicalVersion, false); - expect(version > sameMajorSameMinorVersion, false); - expect(version > sameMajorLowerMinorVersion, true); - expect(version > lowerMajorSameMinorVersion, true); - expect(version > sameMajorGreaterMinorVersion, false); - expect(version > greaterMajorSameMinorVersion, false); - - expect(version >= identicalVersion, true); - expect(version >= sameMajorSameMinorVersion, true); - expect(version >= sameMajorLowerMinorVersion, true); - expect(version >= lowerMajorSameMinorVersion, true); - expect(version >= sameMajorGreaterMinorVersion, false); - expect(version >= greaterMajorSameMinorVersion, false); + void testComparisons(LanguageVersion otherVersion) { + expect(version == otherVersion, version.compareTo(otherVersion) == 0); + + expect(version < otherVersion, version.compareTo(otherVersion) < 0); + expect(version <= otherVersion, version.compareTo(otherVersion) <= 0); + + expect(version > otherVersion, version.compareTo(otherVersion) > 0); + expect(version >= otherVersion, version.compareTo(otherVersion) >= 0); + } + + // Check that relational operator implementations match + // the results of compareTo for valid versions. + [ + version, // Identical. + LanguageVersion(3, 5), // Same major, same minor. + LanguageVersion(3, 4), // Same major, lower minor. + LanguageVersion(2, 5), // Lower major, same minor. + LanguageVersion(3, 6), // Same major, greater minor. + LanguageVersion(4, 5), // Great major, same minor. + ].forEach(testComparisons); }); test('relational invalid', () { + void testComparisonsWithInvalid( + LanguageVersion version, + LanguageVersion otherVersion, + ) { + expect(version == otherVersion, identical(version, otherVersion)); + + expect(version < otherVersion, false); + expect(version <= otherVersion, identical(version, otherVersion)); + + expect(version > otherVersion, false); + expect(version >= otherVersion, identical(version, otherVersion)); + } + var validVersion = LanguageVersion(3, 5); var invalidVersion = LanguageVersion.parse('', onError: (_) {}); var identicalInvalidVersion = invalidVersion; var differentInvalidVersion = LanguageVersion.parse('-', onError: (_) {}); - expect(validVersion == invalidVersion, false); - expect(invalidVersion == validVersion, false); - expect(invalidVersion == identicalInvalidVersion, true); - expect(invalidVersion == differentInvalidVersion, false); - - expect(validVersion < invalidVersion, false); - expect(invalidVersion < validVersion, false); - expect(invalidVersion < identicalInvalidVersion, false); - expect(invalidVersion < differentInvalidVersion, false); - - expect(validVersion <= invalidVersion, false); - expect(invalidVersion <= validVersion, false); - expect(invalidVersion <= identicalInvalidVersion, true); - expect(invalidVersion <= differentInvalidVersion, false); - - expect(validVersion > invalidVersion, false); - expect(invalidVersion > validVersion, false); - expect(invalidVersion > identicalInvalidVersion, false); - expect(invalidVersion > differentInvalidVersion, false); - - expect(validVersion >= invalidVersion, false); - expect(invalidVersion >= validVersion, false); - expect(invalidVersion >= identicalInvalidVersion, true); - expect(invalidVersion >= differentInvalidVersion, false); + testComparisonsWithInvalid(validVersion, invalidVersion); + testComparisonsWithInvalid(invalidVersion, validVersion); + testComparisonsWithInvalid(invalidVersion, identicalInvalidVersion); + testComparisonsWithInvalid(invalidVersion, differentInvalidVersion); }); }); From e4527284fdf169b0c2b9a13ee22eb3667a19e355 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 11 Feb 2025 19:37:25 -0600 Subject: [PATCH 08/14] Add changelog entry --- pkgs/package_config/CHANGELOG.md | 3 +++ pkgs/package_config/lib/src/package_config.dart | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/package_config/CHANGELOG.md b/pkgs/package_config/CHANGELOG.md index 3848a39b49..227840ba9b 100644 --- a/pkgs/package_config/CHANGELOG.md +++ b/pkgs/package_config/CHANGELOG.md @@ -1,5 +1,8 @@ ## 2.2.0-wip +- Add relational operators to `LanguageVersion` with extension methods + exported under `LanguageVersionRelationalOperators`. + ## 2.1.1 - Require Dart 3.4 diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 3f3829a9b3..10e49b9db2 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -349,7 +349,7 @@ abstract class LanguageVersion implements Comparable { /// Two language versions are considered equal if they have the /// same major and minor version numbers. /// - /// A language version is greater then another if the former's major version + /// A language version is greater than another if the former's major version /// is greater than the latter's major version, or if they have /// the same major version and the former's minor version is greater than /// the latter's. From 72cb124b4d6b991465e3534c81a2bcdb61c8f9f0 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 13 Feb 2025 19:32:05 -0600 Subject: [PATCH 09/14] Clarify docs for behavior with invalid versions --- pkgs/package_config/lib/src/package_config.dart | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 10e49b9db2..5662821805 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -402,7 +402,7 @@ abstract class InvalidLanguageVersion implements LanguageVersion { } /// Relational operators for [LanguageVersion] that -/// compare versions with [LanguageVersion.compareTo]. +/// compare valid versions with [LanguageVersion.compareTo]. /// /// An [InvalidLanguageVersion] is not less or greater than other versions /// and is only equal to itself. @@ -410,7 +410,8 @@ abstract class InvalidLanguageVersion implements LanguageVersion { extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is less than [other]. /// - /// If either version is an [InvalidLanguageVersion], returns `false`. + /// An [InvalidLanguageVersion] is never less than or greater than + /// any other language version. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. @@ -426,8 +427,8 @@ extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is less than or equal to [other]. /// - /// If either version is an [InvalidLanguageVersion], - /// returns whether they are the same object. + /// An [InvalidLanguageVersion] is never less than or greater than + /// any other language version. It is equal only to itself. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. @@ -446,7 +447,8 @@ extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is greater than [other]. /// - /// If either version is an [InvalidLanguageVersion], returns `false`. + /// An [InvalidLanguageVersion] is never less than or greater than + /// any other language version. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. @@ -462,8 +464,8 @@ extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is greater than or equal to [other]. /// - /// If either version is an [InvalidLanguageVersion], - /// returns whether they are the same object. + /// An [InvalidLanguageVersion] is never less than or greater than + /// any other language version. It is equal only to itself. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. From 8b1718572f040fb4983c08ce5cfd4723bb9e3e00 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 13 Feb 2025 19:33:48 -0600 Subject: [PATCH 10/14] Don't use unnecessary, duplicate variables for identical tests --- pkgs/package_config/test/package_config_impl_test.dart | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 570fb4d910..0cf9e48812 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -60,16 +60,14 @@ void main() { test('compareTo valid', () { var version = LanguageVersion(3, 5); - var identicalVersion = version; var sameMajorSameMinorVersion = LanguageVersion(3, 5); var sameMajorLowerMinorVersion = LanguageVersion(3, 4); var lowerMajorSameMinorVersion = LanguageVersion(2, 5); var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version.compareTo(identicalVersion), 0); + expect(version.compareTo(version), 0); expect(version.compareTo(sameMajorSameMinorVersion), 0); - expect(identicalVersion.compareTo(version), 0); expect(sameMajorSameMinorVersion.compareTo(version), 0); expect(version.compareTo(sameMajorLowerMinorVersion), isPositive); @@ -128,12 +126,11 @@ void main() { var validVersion = LanguageVersion(3, 5); var invalidVersion = LanguageVersion.parse('', onError: (_) {}); - var identicalInvalidVersion = invalidVersion; var differentInvalidVersion = LanguageVersion.parse('-', onError: (_) {}); testComparisonsWithInvalid(validVersion, invalidVersion); testComparisonsWithInvalid(invalidVersion, validVersion); - testComparisonsWithInvalid(invalidVersion, identicalInvalidVersion); + testComparisonsWithInvalid(invalidVersion, invalidVersion); testComparisonsWithInvalid(invalidVersion, differentInvalidVersion); }); }); From 52a4fde749ae8cacb3d3e0a0146b911a7dd06a0c Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 13 Feb 2025 20:00:11 -0600 Subject: [PATCH 11/14] Test all 10 combinations of same/greater/lower for major.minor --- .../test/package_config_impl_test.dart | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 0cf9e48812..4ad5850aca 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -86,9 +86,10 @@ void main() { }); test('relational valid', () { - var version = LanguageVersion(3, 5); - - void testComparisons(LanguageVersion otherVersion) { + /// Test that the relational comparisons between two valid versions + /// match the results of `compareTo`. + void testComparisons( + LanguageVersion version, LanguageVersion otherVersion) { expect(version == otherVersion, version.compareTo(otherVersion) == 0); expect(version < otherVersion, version.compareTo(otherVersion) < 0); @@ -98,16 +99,19 @@ void main() { expect(version >= otherVersion, version.compareTo(otherVersion) >= 0); } - // Check that relational operator implementations match - // the results of compareTo for valid versions. - [ - version, // Identical. - LanguageVersion(3, 5), // Same major, same minor. - LanguageVersion(3, 4), // Same major, lower minor. - LanguageVersion(2, 5), // Lower major, same minor. - LanguageVersion(3, 6), // Same major, greater minor. - LanguageVersion(4, 5), // Great major, same minor. - ].forEach(testComparisons); + var version = LanguageVersion(3, 5); + + // Check relational comparisons of a version to itself. + testComparisons(version, version); + + // Check relational comparisons of a version to versions with all + // possible combinations of minor and major versions that are + // the same, lower, and greater. + for (final major in [2, 3, 4]) { + for (final minor in [4, 5, 6]) { + testComparisons(version, LanguageVersion(major, minor)); + } + } }); test('relational invalid', () { From bbd9c63ff6a10c79a0a6b74275a17bc6b9645b0b Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Thu, 13 Feb 2025 20:05:28 -0600 Subject: [PATCH 12/14] Test all combinations for compareTo as well --- .../test/package_config_impl_test.dart | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index 4ad5850aca..7d97b7ffd3 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -60,21 +60,21 @@ void main() { test('compareTo valid', () { var version = LanguageVersion(3, 5); - var sameMajorSameMinorVersion = LanguageVersion(3, 5); - var sameMajorLowerMinorVersion = LanguageVersion(3, 4); - var lowerMajorSameMinorVersion = LanguageVersion(2, 5); - var sameMajorGreaterMinorVersion = LanguageVersion(3, 6); - var greaterMajorSameMinorVersion = LanguageVersion(4, 5); - expect(version.compareTo(version), 0); - expect(version.compareTo(sameMajorSameMinorVersion), 0); - expect(sameMajorSameMinorVersion.compareTo(version), 0); - - expect(version.compareTo(sameMajorLowerMinorVersion), isPositive); - expect(version.compareTo(lowerMajorSameMinorVersion), isPositive); - - expect(version.compareTo(sameMajorGreaterMinorVersion), isNegative); - expect(version.compareTo(greaterMajorSameMinorVersion), isNegative); + for (var (otherVersion, matcher) in [ + (version, isZero), // Identical. + (LanguageVersion(3, 5), isZero), // Same major, same minor. + (LanguageVersion(3, 4), isPositive), // Same major, lower minor. + (LanguageVersion(3, 6), isNegative), // Same major, greater minor. + (LanguageVersion(2, 5), isPositive), // Lower major, same minor. + (LanguageVersion(2, 4), isPositive), // Lower major, lower minor. + (LanguageVersion(2, 6), isPositive), // Lower major, greater minor. + (LanguageVersion(4, 5), isNegative), // Greater major, same minor. + (LanguageVersion(4, 4), isNegative), // Greater major, lower minor. + (LanguageVersion(4, 6), isNegative), // Greater major, greater minor. + ]) { + expect(version.compareTo(otherVersion), matcher); + } }); test('compareTo invalid', () { From c1e933dcac284823612b394bc6279c3480744ed0 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Tue, 18 Feb 2025 09:33:20 -0600 Subject: [PATCH 13/14] Remove TODO for unneeded migration --- pkgs/package_config/lib/src/package_config.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 5662821805..de7b13e426 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -406,7 +406,6 @@ abstract class InvalidLanguageVersion implements LanguageVersion { /// /// An [InvalidLanguageVersion] is not less or greater than other versions /// and is only equal to itself. -// TODO(v3): Consider declaring on LanguageVersion class. extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is less than [other]. /// From 2fc5df9544a86db948fe29696e610b4652b37562 Mon Sep 17 00:00:00 2001 From: Parker Lougheed Date: Fri, 21 Feb 2025 12:31:14 -0600 Subject: [PATCH 14/14] Throw an error if either operand is invalid --- .../lib/src/package_config.dart | 70 ++++++++++--------- .../test/package_config_impl_test.dart | 8 +-- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/pkgs/package_config/lib/src/package_config.dart b/pkgs/package_config/lib/src/package_config.dart index 46a2cda037..707e85703e 100644 --- a/pkgs/package_config/lib/src/package_config.dart +++ b/pkgs/package_config/lib/src/package_config.dart @@ -410,21 +410,22 @@ abstract class InvalidLanguageVersion implements LanguageVersion { /// Relational operators for [LanguageVersion] that /// compare valid versions with [LanguageVersion.compareTo]. /// -/// An [InvalidLanguageVersion] is not less or greater than other versions -/// and is only equal to itself. +/// If either operand is an [InvalidLanguageVersion], a [StateError] is thrown. +/// Versions should be verified as valid after parsing and before using them. extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is less than [other]. /// - /// An [InvalidLanguageVersion] is never less than or greater than - /// any other language version. + /// If either version being compared is an [InvalidLanguageVersion], + /// a [StateError] is thrown. Verify versions are valid before comparing them. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. bool operator <(LanguageVersion other) { - // Account for invalid language versions which aren't - // greater or less than any other version. - if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { - return false; + // Throw an error if comparing as or with an invalid language version. + if (this is InvalidLanguageVersion) { + _throwThisInvalid(); + } else if (other is InvalidLanguageVersion) { + _throwOtherInvalid(); } return compareTo(other) < 0; @@ -432,19 +433,17 @@ extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is less than or equal to [other]. /// - /// An [InvalidLanguageVersion] is never less than or greater than - /// any other language version. It is equal only to itself. + /// If either version being compared is an [InvalidLanguageVersion], + /// a [StateError] is thrown. Verify versions are valid before comparing them. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. bool operator <=(LanguageVersion other) { - // Account for invalid language versions only being equal to themselves. - if (identical(this, other)) { - return true; - } - - if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { - return false; + // Throw an error if comparing as or with an invalid language version. + if (this is InvalidLanguageVersion) { + _throwThisInvalid(); + } else if (other is InvalidLanguageVersion) { + _throwOtherInvalid(); } return compareTo(other) <= 0; @@ -452,16 +451,17 @@ extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is greater than [other]. /// - /// An [InvalidLanguageVersion] is never less than or greater than - /// any other language version. + /// If either version being compared is an [InvalidLanguageVersion], + /// a [StateError] is thrown. Verify versions are valid before comparing them. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. bool operator >(LanguageVersion other) { - // Account for invalid language versions which aren't - // greater or less than any other version. - if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { - return false; + // Throw an error if comparing as or with an invalid language version. + if (this is InvalidLanguageVersion) { + _throwThisInvalid(); + } else if (other is InvalidLanguageVersion) { + _throwOtherInvalid(); } return compareTo(other) > 0; @@ -469,21 +469,27 @@ extension LanguageVersionRelationalOperators on LanguageVersion { /// Whether this language version is greater than or equal to [other]. /// - /// An [InvalidLanguageVersion] is never less than or greater than - /// any other language version. It is equal only to itself. + /// If either version being compared is an [InvalidLanguageVersion], + /// a [StateError] is thrown. Verify versions are valid before comparing them. /// /// For details on how valid language versions are compared, /// check out [LanguageVersion.compareTo]. bool operator >=(LanguageVersion other) { - // Account for invalid language versions only being equal to themselves. - if (identical(this, other)) { - return true; - } - - if (this is InvalidLanguageVersion || other is InvalidLanguageVersion) { - return false; + // Throw an error if comparing as or with an invalid language version. + if (this is InvalidLanguageVersion) { + _throwThisInvalid(); + } else if (other is InvalidLanguageVersion) { + _throwOtherInvalid(); } return compareTo(other) >= 0; } + + static Never _throwThisInvalid() => throw StateError( + 'Can\'t compare an invalid language version to another language version. ' + 'Verify language versions are valid after parsing.'); + + static Never _throwOtherInvalid() => throw StateError( + 'Can\'t compare a language version to an invalid language version. ' + 'Verify language versions are valid after parsing.'); } diff --git a/pkgs/package_config/test/package_config_impl_test.dart b/pkgs/package_config/test/package_config_impl_test.dart index d6765c4e04..fff82fa5e4 100644 --- a/pkgs/package_config/test/package_config_impl_test.dart +++ b/pkgs/package_config/test/package_config_impl_test.dart @@ -133,11 +133,11 @@ void main() { ) { expect(version == otherVersion, identical(version, otherVersion)); - expect(version < otherVersion, false); - expect(version <= otherVersion, identical(version, otherVersion)); + expect(() => version < otherVersion, throwsA(isA())); + expect(() => version <= otherVersion, throwsA(isA())); - expect(version > otherVersion, false); - expect(version >= otherVersion, identical(version, otherVersion)); + expect(() => version > otherVersion, throwsA(isA())); + expect(() => version >= otherVersion, throwsA(isA())); } var validVersion = LanguageVersion(3, 5);