fix the unit tests for Dart 3.0 (dart-lang/pubspec_parse#86)

* fix the unit tests for Dart 3.0

* update the package version
diff --git a/pkgs/pubspec_parse/.github/workflows/test-package.yml b/pkgs/pubspec_parse/.github/workflows/test-package.yml
index 5375399..c46df30 100644
--- a/pkgs/pubspec_parse/.github/workflows/test-package.yml
+++ b/pkgs/pubspec_parse/.github/workflows/test-package.yml
@@ -46,7 +46,7 @@
       fail-fast: false
       matrix:
         os: [ubuntu-latest]
-        sdk: [2.14.0, dev]
+        sdk: [2.17.0, dev]
     steps:
       - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8
       - uses: dart-lang/setup-dart@6a218f2413a3e78e9087f638a238f6b40893203d
diff --git a/pkgs/pubspec_parse/CHANGELOG.md b/pkgs/pubspec_parse/CHANGELOG.md
index 069e81c..117fd12 100644
--- a/pkgs/pubspec_parse/CHANGELOG.md
+++ b/pkgs/pubspec_parse/CHANGELOG.md
@@ -1,4 +1,7 @@
-## 1.2.1-dev
+## 1.2.2-dev
+
+- Update SDK requirement to `2.17.0`.
+- Fix the unit tests for Dart 3.0.0.
 
 ## 1.2.1
 
diff --git a/pkgs/pubspec_parse/LICENSE b/pkgs/pubspec_parse/LICENSE
index 9972f6e..4d1ad40 100644
--- a/pkgs/pubspec_parse/LICENSE
+++ b/pkgs/pubspec_parse/LICENSE
@@ -1,4 +1,4 @@
-Copyright 2018, the Dart project authors. 
+Copyright 2018, the Dart project authors.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
diff --git a/pkgs/pubspec_parse/README.md b/pkgs/pubspec_parse/README.md
index eca3610..916742a 100644
--- a/pkgs/pubspec_parse/README.md
+++ b/pkgs/pubspec_parse/README.md
@@ -1,7 +1,12 @@
-[![Build Status](https://github.com/dart-lang/pubspec_parse/workflows/Dart%20CI/badge.svg)](https://github.com/dart-lang/pubspec_parse/actions?query=workflow%3A"Dart+CI"+branch%3Amaster)
+[![Dart CI](https://github.com/dart-lang/pubspec_parse/actions/workflows/test-package.yml/badge.svg)](https://github.com/dart-lang/pubspec_parse/actions/workflows/test-package.yml)
 [![pub package](https://img.shields.io/pub/v/pubspec_parse.svg)](https://pub.dev/packages/pubspec_parse)
+[![package publisher](https://img.shields.io/pub/publisher/pubspec_parse.svg)](https://pub.dev/packages/pubspec_parse/publisher)
+
+## What's this?
 
 Supports parsing `pubspec.yaml` files with robust error reporting and support
 for most of the documented features.
 
+## More information
+
 Read more about the [pubspec format](https://dart.dev/tools/pub/pubspec).
diff --git a/pkgs/pubspec_parse/pubspec.yaml b/pkgs/pubspec_parse/pubspec.yaml
index 23f15c1..03f61bd 100644
--- a/pkgs/pubspec_parse/pubspec.yaml
+++ b/pkgs/pubspec_parse/pubspec.yaml
@@ -2,11 +2,11 @@
 description: >-
   Simple package for parsing pubspec.yaml files with a type-safe API and rich
   error reporting.
-version: 1.2.1
+version: 1.2.2-dev
 repository: https://github.com/dart-lang/pubspec_parse
 
 environment:
-  sdk: '>=2.14.0 <3.0.0'
+  sdk: '>=2.17.0 <3.0.0'
 
 dependencies:
   checked_yaml: ^2.0.1
@@ -19,7 +19,7 @@
   build_runner: ^2.0.3
   build_verify: '>=2.0.0 <4.0.0'
   json_serializable: ^6.0.0
-  lints: ^1.0.0
+  lints: ^2.0.0
   path: ^1.5.1
   # Needed because we are configuring `combining_builder`
   source_gen: ^1.0.0
diff --git a/pkgs/pubspec_parse/test/dependency_test.dart b/pkgs/pubspec_parse/test/dependency_test.dart
index 8fb48e8..b366887 100644
--- a/pkgs/pubspec_parse/test/dependency_test.dart
+++ b/pkgs/pubspec_parse/test/dependency_test.dart
@@ -225,30 +225,16 @@
   });
 
   test('null content', () {
-    _expectThrows(
+    _expectThrowsContaining(
       {'sdk': null},
-      r'''
-line 5, column 11: Unsupported value for "sdk". type 'Null' is not a subtype of type 'String' in type cast
-  ╷
-5 │      "sdk": null
-  │ ┌───────────^
-6 │ │   }
-  │ └──^
-  ╵''',
+      r"type 'Null' is not a subtype of type 'String'",
     );
   });
 
   test('number content', () {
-    _expectThrows(
+    _expectThrowsContaining(
       {'sdk': 42},
-      r'''
-line 5, column 11: Unsupported value for "sdk". type 'int' is not a subtype of type 'String' in type cast
-  ╷
-5 │      "sdk": 42
-  │ ┌───────────^
-6 │ │   }
-  │ └──^
-  ╵''',
+      r"type 'int' is not a subtype of type 'String'",
     );
   });
 }
@@ -337,46 +323,27 @@
   });
 
   test('git - empty map', () {
-    _expectThrows(
+    _expectThrowsContaining(
       {'git': <String, dynamic>{}},
-      r'''
-line 5, column 11: Missing key "url". type 'Null' is not a subtype of type 'String' in type cast
-  ╷
-5 │    "git": {}
-  │           ^^
-  ╵''',
+      r"type 'Null' is not a subtype of type 'String'",
     );
   });
 
   test('git - null url', () {
-    _expectThrows(
+    _expectThrowsContaining(
       {
         'git': {'url': null}
       },
-      r'''
-line 6, column 12: Unsupported value for "url". type 'Null' is not a subtype of type 'String' in type cast
-  ╷
-6 │       "url": null
-  │ ┌────────────^
-7 │ │    }
-  │ └───^
-  ╵''',
+      r"type 'Null' is not a subtype of type 'String'",
     );
   });
 
   test('git - int url', () {
-    _expectThrows(
+    _expectThrowsContaining(
       {
         'git': {'url': 42}
       },
-      r'''
-line 6, column 12: Unsupported value for "url". type 'int' is not a subtype of type 'String' in type cast
-  ╷
-6 │       "url": 42
-  │ ┌────────────^
-7 │ │    }
-  │ └───^
-  ╵''',
+      r"type 'int' is not a subtype of type 'String'",
     );
   });
 }
@@ -446,6 +413,16 @@
   );
 }
 
+void _expectThrowsContaining(Object content, String errorText) {
+  expectParseThrowsContaining(
+    {
+      'name': 'sample',
+      'dependencies': {'dep': content}
+    },
+    errorText,
+  );
+}
+
 T _dependency<T extends Dependency>(
   Object? content, {
   bool skipTryPub = false,
diff --git a/pkgs/pubspec_parse/test/parse_test.dart b/pkgs/pubspec_parse/test/parse_test.dart
index a12d034..f3b4679 100644
--- a/pkgs/pubspec_parse/test/parse_test.dart
+++ b/pkgs/pubspec_parse/test/parse_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // ignore_for_file: deprecated_member_use_from_same_package
+// ignore_for_file: lines_longer_than_80_chars
+
 library parse_test;
 
 import 'package:pub_semver/pub_semver.dart';
@@ -22,7 +24,7 @@
     expect(value.authors, isEmpty);
     expect(
       value.environment,
-      {'sdk': VersionConstraint.parse('>=2.7.0 <3.0.0')},
+      {'sdk': VersionConstraint.parse('>=2.12.0 <3.0.0')},
     );
     expect(value.documentation, isNull);
     expect(value.dependencies, isEmpty);
@@ -36,7 +38,7 @@
 
   test('all fields set', () {
     final version = Version.parse('1.2.3');
-    final sdkConstraint = VersionConstraint.parse('>=2.0.0-dev.54 <3.0.0');
+    final sdkConstraint = VersionConstraint.parse('>=2.12.0 <3.0.0');
     final value = parse({
       'name': 'sample',
       'version': version.toString(),
@@ -85,7 +87,7 @@
       {
         'name': 'sample',
         'environment': {
-          'sdk': '>=2.7.0 <3.0.0',
+          'sdk': '>=2.12.0 <3.0.0',
           'bob': null,
         }
       },
@@ -98,12 +100,7 @@
 
   group('publish_to', () {
     for (var entry in {
-      42: r'''
-line 3, column 16: Unsupported value for "publish_to". type 'int' is not a subtype of type 'String?' in type cast
-  ╷
-3 │  "publish_to": 42
-  │                ^^
-  ╵''',
+      42: "Unsupported value for \"publish_to\". type 'int' is not a subtype of type 'String?'",
       '##not a uri!': r'''
 line 3, column 16: Unsupported value for "publish_to". Must be an http or https URL.

@@ -124,7 +121,7 @@
   ╵''',
     }.entries) {
       test('cannot be `${entry.key}`', () {
-        expectParseThrows(
+        expectParseThrowsContaining(
           {'name': 'sample', 'publish_to': entry.key},
           entry.value,
           skipTryPub: true,
@@ -241,26 +238,16 @@
     });
 
     test('missing name', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {},
-        r'''
-line 1, column 1: Missing key "name". type 'Null' is not a subtype of type 'String' in type cast
-  ╷
-1 │ {}
-  │ ^^
-  ╵''',
+        "Missing key \"name\". type 'Null' is not a subtype of type 'String'",
       );
     });
 
     test('null name value', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {'name': null},
-        r'''
-line 2, column 10: Unsupported value for "name". type 'Null' is not a subtype of type 'String' in type cast
-  ╷
-2 │  "name": null
-  │          ^^^^
-  ╵''',
+        "Unsupported value for \"name\". type 'Null' is not a subtype of type 'String'",
       );
     });
 
@@ -336,37 +323,23 @@
     });
 
     test('bad repository url', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {
           ...defaultPubspec,
           'repository': {'x': 'y'},
         },
-        r'''
-line 6, column 16: Unsupported value for "repository". type 'YamlMap' is not a subtype of type 'String' in type cast
-  ╷
-6 │    "repository": {
-  │ ┌────────────────^
-7 │ │   "x": "y"
-8 │ └  }
-  ╵''',
+        "Unsupported value for \"repository\". type 'YamlMap' is not a subtype of type 'String'",
         skipTryPub: true,
       );
     });
 
     test('bad issue_tracker url', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {
           'name': 'sample',
           'issue_tracker': {'x': 'y'},
         },
-        r'''
-line 3, column 19: Unsupported value for "issue_tracker". type 'YamlMap' is not a subtype of type 'String' in type cast
-  ╷
-3 │    "issue_tracker": {
-  │ ┌───────────────────^
-4 │ │   "x": "y"
-5 │ └  }
-  ╵''',
+        "Unsupported value for \"issue_tracker\". type 'YamlMap' is not a subtype of type 'String'",
         skipTryPub: true,
       );
     });
@@ -374,35 +347,23 @@
 
   group('funding', () {
     test('not a list', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {
           ...defaultPubspec,
           'funding': 1,
         },
-        r'''
-line 6, column 13: Unsupported value for "funding". type 'int' is not a subtype of type 'List<dynamic>?' in type cast
-  ╷
-6 │  "funding": 1
-  │             ^
-  ╵''',
+        "Unsupported value for \"funding\". type 'int' is not a subtype of type 'List<dynamic>?'",
         skipTryPub: true,
       );
     });
 
     test('not an uri', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {
           ...defaultPubspec,
           'funding': [1],
         },
-        r'''
-line 6, column 13: Unsupported value for "funding". type 'int' is not a subtype of type 'String' in type cast
-  ╷
-6 │    "funding": [
-  │ ┌─────────────^
-7 │ │   1
-8 │ └  ]
-  ╵''',
+        "Unsupported value for \"funding\". type 'int' is not a subtype of type 'String'",
         skipTryPub: true,
       );
     });
@@ -608,14 +569,9 @@
     });
 
     test('name cannot be empty', () {
-      expectParseThrows(
+      expectParseThrowsContaining(
         {},
-        r'''
-line 1, column 1: Missing key "name". type 'Null' is not a subtype of type 'String' in type cast
-  ╷
-1 │ {}
-  │ ^^
-  ╵''',
+        "Missing key \"name\". type 'Null' is not a subtype of type 'String'",
         lenient: true,
       );
     });
diff --git a/pkgs/pubspec_parse/test/test_utils.dart b/pkgs/pubspec_parse/test/test_utils.dart
index 72d2142..b573851 100644
--- a/pkgs/pubspec_parse/test/test_utils.dart
+++ b/pkgs/pubspec_parse/test/test_utils.dart
@@ -16,7 +16,7 @@
 
 const defaultPubspec = {
   'name': 'sample',
-  'environment': {'sdk': '>=2.7.0 <3.0.0'},
+  'environment': {'sdk': '>=2.12.0 <3.0.0'},
 };
 
 String _encodeJson(Object? input) =>
@@ -124,3 +124,36 @@
       ),
       _throwsParsedYamlException(expectedError),
     );
+
+void expectParseThrowsContaining(
+  Object? content,
+  String errorFragment, {
+  bool skipTryPub = false,
+  bool lenient = false,
+}) {
+  expect(
+    () => parse(
+      content,
+      lenient: lenient,
+      quietOnError: true,
+      skipTryPub: skipTryPub,
+    ),
+    _throwsParsedYamlExceptionContaining(errorFragment),
+  );
+}
+
+// ignore: prefer_expression_function_bodies
+Matcher _throwsParsedYamlExceptionContaining(String errorFragment) {
+  return throwsA(
+    const TypeMatcher<ParsedYamlException>().having(
+      (e) {
+        final message = e.formattedMessage;
+        printOnFailure("Actual error format:\nr'''\n$message'''");
+        _printDebugParsedYamlException(e);
+        return message;
+      },
+      'formattedMessage',
+      contains(errorFragment),
+    ),
+  );
+}