blob: dafca6915092ebe46009c6f8642c3d239f39d35e [file] [log] [blame]
// 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/src/test_utilities/test_code_format.dart';
import 'package:linter/src/rules.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../utils/test_code_extensions.dart';
import 'server_abstract.dart';
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(DocumentLinkTest);
});
}
@reflectiveTest
class DocumentLinkTest extends AbstractLspAnalysisServerTest {
static const _pubBase = 'https://pub.dev/packages/';
static const _lintBase = 'https://dart.dev/tools/linter-rules/';
@override
void setUp() {
registerLintRules();
super.setUp();
}
Future<void> test_analysisOptions_empty() async {
var content = '';
await _test_analysisOptions_links(content, isEmpty);
}
Future<void> test_analysisOptions_lint_links_list() async {
var content = '''
linter:
rules:
- prefer_relative_imports
- prefer_single_quotes
- prefer_int_literals
''';
var expectedLinks = {
'prefer_relative_imports': '${_lintBase}prefer_relative_imports',
'prefer_single_quotes': '${_lintBase}prefer_single_quotes',
'prefer_int_literals': '${_lintBase}prefer_int_literals',
};
await _test_analysisOptions_links(content, equals(expectedLinks));
}
Future<void> test_analysisOptions_lint_links_map() async {
var content = '''
linter:
rules:
prefer_relative_imports: true
prefer_single_quotes: true
prefer_int_literals: false
''';
var expectedLinks = {
'prefer_relative_imports': '${_lintBase}prefer_relative_imports',
'prefer_single_quotes': '${_lintBase}prefer_single_quotes',
'prefer_int_literals': '${_lintBase}prefer_int_literals',
};
await _test_analysisOptions_links(content, equals(expectedLinks));
}
Future<void> test_analysisOptions_linterRules_empty() async {
var content = '''
linter:
rules:
''';
await _test_pubspec_links(content, isEmpty);
}
Future<void> test_analysisOptions_undefinedLint() async {
var content = '''
linter:
rules:
- undefined
- prefer_single_quotes
''';
var expectedLinks = {
'prefer_single_quotes': '${_lintBase}prefer_single_quotes',
};
await _test_analysisOptions_links(content, equals(expectedLinks));
}
Future<void> test_exampleLink() async {
var exampleFolderPath = join(projectFolderPath, 'examples', 'api');
var exampleFileUri = Uri.file(join(exampleFolderPath, 'foo.dart'));
var code = TestCode.parse('''
/// {@tool dartpad}
/// ** See code in [!examples/api/foo.dart!] **
/// {@end-tool}
class A {}
''');
newFolder(exampleFolderPath);
newFile(mainFilePath, code.code);
await initialize();
var links = await getDocumentLinks(mainFileUri);
var link = links!.single;
expect(link.range, code.range.range);
expect(link.target, exampleFileUri);
}
Future<void> test_pubspec_empty() async {
var content = '';
await _test_pubspec_links(content, isEmpty);
}
Future<void> test_pubspec_packages_empty() async {
var content = '''
dependencies:
''';
await _test_pubspec_links(content, isEmpty);
}
Future<void> test_pubspec_packages_git() async {
var content = '''
dependencies:
github_package_1:
git: https://github.com/dart-lang/sdk.git
github_package_2:
git: git@github.com:dart-lang/sdk.git
github_package_3:
git:
url: https://github.com/dart-lang/sdk.git
''';
var expectedLinks = {
'github_package_1': 'https://github.com/dart-lang/sdk.git',
'github_package_2': 'https://github.com/dart-lang/sdk.git',
'github_package_3': 'https://github.com/dart-lang/sdk.git',
};
await _test_pubspec_links(content, equals(expectedLinks));
}
Future<void> test_pubspec_packages_hosted() async {
var content = '''
dependencies:
hosted_package_1:
hosted: https://custom.dart.dev/
hosted_package_2:
hosted:
url: https://custom.dart.dev/
''';
var expectedLinks = {
'hosted_package_1': 'https://custom.dart.dev/packages/hosted_package_1',
'hosted_package_2': 'https://custom.dart.dev/packages/hosted_package_2',
};
await _test_pubspec_links(content, equals(expectedLinks));
}
Future<void> test_pubspec_packages_pub() async {
var content = '''
dependencies:
pub_package_1: 1.2.3
pub_package_2: ^1.2.3
pub_package_3:
pub_package_4: any
''';
var expectedLinks = {
'pub_package_1': '${_pubBase}pub_package_1',
'pub_package_2': '${_pubBase}pub_package_2',
'pub_package_3': '${_pubBase}pub_package_3',
'pub_package_4': '${_pubBase}pub_package_4',
};
await _test_pubspec_links(content, equals(expectedLinks));
}
Future<void> test_pubspec_packages_unknown() async {
var content = '''
dependencies:
flutter:
sdk: flutter
foo:
path: foo/
bar:
future_unknown_kind:
''';
await _test_pubspec_links(content, isEmpty);
}
Future<void> test_pubspec_packages_withDevDependencies() async {
var content = '''
dependencies:
dep_package: 1.2.3
dev_dependencies:
dev_dep_package:
''';
var expectedLinks = {
'dep_package': '${_pubBase}dep_package',
'dev_dep_package': '${_pubBase}dev_dep_package',
};
await _test_pubspec_links(content, equals(expectedLinks));
}
Future<void> _test_analysisOptions_links(
String content,
Matcher expected,
) async {
await _test_file_links(
analysisOptionsUri,
analysisOptionsPath,
content,
expected,
);
}
Future<void> _test_file_links(
Uri fileUri,
String filePath,
String content,
Matcher expected,
) async {
newFile(filePath, content);
await initialize();
var links = await getDocumentLinks(fileUri);
// Build a map of the links and their text from the document for easy
// comparison.
var linkMap = {
for (var link in links!)
getTextForRange(content, link.range): link.target?.toString(),
};
expect(linkMap, expected);
}
Future<void> _test_pubspec_links(String content, Matcher expected) async {
await _test_file_links(pubspecFileUri, pubspecFilePath, content, expected);
}
}