├── .art └── output_example.png ├── .gitignore ├── CHANGELOG ├── LICENSE ├── README.md ├── analysis_options.yaml ├── bin └── dep_check.dart ├── example ├── main.dart └── pubspec.yaml ├── lib ├── dep_check.dart └── src │ ├── arg.dart │ ├── comparator.dart │ ├── file.dart │ ├── models.dart │ ├── printer.dart │ └── pub.dart ├── pubspec.yaml └── test └── comparator_test.dart /.art/output_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vrtdev/dep_check/28f8280390d2607a114dfe791a9e824e274e4d5a/.art/output_example.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub.dart 2 | .packages 3 | .dart_tool/ 4 | .pub/ 5 | .idea/ 6 | build/ 7 | pubspec.lock 8 | 9 | # Directory created by dartdoc 10 | doc/api/ -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | # 0.0.2 2 | 3 | * 🤦‍♂️ 4 | 5 | # 0.0.1-alpha1 6 | 7 | * Improved documentation 8 | * Followed up on warnings from `pub.dev` 9 | 10 | # 0.0.1 11 | 12 | * Initial Release 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 vrtdev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![pub package](https://img.shields.io/pub/v/dep_check.svg)](https://pub.dartlang.org/packages/dep_check) 2 | 3 | # Pub Dev Dependencies Checker 4 | 5 | Checks if your dependencies are up to date in your `pubspec.yaml`. 6 | 7 | ![output_example](.art/output_example.png) 8 | 9 | # :book: Installation 10 | 11 | ```shell 12 | pub global activate dep_check 13 | ``` 14 | 15 | In your desired project go and enter. 16 | 17 | ```shell 18 | pub global run dep_check 19 | ``` 20 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | analyzer: 2 | linter: 3 | rules: 4 | - annotate_overrides 5 | - always_declare_return_types 6 | - always_put_required_named_parameters_first 7 | - avoid_empty_else 8 | - avoid_field_initializers_in_const_classes 9 | - avoid_init_to_null 10 | - avoid_relative_lib_imports 11 | - avoid_returning_null 12 | - avoid_returning_null_for_void 13 | - avoid_return_types_on_setters 14 | - avoid_returning_null_for_future 15 | - avoid_shadowing_type_parameters 16 | - avoid_types_as_parameter_names 17 | - await_only_futures 18 | - cascade_invocations 19 | - camel_case_types 20 | - curly_braces_in_flow_control_structures 21 | - constant_identifier_names 22 | - directives_ordering 23 | - empty_catches 24 | - empty_constructor_bodies 25 | - empty_statements 26 | - file_names 27 | - implementation_imports 28 | - join_return_with_assignment 29 | - library_names 30 | - library_prefixes 31 | - no_duplicate_case_values 32 | - non_constant_identifier_names 33 | - null_closures 34 | - overridden_fields 35 | - prefer_adjacent_string_concatenation 36 | - prefer_contains 37 | - prefer_conditional_assignment 38 | - prefer_collection_literals 39 | - prefer_expression_function_bodies 40 | - prefer_final_fields 41 | - prefer_final_locals 42 | - prefer_initializing_formals 43 | - prefer_interpolation_to_compose_strings 44 | - prefer_equal_for_default_values 45 | - prefer_int_literals 46 | - prefer_mixin 47 | - prefer_null_aware_operators 48 | - prefer_is_empty 49 | - prefer_is_not_empty 50 | - prefer_spread_collections 51 | - prefer_typing_uninitialized_variables 52 | - prefer_void_to_null 53 | - prefer_iterable_whereType 54 | - recursive_getters 55 | - slash_for_doc_comments 56 | - type_init_formals 57 | - unawaited_futures 58 | - unnecessary_lambdas 59 | - unnecessary_brace_in_string_interps 60 | - unnecessary_null_in_if_null_operators 61 | - unnecessary_overrides 62 | - unnecessary_parenthesis 63 | - unnecessary_this 64 | - unrelated_type_equality_checks 65 | - use_function_type_syntax_for_parameters 66 | - use_to_and_as_if_applicable 67 | - use_rethrow_when_possible 68 | - valid_regexps 69 | - void_checks 70 | - sort_pub_dependencies 71 | - package_names -------------------------------------------------------------------------------- /bin/dep_check.dart: -------------------------------------------------------------------------------- 1 | import 'package:dep_check/dep_check.dart' as dep_check; 2 | 3 | void main(List arguments) => dep_check.checkDependencies(arguments); 4 | -------------------------------------------------------------------------------- /example/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:dep_check/dep_check.dart'; 2 | void main() { 3 | checkDependencies([]); 4 | } -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dep_check_example 2 | 3 | dependencies: 4 | args: ^1.5.2 5 | yaml: ^2.2.0 6 | pub_semver: ^1.4.2 7 | http: ^0.12.0 8 | 9 | environment: 10 | sdk: '>=2.5.0 <3.0.0' 11 | 12 | dev_dependencies: 13 | test: '^1.6.3' 14 | -------------------------------------------------------------------------------- /lib/dep_check.dart: -------------------------------------------------------------------------------- 1 | library dep_check; 2 | 3 | import 'dart:io'; 4 | 5 | import 'package:dep_check/src/arg.dart'; 6 | import 'package:dep_check/src/comparator.dart'; 7 | import 'package:dep_check/src/file.dart'; 8 | import 'package:dep_check/src/models.dart'; 9 | import 'package:dep_check/src/printer.dart'; 10 | import 'package:dep_check/src/pub.dart'; 11 | 12 | /// Checks your `pubspec.yaml` dependencies with pub to see if there are newer versions available 13 | /// You can optionally specify the location of your pubspec.yaml with the `-p` flag 14 | /// You can optionally specify the location of your pubspec.lock with the `-l` flag 15 | void checkDependencies(final List args) async { 16 | try { 17 | final cliArgs = CLIArgParser.fromRawArgs(args); 18 | final FileContents fileContents = 19 | await FileHelper.readFileContents(cliArgs); 20 | final List latestVersions = 21 | await PubService.lastVersions( 22 | fileContents.yamlContents.allDependencies); 23 | 24 | final output = Comparator.compareVersions( 25 | CompareInput( 26 | fileContents.yamlContents.allDependencies, 27 | fileContents.lockContents.resolvedDependencies, 28 | latestVersions, 29 | ), 30 | ); 31 | 32 | Printer.printOutput(output); 33 | exit(0); 34 | } catch (e) { 35 | stderr.writeln(e); 36 | CLIArgParser.printUsage(); 37 | exit(1); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/src/arg.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:args/args.dart'; 4 | 5 | import 'models.dart'; 6 | 7 | class CLIArgParser { 8 | CLIArgParser._(); 9 | 10 | static const _defaultPubSpecLocation = "pubspec.yaml"; 11 | static const _pubSpecKey = "pubspec"; 12 | 13 | static const _defaultPubSpecLockLocation = "pubspec.lock"; 14 | static const _pubLockKey = "lock"; 15 | 16 | static final _cliParser = ArgParser() 17 | ..addSeparator("===== pubspec.yaml") 18 | ..addOption( 19 | _pubSpecKey, 20 | abbr: 'p', 21 | defaultsTo: _defaultPubSpecLocation, 22 | help: 'Location of your pubspec.yaml file', 23 | ) 24 | ..addSeparator('===== pubspec.lock') 25 | ..addOption( 26 | _pubLockKey, 27 | abbr: 'l', 28 | defaultsTo: _defaultPubSpecLockLocation, 29 | help: 'Location of your pubspec.lock file', 30 | ); 31 | 32 | static Input fromRawArgs(final List args) { 33 | final results = _cliParser.parse(args); 34 | return Input( 35 | results[_pubSpecKey], 36 | results[_pubLockKey], 37 | ); 38 | } 39 | 40 | static void printUsage() => stdout.writeln(_cliParser.usage); 41 | } 42 | -------------------------------------------------------------------------------- /lib/src/comparator.dart: -------------------------------------------------------------------------------- 1 | import 'package:dep_check/src/models.dart'; 2 | import 'package:pub_semver/pub_semver.dart'; 3 | 4 | class Comparator { 5 | Comparator._(); 6 | 7 | static Output compareVersions(final CompareInput input) { 8 | final bool Function(PubSpecDependency, ResolvedDependency) 9 | resolvedPredicate = (pubDep, otherDep) => pubDep.name == otherDep.name; 10 | bool isNewVersionAvailableOnPub(Version pubDevDep, Version lockFileDep) => 11 | pubDevDep > lockFileDep; 12 | bool canBeUpgradedWithPubUpgrade(final VersionConstraint pubSpecConstraint, 13 | final Version pubDevDep) => 14 | pubSpecConstraint.allows(pubDevDep); 15 | 16 | final List upToDateDependencies = []; 17 | final List pubUpgradeableDependencies = []; 18 | final List manualUpdatableDependencies = []; 19 | 20 | input.allDependencies.forEach((dependency) { 21 | final pubSpecConstraint = dependency.version; 22 | final lockFileDep = input.lockFileDependencies 23 | .firstWhere((it) => resolvedPredicate(dependency, it)) 24 | .version; 25 | final pubDevDep = input.pubDevDependencies 26 | .firstWhere((it) => resolvedPredicate(dependency, it)) 27 | .version; 28 | 29 | if (isNewVersionAvailableOnPub(pubDevDep, lockFileDep)) { 30 | canBeUpgradedWithPubUpgrade(pubSpecConstraint, pubDevDep) 31 | ? pubUpgradeableDependencies.add( 32 | ProcessedDependency.fromPubSpecDependency( 33 | dependency, 34 | pubDevDep, 35 | ), 36 | ) 37 | : manualUpdatableDependencies.add( 38 | ProcessedDependency.fromPubSpecDependency( 39 | dependency, 40 | pubDevDep, 41 | ), 42 | ); 43 | } else { 44 | upToDateDependencies.add( 45 | ProcessedDependency.fromPubSpecDependency(dependency, pubDevDep)); 46 | } 47 | }); 48 | 49 | return Output( 50 | upToDateDependencies, 51 | pubUpgradeableDependencies, 52 | manualUpdatableDependencies, 53 | ); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/src/file.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:pub_semver/pub_semver.dart'; 4 | import 'package:yaml/yaml.dart'; 5 | 6 | import 'models.dart'; 7 | 8 | class FileHelper { 9 | FileHelper._(); 10 | 11 | static const depKey = "dependencies"; 12 | static const devDepKey = "dev_dependencies"; 13 | static const resolvedPackagesKey = "packages"; 14 | static const resolvedVersionKey = "version"; 15 | 16 | static Future readFileContents(final Input args) async { 17 | final pubSpecYamlFile = File(args.pathToPubSpec); 18 | final pubLockFile = File(args.pathToPubSpecLock); 19 | 20 | if (!(await pubSpecYamlFile.exists())) { 21 | throw Exception( 22 | "'pubspec.yaml' file not found on location ${args.pathToPubSpec}"); 23 | } 24 | 25 | if (!(await pubLockFile.exists())) { 26 | throw Exception( 27 | "'pubspec.lock' file not found on location ${args.pathToPubSpecLock}"); 28 | } 29 | 30 | final pubSpecContents = await _getPubSpecContents(pubSpecYamlFile); 31 | final pubLockContents = await _getPubSpecLockContents(pubLockFile); 32 | 33 | return FileContents( 34 | pubSpecContents, 35 | pubLockContents, 36 | ); 37 | } 38 | 39 | static Future _getPubSpecContents( 40 | final File file) async { 41 | List _getDependencies( 42 | final YamlDocument pubSpecDoc, 43 | final String pubSpecKey, 44 | ) { 45 | VersionConstraint _sanitizeDependencyVersion(final MapEntry it) => 46 | it.value != null 47 | ? VersionConstraint.parse(it.value) 48 | : VersionConstraint.any; 49 | 50 | final YamlMap contents = (pubSpecDoc.contents as YamlMap)[pubSpecKey]; 51 | return contents.entries 52 | .map( 53 | (it) => PubSpecDependency( 54 | name: it.key, 55 | version: !(it.value is YamlNode) 56 | ? _sanitizeDependencyVersion(it) 57 | : VersionConstraint.any, 58 | ), 59 | ) 60 | .cast() 61 | .toList(); 62 | } 63 | 64 | final pubSpecDoc = await _loadYamlFile(file); 65 | return PubSpecYamlContents( 66 | dependencies: _getDependencies(pubSpecDoc, depKey), 67 | devDependencies: _getDependencies(pubSpecDoc, devDepKey), 68 | ); 69 | } 70 | 71 | static Future _getPubSpecLockContents( 72 | final File file) async { 73 | List _getDependencies(final YamlDocument pubSpecDoc) { 74 | Version resolvedVersionFromDepMap(final YamlMap depNode) => 75 | Version.parse(depNode[resolvedVersionKey]); 76 | 77 | final YamlMap contents = 78 | (pubSpecDoc.contents as YamlMap)[resolvedPackagesKey]; 79 | return contents.entries 80 | .map( 81 | (it) => ResolvedDependency( 82 | name: it.key, 83 | version: resolvedVersionFromDepMap(it.value as YamlMap), 84 | ), 85 | ) 86 | .toList(); 87 | } 88 | 89 | final pubLockDoc = await _loadYamlFile(file); 90 | return PubSpecLockContents(_getDependencies(pubLockDoc)); 91 | } 92 | 93 | static Future _loadYamlFile(final File file) async => 94 | loadYamlDocument(await file.readAsString()); 95 | } 96 | -------------------------------------------------------------------------------- /lib/src/models.dart: -------------------------------------------------------------------------------- 1 | import 'package:pub_semver/pub_semver.dart'; 2 | 3 | class Input { 4 | final String pathToPubSpec; 5 | final String pathToPubSpecLock; 6 | 7 | Input( 8 | this.pathToPubSpec, 9 | this.pathToPubSpecLock, 10 | ); 11 | 12 | @override 13 | String toString() => 'CLIArguments{$pathToPubSpec, $pathToPubSpecLock}'; 14 | } 15 | 16 | class PubSpecDependency { 17 | final VersionConstraint version; 18 | final String name; 19 | 20 | PubSpecDependency({this.name, this.version}) 21 | : assert(version != null), 22 | assert(name != null); 23 | 24 | @override 25 | String toString() => 'Dependency{$name, $version}'; 26 | } 27 | 28 | class ResolvedDependency { 29 | final Version version; 30 | final String name; 31 | 32 | ResolvedDependency({this.name, this.version}) 33 | : assert(version != null), 34 | assert(name != null); 35 | } 36 | 37 | class ProcessedDependency extends Comparable { 38 | final String name; 39 | final String currentVersion; 40 | final String latestVersion; 41 | 42 | ProcessedDependency._( 43 | this.name, 44 | this.currentVersion, 45 | this.latestVersion, 46 | ); 47 | 48 | ProcessedDependency.fromPubSpecDependency( 49 | final PubSpecDependency dep, final Version latestVersion) 50 | : this._( 51 | dep.name, 52 | dep.version.toString(), 53 | VersionConstraint.compatibleWith(latestVersion).toString(), 54 | ); 55 | 56 | @override 57 | int compareTo(final ProcessedDependency other) => name.compareTo(other.name); 58 | } 59 | 60 | class PubSpecYamlContents { 61 | final List dependencies; 62 | final List devDependencies; 63 | 64 | PubSpecYamlContents({ 65 | this.dependencies, 66 | this.devDependencies, 67 | }) : assert(dependencies != null), 68 | assert(devDependencies != null); 69 | 70 | List get allDependencies => 71 | (dependencies + devDependencies).toSet().toList(); 72 | } 73 | 74 | class PubSpecLockContents { 75 | final List resolvedDependencies; 76 | 77 | PubSpecLockContents(this.resolvedDependencies); 78 | } 79 | 80 | class FileContents { 81 | final PubSpecYamlContents yamlContents; 82 | final PubSpecLockContents lockContents; 83 | 84 | FileContents(this.yamlContents, this.lockContents); 85 | } 86 | 87 | class CompareInput { 88 | final List allDependencies; 89 | final List lockFileDependencies; 90 | final List pubDevDependencies; 91 | 92 | CompareInput( 93 | this.allDependencies, 94 | this.lockFileDependencies, 95 | this.pubDevDependencies, 96 | ); 97 | } 98 | 99 | class Output { 100 | final List upToDateDependencies; 101 | final List pubUpgradeableDependencies; 102 | final List manualUpdatableDependencies; 103 | 104 | Output( 105 | this.upToDateDependencies, 106 | this.pubUpgradeableDependencies, 107 | this.manualUpdatableDependencies, 108 | ); 109 | } 110 | -------------------------------------------------------------------------------- /lib/src/printer.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'models.dart'; 4 | 5 | class Printer { 6 | Printer._(); 7 | 8 | static void printOutput(final Output output) { 9 | final outputStr = StringBuffer() 10 | ..writeln() 11 | ..writeln("Dependencies Check:") 12 | ..writeln("-------------------"); 13 | 14 | if (output.upToDateDependencies.isNotEmpty) { 15 | outputStr.writeln("Up to date:"); 16 | 17 | output.upToDateDependencies 18 | ..sort() 19 | ..forEach((upToDateDep) { 20 | outputStr.writeln("✅ ${upToDateDep.name}"); 21 | }); 22 | } 23 | 24 | if (output.pubUpgradeableDependencies.isNotEmpty) { 25 | outputStr 26 | ..writeln() 27 | ..writeln("Pub upgradeablable (run `flutter pub upgrade`)"); 28 | 29 | output.pubUpgradeableDependencies 30 | ..sort() 31 | ..forEach((pubUpgradeableDep) { 32 | outputStr.writeln( 33 | "⏫ ${pubUpgradeableDep.name} - ${pubUpgradeableDep.currentVersion} ➡️ ${pubUpgradeableDep.latestVersion}"); 34 | }); 35 | } 36 | 37 | if (output.manualUpdatableDependencies.isNotEmpty) { 38 | outputStr..writeln()..writeln("Manually upgradable"); 39 | 40 | output.manualUpdatableDependencies 41 | ..sort() 42 | ..forEach((depToUpdateManually) { 43 | outputStr.writeln( 44 | "👆 ${depToUpdateManually.name} - ${depToUpdateManually.currentVersion} ➡️ ${depToUpdateManually.latestVersion}"); 45 | }); 46 | } 47 | 48 | stdout.writeln(outputStr.toString()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/src/pub.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | 4 | import 'package:dep_check/src/models.dart'; 5 | import 'package:http/http.dart' as http; 6 | import 'package:pub_semver/pub_semver.dart'; 7 | 8 | class PubService { 9 | PubService._(); 10 | 11 | static const baseUrl = "https://pub.dev/api/packages"; 12 | 13 | static Future> lastVersions( 14 | List dependencies) { 15 | Future _latestVersionForDependency( 16 | final PubSpecDependency dep) async { 17 | final response = await http.get("${PubService.baseUrl}/${dep.name}"); 18 | Version version; 19 | if (response.statusCode == 200) { 20 | final decodedJson = json.decode(response.body); 21 | version = Version.parse(decodedJson["latest"]["version"]); 22 | } else { 23 | stderr.writeln("🤷‍♂️ Could not find latest version for ${dep.name}"); 24 | } 25 | return version ?? Version.none; 26 | } 27 | 28 | return Future.wait(dependencies.map((dep) async { 29 | final latestVersion = await _latestVersionForDependency(dep); 30 | return ResolvedDependency( 31 | name: dep.name, 32 | version: latestVersion, 33 | ); 34 | }).toList()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: dep_check 2 | description: A package which simplifies the task of updating your Flutter dependencies. 3 | version: 0.0.2 4 | maintainer: Tim Rijckaert 5 | homepage: https://github.com/vrtdev/dep_check 6 | authors: 7 | - Tim Rijckaert 8 | 9 | dependencies: 10 | args: ^1.5.2 11 | yaml: ^2.2.0 12 | pub_semver: ^1.4.2 13 | http: ^0.12.0 14 | 15 | environment: 16 | sdk: '>=2.5.0 <3.0.0' 17 | 18 | dev_dependencies: 19 | test: '^1.6.3' 20 | -------------------------------------------------------------------------------- /test/comparator_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:dep_check/src/comparator.dart' as c; 2 | import 'package:dep_check/src/models.dart'; 3 | import 'package:pub_semver/pub_semver.dart'; 4 | import 'package:test/test.dart'; 5 | 6 | void main() { 7 | CompareInput _mapToCompareInput(List<_TestCase> testCases) { 8 | final List allDependencies = []; 9 | final List lockFileDependencies = []; 10 | final List pubDevDependencies = []; 11 | 12 | testCases.forEach((testCase) { 13 | allDependencies.add(PubSpecDependency(name: testCase.name, version: VersionConstraint.parse(testCase.pubSpec))); 14 | lockFileDependencies.add(ResolvedDependency(name: testCase.name, version: Version.parse(testCase.lockFile))); 15 | pubDevDependencies.add(ResolvedDependency(name: testCase.name, version: Version.parse(testCase.pubDev))); 16 | }); 17 | 18 | return CompareInput( 19 | allDependencies, 20 | lockFileDependencies, 21 | pubDevDependencies, 22 | ); 23 | } 24 | 25 | group("up to date dependencies", () { 26 | final compareInput = _mapToCompareInput([ 27 | _TestCase("a", pubSpec: "^1.0.0", lockFile: "1.0.0", pubDev: "1.0.0"), 28 | _TestCase("b", pubSpec: "1.0.0", lockFile: "1.0.0", pubDev: "1.0.0"), 29 | ]); 30 | 31 | test("should all be parsed as up to date", () { 32 | final output = c.Comparator.compareVersions(compareInput); 33 | expect(output.upToDateDependencies.length, 2); 34 | expect(output.pubUpgradeableDependencies.length, 0); 35 | expect(output.manualUpdatableDependencies.length, 0); 36 | }); 37 | }); 38 | 39 | group("pub upgradable dependencies", () { 40 | final compareInput = _mapToCompareInput([ 41 | _TestCase("a", pubSpec: "^1.0.0", lockFile: "1.0.0", pubDev: "1.0.1"), 42 | _TestCase("b", pubSpec: "^1.1.0", lockFile: "1.1.0", pubDev: "1.9.9"), 43 | ]); 44 | 45 | test("should all be parsed as pub upgradable dependencies", () { 46 | final output = c.Comparator.compareVersions(compareInput); 47 | expect(output.upToDateDependencies.length, 0); 48 | expect(output.pubUpgradeableDependencies.length, 2); 49 | expect(output.manualUpdatableDependencies.length, 0); 50 | }); 51 | }); 52 | 53 | group("manually upgradable dependencies", () { 54 | final compareInput = _mapToCompareInput([ 55 | _TestCase("a", pubSpec: "^1.0.0", lockFile: "1.0.0", pubDev: "2.0.0"), 56 | _TestCase("b", pubSpec: "^1.1.0", lockFile: "1.1.0", pubDev: "2.0.0"), 57 | _TestCase("c", pubSpec: "^0.9.0", lockFile: "0.9.0", pubDev: "1.0.0"), 58 | ]); 59 | 60 | test("should all be parsed as manually upgradable dependencies", () { 61 | final output = c.Comparator.compareVersions(compareInput); 62 | expect(output.upToDateDependencies.length, 0); 63 | expect(output.pubUpgradeableDependencies.length, 0); 64 | expect(output.manualUpdatableDependencies.length, 3); 65 | }); 66 | }); 67 | } 68 | 69 | class _TestCase { 70 | final String name; 71 | final String pubSpec; 72 | final String lockFile; 73 | final String pubDev; 74 | 75 | _TestCase(this.name, {this.pubSpec, this.lockFile, this.pubDev}) 76 | : assert(name != null), 77 | assert(pubSpec != null), 78 | assert(lockFile != null), 79 | assert(pubDev != null); 80 | } 81 | --------------------------------------------------------------------------------