| // Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'package:analyzer/diagnostic/diagnostic.dart'; |
| import 'package:analyzer/source/file_source.dart'; |
| import 'package:analyzer/source/source.dart'; |
| import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag; |
| import 'package:analyzer/src/pubspec/validators/missing_dependency_validator.dart'; |
| import 'package:analyzer_testing/resource_provider_mixin.dart'; |
| import 'package:matcher/expect.dart'; |
| import 'package:meta/meta.dart'; |
| import 'package:test_reflective_loader/test_reflective_loader.dart'; |
| import 'package:yaml/yaml.dart'; |
| |
| main() { |
| defineReflectiveSuite(() { |
| defineReflectiveTests(MissingDependencyTest); |
| }); |
| } |
| |
| @reflectiveTest |
| class MissingDependencyTest with ResourceProviderMixin { |
| late Source _source; |
| |
| /// Asserts that when the validator is used on the given [content], a |
| /// [diag.missingDependency] warning is produced. |
| /// |
| /// The problem message and correction message are returned so that it can be |
| /// further validated if desired. |
| ({String problemMessage, String correctionMessage}) assertErrors( |
| String content, { |
| required Set<String> usedDeps, |
| required Set<String> usedDevDeps, |
| List<String> addDeps = const [], |
| List<String> addDevDeps = const [], |
| List<String> removeDevDeps = const [], |
| }) { |
| var error = _runValidator(content, usedDeps, usedDevDeps).first; |
| var data = MissingDependencyData.byDiagnostic[error]!; |
| expect(error.diagnosticCode, diag.missingDependency); |
| expect(data.addDeps, addDeps); |
| expect(data.addDevDeps, addDevDeps); |
| expect(data.removeDevDeps, removeDevDeps); |
| return ( |
| problemMessage: error.problemMessage.messageText(includeUrl: false), |
| correctionMessage: error.correctionMessage!, |
| ); |
| } |
| |
| /// Assert that when the validator is used on the given [content] no errors |
| /// are produced. |
| void assertNoErrors( |
| String content, { |
| Set<String> usedDeps = const {}, |
| Set<String> usedDevDeps = const {}, |
| }) { |
| List<Diagnostic> errors = _runValidator(content, usedDeps, usedDevDeps); |
| expect(errors.isEmpty, true); |
| } |
| |
| @mustCallSuper |
| void setUp() { |
| var file = getFile('/sample/pubspec.yaml'); |
| _source = FileSource(file); |
| } |
| |
| test_missingDependency_error() { |
| var (:problemMessage, :correctionMessage) = assertErrors( |
| ''' |
| name: sample |
| dependencies: |
| path: any |
| ''', |
| usedDeps: {'path', 'matcher'}, |
| addDeps: ['matcher'], |
| usedDevDeps: {}, |
| ); |
| expect(problemMessage, contains("package 'matcher' in 'dependencies'")); |
| expect(correctionMessage, contains("adding 'matcher' to 'dependencies'")); |
| } |
| |
| test_missingDependency_move_to_dev() { |
| var (:problemMessage, :correctionMessage) = assertErrors( |
| ''' |
| name: sample |
| dependencies: |
| path: any |
| dev_dependencies: |
| test: any |
| ''', |
| usedDeps: {'path', 'test'}, |
| addDeps: ['test'], |
| removeDevDeps: ['test'], |
| usedDevDeps: {}, |
| ); |
| expect(problemMessage, contains("package 'test' in 'dependencies'")); |
| expect(correctionMessage, contains("adding 'test' to 'dependencies'")); |
| } |
| |
| test_missingDependency_noError() { |
| assertNoErrors( |
| ''' |
| name: sample |
| dependencies: |
| test: any |
| ''', |
| usedDeps: {'test'}, |
| usedDevDeps: {}, |
| ); |
| } |
| |
| test_missingDependency_package_noError() { |
| assertNoErrors( |
| ''' |
| name: sample |
| dependencies: |
| test: any |
| dev_dependencies: |
| lints: any |
| ''', |
| usedDeps: {'test', 'sample'}, |
| usedDevDeps: {'lints'}, |
| ); |
| } |
| |
| test_missingDevDependency_error() { |
| var (:problemMessage, :correctionMessage) = assertErrors( |
| ''' |
| name: sample |
| dependencies: |
| path: any |
| dev_dependencies: |
| lints: any |
| ''', |
| usedDeps: {'path'}, |
| usedDevDeps: {'lints', 'test'}, |
| addDevDeps: ['test'], |
| ); |
| expect(problemMessage, contains("package 'test' in 'dev_dependencies'")); |
| expect(correctionMessage, contains("adding 'test' to 'dev_dependencies'")); |
| } |
| |
| test_missingDevDependency_inDeps_noError() { |
| assertNoErrors( |
| ''' |
| name: sample |
| dependencies: |
| test: any |
| path: any |
| dev_dependencies: |
| lints: any |
| ''', |
| usedDeps: {'test', 'path'}, |
| usedDevDeps: {'lints', 'path'}, |
| ); |
| } |
| |
| test_missingDevDependency_multiple_deps() { |
| var (:problemMessage, :correctionMessage) = assertErrors( |
| ''' |
| name: sample |
| dependencies: |
| path: any |
| ''', |
| usedDeps: {'path', 'test', 'args'}, |
| usedDevDeps: {}, |
| addDeps: ['test', 'args'], |
| ); |
| expect( |
| problemMessage, |
| contains("packages 'test', 'args' in 'dependencies'"), |
| ); |
| expect( |
| correctionMessage, |
| contains("adding 'test', 'args' to 'dependencies'"), |
| ); |
| } |
| |
| test_missingDevDependency_multiple_depsAndDevDeps() { |
| var (:problemMessage, :correctionMessage) = assertErrors( |
| ''' |
| name: sample |
| ''', |
| usedDeps: {'path', 'args'}, |
| usedDevDeps: {'test', 'lints'}, |
| addDeps: ['path', 'args'], |
| addDevDeps: ['test', 'lints'], |
| ); |
| expect( |
| problemMessage, |
| contains( |
| "packages 'path', 'args' in 'dependencies', and packages 'test', " |
| "'lints' in 'dev_dependencies'", |
| ), |
| ); |
| expect( |
| correctionMessage, |
| contains( |
| "adding 'path', 'args' to 'dependencies', and 'test', 'lints' to " |
| "'dev_dependencies'", |
| ), |
| ); |
| } |
| |
| test_missingDevDependency_multiple_devDeps() { |
| var (:problemMessage, :correctionMessage) = assertErrors( |
| ''' |
| name: sample |
| dev_dependencies: |
| path: any |
| ''', |
| usedDeps: {}, |
| usedDevDeps: {'path', 'test', 'args'}, |
| addDevDeps: ['test', 'args'], |
| ); |
| expect( |
| problemMessage, |
| contains("packages 'test', 'args' in 'dev_dependencies'"), |
| ); |
| expect( |
| correctionMessage, |
| contains("adding 'test', 'args' to 'dev_dependencies'"), |
| ); |
| } |
| |
| test_missingDevDependency_noError() { |
| assertNoErrors( |
| ''' |
| name: sample |
| dependencies: |
| test: any |
| dev_dependencies: |
| lints: any |
| ''', |
| usedDeps: {'test'}, |
| usedDevDeps: {'lints'}, |
| ); |
| } |
| |
| test_missingDevDependency_package_noError() { |
| assertNoErrors( |
| ''' |
| name: sample |
| dependencies: |
| test: any |
| dev_dependencies: |
| lints: any |
| ''', |
| usedDeps: {'test'}, |
| usedDevDeps: {'lints', 'sample'}, |
| ); |
| } |
| |
| List<Diagnostic> _runValidator( |
| String content, |
| Set<String> usedDeps, |
| Set<String> usedDevDeps, |
| ) { |
| YamlNode node = loadYamlNode(content); |
| if (node is! YamlMap) { |
| // The file is empty. |
| node = YamlMap(); |
| } |
| var errors = MissingDependencyValidator( |
| node, |
| _source, |
| resourceProvider, |
| ).validate(usedDeps, usedDevDeps); |
| return errors; |
| } |
| } |